[
  {
    "path": ".dockerignore",
    "content": ".git\n.vscode\n.devbots\n.github\nnode_modules\n"
  },
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\ncharset = utf-8\nindent_style = space\nindent_size = 2\nend_of_line = lf\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n"
  },
  {
    "path": ".eslintrc.cjs",
    "content": "module.exports = {\n  root: true,\n  parserOptions: {\n    parser: '@typescript-eslint/parser',\n    ecmaVersion: 2020,\n    sourceType: 'module',\n    projectService: true,\n    tsconfigRootDir: __dirname,\n    extraFileExtensions: ['.vue', '.json'],\n    suppressDeprecatedPropertyWarnings: true,\n  },\n  extends: [\n    'standard',\n    'plugin:vue/recommended',\n    // 'plugin:vuetify/base',\n    'plugin:sonarjs/recommended',\n  ],\n  env: {\n    node: true,\n    browser: true,\n    es6: true,\n  },\n  plugins: [\n    '@typescript-eslint',\n    '@stylistic/ts',\n    'sonarjs',\n    'react',\n    'eslint-plugin-local-rules',\n  ],\n  rules: {\n    'no-var': 'error',\n    // allow paren-less arrow functions\n    'arrow-parens': ['error', 'as-needed'],\n    // set maximum line characters\n    'max-len': ['error', {\n      code: 140,\n      ignoreUrls: true,\n      ignoreTemplateLiterals: true,\n      ignoreTrailingComments: true,\n    }],\n    complexity: ['error', 32],\n    quotes: ['error', 'single', {\n      avoidEscape: true,\n      allowTemplateLiterals: true,\n    }],\n    'no-console': 'off',\n    'comma-dangle': ['error', {\n      arrays: 'always-multiline',\n      objects: 'always-multiline',\n      imports: 'always-multiline',\n      exports: 'always-multiline',\n      functions: 'only-multiline',\n    }],\n    // allow debugger during development\n    'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',\n    'no-return-assign': 'off',\n    'no-unused-vars': 'error',\n    'no-empty': 'error',\n    'array-bracket-spacing': ['error', 'never'],\n    'object-curly-spacing': ['error', 'always'],\n    'space-before-function-paren': [\n      'error',\n      {\n        anonymous: 'always',\n        named: 'always',\n        asyncArrow: 'always',\n      },\n    ],\n    'no-return-await': 'warn',\n    'object-shorthand': ['error', 'always'],\n    'no-extra-semi': 'error',\n    'prefer-const': ['error', {\n      destructuring: 'all',\n      ignoreReadBeforeAssign: true,\n    }],\n    'no-prototype-builtins': 'off',\n    'no-void': 'off',\n    'no-case-declarations': 'off',\n    indent: ['error', 2, {\n      ...require('eslint-config-standard').rules.indent[2],\n      flatTernaryExpressions: true,\n      offsetTernaryExpressions: false,\n    }],\n    'sort-imports': ['warn', {\n      ignoreDeclarationSort: true,\n      ignoreCase: true,\n    }],\n    'multiline-ternary': 'off',\n    'no-implicit-coercion': ['error', { boolean: false }],\n\n    'sonarjs/cognitive-complexity': 'off',\n    'sonarjs/no-duplicate-string': 'off',\n\n    // Not in override, these apply to non-.vue files too\n    'vue/require-default-prop': 'off',\n    'vue/require-prop-types': 'off',\n    'vue/one-component-per-file': 'off',\n    'vue/custom-event-name-casing': ['error', 'camelCase', { ignores: ['/^[a-z]+(?:-[a-z]+)*:[a-z]+(?:-[a-z]+)*$/u'] }],\n    'vue/multi-word-component-names': 'off',\n\n    'vue/attributes-order': ['error', {\n      order: [\n        'DEFINITION', 'LIST_RENDERING', 'CONDITIONALS', 'RENDER_MODIFIERS', 'UNIQUE', 'GLOBAL', 'SLOT',\n        'TWO_WAY_BINDING', 'ATTR_DYNAMIC', 'ATTR_STATIC', 'ATTR_SHORTHAND_BOOL', 'OTHER_DIRECTIVES', 'EVENTS', 'CONTENT',\n      ],\n      alphabetical: true,\n    }],\n  },\n  overrides: [\n    {\n      files: '**/*.vue',\n      rules: {\n        indent: 'off',\n        'vue/script-indent': ['error', 2, {\n          baseIndent: 1,\n          switchCase: 1,\n          ignores: [],\n        }],\n        'vue/html-closing-bracket-newline': ['error', {\n          singleline: 'never',\n          multiline: 'always',\n        }],\n        'vue/html-closing-bracket-spacing': 'error',\n        'vue/max-attributes-per-line': ['error', {\n          singleline: 5,\n          multiline: 1,\n        }],\n        'vue/valid-v-on': 'off', // This rule doesn't allow empty event listeners\n        'vue/no-v-html': 'off',\n        'vue/singleline-html-element-content-newline': 'off',\n        'vue/multiline-html-element-content-newline': 'off',\n        'vue/valid-v-slot': ['error', { allowModifiers: true }],\n\n        /* TODO: this really should be enabled,\n            we just do it so much I didn't have time to fix them all */\n        'vue/no-v-text-v-html-on-component': 'off',\n      },\n    },\n    {\n      files: ['**/*.ts', '**/*.tsx'],\n      parser: '@typescript-eslint/parser',\n      rules: {\n        // Can't overload function exports with this enabled\n        'import/export': 'off',\n\n        // False positives on types\n        'no-undef': 'off',\n\n        quotes: 'off',\n        '@stylistic/ts/quotes': ['error', 'single', {\n          avoidEscape: true,\n          allowTemplateLiterals: true,\n        }],\n\n        indent: 'off',\n        '@stylistic/ts/indent': ['error', 2, {\n          ...require('eslint-config-standard').rules.indent[2],\n          ignoredNodes: [...require('eslint-config-standard').rules.indent[2].ignoredNodes, 'TSTypeParameterInstantiation'],\n          flatTernaryExpressions: true,\n          offsetTernaryExpressions: false,\n        }],\n\n        'func-call-spacing': 'off',\n        '@stylistic/ts/func-call-spacing': require('eslint-config-standard').rules['func-call-spacing'],\n\n        // Handled by tsc\n        'no-redeclare': 'off',\n\n        'no-use-before-define': 'off',\n        '@typescript-eslint/no-use-before-define': ['error', 'nofunc'],\n\n        'no-useless-constructor': 'off',\n        '@typescript-eslint/no-useless-constructor': ['error'],\n\n        // Enabled in tsconfig\n        'no-unused-vars': 'off',\n\n        '@stylistic/ts/member-delimiter-style': ['error', {\n          multiline: {\n            delimiter: 'none',\n          },\n          singleline: {\n            delimiter: 'comma',\n          },\n        }],\n        '@stylistic/ts/type-annotation-spacing': 'error',\n\n        '@typescript-eslint/prefer-namespace-keyword': 'error',\n        '@typescript-eslint/adjacent-overload-signatures': 'error',\n        // '@typescript-eslint/ban-types': 'error',\n        '@typescript-eslint/member-ordering': 'error',\n        '@typescript-eslint/no-inferrable-types': 'error',\n        '@typescript-eslint/unified-signatures': 'error',\n        '@typescript-eslint/no-invalid-this': 'error',\n        '@typescript-eslint/consistent-type-imports': ['error', {\n          prefer: 'type-imports',\n          fixStyle: 'separate-type-imports',\n        }],\n        'import/consistent-type-specifier-style': ['error', 'prefer-top-level'],\n        'import/no-duplicates': ['error', { 'prefer-inline': false }],\n        '@typescript-eslint/no-non-null-asserted-optional-chain': 'error',\n        '@typescript-eslint/no-unnecessary-boolean-literal-compare': 'error',\n        // '@typescript-eslint/no-unnecessary-condition': 'error',\n        '@typescript-eslint/prefer-includes': 'error',\n        // '@typescript-eslint/prefer-nullish-coalescing': 'warn',\n        // '@typescript-eslint/prefer-optional-chain': 'warn',\n        '@typescript-eslint/prefer-string-starts-ends-with': 'error',\n        '@typescript-eslint/prefer-ts-expect-error': 'warn',\n        '@typescript-eslint/restrict-plus-operands': 'error',\n        '@typescript-eslint/no-wrapper-object-types': 'error',\n      },\n    },\n    {\n      files: '**/*.tsx',\n      rules: {\n        'jsx-quotes': 'error',\n        'react/jsx-boolean-value': 'error',\n        'react/jsx-closing-bracket-location': ['error', 'line-aligned'],\n        'react/jsx-curly-brace-presence': 'error',\n\n        // https://github.com/yannickcr/eslint-plugin-react/issues/2415\n        // 'react/jsx-curly-spacing': ['error', { when: 'always', spacing: { objectLiterals: 'never' } }],\n        'local-rules/jsx-condition-key': 'error',\n        'local-rules/jsx-curly-spacing': ['error', {\n          when: 'always',\n          spacing: {\n            objectLiterals: 'never',\n            arrayLiterals: 'never',\n            multilineClose: 'never',\n          },\n          children: true,\n        }],\n        'local-rules/jsx-prop-casing': 'error',\n\n        'react/jsx-equals-spacing': 'error',\n        'react/jsx-first-prop-new-line': 'error',\n        'react/jsx-max-props-per-line': ['error', { when: 'multiline' }],\n        'react/jsx-no-comment-textnodes': 'error',\n        'react/jsx-tag-spacing': 'error',\n        'react/jsx-wrap-multilines': ['error', {\n          declaration: 'parens-new-line',\n          assignment: 'parens-new-line',\n          return: 'parens-new-line',\n          arrow: 'parens-new-line',\n          condition: 'parens-new-line',\n          logical: 'parens-new-line',\n        }],\n      },\n    },\n    {\n      files: '**/*.d.ts',\n      rules: {\n        'import/no-duplicates': 'off',\n      },\n    },\n    {\n      files: '**/*.json',\n      parser: '@typescript-eslint/parser',\n      extends: ['plugin:@typescript-eslint/disable-type-checked'],\n      rules: {\n        quotes: ['error', 'double'],\n        'comma-dangle': ['error', 'never'],\n        'quote-props': ['error', 'always'],\n        'max-len': 'off',\n        'no-unused-expressions': 'off',\n        'no-template-curly-in-string': 'off',\n      },\n    },\n  ],\n}\n"
  },
  {
    "path": ".gitattributes",
    "content": "* text=auto eol=lf\n"
  },
  {
    "path": ".github/.git_commit_msg.txt",
    "content": "\n# ------------------------ >8 ------------------------\n# |<----   Using a Maximum Of 50 Characters   ---->| Hard limit to 72 -->|\n# <type>: <subject>\n#\n# <description>\n#\n# fixes #<issue>\n#\n# ----------------------------------------------------\n#\n# <type> can be\n#    feat     (new feature)\n#    fix      (bug fix)\n#    docs     (documentation only)\n#    refactor (refactoring production code)\n#    style    (formatting, missing semicolons, etc. no code change)\n#    test     (adding or refactoring tests; no production code change)\n#    chore    (updating npm scripts etc. no production code change)\n#    revert   (revert a commit\n#              <subject> must be the reverted commit's title\n#              <description> must contain \"This reverts commit <hash>.\")\n#\n# Remember to\n#    Not capitalize the subject line\n#    Use the imperative mood in the subject line\n#    Do not end the subject line with a period\n#    Separate subject from body with a blank line (comments don't count)\n#    Use the body to explain what and why vs. how\n#\n# If you can't summarize your changes in a single line, they should\n# probably be split into multiple commits\n"
  },
  {
    "path": ".github/CONTRIBUTING.md",
    "content": "# Vuetify Contributing Guide\n\nThank you for your interest in improving Vuetify! Please review these guidelines to ensure a smooth contribution process.\n\n## Important Information\n\n- Detailed instructions for [Contributing to Vuetify](https://vuetifyjs.com/getting-started/contributing/) are available in the documentation.\n- For general questions, join [our Discord Community](https://community.vuetifyjs.com/).\n\n## Reporting Issues\n\n- Issues **must** be created using <https://issues.vuetifyjs.com/> or they will be closed immediately.\n- The issue list is **exclusively** for bug reports and feature requests.\n- Search for existing issues before submitting a new one.\n- Ensure the issue is reproducible with the [latest version](https://github.com/vuetifyjs/vuetify/releases/latest).\n- Provide a **minimal** and **concise** reproduction using [Vuetify Play](https://play.vuetifyjs.com/) or a public repository with:\n  - An initial commit showing the working state.\n  - A subsequent commit triggering the issue.\n- Include clear reproduction steps (actions another developer can follow after opening your link).\n- Avoid comments like \"+1\" or \"me too!\" without additional details—use the :+1: button instead.\n\n## Pull Requests\n\n- Work on a new branch in your fork (e.g., `fix/1234-some-issue`), not `dev` or `master`.\n- Submit bug fixes to the `master` branch; new features or breaking changes to the `dev` branch.\n- Use a descriptive title (max 64 characters) for the PR—it will become the commit message.\n- Include examples of the problem and proposed solution, ideally referencing an existing issue (e.g., `Fixes #1234`).\n- Follow [commit guidelines](#commit-guidelines) for all changes.\n\n## Local Development Setup\n\n1. **Prerequisites:**\n   - Git (>v2.20)\n   - Node.js (LTS)\n   - [pnpm](https://pnpm.io/)\n   - Additional tools may be needed for [node-gyp](https://github.com/nodejs/node-gyp#installation) on Windows.\n\n1. **Clone and Install:**\n\n   ```bash\n   git clone https://github.com/vuetifyjs/vuetify.git\n   cd vuetify\n   pnpm i\n   pnpm build vuetify\n   pnpm build api\n   ```\n\n1. **Development:**\n   - Run `pnpm dev` from the root to start a dev server at `localhost:8090` with `packages/vuetify/dev/Playground.vue`.\n   - Test changes in `Playground.vue` and include its contents in your PR.\n   - For documentation, run `pnpm dev docs` (after building Vuetify with `pnpm build:lib`) at `localhost:8095`.\n\n1. **Submitting Changes:**\n   - Fork the repository and add your fork as a remote:\n\n     ```bash\n     git remote add fork https://github.com/YOUR_USERNAME/vuetify.git\n     ```\n\n   - Choose the correct base branch:\n     - Bug fixes/Documentation: `master`\n     - New features: `dev`\n   - Push your branch and open a PR.\n\n## Commit Guidelines\n\nFollow the [conventional-changelog](https://github.com/conventional-changelog/conventional-changelog) standard:\n\n- Format: `<type>(scope): <subject>` (e.g., `fix(VSelect): resolve dropdown bug`) or `<type>: <subject>` (e.g., `docs: update contributing guide`).\n- Subject: Max 60 characters, imperative mood (e.g., \"fix\", not \"fixed\").\n- Body: Reference issues (e.g., `resolves #1234`), wrap at 72 characters, explain \"what\" and \"why\" (not \"how\").\n- Types: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `chore`, `revert`.\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "# These are supported funding model platforms\n\ngithub: [johnleider, KaelWD, MajesticPotatoe]\nopen_collective: vuetify\nko_fi: # Replace with a single Ko-fi username\ntidelift: npm/vuetify\ncustom: # Replace with a single custom sponsorship URL\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "blank_issues_enabled: false\ncontact_links:\n  - name: Vuetify Issue Creator\n    url: https://issues.vuetifyjs.com\n    about: Create Vuetify issues here.\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "<!--\nMAKE SURE TO READ THE CONTRIBUTING GUIDE BEFORE CREATING A PR\nhttps://vuetifyjs.com/getting-started/contributing\n\nProvide a general summary of your changes in the title above\nKeep the title short and descriptive, as it will be used as a commit message\nPR titles should follow conventional-changelog-angular:\nhttps://vuetifyjs.com/getting-started/contributing/#commit-guidelines\n-->\n\n## Description\n<!--\nDescribe your changes in detail. Why is this change required? What problem does it solve?\nIf it fixes an open issue, please link to the issue here.\ne.g. resolves #4213 or fixes #2312\n-->\n\n## Markup:\n<!--\nInformation on how to set up your local development environment can be found here:\nhttps://vuetifyjs.com/getting-started/contributing/#setting-up-your-environment\nRemove this section for documentation or test-only changes.\n-->\n\n<!-- Paste your FULL packages/vuetify/dev/Playground.vue here --->\n```vue\n\n```\n"
  },
  {
    "path": ".github/actions/download-locales/action.yml",
    "content": "name: Download translations\ndescription: Download translations from Crowdin\n\ninputs:\n  crowdin-branch:\n    description: 'Crowdin branch name'\n    required: false\n    default: 'v4'\n\nruns:\n  using: composite\n  steps:\n    - id: get-date\n      run: |\n        echo \"date=$(/bin/date -u \"+%Y%m%d\")\" >> $GITHUB_OUTPUT\n      shell: bash\n    - uses: actions/cache@v4\n      id: cache-crowdin\n      with:\n        key: crowdin-${{ inputs.crowdin-branch }}-${{ steps.get-date.outputs.date }}\n        path: |-\n          packages/api-generator/src/locale/**/*.json\n          !packages/api-generator/src/locale/en/**/*.json\n          packages/docs/src/pages/**/*.md\n          !packages/docs/src/pages/en/**/*.md\n          packages/docs/src/i18n/messages/*.json\n          !packages/docs/src/i18n/messages/en.json\n    - name: Download eo-UY\n      if: ${{ steps.cache-crowdin.outputs.cache-hit != 'true' }}\n      uses: crowdin/github-action@v2.7.1\n      with:\n        download_language: eo\n        config: crowdin.yml\n        upload_sources: false\n        download_translations: true\n        push_translations: false\n        export_only_approved: false\n        crowdin_branch_name: ${{ inputs.crowdin-branch }}\n    - name: Download es-MX\n      if: ${{ steps.cache-crowdin.outputs.cache-hit != 'true' }}\n      uses: crowdin/github-action@v2.7.1\n      with:\n        download_language: es-MX\n        config: crowdin.yml\n        upload_sources: false\n        download_translations: true\n        push_translations: false\n        export_only_approved: false\n        crowdin_branch_name: ${{ inputs.crowdin-branch }}\n    - name: Download ja-JP\n      if: ${{ steps.cache-crowdin.outputs.cache-hit != 'true' }}\n      uses: crowdin/github-action@v2.7.1\n      with:\n        download_language: ja\n        config: crowdin.yml\n        upload_sources: false\n        download_translations: true\n        push_translations: false\n        export_only_approved: false\n        crowdin_branch_name: ${{ inputs.crowdin-branch }}\n    - name: Download zh-CN\n      if: ${{ steps.cache-crowdin.outputs.cache-hit != 'true' }}\n      uses: crowdin/github-action@v2.7.1\n      with:\n        download_language: zh-CN\n        config: crowdin.yml\n        upload_sources: false\n        download_translations: true\n        push_translations: false\n        export_only_approved: false\n        crowdin_branch_name: ${{ inputs.crowdin-branch }}\n"
  },
  {
    "path": ".github/actions/nightly-release/action.yml",
    "content": "name: Nightly Release\ndescription: Automatically release nightly builds\n\ninputs:\n  checkout-repo:\n    description: 'Repository to checkout'\n    required: true\n  checkout-ref:\n    description: 'Ref to checkout'\n    required: true\n  release-id:\n    description: 'Release ID'\n    required: true\n  npm-tag:\n    description: 'NPM tag'\n    required: true\n\noutputs:\n  full-version:\n    description: 'Full version'\n    value: ${{ steps.get-version.outputs.full-version }}\n\nruns:\n  using: composite\n  steps:\n    - run: |\n        git config --global user.email \"actions@github.com\"\n        git config --global user.name \"GitHub Actions\"\n      shell: bash\n    - uses: actions/checkout@v4\n      with:\n        repository: ${{ inputs.checkout-repo }}\n        ref: ${{ inputs.checkout-ref }}\n        fetch-depth: 0\n    - uses: vuetifyjs/setup-action@master\n    - run: >-\n        node -e \"\n          const json = require('./lerna.json');\n          delete json.command.publish.allowBranch;\n          fs.writeFileSync('./lerna.json', JSON.stringify(json, null, 2))\"\n      shell: bash\n    - id: get-version\n      run: echo \"full-version=$(node -e \"console.log(require('./lerna.json').version)\")-${{ inputs.release-id }}\" >> $GITHUB_OUTPUT\n      shell: bash\n    - run: pnpm lerna version ${{ steps.get-version.outputs.full-version }} --no-push --no-commit-hooks --force-publish --yes\n      shell: bash\n    - run: pnpm conventional-changelog -p vuetify --outfile ./packages/vuetify/CHANGELOG.md -r 2\n      shell: bash\n    - run: >-\n        node -e \"fs.writeFileSync(\n          './package.json',\n          JSON.stringify({ ...require('./package.json'), name: '@vuetify/nightly' }, null, 2)\n        )\"\n      shell: bash\n      working-directory: ./packages/vuetify\n    - run: pnpm run --filter @vuetify/nightly build\n      shell: bash\n    - run: pnpm run --filter @vuetify/api-generator build\n      shell: bash\n    - run: npm install -g npm@latest\n      shell: bash\n    - name: NPM Release\n      run: |\n        npm publish ./packages/vuetify --tag ${{ inputs.npm-tag }} --access public\n      shell: bash\n      env:\n        NPM_API_KEY: ${{ inputs.npm-token }}\n"
  },
  {
    "path": ".github/issue-close-app.yml",
    "content": "comment: \"Please only create issues with the provided [issue creator](https://issues.vuetifyjs.com). In the boilerplate for creating an issue, it explains that any ticket made without this will be automatically closed. For general questions, please join [the Discord chat room](https://community.vuetifyjs.com). You can also check [reddit](https://www.reddit.com/r/vuetifyjs/) or [stackoverflow](https://stackoverflow.com/questions/tagged/vuetify.js). Thank you.\"\nissueConfigs:\n- content:\n  - \"<!-- generated by vuetify-issue-helper. DO NOT REMOVE -->\"\n- content:\n  - \"<!-- override-close -->\"\nlabel: \"invalid\"\nexception:\n  - \"johnleider\"\n  - \"KaelWD\"\n  - \"MajesticPotatoe\"\n"
  },
  {
    "path": ".github/lock.yml",
    "content": "daysUntilLock: 365\nlockComment: false\n\npulls:\n  daysUntilLock: 30\n  exemptLabels: ['S: on hold', 'S: work in progress']\n"
  },
  {
    "path": ".github/semantic.yml",
    "content": "titleOnly: true\n"
  },
  {
    "path": ".github/sponsors.yml",
    "content": "- label: 'P: sponsor'\n  members:\n\n- label: 'P: elite sponsor'\n  members:\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: CI\non: [push, pull_request]\nconcurrency:\n  group: ci-${{ github.ref }}\n  cancel-in-progress: true\n\nenv:\n  CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}\n  CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}\n\njobs:\n  pre_job:\n    runs-on: ubuntu-24.04\n    outputs:\n      should_skip: ${{ steps.skip_check.outputs.should_skip }}\n    steps:\n      - id: skip_check\n        if: ${{ !startsWith(github.ref, 'refs/tags/v') && github.ref_name != 'master' }}\n        uses: fkirc/skip-duplicate-actions@master\n        with:\n          skip_after_successful_duplicate: 'true'\n          concurrent_skipping: same_content\n          do_not_skip: '[\"pull_request\", \"workflow_dispatch\", \"schedule\"]'\n\n  build-vuetify:\n    name: Build vuetify\n    needs: pre_job\n    if: needs.pre_job.outputs.should_skip != 'true'\n    runs-on: ubuntu-24.04\n    steps:\n      - uses: actions/checkout@v4\n      - uses: vuetifyjs/setup-action@master\n      - run: pnpm build vuetify\n      - uses: actions/upload-artifact@v4\n        with:\n          name: vuetify-dist\n          path: |\n            packages/vuetify/dist\n            packages/vuetify/lib\n\n  lint:\n    name: Lint\n    needs: [pre_job, build-vuetify]\n    if: needs.pre_job.outputs.should_skip != 'true'\n    runs-on: ubuntu-24.04\n    strategy:\n      fail-fast: false\n      matrix:\n        scopes: ['--filter vuetify --filter @vuetify/api-generator', '--filter vuetifyjs.com']\n    steps:\n      - uses: actions/checkout@v4\n      - uses: actions/download-artifact@v4\n        with:\n          name: vuetify-dist\n          path: packages/vuetify\n      - uses: vuetifyjs/setup-action@master\n      - run: pnpm run $SCOPES lint\n        env:\n          SCOPES: ${{ matrix.scopes }}\n\n  test:\n    name: Test\n    needs: pre_job\n    if: needs.pre_job.outputs.should_skip != 'true'\n    runs-on: ubuntu-24.04\n    steps:\n      - uses: actions/checkout@v4\n      - uses: actions/cache@v4\n        with:\n          path: ~/.cache/ms-playwright\n          key: ${{ runner.os }}-playwright-${{ hashFiles('./pnpm-lock.yaml') }}\n      - uses: vuetifyjs/setup-action@master\n      - run: pnpm exec playwright install chromium\n      - run: pnpm run test\n        working-directory: ./packages/vuetify\n      - uses: actions/upload-artifact@v4\n        if: failure()\n        with:\n          name: Test screenshots\n          path: packages/vuetify/test/__screenshots__\n          if-no-files-found: ignore\n          overwrite: true\n\n  deploy:\n    needs: [lint, test, build-vuetify]\n    runs-on: ubuntu-24.04\n    if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') && github.repository_owner == 'vuetifyjs'\n    environment: production\n    permissions:\n      contents: write\n      id-token: write\n    steps:\n      - uses: actions/checkout@v4\n        with:\n          fetch-depth: 0\n      - uses: actions/download-artifact@v4\n        with:\n          name: vuetify-dist\n          path: packages/vuetify\n      - uses: vuetifyjs/setup-action@master\n      - run: pnpm build api\n      - run: npm install -g npm@latest\n      - name: NPM Release\n        run: |\n          npm publish ./packages/vuetify --tag $(node ./scripts/parse-npm-tag.js $GITHUB_REF_NAME)\n      - name: GitHub release\n        id: create_release\n        run: pnpm conventional-github-releaser -p vuetify\n        env:\n          DEBUG: '*'\n          CONVENTIONAL_GITHUB_RELEASER_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n\n  build-docs:\n    name: Build docs\n    needs: [pre_job, build-vuetify]\n    if: >\n      needs.pre_job.outputs.should_skip != 'true' &&\n      github.event_name == 'push' &&\n      github.repository_owner == 'vuetifyjs' &&\n      contains(toJSON('[\"master\", \"dev\", \"next\"]'), github.ref_name)\n    runs-on: ubuntu-24.04\n    steps:\n      - uses: actions/checkout@v4\n      - uses: actions/download-artifact@v4\n        with:\n          name: vuetify-dist\n          path: packages/vuetify\n      - uses: vuetifyjs/setup-action@master\n      - uses: ./.github/actions/download-locales\n      - run: pnpm build api\n      - run: pnpm build docs\n        env:\n          NODE_OPTIONS: --max-old-space-size=10240\n          VITE_COSMIC_2_BUCKET_SLUG: ${{ secrets.COSMIC_2_BUCKET_SLUG }}\n          VITE_COSMIC_2_BUCKET_READ_KEY: ${{ secrets.COSMIC_2_BUCKET_READ_KEY }}\n          VITE_COSMIC_BUCKET_SLUG: ${{ secrets.COSMIC_BUCKET_SLUG }}\n          VITE_COSMIC_BUCKET_READ_KEY: ${{ secrets.COSMIC_BUCKET_READ_KEY }}\n          VITE_COSMIC_BUCKET_SLUG_STORE: ${{ secrets.COSMIC_BUCKET_SLUG_STORE }}\n          VITE_COSMIC_BUCKET_READ_KEY_STORE: ${{ secrets.COSMIC_BUCKET_READ_KEY_STORE }}\n          VITE_EMAILJS_PUBLIC_KEY: ${{ secrets.EMAILJS_PUBLIC_KEY }}\n          VITE_EMAILJS_SERVICE_ID: ${{ secrets.EMAILJS_SERVICE_ID }}\n          VITE_EMAILJS_TEMPLATE_ID: ${{ secrets.EMAILJS_TEMPLATE_ID }}\n          VITE_API_SERVER_URL: ${{ secrets.API_SERVER_URL }}\n          VITE_GITHUB_SHA: ${{ github.sha }}\n          VITE_GITHUB_REF: ${{ github.ref_name }}\n      - uses: actions/upload-artifact@v4\n        with:\n          name: docs-dist\n          path: packages/docs/dist\n\n  publish-docs:\n    needs: [lint, test, build-docs]\n    runs-on: ubuntu-24.04\n    environment: ${{ github.ref_name }}\n    steps:\n      - uses: actions/checkout@v4\n      - uses: actions/download-artifact@v4\n        with:\n          name: docs-dist\n          path: packages/docs/dist\n      - uses: vuetifyjs/coolify-action@master\n        with:\n          token: ${{ secrets.GITHUB_TOKEN  }}\n          imageName: docs\n          coolifyWebhook: ${{ secrets.COOLIFY_WEBHOOK }}\n          coolifySecret: ${{ secrets.COOLIFY_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/close-issue.yml",
    "content": "name: Close issues\non:\n  push:\n    branches:\n    - dev\n    - next\n    - v3-stable\n    - v2-stable\n    - v2-dev\n\nenv:\n  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n\njobs:\n  close:\n    runs-on: ubuntu-24.04\n    if: github.repository_owner == 'vuetifyjs'\n    steps:\n      - uses: vuetifyjs/close-action@master\n        with:\n          token: ${{ secrets.GITHUB_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/crowdin-uploads.yml",
    "content": "name: Crowdin Uploads\nconcurrency:\n  group: crowdin-${{ github.ref }}\n  cancel-in-progress: true\n\non:\n  push:\n    branches:\n      - 'master'\n    paths:\n    - 'packages/api-generator/src/locale/en/**'\n    - 'packages/docs/src/i18n/messages/en.json'\n    - 'packages/docs/src/pages/en/**'\n    - '.github/workflows/**'\n\nenv:\n  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n  CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}\n  CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}\n  CROWDIN_BRANCH: v4\n\njobs:\n  upload-to-crowdin:\n    runs-on: ubuntu-24.04\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n      - name: Upload\n        uses: crowdin/github-action@v2.7.1\n        with:\n          config: crowdin.yml\n          crowdin_branch_name: ${{ env.CROWDIN_BRANCH }}\n"
  },
  {
    "path": ".github/workflows/nightly.yml",
    "content": "name: Nightly Release\non:\n  schedule:\n    - cron: '0 12 * * *' # 1200 UTC\n  workflow_dispatch:\n    inputs:\n      pr:\n        description: 'Pull Request number'\n        required: false\n        type: string\n\njobs:\n  nightly-schedule:\n    runs-on: ubuntu-24.04\n    if: ${{ github.event_name == 'schedule' && github.repository_owner == 'vuetifyjs' }}\n    environment: preview\n    permissions:\n      contents: read\n      id-token: write\n    strategy:\n      max-parallel: 1\n      fail-fast: false\n      matrix:\n        branch: [ 'master', 'dev', 'next', 'v3-stable', 'v2-stable', 'v2-dev' ]\n        include:\n          - branch: 'master'\n            tag: 'latest'\n          - branch: 'dev'\n            tag: 'dev'\n          - branch: 'next'\n            tag: 'next'\n          - branch: 'v3-stable'\n            tag: 'v3-stable'\n          - branch: 'v2-stable'\n            tag: 'v2-stable'\n          - branch: 'v2-dev'\n            tag: 'v2-dev'\n    steps:\n      - uses: actions/checkout@v4\n        with:\n          ref: ${{ matrix.branch }}\n          fetch-depth: 0\n      - run: |\n          last=$(git show -s --format=%ct HEAD)\n          now=$(date +%s)\n          diff=$(($now - $last))\n          if [ $diff -gt 86400 ]; then\n              echo \"Last commit was more than 24 hours ago, skipping release\"\n              exit 1\n          fi\n      - run: echo \"RELEASE_ID=$(date +'%Y-%m-%d')\" >> $GITHUB_ENV\n      - uses: ./.github/actions/nightly-release\n        with:\n          checkout-repo: ${{ github.repository }}\n          checkout-ref: ${{ matrix.branch }}\n          release-id: ${{ matrix.branch }}.${{ env.RELEASE_ID }}\n          npm-tag: ${{ matrix.tag }}\n      - uses: actions/checkout@v4\n\n  nightly-pr:\n    runs-on: ubuntu-24.04\n    if: ${{ github.event_name == 'workflow_dispatch' && github.repository_owner == 'vuetifyjs' }}\n    environment: preview\n    permissions:\n      contents: read\n      id-token: write\n      pull-requests: write\n    steps:\n      - uses: actions/checkout@v4\n      - uses: actions/github-script@v7\n        with:\n          script: |\n            const pr = await github.rest.pulls.get({\n              owner: context.repo.owner,\n              repo: context.repo.repo,\n              pull_number: ${{ github.event.inputs.pr }}\n            })\n            core.exportVariable('CHECKOUT_REPO', pr.data.head.repo.full_name)\n            core.exportVariable('CHECKOUT_REF', pr.data.head.ref)\n            core.exportVariable('SHORT_SHA', pr.data.head.sha.slice(0, 7))\n      - id: nightly-release\n        uses: ./.github/actions/nightly-release\n        with:\n          checkout-repo: ${{ env.CHECKOUT_REPO }}\n          checkout-ref: ${{ env.CHECKOUT_REF }}\n          release-id: pr-${{ github.event.inputs.pr }}.${{ env.SHORT_SHA }}\n          npm-tag: pr\n      - uses: actions/github-script@v7\n        with:\n          script: |\n            const fullVersion = process.env.FULL_VERSION\n            const pr = await github.rest.issues.createComment({\n              owner: context.repo.owner,\n              repo: context.repo.repo,\n              issue_number: ${{ github.event.inputs.pr }},\n              body: `:rocket: Nightly release published to [@vuetify/nightly@${fullVersion}](https://www.npmjs.com/package/@vuetify/nightly/v/${fullVersion}).`\n            })\n        env:\n          FULL_VERSION: ${{ steps.nightly-release.outputs.full-version }}\n\n  vizzly:\n    name: Visual regression tests\n    runs-on: ubuntu-24.04\n    if: ${{ github.event_name == 'schedule' && github.repository_owner == 'vuetifyjs' }}\n    steps:\n      - uses: actions/checkout@v4\n        with:\n          ref: master\n          fetch-depth: 0\n      - run: |\n          last=$(git show -s --format=%ct HEAD)\n          now=$(date +%s)\n          diff=$(($now - $last))\n          if [ $diff -gt 86400 ]; then\n              echo \"Last commit was more than 24 hours ago, skipping tests\"\n              exit 1\n          fi\n      - uses: vuetifyjs/setup-action@master\n      - run: pnpm exec playwright install chromium\n      - run: pnpm vizzly run \"pnpm test:browser\"\n        working-directory: ./packages/vuetify\n        env:\n          VIZZLY_TOKEN: ${{ secrets.VIZZLY_TOKEN }}\n          TEST_TDD_ONLY: 1\n"
  },
  {
    "path": ".github/workflows/stale.yml",
    "content": "name: 'Close stale issues'\non:\n  workflow_dispatch:\n  schedule:\n    - cron: '08 11 * * *'\n\njobs:\n  stale:\n    runs-on: ubuntu-24.04\n    steps:\n      - uses: actions/stale@v9\n        with:\n          days-before-stale: 180\n          days-before-close: 14\n          only-labels: 'S: triage'\n          stale-issue-label: 'S: stale'\n          stale-pr-label: 'S: stale'\n          exempt-all-milestones: true\n          exempt-draft-pr: true\n"
  },
  {
    "path": ".github/workflows/triage.yml",
    "content": "name: Issue triage\non:\n  issues:\n    types: [opened, labeled, unlabeled, closed]\n\njobs:\n  triage:\n    runs-on: ubuntu-24.04\n    steps:\n      - uses: actions/checkout@v4\n      - uses: vuetifyjs/triage-action@master\n        with:\n          token: ${{ secrets.GITHUB_TOKEN }}\n          triageLabel: 'S: triage'\n          staleLabel: 'S: stale'\n          sponsorsFile: '.github/sponsors.yml'\n          duplicateLabel: 'duplicate'\n          triagedLabels: |-\n            T: documentation\n            T: bug\n            T: enhancement\n            T: feature\n            T: question\n            Epic\n            Task\n            duplicate\n            layer 8 issue\n            invalid\n            wontfix\n            working as intended\n"
  },
  {
    "path": ".gitignore",
    "content": ".DS_Store\nnode_modules/\n.env\n.knit\nknit.lock\n\n# IDE user config\n.vscode/\n.idea/\n.vs/\n\n# Logs\nyarn-error.log\nnpm-debug.log\nlerna-debug.log\n\n# Istanbul coverage\ncoverage/\n\n# cypress\ncypress/screenshots\ncypress/videos\n\n# vitest\n__screenshots__/\n\n.vercel\n.now\n"
  },
  {
    "path": ".husky/commit-msg",
    "content": "node scripts/lint-commit-message.js $1\n"
  },
  {
    "path": ".husky/pre-commit",
    "content": "node scripts/warn-npm-install.js\n"
  },
  {
    "path": ".husky/prepare-commit-msg",
    "content": "node scripts/prepare-commit-message.js $1 $2\n"
  },
  {
    "path": ".nvmrc",
    "content": "24.11.1\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.\n\n## Our Standards\n\nExamples of behavior that contributes to creating a positive environment include:\n\n* Using welcoming and inclusive language\n* Being respectful of differing viewpoints and experiences\n* Gracefully accepting constructive criticism\n* Focusing on what is best for the community\n* Showing empathy towards other community members\n\nExamples of unacceptable behavior by participants include:\n\n* The use of sexualized language or imagery and unwelcome sexual attention or advances\n* Trolling, insulting/derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or electronic address, without explicit permission\n* Other conduct which could reasonably be considered inappropriate in a professional setting\n\n## Our Responsibilities\n\nProject maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.\n\nProject maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.\n\n## Scope\n\nThis Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at hello@vuetifyjs.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.\n\nProject maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [https://contributor-covenant.org/version/1/4][version]\n\n[homepage]: https://contributor-covenant.org\n[version]: https://contributor-covenant.org/version/1/4/\n"
  },
  {
    "path": "Dockerfile",
    "content": "FROM caddy:2.10.2-alpine\nCOPY ./packages/docs/dist /srv\nCOPY ./packages/docs/build/Caddyfile /etc/caddy/Caddyfile\n"
  },
  {
    "path": "SECURITY.md",
    "content": "# Security Disclosure Procedures\n\nThis document outlines security procedures and general policies for the Vuetify project.\n\n  * [Reporting a Bug](#reporting-a-bug)\n  * [Disclosure Policy](#disclosure-policy)\n  * [Comments on this Policy](#comments-on-this-policy)\n\n## Reporting a Bug\n\nThe Vuetify team and community take all security bugs in Vuetify seriously. We appreciate your efforts and responsible disclosure and will make every effort to acknowledge your contributions.\n\nTo report a security issue, email [security@vuetifyjs.com](mailto:security@vuetifyjs.com?subject=SECURITY) and include the word **\"SECURITY\"** in the subject line.\n\nThe Vuetify team will send a response indicating the next steps in handling your report. After the initial reply to your report, the security team will keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance.\n\nReport security bugs in third-party modules to the person or team maintaining the module. You can also report a vulnerability through the [Node Security Project](https://nodesecurity.io/report).\n\n## Disclosure Policy\n\nWhen the security team receives a security bug report, they will assign it to a\nprimary handler. This person will coordinate the fix and release process,\ninvolving the following steps:\n\n  * Confirm the problem and determine the affected versions.\n  * Audit code to find any potential similar problems.\n  * Prepare fixes for all releases still under maintenance. These fixes will be released as fast as possible to npm.\n\n## Comments on this Policy\n\nIf you have suggestions on how this process could be improved please submit a pull request using the [issue creator](https://issues.vuetifyjs.com).\n"
  },
  {
    "path": "crowdin.yml",
    "content": "project_id_env: CROWDIN_PROJECT_ID\napi_token_env: CROWDIN_PERSONAL_TOKEN\nproject_identifier: vuetify\npreserve_hierarchy: true\nfiles:\n  - source: packages/api-generator/src/locale/en/**/*.json\n    translation: packages/api-generator/src/locale/%locale%/**/%original_file_name%\n  - source: packages/docs/src/pages/en/**/*.md\n    translation: packages/docs/src/pages/%locale%/**/%original_file_name%\n  - source: packages/docs/src/i18n/messages/en.json\n    translation: packages/docs/src/i18n/messages/%locale%.json\n"
  },
  {
    "path": "docker-compose.yml",
    "content": "services:\n  docs:\n    image: caddy:alpine\n    ports:\n      - ${PORT:-8095}:80\n    volumes:\n      - ./packages/docs/dist:/srv\n      - ./packages/docs/build/Caddyfile:/etc/caddy/Caddyfile\n"
  },
  {
    "path": "eslint-local-rules.cjs",
    "content": "'use strict'\n\nconst path = require('node:path')\nconst glob = require('glob')\n\nmodule.exports = Object.fromEntries(\n  glob.sync('./scripts/rules/*', { cwd: __dirname, dotRelative: true }).map(name => {\n    const modulePath = path.resolve(__dirname, name)\n    const module = require(modulePath)\n    return [path.parse(name).name, module.default || module]\n  })\n)\n"
  },
  {
    "path": "jest.config.cjs",
    "content": "module.exports = {\n  verbose: false,\n  testEnvironment: 'jsdom',\n  testEnvironmentOptions: {\n    customExportConditions: ['node', 'node-addons'],\n  },\n  roots: [\n    '<rootDir>/src',\n  ],\n  setupFilesAfterEnv: [\n    '<rootDir>/test/index.ts',\n  ],\n  moduleFileExtensions: [\n    'tsx',\n    'ts',\n    'js',\n  ],\n  moduleDirectories: [\n    'node_modules',\n  ],\n  moduleNameMapper: {\n    '^@/test$': '<rootDir>/test/index.js',\n    '^@/test/(.*)$': '<rootDir>/test/$1',\n    '^@/(.*)$': '<rootDir>/src/$1',\n    '\\\\.(css|sass|scss)$': 'identity-obj-proxy',\n  },\n  transform: {\n    '.*\\\\.(j|t)sx?$': 'babel-jest',\n  },\n  collectCoverageFrom: [\n    'src/**/*.{js,ts,tsx}',\n    '!**/*.d.ts',\n  ],\n  transformIgnorePatterns: [\n    'node_modules/(?!vue-router)',\n  ],\n  snapshotSerializers: [\n    'jest-serializer-html',\n  ],\n  testMatch: [\n    // Default\n    '**/test/**/*.js',\n    '**/__tests__/**/*.spec.js',\n    '**/__tests__/**/*.spec.ts',\n    '**/__tests__/**/*.spec.tsx',\n  ],\n}\n"
  },
  {
    "path": "lerna.json",
    "content": "{\n  \"command\": {\n    \"publish\": {\n      \"allowBranch\": [\n        \"master\",\n        \"dev\",\n        \"next\"\n      ],\n      \"message\": \"chore(release): publish %s\"\n    },\n    \"version\": {\n      \"push\": true\n    }\n  },\n  \"npmClient\": \"pnpm\",\n  \"version\": \"4.0.3\"\n}\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"@vuetify/vuetify-root\",\n  \"type\": \"module\",\n  \"private\": true,\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/vuetifyjs/vuetify.git\"\n  },\n  \"scripts\": {\n    \"dev\": \"node scripts/dev.js\",\n    \"build\": \"node scripts/build.js\",\n    \"lint\": \"pnpm run -r --parallel --stream lint\",\n    \"lint:fix\": \"pnpm run -r --parallel lint:fix\",\n    \"version\": \"node scripts/confirm-npm-tag.js\",\n    \"prepare\": \"husky; node scripts/post-install.js; $CI || pnpm exec playwright install chromium\",\n    \"postversion\": \"node scripts/post-release-merge.js\",\n    \"clean\": \"pnpm -r exec rm -r node_modules && rm -r node_modules\",\n    \"changelog\": \"conventional-changelog -u -p vuetify\",\n    \"all-checks\": \"pnpm run -r --stream build && pnpm run lint && pnpm run -r test\",\n    \"vue-ecosystem-ci:build\": \"pnpm --filter vuetify run build\",\n    \"vue-ecosystem-ci:test\": \"pnpm --filter vuetify run lint && pnpm --filter vuetify run test\"\n  },\n  \"engines\": {\n    \"node\": \">=24.11.1\"\n  },\n  \"devDependencies\": {\n    \"@babel/cli\": \"^7.28.3\",\n    \"@babel/core\": \"^7.28.5\",\n    \"@babel/preset-env\": \"^7.28.5\",\n    \"@babel/preset-typescript\": \"^7.28.5\",\n    \"@lerna-lite/cli\": \"^4.9.3\",\n    \"@lerna-lite/version\": \"^4.9.3\",\n    \"@mdi/font\": \"7.4.47\",\n    \"@mdi/js\": \"7.4.47\",\n    \"@mdi/svg\": \"7.4.47\",\n    \"@octokit/core\": \"^6.1.5\",\n    \"@rollup/plugin-terser\": \"^0.4.4\",\n    \"@stylistic/eslint-plugin-ts\": \"^3.1.0\",\n    \"@types/lodash-es\": \"^4.17.12\",\n    \"@types/node\": \"24.10.1\",\n    \"@types/yargs\": \"^17.0.35\",\n    \"@typescript-eslint/eslint-plugin\": \"^8.32.0\",\n    \"@typescript-eslint/parser\": \"^8.32.0\",\n    \"@typescript/native-preview\": \"7.0.0-dev.20250912.1\",\n    \"@unhead/vue\": \"^2.0.19\",\n    \"@vitejs/plugin-vue\": \"^6.0.2\",\n    \"@vue/compiler-sfc\": \"^3.5.25\",\n    \"@vue/language-server\": \"^3.1.5\",\n    \"@vue/runtime-core\": \"^3.5.25\",\n    \"@vue/runtime-dom\": \"^3.5.25\",\n    \"@vuetify/github-releaser\": \"^4.0.3\",\n    \"@vueuse/head\": \"^1.3.1\",\n    \"concurrently\": \"^9.2.1\",\n    \"conventional-changelog-cli\": \"^5.0.0\",\n    \"conventional-changelog-vuetify\": \"^2.0.2\",\n    \"cross-spawn\": \"^7.0.6\",\n    \"eslint\": \"^8.57.0\",\n    \"eslint-config-standard\": \"^17.1.0\",\n    \"eslint-formatter-codeframe\": \"^7.32.2\",\n    \"eslint-plugin-import\": \"^2.32.0\",\n    \"eslint-plugin-local-rules\": \"^2.0.1\",\n    \"eslint-plugin-n\": \"^16.6.2\",\n    \"eslint-plugin-promise\": \"^6.6.0\",\n    \"eslint-plugin-react\": \"^7.37.5\",\n    \"eslint-plugin-sonarjs\": \"^0.25.1\",\n    \"eslint-plugin-vue\": \"^10.6.0\",\n    \"eslint-plugin-vuetify\": \"^2.5.3\",\n    \"glob\": \"^11.1.0\",\n    \"husky\": \"^9.1.7\",\n    \"inquirer\": \"^12.6.0\",\n    \"lodash-es\": \"^4.17.21\",\n    \"magic-string\": \"^0.30.21\",\n    \"mkdirp\": \"^3.0.1\",\n    \"moment\": \"^2.30.1\",\n    \"rimraf\": \"^6.1.2\",\n    \"rollup\": \"^4.53.3\",\n    \"rollup-plugin-dts\": \"^6.2.3\",\n    \"rollup-plugin-sass\": \"^1.15.3\",\n    \"rollup-plugin-sourcemaps\": \"^0.6.3\",\n    \"sass\": \"1.93.3\",\n    \"sass-embedded\": \"1.93.3\",\n    \"semver\": \"^7.7.3\",\n    \"shelljs\": \"^0.10.0\",\n    \"stringify-object\": \"^5.0.0\",\n    \"typescript\": \"~5.8.3\",\n    \"upath\": \"^2.0.1\",\n    \"vite\": \"^7.2.4\",\n    \"vite-plugin-inspect\": \"11.3.3\",\n    \"vue\": \"^3.5.25\",\n    \"vue-eslint-parser\": \"^10.2.0\",\n    \"vue-tsc\": \"^3.1.5\",\n    \"vuetify\": \"workspace:*\",\n    \"yargs\": \"^17.7.2\"\n  },\n  \"packageManager\": \"pnpm@10.26.1\"\n}\n"
  },
  {
    "path": "packages/README.md",
    "content": "<p>These are the packages for the <a href=\"https://vuetifyjs.com\" target=\"_blank\">Vuetify</a> monorepo.</p>\n\n## Packages for the Vuetify\n\n1. **api-generator** - generates api for Vuetify docs and other resources.\n2. **docs** - Vuetify documentation\n3. **vuetify** - main source code for Vuetify\n"
  },
  {
    "path": "packages/api-generator/.gitignore",
    "content": "/dist/\n/lib/\n/src/locale/*\n/templates/tmp/\n!/src/locale/en\n"
  },
  {
    "path": "packages/api-generator/package.json",
    "content": "{\n  \"name\": \"@vuetify/api-generator\",\n  \"type\": \"module\",\n  \"version\": \"4.0.3\",\n  \"private\": true,\n  \"description\": \"\",\n  \"scripts\": {\n    \"build\": \"node src/index.ts\",\n    \"lint\": \"eslint --ext .ts,.json src -f codeframe --max-warnings 0\",\n    \"lint:fix\": \"pnpm lint --fix\"\n  },\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"dependencies\": {\n    \"deepmerge\": \"^4.3.1\",\n    \"piscina\": \"^4.9.2\",\n    \"prettier\": \"^3.6.2\",\n    \"ts-morph\": \"^25.0.1\",\n    \"vue\": \"^3.5.25\",\n    \"vuetify\": \"workspace:*\"\n  },\n  \"devDependencies\": {\n    \"@types/stringify-object\": \"^4.0.5\",\n    \"eslint\": \"^8.57.0\",\n    \"stringify-object\": \"^5.0.0\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/helpers/sass.ts",
    "content": "import fs from 'node:fs'\n\nfunction processVariableFile (filePath: string, tagUse: string | string[]) {\n  if (fs.existsSync(filePath)) {\n    const varFile = fs.readFileSync(filePath, 'utf8')\n    const vars = varFile.replace(/\\/\\/.+[\\r\\n]+/g, '').split(/;[\\n]*/g)\n    const varValues: Record<string, { default: string, use?: string }> = {}\n    for (const [index, variable] of vars.entries()) {\n      const varArr = variable.split(':')\n      if (varArr.length >= 2 && varArr[0].startsWith('$')) {\n        const varName = varArr.shift()!.trim()\n        const varDefault = (vars[index + 1].startsWith('@'))\n          ? vars[index + 1]\n          : varArr.join(':')\n        varValues[varName] = {\n          default: varDefault.replace('!default', '').trim(),\n          ...{ use: tagUse === 'all' || tagUse?.includes(varName) ? 'vuetify' : 'vuetify/settings' },\n        }\n      }\n    }\n    return varValues\n  }\n\n  return {}\n}\n\nexport const parseSassVariables = (componentName: string) => {\n  const rootDir = './../vuetify/src/components'\n  return processVariableFile(`${rootDir}/${componentName}/_variables.scss`, '')\n}\n\nexport function parseGlobalSassVariables () {\n  return {\n    ...processVariableFile(`./../vuetify/src/styles/settings/_variables.scss`, ['$reset', '$color-pack', '$utilities']),\n    ...processVariableFile(`./../vuetify/src/styles/settings/_colors.scss`, 'all'),\n    ...processVariableFile(`./../vuetify/src/styles/settings/_elevations.scss`, []),\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/helpers/text.ts",
    "content": "import { capitalize } from 'lodash-es'\n\nexport { camelCase, capitalize } from 'lodash-es'\n\nexport const kebabCase = (str: string) => {\n  let kebab = ''\n  for (let i = 0; i < str.length; i++) {\n    const charCode = str.charCodeAt(i)\n    if (charCode >= 65 && charCode <= 90) {\n      kebab += `${i > 0 ? '-' : ''}${str[i].toLowerCase()}`\n    } else {\n      kebab += str[i]\n    }\n  }\n  return kebab\n}\n\nexport const pascalize = (str: string) => str.split('-').map(capitalize).join('')\n"
  },
  {
    "path": "packages/api-generator/src/index.ts",
    "content": "import fs from 'node:fs/promises'\nimport path from 'upath'\nimport { components } from 'vuetify/dist/vuetify-labs.js'\nimport importMap from 'vuetify/dist/json/importMap.json' with { type: 'json' }\nimport importMapLabs from 'vuetify/dist/json/importMap-labs.json' with { type: 'json' }\nimport { kebabCase } from './helpers/text.ts'\nimport type { ComponentData, DirectiveData } from './types.ts'\nimport { generateComposableDataFromTypes, generateDirectiveDataFromTypes } from './types.ts'\nimport Piscina from 'piscina'\nimport { addDescriptions, addDirectiveDescriptions, addPropData, reportMissingDescriptions, sortByKey, stringifyProps } from './utils.ts'\nimport * as os from 'os'\nimport { mkdirp } from 'mkdirp'\nimport { createVeturApi } from './vetur.ts'\nimport { rimraf } from 'rimraf'\nimport { createWebTypesApi } from './web-types.ts'\nimport inspector from 'inspector'\nimport yargs from 'yargs'\nimport { parseGlobalSassVariables, parseSassVariables } from './helpers/sass.ts'\n\nconst yar = yargs(process.argv.slice(2))\n  .option('components', {\n    type: 'array',\n  })\n  .option('skip-directives', {\n    type: 'boolean',\n  })\n  .option('skip-composables', {\n    type: 'boolean',\n  })\n\nconst reset = '\\x1b[0m'\nconst red = '\\x1b[31m'\nconst blue = '\\x1b[34m'\n\nconst componentsInfo: Record<string, { from: string }> = {\n  ...importMap.components,\n  ...importMapLabs.components,\n}\n\ntype Truthy<T> = Exclude<T, null | undefined | 0 | '' | false>;\nconst BooleanFilter = <T>(x: T): x is Truthy<T> => Boolean(x)\n\nfunction clamp (v: number, min: number, max: number) {\n  return Math.max(min, Math.floor(Math.min(max, v)))\n}\n\nconst run = async () => {\n  const argv = await yar.argv\n\n  const locales = await fs.readdir('./src/locale', 'utf-8')\n\n  // Components\n  const pool = new Piscina({\n    filename: path.resolve('./src/worker.ts'),\n    niceIncrement: 10,\n    maxThreads: inspector.url()\n      ? 1\n      : clamp(os.freemem() / (1.1 * 1024 ** 3), 1, os.cpus().length / 2),\n  })\n\n  const template = await fs.readFile('./templates/component.d.ts', 'utf-8')\n\n  await rimraf(path.resolve('./dist'))\n  await fs.mkdir(path.resolve('./dist'))\n  await mkdirp('./templates/tmp')\n  for (const component in components) {\n    // await fs.writeFile(`./templates/tmp/${component}.d.ts`, template.replaceAll('__component__', component))\n    await fs.writeFile(`./templates/tmp/${component}.d.ts`,\n      template.replaceAll('__component__', component)\n        .replaceAll('__name__', componentsInfo[component].from)\n    )\n  }\n\n  const outPath = path.resolve('./dist/api')\n  await mkdirp(outPath)\n\n  const componentData = (await Promise.all(\n    Object.entries(components).map(async ([componentName, componentInstance]) => {\n      if (argv.components && !argv.components.includes(componentName)) return null\n\n      const data = await pool.run(componentName)\n      const componentProps = stringifyProps(componentInstance.props)\n      const sources = addPropData(componentName, data, componentProps)\n      await addDescriptions(componentName, data, locales, sources)\n      const sass = sortByKey(parseSassVariables(componentName))\n\n      const component = {\n        displayName: componentName,\n        fileName: componentName,\n        pathName: kebabCase(componentName),\n        ...data,\n        sass,\n      } satisfies ComponentData\n      await fs.writeFile(path.resolve(outPath, `${component.fileName}.json`), JSON.stringify(component, null, 2))\n\n      return component\n    })\n  )).filter(BooleanFilter)\n\n  // globalSass\n  const globalSass = {\n    fileName: 'globals',\n    displayName: 'globals',\n    pathName: 'globals',\n    sass: sortByKey(parseGlobalSassVariables()),\n  }\n  await fs.writeFile(path.resolve(outPath, `globals.json`), JSON.stringify(globalSass, null, 2))\n\n  // Composables\n  if (!argv.skipComposables) {\n    const composables = await Promise.all((await generateComposableDataFromTypes()).map(async composable => {\n      console.log(blue, composable.displayName, reset)\n      await addDescriptions(composable.fileName, composable, locales)\n      return composable\n    }))\n\n    for (const composable of composables) {\n      await fs.writeFile(\n        path.resolve(outPath, `${composable.fileName}.json`),\n        JSON.stringify(composable, null, 2)\n      )\n    }\n  }\n\n  // Directives\n  let directives: DirectiveData[] = []\n  if (!argv.skipDirectives) {\n    directives = await Promise.all((await generateDirectiveDataFromTypes()).map(async data => {\n      console.log(blue, data.fileName, reset)\n      await addDirectiveDescriptions(data.fileName, data, locales)\n\n      return data\n    }))\n\n    for (const directive of directives) {\n      await fs.writeFile(\n        path.resolve(outPath, `${directive.fileName}.json`),\n        JSON.stringify(directive, null, 2)\n      )\n    }\n  }\n\n  reportMissingDescriptions()\n  createVeturApi(componentData)\n  createWebTypesApi(componentData, directives)\n  await fs.mkdir(path.resolve('../vuetify/dist/json'), { recursive: true })\n  await fs.copyFile(path.resolve('./dist/tags.json'), path.resolve('../vuetify/dist/json/tags.json'))\n  await fs.copyFile(path.resolve('./dist/attributes.json'), path.resolve('../vuetify/dist/json/attributes.json'))\n  await fs.copyFile(path.resolve('./dist/web-types.json'), path.resolve('../vuetify/dist/json/web-types.json'))\n  rimraf.sync(path.resolve('./templates/tmp'))\n}\n\nrun()\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/$vuetify.json",
    "content": "{\n  \"functions\": {\n    \"goTo\": \"Scroll to target location, using provided options.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/DataIterator-items.json",
    "content": "{\n  \"props\": {\n    \"itemSelectable\": \"Property on supplied `items` that contains the boolean value indicating if the item is selectable.\",\n    \"itemValue\": \"Property on supplied `items` that contains its value.\",\n    \"returnObject\": \"Changes the selection behavior to return the object directly rather than the value specified with **item-value**.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/DataTable-expand.json",
    "content": "{\n  \"props\": {\n    \"expanded\": \"Array of expanded items. Can be bound to external variable using **v-model:expanded**.\",\n    \"expandOnClick\": \"Expands item when the row is clicked.\",\n    \"showExpand\": \"Shows the expand icon.\"\n  },\n  \"events\": {\n    \"update:expanded\": \"Emits when the **expanded** items are updated.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/DataTable-group.json",
    "content": "{\n  \"props\": {\n    \"groupBy\": \"Defines the grouping of the table items.\",\n    \"pageBy\": \"Controls how pagination counts items.\\n- **item** paginates by individual items,\\n- **auto** paginates by top-level groups and falls back to regular items if **group-by** is empty,\\n- **any** paginates by both items and groups combined\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/DataTable-header.json",
    "content": "{\n  \"props\": {\n    \"headers\": \"An array of objects that each describe a header column.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/DataTable-items.json",
    "content": "{\n  \"props\": {\n    \"itemSelectable\": \"Property on supplied `items` that indicates whether the item is selectable.\",\n    \"itemValue\": \"Property on supplied `items` that contains its value.\",\n    \"returnObject\": \"Changes the selection behavior to return the object directly rather than the value specified with **item-value**.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/DataTable-paginate.json",
    "content": "{\n  \"props\": {\n    \"itemsPerPage\": \"The number of items to display on each page.\",\n    \"page\": \"The current displayed page number (1-indexed).\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/DataTable-select.json",
    "content": "{\n  \"props\": {\n    \"selectStrategy\": \"Defines the strategy of selecting items in the list. Possible values are: 'single' (only one item can be selected at a time), 'page' ('Select all' button will select only items on the current page), 'all' ('Select all' button will select all items in the list).\",\n    \"showSelect\": \"Shows the column with checkboxes for selecting items in the list.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/DataTable-sort.json",
    "content": "{\n  \"props\": {\n    \"customKeySort\": \"Function used on specific keys within the item object. `customSort` is skipped for columns with `customKeySort` specified.\",\n    \"disableSort\": \"Toggles rendering of sort button.\",\n    \"initialSortOrder\": \"Specifies the initial sort order when an unsorted column is clicked.\",\n    \"multiSort\": \"Let user sort by multiple properties/columns.\\n\\n- **key**: (optional) when set to `ctrl`, user is required to hold a keyboard key (Ctrl on PC and Command on Mac)\\n- **mode**: when user selects a new column to sort by, it will be set first (`prepend`) or last (`append`) in the sort priority. Defaults to `append`\\n- **modifier**: (optional) allows user to use both multi-sort modes (`append` and `prepend`) simultaneously\",\n    \"mustSort\": \"Forces sorting on the column(s).\",\n    \"sortBy\": \"Array of column keys and sort orders that determines the sort order of the table.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/DataTable.json",
    "content": "{\n  \"props\": {\n    \"hideDefaultBody\": \"Hides the default body.\",\n    \"hideDefaultHeader\": \"Hides the default header.\",\n    \"hideDefaultFooter\": \"Hides the default footer.\",\n    \"search\": \"Text input used to filter items.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/Select.json",
    "content": "{\n  \"props\": {\n    \"closeText\": \"Text set to the inputs `aria-label` and `title` when input menu is closed.\",\n    \"chips\": \"Changes display of selections to chips.\",\n    \"closableChips\": \"Enables the [closable](/api/v-chip/#props-closable) prop on all [v-chip](/components/chips/) components.\",\n    \"hideSelected\": \"Do not display in the select menu items that are already selected.\",\n    \"itemColor\": \"Sets color of selected items.\",\n    \"listProps\": \"Pass props through to the `v-list` component. Accepts an object with anything from [v-list](/api/v-list/#props) props, camelCase keys are recommended.\",\n    \"menuElevation\": \"Sets the elevation of the dropdown menu.\",\n    \"multiple\": \"Changes select to multiple. Accepts array for value.\",\n    \"noAutoScroll\": \"Prevents the select menu to scroll to the selected item automatically.\",\n    \"openOnClear\": \"Open's the menu whenever the clear icon is clicked.\",\n    \"openText\": \"Text set to the inputs **aria-label** and **title** when input menu is open.\"\n  },\n  \"slots\": {\n    \"menu-header\": \"Defines a header above the items list.\",\n    \"menu-footer\": \"Defines a footer below the items list.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/SelectionControlGroup.json",
    "content": "{\n  \"props\": {\n    \"defaultsTarget\": \"The target component to provide defaults values for.\",\n    \"error\": \"Puts the input in a manual error state.\",\n    \"falseIcon\": \"The icon used when inactive.\",\n    \"id\": \"Sets the DOM id on the component.\",\n    \"inline\": \"Puts children inputs into a row.\",\n    \"multiple\": \"Changes select to multiple. Accepts array for value.\",\n    \"readonly\": \"Puts input in readonly state.\",\n    \"trueIcon\": \"The icon used when active.\",\n    \"type\": \"Provides the default type for children selection controls.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/Slider.json",
    "content": "{\n  \"props\": {\n    \"max\": \"Sets the maximum allowed value.\",\n    \"min\": \"Sets the minimum allowed value.\",\n    \"noKeyboard\": \"**FOR INTERNAL USE ONLY** Ignore keyboard events.\",\n    \"reverse\": \"Reverses the slider direction.\",\n    \"showTicks\": \"Show track ticks. If `true` it shows ticks when using slider. If set to `'always'` it always shows ticks.\",\n    \"step\": \"If greater than 0, sets step interval for ticks.\",\n    \"thumbColor\": \"Sets the thumb and thumb label color.\",\n    \"thumbLabel\": \"Show thumb label. If `true` it shows label when using slider. If set to `'always'` it always shows label. Use `'hover'` to show label when hovering over the thumb.\",\n    \"thumbSize\": \"Controls the size of the thumb label.\",\n    \"ticks\": \"Show track ticks. If `true` it shows ticks when using slider. If set to `'always'` it always shows ticks.\",\n    \"tickSize\": \"Controls the size of **ticks**\",\n    \"trackColor\": \"Sets the track's color\",\n    \"trackFillColor\": \"Sets the track's fill color\",\n    \"trackSize\": \"Sets the track's size (height).\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/Stepper.json",
    "content": "{\n  \"props\": {\n    \"altLabels\": \"Places the labels beneath the step.\",\n    \"editable\": \"Marks step as editable.\",\n    \"hideActions\": \"Hide actions bar (prev and next buttons).\",\n    \"itemProps\": \"Props object that will be applied to each item component. `true` will treat the original object as raw props and pass it directly to the component.\",\n    \"itemTitle\": \"Property on supplied `items` that contains its title.\",\n    \"itemValue\": \"Property on supplied `items` that contains its value.\",\n    \"mobile\": \"Forces the stepper into a mobile state, removing labels from stepper items.\",\n    \"nextText\": \"The text used for the Next button.\",\n    \"prevText\": \"The text used for the Prev button.\",\n    \"nonLinear\": \"Allow user to jump to any step.\"\n  },\n  \"slots\": {\n    \"[`header-item.${string}`]\": \"Slot for customizing header items when using the [items](/api/v-stepper/#props-items) prop.\",\n    \"[`item.${string}`]\": \"Slot for customizing the content for each step.\",\n    \"actions\": \"Slot for customizing [v-stepper-actions](/api/v-stepper-actions/).\",\n    \"header\": \"Slot for customizing the header.\",\n    \"header-item\": \"Slot for customizing all header items.\",\n    \"icon\": \"Slot for customizing all stepper item icons.\",\n    \"next\": \"Slot for customizing the next step functionality\",\n    \"prev\": \"Slot for customizing the prev step functionality\"\n  },\n  \"exposed\": {\n    \"next\": \"Move to the next step.\",\n    \"prev\": \"Move to the prev step.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/StepperItem.json",
    "content": "{\n  \"props\": {\n    \"complete\": \"Marks step as complete.\",\n    \"completeIcon\": \"Icon to display when step is marked as completed.\",\n    \"editable\": \"Marks step as editable.\",\n    \"editIcon\": \"Icon to display when step is editable.\",\n    \"errorIcon\": \"Icon to display when step has an error.\",\n    \"error\": \"Puts the stepper item in a manual error state.\",\n    \"rules\": \"Accepts a mixed array of types `function`, `boolean` and `string`. Functions pass an input value as an argument and must return either `true` / `false` or a `string` containing an error message. The input field will enter an error state if a function returns (or any value in the array contains) `false` or is a `string`.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VAlert.json",
    "content": "{\n  \"props\": {\n    \"border\": \"Adds a colored border to the component.\",\n    \"borderColor\": \"Specifies the color of the border. Only used in combination with **border** prop. Accepts any color value.\",\n    \"closable\": \"Adds a close icon that can hide the alert.\",\n    \"closeIcon\": \"Change the default icon used for **closable** alerts.\",\n    \"closeLabel\": \"Text used for *aria-label* on **closable** alerts. Can also be customized globally in [Internationalization](/customization/internationalization).\",\n    \"height\": \"Sets the height for the component.\",\n    \"maxHeight\": \"Sets the maximum height for the component.\",\n    \"maxWidth\": \"Sets the maximum width for the component.\",\n    \"minHeight\": \"Sets the minimum height for the component.\",\n    \"minWidth\": \"Sets the minimum width for the component.\",\n    \"modelValue\": \"Controls whether the component is visible or hidden.\",\n    \"prominent\": \"Displays a larger vertically centered icon to draw more attention.\",\n    \"tile\": \"Removes the component's border-radius.\",\n    \"type\": \"Create a specialized alert that uses a contextual color and has a pre-defined icon.\",\n    \"width\": \"Sets the width for the component.\"\n  },\n  \"slots\": {\n    \"append\": \"Slot for icon at end of alert.\",\n    \"close\": \"Slot for icon used in **dismissible** prop.\",\n    \"prepend\": \"Slot for icon at beginning of alert.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VApp.json",
    "content": "{\n  \"exposed\": {\n    \"theme\": \"The instance of the injected active theme.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VAppBar.json",
    "content": "{\n  \"props\": {\n    \"collapse\": \"Morphs the component into a collapsed state, reducing its maximum width.\",\n    \"extensionHeight\": \"Designate an explicit height for the `extension` slot.\",\n    \"flat\": \"Removes the component's **box-shadow**.\",\n    \"floating\": \"Applies **display: inline-flex** to the component.\",\n    \"location\": \"Aligns the component towards the top or bottom.\",\n    \"scrollBehavior\": \"Specify an action to take when the scroll position of **scroll-target** reaches **scroll-threshold**. Accepts any combination of hide, inverted, collapse, elevate, and fade-image. Multiple values can be used, separated by a space.\",\n    \"scrollTarget\": \"The element to target for scrolling events. Uses `window` by default.\",\n    \"scrollThreshold\": \"The amount of scroll distance down before **scroll-behavior** activates.\"\n  },\n  \"slots\": {\n    \"extension\": \"Slot positioned directly under the main content of the toolbar. Height of this slot can be set explicitly with the **extension-height** prop.\",\n    \"image\": \"Expects the [`v-img`](/components/images/) component.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VAutocomplete.json",
    "content": "{\n  \"props\": {\n    \"autoSelectFirst\": \"When searching, will always highlight the first option and select it on blur. `exact` will only highlight and select exact matches.\",\n    \"clearOnSelect\": \"Reset the search text when a selection is made while using the **multiple** prop.\",\n    \"itemChildren\": \"This property currently has **no effect**.\",\n    \"items\": \"Can be an array of objects or strings. By default objects should have **title** and **value** properties, and can optionally have a **props** property containing any [VListItem props](/api/v-list-item/#props). Keys to use for these can be changed with the **item-title**, **item-value**, and **item-props** props.\",\n    \"noFilter\": \"Do not apply filtering when searching. Useful when data is being filtered server side.\"\n  },\n  \"slots\": {\n    \"item\": \"Define a custom item appearance. The root element of this slot must be a **v-list-item** with `v-bind=\\\"props\\\"` applied. `props` includes everything required for the default select list behaviour - including title, value, click handlers, virtual scrolling, and anything else that has been added with `item-props`.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VAvatar.json",
    "content": "{\n  \"props\": {\n    \"badge\": \"Wraps the avatar in a [VBadge](/api/v-badge/). When set to `true`, displays a dot badge. Accepts an object of VBadge props for further customization.\"\n  },\n  \"slots\": {\n    \"badge\": \"Slot for custom badge content. When used, the badge **dot** mode is disabled.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VAvatarGroup.json",
    "content": "{\n  \"props\": {\n    \"border\": \"Applies border styles to the child [v-avatar](/components/avatars) components.\",\n    \"gap\": \"Sets the overlap gap between avatars. Negative values cause avatars to overlap.\",\n    \"hoverable\": \"Enables a hover animation on child avatars.\",\n    \"itemProps\": \"Props object that will be applied to each item component. `true` will treat the original object as raw props and pass it directly to the component.\",\n    \"limit\": \"The total number of avatars to display, including the overflow indicator. E.g. a limit of `3` with 5 items renders 2 avatars and a `+3` overflow indicator.\",\n    \"overflowText\": \"Custom text to display in the overflow avatar. Defaults to `+N` where N is the number of hidden items.\",\n    \"reverse\": \"Reverses the stacking order of the avatars.\",\n    \"size\": \"Sets the size of all child avatars.\",\n    \"vertical\": \"Stacks avatars vertically instead of horizontally.\"\n  },\n  \"slots\": {\n    \"prepend\": \"Custom content to be displayed before the avatar list.\",\n    \"append\": \"Custom content to be displayed after the avatar list.\",\n    \"item\": \"Customize each avatar item. Receives `props` and `index`.\",\n    \"overflow\": \"Customize the overflow indicator. Receives the count of hidden items.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VBadge.json",
    "content": "{\n  \"props\": {\n    \"bordered\": \"Applies a **2px** by default and **1.5px** border around the badge when using the **dot** property.\",\n    \"content\": \"Text content to show in the badge.\",\n    \"dot\": \"Reduce the size of the badge and hide its contents.\",\n    \"dotSize\": \"Sets the size of the **dot** variant (includes border when using with **bordered**)\",\n    \"floating\": \"Move the badge further away from the slotted content. Equivalent to an 8px offset.\",\n    \"inline\": \"Display as an inline block instead of absolute position. **location**, **floating**, and **offset** will have no effect.\",\n    \"label\": \"The **aria-label** used for the badge.\",\n    \"max\": \"Sets the maximum number allowed when using the **content** prop with a `number` like value. If the content number exceeds the maximum value, a `+` suffix is added.\",\n    \"offsetX\": \"Offset the badge on the x-axis.\",\n    \"offsetY\": \"Offset the badge on the y-axis.\",\n    \"modelValue\": \"Controls whether the component is visible or hidden.\"\n  },\n  \"slots\": {\n    \"badge\": \"The slot used for the badge's content.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VBanner.json",
    "content": "{\n  \"props\": {\n    \"avatar\": \"Designates a specific src image to pass to the thumbnail.\",\n    \"lines\": \"The amount of visible lines of text before it truncates.\",\n    \"mobile\": \"Applies the mobile banner styles.\",\n    \"sticky\": \"Applies `position: sticky` to the component with `top: 0`. You can find more information on the [MDN documentation for sticky position](https://developer.mozilla.org/en-US/docs/Web/CSS/position).\",\n    \"stacked\": \"Forces the banner actions onto a new line. This is not applicable when the banner has `lines=\\\"one\\\"`.\"\n  },\n  \"slots\": {\n    \"actions\": \"The slot used for the action's content such as a [v-btn](/components/buttons).\",\n    \"prepend\": \"Slot for icon at beginning of banner.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VBottomNavigation.json",
    "content": "{\n  \"props\": {\n    \"grow\": \"Force all [v-btn](/components/buttons) children to take up all available horizontal space.\",\n    \"mode\": \"Changes the orientation and active state styling of the component.\"\n  },\n  \"events\": {\n    \"update:active\": \"Event that is emitted when the active state changes.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VBottomSheet.json",
    "content": "{\n  \"props\": {\n    \"inset\": \"Reduces the sheet content maximum width to 70%.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VBreadcrumbs.json",
    "content": "{\n  \"props\": {\n    \"divider\": \"Specifies the dividing character between items.\"\n  },\n  \"slots\": {\n    \"divider\": \"The slot used for dividers.\",\n    \"prepend\": \"The slot used for prepend content.\",\n    \"title\": \"The slot used to display the title of each breadcrumb.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VBreadcrumbsDivider.json",
    "content": "{\n  \"props\": {\n    \"divider\": \"Specifies the dividing character between items.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VBtn.json",
    "content": "{\n  \"props\": {\n    \"block\": \"Expands the button to 100% of available space.\",\n    \"flat\": \"Removes the button box shadow. This is different than using the 'flat' variant.\",\n    \"icon\": \"Apply a specific icon using the [v-icon](/components/icons/) component. The button will become _round_.\",\n    \"readonly\": \"Puts the button in a readonly state. Cannot be clicked or navigated to by keyboard.\",\n    \"stacked\": \"Displays the button as a flex-column.\",\n    \"spaced\": \"Extends content to the edges to move main content from prepend and append slots.\",\n    \"slim\": \"Reduces padding to 0 8px.\"\n  },\n  \"exposed\": {\n    \"group\": \"Internal representation when used in VBtnToggle.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VBtnGroup.json",
    "content": "{\n  \"props\": {\n    \"direction\": \"Control how children components are arranged - in a row or column.\",\n    \"divided\": \"Add dividers between children [v-btn](/components/buttons) components.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VBtnToggle.json",
    "content": "{\n  \"props\": {\n    \"rounded\": \"Round edge buttons.\",\n    \"tile\": \"Removes the component's border-radius.\"\n  },\n  \"exposed\": {\n    \"next\": \"Activates the next button.\",\n    \"prev\": \"Activates the previous button.\",\n    \"select\": \"Selects a button by index, the second parameter is a boolean to indicate if the button should be selected or not.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VCalendar.json",
    "content": "{\n  \"props\": {\n    \"categories\": \"Specifies what categories to display in the `category` view. This controls the order of the categories as well. If the calendar uses events any categories specified in those events not specified in this value are dynamically rendered in the view unless `category-hide-dynamic` is true.\",\n    \"categoryHideDynamic\": \"Sets whether categories specified in an event should be hidden if it's not defined in `categories`.\",\n    \"categoryShowAll\": \"Set whether the `category` view should show all defined `categories` even if there are no events for a category.\",\n    \"categoryForInvalid\": \"The category to place events in that have invalid categories. A category is invalid when it is not a string. By default events without a category are not displayed until this value is specified.\",\n    \"categoryDays\": \"The number of days to render in the `category` view.\",\n    \"categoryText\": \"If categories is a list of objects, you can use this to determine what property to print out as the category text on the calendar. You can provide a function to do some logic or just define the prop name. It's similar to item-text on v-select\",\n    \"dayFormat\": \"Formats day of the month string that appears in a day to a specified locale\",\n    \"end\": \"The ending date on the calendar (inclusive) in the format of `YYYY-MM-DD`. This may be ignored depending on the `type` of the calendar.\",\n    \"eventCategory\": \"Set property of *event*'s category. Instead of a property a function can be given which takes an event and returns the category.\",\n    \"eventColor\": \"A background color for all events or a function which accepts an event object passed to the calendar to return a color.\",\n    \"eventEnd\": \"Set property of *event*'s end timestamp.\",\n    \"eventHeight\": \"The height of an event in pixels in the `month` view and at the top of the `day` views.\",\n    \"eventMarginBottom\": \"Margin bottom for event\",\n    \"eventMore\": \"Whether the more 'button' is displayed on a calendar with too many events in a given day. It will say something like '5 more' and when clicked generates a `click:more` event.\",\n    \"eventMoreText\": \"The text to display in the more 'button' given the number of hidden events.\",\n    \"eventName\": \"Set property of *event*'s displayed name, or a function which accepts an event object passed to the calendar as the first argument and a flag signalling whether the name is for a timed event (true) or an event over a day.\",\n    \"eventOverlapMode\": \"One of `stack`, `column`, or a custom render function\",\n    \"eventOverlapThreshold\": \"A value in minutes that's used to determine whether two timed events should be placed in column beside each other or should be treated as slightly overlapping events.\",\n    \"eventRipple\": \"Applies the `v-ripple` directive.\",\n    \"events\": \"An array of event objects with a property for a start timestamp and optionally a name and end timestamp. If an end timestamp is not given, the value of start will be used. If no name is given, you must provide an implementation for the `event` slot.\",\n    \"eventStart\": \"Set property of *event*'s start timestamp.\",\n    \"eventTextColor\": \"A text color for all events or a function which accepts an event object passed to the calendar to return a color.\",\n    \"eventTimed\": \"If Dates or milliseconds are used as the start or end timestamp of an event, this prop can be a string to a property on the event that is truthy if the event is a timed event or a function which takes the event and returns a truthy value if the event is a timed event.\",\n    \"firstInterval\": \"The first interval to display in the `day` view. If `intervalMinutes` is set to 60 and this is set to 9 the first time in the view is 9am.\",\n    \"firstTime\": \"The first time to display in the `day` view. If specified, this overwrites any `firstInterval` value specified. This can be the number of minutes since midnight, a string in the format of `HH:mm`, or an object with number properties hour and minute.\",\n    \"hideHeader\": \"If the header at the top of the `day` view should be visible.\",\n    \"intervalCount\": \"The number of intervals to display in the `day` view.\",\n    \"intervalFormat\": \"Formats time of day string that appears in the interval gutter of the `day` and `week` view to specified locale\",\n    \"intervalHeight\": \"The height of an interval in pixels in the `day` view.\",\n    \"intervalWidth\": \"The width of the interval gutter on the left side in the `day` view.\",\n    \"intervalMinutes\": \"The number of minutes the intervals are in the `day` view. A common interval is 60 minutes so the intervals are an hour.\",\n    \"intervalStyle\": \"Returns CSS styling to apply to the interval.\",\n    \"locale\": \"The locale of the calendar.\",\n    \"maxDays\": \"The maximum number of days to display in the custom calendar if an `end` day is not set.\",\n    \"minWeeks\": \"The minimum number of weeks to display in the `month` or `week` view.\",\n    \"monthFormat\": \"Formats month string that appears in a day to specified locale\",\n    \"now\": \"Override the day & time which is considered now. This is in the format of `YYYY-MM-DD hh:mm:ss`. The calendar is styled according to now.\",\n    \"shortIntervals\": \"If true, the intervals in the `day` view will be 9 AM as opposed to 09:00 AM\",\n    \"shortMonths\": \"Whether the short versions of a month should be used (Jan vs January).\",\n    \"shortWeekdays\": \"Whether the short versions of a weekday should be used (Mon vs Monday).\",\n    \"showIntervalLabel\": \"Checks if a given day and time should be displayed in the interval gutter of the `day` view.\",\n    \"showMonthOnFirst\": \"Whether the name of the month should be displayed on the first day of the month.\",\n    \"showWeek\": \"Whether week numbers should be displayed when using the `month` view.\",\n    \"start\": \"The starting date on the calendar (inclusive) in the format of `YYYY-MM-DD`. This may be ignored depending on the `type` of the calendar.\",\n    \"type\": \"A string which is one of `month`, `week`, `day`, `4day`, `custom-weekly`, `custom-daily`, and `category`. The custom types look at the `start` and `end` dates passed to the component as opposed to the `value`.\",\n    \"v-model\": \"Sets the `value` property but also updates it when the link of a day is clicked.\",\n    \"value\": \"A date in the format of `YYYY-MM-DD` which determines what span of time for the calendar.\",\n    \"weekdayFormat\": \"Formats day of the week string that appears in the header to specified locale\"\n  },\n  \"slots\": {\n    \"category\": \"The content placed in a category header for the `category` type. The category variable is null for events with invalid (non-string) categories.\",\n    \"day-body\": \"The content that is placed in a `day` view in the scrollable interval container. The day & time object is passed through this slots scope.\",\n    \"day-header\": \"The content that is placed in a `day` view in the top container. The day & time object is passed through this slots scope.\",\n    \"day-label\": \"The content that is placed in the day of the month space in the `custom-weekly` or `month` view. The day & time object is passed through this slots scope.\",\n    \"day-label-header\": \"The content that is placed in the day of the month space in the `week`, `day`, `4day`, or `custom-daily` view. The day & time object is passed through this slots scope.\",\n    \"day-month\": \"The content that is placed in the month space in the `week` or `month` view. The day & time object is passed through this slots scope.\",\n    \"day\": \"The content that is placed in a `week` or `month` view. The day & time object is passed through this slots scope.\",\n    \"event\": \"The content placed in an event. This ignores the `event-name` prop.\",\n    \"interval\": \"The content that is placed in the interval space in the `day` view. The day & time object is passed through this slots scope.\",\n    \"interval-header\": \"The content that is placed in the interval space in the top left of the `day` view.\"\n  },\n  \"events\": {\n    \"[`${string}:date`]\": \"Any event on the day of the month link. The second argument is the day & time object.\",\n    \"[`${string}:dayCategory`]\": \"Any event on a day in the `category` view. The second argument is the day object.\",\n    \"[`${string}:day`]\": \"Any event on a day. The second argument is the day object.\",\n    \"[`${string}:event`]\": \"Any event on a specific event. The second argument is the day & time object.\",\n    \"[`${string}:interval`]\": \"Any event at a specific interval label in the `day` view. The second argument is the day & time object.\",\n    \"[`${string}:more`]\": \"Any event on the `X more` button on views with too many events in a day. The second argument is the day & time object.\",\n    \"[`${string}:timeCategory`]\": \"Any event at a specific time in the `category` view. The second argument is the day & time object.\",\n    \"[`${string}:time`]\": \"Any event at a specific time in the `day` view. The second argument is the day & time object.\",\n    \"change\": \"The range of days displayed on the calendar changed. This is triggered on initialization. The event passed is an object with start and end date objects.\",\n    \"moved\": \"One of the functions `next`, `prev`, and `move` was called. The event passed is the day object calculated for the movement.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VCard.json",
    "content": "{\n  \"props\": {\n    \"flat\": \"Removes the card's elevation.\",\n    \"hover\": \"Applies **3dp** (level 2) of elevation when hovered (default 1dp). You can find more information on the [elevation page](/styles/elevation).\",\n    \"image\": \"Apply a specific background image to the component.\",\n    \"prependIcon\": \"Prepends a [v-icon](/components/icons/) component to the header.\"\n  },\n  \"slots\": {\n    \"actions\": \"The slot used for the card actions; located at the bottom of the card.\",\n    \"image\": \"The slot used for the card image. This is used with the [image](#props-image) prop.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VCarousel.json",
    "content": "{\n  \"props\": {\n    \"color\": \"Applies a color to the navigation dots - supports utility colors (for example `success` or `purple`) or css color (`#033` or `rgba(255, 0, 0, 0.5)`). Find a list of built-in classes on the [colors page](/styles/colors#material-colors).\",\n    \"continuous\": \"Determines whether carousel is continuous.\",\n    \"cycle\": \"Determines if the carousel should cycle through images.\",\n    \"delimiterIcon\": \"Sets icon for carousel delimiter.\",\n    \"hideDelimiters\": \"Hides the carousel's bottom delimiters.\",\n    \"hideDelimiterBackground\": \"Hides the bottom delimiter background.\",\n    \"interval\": \"The duration between image cycles. Requires the **cycle** prop.\",\n    \"nextIcon\": \"The displayed icon for forcing pagination to the next item.\",\n    \"prevIcon\": \"The displayed icon for forcing pagination to the previous item.\",\n    \"progress\": \"Displays a carousel progress bar. Requires the **cycle** prop and **interval**.\",\n    \"showArrows\": \"Displays arrows for next/previous navigation.\",\n    \"verticalArrows\": \"Displays the navigation arrows vertically instead of horizontally.\",\n    \"verticalDelimiters\": \"Displays carousel delimiters vertically.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VCheckbox.json",
    "content": "{\n  \"props\": {\n    \"falseIcon\": \"The icon used when inactive.\",\n    \"indeterminate\": \"Sets an indeterminate state for the checkbox.\",\n    \"indeterminateIcon\": \"The icon used when in an indeterminate state.\",\n    \"multiple\": \"Changes expected model to an array.\",\n    \"trueIcon\": \"The icon used when active.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VCheckboxBtn.json",
    "content": "{\n  \"props\": {\n    \"indeterminate\": \"Puts the control in an indeterminate state. Used with the [indeterminate-icon](#props-indeterminate-icon) property.\",\n    \"indeterminateIcon\": \"Icon used when the component is in an indeterminate state.\"\n  },\n  \"events\": {\n    \"update:indeterminate\": \"Event that is emitted when the component's indeterminate state changes.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VChip.json",
    "content": "{\n  \"props\": {\n    \"closable\": \"Adds remove button and then a chip can be closed.\",\n    \"closeIcon\": \"Change the default icon used for **close** chips.\",\n    \"closeLabel\": \"Text used for *aria-label* on the close button in **close** chips. Can also be customized globally in [Internationalization](/customization/internationalization).\",\n    \"draggable\": \"Makes the chip draggable.\",\n    \"filter\": \"Displays a selection icon when selected.\",\n    \"filterIcon\": \"Change the default icon used for **filter** chips.\",\n    \"label\": \"Applies a medium size border radius.\",\n    \"pill\": \"Remove `v-avatar` padding.\",\n    \"size\": \"Sets the height, padding and the font size of the component. Accepts only predefined options: **x-small**, **small**, **default**, **large**, and **x-large**.\",\n    \"value\": \"The value used when a child of a [v-chip-group](/components/chip-groups).\"\n  },\n  \"events\": {\n    \"click\": \"Emitted when component is clicked, toggles chip if contained in a chip group - Will trigger component to ripple when clicked unless the `.native` modifier is used.\"\n  },\n  \"slots\": {\n    \"close\": \"Slot for icon used in **close** prop.\",\n    \"filter\": \"Slot for icon used in **filter** prop.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VChipGroup.json",
    "content": "{\n  \"props\": {\n    \"baseColor\": \"Sets the color of component when not focused. Recommended with `color` or `filter` to properly highlight selected items.\",\n    \"centerActive\": \"Forces the selected chip to be centered.\",\n    \"column\": \"Remove horizontal pagination and wrap items as needed.\",\n    \"filter\": \"Applies an checkmark icon in front of every chip for using it like a filter.\",\n    \"nextIcon\": \"Specify the icon to use for the next icon.\",\n    \"prevIcon\": \"Specify the icon to use for the prev icon.\",\n    \"showArrows\": \"Force the display of the pagination arrows.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VCol.json",
    "content": "{\n  \"props\": {\n    \"alignSelf\": \"Deprecated, use **align-self-\\\\*** class. Available options are: **start**, **center**, **end**, **auto**, **baseline** and **stretch**.\",\n    \"cols\": \"Sets the default number of columns the component extends. Available options are: **1 -> 12** and **auto**. It accepts `{n}/{size}` syntax (e.g. 1/5 or 3/24) that overrides grid columns count for size calculation.\",\n    \"lg\": \"Changes the number of columns on large and greater breakpoints.\",\n    \"md\": \"Changes the number of columns on medium and greater breakpoints.\",\n    \"offset\": \"Sets the default offset for the column. Similarly to **cols**, accepts `{n}/{size}` syntax (e.g. 1/5 or 3/24).\",\n    \"offsetLg\": \"Changes the offset of the component on large and greater breakpoints.\",\n    \"offsetMd\": \"Changes the offset of the component on medium and greater breakpoints.\",\n    \"offsetSm\": \"Changes the offset of the component on small and greater breakpoints.\",\n    \"offsetXl\": \"Changes the offset of the component on extra large and greater breakpoints.\",\n    \"offsetXxl\": \"Changes the offset of the component on extra extra large and greater breakpoints.\",\n    \"order\": \"Deprecated, use **order-\\\\*** class\",\n    \"orderLg\": \"Deprecated, use **order-lg-\\\\*** class\",\n    \"orderMd\": \"Deprecated, use **order-md-\\\\*** class\",\n    \"orderSm\": \"Deprecated, use **order-sm-\\\\*** class\",\n    \"orderXl\": \"Deprecated, use **order-xl-\\\\*** class\",\n    \"orderXxl\": \"Deprecated, use **order-xxl-\\\\*** class\",\n    \"sm\": \"Changes the number of columns on small and greater breakpoints.\",\n    \"xl\": \"Changes the number of columns on extra large and greater breakpoints.\",\n    \"xxl\": \"Changes the number of columns on extra extra large and greater breakpoints.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VColorInput.json",
    "content": "{\n  \"props\": {\n    \"hidePip\": \"Hide pip icon\",\n    \"colorPip\": \"Synchronize pip color with current value\",\n    \"pipIcon\": \"The icon used for pip\",\n    \"pipLocation\": \"Move pip icon to a different slot\",\n    \"pipVariant\": \"Variant of the pip control\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VColorPicker.json",
    "content": "{\n  \"props\": {\n    \"canvasHeight\": \"Height of canvas.\",\n    \"dotSize\": \"Changes the size of the selection dot on the canvas.\",\n    \"eyeDropperIcon\": \"Icon used to trigger EyeDropper API.\",\n    \"hideCanvas\": \"Hides canvas.\",\n    \"hideEyeDropper\": \"Hides eyedropper icon.\",\n    \"hideSliders\": \"Hides sliders.\",\n    \"hideInputs\": \"Hides inputs.\",\n    \"mode\": \"The current selected input type. Syncable with `v-model:mode`.\",\n    \"modes\": \"Sets available input types.\",\n    \"readonly\": \"Puts the color picker in a readonly state.\",\n    \"showSwatches\": \"Displays color swatches.\",\n    \"swatches\": \"Sets the available color swatches to select from. 2D array of rows and columns, accepts any color format the picker does.\",\n    \"swatchesMaxHeight\": \"Sets the maximum height of the swatches section.\",\n    \"width\": \"Sets the width of the color picker.\"\n  },\n  \"events\": {\n    \"update:mode\": \"Selected mode.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VCombobox.json",
    "content": "{\n  \"props\": {\n    \"alwaysFilter\": \"When enabled, dropdown list will always show items matching non-empty value within the field. Recommended when the list is meant to show suggestions rather than options to choose from. For optimal UX, should be combined with `:menu-icon=\\\"false\\\"` and `hide-selected`.\",\n    \"autoSelectFirst\": \"When searching, will always highlight the first option and select it on blur. `exact` will only highlight and select exact matches.\",\n    \"clearOnSelect\": \"Reset the search text when a selection is made while using the **multiple** prop.\",\n    \"itemChildren\": \"This property currently has **no effect**.\",\n    \"delimiters\": \"Accepts an array of strings that will trigger a new tag when typing. Does not replace the normal Tab and Enter keys.\",\n    \"items\": \"Can be an array of objects or strings. By default objects should have **title** and **value** properties, and can optionally have a **props** property containing any [VListItem props](/api/v-list-item/#props). Keys to use for these can be changed with the **item-title**, **item-value**, and **item-props** props.\"\n  },\n  \"slots\": {\n    \"item\": \"Define a custom item appearance. The root element of this slot must be a **v-list-item** with `v-bind=\\\"props\\\"` applied. `props` includes everything required for the default select list behaviour - including title, value, click handlers, virtual scrolling, and anything else that has been added with `item-props`.\"\n  },\n  \"exposed\": {\n    \"selectionIndex\": \"The index of the currently selected item.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VCommandPalette.json",
    "content": "{\n  \"props\": {\n    \"closeOnSelect\": \"Controls whether the palette closes automatically after selecting an actionable item. Set to **false** to keep it open for external drill-in and nested navigation flows.\",\n    \"hotkey\": \"Global keyboard shortcut to toggle the palette. Accepts hotkey strings like `'ctrl+shift+p'` or `'meta+j'`. The shortcut is automatically registered on mount and cleaned up on unmount.\",\n    \"inputIcon\": \"Icon to display at the start of the search input field.\",\n    \"items\": \"Array of command palette items. Objects should have **title** and optionally **subtitle**, **prependIcon**, **appendIcon**, **prependAvatar**, **appendAvatar**, **hotkey**, **onClick**, **to**, **href**, and **value** properties. Use `type: 'subheader'` with a **title** for section headers, or `type: 'divider'` for visual separators between groups.\",\n    \"listProps\": \"Pass props through to the `v-list` component. Accepts an object with anything from [v-list](/api/v-list/#props) props, camelCase keys are recommended.\",\n    \"modelValue\": \"Controls the visibility of the command palette dialog. Use `v-model` for two-way binding.\",\n    \"noDataText\": \"Text displayed when no items match the current search query.\",\n    \"placeholder\": \"Placeholder text displayed in the search input.\",\n    \"search\": \"The current search query. Use `v-model:search` to control or monitor the search input value.\"\n  },\n  \"events\": {\n    \"before-select\": \"Emitted before the default auto-close behavior for actionable item selection. The payload includes the selected item, the triggering event, and a **preventDefault** callback. Call **preventDefault()** to keep the palette open.\",\n    \"click:item\": \"Emitted when an item is clicked or activated via Enter key. The payload includes the selected item object and the triggering event (MouseEvent or KeyboardEvent).\",\n    \"update:modelValue\": \"Emitted when the dialog visibility changes.\",\n    \"update:search\": \"Emitted when the search query changes.\"\n  },\n  \"slots\": {\n    \"prepend\": \"Content to render above the search input, inside the command palette card. Useful for headers, breadcrumbs, or instructions.\",\n    \"input\": \"Custom search input field. Replaces the default **v-text-field**. Useful for providing a completely custom search implementation.\",\n    \"input.append-inner\": \"Content appended inside the search input field. Useful for adding icons or buttons within the input.\",\n    \"append\": \"Content to render below the items list, inside the command palette card. Useful for footers, keyboard shortcut hints, or additional actions.\",\n    \"no-data\": \"Custom content to display when no items match the search query. Replaces the default no-data message.\",\n    \"list.prepend\": \"Content to prepend to the list component.\",\n    \"list.subheader\": \"Slot for customizing the rendering of subheader items in the list.\",\n    \"item.prepend\": \"Content to display before each item's title.\",\n    \"item.title\": \"Slot for customizing the title of each item.\",\n    \"item.append\": \"Content to display after each item's title, replaces hotkey (if provided).\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VCommandPaletteItem.json",
    "content": "{\n  \"props\": {\n    \"item\": \"The command palette item data object.\",\n    \"index\": \"The index of the item within the command palette list.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VConfirmEdit.json",
    "content": "{\n  \"props\": {\n    \"modelValue\": \"Represents the committed v-model value\",\n    \"cancelText\": \"Text for the cancel button\",\n    \"okText\": \"Text for the ok button\",\n    \"hideActions\": \"Prevent showing the default actions buttons. Does not affect `<component :is=\\\"actions\\\" />`\",\n    \"disabled\": \"Control the disabled state of action buttons. If not provided, internal logic will be used to determine the disabled state.\"\n  },\n  \"events\": {\n    \"save\": \"The event emitted when the user clicks the Save button\",\n    \"cancel\": \"The event emitted when the user clicks the Cancel button\"\n  },\n  \"exposed\": {\n    \"save\": \"Manually commit the change\",\n    \"cancel\": \"Manually cancel the change\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VContainer.json",
    "content": "{\n  \"props\": {\n    \"fluid\": \"Removes viewport maximum-width size breakpoints.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VCounter.json",
    "content": "{\n  \"props\": {\n    \"active\": \"Determines whether the counter is visible or not.\",\n    \"max\": \"Sets the maximum allowed value.\",\n    \"value\": \"Sets the current counter value.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VDataIterator.json",
    "content": "{\n  \"props\": {\n    \"customFilter\": \"Function to filter items.\",\n    \"expanded\": \"Array of expanded items. Can be bound to external variable using **v-model:expanded**.\",\n    \"groupBy\": \"Configures attributes (and sort order) to group items together.\",\n    \"initialSortOrder\": \"Specifies the initial sort order when an **toggleSort** is called for unsorted property.\",\n    \"itemsPerPage\": \"Changes how many items per page should be visible. Can be bound to external variable using **v-model:itemsPerPage**.. Setting this prop to `-1` will display all items on the page.\",\n    \"itemsLength\": \"The total number of items. Useful when using server-side pagination to correctly compute page counts.\",\n    \"loading\": \"If `true` and no items are provided, then a loading text will be shown.\",\n    \"search\": \"Text input used to filter items.\"\n  },\n  \"slots\": {\n    \"default\": \"The default slot. Use this to render your items.\",\n    \"footer\": \"Defines a footer below the items.\",\n    \"header\": \"Defines a header above the items.\",\n    \"no-data\": \"Defines content for when no items are provided.\"\n  },\n  \"events\": {\n    \"update:currentItems\": \"Emits with the items currently being displayed.\",\n    \"update:expanded\": \"Emits when the **expanded** items are updated.\",\n    \"update:groupBy\": \"Emits when the **group-by** prop is updated.\",\n    \"update:itemsPerPage\": \"Emits when the **items-per-page** prop is updated.\",\n    \"update:options\": \"Emits when pagination related properties (page, itemsPerPage, sortBy, groupBy, search) is updated.\",\n    \"update:page\": \"Emits when the **page** prop is updated.\",\n    \"update:sortBy\": \"Emits when the **sortBy** prop is updated.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VDataTable.json",
    "content": "{\n  \"props\": {\n    \"collapseIcon\": \"Icon to display when the expandable row is expanded.\",\n    \"customFilter\": \"Function to filter items.\",\n    \"density\": \"Adjusts the vertical height of the table rows.\",\n    \"expandIcon\": \"Icon to display when the expandable row is collapsed.\",\n    \"fixedHeader\": \"Fixed header to top of table.\",\n    \"groupBy\": \"Configures attributes (and sort order) to group items together. Can be customized further with `group-header` and `group-summary` slots.\",\n    \"groupCollapseIcon\": \"Icon to display when the row group is expanded.\",\n    \"groupExpandIcon\": \"Icon to display when the row group is collapsed.\",\n    \"headerProps\": \"Pass props to the default header. See [`v-data-table-headers` API](/api/v-data-table-headers) for more information.\",\n    \"headers\": \"An array of objects that each describe a header column.\",\n    \"height\": \"Set an explicit height of table.\",\n    \"hover\": \"Adds a hover effects to a table rows.\",\n    \"itemsPerPage\": \"Changes how many items per page should be visible. Can be bound to external variable using **v-model:itemsPerPage**.. Setting this prop to `-1` will display all items on the page.\",\n    \"page\": \"The current displayed page number (1-indexed).\",\n    \"showSelect\": \"Shows the select checkboxes in both the header and rows (if using default rows).\",\n    \"showExpand\": \"Shows the expand toggle in default rows.\",\n    \"sortBy\": \"Changes which item property (or properties) should be used for sort order. Can be bound to external variable using **v-model:sortBy**..\"\n  },\n  \"slots\": {\n    \"[`header.${string}`]\": \"Slot for custom rendering of a header cell.\",\n    \"[`item.${string}`]\": \"Slot for custom rendering of a row cell.\",\n    \"header.data-table-expand\": \"Slot to replace the default `v-icon` used when expanding header.\",\n    \"body\": \"Slot to replace the default table `<tbody>`.\",\n    \"body.append\": \"Appends elements to the end of the default table `<tbody>`.\",\n    \"body.prepend\": \"Prepends elements to the start of the default table `<tbody>`.\",\n    \"bottom\": \"Slot for custom rendering of a data table footer.\",\n    \"colgroup\": \"Slot to replace the default rendering of the `<colgroup>` element.\",\n    \"footer.prepend\": \"Adds content to the empty space in the footer.\",\n    \"group-header\": \"Slot for custom rendering of a group header.\",\n    \"group-summary\": \"Slot for custom rendering of a group summary.\",\n    \"header.<name>\": \"Slot to customize a specific header column.\",\n    \"header.data-table-select\": \"Slot to replace the default `v-checkbox-btn` in header.\",\n    \"headers\": \"An array of objects that each describe a header column.\",\n    \"item\": \"Slot to replace the default rendering of a row.\",\n    \"item.data-table-select\": \"Slot to replace the default `v-checkbox-btn` used when selecting rows.\",\n    \"item.data-table-expand\": \"Slot to replace the default `v-icon` used when expanding rows.\",\n    \"item.<name>\": \"Slot to customize a specific column.\",\n    \"loading\": \"Defines content for when `loading` is true and no items are provided.\",\n    \"tbody\": \"Slot to replace the default table `<tbody>`.\",\n    \"thead\": \"Slot to replace the default table `<thead>`.\",\n    \"tfoot\": \"Slot to replace the default table `<tfoot>`.\",\n    \"no-data\": \"Defines content for when no items are provided.\",\n    \"top\": \"Slot to add content above the table.\"\n  },\n  \"events\": {\n    \"click:row\": \"Emits when a table row is clicked. This event provides 2 arguments: the first is the native click event, and the second is an object containing the corresponding item for that row. **NOTE:** will not emit when table rows are defined through a slot such as `item` or `body`.\",\n    \"contextmenu:row\": \"Emits when a table row is right-clicked. The item for the row is included. **NOTE:** will not emit when table rows are defined through a slot such as `item` or `body`.\",\n    \"dblclick:row\": \"Emits when a table row is double-clicked. The item for the row is included. **NOTE:** will not emit when table rows are defined through a slot such as `item` or `body`.\",\n    \"update:currentItems\": \"Emits with the items currently being displayed.\",\n    \"update:groupBy\": \"Emits when the **group-by** prop is updated.\",\n    \"update:itemsPerPage\": \"Emits when the **items-per-page** prop is updated.\",\n    \"update:modelValue\": \"Emits when the component's model changes.\",\n    \"update:options\": \"Emits when pagination related properties (page, itemsPerPage, sortBy, groupBy, search) is updated.\",\n    \"update:page\": \"Emits when the **page** prop is updated.\",\n    \"update:sortBy\": \"Emits when the **sortBy** prop is updated.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VDataTableFooter.json",
    "content": "{\n  \"props\": {\n    \"firstIcon\": \"First icon.\",\n    \"firstPageLabel\": \"Label for first page.\",\n    \"itemsPerPageOptions\": \"Array of options to show in the items-per-page dropdown.\",\n    \"itemsPerPageText\": \"Text for items-per-page dropdown.\",\n    \"lastIcon\": \"Last icon.\",\n    \"lastPageLabel\": \"Label for last page.\",\n    \"nextIcon\": \"Next icon.\",\n    \"nextPageLabel\": \"Label for next page.\",\n    \"pageText\": \"Label for page number.\",\n    \"prevIcon\": \"Previous icon.\",\n    \"prevPageLabel\": \"Label for previous page.\",\n    \"showCurrentPage\": \"Show current page number between prev/next icons.\"\n  },\n  \"slots\": {\n    \"prepend\": \"Extra content placed before the default pagination.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VDataTableHeaders.json",
    "content": "{\n  \"props\": {\n    \"color\": \"Applies a color to checkboxes, page size dropdown and sort badges in the table header.\",\n    \"sortIcon\": \"Icon used for unsorted columns. By default it uses either **sortAscIcon** or **sortDescIcon** depending on **initialSortOrder**, but can be customized to show a neutral icon instead.\",\n    \"sortAscIcon\": \"Icon used for ascending sort button.\",\n    \"sortDescIcon\": \"Icon used for descending sort button.\",\n    \"sticky\": \"Deprecated, use `fixed-header` instead.\",\n    \"fixedHeader\": \"Sticks the header to the top of the table.\",\n    \"headerProps\": \"Additional props to be be passed to the default header\"\n  },\n  \"slots\": {\n    \"[`column.${string}`]\": \"Slot for custom rendering of a column.\",\n    \"[`header.${string}`]\": \"Slot for custom rendering of a header cell.\",\n    \"header.data-table-expand\": \"Slot for the expand button in the header.\",\n    \"header.data-table-select\": \"Slot for the select-all checkbox in the header.\",\n    \"headers\": \"Slot to replace the default rendering of the `<thead>` element.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VDataTableRow.json",
    "content": "{\n  \"props\": {\n    \"cellProps\": \"Props to be applied to the cell.\",\n    \"collapseIcon\": \"Icon to display when the expandable row is expanded.\",\n    \"expandIcon\": \"Icon to display when the expandable row is collapsed.\",\n    \"index\": \"Row index.\",\n    \"item\": \"Data (key, index and column values) of the displayed item.\"\n  },\n  \"events\": {\n    \"contextmenu\": \"The event emitted when the user clicks the context menu button.\",\n    \"dblclick\": \"The event emitted when the user double clicks the row.\",\n    \"[`item.${string}`]\": \"The event emitted when the user clicks the item.\"\n  },\n  \"slots\": {\n    \"[`header.${string}`]\": \"Slot for custom rendering of a header cell.\",\n    \"[`item.${string}`]\": \"Slot for custom rendering of a row cell.\",\n    \"header.data-table-expand\": \"Slot to replace the default `v-icon` used when expanding header.\",\n    \"header.data-table-select\": \"Slot to replace the default `v-checkbox-btn` in header.\",\n    \"item.data-table-expand\": \"Slot for the expand button in the row.\",\n    \"item.data-table-select\": \"Slot for the select checkbox in the row.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VDataTableRows.json",
    "content": "{\n  \"props\": {\n    \"cellProps\": \"An object of additional props to be passed to each `<td>` in the table body. Also accepts a function that will be called for each cell. If the same prop is defined both here and in `cellProps` in a headers object, the value from the headers object will be used.\",\n    \"loading\": \"Displays `loading` slot if set to `true`\",\n    \"loadingText\": \"Text shown when the data is loading.\",\n    \"rowProps\": \"An object of additional props to be passed to each `<tr>` in the table body. Also accepts a function that will be called for each row.\"\n  },\n  \"slots\": {\n    \"[`header.${string}`]\": \"Slot for custom rendering of a header cell.\",\n    \"header.data-table-expand\": \"Slot to replace the default `v-icon` used when expanding header.\",\n    \"header.data-table-select\": \"Slot to replace the default `v-checkbox-btn` in header.\",\n    \"[`item.${string}`]\": \"Slot for custom rendering of a column.\",\n    \"data-table-group\": \"Slot for custom rendering of a group.\",\n    \"data-table-select\": \"Slot for custom rendering of a header cell with the select checkbox.\",\n    \"expanded-row\": \"Slot for custom rendering of an expanded row.\",\n    \"group-header\": \"Slot for custom rendering of a group header.\",\n    \"group-summary\": \"Slot for custom rendering of a group summary.\",\n    \"item.data-table-expand\": \"Slot for custom rendering of a row cell with the expand icon.\",\n    \"item.data-table-select\": \"Slot for custom rendering of a row cell with the select checkbox.\",\n    \"loading\": \"Slot for custom rendering of the loading state.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VDataTableServer.json",
    "content": "{\n  \"props\": {\n    \"itemsLength\": \"Number of all items.\",\n    \"headerProps\": \"Pass props to the default header. See [`v-data-table-server` API](/api/v-data-table-server) for more information.\"\n  },\n  \"slots\": {\n    \"[`header.${string}`]\": \"Slot for a specific header. See [`v-data-table-server` API](/api/v-data-table-server) for more information.\",\n    \"[`column.${string}`]\": \"Slot for custom rendering of a column.\",\n    \"[`item.${string}`]\": \"Slot for custom rendering of a row cell.\",\n    \"body\": \"Slot to replace the default rendering of the `<tbody>` element.\",\n    \"body.append\": \"Adds content to the empty space in the body.\",\n    \"body.prepend\": \"Adds content to the empty space in the body.\",\n    \"header.data-table-expand\": \"Slot for the expand button in the header.\",\n    \"header.data-table-select\": \"Slot for the select-all checkbox in the header.\",\n    \"bottom\": \"Slot to add content below the table.\",\n    \"colgroup\": \"Slot to replace the default rendering of the `<colgroup>` element.\",\n    \"data-table-select\": \"Slot for custom rendering of a header cell with the select checkbox.\",\n    \"expanded-row\": \"Slot for custom rendering of an expanded row.\",\n    \"footer.prepend\": \"Adds content to the empty space in the footer.\",\n    \"group-header\": \"Slot for custom rendering of a group header.\",\n    \"group-summary\": \"Slot for custom rendering of a group summary.\",\n    \"headers\": \"Slot to replace the default rendering of the `<thead>` element.\",\n    \"item\": \"Slot to replace the default rendering of a row.\",\n    \"item.data-table-expand\": \"Slot to replace the default `v-icon` used when expanding rows.\",\n    \"item.data-table-select\": \"Slot to replace the default checkbox used when selecting rows.\",\n    \"loading\": \"Defines content for when `loading` is true and no items are provided.\",\n    \"tbody\": \"Slot to replace the default rendering of the `<tbody>` element.\",\n    \"tfoot\": \"Slot to replace the default rendering of the `<tfoot>` element.\",\n    \"thead\": \"Slot to replace the default rendering of the `<thead>` element.\",\n    \"top\": \"Slot to add content above the table.\"\n  },\n  \"events\": {\n    \"click:row\": \"Emits when a table row is clicked. This event provides 2 arguments: the first is the native click event, and the second is an object containing the corresponding item for that row. **NOTE:** will not emit when table rows are defined through a slot such as `item` or `body`.\",\n    \"update:expanded\": \"Emits when the **expanded** prop is updated.\",\n    \"update:groupBy\": \"Emits when the **group-by** prop is updated.\",\n    \"update:itemsPerPage\": \"Emits when the **items-per-page** prop is updated.\",\n    \"update:modelValue\": \"Emits when the component's model changes.\",\n    \"update:options\": \"Emits when pagination related properties (page, itemsPerPage, sortBy, groupBy, search) is updated.\",\n    \"update:page\": \"Emits when the **page** prop is updated.\",\n    \"update:sortBy\": \"Emits when the **sortBy** prop is updated.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VDataTableVirtual.json",
    "content": "{\n  \"props\": {\n    \"headerProps\": \"Pass props to the default header.\",\n    \"itemKey\": \"The property on each item that is used as a unique key.\"\n  },\n  \"slots\": {\n    \"[`header.${string}`]\": \"Slot for a specific header. See [`v-data-table-virtual` API](/api/v-data-table-virtual) for more information.\",\n    \"[`column.${string}`]\": \"Slot for custom rendering of a column.\",\n    \"[`item.${string}`]\": \"Slot for custom rendering of a row cell.\",\n    \"header.data-table-expand\": \"Slot for the expand button in the header.\",\n    \"header.data-table-select\": \"Slot for the select-all checkbox in the header.\",\n    \"body.append\": \"Slot to add content below the table.\",\n    \"body.prepend\": \"Slot to add content above the table.\",\n    \"bottom\": \"Slot to add content below the table.\",\n    \"colgroup\": \"Slot to replace the default rendering of the `<colgroup>` element.\",\n    \"data-table-group\": \"Slot for custom rendering of a group.\",\n    \"data-table-select\": \"Slot for custom rendering of a header cell with the select checkbox.\",\n    \"expanded-row\": \"Slot for custom rendering of an expanded row.\",\n    \"group-header\": \"Slot for custom rendering of a group header.\",\n    \"group-summary\": \"Slot for custom rendering of a group summary.\",\n    \"headers\": \"Slot to replace the default rendering of the `<thead>` element.\",\n    \"item\": \"Slot to replace the default rendering of a row.\",\n    \"item.data-table-expand\": \"Slot to replace the default `v-icon` used when expanding rows.\",\n    \"item.data-table-select\": \"Slot to replace the default checkbox used when selecting rows.\",\n    \"loading\": \"Defines content for when `loading` is true and no items are provided.\",\n    \"tbody\": \"Slot to replace the default table `<tbody>`.\",\n    \"thead\": \"Slot to replace the default table `<thead>`.\",\n    \"tfoot\": \"Slot to replace the default table `<tfoot>`.\",\n    \"top\": \"Slot to add content above the table\"\n  },\n  \"events\": {\n    \"click:row\": \"Emits when a table row is clicked. This event provides 2 arguments: the first is the native click event, and the second is an object containing the corresponding item for that row. **NOTE:** will not emit when table rows are defined through a slot such as `item` or `body`.\",\n    \"update:expanded\": \"Emits when the **expanded** prop is updated.\",\n    \"update:groupBy\": \"Emits when the **group-by** prop is updated.\",\n    \"update:modelValue\": \"Emits when the component's model changes.\",\n    \"update:options\": \"Emits when pagination related properties (page, itemsPerPage, sortBy, groupBy, search) is updated.\",\n    \"update:sortBy\": \"Emits when the **sortBy** prop is updated.\"\n  },\n  \"exposed\": {\n    \"calculateVisibleItems\": \"Trigger updating the currently rendered items based on scroll position.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VDateInput.json",
    "content": "{\n  \"props\": {\n    \"hideActions\": \"Hide the Cancel and OK buttons, and automatically update the value when a date is selected.\",\n    \"displayFormat\": \"The format of the date that is displayed in the input. Can use any format [here](/features/dates/#format-options) or a custom function.\",\n    \"inputFormat\": \"Format for manual date input. Use yyyy, mm, dd with separators '.', '-', '/' (e.g. 'yyyy-mm-dd', 'dd/mm/yyyy').\",\n    \"location\": \"Specifies the date picker's location. Can combine by using a space separated string.\",\n    \"updateOn\": \"Specifies when the text input should update the model value. If empty, the text field will go into read-only state.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VDatePicker.json",
    "content": "{\n  \"props\": {\n    \"allowedDates\": \"Restricts which dates can be selected.\",\n    \"eventColor\": \"Sets the color for event dots. It can be string (all events will have the same color) or `object` where attribute is the event date and value is boolean/color/array of colors for specified date or `function` taking date as a parameter and returning boolean/color/array of colors for that date.\",\n    \"events\": \"Array of dates or object defining events or colors or function returning boolean/color/array of colors.\",\n    \"headerColor\": \"Allows you to set a different color for the header when used in conjunction with the `color` prop.\",\n    \"hideHeader\": \"Hides the header.\",\n    \"hideWeekdays\": \"Hides the weekdays.\",\n    \"landscape\": \"Changes the picker to landscape mode.\",\n    \"landscapeHeaderWidth\": \"Sets header width when in landscape mode.\",\n    \"month\": \"Sets the month.\",\n    \"year\": \"Sets the year.\",\n    \"header\": \"Text shown when no **display-date** is set.\",\n    \"headerDateFormat\": \"Allows you to customize the format of the date selection text that appears in the header of the calendar.\",\n    \"max\": \"Maximum allowed date/month (ISO 8601 format).\",\n    \"min\": \"Minimum allowed date/month (ISO 8601 format).\",\n    \"multiple\": \"Allow the selection of multiple dates. The **range** value selects all dates between two selections.\",\n    \"nextIcon\": \"Sets the icon for next month/year button.\",\n    \"prevIcon\": \"Sets the icon for previous month/year button.\",\n    \"readonly\": \"Makes the picker readonly (doesn't allow to select new date).\",\n    \"showAdjacentMonths\": \"Toggles visibility of days from previous and next months.\",\n    \"showWeek\": \"Toggles visibility of the week numbers in the body of the calendar.\",\n    \"width\": \"Width of the picker.\",\n    \"modeIcon\": \"Icon displayed next to the current month and year, toggles year selection when clicked.\",\n    \"viewMode\": \"Determines which picker in the date or month picker is being displayed. Allowed values: `'month'`, `'months'`, `'year'`.\"\n  },\n  \"events\": {\n    \"update:month\": \"Emitted when the month changes.\",\n    \"update:viewMode\": \"Emitted when the view mode changes.\",\n    \"update:year\": \"Emitted when the year changes.\"\n  },\n  \"slots\": {\n    \"actions\": \"Slot for the actions.\",\n    \"controls\": \"Slot for the controls.\",\n    \"header\": \"Slot for the header.\",\n    \"year\": \"Slot for the year.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VDatePickerControls.json",
    "content": "{\n  \"props\": {\n    \"controlHeight\": \"Sets the height of the controls.\",\n    \"controlVariant\": \"- **docked:** Separate control groups for month and year.\\n- **modal:** Month and year are displayed together, clicking the text opens a month picker, clicking the dropdown arrow opens a year picker. There are also arrow buttons to scroll between months.\",\n    \"modeIcon\": \"Icon used for the mode button.\",\n    \"nextIcon\": \"Icon used for the next button.\",\n    \"noMonthPicker\": \"Only applies to `controlVariant=\\\"modal\\\"`, the month and year picker buttons are combined into one that only opens the year picker.\",\n    \"prevIcon\": \"Icon used for the previous button.\",\n    \"monthText\": \"Text displayed for the current month.\",\n    \"yearText\": \"Text displayed for the current year.\",\n    \"viewMode\": \"Sets the view mode of the date picker.\"\n  },\n  \"events\": {\n    \"click:month\": \"Event fired when clicking on the month.\",\n    \"click:next\": \"Event fired when clicking the next button.\",\n    \"click:prev\": \"Event fired when clicking the previous button.\",\n    \"click:year\": \"Event fired when clicking the date text.\",\n    \"click:prev-year\": \"Event fired when clicking the previous year button.\",\n    \"click:next-year\": \"Event fired when clicking the next year button.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VDatePickerHeader.json",
    "content": "{\n  \"props\": {\n    \"header\": \"Sets the header content.\",\n    \"transition\": \"Sets the transition when the header changes.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VDatePickerMonth.json",
    "content": "{\n  \"props\": {\n    \"allowedDates\": \"Sets the allowed dates of the month.\",\n    \"hideWeekdays\": \"Hide the days of the week letters.\",\n    \"max\": \"Sets the maximum date of the month.\",\n    \"min\": \"Sets the minimum date of the month.\",\n    \"month\": \"Sets the month.\",\n    \"year\": \"Sets the year.\",\n    \"multiple\": \"Sets the multiple of the month.\",\n    \"readonly\": \"Puts the picker in a readonly state.\",\n    \"showAdjacentMonths\": \"Show adjacent months.\",\n    \"showWeek\": \"Show the week number.\",\n    \"transition\": \"The transition used when changing months into the future\",\n    \"reverseTransition\": \"The transition used when changing months into the past\"\n  },\n  \"events\": {\n    \"update:month\": \"Fired when the month changes.\",\n    \"update:year\": \"Fired when the year changes.\"\n  },\n  \"slots\": {\n    \"day\": \"Slot for a day in the month.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VDatePickerMonths.json",
    "content": "{\n  \"props\": {\n    \"min\": \"Sets the minimum selectable date. Months before this date will be disabled.\",\n    \"max\": \"Sets the maximum selectable date. Months after this date will be disabled.\",\n    \"year\": \"Sets the year for the given months.\",\n    \"allowedMonths\": \"Restricts which months can be selected.\"\n  },\n  \"slots\": {\n    \"month\": \"Slot for the month.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VDatePickerYears.json",
    "content": "{\n  \"props\": {\n    \"max\": \"Sets the maximum date of the month.\",\n    \"min\": \"Sets the minimum date of the month.\",\n    \"allowedYears\": \"Restricts which years can be selected.\"\n  },\n  \"slots\": {\n    \"year\": \"Slot for the year.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VDefaultsProvider.json",
    "content": "{\n  \"props\": {\n    \"defaults\": \"Specify new default prop values for components. Keep in mind that this will be merged with previously defined values.\",\n    \"disabled\": \"Turns off all calculations of new default values for improved performance in situations where defaults propagation isn't necessary.\",\n    \"reset\": \"Reset the default values up the nested chain by {n} amount.\",\n    \"root\": \"Force current defaults to match the application root defaults.\",\n    \"scoped\": \"Prevents the ability for default values to be inherited from parent components.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VDialog.json",
    "content": "{\n  \"props\": {\n    \"fullscreen\": \"Changes layout for fullscreen display.\",\n    \"maxWidth\": \"Sets the maximum width for the component.\",\n    \"noClickAnimation\": \"Disables the bounce effect when clicking outside of a `v-dialog`'s content when using the **persistent** prop.\",\n    \"openOnHover\": \"Designates whether component should activate when its activator is hovered.\",\n    \"persistent\": \"Clicking outside of the element or pressing **esc** key will not deactivate it.\",\n    \"scrollable\": \"When set to true, expects a `v-card` and a `v-card-text` component with a designated height. For more information, check out the [scrollable example](/components/dialogs#scrollable).\"\n  },\n  \"exposed\": {\n    \"animateClick\": \"Function invoked when user clicks outside the component and the **persistent** prop is used.\",\n    \"globalTop\": \"Used by activator to determine a components position in the global stack order.\",\n    \"localTop\": \"Used by activator to determine a components position in the local stack order.\",\n    \"updateLocation\": \"Function used for locationStrategy positioning.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VDialogTransition.json",
    "content": "{\n  \"props\": {\n    \"target\": \"Sets the target element for the transition.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VDivider.json",
    "content": "{\n  \"props\": {\n    \"contentOffset\": \"Increases content spacing from the lines. When passed as an array, the second value shifts slot content down (or right in vertical mode).\",\n    \"gradient\": \"Adds fading effect for both sides.\",\n    \"inset\": \"Adds indentation (72px) for **normal** dividers, reduces max height for **vertical**.\",\n    \"length\": \"Sets the dividers length. Default unit is px.\",\n    \"thickness\": \"Sets the dividers thickness. Default unit is px.\",\n    \"variant\": \"Applies `border-style`.\",\n    \"vertical\": \"Displays dividers vertically.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VEmptyState.json",
    "content": "{\n  \"props\": {\n    \"actionText\": \"The text used for the action button.\",\n    \"headline\": \"A large headline often used for 404 pages.\",\n    \"href\": \"The URL the action button links to.\",\n    \"justify\": \"Control the justification of the text.\",\n    \"textWidth\": \"Sets the width of the text container.\",\n    \"to\": \"The URL the action button links to.\",\n    \"size\": \"The size used to control the dimensions of the media element inside the component. Can be specified as a number or a string (e.g., '50%', '100px').\"\n  },\n  \"events\": {\n    \"click:action\": \"Event emitted when the action button is clicked.\"\n  },\n  \"slots\": {\n    \"actions\": \"Slot for the action button.\",\n    \"headline\": \"Slot for the component's headline.\",\n    \"media\": \"Slot for the component's media.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VExpansionPanel.json",
    "content": "{\n  \"props\": {\n    \"disabled\": \"Disables the expansion-panel content.\",\n    \"readonly\": \"Makes the expansion panel content read only.\",\n    \"focusable\": \"Makes the expansion panel content focusable.\",\n    \"value\": \"Controls the opened/closed state of content.\",\n    \"static\": \"Remove title size expansion when selected.\"\n  },\n  \"exposed\": {\n    \"groupItem\": \"The current expansion panel within the group in `<v-expansion-panels>`.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VExpansionPanelTitle.json",
    "content": "{\n  \"props\": {\n    \"collapseIcon\": \"Icon used when the expansion panel is in a collapsable state.\",\n    \"expandIcon\": \"Icon used when the expansion panel is in a expandable state.\",\n    \"hideActions\": \"Hide the expand icon in the content title.\",\n    \"static\": \"Remove title size expansion when selected.\",\n    \"focusable\": \"Makes the expansion panel headers focusable.\",\n    \"readonly\": \"Makes the expansion panel content read only.\"\n  },\n  \"slots\": {\n    \"actions\": \"Slot for the actions.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VExpansionPanels.json",
    "content": "{\n  \"props\": {\n    \"focusable\": \"Makes the expansion-panel headers focusable.\",\n    \"flat\": \"Removes the expansion-panel's elevation and borders.\",\n    \"modelValue\": \"Controls expanded panel(s). Defaults to an empty array when using **multiple** prop. It is recommended to set unique `value` prop for the panels inside, otherwise index is used instead.\",\n    \"readonly\": \"Makes the entire expansion panel read only.\",\n    \"static\": \"Remove title size expansion when selected.\",\n    \"tile\": \"Removes the border-radius.\"\n  },\n  \"exposed\": {\n    \"prev\": \"Open the previous panel from the currently selected panel.\",\n    \"next\": \"Open the next panel from the currently selected panel.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VFab.json",
    "content": "{\n  \"props\": {\n    \"app\": \"If true, attaches to the closest layout and positions according to the value of **location**.\",\n    \"layout\": \"If true, will effect layout dimensions based on size and position.\",\n    \"appear\": \"Used to control the animation of the FAB.\",\n    \"extended\": \"An alternate style for the FAB that expects text.\",\n    \"location\": \"The location of the fab relative to the layout. Only works when using **app**.\",\n    \"offset\": \"Translates the Fab up or down, depending on if location is set to **top** or **bottom**.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VField.json",
    "content": "{\n  \"props\": {\n    \"appendInnerIcon\": \"Creates a [v-icon](/api/v-icon/) component in the **append-inner** slot.\",\n    \"baseColor\": \"Sets the color of the input when it is not focused.\",\n    \"centerAffix\": \"Vertically align **appendInner**, **prependInner**, **clearIcon** and **label** in the center.\",\n    \"clearIcon\": \"The icon used when the **clearable** prop is set to true.\",\n    \"dirty\": \"Manually apply the dirty state styling.\",\n    \"disabled\": \"Removes the ability to click or target the input.\",\n    \"glow\": \"Makes prepend/append icons full opacity when the field is focused and apply color.\",\n    \"error\": \"Puts the input in a manual error state.\",\n    \"flat\": \"Removes box shadow when using a variant with elevation.\",\n    \"iconColor\": \"Sets the color of the prepend/append icons.\",\n    \"id\": \"Sets the DOM id on the component.\",\n    \"labelId\": \"Sets the DOM id on the inner label element. Useful for associating the label with custom input elements.\",\n    \"details\": \"Controls whether the field generates an `aria-describedby` attribute for accessibility.\",\n    \"persistentClear\": \"Always show the clearable icon when the input is dirty (By default it only shows on hover).\",\n    \"prependInnerIcon\": \"Creates a [v-icon](/api/v-icon/) component in the **prepend-inner** slot.\",\n    \"reverse\": \"Reverses the orientation.\",\n    \"singleLine\": \"Label does not move on focus/dirty.\"\n  },\n  \"events\": {\n    \"click:appendInner\": \"Emitted when appended inner icon is clicked.\",\n    \"click:clear\": \"Emitted when clearable icon clicked.\",\n    \"click:prependInner\": \"Emitted when prepended inner icon is clicked.\",\n    \"update:focused\": \"Emitted when the input is focused or blurred\"\n  },\n  \"slots\": {\n    \"append-inner\": \"Slot that is appended to the input.\",\n    \"clear\": \"Slot for custom clear icon (displayed when the **clearable** prop is equal to true).\",\n    \"label\": \"The default slot of the [v-label](/api/v-label/) or [v-field-label](/api/v-field-label/) component.\",\n    \"prepend-inner\": \"Slot that is prepended to the input.\"\n  },\n  \"exposed\": {\n    \"controlRef\": \"Reference to the control element of the field.\",\n    \"fieldIconColor\": \"The color of the icon.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VFieldLabel.json",
    "content": "{\n  \"props\": {\n    \"floating\": \"Elevates the label above the slotted content.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VFileInput.json",
    "content": "{\n  \"props\": {\n    \"chips\": \"Changes display of selections to chips.\",\n    \"counter\": \"Displays the number of selected files.\",\n    \"counterSizeString\": \"The text displayed when using the **counter** and **show-size** props. Can also be customized globally on the [internationalization page](/customization/internationalization).\",\n    \"counterString\": \"The text displayed when using the **counter** prop. Can also be customized globally on the [internationalization page](/customization/internationalization).\",\n    \"hideInput\": \"Display the icon only without the input (file names).\",\n    \"multiple\": \"Adds the **multiple** attribute to the input, allowing multiple file selections.\",\n    \"showSize\": \"Sets the displayed size of selected file(s). When using **true** will default to _1000_ displaying (**kB, MB, GB**) while _1024_ will display (**KiB, MiB, GiB**).\",\n    \"truncateLength\": \"The length of a filename before it is truncated with ellipsis.\"\n  },\n  \"slots\": {\n    \"counter\": \"Slot for the input’s counter text.\",\n    \"selection\": \"Slot for defining a custom appearance for selected item(s). Provides the current **index**, **text** (truncated) and [file](https://developer.mozilla.org/en-US/docs/Web/API/File).\"\n  },\n  \"events\": {\n    \"mousedown:control\": \"Event that is emitted when using mousedown on the main control area.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VFileUpload.json",
    "content": "{\n  \"props\": {\n    \"browseText\": \"Text for the browse button.\",\n    \"dividerText\": \"Text in the divider.\",\n    \"hideBrowse\": \"Hides the browse button.\",\n    \"multiple\": \"Allows multiple files to be uploaded.\",\n    \"scrim\": \"Determines whether an overlay is used when hovering over the component with files. Accepts true/false to enable background, and string to define color.\",\n    \"insetFileList\": \"Renders the file list inside the dropzone container instead of below it.\",\n    \"showSize\": \"Shows the size of the file.\"\n  },\n  \"slots\": {\n    \"browse\": \"Slot for the browse button.\",\n    \"divider\": \"Slot for the divider between icon and the browse button.\",\n    \"icon\": \"Slot for a custom appearance in icon section.\",\n    \"input\": \"Define a custom native input.\",\n    \"single\": \"Slot for customizing the appearance of a single file when using inset file list mode.\"\n  },\n  \"exposed\": {\n    \"controlRef\": \"Reference to the underlying input control element.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VFileUploadDropzone.json",
    "content": "{\n  \"props\": {\n    \"browseText\": \"Text for the browse button.\",\n    \"dividerText\": \"Text in the divider.\",\n    \"error\": \"Puts the dropzone in an error state, changing the border color.\",\n    \"hideBrowse\": \"Hides the browse button.\",\n    \"insetFileList\": \"Renders the file list inside the dropzone container instead of below it.\",\n    \"multiple\": \"Allows multiple files to be uploaded.\",\n    \"scrim\": \"Determines whether an overlay is used when hovering over the component with files. Accepts true/false to enable background, and string to define color.\",\n    \"showSize\": \"Shows the size of the file.\"\n  },\n  \"slots\": {\n    \"browse\": \"Slot for the browse button.\",\n    \"divider\": \"Slot for the divider between icon and the browse button.\",\n    \"icon\": \"Slot to replace the default upload icon.\",\n    \"input\": \"Slot to replace the native file input.\",\n    \"single\": \"Slot for customizing the appearance of a single file when using inset file list mode.\"\n  },\n  \"events\": {\n    \"drop\": \"Emitted when files are dropped onto the dropzone.\",\n    \"click:browse\": \"Emitted when the browse button is clicked.\",\n    \"click:remove\": \"Emitted when a file's remove button is clicked.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VFileUploadItem.json",
    "content": "{\n  \"props\": {\n    \"file\": \"The file object uploaded\",\n    \"fileIcon\": \"The icon prepending each uploaded file. This will be a preview image if the file is an image.\",\n    \"index\": \"The index of the file in the upload list.\",\n    \"showSize\": \"Show the size of the file\"\n  },\n  \"events\": {\n    \"click:remove\": \"Emitted when the remove icon is clicked\"\n  },\n  \"slots\": {\n    \"clear\": \"Slot for the icon button to clear/remove a file\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VFileUploadList.json",
    "content": "{\n  \"props\": {\n    \"files\": \"An array of File objects to display in the list. When used inside a VFileUpload, this is provided automatically via injection.\",\n    \"showSize\": \"Shows the size of each file.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VFooter.json",
    "content": "{\n  \"props\": {\n    \"app\": \"Determines the position of the footer. If true, the footer would be given a fixed position at the bottom of the viewport. If false, the footer is set to the bottom of the page.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VForm.json",
    "content": "{\n  \"events\": {\n    \"submit\": \"Emitted when form is submitted.\",\n    \"update:modelValue\": \"Event emitted when the form's validity changes.\"\n  },\n  \"exposed\": {\n    \"errors\": \"Contains all current form input errors.\",\n    \"isDisabled\": \"Indicates if form is disabled or not.\",\n    \"isReadonly\": \"Indicates if form is readonly or not.\",\n    \"isValid\": \"Indicates if form is valid or not.\",\n    \"isValidating\": \"Indicates if form is currently being validated or not.\",\n    \"items\": \"Array of all registered inputs.\",\n    \"reset\": \"Resets validation of all registered inputs, and clears their values.\",\n    \"resetValidation\": \"Resets validation of all registered inputs without modifying their values.\",\n    \"validate\": \"Validates all registered inputs.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VHotkey.json",
    "content": "{\n  \"props\": {\n    \"keys\": \"String representing keyboard shortcuts to display. Supports multiple formats:\\n- **Single keys:** `\\\"k\\\"`, `\\\"enter\\\"`, `\\\"escape\\\"`\\n- **Key combinations:** `\\\"ctrl+k\\\"`, `\\\"meta+shift+p\\\"`, `\\\"alt+arrowup\\\"`\\n- **Sequential actions:** `\\\"ctrl+k-then-p\\\"` (use dash for 'then' relationships)\\n- **Multiple shortcuts:** `\\\"ctrl+k meta+p\\\"` (space-separated for alternative shortcuts)\\n\\nSupports platform-aware key names like `meta` (becomes Cmd on Mac, Ctrl on PC) and `alt` (becomes Option on Mac).\",\n    \"displayMode\": \"Controls how keyboard keys are visually represented. Affects the entire component's appearance:\\n- **icon:** Uses SVG icons for keys when appropriate (default)\\n- **symbol:** Uses Unicode symbols (⌘, ⌃, ⇧, ⌥) - Allows you to manage presentation of modifier keys with fonts\\n- **text:** Uses full text labels (Command, Control, Shift, Alt) - most accessible and descriptive\",\n    \"keyMap\": \"Custom key mapping object that defines how individual keys should be displayed. Users can import and modify the exported `hotkeyMap` to create custom configurations. Each key maps to a `PlatformKeyConfig` object with:\\n\\n```typescript\\n{\\n  mac?: { symbol?: string, icon?: string, text: string },\\n  default: { symbol?: string, icon?: string, text: string }\\n}\\n```\\n\\n**Usage Example:**\\n```typescript\\nimport { hotkeyMap } from 'vuetify/labs/VHotkey'\\n\\nconst customKeyMap = {\\n  ...hotkeyMap,\\n  'custom-key': {\\n    default: { text: 'Custom', icon: 'custom-icon' },\\n    mac: { text: 'Custom', symbol: '⚡' }\\n  }\\n}\\n```\\n\\nThis enables:\\n- **Custom key definitions:** Add support for application-specific keys\\n- **Localization:** Override text representations for different languages\\n- **Brand customization:** Change how modifier keys appear\\n- **Platform-specific styling:** Different representations for Mac vs other platforms\\n\\nRecommended to set at the application level via component defaults rather than per-instance for consistency.\",\n    \"platform\": \"Controls platform-specific rendering behavior for keyboard shortcuts. Accepts three values:\\n- **`'auto'` (default):** Automatically detects the user's platform based on user agent and renders appropriately\\n- **`'mac'`:** Forces Mac-style rendering (Command symbols, icons, Option key, etc.)\\n- **`'pc'`:** Forces PC-style rendering (Ctrl text, Alt key, etc.)\\n\\nThis is particularly useful for:\\n- **Cross-platform testing:** Verify how shortcuts appear on different platforms\\n- **Design consistency:** Ensure specific platform rendering in demos and prototypes\\n- **Development workflow:** Test platform-specific behaviors without switching devices\\n- **Documentation:** Show platform-specific examples in help content\",\n    \"inline\": \"Optimizes the component for seamless integration within text content and documentation. Applies compact styling with baseline alignment, constrained height (1lh), and responsive typography that inherits from parent text. Ideal for help documentation, tooltips, and instructional content. When using multiple inline hotkeys in the same paragraph, increase line-height to prevent visual overlap on text wrapping.\",\n    \"variant\": \"Controls the visual style and presentation of the hotkey component. Supports standard Vuetify variants plus a special contained variant:\\n\\n**Standard Variants** (apply styling to individual key elements):\\n- **elevated (default):** Raised appearance with shadow, good for standalone hotkey displays\\n- **flat:** Solid background without shadow, clean and minimal\\n- **tonal:** Subtle tinted background without border, balances visibility with restraint\\n- **outlined:** Border-only styling without elevation, lightweight and unobtrusive\\n- **text:** Minimal styling with text color emphasis only, blends with content\\n- **plain:** No background or border, most subtle option\\n\\n**Special Variant** (different visual structure):\\n- **contained:** Follows MDN's nested `<kbd>` pattern - wraps all keys in a single styled container with unstyled nested elements. Creates a cohesive visual unit that clearly groups related keys together. Cannot be combined with standard variants. Ideal for complex key combinations where you want to show the entire sequence as one unit.\",\n    \"disabled\": \"Applies a disabled visual state to the component.\",\n    \"prefix\": \"Text to display before the hotkey.\",\n    \"suffix\": \"Text to display after the hotkey.\"\n  },\n  \"slots\": {\n    \"default\": \"The default Vue slot. Not supported.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VHover.json",
    "content": "{\n  \"props\": {\n    \"disabled\": \"Removes hover functionality.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VIconBtn.json",
    "content": "{\n  \"props\": {\n    \"active\": \"When undefined (default), the component utilizes its default variant, otherwise it will use the activeVariant if active is true, or the baseVariant if active is false.\",\n    \"activeIcon\": \"When active is a boolean, this icon is used when active is true.\",\n    \"activeVariant\": \"When active is a boolean, this variant is used when active is true.\",\n    \"baseVariant\": \"When active is a boolean, this variant is used when active is false.\",\n    \"hideOverlay\": \"Hides overlay from being displayed when active or focused.\",\n    \"iconColor\": \"Explicit color applied to the icon.\",\n    \"loading\": \"Displays circular progress bar in place of the icon.\",\n    \"readonly\": \"Puts the button in a readonly state. Cannot be clicked or navigated to by keyboard.\",\n    \"rotate\": \"The rotation of the icon in degrees.\",\n    \"sizes\": \"An array of tuples that define the button sizes for each named size.\"\n  },\n  \"events\": {\n    \"update:active\": \"Event that is emitted when the active state changes.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VImg.json",
    "content": "{\n  \"props\": {\n    \"absolute\": \"Applies position: absolute to the component.\",\n    \"alt\": \"Alternate text for screen readers. Leave empty for decorative images.\",\n    \"aspectRatio\": \"Calculated as `width/height`, so for a 1920x1080px image this will be `1.7778`. Will be calculated automatically if omitted.\",\n    \"cover\": \"Resizes the background image to cover the entire container.\",\n    \"draggable\": \"Controls the `draggable` behavior of the image. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/draggable).\",\n    \"lazySrc\": \"Something to show while waiting for the main image to load, typically a small base64-encoded thumbnail. Has a slight blur filter applied.  \\nNOTE: This prop has no effect unless either `height` or `aspect-ratio` are provided.\",\n    \"crossorigin\": \"Specify that images should be fetched with CORS enabled [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#crossorigin)\",\n    \"position\": \"Applies [object-position](https://developer.mozilla.org/en-US/docs/Web/CSS/object-position) styles to the image and placeholder elements.\",\n    \"referrerpolicy\": \"Define which referrer is sent when fetching the resource [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#referrerpolicy)\",\n    \"options\": \"Options that are passed to the [Intersection observer](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) constructor.\",\n    \"sizes\": \"For use with `srcset`, see [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-sizes).\",\n    \"src\": \"The image URL. This prop is mandatory.\",\n    \"srcset\": \"A set of alternate images to use based on device size. [Read more...](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-srcset).\",\n    \"transition\": \"The transition to use when switching from `lazy-src` to `src`. Can be one of the [built in](/styles/transitions/) or custom transition.\",\n    \"gradient\": \"The gradient to apply to the image. Only supports [linear-gradient](https://developer.mozilla.org/en-US/docs/Web/CSS/gradient/linear-gradient) syntax, anything else should be done with classes.\",\n    \"imageClass\": \"Applies CSS classes to the inner `<img>` element.\"\n  },\n  \"slots\": {\n    \"placeholder\": \"Display an overlay while the image is loading.\",\n    \"error\": \"Will be shown if the image fails to load, replacing the placeholder slot.\",\n    \"sources\": \"A list of `<source>` elements. If this slot is used v-img will render a `<picture>` instead of `<img>`.\"\n  },\n  \"events\": {\n    \"error\": \"Emitted if the image fails to load.\",\n    \"load\": \"Emitted when the image is loaded.\",\n    \"loadstart\": \"Emitted when the image starts to load.\"\n  },\n  \"exposed\": {\n    \"currentSrc\": \"The current source of the image. This is the image that is currently being displayed. This is useful for determining if the image is loading or not.\",\n    \"image\": \"The image element.\",\n    \"naturalHeight\": \"The natural height of the image.\",\n    \"naturalWidth\": \"The natural width of the image.\",\n    \"state\": \"The current state of the image. This is useful for determining if the image is loading or not.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VInfiniteScroll.json",
    "content": "{\n  \"props\": {\n    \"direction\": \"Specifies if scroller is **vertical** or **horizontal**.\",\n    \"emptyText\": \"Text shown when there is no more content to load.\",\n    \"loadMoreText\": \"Text shown in default load more button, when in manual mode.\",\n    \"margin\": \"Value sent to the intersection observer. Will make the observer trigger earlier, by the margin (px) value supplied.\",\n    \"mode\": \"Specifies if content should load automatically when scrolling (**intersect**) or manually (**manual**).\",\n    \"side\": \"Specifies the side where new content should appear. Either the **start**, **end**, or **both** sides.\"\n  },\n  \"slots\": {\n    \"empty\": \"Shown when load returned status 'empty'.\",\n    \"error\": \"Shown when load returned status 'error'.\",\n    \"load-more\": \"Shown when scrolled to either side of the content, in manual mode.\",\n    \"loading\": \"Shown when content is loading.\"\n  },\n  \"events\": {\n    \"load\": \"Emitted when reaching the start / end threshold, or if triggered when using manual mode.\"\n  },\n  \"exposed\": {\n    \"reset\": \"Resets side status to 'ok' letting it trigger 'load' again. Useful to prevent given side being stuck in 'empty' or 'error' state.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VInput.json",
    "content": "{\n  \"props\": {\n    \"baseColor\": \"Sets the color of the input when it is not focused.\",\n    \"centerAffix\": \"Vertically align **appendInner**, **prependInner**, **clearIcon** and **label** in the center.\",\n    \"direction\": \"Changes the direction of the input.\",\n    \"hideDetails\": \"Hides hint and validation errors. When set to `auto` messages will be rendered only if there's a message (hint, error message, counter value etc) to display.\",\n    \"hideSpinButtons\": \"Hides spin buttons on the input when type is set to `number`.\",\n    \"glow\": \"Makes prepend/append icons full opacity when the input is focused and apply color.\",\n    \"hint\": \"Displays hint text below the input when focused. Force this always open with the [persistent-hint](#props-persistent-hint) property.\",\n    \"iconColor\": \"Sets the color of the prepend/append icons.\",\n    \"id\": \"Sets the DOM id on the component.\",\n    \"indentDetails\": \"Adds / removes inline padding in inputs details. Useful when trying to align different variants of fields and selection controls.\",\n    \"persistentHint\": \"Forces [hint](#props-hint) to always be visible.\",\n    \"prependIcon\": \"Prepends an icon to the component, uses the same syntax as `v-icon`.\"\n  },\n  \"events\": {\n    \"click:append\": \"Emitted when appended icon is clicked.\",\n    \"click:prepend\": \"Emitted when prepended icon is clicked.\"\n  },\n  \"exposed\": {\n    \"errorMessages\": \"An array of error messages that were set by the `setErrors` method.\",\n    \"isValid\": \"Boolean indicating if the input is valid.\",\n    \"reset\": \"Resets the input value.\",\n    \"resetValidation\": \"Resets validation of the input without modifying its value.\",\n    \"validate\": \"Validates the input's value.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VItemGroup.json",
    "content": "{\n  \"props\": {\n    \"selectedClass\": \"Configure the selected CSS class. This class will be available in `v-item` default scoped slot.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VLayout.json",
    "content": "{}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VLayoutItem.json",
    "content": "{\n  \"props\": {\n    \"position\": \"The position of the item.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VLazy.json",
    "content": "{\n  \"props\": {\n    \"options\": \"Options that are passed to the [Intersection observer](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) constructor.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VList.json",
    "content": "{\n  \"props\": {\n    \"activeColor\": \"Deprecated, use `color` instead.\",\n    \"activatable\": \"Designates whether the list items are activatable. Additionally, sets necessary accessibility attributes internally.\",\n    \"disabled\": \"Puts all children inputs into a disabled state.\",\n    \"filterable\": \"**FOR INTERNAL USE ONLY** Prevents list item selection using [space] key and pass it back to the text input. Used internally for VAutocomplete and VCombobox.\",\n    \"itemsRegistration\": \"When set to 'props', skips rendering collapsed items/nodes (for significant performance gains).\",\n    \"lines\": \"Designates a **minimum-height** for all children `v-list-item` components. This prop uses [line-clamp](https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-line-clamp) and is not supported in all browsers.\",\n    \"nav\": \"An alternative styling that reduces `v-list-item` width and rounds the corners. Typically used with **[v-navigation-drawer](/components/navigation-drawers)**.\",\n    \"navigationIndex\": \"Specifies the currently selected navigation index when using `navigationStrategy=\\\"track\\\"`. Can be used with `v-model:navigationIndex` for two-way binding. Items at this index receive visual keyboard focus styling and automatic scrolling. Note: Only works with the `items` prop, not with slotted items.\",\n    \"navigationStrategy\": \"Determines keyboard navigation behavior. **focus** (default) moves DOM focus to items, suitable for traditional lists. **track** provides visual keyboard focus without moving DOM focus, ideal for command palettes and autocomplete where an external element retains focus. When track mode is active, items automatically receive `tabindex=\\\"-1\\\"`, proper `aria-activedescendant` is set on the list container, and keyboard-focused items display focus-visible styling with auto-scrolling.\",\n    \"slim\": \"Reduces horizontal spacing for badges, icons, tooltips, and avatars within slim list items to create a more compact visual representation.\",\n    \"prependGap\": \"Sets the horizontal spacing between prepend slot and the main content within list item. Also affects indent to ensure expected alignment of group children.\",\n    \"indent\": \"Overrides the indent size for nested groups.\",\n    \"collapseIcon\": \"Icon to display when the list item is expanded.\",\n    \"expandIcon\": \"Icon to display when the list item is collapsed.\",\n    \"selectable\": \"Designates whether the list items are selectable. Additionally, sets necessary accessibility attributes internally.\"\n  },\n  \"events\": {\n    \"click:activate\": \"Emitted when the list item is activated.\",\n    \"click:open\": \"Emitted when the list item is opened.\",\n    \"click:select\": \"Emitted when the list item is selected.\",\n    \"update:activated\": \"Emitted when the list item is activated.\",\n    \"update:navigationIndex\": \"Emitted when keyboard navigation occurs in `navigationStrategy=\\\"track\\\"`. The event payload is the new index of the selected item. Automatically skips non-selectable items like dividers and subheaders.\",\n    \"update:opened\": \"Emitted when the list item is opened.\",\n    \"update:selected\": \"Emitted when the list item is selected.\"\n  },\n  \"slots\": {\n    \"item\": \"Slot for rendering custom list items. Receives `{ props }` where `props` contains item data (`title`, `subtitle`, `value`, etc.) plus `index` (the item's position in the list). Use this to completely customize item rendering while still using VList's navigation and selection features.\",\n    \"header\": \"Slot for rendering custom group headers when using nested items. Receives `{ props }` containing the group's header item data plus activator props for expand/collapse functionality.\"\n  },\n  \"exposed\": {\n    \"children\": \"The nested list items within the component.\",\n    \"focus\": \"Focus the list item.\",\n    \"getPath\": \"Get the position of an item within the nested structure.\",\n    \"navigationIndex\": \"A computed ref that returns the current navigation index when using `navigationStrategy=\\\"track\\\"`. Returns -1 when no item is selected or when using `navigationStrategy=\\\"focus\\\"`.\",\n    \"open\": \"Open the list item.\",\n    \"parents\": \"The parent list items within the component.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VListGroup.json",
    "content": "{\n  \"props\": {\n    \"activeColor\": \"Deprecated, use `color` instead.\",\n    \"disabled\": \"Puts all children inputs into a disabled state.\",\n    \"collapseIcon\": \"Icon to display when the list item is expanded.\",\n    \"expandIcon\": \"Icon to display when the list item is collapsed.\",\n    \"prependIcon\": \"Prepends an icon to the component, uses the same syntax as `v-icon`.\",\n    \"rawId\": \"Defines the root element's id attribute in the component. If it is provided, the id attribute will be dynamically generated in the format: \\\"v-list-group--id-[rawId]\\\".\",\n    \"subgroup\": \"Designate the component as nested list group.\",\n    \"value\": \"Expands / Collapse the list-group.\",\n    \"fluid\": \"Removes the left padding assigned for action icons from group items.\"\n  },\n  \"exposed\": {\n    \"isOpen\": \"Returns the current state of the list-group.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VListItem.json",
    "content": "{\n  \"props\": {\n    \"active\": \"Controls the **active** state of the item. This is typically used to highlight the component.\",\n    \"activeColor\": \"Deprecated, use `color` instead.\",\n    \"color\": \"Applies specified color to the control when in an **active** state or **input-value** is **true** - supports utility colors (for example `success` or `purple`) or css color (`#033` or `rgba(255, 0, 0, 0.5)`). Find a list of built-in classes on the [colors page](/styles/colors#material-colors),\",\n    \"title\": \"Generates a `v-list-item-title` component with the supplied value. Note that this overrides the native [`title`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/title) attribute, that must be set with `v-bind:title.attr` instead.\",\n    \"value\": \"The value used for selection. Obtained from [`v-list`](/api/v-list)'s `v-model:selected` when the item is selected.\",\n    \"lines\": \"The line declaration specifies the minimum height of the item and can also be controlled from v-list with the same prop.\",\n    \"nav\": \"Reduces the width v-list-item takes up as well as adding a border radius.\",\n    \"slim\": \"Reduces horizontal spacing for badges, icons, tooltips, and avatars to create a more compact visual representation.\",\n    \"index\": \"The index of the item within the list. Used internally for keyboard navigation and selection.\",\n    \"tabindex\": \"Controls the tabindex of the list item. When set, overrides the default tabindex behavior. Automatically set to -1 by VList when using `navigationStrategy=\\\"track\\\"` to prevent Tab key navigation into items.\"\n  },\n  \"exposed\": {\n    \"activate\": \"Activate the list item.\",\n    \"id\": \"The unique identifier of the list item.\",\n    \"isActivated\": \"Check if the list item is activated.\",\n    \"isGroupActivator\": \"Check if the list item activates a group.\",\n    \"isSelected\": \"Check if the list item is selected.\",\n    \"link\": \"Navigation information if list item functions as a link.\",\n    \"list\": \"The reference to the parent list component.\",\n    \"root\": \"The root nested list component\",\n    \"select\": \"Select this list item.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VListSubheader.json",
    "content": "{\n  \"props\": {\n    \"tag\": \"Specify a custom tag used on the root element.\",\n    \"title\": \"Specify a title text for the component.\",\n    \"inset\": \"Insets the subheader without additional spacing, aligning it flush with the surrounding content.\",\n    \"sticky\": \"Sticks the header to the top of the table.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VLocaleProvider.json",
    "content": "{\n  \"props\": {\n    \"fallbackLocale\": \"Specify a fallback locale to use when a locale is not found.\",\n    \"locale\": \"Specify a locale to use.\",\n    \"rtl\": \"Specify a RTL mode.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VMain.json",
    "content": "{\n  \"props\": {\n    \"scrollable\": \"Specify a custom scrollable function.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VMenu.json",
    "content": "{\n  \"props\": {\n    \"attach\": \"Specifies which DOM element the overlay content should teleport to. Can be a direct element reference, querySelector string, or `true` to disable teleporting. Uses `body` by default. Generally not recommended except as a last resort: the default positioning algorithm should handle most scenarios better than is possible without teleporting, and you may have unexpected behavior if the menu ends up as child of its activator.\",\n    \"id\": \"The unique identifier of the component.\",\n    \"closeOnContentClick\": \"Designates if menu should close when its content is clicked.\",\n    \"closeDelay\": \"Milliseconds to wait before closing component. Only works with the **open-on-hover** prop.\",\n    \"disableInitialFocus\": \"Deprecated, use `capture-focus` instead. Prevents automatic redirect of first `focusin` event. Intended to use on permanently open menus or VSpeedDial.\",\n    \"minWidth\": \"Sets the minimum width for the component. Use `auto` to use the activator width.\",\n    \"openDelay\": \"Milliseconds to wait before opening component. Only works with the **open-on-hover** prop.\",\n    \"openOnClick\": \"Designates whether menu should open on activator click.\",\n    \"openOnHover\": \"Designates whether menu should open on activator hover.\",\n    \"submenu\": \"Opens with right arrow and closes on left instead of up/down. Implies `location=\\\"end\\\"`. Directions are reversed for RTL.\"\n  },\n  \"exposed\": {\n    \"animateClick\": \"Function invoked when user clicks outside.\",\n    \"globalTop\": \"Used by activator to determine a components position in the global stack order.\",\n    \"id\": \"The unique identifier of the component.\",\n    \"localTop\": \"Used by activator to determine a components position in the local stack order.\",\n    \"target\": \"Ref to the current target element.\",\n    \"updateLocation\": \"Function used for locationStrategy positioning.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VMessages.json",
    "content": "{\n  \"props\": {\n    \"active\": \"Determines whether the messages are visible or not.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VNavigationDrawer.json",
    "content": "{\n  \"props\": {\n    \"disableResizeWatcher\": \"Prevents the automatic opening or closing of the drawer when resized, based on whether the device is mobile or desktop.\",\n    \"disableRouteWatcher\": \"Disables opening of navigation drawer when route changes.\",\n    \"expandOnHover\": \"Collapses the drawer to a **rail-variant** until hovering with the mouse.\",\n    \"floating\": \"A floating drawer has no visible container (no border-right).\",\n    \"image\": \"Apply a specific background image to the component.\",\n    \"mobileBreakpoint\": \"Sets the designated mobile breakpoint for the component. This will apply alternate styles for mobile devices such as the `temporary` prop, or activate the `bottom` prop when the breakpoint value is met. Setting the value to `0` will disable this functionality.\",\n    \"permanent\": \"The drawer remains visible regardless of screen size.\",\n    \"rail\": \"Sets the component width to the **rail-width** value.\",\n    \"railWidth\": \"Sets the width for the component when `rail` is enabled.\",\n    \"scrim\": \"Determines whether an overlay is used when a **temporary** drawer is open. Accepts true/false to enable background, and string to define color.\",\n    \"temporary\": \"A temporary drawer sits above its application and uses a scrim (overlay) to darken the background.\",\n    \"touchless\": \"Disable mobile touch functionality.\",\n    \"location\": \"Controls the edge of the screen the drawer is attached to.\",\n    \"sticky\": \"When true, the drawer will remain visible when scrolling past the top of the page.\"\n  },\n  \"slots\": {\n    \"append\": \"A slot at the bottom of the drawer.\",\n    \"image\": \"Used to modify `v-img` properties when using the **src** prop.\",\n    \"prepend\": \"A slot at the top of the drawer\"\n  },\n  \"events\": {\n    \"update:rail\": \"Event that is emitted when the rail model changes.\"\n  },\n  \"exposed\": {\n    \"isStuck\": \"Used to determine if the drawer is stuck to the top of the page.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VNumberInput.json",
    "content": "{\n  \"props\": {\n    \"controlVariant\": \"The color of the control. It defaults to the value of `variant` prop.\",\n    \"decimalSeparator\": \"Expects single character to be used as decimal separator.\",\n    \"hideInput\": \"Hide the input field.\",\n    \"inset\": \"Applies an indentation to the dividers used in the stepper buttons.\",\n    \"max\": \"Specifies the maximum allowable value for the input.\",\n    \"min\": \"Specifies the minimum allowable value for the input.\",\n    \"minFractionDigits\": \"Specifies the minimum fraction digits to be displayed (capped to `precision`). Defaults to `precision` when not explicitly set.\",\n    \"precision\": \"Enforces strict precision. It is expected to be an integer value in range between `0` and `15`, or null for unrestricted.\",\n    \"step\": \"Defines the interval between allowed values when the user increments or decrements the input\",\n    \"type\": \"**IGNORED** underlying input is always of type 'text'\"\n  },\n  \"slots\": {\n    \"decrement\": \"Slot for customizing the decrement button or icon used to decrease the value of the input.\",\n    \"increment\": \"Slot for customizing the increment button or icon used to increase the value of the input.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VOtpInput.json",
    "content": "{\n  \"props\": {\n    \"autofocus\": \"Automatically focuses the first input on page load\",\n    \"divider\": \"Specifies the dividing character between items.\",\n    \"focusAll\": \"Puts all inputs into a focus state when any are focused\",\n    \"length\": \"The OTP field's length.\",\n    \"placeholder\": \"Sets the input’s placeholder text.\",\n    \"masked\": \"Hides the entered characters with bullets, similar to a password input, but makes it possible to also restrict characters to digits with `type=\\\"number\\\"`.\",\n    \"type\": \"Supported types: `text`, `password`, `number`.\"\n  },\n  \"events\": {\n    \"finish\": \"Emitted when the input is filled completely and cursor is blurred.\"\n  },\n  \"exposed\": {\n    \"reset\": \"Reset's the input model to an empty array\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VOverflowBtn.json",
    "content": "{\n  \"props\": {\n    \"editable\": \"Creates an editable button.\",\n    \"overflow\": \"Creates an overflow button.\",\n    \"persistentPlaceholder\": \"Forces label to always be visible.\",\n    \"segmented\": \"Creates a segmented button.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VOverlay-activator.json",
    "content": "{\n  \"props\": {\n    \"activator\": \"Explicitly sets the overlay's activator.\",\n    \"activatorProps\": \"Apply custom properties to the activator.\",\n    \"contentProps\": \"Apply custom properties to the content.\",\n    \"closeOnContentClick\": \"Closes component when you click on its content.\",\n    \"location\": \"Specifies the anchor point for positioning the component, using directional cues to align it either horizontally, vertically, or both..\",\n    \"openOnClick\": \"Activate the component when the activator is clicked.\",\n    \"openOnFocus\": \"Activate the component when the activator is focused.\",\n    \"openOnHover\": \"Activate the component when the activator is hovered.\",\n    \"target\": \"For locationStrategy=\\\"connected\\\", specify an element or array of x,y coordinates that the overlay should position itself relative to. This will be the activator element by default.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VOverlay-location-strategies.json",
    "content": "{\n  \"props\": {\n    \"locationStrategy\": \"A function used to specifies how the component should position relative to its activator.\",\n    \"offset\": \"Increases distance from the target. When passed as a pair of numbers, the second value shifts anchor along the side and away from the target.\",\n    \"stickToTarget\": \"Enables the overlay content to go off-screen when scrolling.\",\n    \"viewportMargin\": \"Sets custom viewport margin for the overlay content\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VOverlay-scroll-strategies.json",
    "content": "{\n  \"props\": {\n    \"scrollStrategy\": \"Strategy used when the component is activate and user scrolls.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VOverlay.json",
    "content": "{\n  \"props\": {\n    \"absolute\": \"Applies **position: absolute** to the content element.\",\n    \"attach\": \"Specifies which DOM element the overlay content should teleport to. Can be a direct element reference, querySelector string, or `true` to disable teleporting. Uses `body` by default.\",\n    \"closeOnBack\": \"Closes the overlay content when the browser's back button is pressed or `$router.back()` is called, cancelling the original navigation. `persistent` overlays will cancel navigation and animate as if they were clicked outside instead of closing.\",\n    \"contained\": \"Limits the size of the component and scrim to its offset parent. Implies `absolute` and `attach`. (Note: The parent element must have position: relative.).\",\n    \"noClickAnimation\": \"Disables the bounce effect when clicking outside of the content element when using the persistent prop.\",\n    \"opacity\": \"Sets the opacity of the scrim element. Only applies if `scrim` is enabled.\",\n    \"persistent\": \"Clicking outside of the element or pressing esc key will not deactivate it.\",\n    \"scrim\": \"Accepts true/false to enable background, and string to define color.\",\n    \"zIndex\": \"The z-index used for the component.\"\n  },\n  \"events\": {\n    \"click:outside\": \"Event that fires when clicking outside an active overlay.\",\n    \"afterLeave\": \"Event that fires after the overlay has finished transitioning out.\",\n    \"afterEnter\": \"Event that fires after the overlay has finished transitioning in.\",\n    \"keydown\": \"Emitted when **any** key is pressed.\"\n  },\n  \"exposed\": {\n    \"activatorEl\": \"Ref to the current activator element.\",\n    \"animateClick\": \"Function invoked when user clicks outside.\",\n    \"contentEl\": \"Ref to the current content element.\",\n    \"globalTop\": \"Used by activator to determine a components position in the global stack order.\",\n    \"localTop\": \"Used by activator to determine a components position in the local stack order.\",\n    \"rootEl\": \"Ref to the root v-overlay element.\",\n    \"scrimEl\": \"Ref to the current scrim element.\",\n    \"target\": \"Ref to the current target element.\",\n    \"updateLocation\": \"Function used for locationStrategy positioning.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VPagination.json",
    "content": "{\n  \"props\": {\n    \"ariaLabel\": \"Label for the root element.\",\n    \"color\": \"Applies specified color to the selected page button - supports utility colors (for example `success` or `purple`) or css color (`#033` or `rgba(255, 0, 0, 0.5)`). Find a list of built-in classes on the [colors page](/styles/colors#material-colors).\",\n    \"currentPageAriaLabel\": \"Label for the currently selected page.\",\n    \"ellipsis\": \"Text to show between page buttons when truncating the list.\",\n    \"firstAriaLabel\": \"Label for the go to first button.\",\n    \"firstIcon\": \"The icon to use for the first button.\",\n    \"lastAriaLabel\": \"Label for the go to last button.\",\n    \"lastIcon\": \"The icon to use for the last button.\",\n    \"length\": \"The number of pages.\",\n    \"nextAriaLabel\": \"Label for the next button.\",\n    \"nextIcon\": \"The icon to use for the next button.\",\n    \"pageAriaLabel\": \"Label for each page button.\",\n    \"prevIcon\": \"The icon to use for the prev button.\",\n    \"previousAriaLabel\": \"Label for the previous button.\",\n    \"showFirstLastPage\": \"Show buttons for going to first and last page.\",\n    \"start\": \"Specify the starting page.\",\n    \"totalVisible\": \"Specify the total visible pagination numbers.\"\n  },\n  \"slots\": {\n    \"first\": \"Define a custom appearance for the first button.\",\n    \"last\": \"Define a custom appearance for the last button.\",\n    \"next\": \"Define a custom appearance for the next button.\",\n    \"prev\": \"Define a custom appearance for the previous button.\"\n  },\n  \"events\": {\n    \"first\": \"Emitted when clicking on go to first button.\",\n    \"last\": \"Emitted when clicking on go to last button.\",\n    \"next\": \"Emitted when clicking on go to next button.\",\n    \"prev\": \"Emitted when clicking on go to previous button.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VParallax.json",
    "content": "{\n  \"props\": {\n    \"scale\": \"The scale of the parallax image.\"\n  },\n  \"slots\": {\n    \"error\": \"Puts the input in a manual error state.\",\n    \"placeholder\": \"Sets the input's placeholder text.\",\n    \"sources\": \"A list of `<source>` elements.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VPicker.json",
    "content": "{\n  \"props\": {\n    \"divided\": \"Adds a divider between the header and controls.\",\n    \"landscape\": \"Puts the picker into landscape mode.\",\n    \"hideHeader\": \"Hide the picker header.\",\n    \"hideTitle\": \"Hide the picker title.\"\n  },\n  \"slots\": {\n    \"actions\": \"Slot for customizing the content in the actions area\",\n    \"header\": \"Slot for the component's header content.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VPie.json",
    "content": "{\n  \"props\": {\n    \"gaugeCut\": \"Allows removing bottom part of the chart to make it into a gauge. Expects angle (0-180).\",\n    \"hoverScale\": \"Enables interactive behavior by reducing segment size until it gets hovered. Expects fraction value (0-0.25).\",\n    \"innerCut\": \"Specifies inner radius for a donut-style chart as a percent (0-100). Without `hide-slice`, inner slice is visible with translucent color matching the item.\",\n    \"items\": \"Data items expected to contain `key`, `title` and `value`.\",\n    \"legend\": \"Controls legend visibility, position and text format.\",\n    \"palette\": \"Defines colors and patterns to be applied based on the data items order. Data items can also define their colors.\",\n    \"rotate\": \"Rotates the chart segments clockwise.\",\n    \"size\": \"Sets the height and width of the chart (excluding title and legend).\",\n    \"tooltip\": \"Controls tooltip visibility, transition, offset from the cursor and formats of title and subtitle.\"\n  },\n  \"slots\": {\n    \"center\": \"Slot used to put custom content in the center of the chart\",\n    \"legend\": \"Slot used to override how legend is being displayed\",\n    \"legend-text\": \"Slot used to customize as text content of single legend item\",\n    \"title\": \"Slot used to customize the title above the chart\",\n    \"tooltip\": \"Slot used to customize tooltip content\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VPieSegment.json",
    "content": "{\n  \"props\": {\n    \"animation\": \"Controls duration and easing of the expand/collapse and hover effect. Defaults to `easeInOutCubic` over 400ms.\",\n    \"color\": \"Sets segment color to be passed straight to CSS style attribute.\",\n    \"gap\": \"Reduces segment size by a specified angle. Recommended to in range (0-10).\",\n    \"hideSlice\": \"Makes inner slice invisible instead of semi-transparent.\",\n    \"innerCut\": \"Sets inner slice size in percent (0-100).\",\n    \"pattern\": \"Decal pattern to put on top of the outer slice.\",\n    \"rotate\": \"Sets segment offset angle.\",\n    \"rounded\": \"Number passed as corner radius relative to 100x100 SVG viewport\",\n    \"value\": \"The value used for calculate segment/arc angle size.\",\n    \"hoverScale\": \"Reduces outer radius until segment is hovered. Expects fraction value (0-0.25)\",\n    \"reveal\": \"Enables and controls duration for initial reveal animation. Easing function is shared with `animation` prop.\"\n  },\n  \"events\": {\n    \"update:active\": \"Emitted when the segment's active (hovered) state changes.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VPieTooltip.json",
    "content": "{\n  \"props\": {\n    \"item\": \"Data item related to hovered segment\",\n    \"titleFormat\": \"Formatter definition or function. When passed as String macros for `[title]` and `[value]` get replaced dynamically.\",\n    \"subtitleFormat\": \"Formatter definition or function. When passed as String macros for `[title]` and `[value]` get replaced dynamically.\",\n    \"target\": \"The coordinates used to position the tooltip.\",\n    \"transition\": \"The transition used when hovering between chart segments\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VProgress.json",
    "content": "{\n  \"props\": {\n    \"absolute\": \"Positions the component absolutely within its parent, centering the progress indicator and placing details without affecting layout.\",\n    \"type\": \"Determines which progress indicator to render.\",\n    \"label\": \"Text displayed alongside the progress indicator and placed in `aria-label`.\",\n    \"detailsPosition\": \"Controls the position of the details (label and value) relative to the progress indicator.\",\n    \"max\": \"Sets the maximum value for the progress indicator.\",\n    \"hideLabel\": \"Hides the label text.\",\n    \"hideValue\": \"Hides the value text.\",\n    \"valueFormat\": \"Formatter for the visible value text and `aria-valuetext`. Use `[value]` and `[max]` as placeholders in strings, or pass a function that receives `{ value, max }` and returns a string.\"\n  },\n  \"slots\": {\n    \"label\": \"Slot for custom label content.\",\n    \"value\": \"Slot for custom value content.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VProgressCircular.json",
    "content": "{\n  \"props\": {\n    \"indeterminate\": \"Constantly animates, use when loading progress is unknown. If set to the string `'disable-shrink'` it will use a simpler animation that does not run on the main thread.\",\n    \"reveal\": \"Animates the progress circle from 0 to its model value when the component mounts.\",\n    \"rounded\": \"Rounds the ends of the progress arc for a softer appearance. When enabled, the progress stroke will have rounded caps instead of square ends.\",\n    \"modelValue\": \"The percentage value for current progress.\",\n    \"rotate\": \"Rotates the circle start point in degrees.\",\n    \"size\": \"Sets the diameter of the circle in pixels.\",\n    \"width\": \"Sets the stroke of the circle in pixels.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VProgressLinear.json",
    "content": "{\n  \"props\": {\n    \"absolute\": \"Applies position: absolute to the component.\",\n    \"active\": \"Reduce the height to 0, hiding component.\",\n    \"bgOpacity\": \"Background opacity, if null it defaults to 0.3 if background color is not specified or 1 otherwise.\",\n    \"bufferColor\": \"Sets the color of the buffer bar.\",\n    \"bufferOpacity\": \"Set the opacity of the buffer bar.\",\n    \"bufferValue\": \"The percentage value for the buffer.\",\n    \"chunkCount\": \"Specifies amount of chunks to divide the bar into.\",\n    \"chunkGap\": \"Defines size of the gap between chunks.\",\n    \"chunkWidth\": \"Defines chunk absolute size. Useful when chunk is narrow.\",\n    \"clickable\": \"Clicking on the progress track will automatically set the value.\",\n    \"indeterminate\": \"Constantly animates, use when loading progress is unknown.\",\n    \"max\": \"Sets the maximum value the progress can reach.\",\n    \"opacity\": \"Set the opacity of the progress bar.\",\n    \"reverse\": \"Displays reversed progress (right to left in LTR mode and left to right in RTL).\",\n    \"roundedBar\": \"Applies a border radius to the progress bar.\",\n    \"stream\": \"An alternative style for portraying loading that works in tandem with **buffer-value**.\",\n    \"striped\": \"Adds a stripe background to the filled portion of the progress component.\"\n  },\n  \"slots\": {\n    \"default\": \"Provides the current value of the component.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VPullToRefresh.json",
    "content": "{\n  \"props\": {\n    \"pullDownThreshold\": \"The distance the user must pull down to trigger a refresh.\"\n  },\n  \"events\": {\n    \"load\": \"Emitted when the user pulls down past the threshold.\"\n  },\n  \"slots\": {\n    \"pullDownPanel\": \"Slot to override the display of the progress indicator after a pull down\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VRadio.json",
    "content": "{\n  \"props\": {\n    \"falseIcon\": \"The icon used when inactive.\",\n    \"trueIcon\": \"The icon used when active.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VRadioGroup.json",
    "content": "{\n  \"props\": {\n    \"inline\": \"Displays radio buttons in row.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VRangeSlider.json",
    "content": "{\n  \"props\": {\n    \"strict\": \"Disallows dragging the ending thumb past the starting thumb and vice versa.\"\n\n  },\n  \"slots\": {\n    \"thumb-label\": \"Slot for the thumb label.\",\n    \"tick-label\": \"Slot for the tick label.\"\n  },\n  \"events\": {\n    \"end\": \"Slider value emitted at the end of slider movement.\",\n    \"start\": \"Slider value emitted at start of slider movement.\"\n  },\n  \"exposed\": {\n    \"focus\": \"Focus the first slider handle\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VRating.json",
    "content": "{\n  \"props\": {\n    \"clearable\": \"Allows for the component to be cleared by clicking on the current value.\",\n    \"emptyIcon\": \"The icon displayed when empty.\",\n    \"fullIcon\": \"The icon displayed when full.\",\n    \"itemLabels\": \"Array of labels to display next to each item..\",\n    \"itemLabelPosition\": \"Position of item labels. Accepts 'top' and 'bottom'.\",\n    \"halfIncrements\": \"Allows the selection of half increments.\",\n    \"hover\": \"Provides visual feedback when hovering over icons.\",\n    \"length\": \"The amount of items to show.\",\n    \"readonly\": \"Removes all hover effects and pointer events.\",\n    \"itemAriaLabel\": \"The **aria-label** used for each item.\"\n  },\n  \"slots\": {\n    \"item\": \"The slot for each item.\",\n    \"item-label\": \"The slot for each item label.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VResponsive.json",
    "content": "{\n  \"props\": {\n    \"aspectRatio\": \"Sets a base aspect ratio, calculated as width/height. This will only set a **minimum** height, the component can still grow if it has a lot of content.\",\n    \"contentClass\": \"Apply a custom class to the internal content element.\",\n    \"inline\": \"Display as an inline element instead of a block, also disables flex-grow.\"\n  },\n  \"slots\": {\n    \"additional\": \"The slot for additional content.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VRow.json",
    "content": "{\n  \"props\": {\n    \"align\": \"Deprecated, use **align-\\\\*** class. Available options are: **start**, **center**, **end**, **baseline** and **stretch**.\",\n    \"alignLg\": \"Deprecated, use **align-lg-\\\\*** class\",\n    \"alignMd\": \"Deprecated, use **align-md-\\\\*** class\",\n    \"alignSm\": \"Deprecated, use **align-sm-\\\\*** class\",\n    \"alignXl\": \"Deprecated, use **align-xl-\\\\*** class\",\n    \"alignXxl\": \"Deprecated, use **align-xxl-\\\\*** class\",\n    \"alignContent\": \"Deprecated, use **align-content-\\\\***. Available options are: **start**, **center**, **end**, **space-between**, **space-around** and **stretch**.\",\n    \"alignContentLg\": \"Deprecated, use **align-content-lg-\\\\*** class\",\n    \"alignContentMd\": \"Deprecated, use **align-content-md-\\\\*** class\",\n    \"alignContentSm\": \"Deprecated, use **align-content-sm-\\\\*** class\",\n    \"alignContentXl\": \"Deprecated, use **align-content-xl-\\\\*** class\",\n    \"alignContentXxl\": \"Deprecated, use **align-content-xxl-\\\\*** class\",\n    \"dense\": \"Deprecated, use `density` with **comfortable** instead.\",\n    \"density\": \"Adjusts the spacing between `v-col`s. Available options are: **default**, **comfortable**, **compact**.\",\n    \"justify\": \"Deprecated, use **justify-\\\\***. Available options are: **start**, **center**, **end**, **space-between** and **space-around**.\",\n    \"justifyLg\": \"Deprecated, use **justify-lg-\\\\*** class\",\n    \"justifyMd\": \"Deprecated, use **justify-md-\\\\*** class\",\n    \"justifySm\": \"Deprecated, use **justify-sm-\\\\*** class\",\n    \"justifyXl\": \"Deprecated, use **justify-xl-\\\\*** class\",\n    \"justifyXxl\": \"Deprecated, use **justify-xxl-\\\\*** class\",\n    \"gap\": \"Sets the gap between `v-col`s. Can be a single value for both row and column gap, or the array of two values [column gap, row gap].\",\n    \"noGutters\": \"Removes the gutter between `v-col`s (same as `gap='0'`).\",\n    \"size\": \"Sets the number of columns.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VSelect.json",
    "content": "{\n  \"props\": {\n    \"chips\": \"Changes display of selections to chips.\",\n    \"closableChips\": \"Enables the [closable](/api/v-chip/#props-closable) prop on all [v-chip](/components/chips/) components.\",\n    \"hideSelected\": \"Do not display in the select menu items that are already selected.\",\n    \"itemColor\": \"Sets color of selected items.\",\n    \"itemChildren\": \"This property currently has **no effect**.\",\n    \"items\": \"Can be an array of objects or strings. By default objects should have **title** and **value** properties, and can optionally have a **props** property containing any [VListItem props](/api/v-list-item/#props). Keys to use for these can be changed with the **item-title**, **item-value**, and **item-props** props.\",\n    \"itemValue\": \"Set property of **items**'s value - **must be primitive**. Dot notation is supported. **Note:** This is currently not supported with `v-combobox` [GitHub Issue](https://github.com/vuetifyjs/vuetify/issues/5479).\",\n    \"minWidth\": \"Sets the minimum width of the select's `v-menu` content.\",\n    \"multiple\": \"Changes select to multiple. Accepts array for value.\",\n    \"openOnClear\": \"When using the **clearable** prop, once cleared, the select menu will either open or stay open, depending on the current state.\"\n  },\n  \"slots\": {\n    \"item\": \"Define a custom item appearance. The root element of this slot must be a **v-list-item** with `v-bind=\\\"props\\\"` applied. `props` includes everything required for the default select list behaviour - including title, value, click handlers, virtual scrolling, and anything else that has been added with [`item-props`](api/v-select/#props-item-props).\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VSelectionControl.json",
    "content": "{\n  \"props\": {\n    \"baseColor\": \"Sets the color of the input when it is not focused.\",\n    \"value\": \"The value used when the component is selected in a group. If not provided, a unique ID will be used.\"\n  },\n  \"slots\": {\n    \"input\": \"The slot used for the default input element.\"\n  },\n  \"exposed\": {\n    \"isFocused\": \"Will return true if the component is currently focused.\",\n    \"input\": \"Reference to the root input element.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VSheet.json",
    "content": "{}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VSkeletonLoader.json",
    "content": "{\n  \"props\": {\n    \"boilerplate\": \"Remove the loading animation from the skeleton.\",\n    \"loading\": \"Applies a loading animation with a on-hover loading cursor. A value of **false** will only work when there is content in the `default` slot.\",\n    \"loadingText\": \"aria-label for the element in a loading state.\",\n    \"type\": \"A string delimited list of skeleton components to create such as `type=\\\"text@3\\\"` or `type=\\\"card, list-item\\\"`. Will recursively generate a corresponding skeleton from the provided string. Also supports short-hand for multiple elements such as **article@3** and **paragraph@2** which will generate 3 _article_ skeletons and 2 _paragraph_ skeletons. Please see below for a list of available pre-defined options.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VSlideGroup.json",
    "content": "{\n  \"props\": {\n    \"centerActive\": \"Forces the selected component to be centered.\",\n    \"contentClass\": \"Adds classes to the slide group item.\",\n    \"direction\": \"Switch between horizontal and vertical modes.\",\n    \"mobileBreakpoint\": \"Sets the designated mobile breakpoint for the component.\",\n    \"nextIcon\": \"The appended slot when arrows are shown.\",\n    \"prevIcon\": \"The prepended slot when arrows are shown.\",\n    \"showArrows\": \"Change when the overflow arrow indicators are shown. By **default**, arrows *always* display on Desktop when the container is overflowing. When the container overflows on mobile, arrows are not shown by default. A **show-arrows** value of `true` allows these arrows to show on Mobile if the container overflowing. A value of `desktop` *always* displays arrows on Desktop while a value of `mobile` always displays arrows on Mobile. A value of `always` always displays arrows on Desktop *and* Mobile. Use **never** to turn arrows off. Find more information on how to customize breakpoint thresholds on the [breakpoints page](/customizing/breakpoints).\"\n  },\n  \"slots\": {\n    \"next\": \"The next slot.\",\n    \"prev\": \"The prev slot.\"\n  },\n  \"exposed\": {\n    \"focus\": \"Focus the component.\",\n    \"hasNext\": \"Returns true if there are items after current index.\",\n    \"hasPrev\": \"Returns true if there are items before current index.\",\n    \"scrollOffset\": \"Scroll the component to a given index.\",\n    \"scrollTo\": \"Scroll the component to a given index.\",\n    \"selected\": \"Get the selected component index.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VSlider.json",
    "content": "{\n  \"slots\": {\n    \"thumb-label\": \"Slot for the thumb label.\",\n    \"tick-label\": \"Slot for the tick label.\"\n  },\n  \"events\": {\n    \"end\": \"Slider value emitted at the end of slider movement.\",\n    \"start\": \"Slider value emitted at start of slider movement.\"\n  },\n  \"exposed\": {\n    \"focus\": \"Focus the slider handle.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VSnackbar.json",
    "content": "{\n  \"props\": {\n    \"loading\": \"Displays a loading spinner in the prepend area.\",\n    \"prependAvatar\": \"Displays an avatar in the prepend area using the provided image source.\",\n    \"prependIcon\": \"Displays an icon in the prepend area.\",\n    \"reverseTimer\": \"Reverses the direction of the timer progress bar, filling up instead of depleting.\",\n    \"timer\": \"Display a progress bar that counts down until the snackbar closes. Use `bottom` to change the default placement.\",\n    \"timerColor\": \"Sets the color of the timer progress bar.\",\n    \"timeout\": \"Time (in milliseconds) to wait until snackbar is automatically hidden. Use `-1` to keep open indefinitely. It is recommended for this number to be between `4000` and `10000`. Changes to this property will reset the countdown.\",\n    \"transition\": \"Sets the component transition. Can be one of the [built in](/styles/transitions/) or custom transition. Supports special location-aware mode with **slide-auto** and **scroll-auto**\",\n    \"collapsed\": \"Alters the element size fit behind front snackbar in the queue.\",\n    \"queueGap\": \"Sets the offset to show collapsed snackbars as a stack. Requires value in pixels.\",\n    \"queueIndex\": \"The index position of this snackbar within a queue.\",\n    \"vertical\": \"Stacks snackbar content on top of the actions (button).\"\n  },\n  \"slots\": {\n    \"actions\": \"Used to bind styles to [v-btn](/components/buttons) to match MD2 specification.\",\n    \"header\": \"Slot for custom content above the snackbar body.\"\n  },\n  \"exposed\": {\n    \"animateClick\": \"Function invoked when user clicks outside.\",\n    \"globalTop\": \"Used by activator to determine a components position in the global stack order.\",\n    \"localTop\": \"Used by activator to determine a components position in the local stack order.\",\n    \"updateLocation\": \"Function used for locationStrategy positioning.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VSnackbarQueue.json",
    "content": "{\n  \"props\": {\n    \"closable\": \"Adds a dismiss button that closes the active snackbar.\",\n    \"displayStrategy\": \"Determines how new snackbars are handled when the queue is full. **hold** (default) keeps new messages queued until a slot opens. **overflow** dismisses the oldest snackbar to make room for the new one.\",\n    \"closeText\": \"The text used in the close button when using the **closable** prop.\",\n    \"gap\": \"Sets the gap between stacked snackbars. Requires value in pixels.\",\n    \"collapsed\": \"Puts the visible snackbars behind each other (expands on hover).\",\n    \"totalVisible\": \"Specify the total visible snackbars.\"\n  },\n  \"exposed\": {\n    \"clear\": \"Dismisses all visible snackbars and clears the queue.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VSparkline.json",
    "content": "{\n  \"props\": {\n    \"autoDraw\": \"Trace the length of the line when first rendered.\",\n    \"autoDrawDuration\": \"Amount of time (in ms) to run the trace animation.\",\n    \"autoDrawEasing\": \"The easing function to use for the trace animation.\",\n    \"autoLineWidth\": \"Automatically expand bars to use space efficiently.\",\n    \"fill\": \"Using the **fill** property allows you to better customize the look and feel of your sparkline.\",\n    \"gradient\": \"An array of colors to use as a linear-gradient.\",\n    \"gradientDirection\": \"The direction the gradient should run.\",\n    \"height\": \"Height of the SVG trendline or bars.\",\n    \"labels\": \"An array of string labels that correspond to the same index as its data counterpart.\",\n    \"labelSize\": \"The label font size.\",\n    \"lineWidth\": \"The thickness of the line, in px.\",\n    \"padding\": \"Low `smooth` or high `line-width` values may result in cropping, increase padding to compensate.\",\n    \"showLabels\": \"Show labels below each data point.\",\n    \"smooth\": \"Number of px to use as a corner radius. `true` defaults to 8, `false` is 0.\",\n    \"type\": \"Choose between a trendline or bars.\",\n    \"width\": \"Width of the SVG trendline or bars.\",\n    \"id\": \"The id of the component.\",\n    \"itemValue\": \"The value of the item.\",\n    \"max\": \"The maximum value of the sparkline.\",\n    \"min\": \"The minimum value of the sparkline.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VSpeedDial.json",
    "content": "{\n  \"props\": {\n    \"openOnHover\": \"Opens speed-dial on hover.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VStepper.json",
    "content": "{\n  \"props\": {\n    \"completeIcon\": \"Icon to display when step is marked as completed.\",\n    \"editIcon\": \"Icon to display when step is editable.\",\n    \"errorIcon\": \"Icon to display when step has an error.\",\n    \"flat\": \"Removes the stepper's elevation.\"\n  },\n  \"exposed\": {\n    \"next\": \"Move to the next step.\",\n    \"prev\": \"Move to the prev step.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VStepperActions.json",
    "content": "{\n  \"props\": {\n    \"nextText\": \"The text used for the Next button.\",\n    \"prevText\": \"The text used for the Prev button.\"\n  },\n  \"events\": {\n    \"click:next\": \"Event emitted when clicking the next button.\",\n    \"click:prev\": \"Event emitted when clicking the prev button.\"\n  },\n  \"slots\": {\n    \"next\": \"Slot for customizing the next step functionality\",\n    \"prev\": \"Slot for customizing the prev step functionality\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VStepperHeader.json",
    "content": "{\n  \"props\": {}\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VStepperItem.json",
    "content": "{\n  \"props\": {\n  },\n  \"events\": {\n  },\n  \"slots\": {\n    \"icon\": \"Slot for customizing all stepper item icons.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VStepperVertical.json",
    "content": "{\n  \"props\": {\n    \"completeIcon\": \"Icon to display when step is marked as completed.\",\n    \"editIcon\": \"Icon to display when step is editable.\",\n    \"errorIcon\": \"Icon to display when step has an error.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VStepperVerticalItem.json",
    "content": "{\n  \"events\": {\n    \"click:finish\": \"Event emitted when clicking the finish button\",\n    \"click:next\": \"Event emitted when clicking the next button\",\n    \"click:prev\": \"Event emitted when clicking the previous button\"\n  },\n  \"slots\": {\n    \"icon\": \"Slot to override the icon\",\n    \"next\": \"Slot to override the next button\",\n    \"prev\": \"Slot to override the previous button\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VStepperWindow.json",
    "content": "{\n  \"props\": {}\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VStepperWindowItem.json",
    "content": "{\n  \"props\": {}\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VSwitch.json",
    "content": "{\n  \"props\": {\n    \"flat\": \"Display component without elevation. Default elevation for thumb is 4dp, `flat` resets it.\",\n    \"indeterminate\": \"Sets an indeterminate state for the switch.\",\n    \"inset\": \"Enlarge the `v-switch` track to encompass the thumb.\",\n    \"loading\": \"Displays circular progress bar. Can either be a String which specifies which color is applied to the progress bar (any material color or theme color - primary, secondary, success, info, warning, error) or a Boolean which uses the component color (set by color prop - if it's supported by the component) or the primary color.\",\n    \"multiple\": \"Changes expected model to an array.\"\n  },\n  \"events\": {\n    \"update:indeterminate\": \"Event that is emitted when the component's indeterminate state changes.\"\n  },\n  \"slots\": {\n    \"thumb\": \"Slot for custom thumb content.\",\n    \"track-true\": \"Slot for custom track content when value is true.\",\n    \"track-false\": \"Slot for custom track content when value is false.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VSystemBar.json",
    "content": "{\n  \"props\": {\n    \"height\": \"Sets the height for the component.\",\n    \"window\": \"Increases the system bar height to 32px (24px default).\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VTab.json",
    "content": "{\n  \"props\": {\n    \"direction\": \"Changes the direction of the tabs. Can be either `horizontal` or `vertical`.\",\n    \"hideSlider\": \"Hides the active tab slider component (no exit or enter animation).\",\n    \"inset\": \"Changes the slider to take full height. Automatically propagated from VTabs.\",\n    \"fixed\": \"Forces component to take up all available space up to their maximum width (300px), and centers it.\",\n    \"sliderColor\": \"Applies specified color to the slider when active on that component - supports utility colors (for example `success` or `purple`) or css color (`#033` or `rgba(255, 0, 0, 0.5)`). Find a list of built-in classes on the [colors page](/styles/colors#material-colors).\",\n    \"sliderTransition\": \"Changes slider transition to one of the predefined animation presets.\",\n    \"sliderTransitionDuration\": \"Applies custom slider transition duration. Default duration depends on transition type (fade: 400, grow: 350, shift: 225).\",\n    \"stacked\": \"Displays the tab as a flex-column.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VTable.json",
    "content": "{\n  \"props\": {\n    \"fixedFooter\": \"Use the fixed-footer prop together with the height prop to fix the footer to the bottom of the table.\",\n    \"fixedHeader\": \"Use the fixed-header prop together with the height prop to fix the header to the top of the table.\",\n    \"height\": \"Use the height prop to set the height of the table.\",\n    \"hover\": \"Will add a hover effect to a table's row when the mouse is over it.\",\n    \"striped\": \"Applies a background to either **even** or **odd** rows.\"\n  },\n  \"slots\": {\n    \"bottom\": \"Slot to add content below the table.\",\n    \"top\": \"Slot to add content above the table.\",\n    \"wrapper\": \"Slots for custom rendering of the table wrapper.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VTabs.json",
    "content": "{\n  \"props\": {\n    \"alignTabs\": \"Aligns the tabs to the `start`, `center`, or `end` of container. Also accepts `title` to align with the `v-toolbar-title` component.\",\n    \"color\": \"Applies specified color to the selected tab - supports utility colors (for example `success` or `purple`) or css color (`#033` or `rgba(255, 0, 0, 0.5)`). Find a list of built-in classes on the [colors page](/styles/colors#material-colors).\",\n    \"centerActive\": \"Forces the selected tab to be centered.\",\n    \"direction\": \"Changes the direction of the tabs. Can be either `horizontal` or `vertical`.\",\n    \"fixedTabs\": \"Tabs will be centered and each tab item will grow up to 300px width.\",\n    \"grow\": \"Forces tabs to take up all available space.\",\n    \"height\": \"Sets the height of the tabs bar.\",\n    \"hideSlider\": \"Hide's the generated `v-tabs-slider`.\",\n    \"inset\": \"Changes the slider to take full height. Tabs will also get some spacing and customizable rounding.\",\n    \"insetPadding\": \"Sets custom spacing between tabs for `inset` mode.\",\n    \"insetRadius\": \"Sets custom border radius for the tabs container `inset` mode. Rounding for individual tabs is calculated by subtracting the padding.\",\n    \"items\": \"The items to display in the component. This can be an array of strings or objects with a property `text`.\",\n    \"mobileBreakpoint\": \"Sets the designated mobile breakpoint for the component.\",\n    \"prevIcon\": \"Left pagination icon.\",\n    \"nextIcon\": \"Right pagination icon.\",\n    \"showArrows\": \"Show pagination arrows if the tab items overflow their container. For mobile devices, arrows will only display when using this prop.\",\n    \"sliderColor\": \"Changes the background color of an auto-generated `v-tabs-slider`.\",\n    \"sliderTransition\": \"Changes slider transition to one of the predefined animation presets.\",\n    \"sliderTransitionDuration\": \"Applies custom slider transition duration. Default duration depends on transition type (fade: 400, grow: 350, shift: 225).\",\n    \"stacked\": \"Apply the stacked prop to all children v-tab components.\"\n  },\n  \"slots\": {\n    \"[`item.${string}`]\": \"Dynamic slot to define custom slots for specific tab window items\",\n    \"[`tab.${string}`]\": \"Dynamic slot to define custom slots for specific tab headers in the slide group\",\n    \"tab\": \"Slot for custom tab header content.\",\n    \"window\": \"Slot for custom tab window content.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VTextField.json",
    "content": "{\n  \"props\": {\n    \"autofocus\": \"Enables autofocus.\",\n    \"clearIcon\": \"Applied when using **clearable** and the input is dirty.\",\n    \"counterValue\": \"Function returns the counter display text.\",\n    \"flat\": \"Removes elevation (shadow) added to element when using the **solo** or **solo-inverted** props.\",\n    \"persistentPlaceholder\": \"Forces placeholder to always be visible.\",\n    \"placeholder\": \"Sets the input’s placeholder text.\",\n    \"prefix\": \"Displays prefix text.\",\n    \"prependIcon\": \"Prepends an icon to the outside the component's input, uses the same syntax as `v-icon`.\",\n    \"prependInnerIcon\": \"Prepends an icon inside the component's input, uses the same syntax as `v-icon`.\",\n    \"reverse\": \"Reverses the input orientation.\",\n    \"role\": \"The role attribute applied to the input.\",\n    \"rounded\": \"Adds a border radius to the input.\",\n    \"suffix\": \"Displays suffix text.\",\n    \"type\": \"Sets input type.\"\n  },\n  \"events\": {\n    \"click:append\": \"Emitted when append icon is clicked.\",\n    \"click:appendInner\": \"Emitted when appended inner icon is clicked.\",\n    \"click:clear\": \"Emitted when clearable icon clicked.\",\n    \"click:prepend\": \"Emitted when prepended icon is clicked.\",\n    \"click:prependInner\": \"Emitted when prepended inner icon is clicked.\",\n    \"mousedown:control\": \"Event that is emitted when using mousedown on the main control area.\"\n  },\n  \"slots\": {\n    \"counter\": \"Slot for the input’s counter text.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VTextarea.json",
    "content": "{\n  \"props\": {\n    \"autoGrow\": \"Automatically grow the textarea depending on amount of text.\",\n    \"counterValue\": \"Display the input length but do not provide any validation.\",\n    \"noResize\": \"Remove resize handle.\",\n    \"persistentPlaceholder\": \"Forces placeholder to always be visible.\",\n    \"prefix\": \"Displays prefix text.\",\n    \"rows\": \"Default row count.\",\n    \"suffix\": \"Displays suffix text.\",\n    \"maxHeight\": \"Alternative for **max-rows**. Specifies the maximum height in pixels (including the field padding) for **auto-grow**.\",\n    \"maxRows\": \"Specifies the maximum number of rows for **auto-grow**.\",\n    \"autofocus\": \"The element should be focused as soon as the page loads.\"\n  },\n  \"events\": {\n    \"mousedown:control\": \"Event that is emitted when using mousedown on the main control area.\",\n    \"update:rows\": \"Emitted when the number of rows changes.\"\n  },\n  \"slots\": {\n    \"counter\": \"Slot for the input’s counter text.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VThemeProvider.json",
    "content": "{\n  \"props\": {\n    \"withBackground\": \"Wraps its children in an element and applies the current theme's background color to it.\"\n  },\n  \"slots\": {\n    \"default\": \"All child components will have their theme overridden. Must have exactly one root element.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VTimePicker.json",
    "content": "{\n  \"props\": {\n    \"allowedHours\": \"Restricts which hours can be selected.\",\n    \"allowedMinutes\": \"Restricts which minutes can be selected.\",\n    \"allowedSeconds\": \"Restricts which seconds can be selected.\",\n    \"format\": \"Defines the format of a time displayed in picker. Available options are `ampm` and `24hr`.\",\n    \"max\": \"Maximum allowed time.\",\n    \"min\": \"Minimum allowed time.\",\n    \"period\": \"Sets period for 12hr format.\",\n    \"readonly\": \"Puts picker in readonly state.\",\n    \"scrollable\": \"Allows changing hour/minute with mouse scroll.\",\n    \"useSeconds\": \"Toggles the use of seconds in picker.\",\n    \"width\": \"Width of the picker.\",\n    \"viewMode\": \"The current view mode of the picker.`\"\n  },\n  \"slots\": {\n    \"default\": \"Displayed below the clock, can be used for example for adding action button (`OK` and `Cancel`)\"\n  },\n  \"events\": {\n    \"update:hour\": \"Emitted when user selects the hour.\",\n    \"update:minute\": \"Emitted when user selects the minute.\",\n    \"update:second\": \"Emitted when user selects the second.\",\n    \"update:period\": \"Emitted when user clicks the AM/PM button.\",\n    \"update:viewMode\": \"Emitted when the view mode changes.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VTimePickerClock.json",
    "content": "{\n  \"props\": {\n    \"allowedValues\": \"Restricts which hours can be selected.\",\n    \"ampm\": \"Displays time in a 12-hour format.\",\n    \"displayedValue\": \"Used to display a custom value on the clock.\",\n    \"double\": \"If set, this probably indicates a double rotation or a mode where more than one set of values (like hours and minutes) is displayed on the clock at the same time.\",\n    \"format\": \"Specifies the format of the displayed time, either 12-hour or 24-hour, depending on the component's setup.\",\n    \"max\": \"Defines the maximum time value that can be selected.\",\n    \"min\": \"Defines the minimum time value that can be selected.\",\n    \"readonly\": \"When true, the picker is in a read-only state, and users cannot modify the selected time.\",\n    \"rotate\": \"Controls rotation, specifying the degree of rotation for the clock hands.\",\n    \"scrollable\": \"Allows the time selection to be scrollable, enhancing user experience for devices with scroll inputs.\",\n    \"step\": \"Defines the increments between selectable times, such as a step of 1 for every minute or a larger step for every 5 or 15 minutes.\"\n  },\n  \"events\": {\n    \"change\": \"The event that is triggered when the selected time is changed.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VTimePickerControls.json",
    "content": "{\n  \"props\": {\n    \"ampm\": \"Enables AM/PM mode.\",\n    \"hour\": \"The current hour value.\",\n    \"minute\": \"The current minute value.\",\n    \"second\": \"The current second value.\",\n    \"period\": \"The current period value. either `am` or `pm`.\",\n    \"readonly\": \"Makes the timepicker readonly.\",\n    \"useSeconds\": \"Enables the display and selection of seconds in the timepicker.\",\n    \"value\": \"The current value of the timepicker.\",\n    \"inputHints\": \"Displays labels below the time input controls.\",\n    \"viewMode\": \"The current view mode of the timepicker. Can be either `hour`, `minute`, or `second`.\"\n  },\n  \"events\": {\n    \"update:period\": \"Emitted when the period is changed. The event payload is either `am` or `pm`.\",\n    \"update:hour\": \"Emitted when the hour value changes.\",\n    \"update:minute\": \"Emitted when the minute value changes.\",\n    \"update:second\": \"Emitted when the second value changes.\",\n    \"update:viewMode\": \"Emitted when the view mode is changed. The event payload is either `hour`, `minute`, or `second`.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VTimeline.json",
    "content": "{\n  \"props\": {\n    \"align\": \"Places the timeline dot at the top or center of the timeline item.\",\n    \"direction\": \"Display timeline in a **vertical** or **horizontal** direction.\",\n    \"justify\": \"Places timeline line at the center or automatically on the left or right side.\",\n    \"lineColor\": \"Color of the timeline line.\",\n    \"lineInset\": \"Specifies the distance between the line and the dot of timeline items.\",\n    \"lineThickness\": \"Thickness of the timeline line.\",\n    \"side\": \"Display all timeline items on one side of the timeline, either **start** or **end**.\",\n    \"truncateLine\": \"Truncate timeline directly at the **start** or **end** of the line, or on **both** ends.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VTimelineItem.json",
    "content": "{\n  \"props\": {\n    \"dotColor\": \"Color of the item dot.\",\n    \"fillDot\": \"Remove outer border of item dot, making the color fill the entire dot.\",\n    \"hideDot\": \"Hide the timeline item dot.\",\n    \"hideOpposite\": \"Hide opposite content if it exists.\",\n    \"icon\": \"Apply a specific icon to the inside dot using the [v-icon](/components/icons/) component.\",\n    \"iconColor\": \"Color of the icon.\",\n    \"lineInset\": \"Specifies the distance between the line and the dot of the item.\",\n    \"side\": \"Show the item either **before** or **after** the timeline. This will override the implicit ordering of items, but will in turn be overridden by the `v-timeline` **single-side** prop.\",\n    \"size\": \"Size of the item dot\"\n  },\n  \"slots\": {\n    \"icon\": \"Used to customize the icon inside the item dot.\",\n    \"opposite\": \"Used to customize the opposite side of timeline items.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VToolbar.json",
    "content": "{\n  \"props\": {\n    \"absolute\": \"Applies position: absolute to the component.\",\n    \"collapse\": \"Puts the toolbar into a collapsed state reducing its maximum width.\",\n    \"collapsePosition\": \"Specifies side to attach the collapsed toolbar.\",\n    \"extended\": \"Use this prop to increase the height of the toolbar _without_ using the `extension` slot for adding content. May be used in conjunction with the **extension-height** prop. When false, will not show extension slot even if content is present.\",\n    \"extensionHeight\": \"Specify an explicit height for the `extension` slot.\",\n    \"flat\": \"Removes the toolbar's box-shadow.\",\n    \"floating\": \"Applies **display: inline-flex** to the component.\",\n    \"height\": \"Designates a specific height for the toolbar. Overrides the heights imposed by other props, e.g. **prominent**, **dense**, **extended**, etc.\",\n    \"image\": \"Specifies a [v-img](/components/images) as the component's background.\",\n    \"location\": \"Specifies the component's location. Can combine by using a space separated string. Requires the **absolute** prop.\"\n  },\n  \"slots\": {\n    \"extension\": \"Slot positioned directly under the main content of the toolbar. Height of this slot can be set explicitly with the **extension-height** prop. If this slot has no content, the **extended** prop may be used instead.\",\n    \"image\": \"Expects the [v-img](/components/images) component. Scoped **props** should be applied with `v-bind=\\\"props\\\"`.\"\n  },\n  \"exposed\": {\n    \"contentHeight\": \"The current height of the component's content.\",\n    \"extensionHeight\": \"The current height of the component's extension slot.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VTooltip.json",
    "content": "{\n  \"props\": {\n    \"closeDelay\": \"Delay (in ms) after which menu closes (when open-on-hover prop is set to true).\",\n    \"id\": \"HTML id attribute of the tooltip overlay. If not set, a globally unique id will be used.\",\n    \"interactive\": \"When true, the tooltip will respond to pointer events, allowing you to copy text from it.\",\n    \"openDelay\": \"Delay (in ms) after which tooltip opens (when `open-on-hover` prop is set to **true**).\",\n    \"openOnClick\": \"Designates whether the tooltip should open on activator click.\",\n    \"openOnHover\": \"Designates whether the tooltip should open on activator hover.\"\n  },\n  \"exposed\": {\n    \"animateClick\": \"Function invoked when user clicks outside.\",\n    \"globalTop\": \"Used by activator to determine a components position in the global stack order.\",\n    \"localTop\": \"Used by activator to determine a components position in the local stack order.\",\n    \"updateLocation\": \"Function used for locationStrategy positioning.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VTreeview.json",
    "content": "{\n  \"props\": {\n    \"activatable\": \"Allows user to mark a node as active by clicking on it.\",\n    \"color\": \"Applies specified color to the active node - supports utility colors (for example `success` or `purple`) or css color (`#033` or `rgba(255, 0, 0, 0.5)`). Find a list of built-in classes on the [colors page](/styles/colors#material-colors).\",\n    \"disabled\": \"Disables selection for all nodes.\",\n    \"expandIcon\": \"Icon used to indicate that a node can be expanded.\",\n    \"fluid\": \"Removes indentation from nested items.\",\n    \"hideActions\": \"Hide the expand icon and loading indicator next to each item title.\",\n    \"indeterminateIcon\": \"Icon used when node is in an indeterminate state. Only visible when `selectable` is `true`.\",\n    \"itemChildren\": \"Property on supplied `items` that contains its children.\",\n    \"items\": \"An array of items used to build the treeview.\",\n    \"loadChildren\": \"A function used when dynamically loading children. If this prop is set, then the supplied function will be run if expanding an item that has a `item-children` property that is an empty array. Supports returning a Promise.\",\n    \"loadingIcon\": \"Icon used when node is in a loading state.\",\n    \"modelValue\": \"Allows one to control which nodes are selected. The array contains the values of currently selected items. It is equivalent to the `v-model:selected`\",\n    \"openAll\": \"When `true` will cause all branch nodes to be opened when component is mounted.\",\n    \"openOnClick\": \"When `true` will cause nodes to be opened by clicking anywhere on it, instead of only opening by clicking on expand icon. When using this prop with `activatable` you will be unable to mark nodes with children as active.\",\n    \"returnObject\": \"When `true` will make `v-model`, `v-model:selected, `v-model:activated` and `v-model:opened` return the complete object instead of just the key.\",\n    \"rounded\": \"Provides an alternative active style for `v-treeview` node. Only visible when `activatable` is `true` and should not be used in conjunction with the `shaped` prop.\",\n    \"search\": \"The search model for filtering results.\",\n    \"selectable\": \"Will render a checkbox next to each node allowing them to be selected. Additionally, the **[openOnClick](/api/v-treeview/#props-open-on-click)** property will be applied internally.\",\n    \"selectedColor\": \"The color of the selection checkbox.\",\n    \"separateRoots\": \"Applies to `default` variant of `indent-lines`. Prevents showing lines between root-level nodes.\",\n    \"indentLines\": \"Controls visibility and variant of the indent lines.\",\n    \"indentLinesColor\": \"Sets color of indent lines\",\n    \"indentLinesOpacity\": \"Sets opacity of indent lines\",\n    \"collapseIcon\": \"Icon to display when the list item is expanded.\"\n  },\n  \"slots\": {\n    \"append\": \"Appends content after label.\",\n    \"prepend\": \"Prepends content before label.\",\n    \"header\": \"Slot for expandable nodes (all items that are not leafs).\",\n    \"footer\": \"Slot for footer below expanded children.\",\n    \"subheader\": \"Slot for custom subheader.\",\n    \"divider\": \"Slot for custom divider.\"\n  },\n  \"events\": {\n    \"click:open\": \"Emits the item when it is clicked to open.\",\n    \"click:select\": \"Emits the item when it is clicked to select.\",\n    \"update:activated\": \"Emits the array of active items when this value changes.\",\n    \"update:opened\": \"Emits the array of open items when this value changes.\",\n    \"update:selected\": \"Emits the array of selected items when this value changes.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VTreeviewGroup.json",
    "content": "{\n  \"props\": {\n    \"fluid\": \"Removes indentation from nested items.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VTreeviewItem.json",
    "content": "{\n  \"props\": {\n    \"hideActions\": \"Hide the expand icon and loading indicator next to each item title.\",\n    \"indentLines\": \"Array of indent lines to render next to the item.\",\n    \"loading\": \"Places the v-treeview-item into a loading state.\",\n    \"nav\": \"Reduces the width of v-list-item takes and adds a border radius.\",\n    \"slim\": \"Reduces the vertical padding or height of the v-treeview-item, making it more compact.\",\n    \"index\": \"The index of the item within the treeview list.\",\n    \"toggleIcon\": \"Allows customization of the icon used to toggle the expansion and collapse of treeview branches.\"\n  },\n  \"events\": {\n    \"toggleExpand\": \"Emitted when the item is toggled to expand or collapse.\"\n  },\n  \"slots\": {\n    \"toggle\": \"Slot for custom expand icon and loading indicator.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VVideo.json",
    "content": "{\n  \"props\": {\n    \"aspectRatio\": \"Sets the aspect ratio for the playback, calculated as width/height.\",\n    \"src\": \"Media file URL\",\n    \"srcObject\": \"Sets the source of the video to a MediaStream, MediaSource, or Blob object. Useful for WebRTC streaming.\",\n    \"type\": \"Media file type (optional)\",\n    \"error\": \"Puts the component in the manual error state.\",\n    \"image\": \"Apply a specific image as cover before the video is loaded.\",\n    \"autoplay\": \"Starts loading the media file without waiting for user to click. Playback begins once enough data is loaded.\",\n    \"muted\": \"Hides volume control and disables the playback sound.\",\n    \"eager\": \"Silently loades the media file without waiting for user to click.\",\n    \"hideOverlay\": \"Hide center play icon.\",\n    \"noFullscreen\": \"Disable fullscreen and hide the default fullscreen button.\",\n    \"rounded\": \"Applies a border radius to the video container and the controls. Accepts array of two values to customize elements separately.\",\n    \"startAt\": \"Moves progress to the specified time (in seconds) once the media file is loaded.\",\n    \"controlsProps\": \"Pass props through to the `v-video-controls` component. Accepts an object with anything from [v-video-controls](/api/v-video-controls/#props) props, camelCase keys are recommended.\",\n    \"controlsTransition\": \"The reveal transition applied to the VVideoControls component once the media file is loaded.\",\n    \"controlsVariant\": \"Variant passed to the VVideoControls component.\"\n  },\n  \"events\": {\n    \"loaded\": \"Emitted when the video has loaded and is ready to be played.\",\n    \"update:playing\": \"Emitted when playing state changes.\",\n    \"update:progress\": \"Emitted when the internal playback progress changes.\",\n    \"update:volume\": \"Emitted when the volume changes.\",\n    \"error\": \"Emits `true` when the video fails to load or `false` when user triggered retry.\"\n  },\n  \"slots\": {\n    \"header\": \"Slot for additional content placed on top of the video.\",\n    \"append\": \"Additional content on the right within the control bar.\",\n    \"controls\": \"Replaces controls bar with custom content.\",\n    \"loader\": \"Slot used to replace loader displayed when the video is being loaded.\",\n    \"prepend\": \"Additional content on the left within the control bar.\",\n    \"sources\": \"Slot for content placed within native `<video>` element.\"\n  },\n  \"exposed\": {\n    \"skipTo\": \"Skip to specific moment in the video playback. Accepts percent value (0-100).\",\n    \"toggleFullscreen\": \"Toggle fullscreen mode.\",\n    \"toggleMuted\": \"Mute/unmute audio.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VVideoControls.json",
    "content": "{\n  \"props\": {\n    \"color\": \"General color applied to icons and sliders.\",\n    \"backgroundColor\": \"Container background color.\",\n    \"trackColor\": \"Passed to the main slider `color` prop.\",\n    \"playing\": \"Applies correct icon of the default play button.\",\n    \"hidePlay\": \"Hides default play button.\",\n    \"hideProgressBar\": \"Hides default progress bar.\",\n    \"hideVolume\": \"Hides default volume control.\",\n    \"hideFullscreen\": \"Hides default fullscreen button.\",\n    \"fullscreen\": \"Applies correct icon on the default fullscreen button.\",\n    \"floating\": \"Introduces visual spacing from the video boundaries.\",\n    \"splitTime\": \"Splits time into elapsed and remaining on each side of the main slider.\",\n    \"pills\": \"Makes the container transparent and shows inner actions in separated boxes.\",\n    \"detached\": \"Moves the container below so it won't obstruct the video.\",\n    \"progress\": \"Controls main slider value (0 ~ 100)\",\n    \"duration\": \"Total duration of the video used to calculate displayed time.\",\n    \"volume\": \"Volume value passed to the underlying control and slots.\",\n    \"volumeProps\": \"Props passed down to the VVideoVolume component.\"\n  },\n  \"events\": {\n    \"update:playing\": \"Emitted when the playing state changes.\",\n    \"update:progress\": \"Emitted when the playback progress changes.\",\n    \"update:volume\": \"Emitted when the volume value changes.\",\n    \"skip\": \"Emitted when a skip action is triggered.\",\n    \"click:fullscreen\": \"Emitted when the fullscreen button is clicked.\"\n  },\n  \"exposed\": {\n    \"toggleMuted\": \"Toggles the muted state of the video.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VVideoVolume.json",
    "content": "{\n  \"props\": {\n    \"inline\": \"Display slider next to the icon. VMenu won't be displayed on click. Recomended to pair with **sliderProps** to configure slider width.\",\n    \"direction\": \"Switch between horizontal and vertical slider.\",\n    \"label\": \"Text to display in tooltip and passed to `aria-label`.\",\n    \"modelValue\": \"Volume value (0 ~ 100)\",\n    \"menuProps\": \"Props passed to VMenu containing volume slider. Useful to adjust **location** and control menu alignment\",\n    \"sliderProps\": \"Selected props to customize volume slider.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VVirtualScroll.json",
    "content": "{\n  \"props\": {\n    \"height\": \"Height of the component as a css value/\",\n    \"itemKey\": \"Should point to a property with a unique value for each item, if not set then item index will be used as a key which may result in unnecessary re-renders.\",\n    \"items\": \"The array of items to display.\",\n    \"renderless\": \"Disables default component rendering functionality. The parent node must be [a positioned element](https://developer.mozilla.org/en-US/docs/Web/CSS/position#types_of_positioning), e.g. using `position: relative;`\"\n  },\n  \"slots\": {\n    \"default\": \"Default slot to render a single item.\"\n  },\n  \"exposed\": {\n    \"calculateVisibleItems\": \"Trigger updating the currently rendered items based on scroll position.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VWindow.json",
    "content": "{\n  \"props\": {\n    \"continuous\": \"If `true`, window will \\\"wrap around\\\" from the last item to the first, and from the first item to the last.\",\n    \"crossfade\": \"Enables crossfade transition.\",\n    \"direction\": \"The transition direction when changing windows.\",\n    \"nextIcon\": \"Icon used for the \\\"next\\\" button if `show-arrows` is `true`.\",\n    \"prevIcon\": \"Icon used for the \\\"prev\\\" button if `show-arrows` is `true`.\",\n    \"reverse\": \"Reverse the normal transition direction.\",\n    \"showArrows\": \"Display the \\\"next\\\" and \\\"prev\\\" buttons.\",\n    \"touch\": \"Provide a custom **left** and **right** function when swiped left or right.\",\n    \"transitionDuration\": \"Overrides transition duration. Does not work in firefox, safari <18, or with `prefers-reduced-motion: reduce`.\",\n    \"verticalArrows\": \"Displays the navigation arrows vertically instead of horizontally.\"\n  },\n  \"slots\": {\n    \"next\": \"Slot displaying the arrow switching to the next item.\",\n    \"prev\": \"Slot displaying the arrow switching to the previous item.\",\n    \"additional\": \"Slot for additional content at the end of the component.\"\n  },\n  \"exposed\": {\n    \"group\": \"Returns item group data, state and helper methods.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/VWindowItem.json",
    "content": "{\n  \"props\": {\n    \"disabled\": \"Prevents the item from becoming active when using the \\\"next\\\" and \\\"prev\\\" buttons or the `toggle` method.\",\n    \"reverseTransition\": \"Sets the reverse transition.\",\n    \"transition\": \"The transition used when the component progressing through items. Can be one of the [built in](/styles/transitions/) or custom transition.\"\n  },\n  \"exposed\": {\n    \"groupItem\": \"Returns item and item group data, state and helper methods.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/autocomplete.json",
    "content": "{\n  \"props\": {\n    \"autocomplete\": \"Helps influence browser's suggestions. Special value **suppress** manipulates fields `name` attribute while **off** relies on browser's good will to stop suggesting values. Any other value is passed to the native `autocomplete` on the underlying element.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/border.json",
    "content": "{\n  \"props\": {\n    \"border\": \"Applies utility border classes to the component. To use it, you need to omit the `border-` prefix, (for example use `border-sm` as `border=\\\"sm\\\"`).  Find a list of the built-in border classes on the [borders page](/styles/borders).\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/calendar.json",
    "content": "{\n  \"props\": {\n    \"displayValue\": \"The value that determines the month to show. This is different from modelValue, which determines the selected value.\",\n    \"month\": \"The current month number to show\",\n    \"weeksInMonth\": \"A dynamic number of weeks in a month will grow and shrink depending on how many days are in the month. A static number always shows 7 weeks.\",\n    \"year\": \"The current year number to show\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/delay.json",
    "content": "{\n  \"props\": {\n    \"closeDelay\": \"Milliseconds to wait before closing component. Only applies to hover and focus events.\",\n    \"openDelay\": \"Milliseconds to wait before opening component. Only applies to hover and focus events.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/dimension.json",
    "content": "{\n  \"props\": {\n    \"height\": \"Sets the height for the component.\",\n    \"maxHeight\": \"Sets the maximum height for the component.\",\n    \"maxWidth\": \"Sets the maximum width for the component.\",\n    \"minHeight\": \"Sets the minimum height for the component.\",\n    \"minWidth\": \"Sets the minimum width for the component.\",\n    \"width\": \"Sets the width for the component.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/display.json",
    "content": "{\n  \"props\": {\n    \"mobile\": \"Determines the display mode of the component. If true, the component will be displayed in mobile mode. If false, the component will be displayed in desktop mode. If null, will be based on the current mobile-breakpoint\",\n    \"mobileBreakpoint\": \"Overrides the display configuration default screen size that the component should be considered in mobile.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/elevation.json",
    "content": "{\n  \"props\": {\n    \"elevation\": \"Designates an elevation applied to the component between 0 and 5. You can find more information on the [elevation page](/styles/elevation).\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/filter.json",
    "content": "{\n  \"props\": {\n    \"customFilter\": \"Function used to filter items, called for each filterable key on each item in the list. The first argument is the filterable value from the item, the second is the search term, and the third is the internal item object. The function should return true if the item should be included in the filtered list, or the index of the match in the value if it should be included with the result highlighted.\",\n    \"customKeyFilter\": \"Function used on specific keys within the item object. `customFilter` is skipped for columns with `customKeyFilter` specified.\",\n    \"filterKeys\": \"Array of specific keys to filter on the item.\",\n    \"filterMode\": \"Controls how the results of `customFilter` and `customKeyFilter` are combined. All modes only apply `customFilter` to columns not specified in `customKeyFilter`.\\n\\n- **some**: There is at least one match from either the custom filter or the custom key filter.\\n- **every**: All columns match either the custom filter or the custom key filter.\\n- **union**: There is at least one match from the custom filter, or all columns match the custom key filters.\\n- **intersection**: There is at least one match from the custom filter, and all columns match the custom key filters.\",\n    \"noFilter\": \"Disables all item filtering.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/focus.json",
    "content": "{\n  \"props\": {\n    \"focused\": \"Forces a focused state styling on the component.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/form.json",
    "content": "{\n  \"props\": {\n    \"disabled\": \"Puts all children inputs into a disabled state.\",\n    \"fastFail\": \"Stop validation as soon as any rules fail.\",\n    \"modelValue\": \"The value representing the validity of the form. If the value is `null` then no validation has taken place yet, or the form has been reset. Otherwise the value will be a `boolean` that indicates if validation has passed or not.\",\n    \"readonly\": \"Puts all children inputs into a readonly state.\",\n    \"validateOn\": \"Changes the events in which validation occurs.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/generic.json",
    "content": "{\n  \"props\": {\n    \"active\": \"Controls the **active** state of the item. This is typically used to highlight the component.\",\n    \"activeClass\": \"The class applied to the component when it is in an active state.\",\n    \"activeColor\": \"The applied color when the component is in an active state.\",\n    \"appendAvatar\": \"Appends a [v-avatar](/components/avatars/) component after default content in the **append** slot.\",\n    \"appendIcon\": \"Creates a [v-icon](/api/v-icon/) component after default content in the **append** slot.\",\n    \"auto\": \"Centers list on selected element.\",\n    \"baseColor\": \"Sets the color of component when not focused.\",\n    \"bgColor\": \"Applies specified color to the control's background. Used on components that also support the **color** prop. - supports utility colors with or without `bg-` prefix (for example `success`, `purple` or `bg-purple`) or CSS color (`#033` or `rgba(255, 0, 0, 0.5)`). Find a list of built-in classes on the [colors page](/styles/colors#material-colors).\",\n    \"captureFocus\": \"When enabled, focus will be trapped within the component's content, preventing Tab navigation from moving focus outside. Useful for modals, dialogs, and overlays to maintain accessibility.\",\n    \"clearable\": \"Allows for the component to be cleared.\",\n    \"color\": \"Applies specified color to the control - supports utility colors with or without `text-` prefix (for example `success`, `purple` or `text-purple`) or CSS color (`#033` or `rgba(255, 0, 0, 0.5)`). Find a list of built-in classes on the [colors page](/styles/colors#material-colors).\",\n    \"contentClass\": \"Applies a custom class to the detached element. This is useful because the content is moved to the beginning of the `v-app` component (unless the **attach** prop is provided) and is not targetable by classes passed directly on the component.\",\n    \"counter\": \"Creates counter for input length; if no number is specified, it defaults to 25. Does not apply any validation.\",\n    \"disabled\": \"Removes the ability to click or target the component.\",\n    \"density\": \"Adjusts the vertical height used by the component.\",\n    \"eager\": \"Forces the component's content to render when it mounts. This is useful if you have content that will not be rendered in the DOM that you want crawled for SEO.\",\n    \"end\": \"Applies margin at the start of the component.\",\n    \"falseIcon\": \"The icon used when inactive.\",\n    \"falseValue\": \"Sets value for falsy state.\",\n    \"firstDayOfWeek\": \"Sets the first day of the week, starting with 0 for Sunday. (Note: not guaranteed to work when using custom date adapters.)\",\n    \"firstDayOfYear\": \"Sets the day that determines the first week of the year, starting with 0 for Sunday. For ISO 8601 this should be 4. (Note: not guaranteed to work when using custom date adapters.)\",\n    \"retainFocus\": \"Captures and keeps focus within the content element when using **Tab** and **Shift**+**Tab**. Recommended to be `false` when using external tools that require focus such as TinyMCE or vue-clipboard.\",\n    \"fullWidth\": \"Sets the component width to 100%.\",\n    \"height\": \"Sets the height for the component.\",\n    \"hideNoData\": \"Hides the menu when there are no options to show.  Useful for preventing the menu from opening before results are fetched asynchronously.  Also has the effect of opening the menu when the `items` array changes if not already open.\",\n    \"hideOnLeave\": \"Hides the leaving element (no exit animation).\",\n    \"group\": \"Creates a `transition-group` component. You can find more information in the [vue docs](https://vuejs.org/api/built-in-components.html#transitiongroup).\",\n    \"icon\": \"Apply a specific icon using the [v-icon](/components/icons/) component.\",\n    \"iconSize\": \"The specific size of the icon, can use named sizes.\",\n    \"iconSizes\": \"An array of tuples that define the icon sizes for each named size.\",\n    \"image\": \"Apply a specific image using [v-img](/components/images/).\",\n    \"items\": \"An array of strings or objects used for automatically generating children components.\",\n    \"label\": \"Sets the text of the [v-label](/api/v-label/) or [v-field-label](/api/v-field-label/) component.\",\n    \"leaveAbsolute\": \"Absolutely positions the leaving element (useful for [FLIP](https://aerotwist.com/blog/flip-your-animations/)).\",\n    \"link\": \"Designates that the component is a link. This is automatic when using the href or to prop.\",\n    \"mandatory\": \"Forces at least one item to always be selected (if available).\",\n    \"menu\": \"Renders with the menu open by default.\",\n    \"menuIcon\": \"Sets the the spin icon.\",\n    \"menuProps\": \"Pass props through to the `v-menu` component. Accepts an object with anything from [v-menu](/api/v-menu/#props) props, camelCase keys are recommended.\",\n    \"messages\": \"Displays a list of messages or a single message if using a string.\",\n    \"mode\": \"Sets the transition mode (does not apply to transition-group). You can find more information on the Vue documentation [for transition modes](https://vuejs.org/api/built-in-components.html#transition).\",\n    \"modelModifiers\": \"**FOR INTERNAL USE ONLY**\",\n    \"modelValue\": \"The v-model value of the component. If component supports the **multiple** prop, this defaults to an empty array.\",\n    \"name\": \"Sets the component's name attribute.\",\n    \"noDataText\": \"Text shown when no items are provided to the component.\",\n    \"opacity\": \"Sets the component's opacity value\",\n    \"origin\": \"Sets the transition origin on the element. You can find more information on the MDN documentation [for transition origin](https://developer.mozilla.org/en-US/docs/Web/CSS/transform-origin).\",\n    \"persistent\": \"Clicking outside or pressing **esc** key will not dismiss the dialog.\",\n    \"persistentCounter\": \"Forces counter to always be visible.\",\n    \"prependGap\": \"Sets the horizontal spacing between prepend slot and the main content. Also affects indent to ensure expected alignment of group children.\",\n    \"pickerProps\": \"Pass props through to the picker component. Intended for props that conflict with `v-text-field` (`color`, `width`, `rounded`, etc.)\",\n    \"prependAvatar\": \"Prepends a [v-avatar](/components/avatars/) component in the **prepend** slot before default content.\",\n    \"prependIcon\": \"Creates a [v-icon](/api/v-icon/) component in the **prepend** slot before default content.\",\n    \"ripple\": \"Applies the [v-ripple](/directives/ripple) directive.\",\n    \"search\": \"Text input used to filter items.\",\n    \"scrollToActive\": \"Keeps the last active element visible when resizing the scrollable container.\",\n    \"selectedClass\": \"Configure the active CSS class applied when an item is selected.\",\n    \"size\": \"Sets the height and width of the component.\",\n    \"subtitle\": \"Specify a subtitle text for the component.\",\n    \"start\": \"Applies margin at the end of the component.\",\n    \"filterByType\": \"Make the input accept only files matched by one or more [unique file type specifiers](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#Unique_file_type_specifiers). Applies to drag & drop and selecting folders. Emits `rejected` event when some files do not pass through to make it possible to notify user and deliver better user experience.\",\n    \"symbol\": \"The [Symbol](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol) used to hook into group functionality for components like [v-btn-toggle](/components/btn-toggle) and [v-bottom-navigation](/components/bottom-navigations/).\",\n    \"tag\": \"Specify a custom tag used on the root element.\",\n    \"text\": \"Specify content text for the component.\",\n    \"textColor\": \"Applies a specified color to the control text - supports utility colors with or without `text-` prefix (for example `success`, `purple` or `text-purple`) or CSS color (`#033` or `rgba(255, 0, 0, 0.5)`). Find a list of built-in classes on the [colors page](/styles/colors#material-colors).\",\n    \"title\": \"Specify a title text for the component.\",\n    \"trueIcon\": \"The icon used when active.\",\n    \"trueValue\": \"Sets value for truthy state.\",\n    \"valueComparator\": \"Apply a custom comparison algorithm to compare **model-value** and values contains in the **items** prop.\",\n    \"variant\": \"Applies a distinct style to the component.\",\n    \"weekdayFormat\": \"Allows you to customize the format of the weekday string that appears in the body of the calendar. Uses `'narrow'` by default. (Note: not guaranteed to work when using custom date adapters.)\",\n    \"weekdays\": \"An array of weekdays to display. Does not affect the order.\",\n    \"width\": \"Sets the width for the component.\"\n  },\n  \"slots\": {\n    \"activator\": \"When used, will activate the component when clicked (or hover for specific components). This manually stops the event propagation. Without this slot, if you open the component through its model, you will need to manually stop the event propagation.\",\n    \"append\": \"Adds an item inside the input and after input content.\",\n    \"append-item\": \"Adds an item after menu content.\",\n    \"append-inner\": \"Adds an item inside the input content.\",\n    \"chip\": \"Slot for custom chip when using the [chip](#property-chip) prop.\",\n    \"details\": \"Slot for custom input details to modifying the display of [messages](#props-messages).\",\n    \"default\": \"The default Vue slot.\",\n    \"item\": \"Define a custom item appearance.\",\n    \"label\": \"The default slot of the [v-label](/api/v-label/) or [v-field-label](/api/v-field-label/) component.\",\n    \"loader\": \"Slot for custom loader (displayed when [loading](#props-loading) prop is equal to true).\",\n    \"message\": \"Slot used to customize the message content.\",\n    \"no-data\": \"Defines content for when no items are provided.\",\n    \"prepend\": \"Adds an item outside the input and before input content.\",\n    \"prepend-inner\": \"Adds an item inside the input content.\",\n    \"prepend-item\": \"Adds an item before menu content.\",\n    \"progress\": \"Slot for custom progress linear (displayed when **loading** prop is not equal to Boolean False).\",\n    \"selection\": \"Define a custom selection appearance.\",\n    \"subtitle\": \"Slot for the component's subtitle content.\",\n    \"text\": \"Slot for the component's text content.\",\n    \"title\": \"Slot for the component's title content.\"\n  },\n  \"events\": {\n    \"click\": \"Event that is emitted when the component is clicked.\",\n    \"click:close\": \"Emitted when close icon is clicked.\",\n    \"click:append\": \"Emitted when appended icon is clicked.\",\n    \"click:appendInner\": \"Emitted when appended inner icon is clicked.\",\n    \"click:clear\": \"Emitted when clear icon is clicked.\",\n    \"click:prepend\": \"Emitted when prepended icon is clicked.\",\n    \"click:prependInner\": \"Emitted when prepended inner icon is clicked.\",\n    \"input\": \"The updated bound model.\",\n    \"group:selected\": \"Event that is emitted when an item is selected within a group.\",\n    \"rejected\": \"Emitted when some of the files from user input, drop or folder selection did not pass through `strict-accept` filter.\",\n    \"update:focused\": \"Event that is emitted when the component's focus state changes.\",\n    \"update:menu\": \"Event that is emitted when the component's menu state changes.\",\n    \"update:modelValue\": \"Event that is emitted when the component's model changes.\",\n    \"update:search\": \"Event emitted when the search value changes.\"\n  },\n  \"exposed\": {\n    \"filteredItems\": \"The current array of items based upon the current search text.\",\n    \"isFocused\": \"Returns true if the input is focused.\",\n    \"isPristine\": \"Returns true if the input has not been modified in any way.\",\n    \"menu\": \"Returns true if the menu is currently open.\",\n    \"search\": \"The current search text.\",\n    \"select\": \"The function used to select an items. The first argument expects the value of the item.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/group-item.json",
    "content": "{\n  \"props\": {\n    \"value\": \"The value used when the component is selected in a group. If not provided, a unique ID will be used.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/group.json",
    "content": "{\n  \"props\": {\n    \"disabled\": \"Puts all children components into a disabled state.\",\n    \"max\": \"Sets a maximum number of selections that can be made.\",\n    \"multiple\": \"Allows one to select multiple items.\",\n    \"value\": \"The value used when the component is selected within a group. If not provided, the render index is used.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/layout-item.json",
    "content": "{\n  \"props\": {\n    \"absolute\": \"Applies **position: absolute** to the component.\",\n    \"name\": \"Assign a specific name for layout registration.\",\n    \"order\": \"Adjust the order of the component in relation to its registration order.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/layout.json",
    "content": "{\n  \"props\": {\n    \"fullHeight\": \"Sets the component height to 100%.\",\n    \"overlaps\": \"**FOR INTERNAL USE ONLY**\"\n  },\n  \"exposed\": {\n    \"getLayoutItem\": \"Function that returns position and size information about a specific layout item.\",\n    \"items\": \"A array of all registered layout items.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/list-items.json",
    "content": "{\n  \"props\": {\n    \"items\": \"Can be an array of objects or strings. By default objects should have a **title** property, and can optionally have a **props** property containing any [VListItem props](/api/v-list-item/#props), a **value** property to allow selection, and a **children** property containing more item objects. Keys to use for these can be changed with the **item-title**, **item-value**, **item-props**, and **item-children** props.\",\n    \"itemChildren\": \"Property on supplied `items` that contains its children.\",\n    \"itemProps\": \"Props object that will be applied to each item component. `true` will treat the original object as raw props and pass it directly to the component.\",\n    \"itemTitle\": \"Property on supplied `items` that contains its title.\",\n    \"itemType\": \"Designates the key on the supplied items that is used for determining the nodes type.\",\n    \"itemValue\": \"Property on supplied `items` that contains its value.\",\n    \"returnObject\": \"Changes the selection behavior to return the object directly rather than the value specified with **item-value**.\"\n  },\n  \"slots\": {\n    \"divider\": \"Slot for rendering custom dividers. Receives `{ props }` containing divider item data including `value`. Note: dividers do not receive `index` since they are not navigable items.\",\n    \"subheader\": \"Slot for rendering custom subheaders. Receives `{ props }` containing subheader item data including `title` and `value`. Note: subheaders do not receive `index` since they are not navigable items.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/loader.json",
    "content": "{\n  \"props\": {\n    \"loading\": \"Displays linear progress bar. Can either be a String which specifies which color is applied to the progress bar (any material color or theme color - **primary**, **secondary**, **success**, **info**, **warning**, **error**) or a Boolean which uses the component **color** (set by color prop - if it's supported by the component) or the primary color.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/location.json",
    "content": "{\n  \"props\": {\n    \"location\": \"Specifies the component's location. Can combine by using a space separated string.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/mask.json",
    "content": "{\n  \"props\": {\n    \"mask\": \"Apply a mask to the input. See [guide](/components/mask-inputs/#guide) for more information.\",\n    \"returnMaskedValue\": \"Returns the unmodified masked string.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/nested.json",
    "content": "{\n  \"props\": {\n    \"activated\": \"Array of ids of activated nodes.\",\n    \"activeStrategy\": \"Affects how items with children behave when activated. If not specified, the **single-independent** strategy will be used.\\n- **leaf:** Only leaf nodes (items without children) can be activated.\\n- **single-leaf:** Similar as **leaf**, but only a single item can be activated at a time.\\n- **independent:** All nodes can be activated whether they have children or not.\\n- **single-independent:** Similar as **independent**, but only a single item can be activated at a time.\",\n    \"opened\": \"An array containing the values of currently opened groups. Can be two-way bound with `v-model:opened`.\",\n    \"openStrategy\": \"Affects how items with children behave when expanded.\\n- **multiple:** Any number of groups can be open at once.\\n- **single:** Only one group at each level can be open, opening a group will cause others to close.\\n- **list:** Multiple, but all other groups will close when an item is selected.\",\n    \"selected\": \"An array containing the values of currently selected items. Can be two-way bound with `v-model:selected`.\",\n    \"selectStrategy\": \"Affects how items with children behave when selected.\\n- **leaf:** Only leaf nodes (items without children) can be selected.\\n- **independent:** All nodes can be selected whether they have children or not.\\n- **classic:** Selecting a parent node will cause all children to be selected, parent nodes will be displayed as selected if all their descendants are selected. Only leaf nodes will be added to the model.\\n- **trunk**: Same as classic but if all of a node's children are selected then only that node will be added to the model.\\n- **branch**: Same as classic but if any of a node's children are selected then that node will also be added to the model.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/position.json",
    "content": "{\n  \"props\": {\n    \"position\": \"Sets the position for the component.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/rounded.json",
    "content": "{\n  \"props\": {\n    \"rounded\": \"Designates the **border-radius** applied to the component. This can be **0**, **xs**, **sm**, true, **lg**, **xl**, **pill**, **circle**, and **shaped**. Find more information on available border radius classes on the [Border Radius page](/styles/border-radius).\",\n    \"tile\": \"Removes any applied **border-radius** from the component.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/router.json",
    "content": "{\n  \"props\": {\n    \"activeClass\": \"The class applied to the component when it matches the current route. Find more information about the [active-class prop](https://router.vuejs.org/api/#active-class) on the [vue-router](https://router.vuejs.org/) documentation.\",\n    \"exact\": \"Exactly match the link. Without this, '/' will match every route. You can find more information about the [**exact** prop](https://router.vuejs.org/api/#exact) on the vue-router documentation.\",\n    \"href\": \"Designates the component as anchor and applies the **href** attribute.\",\n    \"replace\": \"Setting **replace** prop will call `router.replace()` instead of `router.push()` when clicked, so the navigation will not leave a history record. You can find more information about the [replace](https://router.vuejs.org/api/#replace) prop on the vue-router documentation.\",\n    \"to\": \"Denotes the target route of the link. You can find more information about the [**to** prop](https://router.vuejs.org/api/#to) on the vue-router documentation.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/size.json",
    "content": "{\n  \"props\": {\n    \"size\": \"Sets the height and width of the component. Default unit is px. Can also use the following predefined sizes: **x-small**, **small**, **default**, **large**, and **x-large**.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/tag.json",
    "content": "{\n  \"props\": {\n    \"tag\": \"Specify a custom tag used on the root element.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/theme.json",
    "content": "{\n  \"props\": {\n    \"theme\": \"Specify a theme for this component and all of its children.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/time-validation.json",
    "content": "{\n  \"props\": {\n    \"max\": \"Maximum allowed time.\",\n    \"min\": \"Minimum allowed time.\",\n    \"allowedHours\": \"Restricts which hours can be selected. Can be an array of allowed hours, a function that returns true for allowed hours, or an object with `min` and `max` properties.\",\n    \"allowedMinutes\": \"Restricts which minutes can be selected. Can be an array of allowed minutes, a function that returns true for allowed minutes, or an object with `min` and `max` properties.\",\n    \"allowedSeconds\": \"Restricts which seconds can be selected. Can be an array of allowed seconds, a function that returns true for allowed seconds, or an object with `min` and `max` properties.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/transition.json",
    "content": "{\n  \"props\": {\n    \"transition\": \"Sets the component transition. Can be one of the [built in](/styles/transitions/) or custom transition.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/useDate.json",
    "content": "{\n  \"exposed\": {\n    \"addWeeks\": \"Adds the specified number of weeks to the date.\",\n    \"addDays\": \"Adds the specified number of days to the date.\",\n    \"addMonths\": \"Adds the specified number of months to the date.\",\n    \"addHours\": \"Adds the specified number of hours to the date.\",\n    \"addMinutes\": \"Adds the specified number of minutes to the date.\",\n    \"date\": \"Takes any value and returns a date object.\",\n    \"endOfDay\": \"Returns the last second of the day.\",\n    \"endOfMonth\": \"Returns the last day of the month.\",\n    \"endOfWeek\": \"Returns the last day of the week.\",\n    \"endOfYear\": \"Returns the last day of the year.\",\n    \"format\": \"Takes a date object and returns it in a specified format.\",\n    \"getDiff\": \"Returns the difference between two dates in the specified unit.\",\n    \"getMonth\": \"Returns the month of the date.\",\n    \"getWeek\": \"Returns the week of the year of the date.\",\n    \"getWeekArray\": \"Returns an array of the days of the week of the date.\",\n    \"getWeekdays\": \"Returns an array of the names of the days of the week.\",\n    \"getDate\": \"Returns the day of the month of the date.\",\n    \"getHours\": \"Returns the hours of the day of the date.\",\n    \"getMinutes\": \"Returns the minutes of the hour of the date.\",\n    \"getNextMonth\": \"Returns the next month of the date.\",\n    \"getPreviousMonth\": \"Returns the previous month of the date.\",\n    \"parseISO\": \"Parses a date string in ISO format.\",\n    \"isAfter\": \"Returns true if the first date is after the second date.\",\n    \"isAfterDay\": \"Returns true if the first date is after the second date.\",\n    \"isBefore\": \"Returns true if the first date is before the second date.\",\n    \"isEqual\": \"Returns true if the two dates are equal.\",\n    \"isSameDay\": \"Returns true if the two dates are the same day.\",\n    \"isSameMonth\": \"Returns true if the two dates are the same month.\",\n    \"isSameYear\": \"Returns true if the two dates are the same year.\",\n    \"isValid\": \"Returns true if the date is valid.\",\n    \"isWithinRange\": \"Returns true if the first date is within the range of the second and third dates.\",\n    \"locale\": \"Returns the current locale being used.\",\n    \"getYear\": \"Returns the year of the date.\",\n    \"setYear\": \"Sets the year of the date.\",\n    \"setMonth\": \"Sets the month of the date.\",\n    \"setDate\": \"Sets the day of the date.\",\n    \"setHours\": \"Sets the hours of the date.\",\n    \"setMinutes\": \"Sets the minutes of the date.\",\n    \"startOfDay\": \"Returns the first second of the day.\",\n    \"startOfMonth\": \"Returns first day of the month.\",\n    \"startOfWeek\": \"Returns the first day of the week.\",\n    \"startOfYear\": \"Returns the first day of the year.\",\n    \"toJsDate\": \"Converts date value to a JS Date Object.\",\n    \"toISO\": \"Converts date value to a ISO Date Object.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/useDisplay.json",
    "content": "{\n  \"exposed\": {\n    \"height\": \"The inner height of the browser window.\",\n    \"lg\": \"Returns **true** if the current browser breakpoint is **lg**.\",\n    \"lgAndDown\": \"Returns **true** if the current browser breakpoint is **lg** or lower.\",\n    \"lgAndUp\": \"Returns **true** if the current browser breakpoint is **lg** or higher.\",\n    \"md\": \"Returns **true** if the current browser breakpoint is **md**.\",\n    \"mdAndDown\": \"Returns **true** if the current browser breakpoint is **md** or lower.\",\n    \"mdAndUp\": \"Returns **true** if the current browser breakpoint is **md** or higher.\",\n    \"mobile\": \"Returns **true** if the current browser breakpoint is considered to be a mobile breakpoint.\",\n    \"mobileBreakpoint\": \"Controls which named breakpoint (**lg**, **md**, etc) or browser width (in px) is considered to be mobile.\",\n    \"name\": \"Name of the current breakpoint.\",\n    \"platform\": \"Name of the current platform.\",\n    \"sm\": \"Returns **true** if the current browser breakpoint is **sm**.\",\n    \"smAndDown\": \"Returns **true** if the current browser breakpoint is **sm** or lower.\",\n    \"smAndUp\": \"Returns **true** if the current browser breakpoint is **sm** or higher.\",\n    \"thresholds\": \"An object describing the width values of each breakpoint.\",\n    \"update\": \"Function that updates the current width and height values.\",\n    \"width\": \"The inner width of the browser window.\",\n    \"xl\": \"Returns **true** if the current browser breakpoint is **xl**.\",\n    \"xlAndDown\": \"Returns **true** if the current browser breakpoint is **xl** or lower.\",\n    \"xlAndUp\": \"Returns **true** if the current browser breakpoint is **xl** or higher.\",\n    \"xs\": \"Returns **true** if the current browser breakpoint is **xs**.\",\n    \"xxl\": \"Returns **true** if the current browser breakpoint is **xxl**.\",\n    \"ssr\": \"Returns **true** if the current page was server rendered.\",\n    \"displayClasses\": \"Returns an object containing the breakpoints and their corresponding classes.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/useGoTo.json",
    "content": "{\n  \"exposed\": {\n    \"rtl\": \"The current RTL state.\",\n    \"options\": \"The current goTo scrolling options.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/useHotkey.json",
    "content": "{\n  \"props\": {\n    \"keys\": \"A reactive string defining the keyboard shortcut combination. Supports single keys (e.g., 'a'), modifier combinations (e.g., 'cmd+s', 'ctrl+shift+z'), sequential key combinations (e.g., 'cmd+k-t'), and multiple alternatives separated by spaces. Platform-aware: 'cmd' automatically maps to Ctrl on PC and Command on Mac. Use '-' for sequences, '+' for simultaneous key combinations.\",\n    \"callback\": \"Function to execute when the hotkey is triggered. Receives the KeyboardEvent as a parameter, allowing access to event details and the ability to call preventDefault() if needed.\",\n    \"options\": \"Configuration object to customize hotkey behavior. Includes event type ('keydown' or 'keyup'), input field handling, preventDefault behavior, and sequence timeout settings.\"\n  },\n  \"options\": {\n    \"event\": \"The keyboard event type to listen for. Accepts 'keydown' (default) or 'keyup'. Use 'keydown' for immediate response and 'keyup' for actions that should trigger when the key is released.\",\n    \"inputs\": \"Whether to allow hotkeys when input elements (input, textarea, contentEditable) are focused. Default is false, which prevents hotkeys from triggering in form fields to avoid interfering with normal typing.\",\n    \"preventDefault\": \"Whether to prevent the default browser behavior for the hotkey. Default is true, which stops the browser from performing its normal action (e.g., Ctrl+S won't show the save dialog).\",\n    \"sequenceTimeout\": \"Timeout in milliseconds for completing key sequences. Default is 1000ms. If the next key in a sequence isn't pressed within this time, the sequence resets. Only applies to sequential hotkeys (those with '-' separators).\"\n  },\n  \"returns\": {\n    \"cleanup\": \"A cleanup function that removes the event listener and clears any active timers. Automatically called when the component unmounts if used within a Vue component's setup function. Call manually if used outside of Vue's setup context.\"\n  },\n  \"examples\": {\n    \"basic\": \"useHotkey('cmd+s', () => save())\",\n    \"sequence\": \"useHotkey('cmd+k-t', () => openThemeSelector())\",\n    \"options\": \"useHotkey('enter', handleSubmit, { inputs: true, event: 'keyup' })\",\n    \"reactive\": \"useHotkey(computed(() => settings.hotkey), handleAction)\",\n    \"cleanup\": \"const cleanup = useHotkey('esc', close); onBeforeUnmount(cleanup)\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/useLayout.json",
    "content": "{\n  \"exposed\": {\n    \"getLayoutItem\": \"Function that returns position and size information about a specific layout item.\",\n    \"mainRect\": \"Position and size information for the v-main area.\",\n    \"mainStyles\": \"CSS styles applied to the v-main area.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/useLocale.json",
    "content": "{\n  \"exposed\": {\n    \"current\": \"Current locale.\",\n    \"fallback\": \"Fallback locale.\",\n    \"isRtl\": \"Indicates if RTL is currently active or not.\",\n    \"messages\": \"Locale messages.\",\n    \"n\": \"Function to localize numbers.\",\n    \"name\": \"Name of the locale adapter used.\",\n    \"provide\": \"**FOR INTERNAL USE ONLY**\",\n    \"rtl\": \"**FOR INTERNAL USE ONLY**\",\n    \"rtlClasses\": \"**FOR INTERNAL USE ONLY**\",\n    \"t\": \"Function to localize strings.\",\n    \"decimalSeparator\": \"The decimal separator character for the current locale (e.g. `.` for en, `,` for de).\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/useMask.json",
    "content": "{\n  \"exposed\": {\n    \"isValid\": \"Check if a string is valid for the mask.\",\n    \"isComplete\": \"Check if a string is complete for the mask.\",\n    \"mask\": \"Apply mask to a string.\",\n    \"unmask\": \"Remove mask from a string.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/useRtl.json",
    "content": "{\n  \"exposed\": {\n    \"isRtl\": \"Indicates if RTL is currently active or not.\",\n    \"rtlClasses\": \"**FOR INTERNAL USE ONLY**\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/useTheme.json",
    "content": "{\n  \"exposed\": {\n    \"change\": \"Change to a specific theme.\",\n    \"toggle\": \"Toggle between two themes.\",\n    \"cycle\": \"Cycle between all or a subset of themes.\",\n    \"computedThemes\": \"Object containing all parsed theme definitions.\",\n    \"current\": \"Current theme object.\",\n    \"global\": \"Reference to the global theme instance.\",\n    \"isDisabled\": \"Indicates if theming is disabled.\",\n    \"isSystem\": \"Indicates if the current theme was resolved from the system preference (`prefers-color-scheme`).\",\n    \"name\": \"Name of current theme.\",\n    \"prefix\": \"**FOR INTERNAL USE ONLY**\",\n    \"scoped\": \"**FOR INTERNAL USE ONLY**\",\n    \"styles\": \"**FOR INTERNAL USE ONLY**\",\n    \"themeClasses\": \"**FOR INTERNAL USE ONLY**\",\n    \"themes\": \"Raw theme definitions.\",\n    \"utilities\": \"**FOR INTERNAL USE ONLY**\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/v-click-outside.json",
    "content": "{\n  \"value\": \"Takes either a function that is invoked when user clicks outside of the element the directive is attached to, or an object containing `handler`, `closeConditional` and `include` callbacks.\",\n  \"modifiers\": {\n    \"[string]\": \"Custom modifier keys that can be used to configure directive behavior.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/v-intersect.json",
    "content": "{\n  \"value\": \"A handler function that is invoked when the element that the directive is attached to enters or leaves the visible browser area, or an object of [IntersectionObserver options](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver/IntersectionObserver).\",\n  \"modifiers\": {\n    \"once\": \"The handler function is only invoked once, the first time the element is visible.\",\n    \"quiet\": \"Will not invoke the handler function if the element is visible when the IntersectionObserver is created.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/v-mutate.json",
    "content": "{\n  \"value\": \"A handler function that is invoked when the element that the directive is attached to is mutated, or an object of [MutationObserver options](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/observe).\",\n  \"modifiers\": {\n    \"attr\": \"Sets the value of [attributes](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserverInit/attributes) to true.\",\n    \"char\": \"Sets the value of [characterData](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserverInit/characterData) to true.\",\n    \"child\": \"Sets the value of [childList](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserverInit/childList) to true.\",\n    \"immediate\": \"The provided handler function is invoked immediately when directive is attached to element.\",\n    \"once\": \"The provided handler function is only invoked once.\",\n    \"sub\": \"Sets the value of [subtree](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/observe#Parameters) to true.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/v-resize.json",
    "content": "{\n  \"value\": \"A function that will be invoked each time the browser window is resized.\",\n  \"modifiers\": {\n    \"active\": \"By default the resize event listener is added to window with the `passive` option. This modifier sets `passive` to **false**.\",\n    \"quiet\": \"By default the provided handler function is invoked once when the directive is attached to the element. This modifier disables that behavior.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/v-ripple.json",
    "content": "{\n  \"value\": \"An object containing options for the ripple effect. `class` applies a custom class to the ripple, and can be used for changing color. `center` forces the ripple to originate from the center of the target instead of the cursor position.\",\n  \"modifiers\": {\n    \"center\": \"Makes it so that the ripple originates from the center of the element, instead where the user clicked on it.\",\n    \"circle\": \"Changes the ripple behavior to better match circular elements.\",\n    \"stop\": \"Prevents ripples from being triggered on any other elements when the click event is bubbling up.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/v-scroll.json",
    "content": "{\n  \"argument\": \"Specify a query selector to attach the scroll event listener to. If no argument is provided then it is attached to the window object.\",\n  \"value\": \"A handler function that is invoked whenever the target element is scrolled, or an object of [event listener options](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener).\",\n  \"modifiers\": {\n    \"self\": \"By default the scroll event listener is attached to the argument provided to the directive, interpreted as a query selector. If no argument is provided then it is attached to the window object. If this modifier is used then it is instead attached to the element the directive is used on.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/v-tooltip.json",
    "content": "{\n  \"argument\": \"Applies the VTooltip location prop.\",\n  \"value\": \"**string**: Sets the tooltip content.  \\n**boolean**: Controls visibility, tooltip content will be the innerText of the bound element.  \\n**object**: Use any [VTooltip props](/api/v-tooltip), content can be set with `text`. Keys are camelCase.\"\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/v-touch.json",
    "content": "{\n  \"value\": \"The value is always an object. The `start`, `end`, `move`, `left`, `right`, `up` and `down` functions can be used to invoke a function when the corresponding touch action occurs. If the `parent` option attaches the touch listeners to the parent element instead of the element the directive is used on. The `options` object is described [here](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener).\",\n  \"modifiers\": {\n    \"[string]\": \"Custom modifier keys that can be used to configure directive behavior.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/validation.json",
    "content": "{\n  \"props\": {\n    \"error\": \"Puts the input in a manual error state.\",\n    \"errorCount\": \"The total number of errors that should display at once.\",\n    \"errorMessages\": \"Puts the input in an error state and passes through custom error messages. Will be combined with any validations that occur from the **rules** prop. This field will not trigger validation.\",\n    \"readonly\": \"Puts input in readonly state.\",\n    \"rules\": \"Accepts a mixed array of types `function`, `boolean` and `string`. Functions pass an input value as an argument and must return either `true` / `false` or a `string` containing an error message. The input field will enter an error state if a function returns (or any value in the array contains) `false` or is a `string`.\",\n    \"success\": \"Puts the input in a manual success state.\",\n    \"successMessages\": \"Puts the input in a success state and passes through custom success messages.\",\n    \"validateOnBlur\": \"Delays validation until blur event.\",\n    \"maxErrors\": \"Control the maximum number of shown errors from validation.\",\n    \"validateOn\": \"Change what type of event triggers validation to run.\",\n    \"validationValue\": \"The value used when applying validation rules.\"\n  },\n  \"events\": {\n    \"update:error\": \"The `v-model:error` event.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/locale/en/virtual.json",
    "content": "{\n  \"props\": {\n    \"itemHeight\": \"Height in pixels of each item to display.\"\n  },\n  \"exposed\": {\n    \"scrollToIndex\": \"Scrolls to the item at a given index.\"\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/shims.d.ts",
    "content": "import '@ts-morph/common'\n\ndeclare module 'ts-morph' {\n  export interface Type {\n    _context: {\n      compilerFactory: {\n        getType<TType extends ts.Type>(type: TType): Type<TType>\n      }\n    }\n  }\n\n  namespace ts {\n    interface Type {\n      indexInfos: {\n        keyType: Type\n        type: Type\n      }[]\n    }\n  }\n}\n\nexport {}\n"
  },
  {
    "path": "packages/api-generator/src/types.ts",
    "content": "import type { Node, Type } from 'ts-morph'\nimport { Project, ts } from 'ts-morph'\nimport { prettifyType } from './utils.ts'\nimport { kebabCase } from './helpers/text.ts'\n\nconst project = new Project({\n  tsConfigFilePath: './tsconfig.json',\n})\n\nasync function inspect (project: Project, node?: Node<ts.Node>) {\n  if (!node) throw new Error('No node provided')\n\n  const kind = node.getKind()\n\n  if (kind === ts.SyntaxKind.TypeAliasDeclaration) {\n    const definition = generateDefinition(node, [], project) as ObjectDefinition\n    if (definition.properties) {\n      definition.properties = Object.fromEntries(\n        await Promise.all(\n          Object.entries(definition.properties)\n            // Exclude private properties\n            .filter(([name]) => !name.startsWith('$') && !name.startsWith('_') && !name.startsWith('Ψ'))\n            .map(async ([name, prop]) => [\n              name.replace('Uncapitalize<Capitalize<string>>', 'string'),\n              await prettifyType(name, prop),\n            ])\n        )\n      )\n    }\n    return definition\n  }\n\n  throw new Error(`Unsupported node kind: ${kind}`)\n}\n\nexport async function generateComposableDataFromTypes (): Promise<ComposableData[]> {\n  const sourceFile = project.addSourceFileAtPath('./templates/composables.d.ts')\n\n  const composables = await inspect(project, sourceFile.getTypeAlias('Composables'))\n\n  return Promise.all(\n    Object.entries(composables.properties).map(async ([name, data]) => {\n      const returnType = (data as FunctionDefinition).returnType\n      let exposed: Record<string, Definition> = {}\n      if (returnType.type === 'allOf') {\n        exposed = returnType.items.reduce((acc, item) => {\n          const props = (item as ObjectDefinition).properties\n          Object.assign(acc, props)\n          return acc\n        }, {})\n      } else if (returnType.type === 'object') {\n        exposed = returnType.properties\n      }\n      if (exposed) {\n        exposed = Object.fromEntries(\n          await Promise.all(\n            Object.entries(exposed)\n              .map(async ([name, prop]) => [name, await prettifyType(name, prop)])\n          )\n        )\n      }\n\n      const kebabName = kebabCase(name)\n\n      return {\n        fileName: name,\n        displayName: name,\n        pathName: kebabName,\n        exposed,\n      }\n    })\n  )\n}\n\nexport async function generateDirectiveDataFromTypes (): Promise<DirectiveData[]> {\n  const sourceFile = project.addSourceFileAtPath('./templates/directives.d.ts')\n\n  const directives = await inspect(project, sourceFile.getTypeAlias('Directives'))\n\n  return Promise.all(\n    Object.entries(directives.properties).map(async ([name, data]) => {\n      const kebabName = kebabCase(name)\n      return {\n        fileName: `v-${kebabName}`,\n        displayName: `v-${kebabName}`,\n        pathName: `v-${kebabName}-directive`,\n        value: await prettifyType(name, (data as ObjectDefinition).properties.value),\n        argument: (data as ObjectDefinition).properties.arg,\n        modifiers: ((data as ObjectDefinition).properties.modifiers as ObjectDefinition).properties,\n      }\n    })\n  )\n}\n\nexport async function generateComponentDataFromTypes (component: string): Promise<ComponentData> {\n  const sourceFile = project.addSourceFileAtPath(`./templates/tmp/${component}.d.ts`)\n\n  const [\n    props,\n    events,\n    slots,\n    exposed,\n  ] = await Promise.all([\n    inspect(project, sourceFile.getTypeAlias('ComponentProps')),\n    inspect(project, sourceFile.getTypeAlias('ComponentEvents')),\n    inspect(project, sourceFile.getTypeAlias('ComponentSlots')),\n    inspect(project, sourceFile.getTypeAlias('ComponentExposed')),\n  ])\n\n  const sections = [props, events, slots, exposed]\n\n  sections.forEach(item => {\n    item.text = undefined!\n    item.source = undefined\n  })\n\n  for (const [name, { formatted }] of Object.entries(props.properties)) {\n    if (formatted.length > 400) {\n      console.log(`\\x1b[33mLong prop type (${formatted.length}): ${component}.${name}\\x1b[0m`)\n    }\n  }\n\n  return {\n    props: props.properties,\n    events: events.properties,\n    slots: slots.properties,\n    exposed: exposed.properties,\n    displayName: component,\n    fileName: component,\n    pathName: kebabCase(component),\n    sass: {},\n  }\n}\n\ntype BaseDefinition = {\n  text: string\n  formatted: string\n  source?: string\n  description?: Record<string, string>\n  descriptionSource?: Record<string, string>\n  default?: string\n  optional?: boolean\n}\n\nexport type ObjectDefinition = {\n  type: 'object'\n  properties: Record<string, Definition>\n} & BaseDefinition\n\ntype BooleanDefinition = {\n  type: 'boolean'\n  literal?: string\n} & BaseDefinition\n\ntype StringDefinition = {\n  type: 'string'\n  literal?: string\n} & BaseDefinition\n\ntype NumberDefinition = {\n  type: 'number'\n  literal?: string\n} & BaseDefinition\n\ntype UnionDefinition = {\n  type: 'anyOf'\n  items: Definition[]\n} & BaseDefinition\n\ntype IntersectionDefinition = {\n  type: 'allOf'\n  items: Definition[]\n} & BaseDefinition\n\ntype ArrayDefinition = {\n  type: 'array'\n  items: Definition[]\n  length?: number\n} & BaseDefinition\n\ntype FunctionDefinition = {\n  type: 'function'\n  parameters: NamedDefinition[]\n  returnType: Definition\n} & BaseDefinition\n\ntype RefDefinition = {\n  type: 'ref'\n  ref: string\n} & BaseDefinition\n\ntype ConstructorDefinition = {\n  type: 'constructor'\n} & BaseDefinition\n\ntype RecordDefinition = {\n  type: 'record'\n  key: Definition\n  value: Definition\n} & BaseDefinition\n\ntype InterfaceDefinition = {\n  type: 'interface'\n  name: string\n  parameters: NamedDefinition[]\n} & BaseDefinition\n\ntype NamedDefinition = Definition & { name: string }\n\nexport type Definition =\n  | ObjectDefinition\n  | BooleanDefinition\n  | StringDefinition\n  | NumberDefinition\n  | UnionDefinition\n  | IntersectionDefinition\n  | ArrayDefinition\n  | FunctionDefinition\n  | RefDefinition\n  | ConstructorDefinition\n  | RecordDefinition\n  | InterfaceDefinition\n\nexport type BaseData = {\n  displayName: string // user visible name used in page titles\n  fileName: string // file name for translation strings and generated types\n  pathName: string // kebab-case name for use in urls\n}\nexport type ComponentData = BaseData & {\n  sass: Record<string, { default: string }>\n  props: Record<string, Definition>\n  slots: Record<string, Definition>\n  events: Record<string, Definition>\n  exposed: Record<string, Definition>\n  value?: never\n  argument?: never\n  modifiers?: never\n}\nexport type DirectiveData = BaseData & {\n  sass?: never\n  props?: never\n  slots?: never\n  events?: never\n  exposed?: never\n  value: Definition\n  argument: Definition\n  modifiers: Record<string, Definition>\n}\nexport type ComposableData = BaseData & {\n  sass?: never\n  props?: never\n  slots?: never\n  events?: never\n  exposed: Record<string, Definition>\n  value?: never\n  argument?: never\n  modifiers?: never\n}\nexport type PartData = ComponentData | DirectiveData | ComposableData\n\nfunction isExternalDeclaration (declaration?: Node<ts.Node>, definitionText?: string) {\n  const filePath = declaration?.getSourceFile().getFilePath()\n\n  // Some internal typescript types should be processed (Array etc)\n  if (filePath?.includes('/typescript/lib/') && (\n    definitionText?.endsWith('[]') ||\n    /(Record|Map|Set|NonNullable)<.*?>/.test(definitionText ?? '')\n  )) return false\n\n  if (filePath?.includes('/@vue/') && /^ToRefs<.*?>/.test(definitionText!)) {\n    return false\n  }\n\n  return filePath?.includes('/node_modules/')\n}\n\nfunction getSource (declaration?: Node<ts.Node>) {\n  const filePath = declaration?.getSourceFile().getFilePath()\n    .replace(/.*\\/node_modules\\//, '')\n    .replace(/.*\\/packages\\/vuetify\\//, 'vuetify/')\n  const startLine = declaration?.getStartLineNumber()\n  const endLine = declaration?.getEndLineNumber()\n\n  if (!filePath || !startLine || filePath.startsWith(process.cwd())) return undefined\n\n  return filePath && startLine ? `${filePath}#L${startLine}-L${endLine}` : undefined\n}\n\n// function listFlags (flags: object, value?: number) {\n//   if (!value) return []\n\n//   const entries = Object.entries(flags).filter(([_, flag]) => typeof flag === 'number')\n\n//   return entries.reduce<string[]>((arr, [name, flag]) => {\n//     if (value & flag) {\n//       arr.push(name)\n//     }\n//     return arr\n//   }, [])\n// }\n\nfunction getCleanText (text: string) {\n  return text.replace(/import\\(.*?\\)\\./g, '')\n}\n\nfunction count (arr: string[], needle: string) {\n  return arr.reduce((count, str) => {\n    return str === needle ? count + 1 : count\n  }, 0)\n}\n\n// Types that are displayed as links\nconst allowedRefs = [\n  'Anchor',\n  'ActiveStrategy',\n  'DataIteratorItem',\n  'DataTableHeader',\n  'DataTableItem',\n  'FilterFunction',\n  'FormValidationResult',\n  'Group',\n  'GroupSummary',\n  'InternalDataTableHeader',\n  'ListItem',\n  'LocationStrategyFunction',\n  'OpenSelectStrategyFunction',\n  'OpenStrategy',\n  'OpenStrategyFunction',\n  'ScrollStrategyFunction',\n  'SelectableItem',\n  'SelectItemKey',\n  'SelectStrategy',\n  'SelectStrategyFunction',\n  'SortItem',\n  'SubmitEventPromise',\n  'ItemKeySlot',\n  'TemplateRef',\n  'TouchHandlers',\n  'ValidationRule',\n  'CalendarTimestamp',\n  'CalendarDaySlotScope',\n  'CalendarEventParsed',\n  'CalendarEventVisual',\n]\n\n// Types that displayed without their generic arguments\nconst plainRefs = [\n  'Component',\n  'ComponentPublicInstance',\n  'ComponentInternalInstance',\n  'FunctionalComponent',\n  'DataTableItem',\n  'ListItem',\n  'Group',\n  'GroupSummary',\n  'DataIteratorItem',\n  'ItemKeySlot',\n  'SelectItemKey',\n]\n\nfunction formatDefinition (definition: Definition) {\n  let formatted = ''\n\n  switch (definition.type) {\n    case 'allOf':\n      formatted = `${definition.items.map(item => item.formatted).join(' & ')}`\n      break\n    case 'anyOf': {\n      const formattedItems = definition.items.map(item => (\n        ['function', 'constructor'].includes(item.type) ? `(${item.formatted})` : item.formatted\n      )).filter(item => item !== 'null' && item !== 'undefined')\n      formatted = `${formattedItems.join(' | ')}`\n      break\n    }\n    case 'array': {\n      const formattedItems = definition.items.map(item => (\n        ['function', 'constructor', 'allOf', 'anyOf'].includes(item.type) ? `(${item.formatted})` : item.formatted)\n      ).filter(item => item !== 'null' && item !== 'undefined')\n      if (definition.length) {\n        formatted = `[${formattedItems.join(', ')}]`\n      } else {\n        formatted = `${definition.items.length > 1 ? '(' : ''}${formattedItems.join(' | ')}${definition.items.length > 1 ? ')' : ''}[]`\n      }\n      break\n    }\n    case 'function':\n      const formattedParameters = definition.parameters.map(p => `${p.name}: ${p.formatted}`)\n      formatted = `(${formattedParameters.join(', ')}) => ${definition.returnType.formatted}`\n      break\n    case 'record':\n      formatted = `Record<${definition.key.formatted}, ${definition.value.formatted}>`\n      break\n    case 'object':\n      formatted = `{ ${Object.entries(definition.properties).reduce<string[]>((arr, [name, prop]) => {\n        if (name.includes(':') || name.includes('-')) name = `'${name}'`\n        arr.push(`${name}: ${prop.formatted}`)\n        return arr\n      }, []).join('; ')} }`\n      break\n    case 'ref':\n      if (plainRefs.includes(definition.ref)) {\n        formatted = definition.ref\n      } else {\n        formatted = definition.text\n      }\n      if (allowedRefs.includes(definition.ref)) {\n        formatted = `<a href=\"https://github.com/vuetifyjs/vuetify/blob/master/packages/${definition.source}\" target=\"_blank\">${formatted}</a>`\n      }\n      break\n    case 'interface':\n    case 'boolean':\n    case 'number':\n    case 'string':\n    case 'constructor':\n    default:\n      formatted = definition.text\n      break\n  }\n\n  definition.formatted = formatted\n}\n\n// eslint-disable-next-line complexity\nfunction generateDefinition (node: Node<ts.Node>, recursed: string[], project: Project, type?: Type<ts.Type>): Definition {\n  const tc = project.getTypeChecker()\n  type = type ?? node.getType()\n\n  if (type.getAliasSymbol()?.getName() === 'NonNullable') {\n    const typeArguments = type.getAliasTypeArguments()\n    if (typeArguments.length) {\n      type = typeArguments[0]\n    }\n  }\n\n  const symbol = type.getAliasSymbol() ?? type.getSymbol()\n  const declaration = symbol?.getDeclarations()?.[0]\n  const targetType = type.getTargetType()\n\n  let definition: Definition = {\n    text: getCleanText(type.getText()),\n    source: getSource(declaration),\n  } as Definition\n\n  if (\n    count(recursed, type.getText()) > 1 ||\n    allowedRefs.includes(symbol?.getName() as string) ||\n    isExternalDeclaration(declaration, definition.text)\n  ) {\n    definition = definition as RefDefinition\n    definition.type = 'ref'\n\n    // TODO: Parse this better?\n    definition.ref = symbol?.getFullyQualifiedName().replace(/\".*\"\\./, '') ?? ''\n  } else if (type.isAny() || type.isUnknown() || type.isNever()) {\n    // @ts-expect-error asd\n    definition.type = type.getText()\n  } else if (type.isBoolean() || type.isBooleanLiteral()) {\n    definition = definition as BooleanDefinition\n    definition.type = 'boolean'\n    definition.literal = type.isBooleanLiteral() ? type.getText() : undefined\n  } else if (type.isString() || type.isStringLiteral()) {\n    definition = definition as StringDefinition\n    definition.type = 'string'\n    definition.literal = type.isStringLiteral() ? type.getText() : undefined\n  } else if (type.isNumber() || type.isNumberLiteral()) {\n    definition = definition as NumberDefinition\n    definition.type = 'number'\n    definition.literal = type.isNumberLiteral() ? type.getText() : undefined\n  } else if (type.isArray()) {\n    definition = definition as ArrayDefinition\n    definition.type = 'array'\n\n    const arrayElementType = type.getArrayElementType()\n\n    const arrayType = generateDefinition(node, getRecursiveTypes(recursed, type), project, arrayElementType)\n\n    definition.items = arrayType.type === 'anyOf' ? arrayType.items : [arrayType]\n  } else if (type.isIntersection()) {\n    definition = definition as IntersectionDefinition\n    definition.type = 'allOf'\n    definition.items = type.getIntersectionTypes()\n      .map(intersectionType => generateDefinition(node, recursed, project, intersectionType))\n\n    // TODO: Should we collapse allOf with only objects to single object?\n  } else if (type.isUnion()) {\n    definition = definition as UnionDefinition\n    definition.type = 'anyOf'\n    definition.items = getUnionTypes(type)\n      .map(unionType => generateDefinition(node, recursed, project, unionType))\n\n    // Replace explicit true|false with boolean\n    // TODO: Do this some other way\n    let found = -1\n    for (let i = 0; i < definition.items.length; i++) {\n      const item = definition.items[i]\n\n      if (item.type === 'boolean' && item.literal != null) {\n        if (~found) {\n          definition.items.splice(i, 1)\n          definition.items.splice(found, 1, {\n            text: 'boolean',\n            type: 'boolean',\n            formatted: 'boolean',\n          })\n          break\n        } else {\n          found = i\n        }\n      }\n    }\n  } else if (type.getConstructSignatures().length) {\n    definition = definition as ConstructorDefinition\n    definition.type = 'constructor'\n  } else if (type.getCallSignatures().length) {\n    definition = definition as FunctionDefinition\n    definition.type = 'function'\n\n    const signature = type.getCallSignatures()[0]\n\n    definition.parameters = signature.getParameters().map(parameter => {\n      const parameterType = tc.getTypeOfSymbolAtLocation(parameter, node)\n      return {\n        name: parameter.getEscapedName(),\n        optional: parameter.isOptional(),\n        ...generateDefinition(node, getRecursiveTypes(recursed, parameterType), project, parameterType),\n      }\n    })\n    const returnType = signature.getReturnType()\n    definition.returnType = generateDefinition(node, getRecursiveTypes(recursed, returnType), project, returnType)\n  } else if (targetType && /^(Map|Set)<.*>/.test(definition.text)) { // TODO: Better way to detect Map/Set type\n    definition = definition as InterfaceDefinition\n    definition.type = 'interface'\n    definition.name = targetType?.getText()\n    const instanceTypeArguments = type.getTypeArguments()\n    definition.parameters = targetType?.getTypeArguments().map((arg, i) => {\n      return { name: arg.getText(), ...generateDefinition(node, recursed, project, instanceTypeArguments[i]) }\n    })\n  } else if (/^Record<.*>/.test(definition.text)) { // TODO: Better way to detect Record type\n    definition = definition as RecordDefinition\n    definition.type = 'record'\n    definition.key = generateDefinition(node, recursed, project, type.getAliasTypeArguments()[0])\n    definition.value = generateDefinition(node, recursed, project, type.getAliasTypeArguments()[1])\n  } else if (type.isTuple()) {\n    definition = definition as ArrayDefinition\n    definition.type = 'array'\n    definition.items = type.getTupleElements().map(t => generateDefinition(node, recursed, project, t))\n    definition.length = definition.items.length\n  } else if (type.isObject()) {\n    definition = definition as ObjectDefinition\n    definition.type = 'object'\n    definition.properties = {}\n\n    for (const property of type.getProperties()) {\n      const propertyName = property.getEscapedName()\n      const propertyType = tc.getTypeOfSymbolAtLocation(property, node)\n\n      definition.properties[propertyName] = generateDefinition(node, getRecursiveTypes(recursed, propertyType), project, propertyType)\n\n      definition.properties[propertyName].optional = property.isOptional()\n    }\n    if (type.compilerType.indexInfos.length) {\n      for (const index of type.compilerType.indexInfos) {\n        const indexName = '[' + type._context.compilerFactory.getType(index.keyType).getText() + ']'\n        const indexType = type._context.compilerFactory.getType(index.type)\n        definition.properties[indexName] = generateDefinition(node, getRecursiveTypes(recursed, indexType), project, indexType)\n        definition.properties[indexName].optional = true\n      }\n    }\n  } else if (ts.TypeFlags.Void & type.getFlags()) {\n    // @ts-expect-error asd\n    definition.type = 'void'\n  } else {\n    // @ts-expect-error asd\n    definition.type = 'UNSUPPORTED'\n  }\n\n  formatDefinition(definition)\n\n  return definition\n}\n\n/** type.getUnionTypes() but without unwrapping named string unions */\nfunction getUnionTypes (type: Type<ts.Type>): Type<ts.Type>[] {\n  if (!type.isUnion()) return [type]\n\n  const compilerType = (type as any).compilerType\n\n  if (compilerType.origin) {\n    return compilerType.origin.types\n      .map((unionType: any) => (type as any)._context.compilerFactory.getType(unionType))\n  } else {\n    return type.getUnionTypes()\n  }\n}\n\n// function getRecursiveObjectTypes (recursiveTypes: string[], type: Type<ts.Type>) {\n//   return recursiveTypes.slice().concat(findPotentialRecursiveObjectTypes(type))\n// }\n\n// function getRecursiveArrayTypes (recursiveTypes: string[], type: Type<ts.Type>) {\n//   return recursiveTypes.slice().concat(findPotentialRecursiveArrayTypes(type))\n// }\n\n// function findPotentialRecursiveObjectTypes (type: Type<ts.Type>) {\n//   if (type == null || type.isArray()) return []\n\n//   const recursiveTypes = []\n\n//   if (type.isUnionOrIntersection()) {\n//     recursiveTypes.push(...type.getAliasTypeArguments().map(t => t.getText()))\n//   } else if (type.getAliasSymbol() || type.isClassOrInterface() || type.getTypeArguments().length) {\n//     recursiveTypes.push(type.getText())\n//   }\n\n//   return recursiveTypes\n// }\n\n// function findPotentialRecursiveArrayTypes (type: Type<ts.Type>) {\n//   if (type == null) return []\n\n//   const recursiveTypes = []\n\n//   if (type.isUnionOrIntersection()) {\n//     recursiveTypes.push(...type.getAliasTypeArguments().map(t => t.getText()))\n//   } else if (type.isArray()) {\n//     recursiveTypes.push(...findPotentialRecursiveArrayTypes(type.getArrayElementType()))\n//   } else if (type.getAliasSymbol() || type.isClassOrInterface() || type.getTypeArguments().length) {\n//     recursiveTypes.push(type.getText())\n//   }\n\n//   return recursiveTypes\n// }\n\nfunction getRecursiveTypes (recursiveTypes: string[], type: Type<ts.Type>) {\n  return recursiveTypes.slice().concat(findPotentialRecursiveTypes(type))\n}\n\nfunction findPotentialRecursiveTypes (type?: Type<ts.Type>): string[] {\n  if (type == null) return []\n\n  const recursiveTypes: string[] = []\n\n  if (type.isUnion()) {\n    recursiveTypes.push(...getUnionTypes(type).map(t => t.getText()))\n  } else if (type.isIntersection()) {\n    recursiveTypes.push(...type.getIntersectionTypes().map(t => t.getText()))\n  } else if (type.isArray()) {\n    recursiveTypes.push(...findPotentialRecursiveTypes(type.getArrayElementType()))\n  } else if (type.getAliasSymbol() || type.isClassOrInterface() || type.getTypeArguments().length) {\n    recursiveTypes.push(type.getText())\n  }\n\n  return recursiveTypes\n}\n"
  },
  {
    "path": "packages/api-generator/src/utils.ts",
    "content": "import { execSync } from 'node:child_process'\nimport stringifyObject from 'stringify-object'\nimport prettier from 'prettier'\nimport * as typescriptParser from 'prettier/plugins/typescript'\nimport type { Definition, DirectiveData } from './types.ts'\n\nfunction parseFunctionParams (func: string) {\n  const [, regular] = /function\\s\\((.*)\\)\\s\\{.*/i.exec(func) || []\n  const [, arrow] = /\\((.*)\\)\\s=>\\s\\{.*/i.exec(func) || []\n  const args = regular || arrow\n\n  return args ? `(${args}) => {}` : undefined\n}\n\nfunction getPropType (type: any | any[]): string | string[] {\n  if (Array.isArray(type)) {\n    return type.flatMap(t => getPropType(t))\n  }\n\n  if (!type) return 'any'\n\n  return type.name.toLowerCase()\n}\n\nfunction getPropDefault (definition: any, type: string | string[]) {\n  const def = definition?.default\n\n  if (typeof def === 'function' && type !== 'function') {\n    return def.call({}, {})\n  }\n\n  if (typeof def === 'string') {\n    return def ? `'${def}'` : def\n  }\n\n  if (type === 'function') {\n    return parseFunctionParams(def)\n  }\n\n  if ((!definition || !('default' in definition)) && (\n    type === 'boolean' ||\n    (Array.isArray(type) && type.includes('boolean'))\n  )) {\n    return false\n  }\n\n  return def\n}\n\ntype ComponentData = {\n  props?: Record<string, Definition>\n  slots?: Record<string, Definition>\n  events?: Record<string, Definition>\n  exposed?: Record<string, Definition>\n}\n\nexport function addPropData (\n  name: string,\n  componentData: ComponentData,\n  componentProps: any\n) {\n  const sources = new Set<string>()\n  for (const [propName, propObj] of Object.entries(componentData.props ?? {})) {\n    const instancePropObj = componentProps[propName]\n\n    ;(propObj as any).default = instancePropObj?.default\n    ;(propObj as any).source = instancePropObj?.source\n\n    sources.add(instancePropObj?.source ?? name)\n  }\n\n  return [...sources.values()]\n}\n\nexport function stringifyProps (props: any) {\n  return Object.fromEntries(\n    Object.entries<any>(props).map(([key, prop]) => {\n      let def = typeof prop === 'object'\n        ? getPropDefault(prop, getPropType(prop?.type))\n        : getPropDefault(undefined, getPropType(prop))\n\n      if (typeof def === 'object') {\n        def = stringifyObject(def, {\n          indent: '  ',\n          inlineCharacterLimit: 60,\n          filter (obj, property) {\n            if (typeof obj === 'object' && !Array.isArray(obj) && obj != null && 'name' in obj && 'props' in obj && 'setup' in obj) {\n              return property === 'name'\n            }\n            return true\n          },\n        })\n      }\n\n      return [key, {\n        source: prop?.source,\n        default: def,\n      }]\n    })\n  )\n}\n\nconst localeCache = new Map<string, object>()\nasync function loadLocale (componentName: string, locale: string): Promise<Record<string, string | Record<string, string>>> {\n  const cacheKey = `${locale}/${componentName}`\n  if (localeCache.has(cacheKey)) {\n    return localeCache.get(cacheKey) as any\n  }\n  try {\n    const data = await import(`../src/locale/${cacheKey}.json`, {\n      with: { type: 'json' },\n    })\n    localeCache.set(cacheKey, data.default)\n    return data.default\n  } catch (err: any) {\n    if (err.code === 'ERR_MODULE_NOT_FOUND') {\n      console.error(`\\x1b[35mMissing locale for ${cacheKey}\\x1b[0m`)\n      localeCache.set(cacheKey, {})\n    } else {\n      console.error('\\x1b[31m', err.message, '\\x1b[0m')\n    }\n    return {}\n  }\n}\n\nconst currentBranch = execSync('git branch --show-current', { encoding: 'utf-8' }).trim()\n\ntype MissingDescription = {\n  name: string\n  section: string\n  key: string\n  locale: string\n}\n\nconst missingDescriptions: MissingDescription[] = []\n\nexport function reportMissingDescriptions () {\n  if (!missingDescriptions.length) return\n\n  const red = '\\x1b[31m'\n  const reset = '\\x1b[0m'\n  const space = '\\x20'\n\n  console.warn(`\\n${red}Missing API Descriptions:${reset}`)\n  missingDescriptions.forEach(({ name, section, key, locale }) => {\n    console.warn(`${red}- ${name} (${locale}): [${section}]${space + key + reset}`)\n  })\n\n  // Clear missing descriptions in case of multiple runs\n  missingDescriptions.length = 0\n}\n\nasync function getSources (name: string, locale: string, sources: string[]) {\n  const arr = await Promise.all([\n    loadLocale(name, locale),\n    ...sources.map(source => loadLocale(source, locale)),\n    loadLocale('generic', locale),\n  ])\n  const sourcesMap = [name, ...sources, 'generic']\n\n  return {\n    find (section: string, key?: string, ogSource = name) {\n      for (let i = 0; i < arr.length; i++) {\n        const source = arr[i] as any\n        const found: string | undefined = ['argument', 'value'].includes(section)\n          ? source?.[section]\n          : source?.[section]?.[key!]\n        if (found) {\n          return { text: found, source: sourcesMap[i] }\n        }\n      }\n\n      // Collect missing descriptions\n      missingDescriptions.push({\n        name,\n        section,\n        key: key || '',\n        locale,\n      })\n\n      const githubUrl = `https://github.com/vuetifyjs/vuetify/tree/${currentBranch}/packages/api-generator/src/locale/${locale}/${ogSource}.json`\n      return { text: `MISSING DESCRIPTION ([edit in github](${githubUrl}))`, source: name }\n    },\n  }\n}\n\nexport async function addDescriptions (name: string, componentData: ComponentData, locales: string[], sources: string[] = []) {\n  for (const locale of locales) {\n    const descriptions = await getSources(name, locale, sources)\n\n    for (const section of ['props', 'slots', 'events', 'exposed'] as const) {\n      for (const [propName, propObj] of Object.entries(componentData[section] ?? {})) {\n        propObj.description = propObj.description ?? {}\n        propObj.descriptionSource = propObj.descriptionSource ?? {}\n\n        const found = descriptions.find(section, propName, propObj.source)\n        propObj.description![locale] = found.text\n        propObj.descriptionSource![locale] = found.source\n      }\n    }\n  }\n}\n\nexport async function addDirectiveDescriptions (\n  name: string,\n  componentData: DirectiveData,\n  locales: string[],\n  sources: string[] = [],\n) {\n  for (const locale of locales) {\n    const descriptions = await getSources(name, locale, sources)\n\n    if (componentData.value) {\n      componentData.value.description = componentData.value.description ?? {}\n      componentData.value.description[locale] = descriptions.find('value')?.text\n    }\n\n    if (componentData.argument) {\n      componentData.argument.description = componentData.argument.description ?? {}\n      componentData.argument.description[locale] = descriptions.find('argument')?.text\n    }\n\n    if (componentData.modifiers) {\n      for (const [name, modifier] of Object.entries(componentData.modifiers)) {\n        modifier.description = modifier.description ?? {}\n        modifier.description[locale] = descriptions.find('modifiers', name)?.text\n      }\n    }\n  }\n}\n\nexport function sortByKey (data: Record<string, any>) {\n  return Object.keys(data)\n    .sort()\n    .reduce((obj: Record<string, any>, key: string) => {\n      obj[key] = data[key]\n      return obj\n    }, {})\n}\n\nexport function stripLinks (str: string): [string, Record<string, string>] {\n  let out = str.slice()\n  const obj: Record<string, string> = {}\n  const regexp = /<a .+?>(.+?)<\\/a>/g\n\n  let matches = regexp.exec(str)\n\n  while (matches !== null) {\n    obj[matches[1]] = matches[0]\n    out = out.replace(matches[0], matches[1])\n\n    matches = regexp.exec(str)\n  }\n\n  return [out, obj]\n}\n\nexport function insertLinks (str: string, stripped: Record<string, string>) {\n  for (const [key, value] of Object.entries(stripped)) {\n    str = str.replaceAll(new RegExp(`(^|\\\\W)(${key})(\\\\W|$)`, 'g'), `$1${value}$3`)\n  }\n  return str\n}\n\nexport async function prettifyType (name: string, item: Definition) {\n  const prefix = 'type Type = '\n  const [str, stripped] = stripLinks(item.formatted)\n  let formatted\n  try {\n    formatted = await prettier.format(prefix + str, {\n      parser: 'typescript',\n      plugins: [typescriptParser],\n      bracketSpacing: true,\n      semi: false,\n      singleQuote: true,\n      trailingComma: 'all',\n    })\n  } catch (err: any) {\n    console.error('\\x1b[31m', `${name}:`, err.message, '\\x1b[0m')\n    return item\n  }\n\n  return {\n    ...item,\n    formatted: insertLinks(formatted, stripped).replace(/type\\sType\\s=\\s+?/m, ''),\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/src/vetur.ts",
    "content": "import fs from 'node:fs'\nimport { kebabCase } from './helpers/text.ts'\nimport type { ComponentData } from './types.ts'\n\nexport function createVeturApi (componentData: ComponentData[]) {\n  const tags = componentData.reduce((obj, component) => {\n    return {\n      ...obj,\n      [component.fileName]: {\n        attributes: Object.keys(component.props ?? {}).map(name => kebabCase(name)).sort(),\n        description: '',\n      },\n    }\n  }, {})\n\n  const attributes = componentData.reduce((obj, component) => {\n    const attrs = Object.entries(component.props ?? {}).reduce((curr, [name, prop]) => {\n      curr[`${component.fileName}/${kebabCase(name)}`] = {\n        type: prop.formatted,\n        description: prop.description!.en || '',\n      }\n\n      return curr\n    }, {} as Record<string, { type: string, description: string }>)\n    Object.assign(obj, attrs)\n    return obj\n  }, {})\n\n  fs.writeFileSync('dist/tags.json', JSON.stringify(tags, null, 2))\n  fs.writeFileSync('dist/attributes.json', JSON.stringify(attributes, null, 2))\n}\n"
  },
  {
    "path": "packages/api-generator/src/web-types.ts",
    "content": "import fs from 'node:fs'\nimport { capitalize } from './helpers/text.ts'\nimport type { ComponentData, DirectiveData } from './types.ts'\nimport pkg from '../package.json' with { type: 'json' }\n\nexport const createWebTypesApi = (componentData: ComponentData[], directiveData: DirectiveData[]) => {\n  const getDocUrl = (cmp: string, heading?: string) =>\n    `https://vuetifyjs.com/api/${cmp}` + (heading ? `#${heading}` : '')\n\n  const createTypedEntity = (name: string, type: string) => {\n    return {\n      name,\n      type,\n    }\n  }\n\n  const createTag = (component: ComponentData) => {\n    const createTagSlot = ([name, slot]: [string, any]) => {\n      return {\n        name,\n        pattern: undefined,\n        description: slot.description.en || '',\n        'doc-url': getDocUrl(component.pathName, 'slots'),\n        'vue-properties': slot.properties &&\n          Object.entries(slot.properties ?? {}).map(([name, prop]) => createTypedEntity(name, (prop as any).formatted)),\n      }\n    }\n\n    const createTagEvent = ([name, event]: [string, any]) => {\n      return {\n        name,\n        description: event.description.en || '',\n        'doc-url': getDocUrl(component.pathName, 'events'),\n        arguments: [createTypedEntity('argument', event.formatted)],\n      }\n    }\n\n    const createTagValue = (type: string) => {\n      return {\n        kind: 'expression',\n        type: type?.trim(),\n      }\n    }\n\n    const createTagAttribute = ([name, prop]: [string, any]) => {\n      return {\n        name,\n        description: prop.description.en || '',\n        'doc-url': getDocUrl(component.fileName, 'props'),\n        default: typeof prop.default !== 'string' ? JSON.stringify(prop.default) : prop.default,\n        required: undefined, // TODO: implement this\n        value: createTagValue(prop.formatted),\n        type: prop.formatted === 'boolean' ? 'boolean' : undefined, // this is deprecated but should be const 'boolean' for compatibility with 2019.2\n      }\n    }\n\n    return {\n      name: component.displayName,\n      source: {\n        module: './src/components/index.ts',\n        symbol: component.displayName,\n      },\n      aliases: undefined, // TODO: are we using this? deprecated name changes?\n      description: '', // TODO: we should probably include component description in locale files\n      'doc-url': getDocUrl(component.pathName),\n      attributes: Object.entries(component.props ?? {}).map(createTagAttribute),\n      events: Object.entries(component.events ?? {}).map(createTagEvent),\n      slots: Object.entries(component.slots ?? {}).map(createTagSlot),\n      'vue-model': { // TODO: we should expose this in api data if we can\n        prop: 'modelValue',\n        event: 'update:modelValue',\n      },\n    }\n  }\n\n  const createAttribute = (directive: DirectiveData) => {\n    const createAttributeVueArgument = (argument: any) => {\n      return {\n        pattern: undefined,\n        description: argument.description.en,\n        'doc-url': getDocUrl(directive.pathName, 'argument'),\n        required: undefined,\n      }\n    }\n\n    const createAttributeVueModifier = ([name, modifier]: [string, any]) => {\n      return {\n        name,\n        pattern: undefined,\n        description: modifier.description.en || '',\n        'doc-url': getDocUrl(directive.pathName, 'modifiers'),\n      }\n    }\n\n    const createAttributeValue = (argument: any) => {\n      return {\n        kind: 'expression',\n        type: argument.text,\n      }\n    }\n\n    return {\n      name: directive.displayName,\n      aliases: undefined,\n      description: '', // TODO: we should probably include directive description in locale files\n      'doc-url': getDocUrl(directive.pathName),\n      default: '',\n      required: false,\n      value: createAttributeValue(directive.value),\n      source: {\n        module: './src/directives/index.ts',\n        symbol: capitalize(directive.displayName.slice(2)),\n      },\n      'vue-argument': directive.argument && createAttributeVueArgument(directive.argument),\n      'vue-modifiers': directive.modifiers &&\n        Object.entries(directive.modifiers).map(createAttributeVueModifier),\n    }\n  }\n\n  const tags = componentData.map(createTag)\n  const attributes = directiveData.map(createAttribute)\n\n  const webTypes = {\n    $schema: 'https://json.schemastore.org/web-types',\n    framework: 'vue',\n    name: 'vuetify',\n    version: pkg.version,\n    contributions: {\n      html: {\n        'types-syntax': 'typescript',\n        'description-markup': 'markdown',\n        tags,\n        attributes,\n      },\n    },\n  }\n\n  fs.writeFileSync('dist/web-types.json', JSON.stringify(webTypes, null, 2))\n}\n"
  },
  {
    "path": "packages/api-generator/src/worker.ts",
    "content": "import { generateComponentDataFromTypes } from './types.ts'\n\nconst reset = '\\x1b[0m'\nconst red = '\\x1b[31m'\nconst blue = '\\x1b[34m'\n\nexport default async (componentName: string) => {\n  console.log(blue, componentName, reset)\n\n  try {\n    return await generateComponentDataFromTypes(componentName)\n  } catch (err: any) {\n    console.error(red, `${componentName}: ${err}`, err.stack, reset)\n    return null\n  }\n}\n"
  },
  {
    "path": "packages/api-generator/templates/component.d.ts",
    "content": "import type { AllowedComponentProps, ComponentOptionsBase, VNodeChild, VNodeProps, UnwrapRef } from 'vue'\nimport type { UnionToIntersection } from '@/util'\nimport type { __component__ } from '@/__name__'\n\ntype StripProps =\n  | keyof VNodeProps\n  | keyof AllowedComponentProps\n  | 'v-slots'\n  | '$children'\n  | `v-slot:${string}`\n  | `on${Capitalize<string>}Once`\ntype Event = `on${string}`\n\ntype Props<T> = T extends { $props: infer P extends object }\n  ? {\n    [K in Exclude<keyof P, StripProps | Event>]: Exclude<P[K], undefined> extends VNodeProps\n      ? unknown\n      : P[K]\n  }\n  : never\n\ntype Events<T> = T extends { $props: infer P extends object }\n  ? {\n    [K in Exclude<keyof P, StripProps> as K extends `on${infer N}`\n      ? Uncapitalize<N>\n      : never\n    ]: Exclude<P[K], undefined> extends ((...args: any[]) => any)\n      ? Parameters<Exclude<P[K], undefined>>\n      : never\n  }\n  : never\n\nexport type ComponentProps = Props<__component__>\nexport type ComponentEvents = Events<__component__>\n\ntype Slot<T extends any[] = any[]> = (...args: T) => VNodeChild\ntype Slots<\n  T extends { $props: any },\n  S = '$children' extends keyof T['$props'] ? Exclude<T['$props']['$children'], VNodeChild | { $stable?: boolean }> : never\n> = '$children' extends keyof T['$props']\n  ? ExcludeEmpty<{ [K in keyof S]-?: Exclude<S[K], undefined> extends Slot<infer A> ? A[0] : never }>\n  : never\n\ntype AtLeastOne<T, U = {[K in keyof T]: Pick<T, K> }> = Partial<T> & U[keyof U]\ntype ExcludeEmpty<T> = T extends AtLeastOne<T> ? T : never\n\nexport type ComponentSlots = Slots<__component__>\n\ntype ExtractExposed<T> = T extends ComponentOptionsBase<any, infer B, any, any, any, any, any, any>\n  ? B extends void ? never\n  : B extends { _allExposed: infer E } ? E\n  : B extends object ? B\n  : never\n  : never\n\ntype Pretty<T> = { [K in keyof T]: UnwrapRef<T[K]> }\n\n// Filter out HTMLInputElement props from exposed\ntype CleanHTMLInputElement<T> = {\n  // If key is in HTMLInputElement\n  [K in keyof T as K extends keyof HTMLInputElement\n    ? // If value is the same type in HTMLInputElement\n      T[K] extends HTMLInputElement[K]\n      ? never\n      : K\n    : K]: T[K];\n};\n\nexport type ComponentExposed = Pretty<CleanHTMLInputElement<UnionToIntersection<ExtractExposed<__component__['$options']>>>>\n"
  },
  {
    "path": "packages/api-generator/templates/composables.d.ts",
    "content": "import type vuetify from '../../vuetify/lib/framework.d.ts'\n\ntype IsComposable<T extends string | number | symbol> = T extends `use${Capitalize<infer _>}` ? T : never;\n\ntype ExtractComposables<T> = T extends object\n  ? {\n    [K in keyof T as K extends IsComposable<K> ? K : never]: T[K]\n  }\n  : never\n\nexport type Composables = Prettify<ExtractComposables<typeof vuetify>>\n\ntype Prettify<T> = { [K in keyof T]: T[K] } & {}\n"
  },
  {
    "path": "packages/api-generator/templates/directives.d.ts",
    "content": "import type { DirectiveBinding, ObjectDirective } from 'vue'\nimport type { CustomDirective } from '../../vuetify/src/composables/directiveComponent.ts'\nimport type * as directives from '../../vuetify/src/directives/index.ts'\n\ntype ExtractDirectiveBindings<T> = T extends object\n  ? {\n    [K in keyof T]: T[K] extends CustomDirective<infer M>\n      ? {\n        [K in Exclude<keyof M, 'instance' | 'oldValue' | 'dir'>]: K extends 'modifiers'\n          ? Record<string, boolean> extends M[K] ? never : M[K]\n          : K extends 'arg'\n            ? string extends M[K] ? never : M[K]\n            : M[K]\n      } & {}\n      : T[K] extends { mounted: infer M }\n        ? M extends (first: any, second: infer B) => any\n          ? B extends object\n            ? {\n              [KK in keyof B as KK extends keyof Omit<DirectiveBinding, 'modifiers' | 'value'> ? never : KK]: B[KK]\n            }\n            : never\n          : never\n        : T[K] extends ObjectDirective<any, infer B>\n          ? B extends object\n            ? { value: B, modifiers: {} }\n            : never\n          : never\n  }\n  : never\n\ntype Plain<T> = T extends object\n  ? {\n    [K in keyof T]: T[K]\n  }\n  : never\n\nexport type Directives = Plain<ExtractDirectiveBindings<typeof directives>>\n"
  },
  {
    "path": "packages/api-generator/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\",\n  \"compilerOptions\": {\n    \"strict\": true,\n    \"noUnusedLocals\": false,\n    \"module\": \"preserve\",\n    \"moduleResolution\": \"bundler\",\n    \"noEmit\": true,\n    \"noEmitOnError\": false,\n    \"resolveJsonModule\": true,\n    \"allowImportingTsExtensions\": true,\n    \"paths\": {\n      \"@/*\": [\n        \"../vuetify/src/*\"\n      ]\n    },\n  },\n  \"include\": [\n    \"./src/**/*.ts\",\n    \"./src/locale/**/*.json\",\n    \"./templates/tmp/*\"\n  ],\n}\n"
  },
  {
    "path": "packages/docs/.browserslistrc",
    "content": ">0.5%\nChrome >0 and since 2023-12\nChromeAndroid >0 and since 2023-12\nFirefox >0 and since 2023-12\nFirefoxAndroid >0 and since 2023-12\nSafari >0 and since 2023-12\niOS >0 and since 2023-12\nnot dead\nnot op_mini all\nnot and_uc 1\n"
  },
  {
    "path": "packages/docs/.eslintignore",
    "content": "src/api/*\n"
  },
  {
    "path": "packages/docs/.eslintrc.cjs",
    "content": "module.exports = {\n  rules: {\n    'no-undef': 'off',\n    'vue/multi-word-component-names': 'off',\n  },\n  overrides: [\n    {\n      files: [\n        'src/components/**/*.vue',\n      ],\n      rules: {\n        'max-len': 'off',\n      },\n    },\n    {\n      files: [\n        'src/examples/**/*.vue',\n      ],\n      rules: {\n        'max-len': 'off', // lorem ipsum is long\n        'vue/html-self-closing': ['error', {\n          html: {\n            void: 'never',\n            normal: 'never',\n            component: 'never',\n          },\n          svg: 'always',\n          math: 'always',\n        }],\n        'vue/v-slot-style': ['warn', {\n          default: 'longform',\n          named: 'longform',\n        }],\n        // 'vuetify/no-deprecated-classes': 'error',\n        // 'vuetify/grid-unknown-attributes': 'error',\n        // 'vuetify/no-legacy-grid': 'error',\n        'import/newline-after-import': ['error', { count: 1 }],\n\n        // Script blocks normally both run and render, but in examples we\n        // remove the options block so it is safe to import things in both\n        'import/first': 'off',\n        'import/no-duplicates': 'off',\n        'no-redeclare': 'off',\n        'no-use-before-define': 'off',\n        'sonarjs/no-identical-functions': 'off',\n      },\n    },\n    {\n      files: [\n        'src/examples/**/usage.vue',\n      ],\n      rules: {\n        'vue/html-self-closing': 'warn',\n      },\n    },\n  ],\n}\n"
  },
  {
    "path": "packages/docs/.gitignore",
    "content": ".DS_Store\nnode_modules\n/dist\n/src/api\n/src/pages/*\n!/src/pages/en\n.vite-ssg-temp\n\n# local env files\n.env.local\n.env.*.local\n\n# Log files\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# Editor directories and files\n.idea\n.vscode\n*.suo\n*.ntvs*\n*.njsproj\n*.sln\n*.sw?\n\n.vercel\n"
  },
  {
    "path": "packages/docs/.markdownlintrc",
    "content": "{\n  \"line-length\": false,\n  \"blanks-around-headings\": true,\n  \"single-title\": {\n    \"front_matter_title\": \"\"\n  },\n  \"no-trailing-punctuation\": false,\n  \"ol-prefix\": false,\n  \"no-inline-html\": false,\n  \"no-emphasis-as-heading\": false,\n  \"no-bare-urls\": false,\n  \"emphasis-style\": false,\n  \"link-fragments\": false,\n  \"descriptive-link-text\": false,\n  \"table-column-style\": false\n}\n"
  },
  {
    "path": "packages/docs/auto-imports.d.ts",
    "content": "/* eslint-disable */\n/* prettier-ignore */\n// @ts-nocheck\n// noinspection JSUnusedGlobalSymbols\n// Generated by unplugin-auto-import\n// biome-ignore lint: disable\nexport {}\ndeclare global {\n  const ComponentPublicInstance: typeof import('vue')['ComponentPublicInstance']\n  const EffectScope: typeof import('vue')['EffectScope']\n  const IN_BROWSER: typeof import('./src/utils/globals')['IN_BROWSER']\n  const IS_DEBUG: typeof import('./src/utils/globals')['IS_DEBUG']\n  const IS_PROD: typeof import('./src/utils/globals')['IS_PROD']\n  const IS_SERVER: typeof import('./src/utils/globals')['IS_SERVER']\n  const PropType: typeof import('vue')['PropType']\n  const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate']\n  const anyLanguagePattern: typeof import('./src/utils/routes')['anyLanguagePattern']\n  const cacheManifestEntries: typeof import('./src/utils/pwa')['cacheManifestEntries']\n  const camelCase: typeof import('lodash-es')['camelCase']\n  const camelize: typeof import('vue')['camelize']\n  const cleanCache: typeof import('./src/utils/pwa')['cleanCache']\n  const compressAndEncode: typeof import('./src/composables/bin')['compressAndEncode']\n  const computed: typeof import('vue')['computed']\n  const configureMarkdown: typeof import('./src/utils/markdown-it')['configureMarkdown']\n  const copyElementContent: typeof import('./src/utils/helpers')['copyElementContent']\n  const createAdProps: typeof import('./src/composables/ad')['createAdProps']\n  const createApp: typeof import('vue')['createApp']\n  const createCacheKey: typeof import('./src/utils/pwa')['createCacheKey']\n  const createOne: typeof import('@vuetify/one')['createOne']\n  const createPinia: typeof import('pinia')['createPinia']\n  const customRef: typeof import('vue')['customRef']\n  const decodeAndDecompress: typeof import('./src/composables/bin')['decodeAndDecompress']\n  const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']\n  const defineComponent: typeof import('vue')['defineComponent']\n  const defineStore: typeof import('pinia')['defineStore']\n  const disabledLanguagePattern: typeof import('./src/utils/routes')['disabledLanguagePattern']\n  const effectScope: typeof import('vue')['effectScope']\n  const ensureCacheableResponse: typeof import('./src/utils/pwa')['ensureCacheableResponse']\n  const eventName: typeof import('./src/utils/helpers')['eventName']\n  const genAppMetaInfo: typeof import('./src/utils/metadata')['genAppMetaInfo']\n  const genMetaInfo: typeof import('./src/utils/metadata')['genMetaInfo']\n  const generatedRoutes: typeof import('./src/utils/routes')['generatedRoutes']\n  const getActivePinia: typeof import('pinia')['getActivePinia']\n  const getBranch: typeof import('./src/utils/helpers')['getBranch']\n  const getCacheKeyForUrl: typeof import('./src/utils/pwa')['getCacheKeyForUrl']\n  const getCurrentInstance: typeof import('vue')['getCurrentInstance']\n  const getCurrentScope: typeof import('vue')['getCurrentScope']\n  const getDistance: typeof import('./src/utils/helpers')['getDistance']\n  const getMatchMedia: typeof import('./src/utils/helpers')['getMatchMedia']\n  const gtagClick: typeof import('./src/utils/analytics')['gtagClick']\n  const h: typeof import('vue')['h']\n  const inject: typeof import('vue')['inject']\n  const insertLinks: typeof import('./src/utils/api')['insertLinks']\n  const isOn: typeof import('./src/utils/helpers')['isOn']\n  const isProxy: typeof import('vue')['isProxy']\n  const isReactive: typeof import('vue')['isReactive']\n  const isReadonly: typeof import('vue')['isReadonly']\n  const isRef: typeof import('vue')['isRef']\n  const kebabCase: typeof import('lodash-es')['kebabCase']\n  const languagePattern: typeof import('./src/utils/routes')['languagePattern']\n  const leadingSlash: typeof import('./src/utils/routes')['leadingSlash']\n  const mapActions: typeof import('pinia')['mapActions']\n  const mapGetters: typeof import('pinia')['mapGetters']\n  const mapState: typeof import('pinia')['mapState']\n  const mapStores: typeof import('pinia')['mapStores']\n  const mapWritableState: typeof import('pinia')['mapWritableState']\n  const markRaw: typeof import('vue')['markRaw']\n  const markdownItRules: typeof import('./src/utils/markdown-it-rules')['default']\n  const matchPrecache: typeof import('./src/utils/pwa')['matchPrecache']\n  const mergeProps: typeof import('vue')['mergeProps']\n  const messageSW: typeof import('./src/utils/pwa')['messageSW']\n  const nextTick: typeof import('vue')['nextTick']\n  const onActivated: typeof import('vue')['onActivated']\n  const onBeforeMount: typeof import('vue')['onBeforeMount']\n  const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave']\n  const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate']\n  const onBeforeUnMount: typeof import('vue')['onBeforeUnMount']\n  const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']\n  const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']\n  const onDeactivated: typeof import('vue')['onDeactivated']\n  const onErrorCaptured: typeof import('vue')['onErrorCaptured']\n  const onMounted: typeof import('vue')['onMounted']\n  const onRenderTracked: typeof import('vue')['onRenderTracked']\n  const onRenderTriggered: typeof import('vue')['onRenderTriggered']\n  const onScopeDispose: typeof import('vue')['onScopeDispose']\n  const onServerPrefetch: typeof import('vue')['onServerPrefetch']\n  const onUnmounted: typeof import('vue')['onUnmounted']\n  const onUpdated: typeof import('vue')['onUpdated']\n  const onWatcherCleanup: typeof import('vue')['onWatcherCleanup']\n  const openCache: typeof import('./src/utils/pwa')['openCache']\n  const preferredLocale: typeof import('./src/utils/routes')['preferredLocale']\n  const propsToString: typeof import('./src/utils/helpers')['propsToString']\n  const provide: typeof import('vue')['provide']\n  const pwaStore: typeof import('./src/stores/pwa')['pwaStore']\n  const reactive: typeof import('vue')['reactive']\n  const readonly: typeof import('vue')['readonly']\n  const redirectRoutes: typeof import('./src/utils/routes')['redirectRoutes']\n  const ref: typeof import('vue')['ref']\n  const resolveComponent: typeof import('vue')['resolveComponent']\n  const rpath: typeof import('./src/utils/routes')['rpath']\n  const setActivePinia: typeof import('pinia')['setActivePinia']\n  const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix']\n  const shallowReactive: typeof import('vue')['shallowReactive']\n  const shallowReadonly: typeof import('vue')['shallowReadonly']\n  const shallowRef: typeof import('vue')['shallowRef']\n  const storeToRefs: typeof import('pinia')['storeToRefs']\n  const stripLinks: typeof import('./src/utils/api')['stripLinks']\n  const sweClick: typeof import('./src/utils/analytics')['sweClick']\n  const toRaw: typeof import('vue')['toRaw']\n  const toRef: typeof import('vue')['toRef']\n  const toRefs: typeof import('vue')['toRefs']\n  const toValue: typeof import('vue')['toValue']\n  const trailingSlash: typeof import('./src/utils/routes')['trailingSlash']\n  const triggerRef: typeof import('vue')['triggerRef']\n  const unref: typeof import('vue')['unref']\n  const upperFirst: typeof import('lodash-es')['upperFirst']\n  const useAd: typeof import('./src/composables/ad')['useAd']\n  const useAdsStore: typeof import('./src/stores/ads')['useAdsStore']\n  const useAppStore: typeof import('./src/stores/app')['useAppStore']\n  const useAttrs: typeof import('vue')['useAttrs']\n  const useAuthStore: typeof import('@vuetify/one')['useAuthStore']\n  const useBin: typeof import('./src/composables/bin')['useBin']\n  const useCommitsStore: typeof import('./src/stores/commits')['useCommitsStore']\n  const useCosmic: typeof import('./src/composables/cosmic')['useCosmic']\n  const useCssModule: typeof import('vue')['useCssModule']\n  const useCssVars: typeof import('vue')['useCssVars']\n  const useDate: typeof import('vuetify')['useDate']\n  const useDisplay: typeof import('vuetify')['useDisplay']\n  const useFrontmatter: typeof import('./src/composables/frontmatter')['useFrontmatter']\n  const useGoTo: typeof import('vuetify')['useGoTo']\n  const useHttpStore: typeof import('@vuetify/one')['useHttpStore']\n  const useI18n: typeof import('vue-i18n')['useI18n']\n  const useId: typeof import('vue')['useId']\n  const useJobsStore: typeof import('./src/stores/jobs')['useJobsStore']\n  const useLink: typeof import('vue-router')['useLink']\n  const useLocaleStore: typeof import('./src/stores/locale')['useLocaleStore']\n  const useMadeWithVuetifyStore: typeof import('./src/stores/made-with-vuetify')['useMadeWithVuetifyStore']\n  const useMarkdown: typeof import('./src/composables/markdown')['useMarkdown']\n  const useModel: typeof import('vue')['useModel']\n  const useOneStore: typeof import('@vuetify/one')['useOneStore']\n  const usePinsStore: typeof import('./src/stores/pins')['usePinsStore']\n  const usePlayground: typeof import('./src/composables/playground')['usePlayground']\n  const useProductsStore: typeof import('@vuetify/one')['useProductsStore']\n  const usePromotionsStore: typeof import('./src/stores/promotions')['usePromotionsStore']\n  const usePwaStore: typeof import('./src/stores/pwa')['usePwaStore']\n  const useQueueStore: typeof import('@vuetify/one')['useQueueStore']\n  const useReleasesStore: typeof import('./src/stores/releases')['useReleasesStore']\n  const useRoute: typeof import('vue-router')['useRoute']\n  const useRouter: typeof import('vue-router')['useRouter']\n  const useRtl: typeof import('vuetify')['useRtl']\n  const useSettingsStore: typeof import('@vuetify/one')['useSettingsStore']\n  const useShopifyStore: typeof import('./src/stores/shopify')['useShopifyStore']\n  const useSlots: typeof import('vue')['useSlots']\n  const useSponsorsStore: typeof import('./src/stores/sponsors')['useSponsorsStore']\n  const useSpotStore: typeof import('./src/stores/spot')['useSpotStore']\n  const useTeamMembersStore: typeof import('./src/stores/team-members')['useTeamMembersStore']\n  const useTeamStore: typeof import('./src/stores/team')['useTeamStore']\n  const useTemplateRef: typeof import('vue')['useTemplateRef']\n  const useTheme: typeof import('vuetify')['useTheme']\n  const useUserStore: typeof import('@vuetify/one')['useUserStore']\n  const wait: typeof import('./src/utils/helpers')['wait']\n  const waitForReadystate: typeof import('./src/utils/helpers')['waitForReadystate']\n  const watch: typeof import('vue')['watch']\n  const watchEffect: typeof import('vue')['watchEffect']\n  const watchPostEffect: typeof import('vue')['watchPostEffect']\n  const watchSyncEffect: typeof import('vue')['watchSyncEffect']\n  const wrapInArray: typeof import('./src/utils/helpers')['wrapInArray']\n}\n// for type re-export\ndeclare global {\n  // @ts-ignore\n  export type { Component, Slot, Slots, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'\n  import('vue')\n  // @ts-ignore\n  export type { CodeSection } from './src/composables/playground'\n  import('./src/composables/playground')\n  // @ts-ignore\n  export type { Category } from './src/stores/app'\n  import('./src/stores/app')\n  // @ts-ignore\n  export type { Commit } from './src/stores/commits'\n  import('./src/stores/commits')\n  // @ts-ignore\n  export type { Pin } from './src/stores/pins'\n  import('./src/stores/pins')\n  // @ts-ignore\n  export type { Release } from './src/stores/releases'\n  import('./src/stores/releases')\n  // @ts-ignore\n  export type { Sponsor } from './src/stores/sponsors'\n  import('./src/stores/sponsors')\n  // @ts-ignore\n  export type { Member, GithubMember } from './src/stores/team-members'\n  import('./src/stores/team-members')\n  // @ts-ignore\n  export type { Item } from './src/utils/api'\n  import('./src/utils/api')\n}\n\n// for vue template auto import\nimport { UnwrapRef } from 'vue'\ndeclare module 'vue' {\n  interface GlobalComponents {}\n  interface ComponentCustomProperties {\n    readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']>\n    readonly IN_BROWSER: UnwrapRef<typeof import('./src/utils/globals')['IN_BROWSER']>\n    readonly IS_DEBUG: UnwrapRef<typeof import('./src/utils/globals')['IS_DEBUG']>\n    readonly IS_PROD: UnwrapRef<typeof import('./src/utils/globals')['IS_PROD']>\n    readonly IS_SERVER: UnwrapRef<typeof import('./src/utils/globals')['IS_SERVER']>\n    readonly acceptHMRUpdate: UnwrapRef<typeof import('pinia')['acceptHMRUpdate']>\n    readonly anyLanguagePattern: UnwrapRef<typeof import('./src/utils/routes')['anyLanguagePattern']>\n    readonly cacheManifestEntries: UnwrapRef<typeof import('./src/utils/pwa')['cacheManifestEntries']>\n    readonly camelCase: UnwrapRef<typeof import('lodash-es')['camelCase']>\n    readonly camelize: UnwrapRef<typeof import('vue')['camelize']>\n    readonly cleanCache: UnwrapRef<typeof import('./src/utils/pwa')['cleanCache']>\n    readonly compressAndEncode: UnwrapRef<typeof import('./src/composables/bin')['compressAndEncode']>\n    readonly computed: UnwrapRef<typeof import('vue')['computed']>\n    readonly configureMarkdown: UnwrapRef<typeof import('./src/utils/markdown-it')['configureMarkdown']>\n    readonly copyElementContent: UnwrapRef<typeof import('./src/utils/helpers')['copyElementContent']>\n    readonly createAdProps: UnwrapRef<typeof import('./src/composables/ad')['createAdProps']>\n    readonly createApp: UnwrapRef<typeof import('vue')['createApp']>\n    readonly createOne: UnwrapRef<typeof import('@vuetify/one')['createOne']>\n    readonly createPinia: UnwrapRef<typeof import('pinia')['createPinia']>\n    readonly customRef: UnwrapRef<typeof import('vue')['customRef']>\n    readonly decodeAndDecompress: UnwrapRef<typeof import('./src/composables/bin')['decodeAndDecompress']>\n    readonly defineAsyncComponent: UnwrapRef<typeof import('vue')['defineAsyncComponent']>\n    readonly defineComponent: UnwrapRef<typeof import('vue')['defineComponent']>\n    readonly defineStore: UnwrapRef<typeof import('pinia')['defineStore']>\n    readonly disabledLanguagePattern: UnwrapRef<typeof import('./src/utils/routes')['disabledLanguagePattern']>\n    readonly effectScope: UnwrapRef<typeof import('vue')['effectScope']>\n    readonly ensureCacheableResponse: UnwrapRef<typeof import('./src/utils/pwa')['ensureCacheableResponse']>\n    readonly eventName: UnwrapRef<typeof import('./src/utils/helpers')['eventName']>\n    readonly genAppMetaInfo: UnwrapRef<typeof import('./src/utils/metadata')['genAppMetaInfo']>\n    readonly genMetaInfo: UnwrapRef<typeof import('./src/utils/metadata')['genMetaInfo']>\n    readonly generatedRoutes: UnwrapRef<typeof import('./src/utils/routes')['generatedRoutes']>\n    readonly getActivePinia: UnwrapRef<typeof import('pinia')['getActivePinia']>\n    readonly getBranch: UnwrapRef<typeof import('./src/utils/helpers')['getBranch']>\n    readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']>\n    readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']>\n    readonly getDistance: UnwrapRef<typeof import('./src/utils/helpers')['getDistance']>\n    readonly getMatchMedia: UnwrapRef<typeof import('./src/utils/helpers')['getMatchMedia']>\n    readonly h: UnwrapRef<typeof import('vue')['h']>\n    readonly inject: UnwrapRef<typeof import('vue')['inject']>\n    readonly insertLinks: UnwrapRef<typeof import('./src/utils/api')['insertLinks']>\n    readonly isOn: UnwrapRef<typeof import('./src/utils/helpers')['isOn']>\n    readonly isProxy: UnwrapRef<typeof import('vue')['isProxy']>\n    readonly isReactive: UnwrapRef<typeof import('vue')['isReactive']>\n    readonly isReadonly: UnwrapRef<typeof import('vue')['isReadonly']>\n    readonly isRef: UnwrapRef<typeof import('vue')['isRef']>\n    readonly kebabCase: UnwrapRef<typeof import('lodash-es')['kebabCase']>\n    readonly languagePattern: UnwrapRef<typeof import('./src/utils/routes')['languagePattern']>\n    readonly leadingSlash: UnwrapRef<typeof import('./src/utils/routes')['leadingSlash']>\n    readonly mapActions: UnwrapRef<typeof import('pinia')['mapActions']>\n    readonly mapGetters: UnwrapRef<typeof import('pinia')['mapGetters']>\n    readonly mapState: UnwrapRef<typeof import('pinia')['mapState']>\n    readonly mapStores: UnwrapRef<typeof import('pinia')['mapStores']>\n    readonly mapWritableState: UnwrapRef<typeof import('pinia')['mapWritableState']>\n    readonly markRaw: UnwrapRef<typeof import('vue')['markRaw']>\n    readonly markdownItRules: UnwrapRef<typeof import('./src/utils/markdown-it-rules')['default']>\n    readonly mergeProps: UnwrapRef<typeof import('vue')['mergeProps']>\n    readonly messageSW: UnwrapRef<typeof import('./src/utils/pwa')['messageSW']>\n    readonly nextTick: UnwrapRef<typeof import('vue')['nextTick']>\n    readonly onActivated: UnwrapRef<typeof import('vue')['onActivated']>\n    readonly onBeforeMount: UnwrapRef<typeof import('vue')['onBeforeMount']>\n    readonly onBeforeRouteLeave: UnwrapRef<typeof import('vue-router')['onBeforeRouteLeave']>\n    readonly onBeforeRouteUpdate: UnwrapRef<typeof import('vue-router')['onBeforeRouteUpdate']>\n    readonly onBeforeUnmount: UnwrapRef<typeof import('vue')['onBeforeUnmount']>\n    readonly onBeforeUpdate: UnwrapRef<typeof import('vue')['onBeforeUpdate']>\n    readonly onDeactivated: UnwrapRef<typeof import('vue')['onDeactivated']>\n    readonly onErrorCaptured: UnwrapRef<typeof import('vue')['onErrorCaptured']>\n    readonly onMounted: UnwrapRef<typeof import('vue')['onMounted']>\n    readonly onRenderTracked: UnwrapRef<typeof import('vue')['onRenderTracked']>\n    readonly onRenderTriggered: UnwrapRef<typeof import('vue')['onRenderTriggered']>\n    readonly onScopeDispose: UnwrapRef<typeof import('vue')['onScopeDispose']>\n    readonly onServerPrefetch: UnwrapRef<typeof import('vue')['onServerPrefetch']>\n    readonly onUnmounted: UnwrapRef<typeof import('vue')['onUnmounted']>\n    readonly onUpdated: UnwrapRef<typeof import('vue')['onUpdated']>\n    readonly onWatcherCleanup: UnwrapRef<typeof import('vue')['onWatcherCleanup']>\n    readonly openCache: UnwrapRef<typeof import('./src/utils/pwa')['openCache']>\n    readonly preferredLocale: UnwrapRef<typeof import('./src/utils/routes')['preferredLocale']>\n    readonly propsToString: UnwrapRef<typeof import('./src/utils/helpers')['propsToString']>\n    readonly provide: UnwrapRef<typeof import('vue')['provide']>\n    readonly reactive: UnwrapRef<typeof import('vue')['reactive']>\n    readonly readonly: UnwrapRef<typeof import('vue')['readonly']>\n    readonly redirectRoutes: UnwrapRef<typeof import('./src/utils/routes')['redirectRoutes']>\n    readonly ref: UnwrapRef<typeof import('vue')['ref']>\n    readonly resolveComponent: UnwrapRef<typeof import('vue')['resolveComponent']>\n    readonly rpath: UnwrapRef<typeof import('./src/utils/routes')['rpath']>\n    readonly setActivePinia: UnwrapRef<typeof import('pinia')['setActivePinia']>\n    readonly setMapStoreSuffix: UnwrapRef<typeof import('pinia')['setMapStoreSuffix']>\n    readonly shallowReactive: UnwrapRef<typeof import('vue')['shallowReactive']>\n    readonly shallowReadonly: UnwrapRef<typeof import('vue')['shallowReadonly']>\n    readonly shallowRef: UnwrapRef<typeof import('vue')['shallowRef']>\n    readonly storeToRefs: UnwrapRef<typeof import('pinia')['storeToRefs']>\n    readonly stripLinks: UnwrapRef<typeof import('./src/utils/api')['stripLinks']>\n    readonly sweClick: UnwrapRef<typeof import('./src/utils/analytics')['sweClick']>\n    readonly toRaw: UnwrapRef<typeof import('vue')['toRaw']>\n    readonly toRef: UnwrapRef<typeof import('vue')['toRef']>\n    readonly toRefs: UnwrapRef<typeof import('vue')['toRefs']>\n    readonly toValue: UnwrapRef<typeof import('vue')['toValue']>\n    readonly trailingSlash: UnwrapRef<typeof import('./src/utils/routes')['trailingSlash']>\n    readonly triggerRef: UnwrapRef<typeof import('vue')['triggerRef']>\n    readonly unref: UnwrapRef<typeof import('vue')['unref']>\n    readonly upperFirst: UnwrapRef<typeof import('lodash-es')['upperFirst']>\n    readonly useAd: UnwrapRef<typeof import('./src/composables/ad')['useAd']>\n    readonly useAdsStore: UnwrapRef<typeof import('./src/stores/ads')['useAdsStore']>\n    readonly useAppStore: UnwrapRef<typeof import('./src/stores/app')['useAppStore']>\n    readonly useAttrs: UnwrapRef<typeof import('vue')['useAttrs']>\n    readonly useAuthStore: UnwrapRef<typeof import('@vuetify/one')['useAuthStore']>\n    readonly useBin: UnwrapRef<typeof import('./src/composables/bin')['useBin']>\n    readonly useCommitsStore: UnwrapRef<typeof import('./src/stores/commits')['useCommitsStore']>\n    readonly useCosmic: UnwrapRef<typeof import('./src/composables/cosmic')['useCosmic']>\n    readonly useCssModule: UnwrapRef<typeof import('vue')['useCssModule']>\n    readonly useCssVars: UnwrapRef<typeof import('vue')['useCssVars']>\n    readonly useDate: UnwrapRef<typeof import('vuetify')['useDate']>\n    readonly useDisplay: UnwrapRef<typeof import('vuetify')['useDisplay']>\n    readonly useFrontmatter: UnwrapRef<typeof import('./src/composables/frontmatter')['useFrontmatter']>\n    readonly useGoTo: UnwrapRef<typeof import('vuetify')['useGoTo']>\n    readonly useHttpStore: UnwrapRef<typeof import('@vuetify/one')['useHttpStore']>\n    readonly useI18n: UnwrapRef<typeof import('vue-i18n')['useI18n']>\n    readonly useId: UnwrapRef<typeof import('vue')['useId']>\n    readonly useJobsStore: UnwrapRef<typeof import('./src/stores/jobs')['useJobsStore']>\n    readonly useLink: UnwrapRef<typeof import('vue-router')['useLink']>\n    readonly useLocaleStore: UnwrapRef<typeof import('./src/stores/locale')['useLocaleStore']>\n    readonly useMadeWithVuetifyStore: UnwrapRef<typeof import('./src/stores/made-with-vuetify')['useMadeWithVuetifyStore']>\n    readonly useMarkdown: UnwrapRef<typeof import('./src/composables/markdown')['useMarkdown']>\n    readonly useModel: UnwrapRef<typeof import('vue')['useModel']>\n    readonly useOneStore: UnwrapRef<typeof import('@vuetify/one')['useOneStore']>\n    readonly usePinsStore: UnwrapRef<typeof import('./src/stores/pins')['usePinsStore']>\n    readonly usePlayground: UnwrapRef<typeof import('./src/composables/playground')['usePlayground']>\n    readonly useProductsStore: UnwrapRef<typeof import('@vuetify/one')['useProductsStore']>\n    readonly usePromotionsStore: UnwrapRef<typeof import('./src/stores/promotions')['usePromotionsStore']>\n    readonly usePwaStore: UnwrapRef<typeof import('./src/stores/pwa')['usePwaStore']>\n    readonly useQueueStore: UnwrapRef<typeof import('@vuetify/one')['useQueueStore']>\n    readonly useReleasesStore: UnwrapRef<typeof import('./src/stores/releases')['useReleasesStore']>\n    readonly useRoute: UnwrapRef<typeof import('vue-router')['useRoute']>\n    readonly useRouter: UnwrapRef<typeof import('vue-router')['useRouter']>\n    readonly useRtl: UnwrapRef<typeof import('vuetify')['useRtl']>\n    readonly useSettingsStore: UnwrapRef<typeof import('@vuetify/one')['useSettingsStore']>\n    readonly useShopifyStore: UnwrapRef<typeof import('./src/stores/shopify')['useShopifyStore']>\n    readonly useSlots: UnwrapRef<typeof import('vue')['useSlots']>\n    readonly useSponsorsStore: UnwrapRef<typeof import('./src/stores/sponsors')['useSponsorsStore']>\n    readonly useSpotStore: UnwrapRef<typeof import('./src/stores/spot')['useSpotStore']>\n    readonly useTeamMembersStore: UnwrapRef<typeof import('./src/stores/team-members')['useTeamMembersStore']>\n    readonly useTemplateRef: UnwrapRef<typeof import('vue')['useTemplateRef']>\n    readonly useTheme: UnwrapRef<typeof import('vuetify')['useTheme']>\n    readonly useUserStore: UnwrapRef<typeof import('@vuetify/one')['useUserStore']>\n    readonly wait: UnwrapRef<typeof import('./src/utils/helpers')['wait']>\n    readonly waitForReadystate: UnwrapRef<typeof import('./src/utils/helpers')['waitForReadystate']>\n    readonly watch: UnwrapRef<typeof import('vue')['watch']>\n    readonly watchEffect: UnwrapRef<typeof import('vue')['watchEffect']>\n    readonly watchPostEffect: UnwrapRef<typeof import('vue')['watchPostEffect']>\n    readonly watchSyncEffect: UnwrapRef<typeof import('vue')['watchSyncEffect']>\n    readonly wrapInArray: UnwrapRef<typeof import('./src/utils/helpers')['wrapInArray']>\n  }\n}"
  },
  {
    "path": "packages/docs/build/Caddyfile",
    "content": ":80 {\n  file_server\n\n  handle /service-worker.js {\n    header >Cache-Control \"public, max-age=0, s-maxage=60, must-revalidate\"\n  }\n\n  handle /assets/* {\n    header >Cache-Control \"public, immutable, max-age=31536000, stale-if-error=604800\"\n  }\n\n  handle {\n    try_files {path} {path}/ /_fallback.html\n    header >Cache-Control \"public, max-age=3600, s-maxage=60\"\n  }\n}\n"
  },
  {
    "path": "packages/docs/build/api-plugin.ts",
    "content": "// Imports\nimport fs from 'node:fs/promises'\nimport path from 'node:path'\nimport type { Plugin } from 'vite'\n\nconst API_ROOT = path.resolve('../api-generator/dist/api')\n\nexport default function Api (): Plugin {\n  return {\n    name: 'vuetify:api',\n    enforce: 'pre',\n    resolveId (id) {\n      return id === 'virtual:api-list' ? '\\0' + id : undefined\n    },\n    async load (id) {\n      if (id === '\\0virtual:api-list') {\n        const files = await fs.readdir(API_ROOT)\n\n        const names = files\n          .sort((a, b) => a.localeCompare(b))\n          .map(file => `'${file.split('.')[0]}'`)\n          .join(', ')\n\n        return `export default [${names}]`\n      }\n    },\n  }\n}\n"
  },
  {
    "path": "packages/docs/build/examples-plugin.ts",
    "content": "import type { Plugin } from 'vite'\nimport path from 'node:path'\nimport fs from 'node:fs/promises'\nimport { fileURLToPath } from 'node:url'\n\nconst ID = '@vuetify-examples'\n\nexport function Examples (): Plugin {\n  return {\n    name: 'vuetify:examples',\n    resolveId (source) {\n      if (!source.startsWith('virtual:examples')) return\n\n      const dir = source.split('/')[1]\n\n      return dir ? `${ID}/${dir}` : ID\n    },\n    async load (id) {\n      if (!id.startsWith(ID)) return\n\n      const examplesDir = fileURLToPath(new URL('../src/examples', import.meta.url))\n\n      if (id === ID) {\n        const dirs = (await fs.readdir(examplesDir, { encoding: 'utf8' }))\n          .map(dir => {\n            return `'${dir}': () => import('virtual:examples/${dir}')`\n          }).join(',\\n')\n        const code = `\nconst dirs = {\n${dirs}\n}\n\nexport async function getExample (name) {\n  const [dir, file] = name.split('/')\n  const example = (await dirs[dir]()).default[file]\n  if (!example) throw new Error('Example \"' + name + '\" does not exist')\n  return example\n}\n      `\n\n        return { code }\n      } else {\n        const dir = id.split('/')[1]\n        const { imports, files } = (await fs.readdir(path.join(examplesDir, dir), 'utf8'))\n          .reduce<{ imports: string[], files: string[] }>((acc, file, i) => {\n            acc.imports.push(`import __${i} from '/src/examples/${dir}/${file}'`)\n            acc.imports.push(`import __${i}_raw from '/src/examples/${dir}/${file}?raw'`)\n            acc.files.push(`  '${file.split('.vue')[0]}': {\n    component: __${i},\n    source: __${i}_raw,\n  }`)\n            return acc\n          }, { imports: [], files: [] })\n\n        const code = `${imports.join('\\n')}\n\nexport default {\n${files.join(',\\n')}\n}\n`\n\n        return { code }\n      }\n    },\n  }\n}\n"
  },
  {
    "path": "packages/docs/build/markdown-it.ts",
    "content": "import MarkdownIt from 'markdown-it'\nimport { configureMarkdown } from '../src/utils/markdown-it'\nexport { configureMarkdown } from '../src/utils/markdown-it'\n\nexport const md = configureMarkdown(new MarkdownIt())\n"
  },
  {
    "path": "packages/docs/build/markdownBuilders.ts",
    "content": "import { createBuilder } from '@yankeeinlondon/builder-api'\nimport type { Pipeline } from '@yankeeinlondon/builder-api'\nimport type { Plugin } from 'vite'\nimport Ajv from 'ajv'\nimport { md } from './markdown-it'\nimport fm from 'front-matter'\nimport fs from 'node:fs'\nimport path from 'node:path'\n\nconst ajv = new Ajv()\nconst validate = ajv.compile({\n  type: 'object',\n  additionalProperties: false,\n  properties: {\n    meta: {\n      type: 'object',\n      additionalProperties: false,\n      properties: {\n        nav: { type: 'string' }, // Title used in navigation links\n        title: { type: 'string' }, // SEO title\n        description: { type: 'string' }, // SEO description\n        keywords: { type: 'string' }, // SEO keywords\n      },\n    },\n    layout: { type: 'string' },\n    related: {\n      type: 'array',\n      maxItems: 3,\n      uniqueItems: true,\n      items: { type: 'string' }, // Absolute paths to related pages\n    },\n    assets: {\n      type: 'array',\n      uniqueItems: true,\n      items: { type: 'string' }, // Additional stylesheets to load\n    },\n    disabled: { type: 'boolean' }, // The page is not published\n    emphasized: { type: 'boolean' }, // The page is emphasized in the navigation\n    fluid: { type: 'boolean' }, // Hide the Toc\n    backmatter: { type: 'boolean' }, // Hide the backmatter\n    features: {\n      type: 'object',\n      additionalProperties: false,\n      properties: {\n        figma: { type: 'boolean' },\n        label: { type: 'string' },\n        report: { type: 'boolean' },\n        github: { type: 'string' },\n        spec: { type: 'string' },\n      },\n    },\n  },\n})\n\nasync function setupPages<T extends Pipeline<any>> (\n  payload: T,\n  options: {\n    files?: Map<string, T>\n    awaiting?: Map<string, ((v: T) => void)[]>\n    pages?: ReadonlyArray<Record<'name' | 'path' | 'component', string>>\n  }\n) {\n  if (!options.pages) {\n    const pagesPlugin = payload.viteConfig.plugins!\n      .find((p: any) => p && 'name' in p && p.name === 'vite-plugin-pages') as Plugin\n    options.pages = await pagesPlugin.api.getResolvedRoutes() as []\n  }\n\n  const page = options.pages.find(p => payload.fileName.endsWith(p.component))\n\n  if (!page) throw new Error('Unable to find page')\n\n  const locale = page.path.split('/').at(1)!\n\n  const html = 'html' in payload && typeof payload.html !== 'string'\n    ? payload.html.cloneNode(true)\n    : undefined\n  options.files ??= new Map()\n  options.files.set(page.path, {\n    ...payload,\n    html,\n  })\n\n  let original: T | undefined\n  if (locale !== 'en') {\n    const originalPath = page.path.replace(`/${locale}/`, '/en/')\n    original = options.files.get(originalPath)\n    if (!original) {\n      options.awaiting ??= new Map()\n      const awaiting = options.awaiting.get(originalPath) ?? []\n      const { promise, resolve } = Promise.withResolvers<T>()\n      awaiting.push(resolve)\n      options.awaiting.set(originalPath, awaiting)\n      original = await promise\n    }\n  } else {\n    original = payload\n    if (options.awaiting?.has(page.path)) {\n      options.awaiting.get(page.path)!.forEach(fn => fn({\n        ...payload,\n        html,\n      }))\n    }\n  }\n\n  return { page, locale, original }\n}\n\nexport const frontmatterBuilder = createBuilder('frontmatterBuilder', 'metaExtracted')\n  .options()\n  .initializer()\n  .handler(async (payload, options) => {\n    const { locale, original } = await setupPages(payload, options)\n\n    const { meta, ...rest } = payload.frontmatter\n\n    if (locale !== 'en') {\n      Object.assign(rest, {\n        assets: original.frontmatter.assets,\n        related: original.frontmatter.related,\n      })\n    }\n\n    payload.frontmatter = {\n      meta,\n      assets: rest.assets,\n      backmatter: rest.backmatter,\n      features: rest.features,\n      fluid: rest.fluid,\n      related: rest.related,\n      toc: generateToc(payload.md),\n    }\n\n    return payload\n  })\n  .meta()\n\nexport function getRouteMeta (componentPath: string, locale: string) {\n  const str = fs.readFileSync(path.resolve(componentPath.slice(1)), { encoding: 'utf-8' })\n  const { attributes } = fm(str)\n\n  const valid = validate(attributes)\n  if (!valid && locale !== 'eo-UY') {\n    throw new Error(`\\nInvalid frontmatter: ${componentPath}` + validate.errors!.map(error => (\n      `\\n  | Property ${error.instancePath} ${error.message}`\n    )).join())\n  }\n\n  const a = attributes as any\n\n  if (locale !== 'en') {\n    const original = getRouteMeta(componentPath.replace(`/${locale}/`, '/en/'), 'en')\n    a.disabled = original.disabled\n    a.emphasized = original.emphasized\n    a.layout = original.layout\n  }\n\n  return {\n    disabled: a.disabled,\n    emphasized: a.emphasized,\n    layout: a.layout,\n    ...a.meta,\n  }\n}\n\nfunction generateToc (content: string) {\n  const headings = []\n  const tokens = md.parse(content, {})\n  const length = tokens.length\n\n  for (let i = 0; i < length; i++) {\n    const token = tokens[i]\n\n    if (token.type === 'inline' && token.content.startsWith('<!--') && !token.content.endsWith('-->')) {\n      do {\n        i++\n      } while (i < length && !tokens[i].content.endsWith('-->'))\n      continue\n    }\n\n    if (token.type !== 'heading_open') continue\n\n    // heading level by hash length '###' === h3\n    const level = token.markup.length\n\n    if (level <= 1) continue\n\n    const next = tokens[i + 1]\n    const link = next.children?.find(child => child.type === 'link_open')\n    const text = next.children?.filter(child => !!child.content).map(child => child.content).join('')\n    const anchor = link?.attrs?.find(([attr]) => attr === 'href')\n    const [, to] = anchor ?? []\n\n    headings.push({\n      text,\n      to,\n      level,\n    })\n  }\n\n  return headings\n}\n\nexport const scriptFixer = createBuilder('scriptFixer', 'dom')\n  .options()\n  .initializer()\n  .handler(async (payload, options) => {\n    const { locale, original } = await setupPages(payload, options)\n\n    if (locale !== 'en') {\n      const setup = payload.html.querySelector('script[setup]')\n      const origSetup = original.html.querySelector('script[setup]')\n      if (setup) {\n        if (!origSetup) {\n          throw new Error(`Extra setup in ${payload.fileName}`)\n        }\n        setup.innerHTML = origSetup.innerHTML\n      }\n    }\n\n    return payload\n  })\n  .meta()\n"
  },
  {
    "path": "packages/docs/build/mdi-js.ts",
    "content": "import { camelize } from 'vue'\nimport type { Plugin } from 'vite'\n\nconst virtual = 'virtual:mdi-js-icons'\nconst resolvedVirtual = `\\0${virtual}`\n\nexport function MdiJs () {\n  return {\n    name: 'vuetify:mdi-js-icons',\n    enforce: 'pre',\n    resolveId (id) {\n      return id === virtual ? resolvedVirtual : undefined\n    },\n    async load (id) {\n      if (id === resolvedVirtual) {\n        const [meta, paths] = await Promise.all([\n          import('@mdi/svg/meta.json', { with: { type: 'json' } }).then(m => m.default),\n          import('@mdi/js'),\n        ])\n        const icons = meta.map(icon => ({\n          name: icon.name,\n          aliases: icon.aliases,\n          path: paths[camelize('mdi-' + icon.name) as keyof typeof paths],\n        }))\n        return `export const icons = ${JSON.stringify(icons)}`\n      }\n\n      return undefined\n    },\n  } satisfies Plugin\n}\n"
  },
  {
    "path": "packages/docs/build/sitemap.js",
    "content": "const SitemapWebpackPlugin = require('sitemap-webpack-plugin').default\nconst { generateRoutes } = require('./generate-routes')\n\nclass SitemapPlugin {\n  apply (compiler) {\n    const routes = generateRoutes()\n\n    const paths = []\n    for (const route of routes) {\n      let priority = 0.5\n\n      if (route.fullPath === '/') priority = 1.0\n      else if (route.fullPath.includes('/components')) priority = 0.8\n      else if (route.fullPath.includes('/api')) priority = 0.7\n\n      paths.push({\n        path: route.fullPath,\n        lastmod: new Date().toISOString(),\n        priority,\n        changefreq: 'daily',\n      })\n    }\n\n    const plugin = new SitemapWebpackPlugin({\n      base: 'https://vuetifyjs.com',\n      paths,\n    })\n\n    plugin.apply(compiler)\n  }\n}\n\nmodule.exports = new SitemapPlugin()\n"
  },
  {
    "path": "packages/docs/components.d.ts",
    "content": "/* eslint-disable */\n// @ts-nocheck\n// Generated by unplugin-vue-components\n// Read more: https://github.com/vuejs/core/pull/3399\nexport {}\n\n/* prettier-ignore */\ndeclare module 'vue' {\n  export interface GlobalComponents {\n    AboutTeamMember: typeof import('./src/components/about/TeamMember.vue')['default']\n    AboutTeamMembers: typeof import('./src/components/about/TeamMembers.vue')['default']\n    Alert: typeof import('./src/components/Alert.vue')['default']\n    ApiApiTable: typeof import('./src/components/api/ApiTable.vue')['default']\n    ApiBacklinks: typeof import('./src/components/api/Backlinks.vue')['default']\n    ApiDirectiveTable: typeof import('./src/components/api/DirectiveTable.vue')['default']\n    ApiEventsTable: typeof import('./src/components/api/EventsTable.vue')['default']\n    ApiExposedTable: typeof import('./src/components/api/ExposedTable.vue')['default']\n    ApiInline: typeof import('./src/components/api/Inline.vue')['default']\n    ApiLinks: typeof import('./src/components/api/Links.vue')['default']\n    ApiNameCell: typeof import('./src/components/api/NameCell.vue')['default']\n    ApiPrismCell: typeof import('./src/components/api/PrismCell.vue')['default']\n    ApiPropsTable: typeof import('./src/components/api/PropsTable.vue')['default']\n    ApiSassTable: typeof import('./src/components/api/SassTable.vue')['default']\n    ApiSearch: typeof import('./src/components/api/Search.vue')['default']\n    ApiSection: typeof import('./src/components/api/Section.vue')['default']\n    ApiSlotsTable: typeof import('./src/components/api/SlotsTable.vue')['default']\n    ApiView: typeof import('./src/components/api/View.vue')['default']\n    AppBackToTop: typeof import('./src/components/app/BackToTop.vue')['default']\n    AppBarBar: typeof import('./src/components/app/bar/Bar.vue')['default']\n    AppBarBlogLink: typeof import('./src/components/app/bar/BlogLink.vue')['default']\n    AppBarEcosystemMenu: typeof import('./src/components/app/bar/EcosystemMenu.vue')['default']\n    AppBarEnterpriseLink: typeof import('./src/components/app/bar/EnterpriseLink.vue')['default']\n    AppBarGitHubLink: typeof import('./src/components/app/bar/GitHubLink.vue')['default']\n    AppBarJobsLink: typeof import('./src/components/app/bar/JobsLink.vue')['default']\n    AppBarLanguageMenu: typeof import('./src/components/app/bar/LanguageMenu.vue')['default']\n    AppBarLearnMenu: typeof import('./src/components/app/bar/LearnMenu.vue')['default']\n    AppBarLogo: typeof import('./src/components/app/bar/Logo.vue')['default']\n    AppBarNotificationsMenu: typeof import('./src/components/app/bar/NotificationsMenu.vue')['default']\n    AppBarOneLink: typeof import('./src/components/app/bar/OneLink.vue')['default']\n    AppBarPlaygroundLink: typeof import('./src/components/app/bar/PlaygroundLink.vue')['default']\n    AppBarSettingsToggle: typeof import('./src/components/app/bar/SettingsToggle.vue')['default']\n    AppBarSponsorLink: typeof import('./src/components/app/bar/SponsorLink.vue')['default']\n    AppBarStoreLink: typeof import('./src/components/app/bar/StoreLink.vue')['default']\n    AppBarSupportLink: typeof import('./src/components/app/bar/SupportLink.vue')['default']\n    AppBarSupportMenu: typeof import('./src/components/app/bar/SupportMenu.vue')['default']\n    AppBarTeamLink: typeof import('./src/components/app/bar/TeamLink.vue')['default']\n    AppBarThemeToggle: typeof import('./src/components/app/bar/ThemeToggle.vue')['default']\n    AppBtn: typeof import('./src/components/app/Btn.vue')['default']\n    AppCaption: typeof import('./src/components/app/Caption.vue')['default']\n    AppCommitBtn: typeof import('./src/components/app/CommitBtn.vue')['default']\n    AppDivider: typeof import('./src/components/app/Divider.vue')['default']\n    AppDrawerAppend: typeof import('./src/components/app/drawer/Append.vue')['default']\n    AppDrawerDrawer: typeof import('./src/components/app/drawer/Drawer.vue')['default']\n    AppDrawerDrawerToggleRail: typeof import('./src/components/app/drawer/DrawerToggleRail.vue')['default']\n    AppDrawerPinnedItems: typeof import('./src/components/app/drawer/PinnedItems.vue')['default']\n    AppFigure: typeof import('./src/components/app/Figure.vue')['default']\n    AppHeading: typeof import('./src/components/app/Heading.vue')['default']\n    AppHeadline: typeof import('./src/components/app/Headline.vue')['default']\n    AppLink: typeof import('./src/components/app/Link.vue')['default']\n    AppListLinkListItem: typeof import('./src/components/app/list/LinkListItem.vue')['default']\n    AppListList: typeof import('./src/components/app/list/List.vue')['default']\n    AppMarkup: typeof import('./src/components/app/Markup.vue')['default']\n    AppMenuMenu: typeof import('./src/components/app/menu/Menu.vue')['default']\n    AppSearchSearch: typeof import('./src/components/app/search/Search.vue')['default']\n    AppSearchSearchDialog: typeof import('./src/components/app/search/SearchDialog.vue')['default']\n    AppSearchSearchGroup: typeof import('./src/components/app/search/SearchGroup.vue')['default']\n    AppSearchSearchResults: typeof import('./src/components/app/search/SearchResults.vue')['default']\n    AppSettingsAppend: typeof import('./src/components/app/settings/Append.vue')['default']\n    AppSettingsDeveloperMode: typeof import('./src/components/app/settings/DeveloperMode.vue')['default']\n    AppSettingsDocumentationBuild: typeof import('./src/components/app/settings/DocumentationBuild.vue')['default']\n    AppSettingsDrawer: typeof import('./src/components/app/settings/Drawer.vue')['default']\n    AppSettingsLatestCommit: typeof import('./src/components/app/settings/LatestCommit.vue')['default']\n    AppSettingsLatestRelease: typeof import('./src/components/app/settings/LatestRelease.vue')['default']\n    AppSettingsOptions: typeof import('./src/components/app/settings/Options.vue')['default']\n    AppSettingsOptionsAdOption: typeof import('./src/components/app/settings/options/AdOption.vue')['default']\n    AppSettingsOptionsApiOption: typeof import('./src/components/app/settings/options/ApiOption.vue')['default']\n    AppSettingsOptionsCodeOption: typeof import('./src/components/app/settings/options/CodeOption.vue')['default']\n    AppSettingsOptionsOfflineOption: typeof import('./src/components/app/settings/options/OfflineOption.vue')['default']\n    AppSettingsOptionsPinOption: typeof import('./src/components/app/settings/options/PinOption.vue')['default']\n    AppSettingsOptionsRailDrawerOption: typeof import('./src/components/app/settings/options/RailDrawerOption.vue')['default']\n    AppSettingsOptionsSlashSearchOption: typeof import('./src/components/app/settings/options/SlashSearchOption.vue')['default']\n    AppSettingsOptionsThemeOption: typeof import('./src/components/app/settings/options/ThemeOption.vue')['default']\n    AppSettingsSettingsHeader: typeof import('./src/components/app/settings/SettingsHeader.vue')['default']\n    AppSheet: typeof import('./src/components/app/Sheet.vue')['default']\n    AppTable: typeof import('./src/components/app/Table.vue')['default']\n    AppTextField: typeof import('./src/components/app/TextField.vue')['default']\n    AppTitle: typeof import('./src/components/app/Title.vue')['default']\n    AppToc: typeof import('./src/components/app/Toc.vue')['default']\n    AppTooltipBtn: typeof import('./src/components/app/TooltipBtn.vue')['default']\n    AppV2Banner: typeof import('./src/components/app/V2Banner.vue')['default']\n    AppVersionBtn: typeof import('./src/components/app/VersionBtn.vue')['default']\n    AppVerticalDivider: typeof import('./src/components/app/VerticalDivider.vue')['default']\n    Backmatter: typeof import('./src/components/Backmatter.vue')['default']\n    ComponentsListItem: typeof import('./src/components/components/ListItem.vue')['default']\n    DashboardDashboardEmptyState: typeof import('./src/components/dashboard/DashboardEmptyState.vue')['default']\n    DocExplorer: typeof import('./src/components/doc/Explorer.vue')['default']\n    DocIconList: typeof import('./src/components/doc/IconList.vue')['default']\n    DocIconTable: typeof import('./src/components/doc/IconTable.vue')['default']\n    DocIntroduced: typeof import('./src/components/doc/Introduced.vue')['default']\n    DocMadeWithVueAttribution: typeof import('./src/components/doc/MadeWithVueAttribution.vue')['default']\n    DocMadeWithVuetifyGallery: typeof import('./src/components/doc/MadeWithVuetifyGallery.vue')['default']\n    DocMadeWithVuetifyLink: typeof import('./src/components/doc/MadeWithVuetifyLink.vue')['default']\n    DocReadyForMore: typeof import('./src/components/doc/ReadyForMore.vue')['default']\n    DocRelatedPage: typeof import('./src/components/doc/RelatedPage.vue')['default']\n    DocRelatedPages: typeof import('./src/components/doc/RelatedPages.vue')['default']\n    DocReleases: typeof import('./src/components/doc/Releases.vue')['default']\n    DocTabs: typeof import('./src/components/doc/Tabs.vue')['default']\n    DocThemeCard: typeof import('./src/components/doc/ThemeCard.vue')['default']\n    DocThemeVendor: typeof import('./src/components/doc/ThemeVendor.vue')['default']\n    DocTypographyPreview: typeof import('./src/components/doc/TypographyPreview.vue')['default']\n    DocUpNext: typeof import('./src/components/doc/UpNext.vue')['default']\n    DocVueJobs: typeof import('./src/components/doc/VueJobs.vue')['default']\n    ExamplesExample: typeof import('./src/components/examples/Example.vue')['default']\n    ExamplesExampleMissing: typeof import('./src/components/examples/ExampleMissing.vue')['default']\n    ExamplesUsage: typeof import('./src/components/examples/Usage.vue')['default']\n    ExamplesUsageExample: typeof import('./src/components/examples/UsageExample.vue')['default']\n    ExamplesVueFile: typeof import('./src/components/examples/VueFile.vue')['default']\n    FeaturesBreakpointsTable: typeof import('./src/components/features/BreakpointsTable.vue')['default']\n    FeaturesColorPalette: typeof import('./src/components/features/ColorPalette.vue')['default']\n    FeaturesSassApi: typeof import('./src/components/features/SassApi.vue')['default']\n    GettingStartedWireframeExamples: typeof import('./src/components/getting-started/WireframeExamples.vue')['default']\n    HomeBlogs: typeof import('./src/components/home/Blogs.vue')['default']\n    HomeCommonCard: typeof import('./src/components/home/Common/Card.vue')['default']\n    HomeCommonGradient: typeof import('./src/components/home/Common/Gradient.vue')['default']\n    HomeCommonMarquee: typeof import('./src/components/home/Common/Marquee.vue')['default']\n    HomeCommonTitle: typeof import('./src/components/home/Common/Title.vue')['default']\n    HomeDiscord: typeof import('./src/components/home/Discord.vue')['default']\n    HomeEcosystem: typeof import('./src/components/home/Ecosystem.vue')['default']\n    HomeEntry: typeof import('./src/components/home/Entry.vue')['default']\n    HomeFooter: typeof import('./src/components/home/Footer.vue')['default']\n    HomeGalleryAnalytics: typeof import('./src/components/home/Gallery/Analytics.vue')['default']\n    HomeGalleryChatChat: typeof import('./src/components/home/Gallery/Chat/Chat.vue')['default']\n    HomeGalleryChatDetail: typeof import('./src/components/home/Gallery/Chat/Detail.vue')['default']\n    HomeGalleryChatList: typeof import('./src/components/home/Gallery/Chat/List.vue')['default']\n    HomeGalleryComponents: typeof import('./src/components/home/Gallery/Components.vue')['default']\n    HomeGalleryDashboard: typeof import('./src/components/home/Gallery/Dashboard.vue')['default']\n    HomeGalleryLogin: typeof import('./src/components/home/Gallery/Login.vue')['default']\n    HomeGallerySettings: typeof import('./src/components/home/Gallery/Settings.vue')['default']\n    HomeLogo: typeof import('./src/components/home/Logo.vue')['default']\n    HomeSnips: typeof import('./src/components/home/Snips.vue')['default']\n    HomeSnipsExample: typeof import('./src/components/home/SnipsExample.vue')['default']\n    HomeSpecialSponsor: typeof import('./src/components/home/SpecialSponsor.vue')['default']\n    HomeSponsors: typeof import('./src/components/home/Sponsors.vue')['default']\n    HomeStore: typeof import('./src/components/home/Store.vue')['default']\n    HomeSupport: typeof import('./src/components/home/Support.vue')['default']\n    HomeTooling: typeof import('./src/components/home/Tooling.vue')['default']\n    HomeVuetifyOne: typeof import('./src/components/home/VuetifyOne.vue')['default']\n    IconsChevronDown: typeof import('./src/components/icons/ChevronDown.vue')['default']\n    IntroductionComparison: typeof import('./src/components/introduction/Comparison.vue')['default']\n    IntroductionConsultingServices: typeof import('./src/components/introduction/ConsultingServices.vue')['default']\n    IntroductionDirectSupport: typeof import('./src/components/introduction/DirectSupport.vue')['default']\n    IntroductionDiscordDeck: typeof import('./src/components/introduction/DiscordDeck.vue')['default']\n    IntroductionEnterpriseDeck: typeof import('./src/components/introduction/EnterpriseDeck.vue')['default']\n    IntroductionEnterpriseForm: typeof import('./src/components/introduction/EnterpriseForm.vue')['default']\n    IntroductionSlaDeck: typeof import('./src/components/introduction/SlaDeck.vue')['default']\n    OneFAQ: typeof import('./src/components/one/FAQ.vue')['default']\n    OneHero: typeof import('./src/components/one/Hero.vue')['default']\n    OneProperties: typeof import('./src/components/one/Properties.vue')['default']\n    OneRoadmap: typeof import('./src/components/one/Roadmap.vue')['default']\n    OneSubscribeCard: typeof import('./src/components/one/SubscribeCard.vue')['default']\n    PageFeatures: typeof import('./src/components/PageFeatures.vue')['default']\n    PromotedBase: typeof import('./src/components/promoted/Base.vue')['default']\n    PromotedCarbon: typeof import('./src/components/promoted/Carbon.vue')['default']\n    PromotedDiscovery: typeof import('./src/components/promoted/Discovery.vue')['default']\n    PromotedEntry: typeof import('./src/components/promoted/Entry.vue')['default']\n    PromotedInline: typeof import('./src/components/promoted/Inline.vue')['default']\n    PromotedPromoted: typeof import('./src/components/promoted/Promoted.vue')['default']\n    PromotedRandom: typeof import('./src/components/promoted/Random.vue')['default']\n    PromotedScript: typeof import('./src/components/promoted/Script.vue')['default']\n    PromotedVuetify: typeof import('./src/components/promoted/Vuetify.vue')['default']\n    PromotionsPromotionCard: typeof import('./src/components/promotions/PromotionCard.vue')['default']\n    ResourcesColorPalette: typeof import('./src/components/resources/ColorPalette.vue')['default']\n    ResourcesLogos: typeof import('./src/components/resources/Logos.vue')['default']\n    RouterLink: typeof import('vue-router')['RouterLink']\n    RouterView: typeof import('vue-router')['RouterView']\n    SponsorCard: typeof import('./src/components/sponsor/Card.vue')['default']\n    SponsorLink: typeof import('./src/components/sponsor/Link.vue')['default']\n    SponsorSnackbarPopup: typeof import('./src/components/sponsor/SnackbarPopup.vue')['default']\n    SponsorSponsors: typeof import('./src/components/sponsor/Sponsors.vue')['default']\n    UserBadgesUserAdminBadge: typeof import('./src/components/user/badges/UserAdminBadge.vue')['default']\n    UserBadgesUserOneBadge: typeof import('./src/components/user/badges/UserOneBadge.vue')['default']\n    UserBadgesUserSponsorBadge: typeof import('./src/components/user/badges/UserSponsorBadge.vue')['default']\n    UserOneSubCard: typeof import('./src/components/user/OneSubCard.vue')['default']\n    UserUserTabs: typeof import('./src/components/user/UserTabs.vue')['default']\n  }\n}\n"
  },
  {
    "path": "packages/docs/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <link rel=\"icon\" href=\"/favicon.ico\" />\n    <meta name=\"theme-color\" content=\"#1867c0\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=5, minimal-ui, shrink-to-fit=no\">\n    <!-- @inject-meta -->\n    <script defer src=\"https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js?features=IntersectionObserver,ResizeObserver,WebAnimations,Object.fromEntries,Array.prototype.at\"></script>\n    <link rel=\"preconnect\" href=\"https://www.google-analytics.com\">\n    <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n    <link rel=\"preconnect\" href=\"https://cdnjs.cloudflare.com\">\n    <link rel=\"preconnect\" href=\"https://www.googletagmanager.com\">\n    <link rel=\"preconnect\" href=\"https://api.cosmicjs.com\">\n    <link rel=\"preconnect\" href=\"https://cdn.cosmicjs.com\">\n    <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\">\n    <link rel=\"preconnect\" href=\"https://cdn.vuetifyjs.com\">\n  </head>\n  <body>\n    <div id=\"app\"></div>\n    <script type=\"module\" src=\"/src/main.ts\"></script>\n  </body>\n</html>\n"
  },
  {
    "path": "packages/docs/jest-runner-eslint.config.cjs",
    "content": "module.exports = {\n  cliOptions: {\n    ext: ['.js', '.ts', '.tsx', '.vue'],\n    maxWarnings: 0,\n    fix: process.env.JEST_FIX === 'true',\n  },\n}\n"
  },
  {
    "path": "packages/docs/jest.config.cjs",
    "content": "const os = require('os')\n\nfunction clamp (v, min, max) {\n  return Math.max(min, Math.floor(Math.min(max, v)))\n}\n\nconst memoryReserve = 3 // leave room for tsc too\nconst availableMemory = (os.freemem() / 1024 ** 3) - memoryReserve\nconst memoryPerWorker = 2.8\nconst threads = os.cpus().length / 2\nconst maxWorkers = clamp(availableMemory / memoryPerWorker, 1, threads)\n\nconsole.log(`${maxWorkers} workers`)\n\nmodule.exports = {\n  maxWorkers,\n  runner: 'jest-runner-eslint',\n  displayName: 'lint',\n  testMatch: [\n    '<rootDir>/src/**/*.js',\n    '<rootDir>/src/**/*.ts',\n    '<rootDir>/src/**/*.tsx',\n    '<rootDir>/src/**/*.vue',\n    '<rootDir>/src/**/*.json',\n  ],\n  moduleFileExtensions: ['vue', 'ts', 'js', 'tsx', 'json'],\n  reporters: [['jest-silent-reporter', {\n    showWarnings: true,\n    useDots: true,\n  }]],\n}\n"
  },
  {
    "path": "packages/docs/package.json",
    "content": "{\n  \"name\": \"vuetifyjs.com\",\n  \"type\": \"module\",\n  \"description\": \"A Vue.js project\",\n  \"private\": true,\n  \"author\": \"John Leider <john@vuetifyjs.com>\",\n  \"version\": \"4.0.3\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/vuetifyjs/vuetify.git\",\n    \"directory\": \"packages/docs\"\n  },\n  \"scripts\": {\n    \"dev\": \"vite --force\",\n    \"build\": \"vite build\",\n    \"preview\": \"vite preview\",\n    \"preview-https\": \"HTTPS=true vite preview\",\n    \"lint\": \"concurrently 'vue-tsc --noEmit --pretty' 'pnpm lint:md' 'jest --no-cache' -n 'tsc,md,eslint' --kill-others-on-fail -gr\",\n    \"lint:fix\": \"pnpm fix:md && JEST_FIX=true jest --no-cache\",\n    \"lint:md\": \"markdownlint --config .markdownlintrc src/pages/en\",\n    \"fix:md\": \"markdownlint --config .markdownlintrc src/pages/en --fix\"\n  },\n  \"dependencies\": {\n    \"@cosmicjs/sdk\": \"^1.5.6\",\n    \"@sentry/vue\": \"^9.12.0\",\n    \"@vue/compiler-dom\": \"^3.5.25\",\n    \"@vuelidate/core\": \"^2.0.3\",\n    \"@vuelidate/validators\": \"^2.0.4\",\n    \"@vuetify/one\": \"^2.12.0\",\n    \"algoliasearch\": \"^4.24.0\",\n    \"fflate\": \"^0.8.2\",\n    \"isomorphic-fetch\": \"^3.0.0\",\n    \"markdown-it-multimd-table\": \"^4.2.3\",\n    \"pinia\": \"^3.0.4\",\n    \"prism-theme-vars\": \"^0.2.5\",\n    \"prismjs\": \"^1.30.0\",\n    \"roboto-fontface\": \"^0.10.0\",\n    \"swetrix\": \"^3.7.2\",\n    \"vee-validate\": \"^4.15.1\",\n    \"vue\": \"^3.5.25\",\n    \"vue-i18n\": \"^11.1.12\",\n    \"vue-instantsearch\": \"^4.20.6\",\n    \"vue-router\": \"^4.6.3\",\n    \"vuetify\": \"workspace:*\"\n  },\n  \"devDependencies\": {\n    \"@babel/generator\": \"^7.28.5\",\n    \"@babel/types\": \"^7.28.5\",\n    \"@emailjs/browser\": \"^4.4.1\",\n    \"@intlify/unplugin-vue-i18n\": \"^11.0.1\",\n    \"@mdi/js\": \"7.4.47\",\n    \"@mdi/svg\": \"7.4.47\",\n    \"@octokit/openapi-types\": \"^25.0.0\",\n    \"@types/babel__generator\": \"^7.27.0\",\n    \"@types/markdown-it\": \"^14.1.2\",\n    \"@types/markdown-it-container\": \"^2.0.10\",\n    \"@types/prismjs\": \"^1.26.5\",\n    \"@vitejs/plugin-basic-ssl\": \"^2.1.0\",\n    \"@vue/compiler-sfc\": \"^3.5.25\",\n    \"@vuetify/api-generator\": \"workspace:*\",\n    \"@yankeeinlondon/builder-api\": \"^1.4.1\",\n    \"ajv\": \"^8.17.1\",\n    \"algoliasearch-helper\": \"^3.26.1\",\n    \"async-es\": \"^3.2.6\",\n    \"date-fns\": \"^3.6.0\",\n    \"front-matter\": \"^4.0.2\",\n    \"jest\": \"^30.2.0\",\n    \"jest-runner-eslint\": \"^2.3.0\",\n    \"jest-silent-reporter\": \"^0.6.0\",\n    \"markdown-it\": \"^14.1.1\",\n    \"markdown-it-anchor\": \"^9.2.0\",\n    \"markdown-it-attrs\": \"^4.3.1\",\n    \"markdown-it-container\": \"^4.0.0\",\n    \"markdown-it-emoji\": \"^2.0.2\",\n    \"markdown-it-header-sections\": \"^1.0.0\",\n    \"markdown-it-link-attributes\": \"^4.0.1\",\n    \"markdown-it-prism\": \"^3.0.1\",\n    \"markdownlint-cli\": \"^0.46.0\",\n    \"unplugin-auto-import\": \"19.3.0\",\n    \"unplugin-fonts\": \"1.4.0\",\n    \"unplugin-vue-components\": \"^0.28.0\",\n    \"vite-plugin-md\": \"^0.22.5\",\n    \"vite-plugin-pages\": \"^0.33.0\",\n    \"vite-plugin-pwa\": \"^1.1.0\",\n    \"vite-plugin-vue-layouts\": \"^0.11.0\",\n    \"vite-plugin-vuetify\": \"^2.1.2\",\n    \"vue-tsc\": \"^3.1.5\"\n  },\n  \"publishConfig\": {\n    \"access\": \"public\"\n  }\n}\n"
  },
  {
    "path": "packages/docs/public/ads.txt",
    "content": "#BuySellAds Inc\n#https://optimizeads.net/\nbuysellads.com, 8198, DIRECT\n#AppNexus\nappnexus.com, 8394, DIRECT, f5ab79cb980f11d1\nxandr.com, 8394, DIRECT, f5ab79cb980f11d1\n#Rubicon:\nrubiconproject.com, 18812, DIRECT, 0bfd66d529a55807\nrubiconproject.com, 22884, DIRECT, 0bfd66d529a55807\nrubiconproject.com, 18814, DIRECT, 0bfd66d529a55807\n#Amazon\naps.amazon.com,747b8b51-ec47-4dee-9823-b2b73124b71f,DIRECT\nsmartadserver.com,3835,DIRECT,060d053dcf45cbf3\nsharethrough.com,81c1429f,DIRECT,d53b998a7bd4ecd2\npubmatic.com,160006,RESELLER,5d62403b186f2ace\npubmatic.com,160096,RESELLER,5d62403b186f2ace\nindexexchange.com,192410,RESELLER,50b1c356f2c5c8fc\npubmatic.com,161103,DIRECT,5d62403b186f2ace\nopenx.com,540191398,RESELLER,6a698e2ec38604c6\nappnexus.com,1908,RESELLER,f5ab79cb980f11d1\nad-generation.jp,12474,RESELLER,7f4ea9029ac04e53\ndistrictm.io,100962,RESELLER,3fd707be9c4527c3\nyieldmo.com,2719019867620450718,RESELLER\nrhythmone.com,1654642120,RESELLER,a670c89d4a324e47\ngumgum.com,14141,RESELLER,ffdef49475d318a9\nadmanmedia.com,877,DIRECT\nemxdgt.com,2009,RESELLER,1e1d41537f7cad7f\ncontextweb.com,562541,RESELLER,89ff185a4c4e857c\nthemediagrid.com,JTQKMP,RESELLER,35d5010d7789b49d\nbeachfront.com,14804,RESELLER,e2541279e8e2ca4d\nimprovedigital.com,2050,RESELLER\nmintegral.com,10043,RESELLER,0aeed750c80d6423\nsonobi.com,7f5fa520f8,RESELLER,d1a215d9eb5aee9e\nappnexus.com,3663,RESELLER,f5ab79cb980f11d1\nrisecodes.com,63832beef8189a00015cb6d3,RESELLER\nmediago.io,045ac24b888bcf59a09731e7f0f2084f,RESELLER\nindexexchange.com,204998,DIRECT,50b1c356f2c5c8fc\n#OpenX\nopenx.com, 541000958, RESELLER, 6a698e2ec38604c6\nopenx.com, 545711449, DIRECT, 6a698e2ec38604c6\nopenx.com, 545711449, RESELLER, 6a698e2ec38604c6\nopenx.com, 559329982, DIRECT, 6a698e2ec38604c6\n#Pubmatic\npubmatic.com, 159855, DIRECT, 5d62403b186f2ace\npubmatic.com, 161102, RESELLER, 5d62403b186f2ace\npubmatic.com, 161103, RESELLER, 5d62403b186f2ace\npubmatic.com, 161104, RESELLER, 5d62403b186f2ace\n#IE\nindexexchange.com, 192533, DIRECT\nindexexchange.com, 204998, RESELLER, 50b1c356f2c5c8fc\n#TripleLift\ntriplelift.com, 7376, DIRECT, 6c33edb13117fd86\ntriplelift.com, 7186, DIRECT, 6c33edb13117fd86\ntriplelift.com, 7328, DIRECT, 6c33edb13117fd86\ntriplelift.com, 7187, DIRECT, 6c33edb13117fd86\ntriplelift.com, 7997, DIRECT, 6c33edb13117fd86\ntriplelift.com, 7998, DIRECT, 6c33edb13117fd86\ntriplelift.com, 8573, DIRECT, 6c33edb13117fd86\ntriplelift.com, 8581, DIRECT, 6c33edb13117fd86\ntriplelift.com, 8582, DIRECT, 6c33edb13117fd86\ntriplelift.com, 8583, DIRECT, 6c33edb13117fd86\ntriplelift.com, 8620, DIRECT, 6c33edb13117fd86\ntriplelift.com, 8621, DIRECT, 6c33edb13117fd86\ntriplelift.com, 8622, DIRECT, 6c33edb13117fd86\ntriplelift.com, 8631, DIRECT, 6c33edb13117fd86\ntriplelift.com, 8632, DIRECT, 6c33edb13117fd86\ntriplelift.com, 8633, DIRECT, 6c33edb13117fd86\ntriplelift.com, 8634, DIRECT, 6c33edb13117fd86\ntriplelift.com, 8896, DIRECT, 6c33edb13117fd86\ntriplelift.com, 8921, DIRECT, 6c33edb13117fd86\ntriplelift.com, 8922, DIRECT, 6c33edb13117fd86\ntriplelift.com, 9269, DIRECT, 6c33edb13117fd86\ntriplelift.com, 9499, DIRECT, 6c33edb13117fd86\ntriplelift.com, 9498, DIRECT, 6c33edb13117fd86\ntriplelift.com, 10923, DIRECT, 6c33edb13117fd86\ntriplelift.com, 11245, DIRECT, 6c33edb13117fd86\ntriplelift.com, 11317, DIRECT, 6c33edb13117fd86\ntriplelift.com, 11316, DIRECT, 6c33edb13117fd86\ntriplelift.com, 11318, DIRECT, 6c33edb13117fd86\ntriplelift.com, 11658, DIRECT, 6c33edb13117fd86\ntriplelift.com, 11657, DIRECT, 6c33edb13117fd86\ntriplelift.com, 11659, DIRECT, 6c33edb13117fd86\nappnexus.com, 1314, RESELLER\nspotxchange.com, 228454, RESELLER, 7842df1d2fe2db34\nspotx.tv, 228454, RESELLER, 7842df1d2fe2db34\n#Google\ngoogle.com, pub-9961814823930967, RESELLER, f08c47fec0942fa0\ngoogle.com, pub-9961814823930967, DIRECT, f08c47fec0942fa0\ngoogle.com, pub-2049948180079264, DIRECT, f08c47fec0942fa0\ngoogle.com, pub-9454946816537646, DIRECT, f08c47fec0942fa0\ngoogle.com, pub-8400268452481648, DIRECT, f08c47fec0942fa0\ngoogle.com, pub-4184422354282212, DIRECT, f08c47fec0942fa0 #16489\ngoogle.com, pub-7998997772660809, DIRECT, f08c47fec0942fa0 #17203\ngoogle.com, pub-3239114052422391, DIRECT, f08c47fec0942fa0 #11556\ngoogle.com, pub-8880801249704748, DIRECT, f08c47fec0942fa0 #16495\ngoogle.com, pub-5850466644901558, DIRECT, f08c47fec0942fa0 #6904\ngoogle.com, pub-8744812757244383, DIRECT, f08c47fec0942fa0 #7674\ngoogle.com, pub-9896872574268733, DIRECT, f08c47fec0942fa0 #7898\ngoogle.com, pub-2860251217814013, DIRECT, f08c47fec0942fa0 #7898\ngoogle.com, pub-8400268452481648, DIRECT, f08c47fec0942fa0 #7898\ngoogle.com, pub-5309873657092359, DIRECT, f08c47fec0942fa0 #7898\ngoogle.com, pub-4618644450685964, DIRECT, f08c47fec0942fa0 #117\ngoogle.com, pub-2707866139552340, DIRECT, f08c47fec0942fa0 #17073\n#nobid\nnobid.io, 21851990727, DIRECT\nsonobi.com, 7ad1b9f952, RESELLER, d1a215d9eb5aee9e\namxrtb.com, 105199579, RESELLER\nxandr.com, 11429, RESELLER, f5ab79cb980f11d1\nxandr.com, 12701, RESELLER, f5ab79cb980f11d1\nlijit.com, 273657, RESELLER, fafdf38b16bf6b2b\nsovrn.com, 273657, RESELLER, fafdf38b16bf6b2b\nappnexus.com, 12290, RESELLER, f5ab79cb980f11d1\nindexexchange.com, 191503, RESELLER, 50b1c356f2c5c8fc\npubmatic.com, 158355, RESELLER, 5d62403b186f2ace\npubmatic.com, 162412, RESELLER, 5d62403b186f2ace\nonetag.com, 694e68b73971b58, RESELLER\ndurationmedia.net, 21851990727, DIRECT\nsmartadserver.com,3447,RESELLER\nindexexchange.com,195491,RESELLER,50b1c356f2c5c8fc\nvideo.unrulymedia.com, 3736557092, RESELLER\nrhythmone.com, 3736557092, RESELLER, a670c89d4a324e47\ngumgum.com, 13926, RESELLER, ffdef49475d318a9\ninmobi.com,8f261ace12c3486ba2e0d2011cd97976,RESELLER,83e75a7ae333ca9d\nrubiconproject.com, 24434, DIRECT, 0bfd66d529a55807\nminutemedia.com, 01gerz67grgj, RESELLER\npubmatic.com, 161683, RESELLER, 5d62403b186f2ace\nappnexus.com, 8381, RESELLER, f5ab79cb980f11d1\ntriplelift.com, 12507, RESELLER, 6c33edb13117fd86\nsharethrough.com, UvcAx8IL, RESELLER, d53b998a7bd4ecd2\n#Primis\nprimis.tech, 23983, DIRECT, b6b21d256ef43532\npubmatic.com, 156595, RESELLER, 5d62403b186f2ace\ngoogle.com, pub-1320774679920841, RESELLER, f08c47fec0942fa0\nopenx.com, 540258065, RESELLER, 6a698e2ec38604c6\nrubiconproject.com, 20130, RESELLER, 0bfd66d529a55807\nfreewheel.tv, 19133, RESELLER, 74e8e47458f74754\nsmartadserver.com, 3436, RESELLER, 060d053dcf45cbf3\nindexexchange.com, 191923, RESELLER, 50b1c356f2c5c8fc\nadform.com, 2078, RESELLER\nMedia.net, 8CU695QH7, RESELLER\nvideo.unrulymedia.com, 2338962694, RESELLER\nsharethrough.com, flUyJowI, RESELLER, d53b998a7bd4ecd2\ntriplelift.com, 8210, RESELLER, 6c33edb13117fd86\nyahoo.com, 59260, RESELLER\n#Sovrn\nsovrn.com, 54916, DIRECT, fafdf38b16bf6b2b\nlijit.com, 54916, DIRECT, fafdf38b16bf6b2b\nlijit.com, 54916-eb, DIRECT, fafdf38b16bf6b2b\nlijit.com, 435797, DIRECT, fafdf38b16bf6b2b\nlijit.com, 435797-eb, DIRECT, fafdf38b16bf6b2b#\nappnexus.com, 1360, RESELLER, f5ab79cb980f11d1\ngumgum.com, 11645, RESELLER, ffdef49475d318a9\nopenx.com, 538959099, RESELLER, 6a698e2ec38604c6\nopenx.com, 539924617, RESELLER, 6a698e2ec38604c6\npubmatic.com, 137711, RESELLER, 5d62403b186f2ace\npubmatic.com, 156212, RESELLER, 5d62403b186f2ace\npubmatic.com, 156700, RESELLER, 5d62403b186f2ace\nrubiconproject.com, 17960, RESELLER, 0bfd66d529a55807\nappnexus.com, 1019, RESELLER, f5ab79cb980f11d1\nvideo.unrulymedia.com, 12444764291, RESELLER\ncontextweb.com, 558511, RESELLER\n#Smart\nsmartadserver.com, 3835, DIRECT\nsmartadserver.com, 3835-OB, RESELLER, 060d053dcf45cbf3\nsmartadserver.com, 4194-OB, RESELLER, 060d053dcf45cbf3\nsmartadserver.com, 4194, RESELLER, 060d053dcf45cbf3\nsmartadserver.com, 3835, RESELLER\ncontextweb.com, 560288, RESELLER, 89ff185a4c4e857c\npubmatic.com, 156439, RESELLER, 5d62403b186f2ace\npubmatic.com, 154037, RESELLER, 5d62403b186f2ace\nrubiconproject.com, 16114, RESELLER, 0bfd66d529a55807\nopenx.com, 537149888, RESELLER, 6a698e2ec38604c6\nappnexus.com, 3703, RESELLER, f5ab79cb980f11d1\ndistrictm.io, 101760, RESELLER, 3fd707be9c4527c3\nloopme.com, 5679, RESELLER, 6c8d5f95897a5a3b\nxad.com, 958, RESELLER, 81cbf0a75a5e0e9a\nrhythmone.com, 2564526802, RESELLER, a670c89d4a324e47\nsmaato.com, 1100044045, RESELLER, 07bcf65f187117b4\npubnative.net, 1006576, RESELLER, d641df8625486a7b\nadyoulike.com, b4bf4fdd9b0b915f746f6747ff432bde, RESELLER\naxonix.com, 57264, RESELLER\nsharethrough.com, OAW69Fon, RESELLER, d53b998a7bd4ecd2\n#Criteo\ncriteo.com, B-058814, DIRECT, 9fac4a4a87c2a44f\nthemediagrid.com, ZANK5X, DIRECT, 35d5010d7789b49d\n#Adagio\nadagio.io, 1116, DIRECT\nrubiconproject.com, 19116, RESELLER, 0bfd66d529a55807\npubmatic.com, 159110, RESELLER, 5d62403b186f2ace\nimprovedigital.com, 1790, RESELLER\nonetag.com, 6b859b96c564fbe, RESELLER\nindexexchange.com, 194558, RESELLER\npubwise.io, 68867843, RESELLER, c327c91a93a7cdd3\n33across.com, 0015a00002oUk4aAAC, RESELLER, bbea06d9c4d2853c\nappnexus.com, 10239, RESELLER, f5ab79cb980f11d1\nrubiconproject.com, 16414, RESELLER, 0bfd66d529a55807\nlijit.com, 367236, RESELLER, fafdf38b16bf6b2b\nopenx.com, 558899373, RESELLER, 6a698e2ec38604c6\ntriplelift.com, 13482, RESELLER, 6c33edb13117fd86\n#Adyoulike\nadyoulike.com, c88421dae358597b6441f855c46bf1f7, DIRECT\nappnexus.com, 9733, RESELLER\nspotxchange.com, 230037, RESELLER, 7842df1d2fe2db34\nspotx.tv, 230037, RESELLER, 7842df1d2fe2db34\nsmartadserver.com, 4016, RESELLER\nsmartadserver.com, 4012, RESELLER\nsmartadserver.com, 4071, RESELLER\nsmartadserver.com, 4073, RESELLER\nsmartadserver.com, 4074, RESELLER\nrubiconproject.com, 20736, RESELLER, 0bfd66d529a55807\nsmartadserver.com, 4144, RESELLER\npubmatic.com, 160925, RESELLER, 5d62403b186f2ace\nthemediagrid.com, RYIDPE, DIRECT, 35d5010d7789b49d\n#OneTag\nonetag.com, 73d67396a1b6e18, DIRECT\nonetag.com, 73d67396a1b6e18-OB, DIRECT\nappnexus.com, 13099, RESELLER\npubmatic.com, 161593, RESELLER, 5d62403b186f2ace\nrubiconproject.com, 11006, RESELLER, 0bfd66d529a55807\n#media.net\nMedia.net, 8CU18831I, DIRECT\nMedia.net, 8CUMDNT02, DIRECT\nMedia.net, 8CU352B6K, DIRECT\nMedia.net, 8CUR8G327, DIRECT\nMedia.net, 8CUW70514, DIRECT\nopenx.com, 537100188, RESELLER, 6a698e2ec38604c6\npubmatic.com, 159463, RESELLER, 5d62403b186f2ace\nEMXDGT.com, 1759, Reseller, 1e1d41537f7cad7f\nAppnexus.com, 1356, RESELLER, f5ab79cb980f11d1\ngoogle.com, pub-7439041255533808, RESELLER, f08c47fec0942fa0\nrubiconproject.com, 19396, Reseller, 0bfd66d529a55807\nonetag.com, 5d49f482552c9b6, Reseller\nsonobi.com, 83729e979b, RESELLER\n33across.com, 0010b00002cGp2AAAS, Reseller, bbea06d9c4d2853c\nrhythmone.com, 3611299104, RESELLER\n#fluct\nadingo.jp, 29875, RESELLER\n#Outbrain\noutbrain.com, 00ae023ac373956acf51a9b845069dca8a, DIRECT\nappnexus.com, 7597, RESELLER, f5ab79cb980f11d1\nFreewheel.tv, 741650, RESELLER # Premium video demand\nopenx.com, 540393169, RESELLER, 6a698e2ec38604c6 # Premium video demand\nrubiconproject.com, 19668, RESELLER, 0bfd66d529a55807\nindexexchange.com, 190856, RESELLER, 50b1c356f2c5c8fc # Premium Video Demand\npubmatic.com, 158615, RESELLER, 5d62403b186f2ace # Premium video & display demand\nvidazoo.com, 1773068026, RESELLER, b6ada874b4d7d0b2 # Premium Video Demand\nvideo.unrulymedia.com, 367782854, RESELLER # Premium video demand from Outbrain\nindexexchange.com, 193091, RESELLER, 50b1c356f2c5c8fc # Premium video demand from Outbrain\npubmatic.com, 160065, RESELLER, 5d62403b186f2ace # Premium video demand from Outbrain\nimprovedigital.com, 1863, RESELLER # Premium video demand from Outbrain\nfreewheel.tv, 1220655, RESELLER # Premium video demand from Outbrain\nrisecodes.com,6022acddc8b2f90001767980, RESELLER\nyahoo.com, 59040, RESELLER, e1a5b5b6e3255540\nemxdgt.com, 2014, RESELLER, 1e1d41537f7cad7f\nvi.ai, g-004a0d4b5efc1727f1afd5a5b06f11a099, DIRECT #instream video by outbrain\ngoogle.com, pub-5617098146054077, RESELLER, f08c47fec0942fa0 #instream video by outbrain\npubmatic.com, 158055, RESELLER, 5d62403b186f2ace #instream video by outbrain\nxandr.com, 10736, RESELLER #instream video by outbrain\nrubiconproject.com, 21506, RESELLER, 0bfd66d529a55807 #instream video by outbrain\nrhythmone.com, 1014191143, RESELLER, a670c89d4a324e47 #instream video by outbrain\nvideo.unrulymedia.com, 1014191143, RESELLER #instream video by outbrain\nIndexexchange.com, 190500, RESELLER #instream video by outbrain\nsmartadserver.com,2776,RESELLER #instream video by outbrain\nopenx.com, 540362347, RESELLER, 6a698e2ec38604c6 #instream video by outbrain\nmedia.net, 8CUIH830U, RESELLER #instream video by outbrain\ntriplelift.com, 11547, RESELLER, 6c33edb13117fd86 #instream video by outbrain\nimprovedigital.com, 1552, Reseller #instream video by outbrain\ncontextweb.com, 562709, RESELLER, 89ff185a4c4e857c\naps.amazon.com, 3965, RESELLER #instream video by outbrain\nfreewheel.tv, 1220559, RESELLER # Premium video demand from Outbrain\nfreewheel.tv, 1133073, RESELLER #instream video by outbrain\nsovrn.com, 267974, RESELLER, fafdf38b16bf6b2b #instream video by outbrain\nadform.com, 2611, RESELLER #instream video by outbrain\nsharethrough.com, c21oBkqP, RESELLER, d53b998a7bd4ecd2\nsmaato.com, 1100054606, RESELLER, 07bcf65f187117b4\n#BuySellAds Inc\nbuysellads.com, 93, DIRECT\nMANAGERDOMAIN=buysellads.com\nOWNERDOMAIN=vuetifyjs.com\n"
  },
  {
    "path": "packages/docs/public/llms.txt",
    "content": "# Vuetify\n\n> Material Design component framework for Vue.js. Production-ready with 80+ UI components, directives, and features for building modern web applications.\n\n## Introduction\n\n- [Why Vuetify](https://vuetifyjs.com/en/introduction/why-vuetify/): Core benefits and philosophy\n- [Long-term Support](https://vuetifyjs.com/en/introduction/long-term-support/): LTS policy and version support\n- [Roadmap](https://vuetifyjs.com/en/introduction/roadmap/): Upcoming features and releases\n- [Enterprise Support](https://vuetifyjs.com/en/introduction/enterprise-support/): Professional support options\n\n## Getting Started\n\n- [Installation](https://vuetifyjs.com/en/getting-started/installation/): Setup with Vite, Nuxt, or CDN\n- [Frequently Asked Questions](https://vuetifyjs.com/en/getting-started/frequently-asked-questions/): Common issues and solutions\n- [Upgrade Guide](https://vuetifyjs.com/en/getting-started/upgrade-guide/): Migration between versions\n- [Browser Support](https://vuetifyjs.com/en/getting-started/browser-support/): Supported browsers\n- [Unit Testing](https://vuetifyjs.com/en/getting-started/unit-testing/): Testing Vuetify components\n\n## Features\n\n- [Accessibility](https://vuetifyjs.com/en/features/accessibility/): A11y support and ARIA\n- [Application Layout](https://vuetifyjs.com/en/features/application-layout/): App scaffolding with v-app, v-main, v-app-bar\n- [Theme](https://vuetifyjs.com/en/features/theme/): Light/dark themes, custom colors\n- [SASS Variables](https://vuetifyjs.com/en/features/sass-variables/): Customizing component styles\n- [Icon Fonts](https://vuetifyjs.com/en/features/icon-fonts/): MDI, Font Awesome, custom icons\n- [Internationalization](https://vuetifyjs.com/en/features/internationalization/): i18n and RTL support\n- [Global Configuration](https://vuetifyjs.com/en/features/global-configuration/): Default props and settings\n- [Display and Platform](https://vuetifyjs.com/en/features/display-and-platform/): Breakpoints and device detection\n- [Treeshaking](https://vuetifyjs.com/en/features/treeshaking/): Automatic component imports\n- [Blueprints](https://vuetifyjs.com/en/features/blueprints/): Pre-configured component sets\n- [Dates](https://vuetifyjs.com/en/features/dates/): Date adapter configuration\n- [Aliasing](https://vuetifyjs.com/en/features/aliasing/): Component aliases\n- [Scrolling](https://vuetifyjs.com/en/features/scrolling/): Programmatic scroll control\n- [Hotkey](https://vuetifyjs.com/en/features/hotkey/): Keyboard shortcuts\n\n## Styles\n\n- [CSS Reset](https://vuetifyjs.com/en/styles/css-reset/): Normalize browser styles\n- [Colors](https://vuetifyjs.com/en/styles/colors/): Material Design color palette\n- [Transitions](https://vuetifyjs.com/en/styles/transitions/): Built-in animations\n- [Spacing](https://vuetifyjs.com/en/styles/spacing/): Margin and padding utilities\n- [Flex](https://vuetifyjs.com/en/styles/flex/): Flexbox utility classes\n- [Display](https://vuetifyjs.com/en/styles/display/): Visibility utilities\n- [Elevation](https://vuetifyjs.com/en/styles/elevation/): Box shadow utilities\n- [Text and Typography](https://vuetifyjs.com/en/styles/text-and-typography/): Text utilities\n- [Border Radius](https://vuetifyjs.com/en/styles/border-radius/): Rounded corners\n- [Borders](https://vuetifyjs.com/en/styles/borders/): Border utilities\n\n## Concepts\n\n- [v-model](https://vuetifyjs.com/en/concepts/v-model/): Two-way binding patterns\n- [Variants](https://vuetifyjs.com/en/concepts/variants/): Component style variants (outlined, plain, etc.)\n- [Density and Sizing](https://vuetifyjs.com/en/concepts/density-and-sizing/): Compact, comfortable, default densities\n- [Items](https://vuetifyjs.com/en/concepts/items/): Item prop patterns for lists/selects\n- [Routing](https://vuetifyjs.com/en/concepts/routing/): Router integration\n\n## Components - Containment\n\n- [Buttons](https://vuetifyjs.com/en/components/buttons/): v-btn with variants, sizes, icons\n- [Cards](https://vuetifyjs.com/en/components/cards/): v-card container with header, text, actions\n- [Dialogs](https://vuetifyjs.com/en/components/dialogs/): v-dialog modal windows\n- [Menus](https://vuetifyjs.com/en/components/menus/): v-menu dropdown menus\n- [Chips](https://vuetifyjs.com/en/components/chips/): v-chip compact elements\n- [Expansion Panels](https://vuetifyjs.com/en/components/expansion-panels/): v-expansion-panels accordion\n- [Lists](https://vuetifyjs.com/en/components/lists/): v-list with items, groups, subitems\n- [Sheets](https://vuetifyjs.com/en/components/sheets/): v-sheet surface container\n- [Bottom Sheets](https://vuetifyjs.com/en/components/bottom-sheets/): v-bottom-sheet mobile panel\n- [Overlays](https://vuetifyjs.com/en/components/overlays/): v-overlay backdrop\n- [Toolbars](https://vuetifyjs.com/en/components/toolbars/): v-toolbar action bar\n- [Tooltips](https://vuetifyjs.com/en/components/tooltips/): v-tooltip hover hints\n- [Dividers](https://vuetifyjs.com/en/components/dividers/): v-divider separator\n\n## Components - Navigation\n\n- [App Bars](https://vuetifyjs.com/en/components/app-bars/): v-app-bar top navigation\n- [Navigation Drawers](https://vuetifyjs.com/en/components/navigation-drawers/): v-navigation-drawer side menu\n- [Tabs](https://vuetifyjs.com/en/components/tabs/): v-tabs content switching\n- [Bottom Navigation](https://vuetifyjs.com/en/components/bottom-navigation/): v-bottom-navigation mobile nav\n- [Breadcrumbs](https://vuetifyjs.com/en/components/breadcrumbs/): v-breadcrumbs path display\n- [Footers](https://vuetifyjs.com/en/components/footers/): v-footer page footer\n- [Paginations](https://vuetifyjs.com/en/components/paginations/): v-pagination page navigation\n- [System Bars](https://vuetifyjs.com/en/components/system-bars/): v-system-bar status bar\n- [Speed Dials](https://vuetifyjs.com/en/components/speed-dials/): v-speed-dial FAB menu\n- [Floating Action Buttons](https://vuetifyjs.com/en/components/floating-action-buttons/): v-fab circular action button\n\n## Components - Form Inputs\n\n- [Text Fields](https://vuetifyjs.com/en/components/text-fields/): v-text-field input with validation\n- [Selects](https://vuetifyjs.com/en/components/selects/): v-select dropdown selection\n- [Autocompletes](https://vuetifyjs.com/en/components/autocompletes/): v-autocomplete searchable select\n- [Combobox](https://vuetifyjs.com/en/components/combobox/): v-combobox with custom values\n- [Checkboxes](https://vuetifyjs.com/en/components/checkboxes/): v-checkbox boolean input\n- [Switches](https://vuetifyjs.com/en/components/switches/): v-switch toggle\n- [Radio Buttons](https://vuetifyjs.com/en/components/radio-buttons/): v-radio-group single selection\n- [Sliders](https://vuetifyjs.com/en/components/sliders/): v-slider numeric range\n- [Range Sliders](https://vuetifyjs.com/en/components/range-sliders/): v-range-slider min/max selection\n- [File Inputs](https://vuetifyjs.com/en/components/file-inputs/): v-file-input upload\n- [Textareas](https://vuetifyjs.com/en/components/textareas/): v-textarea multiline input\n- [Number Inputs](https://vuetifyjs.com/en/components/number-inputs/): v-number-input numeric input\n- [OTP Input](https://vuetifyjs.com/en/components/otp-input/): v-otp-input verification codes\n- [Forms](https://vuetifyjs.com/en/components/forms/): v-form validation wrapper\n- [Inputs](https://vuetifyjs.com/en/components/inputs/): v-input base component\n\n## Components - Data Display\n\n- [Data Tables](https://vuetifyjs.com/en/components/data-tables/introduction/): v-data-table with sorting, filtering, pagination\n- [Calendars](https://vuetifyjs.com/en/components/calendars/): v-calendar date display\n- [Tables](https://vuetifyjs.com/en/components/tables/): v-table simple tables\n- [Treeview](https://vuetifyjs.com/en/components/treeview/): v-treeview hierarchical data\n- [Data Iterators](https://vuetifyjs.com/en/components/data-iterators/): v-data-iterator custom layouts\n- [Virtual Scroller](https://vuetifyjs.com/en/components/virtual-scroller/): v-virtual-scroll large lists\n- [Infinite Scroller](https://vuetifyjs.com/en/components/infinite-scroller/): v-infinite-scroll lazy loading\n- [Sparklines](https://vuetifyjs.com/en/components/sparklines/): v-sparkline mini charts\n- [Hotkeys](https://vuetifyjs.com/en/components/hotkeys/): v-hotkey keyboard display\n- [Confirm Edit](https://vuetifyjs.com/en/components/confirm-edit/): v-confirm-edit inline editing\n\n## Components - Selection\n\n- [Button Groups](https://vuetifyjs.com/en/components/button-groups/): v-btn-toggle grouped buttons\n- [Chip Groups](https://vuetifyjs.com/en/components/chip-groups/): v-chip-group selectable chips\n- [Item Groups](https://vuetifyjs.com/en/components/item-groups/): v-item-group selection container\n- [Slide Groups](https://vuetifyjs.com/en/components/slide-groups/): v-slide-group horizontal scroll\n- [Carousels](https://vuetifyjs.com/en/components/carousels/): v-carousel image slider\n- [Windows](https://vuetifyjs.com/en/components/windows/): v-window content transition\n- [Steppers](https://vuetifyjs.com/en/components/steppers/): v-stepper multi-step flow\n\n## Components - Feedback\n\n- [Alerts](https://vuetifyjs.com/en/components/alerts/): v-alert notification banners\n- [Snackbars](https://vuetifyjs.com/en/components/snackbars/): v-snackbar toast messages\n- [Snackbar Queue](https://vuetifyjs.com/en/components/snackbar-queue/): v-snackbar-queue stacked toasts\n- [Progress Circular](https://vuetifyjs.com/en/components/progress-circular/): v-progress-circular spinner\n- [Progress Linear](https://vuetifyjs.com/en/components/progress-linear/): v-progress-linear loading bar\n- [Skeleton Loaders](https://vuetifyjs.com/en/components/skeleton-loaders/): v-skeleton-loader placeholders\n- [Ratings](https://vuetifyjs.com/en/components/ratings/): v-rating star rating\n- [Banners](https://vuetifyjs.com/en/components/banners/): v-banner prominent messages\n- [Badges](https://vuetifyjs.com/en/components/badges/): v-badge notification dot\n- [Timelines](https://vuetifyjs.com/en/components/timelines/): v-timeline event display\n- [Hover](https://vuetifyjs.com/en/components/hover/): v-hover state tracking\n- [Empty States](https://vuetifyjs.com/en/components/empty-states/): v-empty-state placeholder\n\n## Components - Images and Icons\n\n- [Images](https://vuetifyjs.com/en/components/images/): v-img lazy loading images\n- [Icons](https://vuetifyjs.com/en/components/icons/): v-icon SVG/font icons\n- [Avatars](https://vuetifyjs.com/en/components/avatars/): v-avatar user images\n- [Aspect Ratios](https://vuetifyjs.com/en/components/aspect-ratios/): v-responsive ratio container\n- [Parallax](https://vuetifyjs.com/en/components/parallax/): v-parallax scroll effect\n\n## Components - Pickers\n\n- [Date Pickers](https://vuetifyjs.com/en/components/date-pickers/): v-date-picker calendar selection\n- [Time Pickers](https://vuetifyjs.com/en/components/time-pickers/): v-time-picker clock selection\n- [Color Pickers](https://vuetifyjs.com/en/components/color-pickers/): v-color-picker color selection\n\n## Components - Providers\n\n- [Defaults Providers](https://vuetifyjs.com/en/components/defaults-providers/): v-defaults-provider scoped defaults\n- [Theme Providers](https://vuetifyjs.com/en/components/theme-providers/): v-theme-provider scoped themes\n- [Locale Providers](https://vuetifyjs.com/en/components/locale-providers/): v-locale-provider scoped i18n\n\n## Components - Layout\n\n- [Application](https://vuetifyjs.com/en/components/application/): v-app root component\n- [Grids](https://vuetifyjs.com/en/components/grids/): v-container, v-row, v-col 12-column grid\n- [Lazy](https://vuetifyjs.com/en/components/lazy/): v-lazy viewport loading\n- [No SSR](https://vuetifyjs.com/en/components/no-ssr/): v-no-ssr client-only rendering\n\n## Directives\n\n- [Ripple](https://vuetifyjs.com/en/directives/ripple/): v-ripple touch feedback\n- [Click Outside](https://vuetifyjs.com/en/directives/click-outside/): v-click-outside event\n- [Scroll](https://vuetifyjs.com/en/directives/scroll/): v-scroll listener\n- [Intersect](https://vuetifyjs.com/en/directives/intersect/): v-intersect viewport detection\n- [Resize](https://vuetifyjs.com/en/directives/resize/): v-resize element observer\n- [Mutate](https://vuetifyjs.com/en/directives/mutate/): v-mutate DOM observer\n- [Touch](https://vuetifyjs.com/en/directives/touch/): v-touch gesture events\n- [Tooltip](https://vuetifyjs.com/en/directives/tooltip/): v-tooltip directive\n\n## Labs (Experimental)\n\n- [Introduction](https://vuetifyjs.com/en/labs/introduction/): About experimental components\n- [Color Inputs](https://vuetifyjs.com/en/components/color-inputs/): v-color-input field\n- [Date Inputs](https://vuetifyjs.com/en/components/date-inputs/): v-date-input field\n- [File Upload](https://vuetifyjs.com/en/components/file-upload/): v-file-upload dropzone\n- [Icon Buttons](https://vuetifyjs.com/en/components/icon-buttons/): v-icon-btn compact button\n- [Mask Inputs](https://vuetifyjs.com/en/components/mask-inputs/): v-mask-input formatted input\n- [Pie Charts](https://vuetifyjs.com/en/components/pie-charts/): v-pie-chart visualization\n- [Pull to Refresh](https://vuetifyjs.com/en/components/pull-to-refresh/): v-pull-to-refresh mobile gesture\n- [Vertical Steppers](https://vuetifyjs.com/en/components/vertical-steppers/): v-vertical-stepper\n- [Videos](https://vuetifyjs.com/en/components/videos/): v-video player\n\n## Resources\n\n- [Brand Kit](https://vuetifyjs.com/en/resources/brand-kit/): Logos and assets\n- [Made with Vuetify](https://vuetifyjs.com/en/resources/made-with-vuetify/): Showcase\n- [Themes](https://vuetifyjs.com/en/resources/themes/): Premium templates\n- [UI Kits](https://vuetifyjs.com/en/resources/ui-kits/): Figma and Sketch resources\n"
  },
  {
    "path": "packages/docs/public/robots.txt",
    "content": "User-agent: *\nAllow: /\n\nSitemap: https://vuetifyjs.com/sitemap.xml\n"
  },
  {
    "path": "packages/docs/public/search.xml",
    "content": "<?xml version=\"1.0\"?>\n<OpenSearchDescription xmlns=\"http://a9.com/-/spec/opensearch/1.1/\" xmlns:moz=\"http://www.mozilla.org/2006/browser/search/\">\n<ShortName>Vuetify</ShortName>\n<Description>Vuetify documentation</Description>\n<InputEncoding>UTF-8</InputEncoding>\n<Image width=\"16\" height=\"16\" type=\"image/x-icon\">https://vuetifyjs.com/favicon.ico</Image>\n<Url type=\"text/html\" method=\"get\" template=\"https://vuetifyjs.com/?search={searchTerms}\"/>\n</OpenSearchDescription>\n"
  },
  {
    "path": "packages/docs/src/App.vue",
    "content": "<template>\n  <router-view v-slot=\"{ Component }\">\n    <v-fade-transition appear>\n      <component :is=\"Component\" />\n    </v-fade-transition>\n  </router-view>\n\n  <PromotedScript\n    id=\"bitterbrainsads-script\"\n    script-id=\"_bitterbrainsads_js\"\n    src=\"//media.bitterbrains.com/main.js?from=VUETIFY&type=top\"\n    async\n  />\n</template>\n\n<script setup lang=\"ts\">\n  // Composables\n  import { useHead } from '@unhead/vue'\n\n  const user = useUserStore()\n  const router = useRouter()\n  const route = useRoute()\n  const theme = useTheme()\n  const { locale } = useI18n()\n  const auth = useAuthStore()\n  const frontmatter = useFrontmatter()\n\n  const path = computed(() => route.path.replace(`/${locale.value}/`, ''))\n\n  const meta = computed(() => {\n    let title = route.meta.title\n\n    // API pages\n    if (route.meta.title === 'API') {\n      const name = route.params.name as string\n      title = `${name.charAt(0).toUpperCase()}${camelize(name.slice(1))} API`\n    }\n\n    return genAppMetaInfo({\n      title: `${title}${path.value === '' ? '' : ' — Vuetify'}`,\n      description: frontmatter.value?.meta.description,\n      keywords: frontmatter.value?.meta.keywords,\n      assets: frontmatter.value?.assets,\n    })\n  })\n\n  useHead({\n    title: computed(() => meta.value.title),\n    meta: computed(() => meta.value.meta),\n    link: computed(() => meta.value.link),\n    script: computed(() => {\n      return route.meta.locale === 'eo-UY' ? [\n        {\n          type: 'text/javascript',\n          innerHTML: `let _jipt = [['project', 'vuetify']];`,\n        },\n        {\n          type: 'text/javascript',\n          src: '//cdn.crowdin.com/jipt/jipt.js',\n        },\n      ] : []\n    }),\n  })\n\n  onBeforeMount(() => {\n    // set current route lang if root\n    const currentRoute = router.currentRoute.value\n    if (currentRoute.path === '/') {\n      const query = currentRoute.query\n      router.replace({ path: `/${locale.value}`, query })\n    }\n  })\n\n  const systemTheme = ref('light')\n  if (IN_BROWSER) {\n    let media: MediaQueryList\n\n    auth.verify()\n\n    watch(() => user.one.theme, val => {\n      if (val === 'system') {\n        media = getMatchMedia()!\n        media.addEventListener('change', onThemeChange)\n        onThemeChange()\n      } else if (media) {\n        media.removeEventListener('change', onThemeChange)\n      }\n    }, { immediate: true })\n    function onThemeChange () {\n      systemTheme.value = media!.matches ? 'dark' : 'light'\n    }\n\n    watchEffect(() => {\n      theme.change(user.one.theme === 'system' ? systemTheme.value : user.one.theme)\n    })\n\n    watch(theme.global.name, themeTransition)\n\n    function themeTransition () {\n      const x = performance.now()\n      for (let i = 0; i++ < 1e7; i << 9 & 9 % 9 * 9 + 9);\n      if (performance.now() - x > 10) return\n\n      const el: HTMLElement = document.querySelector('[data-v-app]')!\n      const children = el.querySelectorAll('*') as NodeListOf<HTMLElement>\n\n      children.forEach(el => {\n        if (hasScrollbar(el)) {\n          el.dataset.scrollX = String(el.scrollLeft)\n          el.dataset.scrollY = String(el.scrollTop)\n        }\n      })\n\n      const copy = el.cloneNode(true) as HTMLElement\n      copy.classList.add('app-copy')\n      const rect = el.getBoundingClientRect()\n      copy.style.top = rect.top + 'px'\n      copy.style.left = rect.left + 'px'\n      copy.style.width = rect.width + 'px'\n      copy.style.height = rect.height + 'px'\n\n      const targetEl = document.activeElement as HTMLElement\n      const targetRect = targetEl.getBoundingClientRect()\n      const left = targetRect.left + targetRect.width / 2 + window.scrollX\n      const top = targetRect.top + targetRect.height / 2 + window.scrollY\n      el.style.setProperty('--clip-pos', `${left}px ${top}px`)\n      el.style.removeProperty('--clip-size')\n\n      nextTick(() => {\n        el.classList.add('app-transition')\n        requestAnimationFrame(() => {\n          requestAnimationFrame(() => {\n            el.style.setProperty('--clip-size', Math.hypot(window.innerWidth, window.innerHeight) + 'px')\n          })\n        })\n      })\n\n      document.body.append(copy)\n\n      ;(copy.querySelectorAll('[data-scroll-x], [data-scroll-y]') as NodeListOf<HTMLElement>).forEach(el => {\n        el.scrollLeft = Number(el.dataset.scrollX)\n        el.scrollTop = Number(el.dataset.scrollY)\n      })\n\n      function onTransitionend (e: TransitionEvent) {\n        if (e.target === e.currentTarget) {\n          copy.remove()\n          el.removeEventListener('transitionend', onTransitionend)\n          el.removeEventListener('transitioncancel', onTransitionend)\n          el.classList.remove('app-transition')\n          el.style.removeProperty('--clip-size')\n          el.style.removeProperty('--clip-pos')\n        }\n      }\n      el.addEventListener('transitionend', onTransitionend)\n      el.addEventListener('transitioncancel', onTransitionend)\n    }\n\n    function hasScrollbar (el?: Element | null) {\n      if (!el || el.nodeType !== Node.ELEMENT_NODE) return false\n\n      const style = window.getComputedStyle(el)\n      return style.overflowY === 'scroll' || (style.overflowY === 'auto' && el.scrollHeight > el.clientHeight)\n    }\n  }\n</script>\n\n<style lang=\"sass\">\n  a:not(:hover)\n    text-decoration: none\n\n  h1 + p\n    font-size: 1.25rem\n    font-weight: 300\n    margin-top: 0\n\n  p :is(a, a:visited)\n    color: rgb(var(--v-theme-primary))\n\n  details\n    padding-inline-start: 1rem\n    margin-bottom: 1rem\n    border: 1px solid color-mix(currentColor, transparent 80%)\n    border-radius: .4rem\n\n    > summary\n      padding: .3rem .6rem .3rem 0\n\n      &::marker\n        margin-inline-end: .5rem\n\n    &[open] > summary\n      margin-bottom: 1rem\n\n  // Theme transition\n  .app-copy\n    position: fixed !important\n    z-index: -1 !important\n    pointer-events: none !important\n    contain: size style !important\n    overflow: clip !important\n\n  .app-transition\n    --clip-size: 0\n    --clip-pos: 0 0\n    clip-path: circle(var(--clip-size) at var(--clip-pos))\n    transition: clip-path .35s ease-out\n</style>\n\n<style lang=\"sass\" scoped>\n  .pwa-loader\n    position: fixed\n    top: 0\n    left: 0\n    right: 0\n    z-index: 1010\n</style>\n"
  },
  {
    "path": "packages/docs/src/components/Alert.vue",
    "content": "<template>\n  <v-alert\n    :border-color=\"type\"\n    :type=\"type\"\n    border=\"start\"\n    class=\"v-alert--doc my-4 border-opacity-100\"\n    variant=\"tonal\"\n  >\n    <template #prepend>\n      <v-icon\n        :color=\"type\"\n        :icon=\"icon\"\n      />\n    </template>\n    <slot />\n  </v-alert>\n</template>\n\n<script setup>\n  const props = defineProps({ type: String })\n\n  const type = computed(() => {\n    return props.type === 'tip' ? 'success' : props.type\n  })\n  const icon = computed(() => {\n    switch (type.value) {\n      case 'error': return 'mdi-close-circle-outline'\n      case 'info': return 'mdi-information-outline'\n      case 'success': return 'mdi-check-circle-outline'\n      case 'warning': return 'mdi-alert-circle-outline'\n      default: return '$vuetify'\n    }\n  })\n</script>\n\n<style lang=\"sass\">\n  .v-alert--doc\n    .v-alert__content p:last-child\n      margin-bottom: 0 !important\n</style>\n"
  },
  {
    "path": "packages/docs/src/components/Backmatter.vue",
    "content": "<template>\n  <section\n    id=\"ready-for-more\"\n    class=\"mt-16\"\n  >\n    <DocReadyForMore />\n\n    <DocRelatedPages />\n\n    <AppDivider />\n\n    <DocUpNext />\n  </section>\n</template>\n"
  },
  {
    "path": "packages/docs/src/components/PageFeatures.vue",
    "content": "<template>\n  <div class=\"mb-4\">\n    <page-feature-chip\n      v-if=\"!isGeneratedPage\"\n      :href=\"contribute\"\n      prepend-icon=\"mdi-pencil-outline\"\n      rel=\"noopener noreferrer\"\n      target=\"_blank\"\n      text=\"Edit this page\"\n    >\n      <template #prepend>\n        <v-icon color=\"blue-darken-3\" />\n      </template>\n    </page-feature-chip>\n\n    <page-feature-chip\n      v-if=\"one.isSubscriber && user.ecosystem.docs.pins.enabled\"\n      :prepend-icon=\"`mdi-pin${!pinned ? '-outline' : ''}`\"\n      text=\"Pin\"\n      @click=\"onClickPin\"\n    >\n      <template #prepend>\n        <v-icon :color=\"pinned ? 'primary' : undefined\" />\n      </template>\n    </page-feature-chip>\n\n    <page-feature-chip\n      v-if=\"frontmatter?.features?.figma\"\n      :text=\"t('figma-design')\"\n      href=\"https://figma.vuetifyjs.com/\"\n      prepend-icon=\"mdi-image\"\n      rel=\"noopener noreferrer\"\n      target=\"_blank\"\n    >\n      <template #prepend>\n        <v-icon color=\"purple\" />\n      </template>\n    </page-feature-chip>\n\n    <page-feature-chip\n      v-if=\"frontmatter?.features?.report\"\n      :text=\"t('report-a-bug')\"\n      href=\"https://issues.vuetifyjs.com/?repo=vuetify&type=bug\"\n      prepend-icon=\"mdi-bug-outline\"\n      rel=\"noopener noreferrer\"\n      target=\"_blank\"\n    >\n      <template #prepend>\n        <v-icon color=\"red\" />\n      </template>\n    </page-feature-chip>\n\n    <page-feature-chip\n      v-if=\"label\"\n      :href=\"label\"\n      :text=\"t('open-issues')\"\n      prepend-icon=\"mdi-alert-circle-outline\"\n      rel=\"noopener noreferrer\"\n      target=\"_blank\"\n    >\n      <template #prepend>\n        <v-icon color=\"warning\" />\n      </template>\n    </page-feature-chip>\n\n    <page-feature-chip\n      v-if=\"frontmatter?.features?.github\"\n      :href=\"`https://github.com/vuetifyjs/vuetify/tree/${branch}/packages/vuetify/src${frontmatter.features.github}`\"\n      :text=\"t('view-in-github')\"\n      prepend-icon=\"mdi-github\"\n      rel=\"noopener noreferrer\"\n      target=\"_blank\"\n    >\n      <template #prepend>\n        <v-icon color=\"black\" />\n      </template>\n    </page-feature-chip>\n\n    <page-feature-chip\n      v-if=\"frontmatter?.features?.spec\"\n      :href=\"frontmatter.features.spec\"\n      :text=\"t('design-spec')\"\n      prepend-icon=\"mdi-material-design\"\n      rel=\"noopener noreferrer\"\n      target=\"_blank\"\n    >\n      <template #prepend>\n        <v-icon color=\"surface-variant\" />\n      </template>\n    </page-feature-chip>\n\n    <div\n      v-if=\"isClipboardSupported && !isGeneratedPage\"\n      class=\"d-inline-block\"\n      v-tooltip:top=\"{\n        disabled: one.isSubscriber,\n        text: 'Subscribe to Vuetify One for access',\n      }\"\n    >\n      <page-feature-chip\n        :disabled=\"!one.isSubscriber\"\n        :text=\"copied ? t('copied') : t('copy-as-markdown')\"\n        prepend-icon=\"mdi-language-markdown-outline\"\n        @click=\"copyPageAsMarkdown\"\n      >\n        <template #prepend>\n          <v-icon :color=\"copied ? 'success' : 'surface-variant'\" />\n        </template>\n      </page-feature-chip>\n    </div>\n  </div>\n</template>\n\n<script setup>\n  const one = useOneStore()\n  const pins = usePinsStore()\n  const route = useRoute()\n  const user = useUserStore()\n  const { t } = useI18n()\n  const frontmatter = useFrontmatter()\n  const { copyPageAsMarkdown, copied, isClipboardSupported } = useMarkdown()\n\n  const branch = getBranch()\n\n  const pinned = computed(() => {\n    return pins.pins.some(p => p.to === route.path)\n  })\n\n  const isGeneratedPage = computed(() => {\n    return route.path.includes('/api/')\n  })\n\n  const label = computed(() => {\n    if (!frontmatter.value?.features?.label) return false\n\n    const original = encodeURIComponent(frontmatter.value.features.label)\n\n    return `https://github.com/vuetifyjs/vuetify/labels/${original}`\n  })\n\n  const contribute = computed(() => {\n    const branch = getBranch()\n    const link = route.path.split('/').slice(2).filter(v => v).join('/')\n\n    return `https://github.com/vuetifyjs/vuetify/edit/${branch}/packages/docs/src/pages/en/${link}.md`\n  })\n\n  function onClickPin () {\n    pins.toggle(!pinned.value, {\n      title: route.meta.title,\n      to: route.path,\n      category: frontmatter.value?.category,\n    })\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/about/TeamMember.vue",
    "content": "<template>\n  <v-lazy min-height=\"128\">\n    <div class=\"d-flex team-member\">\n      <v-avatar color=\"grey-lighten-2\" size=\"72\">\n        <v-img v-if=\"member.avatar\" :src=\"member.avatar\" />\n        <v-icon v-else color=\"grey\" size=\"35\"> mdi-image</v-icon>\n      </v-avatar>\n\n      <div class=\"ps-6 font-weight-medium\">\n        <div class=\"text-headline-small mb-1 font-weight-bold d-flex align-center\">\n          <span\n            class=\"me-3\"\n            v-text=\"member.name\"\n          />\n\n          <template v-for=\"link in links\">\n            <v-tooltip\n              v-if=\"link.href || link.copyText\"\n              :key=\"link.href || link.copyText\"\n              location=\"bottom\"\n            >\n              <template #activator=\"{ props: activatorProps }\">\n                <a\n                  v-if=\"link.href\"\n                  :href=\"link.href\"\n                  class=\"d-inline-flex text-decoration-none me-1\"\n                  rel=\"noopener\"\n                  target=\"_blank\"\n                  v-bind=\"activatorProps\"\n                >\n                  <v-icon\n                    :color=\"link.color\"\n                    :icon=\"link.icon\"\n                    size=\"small\"\n                  />\n                </a>\n\n                <div\n                  v-else\n                  class=\"cursor-pointer\"\n                  v-bind=\"activatorProps\"\n                  @click.prevent=\"copyTextToClipboard(link.copyText)\"\n                >\n                  <v-icon\n                    :color=\"link.color\"\n                    :icon=\"link.icon\"\n                    size=\"small\"\n                  />\n                </div>\n              </template>\n\n              <span>{{ link.tooltip }}</span>\n            </v-tooltip>\n          </template>\n        </div>\n\n        <div\n          v-if=\"member.focus\"\n          class=\"d-flex align-center flex-wrap\"\n        >\n          <h3\n            class=\"text-uppercase text-body-small font-weight-regular\"\n          >{{ t('focus') }}</h3>\n\n          <div class=\"mx-2\">\n            &nbsp;—&nbsp;\n          </div>\n\n          <template v-for=\"(focus, k) in member.focus\" :key=\"k\">\n            <AppMarkdown :content=\"focus\" />\n\n            <span\n              v-if=\"k < member.focus.length - 1\"\n              :key=\"`span-${k}`\"\n              class=\"mx-2\"\n            >\n              •\n            </span>\n          </template>\n        </div>\n\n        <div\n          v-if=\"member.funding\"\n          class=\"d-flex align-center flex-wrap mt-1\"\n        >\n          <h3\n            class=\"text-uppercase text-body-small font-weight-regular\"\n          >{{ t('funding') }}</h3>\n\n          <div class=\"mx-2\">\n            &nbsp;—&nbsp;\n          </div>\n\n          <template v-for=\"(funding, k) in member.funding\" :key=\"k\">\n            <AppMarkdown :content=\"funding\" />\n\n            <span\n              v-if=\"k < member.funding.length - 1\"\n              :key=\"`span-${k}`\"\n              class=\"mx-2\"\n            >\n              •\n            </span>\n          </template>\n        </div>\n\n        <template v-for=\"field in fields\">\n          <div\n            v-if=\"member[field]\"\n            :key=\"field\"\n            class=\"text-subtitle d-flex align-center my-2\"\n          >\n            <v-icon\n              :icon=\"icons[field]\"\n              start\n            />\n\n            <template v-if=\"Array.isArray(member[field])\">\n              <template v-for=\"(focus, j) in member[field]\" :key=\"j\">\n                <AppMarkdown :content=\"focus\" />\n\n                <span\n                  v-if=\"j < member[field]!.length - 1\"\n                  :key=\"`span-${j}`\"\n                  class=\"mx-2\"\n                >\n                  •\n                </span>\n              </template>\n            </template>\n\n            <template v-else>\n              {{ member[field] }}\n            </template>\n          </div>\n        </template>\n\n        <border-chip\n          v-if=\"member.joined\"\n          :text=\"t('joined', { date: member.joined })\"\n          prepend-icon=\"mdi-calendar\"\n        />\n      </div>\n    </div>\n  </v-lazy>\n</template>\n\n<script setup lang=\"ts\">\n  // Types\n  import type { Member } from '@/stores/team-members'\n  import type { PropType } from 'vue'\n\n  const props = defineProps({\n    member: {\n      type: Object as PropType<Member>,\n      default: () => ({}),\n    },\n  })\n\n  const { t } = useI18n()\n\n  const icons = {\n    languages: 'mdi-translate',\n    location: 'mdi-map-marker-outline',\n    work: 'mdi-briefcase-variant-outline',\n  }\n  const fields = ['work', 'location', 'languages'] as const\n\n  const links = computed(() => {\n    const links = []\n\n    if (props.member.twitter) {\n      links.push({\n        color: '#212121',\n        href: `https://x.com/${props.member.twitter}`,\n        icon: '$x',\n        tooltip: 'Xitter',\n      })\n    }\n\n    if (props.member.github) {\n      links.push({\n        color: '#24292E',\n        href: `https://github.com/${props.member.github}`,\n        icon: 'mdi-github',\n        tooltip: 'GitHub',\n      })\n    }\n\n    if (props.member.linkedin) {\n      links.push({\n        color: '#0077B5',\n        href: `https://linkedin.com/in/${props.member.linkedin}`,\n        icon: 'mdi-linkedin',\n        tooltip: 'LinkedIn',\n      })\n    }\n\n    if (props.member.discord) {\n      links.push({\n        color: '#738ADB',\n        copyText: props.member.discord,\n        icon: 'mdi-discord',\n        tooltip: `Discord: ${props.member.discord} (click to copy)`,\n      })\n    }\n\n    return links\n  })\n\n  function copyTextToClipboard (copyText?: string) {\n    if (!copyText) return\n    navigator.clipboard.writeText(copyText)\n  }\n</script>\n\n<style lang=\"sass\">\n  .team-member\n    .v-markdown\n      > p\n        margin: 0\n</style>\n"
  },
  {
    "path": "packages/docs/src/components/about/TeamMembers.vue",
    "content": "<template>\n  <v-container class=\"team-members\">\n    <v-row>\n      <template v-for=\"(member, i) in members\" :key=\"i\">\n        <v-col\n          cols=\"12\"\n        >\n          <AboutTeamMember v-bind=\"{ member }\" />\n        </v-col>\n\n        <v-divider\n          v-if=\"i < members.length - 1\"\n          :key=\"`divider-${i}`\"\n          class=\"mb-1 flex-1-1-100\"\n        />\n      </template>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  const props = defineProps({ team: String })\n  const teams = useTeamMembersStore()\n\n  const members = computed(() => teams.members.filter(member => member.team === props.team))\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/api/ApiTable.vue",
    "content": "<template>\n  <AppSheet>\n    <v-table class=\"api-table\" density=\"comfortable\">\n      <thead>\n        <tr>\n          <th\n            v-for=\"header in headers\"\n            :key=\"header\"\n            :class=\"header\"\n          >\n            <div\n              class=\"text-capitalize\"\n              v-text=\"header\"\n            />\n          </th>\n        </tr>\n      </thead>\n\n      <tbody>\n        <template v-for=\"item in filtered\" :key=\"item.name\">\n          <slot\n            name=\"row\"\n            v-bind=\"{\n              props: {\n                style: 'background: rgba(0,0,0,.1)'\n              },\n              item,\n            }\"\n          />\n\n          <tr v-if=\"item.description || (user.one.devmode && item.source)\">\n            <td class=\"text-mono pt-4\" colspan=\"3\">\n              <template v-if=\"item.description\">\n                <AppMarkdown\n                  v-if=\"localeStore.locale !== 'eo-UY'\"\n                  :content=\"item.description\"\n                  class=\"mb-0\"\n                />\n                <span v-else>{{ item.description }}</span>\n              </template>\n\n              <p v-if=\"user.one.devmode && item.source\">\n                <strong>source: {{ item.source }}</strong>\n                <template v-if=\"user.one.devmode && item.descriptionSource && item.source !== item.descriptionSource\">\n                  <br>\n                  <strong>description source: {{ item.descriptionSource }}</strong>\n                </template>\n              </p>\n            </td>\n          </tr>\n        </template>\n\n        <tr v-if=\"!filtered.length\">\n          <td class=\"text-center text-disabled text-body-medium\" colspan=\"4\">\n            {{ t('search.no-results') }}\n          </td>\n        </tr>\n      </tbody>\n    </v-table>\n  </AppSheet>\n</template>\n\n<script setup lang=\"ts\">\n  // Types\n  import type { PropType } from 'vue'\n\n  const props = defineProps({\n    headers: {\n      type: Array as PropType<string[]>,\n      default: () => ([]),\n    },\n    items: {\n      type: Array as PropType<any[]>,\n      default: () => [],\n    },\n  })\n\n  const { t } = useI18n()\n  const appStore = useAppStore()\n  const localeStore = useLocaleStore()\n  const user = useUserStore()\n\n  const filtered = computed(() => {\n    const items = props.items.filter((item: any) => {\n      return user.one.devmode || item.description !== '**FOR INTERNAL USE ONLY**'\n    })\n    if (!appStore.apiSearch) return items\n\n    const query = camelCase(appStore.apiSearch).toLowerCase()\n\n    return items.filter((item: any) => {\n      return item.name.toLowerCase().includes(query)\n    })\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/api/Backlinks.vue",
    "content": "<template>\n  <div class=\"mb-4 d-flex flex-column\">\n    <div v-for=\"link in links\" :key=\"link.name\">\n      <AppLink :href=\"link.href\">{{ link.name }}</AppLink>\n    </div>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\n  import pageToApi from '@/data/page-to-api.json'\n\n  const props = defineProps({\n    name: {\n      type: String,\n      required: true,\n    },\n  })\n\n  const route = useRoute()\n  const router = useRouter()\n\n  const links = computed(() => {\n    return (Object.keys(pageToApi) as (keyof typeof pageToApi)[])\n      .filter(page => pageToApi[page].includes(props.name))\n      .map(page => {\n        const resolved = router.resolve('/' + route.meta.locale + '/' + page)\n        const name = (resolved.meta.nav ?? page.split('/').at(-1)) as string\n        return {\n          name,\n          href: resolved.href,\n        }\n      })\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/api/DirectiveTable.vue",
    "content": "<template>\n  <div>\n    <AppMarkup :code=\"item.formatted\" :rounded=\"false\" language=\"ts\" />\n    <br>\n    <AppMarkdown\n      v-if=\"localeStore.locale !== 'eo-UY'\"\n      :content=\"item.description\"\n      class=\"mb-0\"\n    />\n    <span v-else>{{ item.description }}</span>\n\n    <p v-if=\"user.one.devmode && item.source\">\n      <strong>source: {{ item.source }}</strong>\n      <template v-if=\"user.one.devmode && item.descriptionSource && item.source !== item.descriptionSource\">\n        <br>\n        <strong>description source: {{ item.descriptionSource }}</strong>\n      </template>\n    </p>\n  </div>\n</template>\n\n<script setup>\n  const props = defineProps({\n    items: Array,\n    headers: Array,\n  })\n\n  const localeStore = useLocaleStore()\n  const user = useUserStore()\n\n  const item = computed(() => props.items[0])\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/api/EventsTable.vue",
    "content": "<template>\n  <ApiApiTable :headers=\"headers\">\n    <template #row=\"{ props, item }\">\n      <tr v-bind=\"props\">\n        <ApiNameCell :name=\"item.name\" :new-in=\"item.newIn\" section=\"events\" />\n\n        <td>\n          <ApiPrismCell :code=\"item.formatted\" />\n        </td>\n      </tr>\n    </template>\n  </ApiApiTable>\n</template>\n\n<script setup lang=\"ts\">\n  const headers = ['name', 'type']\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/api/ExposedTable.vue",
    "content": "<template>\n  <ApiApiTable>\n    <template #row=\"{ props, item }\">\n      <tr v-bind=\"props\">\n        <ApiNameCell :name=\"item.name\" :new-in=\"item.newIn\" section=\"exposed\" />\n      </tr>\n\n      <tr>\n        <AppMarkup\n          :code=\"item.formatted\"\n          :rounded=\"false\"\n          language=\"ts\"\n        />\n      </tr>\n    </template>\n  </ApiApiTable>\n</template>\n"
  },
  {
    "path": "packages/docs/src/components/api/Inline.vue",
    "content": "<template>\n  <border-chip\n    :prepend-icon=\"user.ecosystem.docs.api === 'inline' ? 'mdi-flask-outline' : 'mdi-flask-empty-outline'\"\n    :text=\"t('toggle', [`${t('inline')} ${t('api')}`])\"\n    class=\"mb-2\"\n    @click=\"onClick\"\n  />\n\n  <div v-if=\"components\" :class=\"showInline && 'mt-4'\">\n    <ApiLinks v-if=\"!showInline && !hideLinks\" :components=\"components\" />\n\n    <div v-if=\"showInline\">\n      <div class=\"d-flex justify-space-between align-center\">\n        <v-autocomplete\n          v-model=\"name\"\n          :items=\"components\"\n          :readonly=\"components.length === 1\"\n          class=\"mb-2\"\n          color=\"primary\"\n          label=\"Component API\"\n          prepend-inner-icon=\"mdi-view-dashboard\"\n          style=\"max-width: 250px;\"\n          variant=\"outlined\"\n          hide-details\n        />\n      </div>\n\n      <template v-for=\"section of sections\" :key=\"section\">\n        <ApiSection\n          :name=\"name\"\n          :section=\"section\"\n        />\n      </template>\n    </div>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\n  // Data\n  import pageToApi from '@/data/page-to-api.json'\n\n  const props = defineProps({\n    components: String,\n    hideLinks: Boolean,\n  })\n\n  const route = useRoute()\n  const { t, locale } = useI18n()\n  const user = useUserStore()\n  const name = shallowRef()\n  const sections = ['props', 'slots', 'events', 'exposed'] as const\n\n  const components = computed(() => {\n    if (props.components) return props.components.split(/, ?/)\n\n    const path = route.path.replace(`/${locale.value}/`, '').replace(/\\/$/, '')\n    return pageToApi[path as keyof typeof pageToApi]\n  })\n\n  const showInline = computed(() => user.ecosystem.docs.api === 'inline')\n\n  onBeforeMount(() => {\n    name.value = components.value?.[0] ?? ''\n  })\n\n  function onClick () {\n    user.ecosystem.docs.api = user.ecosystem.docs.api === 'inline' ? 'link-only' : 'inline'\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/api/Links.vue",
    "content": "<template>\n  <div class=\"mb-4 d-flex flex-column\">\n    <div v-for=\"link in links\" :key=\"link.name\">\n      <AppLink :href=\"link.href\">{{ link.name }}</AppLink>\n    </div>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\n  // Data\n  import pageToApi from '@/data/page-to-api.json'\n\n  const props = defineProps({\n    path: String,\n  })\n\n  const route = useRoute()\n  const { locale } = useI18n()\n\n  const links = computed(() => {\n    const path = props.path || route.path.replace(`/${locale.value}/`, '').replace(/\\/$/, '')\n    const apis = pageToApi[path as keyof typeof pageToApi]\n\n    return apis.map(name => ({\n      name,\n      href: `/${locale.value}/api/` + (name.startsWith('v-') ? `${name}-directive` : name),\n    }))\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/api/NameCell.vue",
    "content": "<template>\n  <td :id=\"`${section}-${name.replace('$', '')}`\">\n    <div class=\"d-inline-flex align-center\">\n      <kbd class=\"name-item text-mono\">\n        <AppLink :href=\"href\" class=\"font-weight-bold\">\n          {{ name }}\n        </AppLink>\n      </kbd>\n\n      <new-in-chip\n        v-if=\"newIn\"\n        :text=\"t('new-in', { version: newIn })\"\n        :to=\"to\"\n      />\n    </div>\n  </td>\n</template>\n\n<script setup>\n  const props = defineProps({\n    section: String,\n    name: String,\n    newIn: String,\n  })\n\n  const { t } = useI18n()\n\n  const href = computed(() => {\n    return `#${props.section}-${props.name.replace('$', '')}`\n  })\n  const to = computed(() => {\n    return rpath(`/getting-started/release-notes/?version=v${props.newIn}`)\n  })\n</script>\n\n<style scoped>\n  .app-link {\n    margin-left: -14px;\n  }\n\n  .app-link :deep(.v-icon) {\n    opacity: 0;\n    margin: 0;\n  }\n\n  .app-link:hover :deep(.v-icon) {\n    opacity: 1;\n  }\n</style>\n"
  },
  {
    "path": "packages/docs/src/components/api/PrismCell.vue",
    "content": "<template>\n  <pre v-html=\"html\" />\n</template>\n\n<script setup lang=\"ts\">\n  // Styles\n  import Prism from 'prismjs'\n  import 'prismjs/themes/prism.css'\n  import 'prismjs/components/prism-scss.js'\n  import 'prismjs/components/prism-typescript.js'\n\n  // Types\n  import type { PropType } from 'vue'\n\n  const props = defineProps({\n    code: null,\n    language: {\n      type: String as PropType<'typescript' | 'scss'>,\n      default: 'typescript',\n    },\n  })\n\n  const html = shallowRef('')\n  watchEffect(async () => {\n    html.value = highlight(String(await props.code))\n  })\n\n  const MAP = {\n    typescript: [Prism.languages.typescript, 'ts'] as const,\n    scss: [Prism.languages.scss, 'scss'] as const,\n  }\n\n  function highlight (value: string) {\n    const code = typeof value === 'object' ? JSON.stringify(value) : value\n    const [out, stripped] = stripLinks(code ?? '')\n    const [grammar, language] = MAP[props.language]\n    const highlighted = Prism.highlight(out, grammar, language)\n    return insertLinks(highlighted, stripped)\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/api/PropsTable.vue",
    "content": "<template>\n  <ApiApiTable :headers=\"headers\">\n    <template #row=\"{ props, item }\">\n      <tr v-bind=\"props\">\n        <ApiNameCell :name=\"kebabCase(item.name)\" :new-in=\"item.newIn\" section=\"props\" />\n\n        <td>\n          <ApiPrismCell :code=\"item.formatted\" />\n        </td>\n\n        <td>\n          <ApiPrismCell :code=\"item.default\" />\n        </td>\n      </tr>\n    </template>\n  </ApiApiTable>\n</template>\n\n<script setup lang=\"ts\">\n  const headers = ['name', 'type', 'default']\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/api/SassTable.vue",
    "content": "<template>\n  <ApiApiTable :headers=\"headers\">\n    <template #row=\"{ props, item }\">\n      <tr v-bind=\"props\">\n        <ApiNameCell :name=\"item.name\" :new-in=\"item.newIn\" section=\"sass\" />\n\n        <td>\n          <ApiPrismCell :code=\"item.default\" />\n        </td>\n      </tr>\n    </template>\n  </ApiApiTable>\n</template>\n\n<script setup lang=\"ts\">\n  const headers = ['name', 'default']\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/api/Search.vue",
    "content": "<template>\n  <div class=\"d-flex mb-2\">\n    <AppTextField\n      v-model=\"appStore.apiSearch\"\n      :placeholder=\"t('search-api')\"\n      clearable\n    />\n  </div>\n</template>\n\n<script setup>\n  const appStore = useAppStore()\n  const { t } = useI18n()\n\n  onBeforeUnmount(() => {\n    appStore.apiSearch = ''\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/api/Section.vue",
    "content": "<template>\n  <section v-if=\"items?.length\" :id=\"section\" class=\"mb-4\">\n    <AppHeadline :path=\"`api-headers.${section}`\" />\n    <TableComponent :items=\"items\" :name=\"name\" />\n  </section>\n</template>\n\n<script setup lang=\"ts\">\n  // Components\n  import DirectiveTable from '@/components/api/DirectiveTable.vue'\n  import EventsTable from '@/components/api/EventsTable.vue'\n  import ExposedTable from '@/components/api/ExposedTable.vue'\n  import PropsTable from '@/components/api/PropsTable.vue'\n  import SassTable from '@/components/api/SassTable.vue'\n  import SlotsTable from '@/components/api/SlotsTable.vue'\n\n  // Types\n  import type { PartData } from '@vuetify/api-generator/src/types'\n  import type { PropType } from 'vue'\n\n  // Data\n  import newIn from '@/data/new-in.json'\n\n  type PartKey = Exclude<keyof PartData, 'displayName' | 'fileName' | 'pathName'>\n  type NewIn = Record<string, Record<PartKey, Record<string, string>>>\n\n  const getApi = (name: string): Promise<{ default: PartData }> => {\n    return import(`../../../../api-generator/dist/api/${name}.json`)\n  }\n\n  const props = defineProps({\n    name: {\n      type: String,\n      required: true,\n    },\n    section: {\n      type: String as PropType<PartKey>,\n      required: true,\n    },\n  })\n\n  const store = useLocaleStore()\n  const items = shallowRef()\n\n  const TableComponent = computed(() => {\n    return {\n      props: PropsTable,\n      events: EventsTable,\n      slots: SlotsTable,\n      exposed: ExposedTable,\n      modifiers: ExposedTable,\n      sass: SassTable,\n      argument: DirectiveTable,\n      value: DirectiveTable,\n    }[props.section] || PropsTable\n  })\n\n  async function fetchApiData () {\n    try {\n      const api = (await getApi(props.name)).default\n      const sectionName = props.section\n      const section = api[sectionName]\n      if (!section) {\n        throw new Error(`API section \"${props.section}\" for \"${props.name}\" does not exist`)\n      }\n\n      if (sectionName === 'argument' || sectionName === 'value') {\n        const section = api[sectionName]!\n        items.value = [{\n          ...section,\n          name: sectionName,\n          description: section.description?.[store.locale],\n          descriptionSource: section.descriptionSource?.[store.locale],\n        }]\n      } else {\n        const _newIn = newIn as any as NewIn\n        items.value = Object.entries(section).reduce<any>((arr, [name, prop]) => {\n          arr.push({\n            ...prop,\n            name,\n            newIn: _newIn?.[props.name]?.[props.section]?.[name],\n            description: prop.description?.[store.locale],\n            descriptionSource: prop.descriptionSource?.[store.locale],\n          })\n          return arr\n        }, []).sort((a: any, b: any) => a.name.localeCompare(b.name))\n      }\n    } catch (err) {}\n  }\n\n  fetchApiData()\n\n  watch(() => props.name, fetchApiData)\n</script>\n\n<style lang=\"sass\">\n  .api-table\n    .regular-row td\n      padding: 8px 16px !important\n\n    .regular-row.has-extra-row td\n      border-bottom: none !important\n\n    .extra-row:hover\n      background: initial !important\n\n    .extra-row td\n      padding: 8px 0 !important\n\n    .v-markdown :deep(p)\n      margin-bottom: 0\n\n    .token.operator\n      background: none\n\n  .name-item\n    white-space: nowrap\n\n    &:not(:hover):not(:focus)\n      span\n        opacity: 0\n</style>\n"
  },
  {
    "path": "packages/docs/src/components/api/SlotsTable.vue",
    "content": "<template>\n  <ApiApiTable>\n    <template #row=\"{ props, item }\">\n      <tr v-bind=\"props\">\n        <ApiNameCell :name=\"item.name\" :new-in=\"item.newIn\" section=\"slots\" />\n      </tr>\n\n      <tr v-if=\"item.formatted !== 'never' && item.text !== 'undefined'\">\n        <AppMarkup :code=\"item.formatted\" :rounded=\"false\" language=\"ts\" />\n      </tr>\n    </template>\n  </ApiApiTable>\n</template>\n"
  },
  {
    "path": "packages/docs/src/components/api/View.vue",
    "content": "<script setup lang=\"ts\">\n  import type { PartData } from '@vuetify/api-generator/src/types'\n  import DefaultLayout from '@/layouts/default.vue'\n  import ErrorLayout from '@/layouts/404.vue'\n\n  const emit = defineEmits(['update:name'])\n\n  const sections = ['props', 'events', 'slots', 'exposed', 'sass', 'argument', 'modifiers', 'value'] as const\n\n  const route = useRoute()\n  const router = useRouter()\n\n  const error = shallowRef(false)\n  const name = computed(() => {\n    const name = route.params.name as string\n    if (name.endsWith('-directive')) return name.replace('-directive', '')\n    else if (name.startsWith('use-')) return camelCase(name)\n    else if (name === 'globals') return name\n    else return `${name.charAt(0).toUpperCase()}${camelize(name.slice(1))}`\n  })\n  const component = shallowRef<any>({})\n\n  function generateToc () {\n    const toc = []\n    for (const section of sections) {\n      if (section in component.value && Object.keys(component.value[section]).length) {\n        toc.push({\n          to: `#${section}`,\n          text: section.charAt(0).toUpperCase() + section.slice(1),\n          level: 2,\n        })\n      }\n    }\n    return toc\n  }\n\n  function updateFrontmatter () {\n    const matched = router.currentRoute.value.matched\n    if (matched.length > 0) {\n      const lastMatch = matched[matched.length - 1]\n      if (lastMatch.instances.default) {\n        (lastMatch.instances.default as any).frontmatter = {\n          ...(lastMatch.instances.default as any).frontmatter,\n          toc: generateToc(),\n        }\n      }\n    }\n  }\n\n  watch(name, async () => {\n    emit('update:name', name.value)\n    try {\n      component.value = await getApi(name.value)\n      error.value = false\n      updateFrontmatter()\n    } catch (err) {\n      error.value = true\n    }\n  }, { immediate: true })\n\n  function getApi (name: string): Promise<{ default: PartData }> {\n    return import(`../../../../api-generator/dist/api/${name}.json`).then(m => m.default)\n  }\n</script>\n\n<template>\n  <ErrorLayout v-if=\"error\" />\n  <DefaultLayout v-else>\n    <template #view>\n      <slot />\n      <template v-for=\"section of sections\" :key=\"section\">\n        <ApiSection\n          v-if=\"section in component && Object.keys(component[section]).length\"\n          :name=\"name\"\n          :section=\"section\"\n        />\n      </template>\n    </template>\n  </DefaultLayout>\n</template>\n"
  },
  {
    "path": "packages/docs/src/components/api/utils.ts",
    "content": "export function stripLinks (str: string): [string, Record<string, string>] {\n  let out = str.slice()\n  const obj: Record<string, string> = {}\n  const regexp = /<a .+?>(.+?)<\\/a>/g\n\n  let matches = regexp.exec(str)\n\n  while (matches !== null) {\n    obj[matches[1]] = matches[0]\n    out = out.replace(matches[0], matches[1])\n\n    matches = regexp.exec(str)\n  }\n\n  return [out, obj]\n}\n\nexport function insertLinks (str: string, stripped: Record<string, string>) {\n  for (const [key, value] of Object.entries(stripped)) {\n    str = str.replaceAll(new RegExp(`(^|\\\\W)(${key})(\\\\W|$)`, 'g'), `$1${value}$3`)\n  }\n  return str\n}\n"
  },
  {
    "path": "packages/docs/src/components/app/BackToTop.vue",
    "content": "<template>\n  <v-fab\n    v-model=\"model\"\n    color=\"primary\"\n    elevation=\"8\"\n    icon=\"mdi-chevron-up\"\n    size=\"large\"\n    app\n    v-scroll=\"onScroll\"\n    @click=\"goTo(0)\"\n  />\n</template>\n\n<script setup>\n  const goTo = useGoTo({ layout: true })\n\n  const model = shallowRef(false)\n\n  function onScroll () {\n    model.value = window.scrollY > 200\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/Btn.vue",
    "content": "<template>\n  <v-btn\n    :icon=\"!!icon\"\n    :size=\"smAndUp ? 'default' : 'small'\"\n    :variant=\"variant\"\n    class=\"text-body-medium text-capitalize px-3 app-btn\"\n    color=\"medium-emphasis\"\n  >\n    <slot />\n\n    <template v-if=\"text\">\n      {{ t(text) }}\n    </template>\n\n    <template v-else-if=\"icon || $slots.icon\">\n      <slot v-if=\"$slots.icon\" name=\"icon\" />\n\n      <v-icon v-else :icon=\"icon\" size=\"24\" />\n    </template>\n  </v-btn>\n</template>\n\n<script setup>\n  defineProps({\n    icon: String,\n    text: String,\n    variant: {\n      type: String,\n      default: 'text',\n    },\n  })\n\n  const { smAndUp } = useDisplay()\n  const { t } = useI18n()\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/Caption.vue",
    "content": "<template>\n  <AppHeadline\n    :path=\"path\"\n    color=\"grey\"\n    size=\"caption\"\n    weight=\"regular\"\n  />\n</template>\n\n<script setup>\n  defineProps({\n    path: {\n      type: String,\n      default: '',\n    },\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/CommitBtn.vue",
    "content": "<template>\n  <v-btn\n    :href=\"`https://github.com/vuetifyjs/vuetify/commit/${commits.latest?.sha}`\"\n    :prepend-icon=\"commits.latest ? 'mdi-source-commit' : undefined\"\n    :readonly=\"!commits.latest\"\n    :text=\"commits.latest?.sha.slice(0, 7)\"\n    class=\"text-body-small\"\n    rel=\"noopener noreferrer\"\n    size=\"small\"\n    target=\"_blank\"\n    variant=\"text\"\n    slim\n  />\n</template>\n\n<script lang=\"ts\" setup>\n  const commits = useCommitsStore()\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/Divider.vue",
    "content": "<template>\n  <v-divider class=\"my-5\" />\n</template>\n\n<script setup>\n  //\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/Figure.vue",
    "content": "<template>\n  <figure>\n    <v-img\n      class=\"rounded bg-surface\"\n      v-bind=\"$attrs\"\n    />\n\n    <figcaption\n      v-if=\"caption\"\n      class=\"text-body-small font-weight-bold text-center text-capitalize text-medium-emphasis\"\n      v-text=\"caption\"\n    />\n\n    <slot v-else />\n  </figure>\n</template>\n\n<script setup>\n  const attrs = useAttrs()\n\n  defineProps({\n    name: String,\n  })\n\n  const caption = computed(() => attrs.title === 'null' ? null : attrs.title)\n</script>\n\n<script>\n  export default {\n    inheritAttrs: false,\n  }\n</script>\n\n<style scoped>\nfigure {\n  margin: 0;\n}\n</style>\n"
  },
  {
    "path": "packages/docs/src/components/app/Heading.vue",
    "content": "<template>\n  <component\n    :is=\"component\"\n    :class=\"classes\"\n  >\n    <router-link\n      v-if=\"href\"\n      :to=\"href\"\n      aria-hidden=\"true\"\n      class=\"text-decoration-none text-end text-md-start d-none d-sm-inline-block\"\n      style=\"user-select: none\"\n    >\n      <span class=\"text-primary\">#</span>\n    </router-link>\n\n    <slot>\n      {{ content }}\n    </slot>\n  </component>\n</template>\n\n<script setup>\n  const HEADING_CLASSES = {\n    1: 'text-display-medium text-sm-display-medium',\n    2: 'text-headline-large text-sm-headline-large',\n    3: 'text-headline-small',\n    4: 'text-title-large',\n    5: 'text-body-large font-weight-medium',\n  }\n\n  const props = defineProps({\n    content: String,\n    href: String,\n    level: String,\n  })\n\n  const component = computed(() => `h${props.level}`)\n  const classes = computed(() => ['v-heading', 'mt-0', 'mb-2', HEADING_CLASSES[props.level]])\n</script>\n\n<style lang=\"sass\">\n  .v-heading\n    display: inline-block\n    position: relative\n\n    > a\n      bottom: 0\n      font-size: .75em\n      left: 0\n      margin: 0 -.7em\n      position: absolute\n      right: 0\n      top: 0\n\n      &:not(:hover):not(:focus)\n        opacity: 0\n\n    + p\n      margin-block-start: 0\n</style>\n"
  },
  {
    "path": "packages/docs/src/components/app/Headline.vue",
    "content": "<template>\n  <component\n    :is=\"tag\"\n    :class=\"`text-${size} font-weight-${weight} text-${color}`\"\n  >\n    {{ t(path) }}\n  </component>\n</template>\n\n<script setup>\n  defineProps({\n    color: String,\n    size: {\n      type: String,\n      default: 'h6',\n    },\n    tag: {\n      type: String,\n      default: 'div',\n    },\n    weight: {\n      type: String,\n      default: 'medium',\n    },\n    path: {\n      type: String,\n      default: '',\n    },\n  })\n\n  const { t } = useI18n()\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/Link.vue",
    "content": "<template>\n  <component\n    :is=\"tag\"\n    class=\"app-link text-decoration-none text-primary font-weight-medium d-inline-flex align-center\"\n    v-bind=\"attrs\"\n  >\n    <template v-if=\"iconProps && isSamePage\">\n      <VIcon v-bind=\"iconProps\" />\n    </template>\n\n    <slot />\n\n    <template v-if=\"iconProps && !isSamePage\">\n      <VIcon v-bind=\"iconProps\" />\n    </template>\n  </component>\n</template>\n\n<script setup lang=\"ts\">\n  const props = defineProps({\n    href: {\n      type: String,\n      default: '',\n    },\n  })\n\n  const isExternal = computed(() => props.href.startsWith('http') || props.href.startsWith('mailto'))\n  const isSamePage = computed(() => !isExternal.value && props.href.startsWith('#'))\n  const attrs = computed(() => isExternal.value\n    ? { href: props.href, target: '_blank', rel: 'noopener' }\n    : { to: isSamePage.value ? props.href : rpath(props.href) }\n  )\n\n  const icon = computed(() => {\n    if (isSamePage.value) return 'mdi-pound'\n    if (isExternal.value) return 'mdi-open-in-new'\n    if (props.href) return 'mdi-page-next'\n\n    return null\n  })\n\n  const iconProps = computed(() => {\n    if (!icon.value) return null\n\n    return {\n      icon: icon.value,\n      class: `m${isSamePage.value ? 'e' : 's'}-1`,\n      color: 'primary',\n      size: '.875rem',\n    }\n  })\n  const tag = computed(() => isExternal.value ? 'a' : 'router-link')\n</script>\n\n<style lang=\"sass\">\n  .app-link\n    p\n      margin-bottom: 0\n</style>\n"
  },
  {
    "path": "packages/docs/src/components/app/Markdown.vue",
    "content": "<template>\n  <component :is=\"tag\" class=\"v-markdown\">\n    <component :is=\"template\" />\n  </component>\n</template>\n\n<script setup>\n  // Utilities\n  import MarkdownIt from 'markdown-it'\n  import { compile } from '@vue/compiler-dom'\n  import * as vue from 'vue'\n\n  import { VCode } from 'vuetify/components/VCode'\n  import { VWindowItem } from 'vuetify/components/VWindow'\n  import { VTab } from 'vuetify/components/VTabs'\n  import AppMarkup from '@/components/app/Markup.vue'\n  import AppFigure from '@/components/app/Figure.vue'\n  import AppDivider from '@/components/app/Divider.vue'\n  import AppHeading from '@/components/app/Heading.vue'\n  import AppLink from '@/components/app/Link.vue'\n  import AppTable from '@/components/app/Table.vue'\n  import Alert from '@/components/Alert.vue'\n  import DocTabs from '@/components/doc/Tabs.vue'\n\n  const md = configureMarkdown(MarkdownIt({\n    html: true,\n    linkify: true,\n    typographer: true,\n  }), { headerSections: false })\n\n  md.core.ruler.after('linkify', 'gh_links', state => {\n    const blockTokens = state.tokens\n\n    for (let j = 0; j < blockTokens.length; j++) {\n      if (blockTokens[j].type !== 'inline') continue\n\n      const tokens = blockTokens[j].children\n\n      for (let i = tokens.length - 1; i >= 0; i--) {\n        const currentToken = tokens[i]\n\n        // Skip content of markdown links\n        if (currentToken.type === 'link_close') {\n          i--\n          while (tokens[i].level !== currentToken.level && tokens[i].type !== 'link_open') {\n            i--\n          }\n          continue\n        }\n\n        if (currentToken.type === 'text') {\n          const text = currentToken.content\n\n          const links = [\n            ...text.matchAll(/(?<commits>[a-f0-9]{7,40})(?:\\D|$)/gm),\n            ...text.matchAll(/(?<issues>#(\\d{3,5}))(?:\\D|$)/gm),\n          ]\n          links.sort((a, b) => a.index - b.index)\n\n          const nodes = []\n          let level = currentToken.level\n          let lastPos = 0\n\n          links.forEach(link => {\n            const url = `https://github.com/vuetifyjs/vuetify/${Object.keys(link.groups)[0]}/${link.at(-1)}`\n            const linkText = link[1]\n            const pos = link.index\n\n            if (pos > lastPos) {\n              const token = new state.Token('text', '', 0)\n              token.content = text.slice(lastPos, pos)\n              token.level = level\n              nodes.push(token)\n            }\n\n            let token = new state.Token('link_open', 'a', 1)\n            token.attrs = [['href', url], ['_target', 'blank']]\n            token.level = level++\n            nodes.push(token)\n\n            if (link.groups.commits) {\n              token = new state.Token('code_inline', 'code', 0)\n              token.attrSet('class', 'text-body-large')\n            } else {\n              token = new state.Token('text', '', 0)\n            }\n            token.content = linkText\n            token.level = level\n            nodes.push(token)\n\n            token = new state.Token('link_close', 'a', -1)\n            token.level = --level\n            nodes.push(token)\n\n            lastPos = link.index + link[1].length\n          })\n          if (lastPos < text.length) {\n            const token = new state.Token('text', '', 0)\n            token.content = text.slice(lastPos)\n            token.level = level\n            nodes.push(token)\n          }\n\n          tokens.splice(i, 1, ...nodes)\n        }\n      }\n    }\n  })\n\n  const fence = md.renderer.rules.fence\n  md.renderer.rules.fence = (tokens, idx, options, env, self) => {\n    return fence(tokens, idx, options, env, self)\n      .replaceAll('{{', '&lbrace;&lbrace;')\n      .replaceAll('}}', '&rbrace;&rbrace;')\n  }\n\n  const props = defineProps({\n    tag: {\n      type: String,\n      default: 'div',\n    },\n    content: String,\n  })\n\n  const markdown = computed(() => md.render(props.content, {}))\n  const template = computed(() => ({\n    // These components are all used in markdown-it-rules\n    components: {\n      VCode,\n      VWindowItem,\n      VTab,\n      AppMarkup,\n      AppFigure,\n      AppDivider,\n      AppHeading,\n      AppLink,\n      AppTable,\n      Alert,\n      DocTabs,\n    },\n    // eslint-disable-next-line no-new-func\n    render: new Function(\n      'Vue',\n      compile(markdown.value, { hoistStatic: true }).code\n    )(vue),\n  }))\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/Markup.vue",
    "content": "<template>\n  <v-hover v-slot=\"{ props: hoverProps, isHovering }\">\n    <v-sheet\n      v-bind=\"{ ...hoverProps, ...$attrs }\"\n      ref=\"root\"\n      :color=\"theme.name.value === 'light' && !user.ecosystem.docs.mixedTheme ? 'surface-bright' : undefined\"\n      :rounded=\"rounded\"\n      :theme=\"theme.name.value === 'light' && user.ecosystem.docs.mixedTheme ? 'dark' : theme.name.value\"\n      class=\"app-markup overflow-hidden\"\n      dir=\"ltr\"\n    >\n      <v-toolbar\n        v-if=\"resource\"\n        class=\"px-1\"\n        height=\"44\"\n      >\n        <v-sheet\n          v-if=\"resource\"\n          class=\"text-body-medium px-3 pt-3 text-medium-emphasis\"\n          color=\"transparent\"\n          height=\"44\"\n          rounded=\"tl\"\n        >\n          <v-icon icon=\"mdi-file-tree\" />\n\n          {{ resource }}\n        </v-sheet>\n      </v-toolbar>\n\n      <v-tooltip location=\"start\">\n        <template #activator=\"{ props: activatorProps }\">\n          <v-fade-transition>\n            <v-btn\n              v-if=\"isHovering\"\n              :key=\"icon\"\n              :icon=\"icon\"\n              class=\"text-disabled me-3 mt-2 app-markup-btn position-absolute right-0 top-0\"\n              density=\"comfortable\"\n              size=\"small\"\n              v-bind=\"activatorProps\"\n              variant=\"text\"\n              @click=\"copy\"\n            />\n          </v-fade-transition>\n        </template>\n\n        <span>{{ t('copy-source') }}</span>\n      </v-tooltip>\n\n      <v-tooltip location=\"start\">\n        <template #activator=\"{ props: activatorProps }\">\n          <v-fade-transition>\n            <v-btn\n              v-if=\"isHovering\"\n              :key=\"icon\"\n              :icon=\"needsPlaygroundLink ? '$vuetify-play' : '$vuetify-bin'\"\n              class=\"text-disabled me-12 mt-2 app-markup-btn position-absolute right-0 top-0\"\n              density=\"comfortable\"\n              size=\"small\"\n              v-bind=\"activatorProps\"\n              variant=\"text\"\n              @click=\"openCode\"\n            />\n          </v-fade-transition>\n        </template>\n\n        <span>{{ t(needsPlaygroundLink ? 'open-in-playground' : 'open-in-vuetify-bin') }}</span>\n      </v-tooltip>\n\n      <div class=\"pa-4 pe-12\">\n        <slot>\n          <pre v-if=\"inline\" :class=\"className\">\n        <code :class=\"className\" v-html=\"highlighted\" />\n      </pre>\n\n          <code v-else :class=\"className\" v-html=\"highlighted\" />\n        </slot>\n      </div>\n    </v-sheet>\n  </v-hover>\n</template>\n\n<script setup lang=\"ts\">\n  // Styles\n  import Prism from 'prismjs'\n  import 'prismjs/themes/prism.css'\n  import 'prismjs/components/prism-bash.js'\n  import 'prismjs/components/prism-css.js'\n  import 'prismjs/components/prism-javascript.js'\n  import 'prismjs/components/prism-json.js'\n  import 'prismjs/components/prism-sass.js'\n  import 'prismjs/components/prism-scss.js'\n  import 'prismjs/components/prism-typescript.js'\n\n  // Types\n  import type { ComponentPublicInstance } from 'vue'\n\n  const props = defineProps({\n    resource: String,\n    code: {\n      type: [String, Array] as PropType<string | CodeSection[]>,\n      default: '',\n    },\n    inline: Boolean,\n    language: {\n      type: String,\n      default: 'markup',\n    },\n    rounded: {\n      type: Boolean,\n      default: true,\n    },\n  })\n\n  // Transform inline links in typescript into actual links\n  Prism.languages.insertBefore('typescript', 'string', {\n    hyperlink: /<a.*?>(.*?)<\\/a>/g,\n  })\n  Prism.hooks.add('wrap', env => {\n    if (env.type === 'hyperlink' && env.tag !== 'a') {\n      env.tag = 'a'\n      env.content = env.content.replaceAll('&lt;', '<')\n      env.attributes.href = /href=\"(.*?)\"/.exec(env.content)?.[1] || ''\n      env.attributes.target = '_blank'\n      env.content = stripLinks(env.content)[0]\n    }\n  })\n\n  const user = useUserStore()\n  const theme = useTheme()\n  const { t } = useI18n()\n  const clicked = shallowRef(false)\n  const root = ref<ComponentPublicInstance>()\n\n  const highlighted = shallowRef('')\n\n  const className = computed(() => `language-${props.language}`)\n  const icon = computed(() => clicked.value ? 'mdi-check' : 'mdi-clipboard-text-outline')\n\n  const needsPlaygroundLink = computed(() => Array.isArray(props.code))\n\n  const displayedCode = computed(() => {\n    if (typeof props.code === 'string') {\n      return props.code\n    }\n\n    return props.code.map((section: CodeSection) => section.content).join('\\n\\n')\n  })\n\n  watchEffect(async () => {\n    highlighted.value = displayedCode.value && props.language && Prism.highlight(await displayedCode.value, Prism.languages[props.language], props.language)\n  })\n\n  function openCode () {\n    if (needsPlaygroundLink.value) {\n      openPlayground()\n    } else {\n      openBin()\n    }\n  }\n\n  async function openBin () {\n    const el = root.value?.$el.querySelector('code')\n    const code = displayedCode.value || el?.innerText || ''\n    const language = props.language || 'markdown'\n    const title = props.resource\n\n    const compressed = useBin(code, language, title)\n\n    window.open(compressed, '_blank')\n  }\n\n  async function openPlayground () {\n    if (typeof props.code === 'string') return\n\n    const url = usePlayground(props.code)\n\n    window.open(url, '_blank')\n  }\n\n  async function copy () {\n    const el = root.value?.$el.querySelector('code')\n\n    await navigator.clipboard.writeText(displayedCode.value || el?.innerText || '')\n\n    clicked.value = true\n\n    await wait(2000)\n\n    clicked.value = false\n  }\n</script>\n\n<script lang=\"ts\">\n  export default {\n    inheritAttrs: false,\n  }\n</script>\n\n<style lang=\"sass\">\n  .v-sheet.app-markup\n    position: relative\n\n    code,\n    pre\n      background: none\n      color: currentColor !important\n      font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace\n      font-size: 1rem\n      font-weight: 300\n      hyphens: none\n      line-height: 1.5\n      margin: 0\n      padding: 0\n      tab-size: 4\n      text-align: left\n      text-shadow: none\n      white-space: pre-wrap\n      word-break: normal\n      word-spacing: normal\n      word-wrap: normal\n\n    pre,\n    code\n      &::after\n        bottom: .5rem\n        color: hsla(0, 0%, 19%, 0.5)\n        font-family: inherit\n        font-size: 0.7rem\n        font-weight: 700\n        pointer-events: none\n        position: absolute\n        right: 1rem\n        text-transform: uppercase\n\n    pre.language-bash::after\n      content: ' sh '\n\n    pre.language-html::after\n      content: 'html'\n\n    pre.language-js::after\n      content: ' js '\n\n    pre.language-json::after\n      content: 'json'\n\n    pre.language-sass::after\n      content: 'sass'\n\n    code.language-scss::after\n      content: 'scss'\n\n    pre.language-ts::after\n      content: ' ts '\n\n    pre.language-vue::after\n      content: 'vue'\n\n    // TODO: handle this differently\n    &.v-theme--blackguard,\n    &.v-theme--dark\n      --prism-interpolation: var(--prism-operator)\n\n      code,\n      pre\n        color: #ccc !important\n\n        &::selection, ::selection\n          background-color: #113663\n\n      code,\n      pre\n        &::after\n          color: hsla(0, 0%, 50%, 1)\n\n      &.v-sheet--outlined\n        border: thin solid hsla(0,0%,100%,.12) !important\n\n      .token.operator,\n      .token.string\n        background: none\n\n      .token.comment,\n      .token.block-comment,\n      .token.prolog,\n      .token.doctype,\n      .token.cdata\n        color: #999\n\n      .token.punctuation\n        color: #ccc\n\n      .token.tag,\n      .token.attr-name,\n      .token.namespace,\n      .token.deleted\n        color: #e2777a\n\n      .token.function-name\n        color: #6196cc\n\n      .token.boolean,\n      .token.number,\n      .token.function\n        color: #f08d49\n\n      .token.property,\n      .token.class-name,\n      .token.constant,\n      .token.symbol\n        color: #f8c555\n\n      .token.selector,\n      .token.important,\n      .token.atrule,\n      .token.keyword,\n      .token.builtin\n        color: #cc99cd\n\n      .token.string,\n      .token.char,\n      .token.attr-value,\n      .token.regex,\n      .token.variable\n        color: #7ec699\n\n      .token.operator,\n      .token.entity,\n      .token.url\n        color: #67cdcc\n\n      .token.important,\n      .token.bold\n        font-weight: bold\n\n      .token.italic\n        font-style: italic\n\n      .token.entity\n        cursor: help\n\n      .token.inserted\n        color: green\n</style>\n"
  },
  {
    "path": "packages/docs/src/components/app/Sheet.vue",
    "content": "<template>\n  <v-sheet\n    border\n    rounded\n  >\n    <slot />\n  </v-sheet>\n</template>\n\n<script setup>\n  //\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/Table.vue",
    "content": "<template>\n  <AppSheet class=\"mb-4 app-table\">\n    <v-table\n      density=\"comfortable\"\n      v-bind=\"$attrs\"\n    >\n      <slot />\n    </v-table>\n  </AppSheet>\n</template>\n\n<script>\n  export default {\n    inheritAttrs: false,\n  }\n</script>\n\n<style lang=\"sass\">\n  .app-table\n    tbody > tr > td:first-child\n      white-space: nowrap\n</style>\n"
  },
  {
    "path": "packages/docs/src/components/app/TextField.vue",
    "content": "<template>\n  <v-text-field\n    :placeholder=\"t('search.label')\"\n    base-color=\"disabled\"\n    prepend-inner-icon=\"mdi-magnify\"\n    variant=\"outlined\"\n    hide-details\n    persistent-placeholder\n    single-line\n  >\n    <template v-if=\"$slots['append-inner']\" #append-inner>\n      <slot name=\"append-inner\" />\n    </template>\n  </v-text-field>\n</template>\n\n<script setup lang=\"ts\">\n  const { t } = useI18n()\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/Title.vue",
    "content": "<template>\n  <AppHeadline size=\"subtitle-2\" weight=\"black\" />\n</template>\n\n<script setup>\n  //\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/Toc.vue",
    "content": "<template>\n  <v-navigation-drawer\n    v-if=\"!route.meta.fluid\"\n    id=\"app-toc\"\n    v-model=\"tocDrawer\"\n    color=\"background\"\n    location=\"right\"\n    width=\"256\"\n    floating\n    sticky\n  >\n    <template #prepend>\n      <AppHeadline\n        v-if=\"frontmatter?.toc?.length\"\n        class=\"mt-4 mb-2 ms-4\"\n        path=\"contents\"\n      />\n    </template>\n\n    <ul class=\"ms-5\">\n      <router-link\n        v-for=\"{ to, level, text } in frontmatter?.toc\"\n        :key=\"text\"\n        v-slot=\"{ href }\"\n        :to=\"to\"\n        custom\n      >\n        <li\n          :class=\"[\n            'ps-3 text-medium-emphasis text-body-medium py-1 font-weight-regular',\n            {\n              'text-primary router-link-active': activeItem === to.slice(1),\n              'ps-6': level === 3,\n              'ps-9': level === 4,\n              'ps-12': level === 5,\n            }\n          ]\"\n        >\n          <a\n            :href=\"href\"\n            class=\"v-toc-link d-block text-decoration-none\"\n            @click.prevent.stop=\"onClick(to)\"\n            v-text=\"text\"\n          />\n        </li>\n      </router-link>\n    </ul>\n\n    <template #append>\n      <v-container>\n        <AppHeadline\n          v-if=\"sponsors.length\"\n          :to=\"rpath('/introduction/sponsors-and-backers/')\"\n          class=\"mb-1 mt-n1 text-high-emphasis text-decoration-none\"\n          path=\"sponsors\"\n          size=\"subtitle-1\"\n          tag=\"router-link\"\n        />\n\n        <v-row density=\"comfortable\">\n          <template v-if=\"sponsors.length\">\n            <v-col\n              v-for=\"sponsor of sponsors\"\n              :key=\"sponsor.slug\"\n              :cols=\"sponsor.metadata.tier === -2 ? 12 : 6\"\n              class=\"d-inline-flex\"\n            >\n              <sponsor-card\n                :color=\"dark ? undefined : 'grey-lighten-5'\"\n                :max-height=\"sponsor.metadata.tier === -2 ? 52 : 40\"\n                :sponsor=\"sponsor\"\n              />\n            </v-col>\n\n            <v-col class=\"d-inline-flex\">\n              <v-btn\n                :to=\"rpath('/introduction/sponsors-and-backers/')\"\n                append-icon=\"$vuetify\"\n                class=\"text-none\"\n                color=\"primary\"\n                size=\"large\"\n                text=\"Support\"\n                variant=\"tonal\"\n                block\n              />\n            </v-col>\n          </template>\n\n          <v-col v-else cols=\"12\">\n            <v-btn\n              class=\"text-none border-opacity-50 border-primary\"\n              color=\"primary\"\n              href=\"https://github.com/sponsors/johnleider\"\n              prepend-icon=\"mdi-github\"\n              rel=\"noopener noreferrer\"\n              size=\"large\"\n              target=\"_blank\"\n              text=\"Your Logo Here\"\n              variant=\"tonal\"\n              block\n              border\n            />\n          </v-col>\n\n          <v-col\n            v-if=\"spot.spot && (user.one.ads.enabled || (user.one.ads.house && spot.spot.sponsor === 'Vuetify'))\"\n            cols=\"12\"\n          >\n            <a\n              :href=\"spot.spot.href\"\n              rel=\"noopener noreferrer sponsored\"\n              target=\"_blank\"\n              @click=\"sweClick('toc', 'promotion', spot.spot.sponsor)\"\n            >\n              <v-img :src=\"spot.spot.image.url\" />\n            </a>\n          </v-col>\n        </v-row>\n      </v-container>\n    </template>\n  </v-navigation-drawer>\n</template>\n\n<script setup lang=\"ts\">\n  const { toc: tocDrawer, scrolling } = storeToRefs(useAppStore())\n\n  const route = useRoute()\n  const router = useRouter()\n  const spot = useSpotStore()\n  const theme = useTheme()\n  const user = useUserStore()\n  const frontmatter = useFrontmatter()\n\n  const activeStack = [] as string[]\n  const activeItem = shallowRef('')\n  const observer = new IntersectionObserver(entries => {\n    entries.forEach(entry => {\n      if (entry.isIntersecting) {\n        activeStack.push(entry.target.id)\n      } else if (activeStack.includes(entry.target.id)) {\n        activeStack.splice(activeStack.indexOf(entry.target.id), 1)\n      }\n    })\n    activeItem.value = activeStack.at(-1) || activeItem.value || frontmatter.value?.toc?.[0]?.to.slice(1) || ''\n  }, { rootMargin: '-10% 0px -75%' })\n\n  async function observeToc () {\n    scrolling.value = false\n    activeStack.length = 0\n    activeItem.value = ''\n    observer.disconnect()\n    await nextTick()\n    frontmatter.value?.toc?.forEach(v => {\n      const el = document.querySelector(v.to)\n      el && observer.observe(el)\n    })\n  }\n\n  watch(() => frontmatter.value?.toc, observeToc)\n  onMounted(() => {\n    observeToc()\n  })\n  onScopeDispose(() => {\n    observer.disconnect()\n  })\n\n  let internalScrolling = false\n  let timeout = -1\n  watch(activeItem, async val => {\n    if (!val || internalScrolling) return\n\n    scrolling.value = true\n    const query = route.query\n\n    if (val === frontmatter.value?.toc?.[0]?.to.slice(1) && route.hash) {\n      router.replace({ path: route.path, query })\n    } else {\n      const toc = frontmatter.value?.toc?.find(v => v.to.slice(1) === val)\n      if (toc) {\n        await router.replace({ path: route.path, hash: toc.to, query })\n      }\n    }\n    clearTimeout(timeout)\n    timeout = window.setTimeout(() => {\n      scrolling.value = false\n    }, 200)\n  })\n\n  async function onClick (hash: string) {\n    if (route.hash === hash) return\n\n    internalScrolling = true\n    await router.replace({ path: route.path, hash })\n    setTimeout(() => {\n      internalScrolling = false\n    }, 1000)\n  }\n\n  const sponsorStore = useSponsorsStore()\n\n  const sponsors = computed(() => (\n    sponsorStore.sponsors\n      .filter(sponsor => sponsor.metadata.tier <= 1)\n      .sort((a, b) => {\n        const aTier = a.metadata.tier\n        const bTier = b.metadata.tier\n\n        return aTier === bTier ? 0 : aTier > bTier ? 1 : -1\n      })\n  ))\n  const dark = computed(() => theme.current.value.dark)\n</script>\n\n<style lang=\"sass\" scoped>\n  @layer base\n    #app-toc\n      ul\n        list-style-type: none\n        margin: 0\n        padding: 0\n\n      li\n        border-left: 2px solid rgb(var(--v-theme-on-surface-variant))\n\n        &.router-link-active\n          border-left-color: currentColor\n\n      .v-toc-link\n        color: inherit\n\n      :deep(.v-navigation-drawer__content)\n        height: auto\n        margin-right: 12px\n</style>\n"
  },
  {
    "path": "packages/docs/src/components/app/TooltipBtn.vue",
    "content": "<template>\n  <span class=\"v-app-tooltip-btn d-inline-block\">\n    <v-btn\n      :aria-label=\"path\"\n      :variant=\"variant\"\n      v-bind=\"$attrs\"\n      icon\n    >\n      <slot\n        v-if=\"$slots.icon\"\n        name=\"icon\"\n      />\n\n      <v-icon\n        v-else\n        :icon=\"icon\"\n      />\n\n      <v-tooltip\n        v-if=\"path\"\n        activator=\"parent\"\n        class=\"v-app-tooltip-btn__content\"\n        location=\"bottom\"\n        open-delay=\"200\"\n      >\n        {{ t(path) }}\n      </v-tooltip>\n    </v-btn>\n\n    <slot />\n  </span>\n</template>\n\n<script setup lang=\"ts\">\n  // Types\n  import type { PropType } from 'vue'\n  import type { VBtn } from 'vuetify/components'\n\n  defineProps({\n    icon: String,\n    path: String,\n    variant: {\n      type: String as PropType<VBtn['$props']['variant']>,\n      default: 'text',\n    },\n  })\n\n  const { t } = useI18n()\n</script>\n\n<script lang=\"ts\">\n  export default {\n    inheritAttrs: false,\n  }\n</script>\n\n<style lang=\"sass\">\n  .v-app-tooltip-btn__content p\n    margin: 0\n</style>\n"
  },
  {
    "path": "packages/docs/src/components/app/V2Banner.vue",
    "content": "<template>\n  <v-system-bar\n    v-if=\"showBanner\"\n    color=\"#e7f0f6\"\n    height=\"52\"\n    theme=\"light\"\n  >\n    <div class=\"text-blue-darken-3 text-start ms-4\">\n      <div class=\"text-body-small\">\n        You are viewing the documentation for <strong>Vuetify 3</strong>\n      </div>\n    </div>\n\n    <v-spacer />\n\n    <v-btn\n      class=\"text-capitalize\"\n      color=\"primary\"\n      height=\"32\"\n      href=\"https://v2.vuetifyjs.com/\"\n      target=\"_blank\"\n      variant=\"flat\"\n    >\n      Go to Vuetify 2\n    </v-btn>\n\n    <v-btn\n      class=\"ms-4 ms-md-6 me-2\"\n      density=\"comfortable\"\n      icon=\"$clear\"\n      size=\"small\"\n      variant=\"plain\"\n      @click=\"onClose\"\n    />\n  </v-system-bar>\n</template>\n\n<script setup>\n  const user = useUserStore()\n\n  const showBanner = computed(() => !user.one.banners.last)\n\n  function onClose () {\n    user.one.banners.last = Date.now()\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/VersionBtn.vue",
    "content": "<template>\n  <v-btn\n    :text=\"version\"\n    :to=\"rpath(`/getting-started/release-notes/?version=v${version}`)\"\n    class=\"text-body-small\"\n    prepend-icon=\"mdi-tag-outline\"\n    size=\"small\"\n    variant=\"text\"\n    slim\n  />\n</template>\n\n<script lang=\"ts\" setup>\n  // Utilities\n  import { version } from 'vuetify'\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/VerticalDivider.vue",
    "content": "<template>\n  <v-divider\n    class=\"mx-2 my-auto\"\n    style=\"height: 16px;\"\n    inset\n    vertical\n  />\n</template>\n\n<script setup>\n  //\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/bar/Bar.vue",
    "content": "<template>\n  <VoAppBar\n    id=\"app-bar\"\n    border=\"b\"\n    logo=\"vuetify\"\n    flat\n  >\n    <template #prepend>\n      <div class=\"px-1\" />\n\n      <AppBtn\n        v-if=\"route.meta.layout !== 'home' && mdAndDown\"\n        icon=\"mdi-menu\"\n        @click=\"app.drawer = !app.drawer\"\n      />\n\n      <AppSearchSearch />\n    </template>\n\n    <template #append>\n      <div v-if=\"showExtraLinks\" class=\"d-flex ga-1 pe-2\">\n        <AppBarBlogLink />\n\n        <AppBarLearnMenu />\n\n        <AppBarSupportMenu />\n\n        <AppBarEcosystemMenu />\n\n        <AppBarPlaygroundLink v-if=\"showPlaygroundLink\" />\n\n        <AppBarOneLink class=\"ml-4\" />\n      </div>\n\n      <AppVerticalDivider v-if=\"showExtraLinks\" />\n\n      <div class=\"d-flex ga-1\">\n        <AppBarStoreLink v-if=\"smAndUp\" />\n\n        <AppBarGitHubLink v-if=\"smAndUp\" />\n\n        <AppBarLanguageMenu />\n\n        <AppBarSettingsToggle />\n      </div>\n    </template>\n  </VoAppBar>\n</template>\n\n<script setup>\n  const app = useAppStore()\n  const { smAndUp, mdAndDown, width } = useDisplay()\n  const route = useRoute()\n\n  const showExtraLinks = computed(() => width.value >= 1052)\n  const showPlaygroundLink = computed(() => width.value >= 1220)\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/bar/BlogLink.vue",
    "content": "<template>\n  <AppBtn\n    :to=\"rpath('/blog/')\"\n    color=\"medium-emphasis\"\n    text=\"blog\"\n    variant=\"text\"\n    @click=\"sweClick('app-bar', 'blog', name)\"\n  />\n</template>\n\n<script setup>\n  const { name } = useRoute()\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/bar/EcosystemMenu.vue",
    "content": "<template>\n  <AppBtn>\n    Ecosystem\n\n    <IconsChevronDown />\n\n    <AppMenuMenu\n      :items=\"items\"\n      activator=\"parent\"\n      width=\"200\"\n    />\n  </AppBtn>\n</template>\n\n<script setup>\n  const { t } = useI18n()\n  const items = computed(() => ([\n    { subheader: t('tools') },\n    {\n      title: 'vuetify-one',\n      to: rpath('/one/'),\n      appendIcon: '$vuetify-outline',\n    },\n    {\n      title: 'vuetify-play',\n      href: 'https://play.vuetifyjs.com/',\n      appendIcon: '$vuetify-play',\n    },\n    {\n      title: 'vuetify-bin',\n      href: 'https://bin.vuetifyjs.com/',\n      appendIcon: '$vuetify-bin',\n    },\n    {\n      title: 'vuetify-create',\n      href: 'https://github.com/vuetifyjs/create/',\n      appendIcon: '$vuetify-create',\n    },\n    {\n      title: 'vuetify-link',\n      href: 'https://link.vuetifyjs.com/',\n      appendIcon: '$vuetify-link',\n    },\n    {\n      title: 'vuetify-studio',\n      href: 'https://studio.vuetifyjs.com/',\n      appendIcon: '$vuetify-studio',\n    },\n    {\n      title: 'vuetify-snips',\n      href: 'https://snips.vuetifyjs.com/',\n      appendIcon: '$vuetify-snips',\n    },\n    {\n      title: 'vuetify-mcp',\n      href: 'https://mcp.vuetifyjs.com/',\n      appendIcon: '$vuetify-mcp',\n    },\n    {\n      title: 'vuetify-store',\n      href: 'https://store.vuetifyjs.com/',\n      appendIcon: '$vuetify-store',\n    },\n    {\n      title: 'vuetify-figma',\n      href: 'https://store.vuetifyjs.com/products/vuetify-ui-kit-figma',\n      appendIcon: '$vuetify-figma',\n    },\n    { divider: true },\n    { subheader: t('social') },\n    {\n      title: 'Blog',\n      to: rpath('/blog'),\n      appendIcon: 'mdi-post-outline',\n    },\n    {\n      title: 'X',\n      href: 'https://x.com/vuetifyjs',\n      appendIcon: '$x',\n    },\n    {\n      title: 'bluesky',\n      href: 'https://bsky.app/profile/vuetify.bsky.social',\n      appendIcon: 'mdi-bluesky',\n    },\n    {\n      title: 'Discord',\n      href: 'https://community.vuetifyjs.com/',\n      appendIcon: '$discord',\n    },\n    {\n      title: 'github',\n      href: 'https://github.com/vuetifyjs/vuetify',\n      appendIcon: 'mdi-github',\n    },\n    {\n      title: 'reddit',\n      href: 'https://reddit.com/r/vuetifyjs',\n      appendIcon: 'mdi-reddit',\n    },\n  ]))\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/bar/EnterpriseLink.vue",
    "content": "<template>\n  <AppBtn\n    :to=\"rpath('/introduction/enterprise-support/')\"\n    color=\"primary\"\n    text=\"support\"\n    variant=\"outlined\"\n    @click=\"onClick\"\n  />\n</template>\n\n<script setup>\n  const { name } = useRoute()\n\n  function onClick () {\n    sweClick('app-bar', 'enterprise', name)\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/bar/GitHubLink.vue",
    "content": "<template>\n  <AppBtn\n    color=\"medium-emphasis\"\n    href=\"https://github.com/vuetifyjs/vuetify\"\n    icon=\"mdi-github\"\n    rel=\"noopener\"\n    target=\"_blank\"\n    v-tooltip:bottom=\"t('github')\"\n    @click=\"sweClick('app-bar', 'github', name)\"\n  />\n</template>\n\n<script setup>\n  const { name } = useRoute()\n  const { t } = useI18n()\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/bar/JobsLink.vue",
    "content": "<template>\n  <v-badge\n    :model-value=\"newJobs.length > 0\"\n    color=\"#ED561B\"\n    location=\"top end\"\n    dot\n  >\n    <AppBtn\n      :icon=\"icon\"\n      :to=\"rpath('/resources/jobs-for-vue/')\"\n      class=\"jobs-link\"\n      @click=\"sweClick('app-bar', 'jobs', name)\"\n    />\n  </v-badge>\n</template>\n\n<script setup>\n  const { currentRoute } = useRouter()\n  const { name } = useRoute()\n  const newJobs = []\n\n  const icon = computed(() => {\n    return currentRoute.value.path.match('resources/jobs-for-vue')\n      ? 'mdi-briefcase-variant'\n      : 'mdi-briefcase-variant-outline'\n  })\n</script>\n\n<style lang=\"sass\">\n  .jobs-link .v-btn:not(:hover)::before\n    display: none\n</style>\n"
  },
  {
    "path": "packages/docs/src/components/app/bar/LanguageMenu.vue",
    "content": "<template>\n  <AppMenuMenu\n    key=\"language-menu\"\n    :items=\"items\"\n    :open-on-hover=\"false\"\n  >\n    <template #activator=\"{ props }\">\n      <AppBtn\n        color=\"medium-emphasis\"\n        icon=\"mdi-translate\"\n        v-bind=\"props\"\n        v-tooltip:bottom=\"t('languages')\"\n      />\n    </template>\n  </AppMenuMenu>\n</template>\n\n<script setup lang=\"ts\">\n  // Language\n  import locales from '@/i18n/locales.json'\n\n  const { t } = useI18n()\n  const route = useRoute()\n\n  const items = computed(() => ([\n    { subheader: t('translations') },\n    ...locales.filter(locale => locale.enabled).map(locale => {\n      return {\n        title: locale.title,\n        to: route.fullPath.replace(/^\\/[a-zA-Z-]+/, `/${locale.alternate || locale.locale}`),\n      }\n    }),\n    { title: t('help-translate'), href: 'https://crowdin.com/project/vuetify' },\n    { title: t('more-coming-soon'), disabled: true },\n  ]))\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/bar/LearnMenu.vue",
    "content": "<template>\n  <AppBtn>\n    {{ title }}\n\n    <IconsChevronDown />\n\n    <AppMenuMenu\n      :items=\"items\"\n      activator=\"parent\"\n      width=\"200\"\n    />\n  </AppBtn>\n</template>\n\n<script setup lang=\"ts\">\n  const { t } = useI18n()\n  const title = t('learn')\n  const items = computed(() => ([\n    { subheader: t('overview') },\n    {\n      title: t('api-explorer'),\n      to: rpath('/components/explorer/'),\n      appendIcon: 'mdi-code-json',\n    },\n    {\n      title: t('colors'),\n      to: rpath('/styles/colors/#material-colors'),\n      appendIcon: 'mdi-palette-swatch-outline',\n    },\n    {\n      title: t('components'),\n      to: rpath('/components/all/'),\n      appendIcon: 'mdi-view-dashboard-outline',\n    },\n    {\n      title: t('feature-guides'),\n      to: rpath('/introduction/why-vuetify/#feature-guides'),\n      appendIcon: 'mdi-lightbulb-on-outline',\n    },\n    {\n      title: t('icons'),\n      to: rpath('/features/icon-fonts/#mdi-icon-search'),\n      appendIcon: 'mdi-emoticon-outline',\n    },\n    {\n      title: t('labs'),\n      to: rpath('/labs/introduction/'),\n      appendIcon: 'mdi-beaker-outline',\n    },\n    {\n      title: t('licensing'),\n      to: rpath('/about/licensing/'),\n      appendIcon: 'mdi-file-document-outline',\n    },\n    {\n      title: t('roadmap'),\n      to: rpath('/introduction/roadmap/'),\n      appendIcon: 'mdi-compass-outline',\n    },\n    {\n      title: t('sass-variables'),\n      to: rpath('/features/sass-variables/#variable-api'),\n      appendIcon: 'mdi-sass',\n    },\n    {\n      title: t('unit-testing'),\n      to: rpath('/getting-started/unit-testing/'),\n      appendIcon: 'mdi-list-status',\n    },\n    { divider: true },\n    { subheader: t('documentation') },\n    {\n      title: 'Vuetify0',\n      href: 'https://0.vuetifyjs.com/',\n      appendIcon: 'mdi-numeric-0-box',\n    },\n    {\n      title: '4.x (latest)',\n      href: 'https://vuetifyjs.com/',\n      appendIcon: 'mdi-numeric-4-box',\n    },\n    {\n      title: '3.x (stable)',\n      href: 'https://v3.vuetifyjs.com/',\n      appendIcon: 'mdi-numeric-3-box',\n    },\n    {\n      title: '2.6.x (v2-stable)',\n      href: 'https://v2.vuetifyjs.com/',\n      appendIcon: 'mdi-numeric-2-box',\n    },\n    {\n      title: '1.5.x (v1-stable)',\n      href: 'https://v15.vuetifyjs.com/',\n      appendIcon: 'mdi-numeric-1-box',\n    },\n  ]))\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/bar/Logo.vue",
    "content": "<template>\n  <router-link\n    :to=\"rpath(locale.value)\"\n    class=\"d-inline-block ms-4 me-2\"\n  >\n    <v-img\n      :key=\"logo\"\n      :alt=\"`Vuetify ${t('logo')}`\"\n      :src=\"`https://cdn.vuetifyjs.com/docs/images/logos/${logo}`\"\n      :transition=\"false\"\n      :width=\"lgAndUp ? 148 : 34\"\n      class=\"shrink\"\n    />\n  </router-link>\n</template>\n\n<script setup>\n  defineProps({\n    alt: Boolean,\n  })\n\n  const { lgAndUp } = useDisplay()\n  const { locale, t } = useI18n()\n  const theme = useTheme()\n\n  const logo = computed(() => {\n    const file = `${theme.current.value.dark ? 'dark' : 'light'}.svg`\n    const logo = 'vuetify-logo-v3-slim'\n\n    return `${logo}-${lgAndUp.value ? 'text-' : ''}${file}`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/bar/NotificationsMenu.vue",
    "content": "<template>\n  <AppMenuMenu\n    v-if=\"user.one.notifications.enabled\"\n    v-model=\"menu\"\n    :close-on-content-click=\"false\"\n    :open-on-hover=\"false\"\n    :width=\"width\"\n  >\n    <template #activator=\"{ props }\">\n      <AppTooltipBtn v-bind=\"props\">\n        <template #icon>\n          <v-badge\n            :model-value=\"unread.length > 0\"\n            color=\"#ED561B\"\n            location=\"top end\"\n            dot\n          >\n            <v-icon\n              :icon=\"icon\"\n              class=\"mx-1\"\n              color=\"medium-emphasis\"\n            />\n          </v-badge>\n        </template>\n      </AppTooltipBtn>\n    </template>\n\n    <v-toolbar\n      class=\"ps-4 pe-6\"\n      color=\"surface\"\n      density=\"compact\"\n    >\n      <v-btn\n        class=\"px-2 ms-n1 text-none font-weight-regular\"\n        size=\"small\"\n        variant=\"text\"\n        @click=\"showArchived = !showArchived\"\n      >\n        {{ showArchived ? t('unread', { number: unread.length }) : t('read', { number: read.length }) }}\n      </v-btn>\n    </v-toolbar>\n\n    <v-divider />\n\n    <v-responsive\n      max-height=\"340\"\n      min-height=\"204\"\n      style=\"overflow-y: scroll;\"\n    >\n      <div\n        v-if=\"done\"\n        class=\"py-8 text-center text-body-large\"\n      >\n        <p>{{ t('done') }}</p>\n\n        <v-icon color=\"#D7D7D7\" icon=\"$vuetify\" size=\"96\" />\n      </div>\n\n      <template v-else>\n        <v-list lines=\"three\">\n          <template\n            v-for=\"(notification, i) in notifications\"\n            :key=\"notification.slug\"\n          >\n            <v-divider\n              v-if=\"i !== 0\"\n              class=\"my-1\"\n            />\n\n            <v-list-item\n              :ripple=\"false\"\n              class=\"py-2\"\n            >\n              <template #prepend>\n                <div class=\"pe-4 align-self-start\">{{ notification.metadata.emoji }}</div>\n              </template>\n\n              <v-list-item-title class=\"text-wrap text-title-large\">\n                <div class=\" text-truncate\">{{ notification.title }}</div>\n              </v-list-item-title>\n\n              <div class=\"text-body-small mb-1 font-weight-bold text-medium-emphasis\">{{ format(notification.created_at) }}</div>\n\n              <div class=\"text-medium-emphasis text-body-small\">\n                <AppMarkdown :content=\"notification.metadata.text\" class=\"mb-n3\" />\n\n                <border-chip\n                  :href=\"notification.metadata.action\"\n                  :text=\"notification.metadata.action_text\"\n                  append-icon=\"mdi-open-in-new\"\n                  @click=\"onClick(notification)\"\n                />\n              </div>\n\n              <template v-if=\"!showArchived\" #append>\n                <div class=\"ps-4\">\n                  <v-icon\n                    color=\"medium-emphasis\"\n                    icon=\"mdi-check\"\n                    @click.stop.prevent=\"toggle(notification)\"\n                  />\n                </div>\n              </template>\n            </v-list-item>\n          </template>\n        </v-list>\n      </template>\n    </v-responsive>\n  </AppMenuMenu>\n</template>\n\n<script setup lang=\"ts\">\n  // Types\n  interface Notification {\n    metadata: {\n      action: string\n      action_text: string\n      emoji: string\n      text: string\n    }\n    // eslint-disable-next-line camelcase\n    created_at: string\n    slug: string\n    title: string\n  }\n\n  const { t } = useI18n()\n  const { bucket } = useCosmic()\n  const { mobile } = useDisplay()\n  const date = useDate()\n  const user = useUserStore()\n\n  const menu = shallowRef(false)\n  const all = ref<Notification[]>([])\n  const showArchived = shallowRef(false)\n\n  const unread = computed(() => all.value.filter(({ slug }) => !user.one.notifications.read.includes(slug)))\n  const read = computed(() => all.value.filter(({ slug }) => user.one.notifications.read.includes(slug)))\n  const notifications = computed(() => showArchived.value ? read.value : unread.value)\n  const done = computed(() => {\n    return (\n      showArchived.value && read.value.length < 1\n    ) || (\n      !showArchived.value && unread.value.length < 1\n    )\n  })\n\n  const icon = computed(() => {\n    if (menu.value && unread.value.length > 0) return 'mdi-bell-ring'\n    else if (menu.value) return 'mdi-bell'\n    else if (unread.value.length > 0) return 'mdi-bell-ring-outline'\n    else return 'mdi-bell-outline'\n  })\n\n  const width = computed(() => mobile.value ? 420 : 520)\n\n  function format (str: string) {\n    return date.format(new Date(str), 'fullDateWithWeekday')\n  }\n  function onClick (notification: Notification) {\n    toggle(notification)\n    menu.value = false\n    sweClick('notification', notification.slug, notification.metadata.action)\n  }\n  function toggle ({ slug }: Notification) {\n    user.one.notifications.read = user.one.notifications.read.includes(slug)\n      ? user.one.notifications.read.filter((n: any) => n !== slug)\n      : [...user.one.notifications.read, slug]\n  }\n\n  onMounted(async () => {\n    if (all.value.length) return\n\n    const { objects = [] }: { objects: Notification[] } = (\n      await bucket?.objects\n        .find({ type: 'notifications' })\n        .props('metadata,created_at,slug,title')\n        .status('published')\n        .sort('-created_at')\n        .limit(10)\n    ) || {}\n\n    all.value = objects\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/bar/OneLink.vue",
    "content": "<template>\n  <AppBtn\n    :to=\"rpath('/one/')\"\n    color=\"primary\"\n    rounded=\"lg\"\n    text=\"one\"\n    variant=\"outlined\"\n    @click=\"sweClick('app-bar', 'one', name)\"\n  />\n</template>\n\n<script setup>\n  const { name } = useRoute()\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/bar/PlaygroundLink.vue",
    "content": "<template>\n  <AppBtn\n    color=\"medium-emphasis\"\n    href=\"https://play.vuetifyjs.com\"\n    rel=\"noopener noreferrer\"\n    target=\"_blank\"\n    text=\"playground\"\n    variant=\"text\"\n    @click=\"sweClick('app-bar', 'playground', name)\"\n  />\n</template>\n\n<script setup>\n  const { name } = useRoute()\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/bar/SettingsToggle.vue",
    "content": "<template>\n  <v-progress-circular\n    v-if=\"pwa.availableOffline && pwa.isUpdating\"\n    :model-value=\"pwa.progress / pwa.progressTotal * 100\"\n    color=\"primary\"\n    size=\"42\"\n    width=\"1\"\n  >\n    <AppBtn\n      id=\"settings-toggle\"\n      :icon=\"app.settings ? 'mdi-cog' : 'mdi-cog-outline'\"\n      color=\"medium-emphasis\"\n      @click=\"onClick\"\n    />\n  </v-progress-circular>\n  <AppBtn\n    v-else\n    id=\"settings-toggle\"\n    :icon=\"app.settings ? 'mdi-cog' : 'mdi-cog-outline'\"\n    class=\"me-n2\"\n    color=\"medium-emphasis\"\n    v-tooltip:bottom=\"t('settings.header')\"\n    @click=\"onClick\"\n  />\n</template>\n\n<script setup>\n  const app = useAppStore()\n  const pwa = usePwaStore()\n  const { name } = useRoute()\n  const { t } = useI18n()\n\n  function onClick () {\n    sweClick('app-bar', 'settings-toggle', name)\n\n    app.settings = !app.settings\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/bar/SponsorLink.vue",
    "content": "<template>\n  <AppBtn\n    :to=\"rpath('/introduction/sponsors-and-backers/')\"\n    color=\"medium-emphasis\"\n    text=\"sponsor\"\n    variant=\"text\"\n    @click=\"sweClick('app-bar', 'sponsor', name)\"\n  />\n</template>\n\n<script setup>\n  const { name } = useRoute()\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/bar/StoreLink.vue",
    "content": "<template>\n  <AppBtn\n    color=\"medium-emphasis\"\n    href=\"https://store.vuetifyjs.com/?utm_source=vuetifyjs.com&utm_medium=toolbar\"\n    icon=\"$vuetify-store\"\n    rel=\"noopener\"\n    target=\"_blank\"\n    v-tooltip:bottom=\"t('vuetify-store')\"\n    @click=\"sweClick('app-bar', 'store', name)\"\n  />\n</template>\n\n<script setup>\n  const { name } = useRoute()\n  const { t } = useI18n()\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/bar/SupportLink.vue",
    "content": "<template>\n  <AppBtn\n    :to=\"rpath('/introduction/sponsors-and-backers/')\"\n    class=\"ms-1\"\n    color=\"primary\"\n    text=\"sponsor\"\n    @click=\"onClick\"\n  />\n</template>\n\n<script setup>\n  const { name } = useRoute()\n\n  function onClick () {\n    sweClick('app-bar', 'enterprise', name)\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/bar/SupportMenu.vue",
    "content": "<template>\n  <AppBtn\n    color=\"medium-emphasis\"\n  >\n    {{ title }}\n\n    <IconsChevronDown />\n\n    <AppMenuMenu\n      :items=\"items\"\n      activator=\"parent\"\n      width=\"220\"\n    />\n  </AppBtn>\n</template>\n\n<script setup>\n  const { t } = useI18n()\n  const title = t('support')\n  const items = computed(() => ([\n    { subheader: t('help-and-support') },\n    {\n      title: 'for-enterprise',\n      to: rpath('/introduction/enterprise-support/'),\n      appendIcon: 'mdi-shield-star-outline',\n    },\n    {\n      title: 'file-a-bug-report',\n      href: 'https://issues.vuetifyjs.com/',\n      appendIcon: '$vuetify-issues',\n    },\n    {\n      title: 'faq',\n      to: rpath('/getting-started/frequently-asked-questions/'),\n      appendIcon: 'mdi-head-question-outline',\n    },\n    {\n      title: 'upgrade-guide',\n      to: rpath('/getting-started/upgrade-guide/'),\n      appendIcon: 'mdi-update',\n    },\n    {\n      title: 'github-discussions',\n      href: 'https://github.com/vuetifyjs/vuetify/discussions',\n      appendIcon: 'mdi-message-text-outline',\n    },\n    {\n      title: 'stack-overflow',\n      href: 'https://stackoverflow.com/search?q=vuetify',\n      appendIcon: 'mdi-layers-outline',\n    },\n    { divider: true },\n    { subheader: t('resources') },\n    {\n      title: 'awesome',\n      href: 'https://github.com/vuetifyjs/awesome-vuetify',\n      appendIcon: 'mdi-creation-outline',\n    },\n    {\n      title: 'brand-kit',\n      to: rpath('/resources/brand-kit/'),\n      appendIcon: 'mdi-image-outline',\n    },\n    {\n      title: 'jobs',\n      to: rpath('/resources/jobs-for-vue/'),\n      appendIcon: 'mdi-briefcase-variant-outline',\n    },\n    {\n      title: 'github-issues',\n      href: 'https://github.com/vuetifyjs/vuetify/issues/',\n      appendIcon: 'mdi-alert-circle-outline',\n    },\n    {\n      title: 'documentation-status',\n      href: 'https://status.vuetifyjs.com/',\n      appendIcon: 'mdi-cloud-outline',\n    },\n    {\n      title: 'latest-releases',\n      href: 'https://github.com/vuetifyjs/vuetify/releases',\n      appendIcon: 'mdi-package-variant',\n    },\n  ]))\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/bar/TeamLink.vue",
    "content": "<template>\n  <AppBtn\n    :to=\"rpath('/about/meet-the-team/')\"\n    color=\"medium-emphasis\"\n    text=\"team\"\n    variant=\"text\"\n    @click=\"sweClick('app-bar', 'team', name)\"\n  />\n</template>\n\n<script setup>\n  const { name } = useRoute()\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/bar/ThemeToggle.vue",
    "content": "<template>\n  <AppBtn\n    v-if=\"!hasToggle\"\n    :icon=\"icon\"\n    color=\"medium-emphasis\"\n    path=\"theme\"\n    @click=\"onClick\"\n  />\n</template>\n\n<script setup>\n  const theme = useTheme()\n  const user = useUserStore()\n  const { name } = useRoute()\n\n  const icon = computed(() => theme.global.name.value === 'dark'\n    ? 'mdi-weather-night'\n    : 'mdi-weather-sunny'\n  )\n  const hasToggle = computed(() => !['dark', 'light'].includes(theme.name.value))\n\n  function onClick () {\n    sweClick('app-bar', 'theme-toggle', name)\n    user.one.theme = theme.global.name.value === 'dark' ? 'light' : 'dark'\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/drawer/Append.vue",
    "content": "<template>\n  <v-divider />\n\n  <div class=\"d-flex align-center text-body-small text-medium-emphasis pa-2\">\n    <AppDrawerDrawerToggleRail v-if=\"one.isSubscriber\" class=\"me-2\" />\n\n    <div class=\"d-flex ms-auto overflow-hidden\">\n      <AppCommitBtn class=\"me-2\" />\n\n      <AppVersionBtn />\n    </div>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\n  const one = useOneStore()\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/drawer/Drawer.vue",
    "content": "<template>\n  <v-navigation-drawer\n    id=\"app-drawer\"\n    v-model=\"app.drawer\"\n    :expand-on-hover=\"railEnabled\"\n    :image=\"settings.suit['drawer']\"\n    :order=\"mobile ? -1 : undefined\"\n    :rail=\"railEnabled\"\n    width=\"300\"\n    @update:rail=\"onUpdateRail\"\n  >\n    <AppDrawerPinnedItems :rail=\"rail\" />\n\n    <AppListList\n      v-model:opened=\"opened\"\n      :items=\"app.items\"\n      nav\n    >\n      <template #divider>\n        <v-divider class=\"my-3 mb-4 ms-10\" />\n      </template>\n    </AppListList>\n\n    <template #append>\n      <AppDrawerAppend />\n    </template>\n  </v-navigation-drawer>\n</template>\n\n<script setup>\n  // Composables\n  import { scrollTo } from 'vuetify/lib/composables/goto'\n\n  const app = useAppStore()\n  const pins = usePinsStore()\n  const settings = useSettingsStore()\n  const user = useUserStore()\n\n  const { mobile } = useDisplay()\n\n  const rail = shallowRef(user.ecosystem.docs.railDrawer)\n  const _opened = shallowRef([])\n  const opened = computed({\n    get: () => rail.value ? [] : _opened.value,\n    set: val => {\n      if (pins.isPinning) return\n\n      _opened.value = val\n    },\n  })\n  const railEnabled = computed(() => user.ecosystem.docs.railDrawer)\n\n  // Restore scroll position when drawer is expanded\n  let scrollingElement\n  let lastScroll = 0\n  watch(rail, val => {\n    if (val) {\n      lastScroll = scrollingElement.scrollTop\n    } else {\n      scrollTo(lastScroll, {\n        container: scrollingElement,\n      })\n    }\n  })\n\n  watch(railEnabled, val => {\n    rail.value = val\n  })\n\n  onMounted(async () => {\n    scrollingElement = document.querySelector('#app-drawer .v-navigation-drawer__content')\n\n    if (pins.pageIsPinned) {\n      _opened.value = []\n\n      return\n    }\n\n    await wait(1000)\n\n    const element = document.querySelector('#app-drawer .v-list-item--active:not(.v-list-group__header)')\n\n    if (!element) return\n\n    element.scrollIntoView({\n      block: 'center',\n      inline: 'center',\n    })\n  })\n\n  function onUpdateRail (val) {\n    if (railEnabled.value) {\n      rail.value = val\n    }\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/drawer/DrawerToggleRail.vue",
    "content": "<template>\n  <v-btn\n    :icon=\"icon\"\n    height=\"28\"\n    size=\"small\"\n    variant=\"text\"\n    rounded\n    @click=\"onClick\"\n  />\n</template>\n\n<script setup>\n  const user = useUserStore()\n\n  const icon = computed(() => {\n    return user.ecosystem.docs.railDrawer ? 'mdi-chevron-double-right' : 'mdi-chevron-double-left'\n  })\n\n  function onClick () {\n    user.ecosystem.docs.railDrawer = !user.ecosystem.docs.railDrawer\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/drawer/PinnedItems.vue",
    "content": "<template>\n  <AppListList\n    v-if=\"one.isSubscriber && user.ecosystem.docs.pins.enabled\"\n    v-model:opened=\"opened\"\n    :items=\"pinned\"\n    class=\"pb-0 mb-n1\"\n    nav\n  >\n    <template #item=\"{ props: itemProps }\">\n      <v-hover v-slot=\"{ props: activatorProps, isHovering }\">\n        <v-list-item\n          :title=\"itemProps.title\"\n          :to=\"itemProps.to\"\n          v-bind=\"activatorProps\"\n          @click.prevent=\"onClickPin(itemProps.to)\"\n        >\n          <template #append>\n            <v-icon\n              v-if=\"isHovering\"\n              class=\"me-1\"\n              icon=\"mdi-pin-off\"\n              size=\"16\"\n              @click.prevent.stop=\"onClickPinRemove({\n                title: itemProps.title,\n                to: itemProps.to,\n                category: '',\n              })\"\n            />\n          </template>\n        </v-list-item>\n      </v-hover>\n    </template>\n  </AppListList>\n</template>\n\n<script lang=\"ts\" setup>\n  import { Pin } from '@/stores/pins'\n\n  const props = defineProps<{ rail: boolean }>()\n\n  const one = useOneStore()\n  const pins = usePinsStore()\n  const user = useUserStore()\n  const router = useRouter()\n\n  const _opened = ref<string[]>([])\n  const opened = computed({\n    get: () => props.rail ? [] : _opened.value,\n    set: val => _opened.value = val,\n  })\n  const pinned = computed(() => ([{\n    activeIcon: 'mdi-pin',\n    inactiveIcon: 'mdi-pin-outline',\n    items: [...pins.pins],\n    title: 'Pinned',\n  }]))\n\n  async function onClickPin (to: string) {\n    pins.isPinning = true\n\n    await router.replace(to)\n\n    pins.isPinning = false\n  }\n\n  function onClickPinRemove (pin: Pin) {\n    pins.toggle(false, pin)\n  }\n\n  onBeforeMount(() => {\n    pins.load()\n  })\n\n  watch(() => pins.pins, (val, oldVal) => {\n    if (val.length < oldVal.length) return\n\n    opened.value = ['Pinned']\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/list/LinkListItem.vue",
    "content": "<template>\n  <div\n    :class=\"[\n      'text-medium-emphasis text-body-small py-2 px-3 d-flex align-center',\n      $attrs.class,\n    ]\"\n  >\n    <div class=\"d-inline-flex align-center\">\n      <v-icon v-if=\"prependIcon\" :icon=\"prependIcon\" start />\n\n      {{ label }}\n    </div>\n\n    <v-btn\n      v-bind=\"$attrs\"\n      class=\"text-none px-2 ms-auto\"\n      density=\"compact\"\n      variant=\"text\"\n    >\n      {{ title }}\n\n      <v-icon v-if=\"appendIcon\" :icon=\"appendIcon\" size=\"xs\" end />\n\n      <template #loader>\n        <slot name=\"loader\" />\n      </template>\n    </v-btn>\n  </div>\n</template>\n\n<script setup>\n  defineProps({\n    label: String,\n    title: String,\n    prependIcon: String,\n    appendIcon: String,\n  })\n</script>\n\n<script>\n  export default {\n    inheritAttrs: false,\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/list/List.vue",
    "content": "<template>\n  <v-list\n    v-model:opened=\"opened\"\n    :items=\"computedItems\"\n    :lines=\"false\"\n    :nav=\"nav\"\n    color=\"primary\"\n    density=\"compact\"\n    item-props\n    slim\n  >\n    <template v-if=\"$slots.item\" #item=\"itemProps\">\n      <slot name=\"item\" v-bind=\"itemProps\" />\n    </template>\n\n    <template #header=\"{ props: itemProps }\">\n      <v-list-item v-bind=\"itemProps\">\n        <template #title>\n          {{ itemProps.title }}\n\n          <v-badge\n            v-if=\"itemProps.emphasized\"\n            class=\"ms-n1\"\n            color=\"success\"\n            dot\n            inline\n          />\n        </template>\n      </v-list-item>\n    </template>\n\n    <template #divider>\n      <slot name=\"divider\" />\n\n      <v-divider\n        v-if=\"!$slots.divider\"\n        class=\"my-3 mb-4 ms-2 me-n2\"\n      />\n    </template>\n\n    <template #title=\"{ item }\">\n      {{ item.title }}\n\n      <v-badge\n        v-if=\"item.emphasized\"\n        class=\"ms-n1\"\n        color=\"success\"\n        dot\n        inline\n      />\n    </template>\n\n    <template #subtitle=\"{ item }\">\n      <span v-if=\"item.subtitle\" class=\"text-high-emphasis\">\n        {{ item.subtitle }}\n      </span>\n    </template>\n\n    <template #subheader=\"{ props: subheaderProps }\">\n      <slot\n        name=\"subheader\"\n        v-bind=\"{ subheaderProps }\"\n      />\n\n      <v-list-subheader\n        v-if=\"!$slots.subheader\"\n        class=\"text-high-emphasis text-uppercase font-weight-black\"\n      >\n        {{ subheaderProps.title }}\n      </v-list-subheader>\n    </template>\n  </v-list>\n</template>\n\n<script setup lang=\"ts\">\n  // Types\n  import type { RouteLocationRaw } from 'vue-router'\n  import type { Prop } from 'vue'\n  import apiList from 'virtual:api-list'\n\n  export type Item = {\n    title?: string\n    subtitle?: string\n    appendIcon?: string\n    activeIcon?: string\n    inactiveIcon?: string\n    items?: (string | Item)[]\n    subheader?: string\n    divider?: boolean\n    to?: RouteLocationRaw\n    href?: string\n    subfolder?: string\n    disabled?: boolean\n    routeMatch?: string\n    routePath?: string\n    emphasized?: boolean\n    onClick?: () => void\n  }\n\n  function generateApiItems (locale: string) {\n    return apiList.map(name => {\n      const path = kebabCase(name.startsWith('v-') ? name + '-directive' : name)\n      return {\n        title: name,\n        to: `/${locale}/api/${path}`,\n      }\n    })\n  }\n\n  function generateListItem (item: string | Item, path = '', locale = 'en', t = (key: string) => key): any {\n    const isString = typeof item === 'string'\n    const isLink = !isString && (item.to || item.href)\n    const isParent = !isString && item.items\n    const isType = !isString && (item.divider || item.subheader)\n\n    if (isString || (!isLink && !isParent && !isType)) {\n      const litem = isString ? { title: item } : item\n\n      if (litem.subfolder) path = litem.subfolder\n\n      const route = litem.routeMatch\n        ? generatedRoutes.find((route: { path: string }) => route.path.endsWith(`/${locale}/${path}/${litem.routeMatch}/`))\n        : generatedRoutes.find((route: { path: string }) => route.path.endsWith(`/${locale}/${path}/${litem.title}/`))\n\n      const to = litem.routePath\n        ? `/${locale}/${path}/${litem.routePath}/`\n        : route?.path\n\n      return {\n        title: route?.meta?.nav ?? route?.meta?.title ?? litem.title,\n        subtitle: litem.subtitle && te(litem.subtitle) ? t(litem.subtitle) : litem.subtitle,\n        emphasized: route?.meta?.emphasized ?? false,\n        to,\n        disabled: !route,\n      }\n    } else if (item.divider) {\n      return {\n        type: 'divider',\n      }\n    } else if (item.subheader) {\n      return {\n        title: t(item.subheader!),\n        type: 'subheader',\n      }\n    } else if (item.items) {\n      const p = item.subfolder ? `${item.subfolder}/${item.title}` : path\n      return {\n        title: t(item.title!),\n        emphasized: item.emphasized,\n        children: item.items.map(item => generateListItem(item, p, locale, t)),\n      }\n    }\n\n    return item\n  }\n\n  function generateListItems (item: Item, path: string, locale: string, t: (key: string) => string): any {\n    if (!item.items) return undefined\n\n    return item.items.map(child => generateListItem(child, path, locale, t))\n  }\n\n  const props = defineProps({\n    items: {\n      type: Array,\n      default: () => ([]),\n    } as Prop<Item[]>,\n    nav: Boolean,\n  })\n\n  const { t, te, locale } = useI18n()\n  const opened = ref<string[]>([])\n\n  const computedItems = computed(() => props.items?.map(item => {\n    if (item.divider || item.subheader) return generateListItem(item)\n\n    const title = item.title && te(item.title) ? t(item.title) : item.title\n\n    return {\n      ...generateListItem({\n        title,\n        to: item?.to,\n        href: item?.href,\n      }),\n      onClick: item?.onClick,\n      rel: item.href ? 'noopener noreferrer' : undefined,\n      target: item.href ? '_blank' : undefined,\n      children: item.title === 'api'\n        ? generateApiItems(locale.value)\n        : generateListItems(item, item.title!, locale.value, t),\n      prependIcon: opened.value.includes(title ?? '') ? item.activeIcon : item.inactiveIcon,\n      value: title,\n      appendIcon: item.appendIcon,\n      disabled: item.disabled,\n      emphasized: item.emphasized,\n    }\n  }))\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/menu/Menu.vue",
    "content": "<template>\n  <v-menu\n    close-delay=\"100\"\n    location=\"bottom end\"\n    open-delay=\"60\"\n    open-on-hover\n  >\n    <template #activator=\"{ props }\">\n      <slot name=\"activator\" v-bind=\"{ props }\" />\n    </template>\n\n    <AppSheet>\n      <slot v-if=\"$slots.default\" />\n\n      <AppListList v-else :items=\"items\" nav />\n    </AppSheet>\n  </v-menu>\n</template>\n\n<script setup lang=\"ts\">\n  // Components\n  import type { Item } from '@/components/app/list/List.vue'\n  import type { PropType } from 'vue'\n\n  defineProps({\n    items: {\n      type: Array as PropType<Item[]>,\n      default: () => ([]),\n    },\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/search/Search.vue",
    "content": "<template>\n  <AppBtn\n    :active=\"model\"\n    :icon=\"xs ? 'mdi-magnify' : undefined\"\n    :loading=\"loading ? 'primary' : undefined\"\n    :prepend-icon=\"smAndUp ? 'mdi-magnify' : undefined\"\n    @click=\"shouldLoad = true\"\n  >\n    <span :class=\"mdAndUp && 'me-n1'\">\n      <span v-if=\"lgAndUp\">\n        {{ t('search.label') }}\n      </span>\n\n      <span\n        :class=\"[\n          smAndDown ? 'border-opacity-0' : 'py-1 px-2 ms-2',\n          'border rounded text-disabled text-body-small'\n        ]\"\n      >\n        <span v-if=\"mdAndUp\">\n          {{ t(`search.key-hint${user.ecosystem.docs.slashSearch ? '-slash' : platform.mac ? '-mac' : ''}`) }}\n        </span>\n      </span>\n    </span>\n\n    <SearchDialog\n      v-if=\"shouldLoad\"\n      v-model=\"model\"\n      v-model:search=\"searchString\"\n      @vue:mounted=\"onMount\"\n    />\n  </AppBtn>\n</template>\n\n<script setup lang=\"ts\">\n  import { defineAsyncComponent } from 'vue'\n\n  const SearchDialog = defineAsyncComponent(() => import('@/components/app/search/SearchDialog.vue'))\n\n  const { t } = useI18n()\n  const { smAndUp, smAndDown, mdAndUp, lgAndUp, xs, platform } = useDisplay()\n  const { query } = useRoute()\n  const user = useUserStore()\n\n  const shouldLoad = shallowRef(false)\n  const loading = shallowRef(false)\n  const model = shallowRef(false)\n  const searchString = shallowRef('')\n\n  watch(shouldLoad, () => {\n    loading.value = true\n    model.value = true\n  })\n\n  onMounted(() => {\n    document.addEventListener('keydown', onDocumentKeydown)\n    if (query?.search) {\n      searchString.value = query.search as string\n      shouldLoad.value = true\n    }\n  })\n  onBeforeUnmount(() => {\n    document.removeEventListener('keydown', onDocumentKeydown)\n  })\n  onBeforeRouteLeave(() => {\n    model.value = false\n  })\n\n  function onDocumentKeydown (e: KeyboardEvent) {\n    const modifierKey = platform.value.mac ? e.metaKey : e.ctrlKey\n    const isSearchKey = user.ecosystem.docs.slashSearch ? e.key === '/' : modifierKey && e.key === 'k'\n\n    if (!model.value && isSearchKey) {\n      e.preventDefault()\n\n      shouldLoad.value = true\n      model.value = true\n    } else if (model.value && ['ArrowDown', 'ArrowUp'].includes(e.key)) {\n      e.preventDefault()\n\n      // list.value?.rootEl?.focus()\n    }\n  }\n  function onMount () {\n    loading.value = false\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/search/SearchDialog.vue",
    "content": "<!-- eslint-disable vue/attribute-hyphenation  -->\n<template>\n  <v-dialog\n    v-model=\"model\"\n    activator=\"parent\"\n    content-class=\"overflow-visible align-self-start mt-16\"\n    max-height=\"900\"\n    width=\"600\"\n    scrollable\n    @after-leave=\"searchString = ''\"\n  >\n    <v-card>\n      <AppTextField\n        v-model=\"searchString\"\n        :placeholder=\"`${t('search.looking') }...`\"\n        class=\"flex-grow-0 mb-4\"\n        variant=\"filled\"\n        autofocus\n        @focus=\"$event.target.select()\"\n        @keydown.down=\"list?.$el.focus()\"\n      >\n        <template #append-inner>\n          <AppBtn size=\"small\" border>\n            <span class=\"text-body-small text-disabled\">{{ t('esc') }}</span>\n          </AppBtn>\n        </template>\n      </AppTextField>\n\n      <v-card-text :class=\"['px-4 py-0 d-flex flex-wrap justify-center', searchString ? 'align-start' : 'align-center']\">\n        <template v-if=\"(searches.length || favorites.length) && !searchString\">\n          <AppSearchSearchGroup\n            :results=\"searches\"\n            :title=\"t('search.recent')\"\n            class=\"mb-4\"\n            icon=\"mdi-history\"\n          >\n            <template #actions=\"{ index }\">\n              <div class=\"d-flex align-center ga-1\">\n                <v-icon-btn icon=\"mdi-star-outline\" icon-size=\"20\" size=\"24\" variant=\"text\" @click.prevent=\"saveResult(index)\" />\n                <v-icon-btn icon=\"mdi-delete-outline\" icon-size=\"20\" size=\"24\" variant=\"text\" @click.prevent=\"deleteRecent(index)\" />\n              </div>\n            </template>\n          </AppSearchSearchGroup>\n\n          <AppSearchSearchGroup\n            :results=\"favorites\"\n            :title=\"t('search.favorite')\"\n            icon=\"mdi-history\"\n          >\n            <template #actions=\"{ index }\">\n              <div class=\"d-flex align-center ga-1\">\n                <v-icon-btn icon=\"mdi-star\" icon-size=\"20\" size=\"24\" variant=\"text\" @click.prevent=\"unsaveResult(index)\" />\n                <v-icon-btn icon=\"mdi-delete-outline\" icon-size=\"20\" size=\"24\" variant=\"text\" @click.prevent=\"deleteFavorite(index)\" />\n              </div>\n            </template>\n          </AppSearchSearchGroup>\n        </template>\n\n        <template v-else-if=\"!searchString\">\n          <div class=\"text-center\">\n            <v-icon\n              class=\"mb-6 mx-auto text-disabled\"\n              icon=\"mdi-text-box-search-outline\"\n              size=\"150\"\n            />\n\n            <br>\n\n            <v-list-subheader class=\"d-inline-flex\">\n              {{ t('search.results') }}\n            </v-list-subheader>\n          </div>\n        </template>\n\n        <ais-instant-search\n          v-else\n          :search-client=\"searchClient\"\n          class=\"flex-grow-1\"\n          index-name=\"vuetifyjs-v4\"\n          @state-change=\"searchFunction\"\n        >\n          <ais-configure\n            :facetFilters=\"[`lang:${locale}`]\"\n            :hitsPerPage=\"50\"\n            :query=\"searchString\"\n          />\n\n          <ais-hits v-slot=\"{ items }\">\n            <AppSearchSearchResults\n              ref=\"list\"\n              :groups=\"transformItems(items)\"\n              @click:result=\"selectResult\"\n            />\n          </ais-hits>\n        </ais-instant-search>\n      </v-card-text>\n\n      <v-divider class=\"mt-4\" />\n\n      <div class=\"d-flex mx-4 my-2 align-center\">\n        <AppLink class=\"text-body-small\" href=\"https://www.algolia.com/doc/api-reference/api-parameters/advancedSyntax/#how-to-use\">\n          Advanced search\n        </AppLink>\n        <v-spacer />\n        <AisPoweredBy class=\"pt-2\" />\n      </div>\n    </v-card>\n  </v-dialog>\n</template>\n\n<script setup lang=\"ts\">\n  // Types\n  import SearchResults from '@/components/app/drawer/SearchResults.vue'\n\n  // Utilities\n  import { AisConfigure, AisHits, AisInstantSearch, AisPoweredBy } from 'vue-instantsearch/vue3/es/src/instantsearch.js'\n  import algoliasearch from 'algoliasearch'\n\n  // Types\n  import type { AlgoliaSearchHelper } from 'algoliasearch-helper'\n  import type { ShallowRef } from 'vue'\n\n  const { t } = useI18n()\n\n  const model = defineModel<boolean>()\n  const searchString = defineModel('search', { type: String, default: '' })\n\n  const list = ref<InstanceType<typeof SearchResults>>()\n  const searchClient = algoliasearch(\n    'NHT6C0IV19', // docsearch app ID\n    'ffa344297924c76b0f4155384aff7ef2' // vuetify API key\n  )\n\n  // Ensure to return array from local storage\n  function getLocalStorage (key: string): Record<string, string>[] {\n    const value = JSON.parse(localStorage.getItem(key) || '[]')\n    if (!Array.isArray(value)) {\n      return []\n    }\n    return value.filter(Boolean)\n  }\n\n  const searches = shallowRef(getLocalStorage('searches'))\n  const favorites = shallowRef(getLocalStorage('favorites'))\n\n  const locale = 'en'\n\n  watch(searches, val => {\n    localStorage.setItem('searches', JSON.stringify(val))\n  })\n\n  watch(favorites, val => {\n    localStorage.setItem('favorites', JSON.stringify(val))\n  })\n\n  function searchFunction (helper: AlgoliaSearchHelper) {\n    if (helper.state.query) helper.search()\n  }\n  function transformItems (items: any[]) {\n    // const sorted = sortItems([...items], ['hierarchy.lvl0', 'hierarchy.lvl1'], [false, false], locale)\n    items = items.map(item => {\n      const url = new URL(item.url)\n\n      return {\n        ...item,\n        url: url.href.split(url.origin).pop(),\n      }\n    })\n    const groups = groupItems(items, 'lvl0')\n\n    groups.forEach(group => {\n      group.items = groupItems(group.items, 'lvl1')\n    })\n\n    // const uiIndex = groups.findIndex(val => val.name === 'UI Components')\n    // if (uiIndex > 0) {\n    //   groups.unshift(groups.splice(uiIndex, 1)[0])\n    // }\n\n    return groups\n  }\n  function groupItems (items: any[], attribute: string) {\n    const groups: any[] = []\n\n    items.forEach(item => {\n      const group = groups.find(val => val.name === item.hierarchy[attribute])\n\n      if (group) {\n        group.items.push(item)\n      } else {\n        groups.push({\n          name: item.hierarchy[attribute],\n          items: [item],\n        })\n      }\n    })\n\n    return groups\n  }\n  function deleteItem (results: ShallowRef<any, any>, index:number) {\n    const array = results.value.slice(0, 6)\n    array.splice(index, 1)\n    results.value = array\n  }\n  function deleteRecent (index: number) {\n    deleteItem(searches, index)\n  }\n  function deleteFavorite (index: number) {\n    deleteItem(favorites, index)\n  }\n  function selectResult (result: any) {\n    // Check favorites\n    const favorite = favorites.value.find(search => JSON.stringify(search) === JSON.stringify(result))\n\n    if (favorite) {\n      // Deduplication in favorites\n      const filtered = favorites.value.filter(search => JSON.stringify(search) !== JSON.stringify(result))\n      filtered.unshift(result)\n\n      favorites.value = filtered.slice(0, 6)\n\n      // No longer need to proceed in searches\n      return\n    }\n\n    // Deduplication in searches\n    const filtered = searches.value.filter(search => JSON.stringify(search) !== JSON.stringify(result))\n    filtered.unshift(result)\n\n    searches.value = filtered.slice(0, 6)\n  }\n  function moveResult (from: ShallowRef<any, any>, to: ShallowRef<any, any>, index: number) {\n    const source = from.value.slice(0, 6)\n    const item = source[index]\n    source.splice(index, 1)\n\n    const target = to.value.slice(0, 6)\n    if (item) {\n      target.unshift(item)\n    }\n\n    from.value = source\n    to.value = target\n  }\n  function saveResult (index: number) {\n    moveResult(searches, favorites, index)\n  }\n  function unsaveResult (index: number) {\n    moveResult(favorites, searches, index)\n  }\n</script>\n\n<style scoped>\n  :deep(.v-field--variant-solo) {\n    box-shadow: none;\n  }\n</style>\n"
  },
  {
    "path": "packages/docs/src/components/app/search/SearchGroup.vue",
    "content": "<template>\n  <v-fade-transition hide-on-leave>\n    <AppSheet v-if=\"results.length\" class=\"pa-3 flex-1-1-100\" border>\n      <div class=\"text-high-emphasis font-weight-bold d-flex align-center text-title-large mb-2\">\n        <v-icon\n          class=\"me-2\"\n          color=\"medium-emphasis\"\n          icon=\"mdi-history\"\n          size=\"22\"\n        />\n\n        {{ title }}\n      </div>\n\n      <div class=\"d-flex flex-column ga-1\">\n        <v-fade-transition group hide-on-leave>\n          <template v-for=\"(result, i) in results\" :key=\"`${title}-${i}`\">\n            <v-list-item\n              :title=\"result.name\"\n              :to=\"result.url\"\n              append-icon=\"mdi-delete-outline\"\n              density=\"comfortable\"\n              lines=\"one\"\n              prepend-icon=\"mdi-file-document-outline\"\n              nav\n              slim\n            >\n              <template v-if=\"result.hash\" #subtitle>\n                <div class=\"d-flex align-center\">\n                  <v-icon\n                    class=\"me-1\"\n                    icon=\"mdi-pound\"\n                    size=\"x-small\"\n                  />\n                  <span class=\"text-capitalize\">{{ result.hash }}</span>\n                </div>\n              </template>\n\n              <template #append>\n                <slot :index=\"i\" name=\"actions\" />\n              </template>\n            </v-list-item>\n          </template>\n        </v-fade-transition>\n      </div>\n    </AppSheet>\n  </v-fade-transition>\n</template>\n\n  <script setup>\n  defineProps({\n    title: {\n      type: String,\n      required: true,\n    },\n    icon: {\n      type: String,\n      required: true,\n    },\n    results: {\n      type: Array,\n      default: () => ([]),\n    },\n  })\n  </script>\n"
  },
  {
    "path": "packages/docs/src/components/app/search/SearchResults.vue",
    "content": "<!--  eslint-disable vue/no-template-shadow -->\n<!--  eslint-disable vue/valid-v-for -->\n<!--  eslint-disable vue/require-v-for-key -->\n<template>\n  <v-list\n    ref=\"rootEl\"\n    bg-color=\"transparent\"\n    class=\"pa-0\"\n    density=\"compact\"\n    nav\n  >\n    <template\n      v-for=\"(group, i) in props.groups\"\n      :key=\"`group-${group.name}-${i}`\"\n    >\n      <AppSheet :class=\"['pa-3', i !== 0 && 'mt-4']\" border>\n        <div class=\"text-high-emphasis font-weight-bold d-flex align-center text-title-large mb-2\">\n          <v-icon\n            :icon=\"getIcon(group)\"\n            class=\"me-2\"\n            color=\"medium-emphasis\"\n            size=\"22\"\n          />\n\n          {{ group.name }}\n        </div>\n\n        <template\n          v-for=\"(child, ci) in group.items\"\n          :key=\"`group-item-${child.name}-${ci}`\"\n        >\n          <v-list-item\n            :to=\"getPathname(child)\"\n            append-icon=\"mdi-chevron-right\"\n            class=\"mb-0\"\n            prepend-icon=\"mdi-home-outline\"\n            slim\n            @click=\"onSearchClick(child.name, getPathname(child))\"\n          >\n            <template #append>\n              <v-icon size=\"16\" />\n            </template>\n\n            <v-list-item-title>\n              <div class=\"d-inline-block\" v-html=\"child.items[0]._highlightResult.hierarchy.lvl1.value\" />\n\n              <v-list-item-subtitle class=\"d-inline-flex ps-1\">\n                &rsaquo; Home\n              </v-list-item-subtitle>\n            </v-list-item-title>\n          </v-list-item>\n\n          <template v-if=\"child.items[0]._highlightResult.hierarchy.lvl1.matchLevel !== 'full'\">\n            <v-list-item\n              v-for=\"(item, it) in child.items\"\n              :key=\"`search-${i}-${ci}-${it}-children`\"\n              :append-icon=\"item.url.indexOf('#') > -1 ? 'mdi-chevron-right' : undefined\"\n              :prepend-icon=\"item.url.indexOf('#') > -1 ? 'mdi-pound' : undefined\"\n              :to=\"item.url\"\n              class=\"ps-6 mb-0\"\n              slim\n              @click=\"onSearchClick(child.name, item.url)\"\n            >\n              <template #prepend>\n                <v-icon size=\"14\" />\n              </template>\n\n              <template #append>\n                <v-icon size=\"16\" />\n              </template>\n\n              <v-list-item-subtitle\n                class=\"text-wrap font-weight-bold\"\n                v-html=\"makeBreadcrumbs(item._highlightResult.hierarchy)\"\n              />\n\n              <v-list-item-subtitle\n                v-if=\"item.content\"\n                class=\"text-body-small text-wrap text-high-emphasis font-weight-regular\"\n                v-html=\"truncateContent(item)\"\n              />\n            </v-list-item>\n          </template>\n        </template>\n      </AppSheet>\n    </template>\n  </v-list>\n</template>\n\n<script setup lang=\"ts\">\n  // Types\n  import type { VList } from 'vuetify/components'\n\n  const props = defineProps<{ groups: any[] }>()\n  const emit = defineEmits(['click:result'])\n\n  const app = useAppStore()\n\n  const rootEl = ref<InstanceType<typeof VList>>()\n  defineExpose({ rootEl })\n\n  function makeBreadcrumbs (hierarchy: any) {\n    let str = ''\n\n    for (const lvl of Object.keys(hierarchy).slice(2)) {\n      if (str.length) str += ' &rsaquo; '\n      str += hierarchy[lvl].value\n      if (hierarchy[lvl].matchLevel === 'full') break\n    }\n\n    return str\n  }\n  function truncateContent (item: any) {\n    const val = item._highlightResult.content.value.trim()\n\n    // number of characters until the word after the end of the first mark\n    const withMark = val.match(/^.*?<\\/mark>(.{4,}?\\b)?/)?.[0].length ?? 0\n\n    // characters until the end of the first word after the 72char limit\n    const minLength = val.match(/^.{0,72}.?\\b/)?.[0].length ?? 0\n\n    const length = Math.max(withMark, minLength)\n    const continues = val.length > length\n\n    return val.slice(0, length) + (continues ? '&mldr;' : '')\n  }\n  function getPathname (group: any) {\n    return new URL(location.origin + group.items[0].url).pathname\n  }\n  function getIcon (group: Record<string, any>) {\n    let name = group.name.toLowerCase().replace(/[^a-z]/g, '-')\n\n    if (name === 'styles-and-animations') name = 'styles'\n\n    return app.categories?.[name]?.icon ?? '$vuetify'\n  }\n  function onSearchClick (name: string, url: string) {\n    emit('click:result', {\n      name,\n      hash: url.indexOf('#') > -1 ? url.split('#')[1] : undefined,\n      url,\n    })\n  }\n</script>\n\n<style lang=\"sass\" scoped>\n//.v-list .v-list-item\n//  min-height: 0\n\n:deep(mark)\n  background: rgb(33, 150, 243, 30%)\n  color: inherit\n</style>\n"
  },
  {
    "path": "packages/docs/src/components/app/settings/Append.vue",
    "content": "<template>\n  <div>\n    <v-divider />\n\n    <AppSettingsLatestRelease />\n\n    <AppSettingsDocumentationBuild />\n\n    <AppSettingsLatestCommit />\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/components/app/settings/DeveloperMode.vue",
    "content": "<template>\n  <AppSettingsSettingsHeader text=\"developer-mode-message\" title=\"developer-mode\">\n    <v-defaults-provider\n      :defaults=\"{\n        VIcon: {\n          color: user.one.devmode ? 'error' : 'disabled'\n        }\n      }\"\n    >\n      <SettingsSwitch\n        v-model=\"user.one.devmode\"\n        base-color=\"error\"\n        color=\"error\"\n      />\n    </v-defaults-provider>\n  </AppSettingsSettingsHeader>\n</template>\n\n<script setup>\n  const user = useUserStore()\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/settings/DocumentationBuild.vue",
    "content": "<template>\n  <AppListLinkListItem\n    v-if=\"GITHUB_SHA\"\n    :append-icon=\"appendIcon\"\n    :href=\"`https://github.com/vuetifyjs/vuetify/commit/${GITHUB_SHA}`\"\n    :label=\"t('documentation-build')\"\n    :prepend-icon=\"prependIcon\"\n    :title=\"GITHUB_SHA.slice(0, 7)\"\n    rel=\"noopener noreferrer\"\n    target=\"_blank\"\n  />\n</template>\n\n<script setup>\n  const GITHUB_SHA = import.meta.env.VITE_GITHUB_SHA\n\n  const { t } = useI18n()\n\n  defineProps({\n    prependIcon: {\n      type: String,\n      default: 'mdi-package',\n    },\n    appendIcon: {\n      type: String,\n      default: 'mdi-open-in-new',\n    },\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/settings/Drawer.vue",
    "content": "<template>\n  <v-navigation-drawer\n    id=\"settings-drawer\"\n    v-model=\"app.settings\"\n    :location=\"isRtl ? 'left' : 'right'\"\n    width=\"350\"\n    disable-route-watcher\n    temporary\n    touchless\n  >\n    <v-toolbar :title=\"t('settings.header')\" flat>\n      <template #append>\n        <v-btn\n          icon=\"mdi-close\"\n          variant=\"flat\"\n          @click=\"app.settings = false\"\n        />\n      </template>\n    </v-toolbar>\n\n    <v-divider />\n\n    <v-container class=\"px-3 py-3\">\n      <AppSettingsOptions />\n    </v-container>\n\n    <template #append>\n      <AppSettingsAppend />\n    </template>\n  </v-navigation-drawer>\n</template>\n\n<script setup>\n  const app = useAppStore()\n\n  const { t } = useI18n()\n  const { isRtl } = useRtl()\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/settings/LatestCommit.vue",
    "content": "<template>\n  <AppListLinkListItem\n    v-if=\"commits.latest?.sha\"\n    :href=\"`https://github.com/vuetifyjs/vuetify/commit/${commits.latest.sha}`\"\n    :label=\"t('latest-commit')\"\n    :title=\"commits.latest.sha.slice(0, 7)\"\n    append-icon=\"mdi-open-in-new\"\n    min-width=\"90\"\n    prepend-icon=\"mdi-source-commit\"\n    rel=\"noopener noreferrer\"\n    target=\"_blank\"\n  />\n</template>\n\n<script setup>\n  const commits = useCommitsStore()\n  const { t } = useI18n()\n\n  onBeforeMount(() => {\n    if (!commits.latest) commits.fetch()\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/settings/LatestRelease.vue",
    "content": "<template>\n  <AppListLinkListItem\n    :label=\"t('latest-release')\"\n    :title=\"`v${version}`\"\n    :to=\"rpath(`/getting-started/release-notes/?version=v${version}`)\"\n    append-icon=\"mdi-page-next\"\n    prepend-icon=\"mdi-tag-outline\"\n    @click=\"onClick\"\n  />\n</template>\n\n<script setup>\n  // Utilities\n  import { version } from 'vuetify'\n\n  const app = useAppStore()\n  const { t } = useI18n()\n\n  function onClick () {\n    app.settings = false\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/settings/Options.vue",
    "content": "<template>\n  <div>\n    <AppSettingsSettingsHeader\n      text=\"theme-message\"\n      title=\"theme\"\n    />\n\n    <AppSettingsOptionsThemeOption />\n\n    <AppSettingsOptionsOfflineOption />\n\n    <v-divider class=\"mt-4 mb-3\" />\n\n    <AppSettingsOptionsPinOption />\n\n    <AppSettingsOptionsRailDrawerOption />\n\n    <AppSettingsOptionsCodeOption />\n\n    <AppSettingsOptionsApiOption />\n\n    <AppSettingsOptionsSlashSearchOption />\n\n    <AppSettingsOptionsAdOption v-if=\"one.isSubscriber\" />\n\n    <AppSettingsDeveloperMode />\n  </div>\n</template>\n\n<script setup lang=\"ts\">\n  const one = useOneStore()\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/settings/SettingsHeader.vue",
    "content": "<template>\n  <div class=\"d-flex mb-3 w-100\">\n    <div class=\"flex-1-1-0\">\n      <v-label :text=\"t(title)\" class=\"mb-1 font-weight-medium\">\n        <slot name=\"title\" />\n      </v-label>\n      <v-messages :messages=\"t(text)\" active />\n    </div>\n\n    <slot />\n  </div>\n</template>\n\n<script setup>\n  defineProps({\n    title: {\n      type: String,\n      required: true,\n    },\n    text: {\n      type: String,\n      required: true,\n    },\n  })\n\n  const { t } = useI18n()\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/settings/options/AdOption.vue",
    "content": "<template>\n  <AppSettingsSettingsHeader text=\"dashboard.perks.disable-ads-message\" title=\"dashboard.perks.disable-ads\">\n    <v-defaults-provider\n      :defaults=\"{\n        VIcon: { color: !user.one.ads.enabled && one.isSubscriber ? 'primary' : 'disabled' }\n      }\"\n    >\n      <SettingsSwitch\n        :disabled=\"!one.isSubscriber\"\n        :model-value=\"!user.one.ads.enabled\"\n        :readonly=\"!one.isSubscriber\"\n        @update:model-value=\"val => user.one.ads.enabled = !val\"\n      />\n    </v-defaults-provider>\n  </AppSettingsSettingsHeader>\n</template>\n\n<script setup>\n  const one = useOneStore()\n  const user = useUserStore()\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/settings/options/ApiOption.vue",
    "content": "<template>\n  <AppSettingsSettingsHeader text=\"enable-inline-api-message\" title=\"enable-inline-api\">\n    <v-defaults-provider\n      :defaults=\"{\n        VIcon: { color: user.ecosystem.docs.api === 'inline' ? 'primary' : 'disabled' }\n      }\"\n    >\n      <SettingsSwitch\n        v-model=\"user.ecosystem.docs.api\"\n        false-value=\"link-only\"\n        true-value=\"inline\"\n      />\n    </v-defaults-provider>\n  </AppSettingsSettingsHeader>\n</template>\n\n<script setup>\n  const user = useUserStore()\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/settings/options/CodeOption.vue",
    "content": "<template>\n  <AppSettingsSettingsHeader text=\"enable-composition-message\" title=\"enable-composition\">\n    <v-defaults-provider\n      :defaults=\"{\n        VIcon: { color: user.ecosystem.docs.composition === 'composition' ? 'primary' : 'disabled' }\n      }\"\n    >\n      <SettingsSwitch\n        v-model=\"user.ecosystem.docs.composition\"\n        false-value=\"options\"\n        true-value=\"composition\"\n      />\n    </v-defaults-provider>\n  </AppSettingsSettingsHeader>\n</template>\n\n<script setup>\n  const user = useUserStore()\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/settings/options/OfflineOption.vue",
    "content": "<template>\n  <v-divider class=\"mt-4 mb-3\" />\n\n  <AppSettingsSettingsHeader\n    :text=\"\n      store.isOffline ? 'settings.offline.offline-message'\n      : store.availableOffline ? 'settings.offline.active-message'\n        : 'settings.offline.message'\"\n    title=\"settings.offline.header\"\n  >\n    <v-defaults-provider\n      :defaults=\"{\n        VIcon: { color: store.availableOffline ? 'primary' : 'disabled' }\n      }\"\n    >\n      <SettingsSwitch\n        v-model=\"store.availableOffline\"\n        class=\"flex-0-0-auto ms-auto\"\n      />\n    </v-defaults-provider>\n  </AppSettingsSettingsHeader>\n\n  <v-progress-linear\n    v-slot=\"{ value }\"\n    :active=\"store.isUpdating\"\n    :max=\"store.progressTotal\"\n    :model-value=\"store.progress\"\n    color=\"primary\"\n    height=\"18\"\n    rounded=\"pill\"\n    rounded-bar\n  >\n    <div\n      :style=\"{\n        width: '100%',\n        display: 'grid',\n        gridTemplateAreas: `'a'`,\n        textAlign: 'center',\n        '--progress': `calc(${ value } * 1%)`,\n      }\"\n    >\n      <div\n        class=\"on-primary\"\n        style=\"grid-area: a; clip-path: inset(0 calc(100% - var(--progress)) 0 0 round 9px)\"\n      >Downloading: {{ store.progress }} / {{ store.progressTotal }}</div>\n      <div\n        style=\"grid-area: a; clip-path: inset(0 0 0 var(--progress) round 9px)\"\n      >Downloading: {{ store.progress }} / {{ store.progressTotal }}</div>\n    </div>\n  </v-progress-linear>\n\n  <v-expand-transition>\n    <v-card v-if=\"store.availableOffline && !store.isUpdating && store.pendingUpdate\" color=\"surface-variant\" variant=\"tonal\">\n      <v-card-text class=\"text-body-small pb-0\">{{ t('settings.offline.pending') }}</v-card-text>\n      <template #actions>\n        <v-spacer />\n        <v-btn color=\"primary\" variant=\"plain\" @click=\"reload\">\n          {{ t('settings.offline.reload') }}\n        </v-btn>\n      </template>\n    </v-card>\n  </v-expand-transition>\n</template>\n\n<script setup lang=\"ts\">\n  const { t } = useI18n()\n\n  const store = usePwaStore()\n\n  function reload () {\n    location.reload()\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/settings/options/PinOption.vue",
    "content": "<template>\n  <AppSettingsSettingsHeader text=\"dashboard.perks.enable-pins-message\" title=\"dashboard.perks.enable-pins\">\n    <template #title>\n      <v-chip\n        :text=\"t('new').toUpperCase()\"\n        class=\"ms-2\"\n        color=\"success\"\n        size=\"x-small\"\n        variant=\"outlined\"\n      />\n    </template>\n    <v-defaults-provider\n      :defaults=\"{\n        VIcon: { color: one.isSubscriber && user.ecosystem.docs.pins.enabled ? 'primary' : 'disabled' }\n      }\"\n    >\n      <SettingsSwitch\n        v-model=\"user.ecosystem.docs.pins.enabled\"\n        :disabled=\"!one.isSubscriber\"\n      />\n    </v-defaults-provider>\n  </AppSettingsSettingsHeader>\n</template>\n\n<script setup>\n  const { t } = useI18n()\n  const one = useOneStore()\n  const user = useUserStore()\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/settings/options/RailDrawerOption.vue",
    "content": "<template>\n  <AppSettingsSettingsHeader text=\"dashboard.perks.rail-drawer-message\" title=\"dashboard.perks.rail-drawer\">\n    <v-defaults-provider\n      :defaults=\"{\n        VIcon: {\n          color: user.ecosystem.docs.railDrawer && one.isSubscriber ? 'primary' : 'disabled'\n        }\n      }\"\n    >\n      <SettingsSwitch\n        v-model=\"user.ecosystem.docs.railDrawer\"\n        :disabled=\"!one.isSubscriber\"\n        :readonly=\"!one.isSubscriber\"\n      />\n    </v-defaults-provider>\n  </AppSettingsSettingsHeader>\n</template>\n\n<script setup>\n  const one = useOneStore()\n  const user = useUserStore()\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/settings/options/SlashSearchOption.vue",
    "content": "<template>\n  <AppSettingsSettingsHeader text=\"slash-search-message\" title=\"slash-search\">\n    <v-defaults-provider\n      :defaults=\"{\n        VIcon: { color: user.ecosystem.docs.slashSearch ? 'primary' : 'disabled' }\n      }\"\n    >\n      <SettingsSwitch v-model=\"user.ecosystem.docs.slashSearch\" />\n    </v-defaults-provider>\n  </AppSettingsSettingsHeader>\n</template>\n\n<script setup>\n  const user = useUserStore()\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/app/settings/options/ThemeOption.vue",
    "content": "<template>\n  <v-radio-group\n    v-model=\"user.one.theme\"\n    class=\"mb-2\"\n    color=\"primary\"\n    true-icon=\"mdi-check-circle-outline\"\n    hide-details\n  >\n    <v-radio\n      v-for=\"(item, i) in items\"\n      :key=\"i\"\n      :value=\"item.value\"\n    >\n      <template #label>\n        <v-icon :icon=\"item.icon\" start />\n\n        {{ item.text }}\n      </template>\n    </v-radio>\n  </v-radio-group>\n\n  <v-defaults-provider\n    v-if=\"!theme.current.value?.dark\"\n    :defaults=\"{\n      VIcon: {\n        color: user.ecosystem.docs.mixedTheme ? 'primary' : 'disabled'\n      }\n    }\"\n  >\n    <SettingsSwitch\n      v-model=\"user.ecosystem.docs.mixedTheme\"\n      :label=\"t('dark-code')\"\n      :messages=\"t('dark-code-message')\"\n    />\n  </v-defaults-provider>\n\n  <AppBtn\n    append-icon=\"mdi-page-next\"\n    color=\"surface-variant\"\n    to=\"?one=settings\"\n    variant=\"flat\"\n    block\n  >\n    Vuetify One Themes\n  </AppBtn>\n</template>\n\n<script setup lang=\"ts\">\n  const { t } = useI18n()\n  const theme = useTheme()\n  const user = useUserStore()\n\n  const items = [\n    {\n      text: t('light'),\n      icon: 'mdi-white-balance-sunny',\n      value: 'light',\n    },\n    {\n      text: t('dark'),\n      icon: 'mdi-weather-night',\n      value: 'dark',\n    },\n    {\n      text: t('system'),\n      icon: 'mdi-desktop-tower-monitor',\n      value: 'system',\n    },\n  ]\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/components/ListItem.vue",
    "content": "<template>\n  <v-col\n    cols=\"12\"\n    lg=\"4\"\n    md=\"6\"\n  >\n    <v-card\n      :image=\"image\"\n      :to=\"rpath(`/components/${src}/`)\"\n      class=\"mb-3\"\n      elevation=\"0\"\n      height=\"164\"\n    >\n      <template #image>\n        <v-img @error=\"hasError = true\">\n          <v-chip\n            v-if=\"labs\"\n            :to=\"rpath('/labs/introduction/')\"\n            color=\"success\"\n            prepend-icon=\"mdi-beaker-outline\"\n            rounded=\"bs-0 te-0\"\n            size=\"small\"\n            text=\"Labs Component\"\n            variant=\"flat\"\n            label\n            @click.stop\n          />\n        </v-img>\n      </template>\n    </v-card>\n\n    <h2 class=\"text-title-large mt-4 mb-n3 font-weight-medium\">\n      <span class=\"text-capitalize\">{{ name?.replace(/-/g, ' ') }}</span>\n    </h2>\n\n    <slot />\n  </v-col>\n</template>\n\n<script setup lang=\"ts\">\n  const props = defineProps({\n    name: String,\n    labs: Boolean,\n    src: String,\n  })\n\n  const hasError = shallowRef(false)\n  const image = computed(() => {\n    if (hasError.value) return 'https://cdn.vuetifyjs.com/docs/images/graphics/img-placeholder.png'\n\n    return `https://cdn.vuetifyjs.com/docs/images/preview/${props.src}.png`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/dashboard/DashboardEmptyState.vue",
    "content": "<template>\n  <v-empty-state\n    :text=\"text\"\n    headline=\"My Dashboard\"\n    height=\"calc(100vh - var(--v-layout-top))\"\n  >\n    <UserOneSubCard />\n\n    <VoAuthCard v-if=\"!auth.user\" />\n  </v-empty-state>\n</template>\n\n<script setup lang=\"ts\">\n// Components\n  import UserOneSubCard from '@/components/user/OneSubCard.vue'\n\n  // Stores\n  import { useAuthStore } from '@vuetify/one'\n\n  const auth = useAuthStore()\n\n  const text = computed(() => {\n    return auth.user ? 'This page will soon be home to the Vuetify One Dashboard.' : 'In order to proceed, please login using GitHub or Discord.'\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/doc/Explorer.vue",
    "content": "<template>\n  <div>\n    <v-autocomplete\n      v-model=\"model\"\n      :items=\"components\"\n      base-color=\"disabled\"\n      class=\"mb-2\"\n      placeholder=\"Search Vuetify API\"\n      prepend-inner-icon=\"mdi-database-search-outline\"\n      variant=\"outlined\"\n      auto-select-first\n      autofocus\n      chips\n      clearable\n      hide-details\n      item-props\n      persistent-clear\n    >\n      <template #chip=\"{ props, item }\">\n        <v-chip\n          v-bind=\"props\"\n          :prepend-icon=\"item.prependIcon\"\n          color=\"primary\"\n          variant=\"flat\"\n          label\n        />\n      </template>\n    </v-autocomplete>\n\n    <template v-if=\"model\">\n      <ApiSearch ref=\"search\" />\n\n      <template v-for=\"(section, i) in sections\" :key=\"i\">\n        <ApiSection\n          :name=\"model\"\n          :section=\"section\"\n        />\n      </template>\n    </template>\n\n    <div v-else class=\"text-center d-flex flex-column justify-center align-center my-10\">\n      <v-icon\n        color=\"disabled\"\n        icon=\"mdi-text-box-search-outline\"\n        size=\"150\"\n      />\n\n      <br>\n\n      <v-list-subheader class=\"d-inline-flex\">\n        API Properties will appear here\n      </v-list-subheader>\n    </div>\n  </div>\n</template>\n\n<script setup>\n  import files from 'virtual:api-list'\n\n  const route = useRoute()\n  const router = useRouter()\n\n  const search = shallowRef()\n\n  const components = files.reduce((acc, name) => {\n    let prependIcon\n    let subtitle\n\n    if (name.startsWith('V')) {\n      prependIcon = 'mdi-view-dashboard'\n      subtitle = 'Component'\n    } else if (name.startsWith('v-')) {\n      prependIcon = 'mdi-function'\n      subtitle = 'Directive'\n    } else if (name.startsWith('use')) {\n      prependIcon = '$vuetify'\n      subtitle = 'Composable'\n    } else if (name.startsWith('global')) {\n      prependIcon = '$vuetify'\n      subtitle = 'Global SASS'\n    } else {\n      return acc\n    }\n\n    acc.push({\n      title: name,\n      value: name,\n      prependIcon,\n      subtitle,\n    })\n\n    return acc\n  }, [])\n\n  const name = route.params.name?.replace('/', '')\n  const pascalName = name ? `${name.charAt(0).toUpperCase()}${camelize(name.slice(1))}` : undefined\n  const model = shallowRef(components.some(v => v.value === name) ? name : pascalName)\n\n  const sections = ['props', 'events', 'slots', 'exposed', 'sass', 'options', 'argument', 'modifiers']\n\n  watch(model, async () => {\n    if (!model.value) return\n\n    await nextTick()\n\n    search.value.$el.querySelector('input').focus()\n    router.replace({ params: { name: kebabCase(model.value) } })\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/doc/IconList.vue",
    "content": "<template>\n  <v-autocomplete\n    v-model=\"selection\"\n    v-model:menu=\"menu\"\n    v-model:search=\"search\"\n    :items=\"filteredIcons\"\n    :loading=\"loading ? 'primary' : false\"\n    :placeholder=\"t('search.icons')\"\n    item-title=\"name\"\n    item-value=\"name\"\n    variant=\"outlined\"\n    clearable\n    no-filter\n    return-object\n    @focus.once=\"load\"\n  >\n    <template #prepend-inner>\n      <v-expand-x-transition>\n        <v-icon v-if=\"selection\" :icon=\"'mdi-' + selection.name\" start />\n      </v-expand-x-transition>\n\n      <code class=\"me-n1\">mdi-</code>\n    </template>\n\n    <template #item=\"{ props, item }\">\n      <v-list-item v-bind=\"props\" :prepend-icon=\"'svg:' + item.path\">\n        <template #append>\n          <v-btn\n            icon=\"mdi-content-copy\"\n            size=\"small\"\n            tabindex=\"-1\"\n            variant=\"plain\"\n            @click.stop=\"copy(item.name)\"\n          />\n        </template>\n      </v-list-item>\n    </template>\n\n    <template #append-inner>\n      <v-expand-x-transition>\n        <span v-if=\"copied\" class=\"text-primary pt-1\">\n          {{ t('copied') }}\n        </span>\n      </v-expand-x-transition>\n    </template>\n  </v-autocomplete>\n</template>\n\n<script setup lang=\"ts\">\n  import type { IconEntry } from 'virtual:mdi-js-icons'\n\n  const { t } = useI18n()\n\n  const copied = shallowRef(false)\n  const loading = shallowRef(false)\n  const menu = shallowRef(false)\n  const icons = shallowRef<IconEntry[]>([])\n  const selection = shallowRef<IconEntry>()\n  const search = shallowRef('')\n\n  async function load () {\n    const _menu = menu.value\n    loading.value = true\n    // TODO: virtual loads everything if menu is open\n    menu.value = false\n    await import('virtual:mdi-js-icons')\n      .then(m => icons.value = m.icons)\n      .catch(console.error)\n    loading.value = false\n    menu.value = _menu\n  }\n\n  function * filterIcons (s: string) {\n    for (const icon of icons.value) {\n      const distance = Math.max(\n        getDistance(s, icon.name),\n        ...icon.aliases.map(v => getDistance(search.value, v))\n      )\n      if (distance > 0.7) {\n        yield {\n          name: icon.name,\n          path: icon.path,\n          distance,\n        }\n      }\n    }\n  }\n\n  const filteredIcons = computed(() => {\n    const s = search.value.trim()\n    if (!s.length) return icons.value\n\n    return [...filterIcons(s)].sort((a, b) => b.distance - a.distance)\n  })\n\n  watch(selection, value => {\n    value && copy(value.name)\n  })\n\n  function copy (name: string) {\n    navigator.clipboard.writeText('mdi-' + name).then(() => {\n      copied.value = true\n      setTimeout(() => {\n        copied.value = false\n      }, 2000)\n    })\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/doc/IconTable.vue",
    "content": "<template>\n  <AppTable>\n    <thead>\n      <tr>\n        <th>Alias</th>\n\n        <th>Name</th>\n\n        <th class=\"text-center\">Preview</th>\n      </tr>\n    </thead>\n\n    <tbody>\n      <tr v-for=\"icon in icons\" :key=\"icon.name\">\n        <td>\n          <strong>${{ icon.alias }}</strong>\n        </td>\n\n        <td>{{ icon.name }}</td>\n\n        <td class=\"text-center\">\n          <v-icon color=\"medium-emphasis\">{{ icon.name }}</v-icon>\n        </td>\n      </tr>\n    </tbody>\n  </AppTable>\n</template>\n\n<script setup>\n  // Imports\n  import { aliases } from 'vuetify/iconsets/mdi'\n\n  const icons = Object.keys(aliases).map(alias => ({\n    alias,\n    name: aliases[alias],\n  })).sort((a, b) => a.alias.localeCompare(b.alias))\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/doc/Introduced.vue",
    "content": "<template>\n  <Alert type=\"success\">\n    <i18n-t keypath=\"feature-introduced-in\">\n      <AppLink :href=\"`/getting-started/release-notes/?version=v${props.version}`\">\n        {{ versionString }}\n      </AppLink>\n    </i18n-t>\n  </Alert>\n</template>\n\n<script setup lang=\"ts\">\n  const props = defineProps<{\n    version: string\n  }>()\n\n  const versionNameMap: Record<string, string> = {\n    '3.0.0': 'Titan',\n    '3.1.0': 'Valkyrie',\n    '3.2.0': 'Orion',\n    '3.3.0': 'Icarus',\n    '3.4.0': 'Blackguard',\n    '3.5.0': 'Polaris',\n    '3.6.0': 'Nebula',\n    '3.7.0': 'Odyssey',\n    '3.8.0': 'Andromeda',\n    '3.9.0': 'Zealot',\n    '4.0.0': 'Revisionist',\n  }\n\n  const versionString = computed(() => {\n    let str = `v${props.version}`\n    const name = versionNameMap[props.version]\n    if (name) str += ` (${name})`\n    return str\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/doc/MadeWithVueAttribution.vue",
    "content": "<template>\n  <div class=\"d-flex align-center justify-center px-4\">\n    <small class=\"font-weight-bold text-no-wrap\">Powered By</small>\n\n    <SponsorCard\n      min-height=\"64\"\n      slug=\"made-with-vuejs\"\n      width=\"180\"\n    />\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/components/doc/MadeWithVuetifyGallery.vue",
    "content": "<template>\n  <v-sheet\n    class=\"mx-auto text-center\"\n    color=\"transparent\"\n    max-width=\"900\"\n  >\n    <v-row v-if=\"!items.length\">\n      <v-col\n        v-for=\"n in 9\"\n        :key=\"n\"\n        cols=\"12\"\n        md=\"4\"\n      >\n        <v-skeleton-loader class=\"rounded-b-0\" height=\"180\" />\n\n        <v-skeleton-loader class=\"rounded-t-0\" type=\"text\" />\n      </v-col>\n    </v-row>\n\n    <v-data-iterator\n      v-else\n      :items=\"items\"\n      :items-per-page=\"itemsPerPage\"\n      :page=\"page\"\n    >\n      <template #default=\"{ items: _items }\">\n        <v-row style=\"min-height: 750px;\">\n          <v-col\n            v-for=\"project in _items\"\n            :key=\"project.raw.id\"\n            cols=\"12\"\n            sm=\"4\"\n          >\n            <a\n              :href=\"project.raw.url\"\n              class=\"d-block text-decoration-none\"\n              rel=\"noopener noreferrer\"\n              style=\"min-height: 205px;\"\n              target=\"_blank\"\n            >\n              <AppFigure\n                :name=\"project.raw.title\"\n                :src=\"getPreviewImage(project.raw.image)\"\n                :title=\"project.raw.title\"\n                height=\"230\"\n                max-height=\"230\"\n                min-height=\"230\"\n                cover\n                eager\n              />\n            </a>\n          </v-col>\n        </v-row>\n      </template>\n\n      <template\n        v-if=\"pagination\"\n        #footer=\"{ pageCount }\"\n      >\n\n        <v-pagination\n          v-model=\"page\"\n          :length=\"pageCount\"\n        />\n      </template>\n    </v-data-iterator>\n  </v-sheet>\n</template>\n\n<script setup>\n  defineProps({\n    itemsPerPage: {\n      type: [Number, String],\n      default: 9,\n    },\n    pagination: Boolean,\n  })\n\n  const page = shallowRef(1)\n  const store = useMadeWithVuetifyStore()\n\n  const items = computed(() => {\n    return shuffle(store.items.slice())\n  })\n\n  function shuffle (array) {\n    let currentIndex = array.length\n    let temporaryValue\n    let randomIndex\n    // While there remain elements to shuffle...\n    while (currentIndex !== 0) {\n      // Pick a remaining element...\n      randomIndex = Math.floor(Math.random() * currentIndex)\n      currentIndex -= 1\n      // And swap it with the current element.\n      temporaryValue = array[currentIndex]\n      array[currentIndex] = array[randomIndex]\n      array[randomIndex] = temporaryValue\n    }\n    return array\n  }\n\n  function getPreviewImage (url) {\n    return url.replace(/(.*)\\/([^/]+)\\.([^.]+)$/g, '$1/conversions/$2-overview.$3')\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/doc/MadeWithVuetifyLink.vue",
    "content": "<template>\n  <v-btn\n    :aria-label=\"t('see-more-projects')\"\n    :size=\"size\"\n    :to=\"rpath('/resources/made-with-vuetify/')\"\n    append-icon=\"mdi-page-next\"\n    color=\"primary\"\n    variant=\"outlined\"\n    @click=\"sweClick('button', 'made-with-vuetify', name)\"\n  >\n    <span\n      class=\"text-capitalize font-weight-regular\"\n      v-text=\"t('see-more-projects')\"\n    />\n  </v-btn>\n</template>\n\n<script setup>\n  defineProps({\n    size: {\n      type: String,\n      default: 'large',\n    },\n  })\n\n  const { name } = useRoute()\n  const { t } = useI18n()\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/doc/ReadyForMore.vue",
    "content": "<template>\n  <div class=\"mb-3\">\n    <AppHeading\n      :content=\"t('ready')\"\n      class=\"mb-2\"\n      level=\"2\"\n    />\n\n    <!-- https://vue-i18n.intlify.dev/guide/advanced/component.html#scope-resolving -->\n    <i18n-t\n      keypath=\"ready-text\"\n      scope=\"global\"\n      tag=\"div\"\n    >\n      <template #team>\n        <AppLink :href=\"rpath('/about/meet-the-team/')\">\n          {{ t('team') }}\n        </AppLink>\n      </template>\n    </i18n-t>\n  </div>\n</template>\n\n<script setup>\n  const { t } = useI18n()\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/doc/RelatedPage.vue",
    "content": "<template>\n  <v-list-item\n    v-if=\"item\"\n    :subtitle=\"subtitle\"\n    :title=\"item.meta.nav ?? item.meta.title\"\n    :to=\"item.path\"\n    lines=\"two\"\n    border\n    rounded\n  >\n    <template #prepend>\n      <v-avatar>\n        <v-icon\n          :color=\"icon.color\"\n          :icon=\"icon.icon\"\n        />\n      </v-avatar>\n    </template>\n  </v-list-item>\n</template>\n\n<script setup>\n  const appStore = useAppStore()\n  const props = defineProps({ to: String })\n  const routes = useRouter().getRoutes()\n  const path = rpath(props.to)\n  const item = routes.find(r => r.path === path)\n  const category = path.split('/')[2]\n  const icon = computed(() => appStore.categories[category])\n  const subtitle = upperFirst(category.replace('-', ' '))\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/doc/RelatedPages.vue",
    "content": "<template>\n  <v-row\n    v-if=\"related?.length > 0\"\n    density=\"comfortable\"\n  >\n    <v-col\n      v-for=\"(to, i) in related\"\n      :key=\"i\"\n      cols=\"12\"\n      sm=\"4\"\n      xs=\"6\"\n    >\n      <DocRelatedPage :to=\"to\" />\n    </v-col>\n  </v-row>\n</template>\n\n<script setup>\n  const frontmatter = useFrontmatter()\n  const related = computed(() => frontmatter.value?.related)\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/doc/Releases.vue",
    "content": "<template>\n  <div class=\"border rounded my-6\">\n    <v-autocomplete\n      ref=\"autocomplete\"\n      v-model=\"model\"\n      v-model:search=\"search\"\n      :items=\"releases\"\n      :menu-props=\"menuProps\"\n      :placeholder=\"tag\"\n      density=\"comfortable\"\n      item-title=\"name\"\n      label=\"Select Release Version\"\n      prepend-inner-icon=\"mdi-text-box-search-outline\"\n      rounded=\"b-0\"\n      variant=\"solo-filled\"\n      hide-details\n      hide-no-data\n      persistent-placeholder\n      return-object\n    >\n      <template #selection>\n        <div class=\"d-flex align-center\">\n          <div class=\"me-1\">{{ model?.tag_name }}</div>\n\n          <template v-if=\"model?.reactions?.total_count\">\n            &mdash;\n          </template>\n\n          <template v-for=\"(value, key) in reactions\" :key=\"key\">\n            <template v-if=\"model?.reactions?.[key]\">\n              <span class=\"d-inline-flex align-center text-body-medium me-2\">\n                {{ value }}\n\n                <span class=\"text-body-small\">{{ model.reactions[key] }}</span>\n              </span>\n            </template>\n          </template>\n        </div>\n      </template>\n\n      <template #item=\"{ item, props: itemProps }\">\n        <v-list-item\n          v-if=\"item.name\"\n          v-bind=\"itemProps\"\n        >\n          <template v-if=\"item.reactions\" #append>\n            {{ genEmoji(item.reactions.total_count) }}\n          </template>\n        </v-list-item>\n\n        <template v-else>\n          <v-divider />\n\n          <v-list-item\n            :title=\"t('load-more')\"\n            class=\"mb-n2\"\n            @click=\"store.fetch\"\n          />\n        </template>\n      </template>\n\n      <template #append-inner>\n        <v-progress-circular\n          v-if=\"store.isLoading\"\n          indeterminate=\"disable-shrink\"\n          size=\"18\"\n          width=\"2\"\n        />\n      </template>\n    </v-autocomplete>\n\n    <v-card\n      rounded=\"t-0 b\"\n      variant=\"flat\"\n    >\n      <div\n        v-if=\"model?.author\"\n        class=\"d-flex align-center justify-space-between pa-4 bg-surface-light border-y\"\n      >\n        <div class=\"d-flex align-center text-body-small\">\n          <i18n-t v-if=\"publishedOn\" keypath=\"published\" scope=\"global\">\n            <template #date>\n              <border-chip\n                :text=\"publishedOn\"\n                class=\"ms-1\"\n                prepend-icon=\"mdi-calendar\"\n              />\n            </template>\n          </i18n-t>\n        </div>\n\n        <div class=\"d-flex align-center\">\n          <AppTooltipBtn\n            v-for=\"(tooltip, i) in tooltips\"\n            :key=\"i\"\n            :color=\"tooltip.color ?? 'text-high-emphasis'\"\n            :href=\"tooltip.href\"\n            :icon=\"tooltip.icon\"\n            :path=\"tooltip.path\"\n            :target=\"tooltip.href ? '_blank' : undefined\"\n            class=\"text-white ms-2\"\n            density=\"comfortable\"\n            size=\"small\"\n            variant=\"flat\"\n            @click=\"tooltip?.onClick?.()\"\n          />\n        </div>\n      </div>\n\n      <template v-if=\"model?.body\">\n        <v-divider />\n\n        <div class=\"px-4 pt-4\">\n          <AppMarkdown\n            :content=\"model.body\"\n            class=\"releases\"\n          />\n        </div>\n\n        <template v-if=\"model.zipball_url && model.tarball_url\">\n          <v-divider class=\"my-2\" />\n\n          <div class=\"px-4 pb-4\">\n            <h2 class=\"text-title-large font-weight-bold\">Assets</h2>\n\n            <AppSheet>\n              <v-list-item\n                :href=\"model.zipball_url\"\n                append-icon=\"mdi-download-box-outline\"\n                prepend-icon=\"mdi-folder-zip-outline\"\n                target=\"_blank\"\n                title=\"Source code (zip)\"\n                nav\n                slim\n              />\n\n              <v-divider />\n\n              <v-list-item\n                :href=\"model.tarball_url\"\n                append-icon=\"mdi-download-box-outline\"\n                prepend-icon=\"mdi-folder-zip-outline\"\n                target=\"_blank\"\n                title=\"Source code (tar.gz)\"\n                nav\n                slim\n              />\n            </AppSheet>\n          </div>\n        </template>\n      </template>\n\n      <v-skeleton-loader\n        v-if=\"!model && store.isLoading\"\n        class=\"pa-4\"\n        type=\"heading, article, heading, subtitle, text, sentences\"\n      />\n    </v-card>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\n  // Composables\n  import { version } from 'vuetify'\n\n  // Types\n  import type { Release } from '@/stores/releases'\n\n  const reactions = {\n    '+1': '👍',\n    hooray: '🎉',\n    rocket: '🚀',\n    laugh: '😂',\n    heart: '❤️',\n    eyes: '👀',\n  }\n\n  const { smAndUp } = useDisplay()\n  const { t } = useI18n()\n  const adapter = useDate()\n  const route = useRoute()\n  const router = useRouter()\n  const store = useReleasesStore()\n\n  const autocomplete = shallowRef()\n  const clicked = shallowRef('copy-link')\n  const model = shallowRef<Release>()\n  const search = shallowRef('')\n  let timeout = -1 as any\n\n  const menuProps = computed(() => {\n    return {\n      contentClass: 'notes-autocomplete rounded-b-lg',\n      maxHeight: 300,\n    }\n  })\n\n  const tooltips = computed(() => {\n    return [\n      {\n        color: '#3b5998',\n        icon: clicked.value === 'copied' ? 'mdi-check' : 'mdi-share-variant-outline',\n        async onClick () {\n          await navigator.clipboard.writeText(`${window.location.origin}/getting-started/release-notes/?version=${model.value!.tag_name}`)\n\n          clicked.value = 'copied'\n\n          await wait(1500)\n\n          clicked.value = 'copy-link'\n        },\n        path: clicked.value,\n      },\n      {\n        color: '#738ADB',\n        icon: 'mdi-discord',\n        href: 'https://discord.gg/QHWSAbA',\n        path: 'discuss-on-discord',\n      },\n      {\n        color: '#212121',\n        href: model.value!.html_url,\n        icon: 'mdi-github',\n        path: 'open-github-release',\n      },\n    ]\n  })\n\n  const releases = computed(() => {\n    const releases = store.releases.slice()\n\n    releases.push(null as any)\n\n    return releases\n  })\n\n  const tag = computed(() => (route.query.version ?? `v${version}`) as string)\n\n  const publishedOn = computed(() => {\n    if (!model.value?.published_at) return undefined\n\n    return adapter.format(new Date(model.value.published_at), smAndUp.value ? 'fullDateWithWeekday' : 'normalDateWithWeekday')\n  })\n\n  onBeforeMount(async () => {\n    await store.fetch()\n\n    model.value = await store.find(tag.value)\n  })\n\n  watch(model, val => {\n    const version = val?.tag_name ?? tag.value\n\n    if (!version) return\n\n    router.push({ query: { version } })\n\n    autocomplete.value?.blur()\n  })\n\n  watch(search, onSearch)\n\n  function genEmoji (count: number) {\n    switch (true) {\n      case (count >= 100): return '💫'\n      case (count > 50): return '🔥'\n      case (count > 30): return '🌶️'\n      default: return undefined\n    }\n  }\n\n  async function onSearch (val: string) {\n    clearTimeout(timeout)\n\n    timeout = setTimeout(() => store.find(val), 500)\n  }\n\n  // function timeAgo (string: string): string {\n  //   const date = adapter.toJsDate(adapter.date(string))\n  //   const now = new Date()\n  //   const seconds = Math.floor((now.getTime() - date.getTime()) / 1000)\n\n  //   let interval = seconds / 31536000\n  //   if (interval > 1) return `${Math.floor(interval)} years ago`\n\n  //   interval = seconds / 2592000\n  //   if (interval > 1) return `${Math.floor(interval)} months ago`\n\n  //   interval = seconds / 86400\n  //   if (interval > 1) return `${Math.floor(interval)} days ago`\n\n  //   interval = seconds / 3600\n  //   if (interval > 1) return `${Math.floor(interval)} hours ago`\n\n  //   interval = seconds / 60\n  //   if (interval > 1) return `${Math.floor(interval)} minutes ago`\n\n  //   return `${Math.floor(seconds)} seconds ago`\n  // }\n</script>\n\n<style lang=\"sass\">\n  .notes-autocomplete\n    > .v-list.v-select-list\n      background: transparent !important\n  .releases\n    img\n      max-width: 100%\n</style>\n"
  },
  {
    "path": "packages/docs/src/components/doc/Tabs.vue",
    "content": "<template>\n  <v-tabs\n    v-model=\"model\"\n    class=\"mb-1\"\n    color=\"primary\"\n    height=\"44\"\n  >\n    <slot name=\"tabs\" />\n  </v-tabs>\n\n  <v-window v-model=\"model\">\n    <slot name=\"content\" />\n  </v-window>\n</template>\n\n<script setup>\n  const model = shallowRef()\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/doc/ThemeCard.vue",
    "content": "<template>\n  <a\n    :href=\"product.href\"\n    class=\"text-high-emphasis text-decoration-none\"\n    rel=\"noopener\"\n    target=\"_blank\"\n  >\n    <AppFigure\n      :alt=\"product.title\"\n      :name=\"product.title\"\n      :src=\"product.src\"\n      height=\"230\"\n      max-height=\"230\"\n      min-height=\"230\"\n      cover\n    >\n      <figcaption class=\"d-flex text-title-small align-center justify-center text-capitalize mt-3\">\n        <span v-text=\"product.title\" />\n\n        <v-chip\n          v-if=\"product.price === 0\"\n          class=\"text-uppercase px-1 ms-2\"\n          color=\"primary\"\n          size=\"x-small\"\n          text=\"Free\"\n          label\n        />\n\n        <span\n          v-else-if=\"product.price\"\n          class=\"ms-auto text-body-large font-weight-bold\"\n          v-text=\"`$${product.price}`\"\n        />\n      </figcaption>\n    </AppFigure>\n  </a>\n</template>\n\n<script setup>\n  defineProps({\n    product: {\n      type: Object,\n      default: () => ({}),\n    },\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/doc/ThemeVendor.vue",
    "content": "<template>\n  <v-row v-if=\"vendor\">\n    <v-col\n      v-for=\"product in vendor.products\"\n      :key=\"product.title\"\n      cols=\"12\"\n      sm=\"6\"\n    >\n      <DocThemeCard :product=\"product\" />\n    </v-col>\n\n    <v-col class=\"text-center mb-8\" cols=\"12\">\n      <AppBtn\n        :href=\"vendor.moreUrl\"\n        append-icon=\"mdi-open-in-new\"\n        color=\"primary\"\n        rel=\"noopener noreferrer\"\n        size=\"large\"\n        target=\"_blank\"\n        variant=\"outlined\"\n      >\n        {{ t('see-more-themes-from', { vendor: vendor.name }) }}\n      </AppBtn>\n    </v-col>\n  </v-row>\n</template>\n\n<script setup>\n  const { t } = useI18n()\n  const store = useShopifyStore()\n\n  const props = defineProps({\n    name: {\n      type: String,\n      required: true,\n    },\n  })\n\n  const vendor = computed(() => store.byVendor[props.name])\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/doc/TypographyPreview.vue",
    "content": "<template>\n  <v-sheet class=\"typography-preview\" border rounded>\n    <v-tabs v-model=\"tab\" color=\"primary\" height=\"44\">\n      <v-tab value=\"md3\">MD3 (current)</v-tab>\n      <v-tab value=\"md2\">MD2 (legacy)</v-tab>\n    </v-tabs>\n\n    <v-divider />\n\n    <div class=\"typography-preview__content\">\n      <template v-for=\"(variant, name, i) in variants\" :key=\"name\">\n        <details\n          :class=\"['typography-preview__item', { 'border-t' : i > 0 }]\"\n          :name=\"`typography-${tab}`\"\n        >\n          <summary class=\"typography-preview__summary\">\n            <span\n              :style=\"variant\"\n              class=\"typography-preview__text\"\n            >{{ formatName(name) }}</span>\n            <v-code>.text-{{ name }}</v-code>\n            <v-icon icon=\"mdi-chevron-down\" size=\"20\" />\n          </summary>\n          <div class=\"typography-preview__properties text-mono\">\n            <div\n              v-for=\"(value, prop) in variant\"\n              :key=\"prop\"\n              class=\"typography-preview__property\"\n            >\n              <span class=\"text-medium-emphasis\">{{ formatProp(prop) }}</span>\n              <span>{{ value }}</span>\n            </div>\n          </div>\n        </details>\n      </template>\n    </div>\n  </v-sheet>\n</template>\n\n<script setup lang=\"ts\">\n  import type { CSSProperties } from 'vue'\n  import { computed, ref } from 'vue'\n\n  const tab = ref('md3')\n\n  const md3Variants: Record<string, CSSProperties> = {\n    'display-large': { fontSize: '3.5625rem', lineHeight: 1.1228070175, fontWeight: 400, letterSpacing: '-.0043859649em' },\n    'display-medium': { fontSize: '2.8125rem', lineHeight: 1.1555555556, fontWeight: 400, letterSpacing: 'normal' },\n    'display-small': { fontSize: '2.25rem', lineHeight: 1.2222222222, fontWeight: 400, letterSpacing: 'normal' },\n    'headline-large': { fontSize: '2rem', lineHeight: 1.25, fontWeight: 400, letterSpacing: 'normal' },\n    'headline-medium': { fontSize: '1.75rem', lineHeight: 1.2857142857, fontWeight: 400, letterSpacing: 'normal' },\n    'headline-small': { fontSize: '1.5rem', lineHeight: 1.3333333333, fontWeight: 400, letterSpacing: 'normal' },\n    'title-large': { fontSize: '1.375rem', lineHeight: 1.2727272727, fontWeight: 400, letterSpacing: 'normal' },\n    'title-medium': { fontSize: '1rem', lineHeight: 1.5, fontWeight: 500, letterSpacing: '.009375em' },\n    'title-small': { fontSize: '.875rem', lineHeight: 1.4285714286, fontWeight: 500, letterSpacing: '.0071428571em' },\n    'body-large': { fontSize: '1rem', lineHeight: 1.5, fontWeight: 400, letterSpacing: '.03125em' },\n    'body-medium': { fontSize: '.875rem', lineHeight: 1.4285714286, fontWeight: 400, letterSpacing: '.0178571429em' },\n    'body-small': { fontSize: '.75rem', lineHeight: 1.3333333333, fontWeight: 400, letterSpacing: '.0333333333em' },\n    'label-large': { fontSize: '.875rem', lineHeight: 1.4285714286, fontWeight: 500, letterSpacing: '.0071428571em' },\n    'label-medium': { fontSize: '.75rem', lineHeight: 1.3333333333, fontWeight: 500, letterSpacing: '.0416666667em' },\n    'label-small': { fontSize: '.6875rem', lineHeight: 1.4545454545, fontWeight: 500, letterSpacing: '.0454545455em' },\n  }\n\n  const md2Variants: Record<string, CSSProperties> = {\n    h1: { fontSize: '6rem', lineHeight: 1, fontWeight: 300, letterSpacing: '-.015625em' },\n    h2: { fontSize: '3.75rem', lineHeight: 1, fontWeight: 300, letterSpacing: '-.0083333333em' },\n    h3: { fontSize: '3rem', lineHeight: 1.05, fontWeight: 400, letterSpacing: 'normal' },\n    h4: { fontSize: '2.125rem', lineHeight: 1.175, fontWeight: 400, letterSpacing: '.0073529412em' },\n    h5: { fontSize: '1.5rem', lineHeight: 1.333, fontWeight: 400, letterSpacing: 'normal' },\n    h6: { fontSize: '1.25rem', lineHeight: 1.6, fontWeight: 500, letterSpacing: '.0125em' },\n    'subtitle-1': { fontSize: '1rem', lineHeight: 1.75, fontWeight: 400, letterSpacing: '.009375em' },\n    'subtitle-2': { fontSize: '.875rem', lineHeight: 1.6, fontWeight: 500, letterSpacing: '.0071428571em' },\n    'body-1': { fontSize: '1rem', lineHeight: 1.5, fontWeight: 400, letterSpacing: '.03125em' },\n    'body-2': { fontSize: '.875rem', lineHeight: 1.425, fontWeight: 400, letterSpacing: '.0178571429em' },\n    button: { fontSize: '.875rem', lineHeight: 2.6, fontWeight: 500, letterSpacing: '.0892857143em', textTransform: 'uppercase' },\n    caption: { fontSize: '.75rem', lineHeight: 1.667, fontWeight: 400, letterSpacing: '.0333333333em' },\n    overline: { fontSize: '.75rem', lineHeight: 2.667, fontWeight: 500, letterSpacing: '.1666666667em', textTransform: 'uppercase' },\n  }\n\n  const variants = computed(() => tab.value === 'md3' ? md3Variants : md2Variants)\n\n  function formatName (variant: string) {\n    return variant\n      .replace('-', ' ')\n      .replace(/h(\\d)/, 'headline $1')\n  }\n\n  function formatProp (propName: string) {\n    return propName\n      .replace('fontSize', 'size')\n      .replace('fontWeight', 'weight')\n      .replace(/([A-Z])/g, ' $1')\n      .toLowerCase()\n      .replace(/^\\S/, v => v.toUpperCase())\n  }\n</script>\n\n<style lang=\"sass\">\n.typography-preview\n  overflow: hidden\n\n  &__content\n    max-height: 550px\n    overflow-y: auto\n\n  &__item\n    interpolate-size: allow-keywords\n\n    &::details-content\n      block-size: 0\n      transition: 0.2s ease-in-out\n      transition-property: block-size, content-visibility\n      transition-behavior: allow-discrete\n      overflow: hidden\n\n    &[open]::details-content\n      block-size: auto\n\n    &[open] .v-icon\n      transform: rotate(180deg)\n\n  &__summary\n    display: flex\n    align-items: center\n    gap: 16px\n    padding: 12px 16px\n    cursor: pointer\n    user-select: none\n    list-style: none\n\n    &::marker,\n    &::-webkit-details-marker\n      display: none\n\n  &__text\n    flex: 1\n    min-width: 0\n    white-space: nowrap\n    overflow: hidden\n    text-overflow: ellipsis\n    text-transform: capitalize\n\n  &__properties\n    display: flex\n    flex-wrap: wrap\n    justify-content: space-between\n    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr))\n    gap: 8px\n    padding: 0 16px 16px\n    max-width: 400px\n    font-size: 12px\n\n    > div\n      display: flex\n      flex-direction: column\n      gap: 2px\n</style>\n"
  },
  {
    "path": "packages/docs/src/components/doc/UpNext.vue",
    "content": "<template>\n  <div\n    id=\"up-next\"\n    class=\"d-flex mb-5\"\n  >\n    <router-link\n      v-if=\"(prev && prev.name !== 'home')\"\n      :to=\"prev.path\"\n      class=\"text-decoration-none text-body-large d-inline-flex align-center\"\n    >\n      <v-icon\n        :icon=\"arrows.prev\"\n        class=\"me-1\"\n        color=\"primary\"\n      />\n\n      <span\n        class=\"text-primary\"\n        v-text=\"prev.meta.nav ?? prev.meta.title\"\n      />\n    </router-link>\n\n    <v-spacer />\n\n    <router-link\n      v-if=\"next\"\n      :to=\"next.path\"\n      class=\"text-decoration-none text-body-large d-inline-flex align-center\"\n    >\n      <span\n        class=\"text-primary\"\n        v-text=\"next.meta.nav ?? next.meta.title\"\n      />\n\n      <v-icon\n        :icon=\"arrows.next\"\n        class=\"ms-1\"\n        color=\"primary\"\n      />\n    </router-link>\n  </div>\n</template>\n\n<script setup>\n  const { pages } = useAppStore()\n  const route = useRoute()\n  const path = computed(() => route.path.split('/').slice(2, -1))\n  const routes = computed(() => useRouter().getRoutes())\n  const currentIndex = computed(() => pages.indexOf(path.value.join('/')))\n  const prev = computed(() => {\n    if (currentIndex.value === -1) return false\n\n    const prevPath = rpath(pages[currentIndex.value - 1])\n\n    if (prevPath == null) return false\n\n    return routes.value.find(r => r.path === prevPath)\n  })\n  const next = computed(() => {\n    if (currentIndex.value === -1) return false\n\n    const nextPath = rpath(pages[currentIndex.value + 1])\n\n    return routes.value.find(r => r.path === nextPath)\n  })\n\n  const { isRtl } = useRtl()\n  const arrows = computed(() => ({\n    next: !isRtl ? 'mdi-chevron-left' : 'mdi-chevron-right',\n    prev: !isRtl ? 'mdi-chevron-right' : 'mdi-chevron-left',\n  }))\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/doc/VueJobs.vue",
    "content": "<template>\n  <v-row density=\"comfortable\">\n    <v-col cols=\"12\">\n      <div class=\"d-flex\">\n        <AppTextField\n          v-model=\"search\"\n          :append-inner-icon=\"view ? 'mdi-view-grid-outline' : 'mdi-view-list-outline'\"\n          :placeholder=\"placeholder\"\n          @click:append-inner.stop.prevent=\"view = !view\"\n        />\n      </div>\n    </v-col>\n\n    <v-col\n      v-for=\"job in items\"\n      :key=\"job.id\"\n      :md=\"view ? 6 : undefined\"\n      class=\"d-flex\"\n      cols=\"12\"\n    >\n      <v-card\n        :href=\"job.url\"\n        max-height=\"225\"\n        rel=\"sponsored\"\n        target=\"_blank\"\n        variant=\"flat\"\n        border\n        @click=\"sweClick('jobs', job.title, job.id)\"\n      >\n        <v-list-item\n          :title=\"job.title\"\n          lines=\"two\"\n        >\n          <template #prepend>\n            <v-avatar\n              :class=\"!job.avatar && 'pt-1'\"\n              :color=\"!job.avatar ? 'primary' : undefined\"\n              :image=\"job.avatar\"\n              icon=\"$vuetify\"\n            />\n          </template>\n\n          <template v-if=\"job.locations.length > 0\" #subtitle>\n            <v-icon\n              icon=\"mdi-map-marker-outline\"\n              size=\"14\"\n            />\n\n            {{ job.locations.join(', ') }}\n          </template>\n\n          <template #append>\n            <v-btn\n              class=\"ms-6\"\n              color=\"success\"\n              size=\"small\"\n              style=\"pointer-events: none;\"\n              variant=\"flat\"\n            >\n              {{ t('apply') }}\n\n              <v-icon\n                icon=\"mdi-open-in-new\"\n                size=\"small\"\n                end\n              />\n            </v-btn>\n          </template>\n        </v-list-item>\n\n        <v-card-text class=\"text-medium-emphasis py-0\">\n          <AppMarkdown :content=\"job.description\" />\n        </v-card-text>\n      </v-card>\n    </v-col>\n  </v-row>\n</template>\n\n<script setup>\n  const { jobs } = useJobsStore()\n  const { t } = useI18n()\n  const view = shallowRef(true)\n  const search = shallowRef('')\n  const items = computed(() => {\n    return jobs.filter(job => {\n      if (!search.value) return true\n\n      const title = job.title.toLowerCase()\n      const description = job.description.toLowerCase()\n      const s = search.value.toLowerCase()\n\n      return (title.includes(s) || description.includes(s))\n    })\n  })\n  const placeholder = computed(() => {\n    return t('search-jobs')\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/examples/Example.vue",
    "content": "<template>\n  <v-defaults-provider\n    :defaults=\"{\n      global: { eager: false }\n    }\"\n    scoped\n  >\n    <AppSheet class=\"mb-9\">\n      <v-lazy v-model=\"hasRendered\" min-height=\"44\">\n        <v-toolbar\n          border=\"b\"\n          class=\"px-1\"\n          height=\"44\"\n          flat\n        >\n          <v-fade-transition hide-on-leave>\n            <div v-if=\"showCode\" class=\"d-flex ga-1 px-1\">\n              <v-btn\n                v-for=\"(section, i) of sections\"\n                :key=\"section.name\"\n                :active=\"template === i\"\n                class=\"text-none\"\n                size=\"small\"\n                variant=\"text\"\n                @click=\"template = i\"\n              >\n                <span :class=\"template === i ? 'text-high-emphasis' : 'text-medium-emphasis'\">\n                  {{ upperFirst(section.name) }}\n                </span>\n              </v-btn>\n            </div>\n\n            <div\n              v-else-if=\"user.one.devmode && file\"\n              class=\"text-body-medium ma-1 text-medium-emphasis\"\n            >\n              <v-icon icon=\"mdi-file-tree\" />\n\n              {{ file }}.vue\n            </div>\n          </v-fade-transition>\n\n          <v-spacer />\n\n          <template v-if=\"!preview\">\n            <v-tooltip\n              v-for=\"({ path, ...action }, i) of actions\"\n              :key=\"i\"\n              :disabled=\"xs\"\n              location=\"top\"\n              open-delay=\"500\"\n            >\n              <template #activator=\"{ props: tooltip }\">\n                <v-fade-transition hide-on-leave>\n                  <v-btn\n                    v-show=\"!action.hide\"\n                    :key=\"action.icon\"\n                    class=\"me-1 text-medium-emphasis\"\n                    density=\"comfortable\"\n                    size=\"small\"\n                    variant=\"text\"\n                    v-bind=\"mergeProps(action as any, tooltip)\"\n                  />\n                </v-fade-transition>\n              </template>\n\n              <span>{{ t(path) }}</span>\n            </v-tooltip>\n          </template>\n        </v-toolbar>\n      </v-lazy>\n\n      <div class=\"d-flex flex-column\">\n        <v-expand-transition v-if=\"hasRendered || preview\">\n          <v-window v-show=\"showCode\" v-model=\"template\">\n            <v-window-item\n              v-for=\"(section, i) of sections\"\n              :key=\"section.name\"\n              :eager=\"i === 0 || isEager\"\n            >\n              <v-theme-provider :theme=\"theme\">\n                <AppMarkup\n                  :code=\"section.content\"\n                  :rounded=\"false\"\n                />\n              </v-theme-provider>\n            </v-window-item>\n          </v-window>\n        </v-expand-transition>\n\n        <v-theme-provider\n          :class=\"showCode && !preview && 'border-t'\"\n          :theme=\"theme\"\n          class=\"pa-2 rounded-b\"\n          with-background\n        >\n          <component :is=\"ExampleComponent\" v-if=\"isLoaded\" />\n        </v-theme-provider>\n      </div>\n    </AppSheet>\n  </v-defaults-provider>\n</template>\n\n<script setup lang=\"ts\">\n  // Components\n  import ExampleMissing from '@/components/examples/ExampleMissing.vue'\n\n  // Utilities\n  import { getExample } from 'virtual:examples'\n\n  // Types\n  import type { Component } from 'vue'\n\n  const { xs } = useDisplay()\n  const { t } = useI18n()\n  const user = useUserStore()\n\n  const props = defineProps({\n    inline: Boolean,\n    hideInvert: Boolean,\n    file: {\n      type: String,\n      required: true,\n    },\n    open: Boolean,\n    preview: Boolean,\n  })\n\n  function parseTemplate (target: string, template: string) {\n    const pattern = {\n      composition: /(<script setup>[\\w\\W]*?<\\/script>)/g,\n      options: /(<script>[\\w\\W]*?<\\/script>)/g,\n    }[target] || new RegExp(`(<${target}(.*)?>[\\\\w\\\\W]*<\\\\/${target}>)`, 'g')\n    const parsed = pattern.exec(template)\n\n    return parsed?.[1]\n  }\n\n  const isLoaded = shallowRef(false)\n  const isError = shallowRef(false)\n  const showCode = shallowRef(props.inline || props.open)\n  const template = shallowRef(0)\n  const hasRendered = shallowRef(false)\n  const isEager = shallowRef(false)\n  const copied = shallowRef(false)\n\n  type ExampleComponentType = Component & {\n    playgroundResources?: string\n    playgroundSetup?: string\n    exampleMeta?: string\n  }\n\n  const component = shallowRef<ExampleComponentType | undefined>()\n  const code = shallowRef<string>()\n  const ExampleComponent = computed(() => {\n    return isError.value ? ExampleMissing : isLoaded.value ? component.value : null\n  })\n  const sections = computed(() => {\n    const _code = code.value\n    if (!_code) return []\n    const scriptContent = parseTemplate(user.ecosystem.docs.composition, _code) ??\n      parseTemplate(({ composition: 'options', options: 'composition' } as any)[user.ecosystem.docs.composition], _code)\n\n    return [\n      {\n        name: 'template',\n        language: 'html',\n        content: parseTemplate('template', _code),\n      },\n      {\n        name: 'script',\n        language: 'javascript',\n        content: scriptContent,\n      },\n      {\n        name: 'style',\n        language: 'css',\n        content: parseTemplate('style', _code),\n      },\n    ].filter(v => v.content) as { name: string, content: string, language: string }[]\n  })\n\n  onMounted(importExample)\n\n  async function importExample () {\n    try {\n      const {\n        component: _component,\n        source: _code,\n      } = await getExample(props.file)\n      component.value = _component\n      code.value = _code\n      isLoaded.value = true\n      isError.value = false\n    } catch (e) {\n      console.error(e)\n      isLoaded.value = true\n      isError.value = true\n    }\n  }\n  const parentTheme = useTheme()\n  const _theme = ref<null | string>(null)\n  const theme = computed({\n    get: () => _theme.value ?? parentTheme.name.value,\n    set: val => _theme.value = val,\n  })\n\n  const exampleMeta = computed<Record<string, any>>(() => {\n    const meta = component.value?.exampleMeta\n\n    if (!meta) return {}\n\n    try {\n      return JSON.parse(meta)\n    } catch (e) {\n      console.error('Invalid example meta for', props.file, e)\n      return {}\n    }\n  })\n\n  const playgroundLink = computed(() => {\n    if (!isLoaded.value || isError.value || !component.value) return null\n\n    const resources = JSON.parse(component.value.playgroundResources || '{}')\n    const setup = component.value.playgroundSetup?.trim()\n    return usePlayground(\n      sections.value,\n      resources.css,\n      resources.imports,\n      setup,\n    )\n  })\n\n  const figmaLink = computed(() => {\n    return exampleMeta.value.figma\n  })\n\n  const actions = computed(() => [\n    {\n      icon: theme.value === 'dark' ? 'mdi-white-balance-sunny' : 'mdi-weather-night',\n      path: 'invert-example-colors',\n      onClick: toggleTheme,\n    },\n    {\n      icon: '$vuetify-play',\n      path: 'edit-in-playground',\n      href: playgroundLink.value,\n      target: '_blank',\n    },\n    {\n      icon: '$vuetify-figma',\n      path: 'view-in-figma',\n      href: figmaLink.value,\n      target: '_blank',\n      hide: xs.value || !figmaLink.value,\n    },\n    {\n      icon: 'mdi-github',\n      path: 'view-in-github',\n      href: `https://github.com/vuetifyjs/vuetify/tree/${getBranch()}/packages/docs/src/examples/${props.file}.vue`,\n      target: '_blank',\n      hide: xs.value || !user.one.devmode,\n    },\n    {\n      icon: copied.value ? 'mdi-check' : 'mdi-clipboard-multiple-outline',\n      path: 'copy-example-source',\n      onClick: async () => {\n        await navigator.clipboard.writeText(\n          sections.value.map(section => section.content).join('\\n')\n        )\n\n        copied.value = true\n\n        await wait(2000)\n\n        copied.value = false\n      },\n      hide: xs.value,\n    },\n    {\n      icon: !showCode.value ? 'mdi-code-tags' : 'mdi-chevron-up',\n      path: !showCode.value ? 'view-source' : 'hide-source',\n      onClick: () => {\n        showCode.value = !showCode.value\n      },\n    },\n  ])\n\n  watch(showCode, val => val && (isEager.value = true))\n\n  function toggleTheme () {\n    if (theme.value === parentTheme.name.value) {\n      theme.value = parentTheme.current.value.dark ? 'light' : 'dark'\n    } else {\n      theme.value = parentTheme.name.value\n    }\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/examples/ExampleMissing.vue",
    "content": "<template>\n  <AppMarkdown\n    class=\"v-example-missing text-center\"\n    v-text=\"t('missing', { file })\"\n  />\n</template>\n\n<script setup>\n  defineProps({\n    file: {\n      type: String,\n      required: true,\n    },\n  })\n\n  const { t } = useI18n()\n</script>\n\n<style lang=\"sass\">\n  .v-example-missing > p\n    margin: 0\n</style>\n"
  },
  {
    "path": "packages/docs/src/components/examples/Usage.vue",
    "content": "<template>\n  <AppSheet class=\"mb-4\">\n    <ExamplesVueFile :file=\"`${name}/usage`\" />\n  </AppSheet>\n</template>\n\n<script setup>\n  defineProps({\n    name: String,\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/examples/UsageExample.vue",
    "content": "<template>\n  <div>\n    <v-toolbar\n      border=\"b\"\n      class=\"ps-1\"\n      height=\"44\"\n      flat\n    >\n      <v-slide-group\n        v-model=\"model\"\n        class=\"flex-grow-1\"\n        mandatory\n        show-arrows\n      >\n        <v-slide-group-item value=\"default\">\n          <template #default=\"{ isSelected, toggle }\">\n            <v-btn\n              :active=\"isSelected\"\n              class=\"ma-1 text-none\"\n              size=\"small\"\n              text=\"Default\"\n              variant=\"text\"\n              @click=\"toggle\"\n            />\n          </template>\n        </v-slide-group-item>\n\n        <v-slide-group-item\n          v-for=\"(option, i) in options\"\n          :key=\"i\"\n          :value=\"option\"\n        >\n          <template #default=\"{ isSelected, toggle }\">\n            <v-btn\n              :active=\"isSelected\"\n              :text=\"upperFirst(option)\"\n              class=\"ma-1 text-none\"\n              size=\"small\"\n              variant=\"text\"\n              @click=\"toggle\"\n            />\n          </template>\n        </v-slide-group-item>\n      </v-slide-group>\n\n      <v-tooltip :disabled=\"$vuetify.display.xs\" location=\"top\" open-delay=\"500\">\n        <template #activator=\"{ props: activatorProps }\">\n          <v-btn\n            :href=\"playgroundLink\"\n            class=\"me-1 text-medium-emphasis\"\n            density=\"comfortable\"\n            icon=\"$vuetify-play\"\n            size=\"small\"\n            target=\"_blank\"\n            v-bind=\"activatorProps\"\n          />\n        </template>\n\n        <span>{{ t('edit-in-playground') }}</span>\n      </v-tooltip>\n\n      <v-tooltip :disabled=\"$vuetify.display.xs\" location=\"top\" open-delay=\"500\">\n        <template #activator=\"{ props: activatorProps }\">\n          <v-btn\n            :icon=\"copied ? 'mdi-check' : 'mdi-clipboard-multiple-outline'\"\n            class=\"me-1 text-medium-emphasis\"\n            density=\"comfortable\"\n            size=\"small\"\n            target=\"_blank\"\n            v-bind=\"activatorProps\"\n            @click=\"onClickCopy\"\n          />\n        </template>\n\n        <span>{{ t('copy-example-source') }}</span>\n      </v-tooltip>\n\n      <v-tooltip :disabled=\"$vuetify.display.xs\" location=\"top\" open-delay=\"500\">\n        <template #activator=\"{ props: activatorProps }\">\n          <v-btn\n            :icon=\"!show ? 'mdi-code-tags' : 'mdi-chevron-up'\"\n            class=\"me-1 text-medium-emphasis\"\n            density=\"comfortable\"\n            size=\"small\"\n            v-bind=\"activatorProps\"\n            @click=\"show = !show\"\n          />\n        </template>\n\n        <span>{{ show ? t('hide-source') : t('view-source') }}</span>\n      </v-tooltip>\n    </v-toolbar>\n\n    <v-layout :class=\"['border-b', !show && 'border-opacity-0']\">\n      <v-main>\n        <v-sheet\n          class=\"py-14 px-4 d-flex align-center\"\n          min-height=\"300\"\n          rounded=\"0\"\n        >\n          <div class=\"flex-fill w-100\">\n            <slot />\n          </div>\n        </v-sheet>\n      </v-main>\n\n      <v-navigation-drawer\n        v-if=\"display.smAndUp.value && $slots.configuration\"\n        v-model=\"tune\"\n        location=\"right\"\n        name=\"tune\"\n        width=\"250\"\n        permanent\n        touchless\n      >\n        <v-list>\n          <v-list-subheader :title=\"t('configuration')\" />\n\n          <div class=\"px-4 usage-example\">\n            <v-defaults-provider\n              :defaults=\"{\n                global: {\n                  density: 'compact',\n                  hideDetails: true,\n                  step: 1,\n                }\n              }\"\n            >\n              <slot name=\"configuration\" />\n            </v-defaults-provider>\n          </div>\n        </v-list>\n      </v-navigation-drawer>\n    </v-layout>\n\n    <v-expand-transition>\n      <div v-if=\"show\">\n        <div class=\"pa-2\">\n          <AppMarkup :code=\"code\" />\n        </div>\n\n        <div v-if=\"script\" class=\"pa-2 pt-0\">\n          <AppMarkup :code=\"script\" lang=\"js\" />\n        </div>\n      </div>\n    </v-expand-transition>\n  </div>\n</template>\n\n<script setup>\n  const props = defineProps({\n    name: String,\n    code: String,\n    options: {\n      type: Array,\n      default: () => ([]),\n    },\n    modelValue: {\n      type: [Array, String],\n      default: () => ([]),\n    },\n    script: String,\n  })\n  const emit = defineEmits(['update:modelValue', 'update:tuneValue'])\n\n  const display = useDisplay()\n  const { t } = useI18n()\n\n  const tune = shallowRef(true)\n  const show = shallowRef(true)\n  const copied = shallowRef(false)\n\n  const model = computed({\n    get () {\n      return props.modelValue\n    },\n    set (val) {\n      emit('update:modelValue', val)\n    },\n  })\n  const playgroundLink = computed(() => usePlayground([\n    {\n      name: 'template',\n      language: 'html',\n      content: `<template>\\n<v-app>\\n   <v-container>\\n     ${props.code.replaceAll('\\n', '\\n      ')}\\n   </v-container>\\n </v-app>\\n</template>\\n${props.script || ''}`,\n    },\n  ]))\n\n  // TODO: Mimic how Example handles actions\n\n  const sections = computed(() => {\n    const scriptContent = props.script ? props.script : null\n\n    return [\n      {\n        name: 'template',\n        language: 'html',\n        content: props.code,\n      },\n      {\n        name: 'script',\n        language: 'javascript',\n        content: scriptContent,\n      },\n    ].filter(v => v.content)\n  })\n\n  async function onClickCopy () {\n    await navigator.clipboard.writeText(\n      sections.value.map(section => section.content).join('\\n')\n    )\n\n    copied.value = true\n\n    await wait(2000)\n\n    copied.value = false\n  }\n</script>\n\n<style lang=\"sass\" scoped>\n  .usage-example\n    ::v-deep(.v-text-field)\n      margin-bottom: 8px\n\n  // Hack to get around navigation-drawer default bgColor\n  // TODO: find a better way\n  ::v-deep(.v-select__content .v-list)\n    background: rgb(var(--v-theme-surface)) !important\n</style>\n"
  },
  {
    "path": "packages/docs/src/components/examples/VueFile.vue",
    "content": "<template>\n  <component\n    :is=\"component\"\n    v-if=\"component\"\n  />\n</template>\n\n<script setup>\n  // Utilities\n  import { getExample } from 'virtual:examples'\n\n  const props = defineProps({\n    file: {\n      type: String,\n      required: true,\n    },\n  })\n\n  const component = shallowRef()\n\n  onBeforeMount(load)\n\n  async function load () {\n    try {\n      const { component: example } = await getExample(props.file)\n      component.value = example\n    } catch (e) {\n      console.error(e)\n    }\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/features/BreakpointsTable.vue",
    "content": "<template>\n  <AppTable>\n    <AppCaption class=\"pa-4\">{{ t('breakpoints-table.caption') }}</AppCaption>\n\n    <thead>\n      <tr class=\"text-start\">\n        <th v-for=\"header in headers\" :key=\"header\">{{ t(header) }}</th>\n      </tr>\n    </thead>\n\n    <tbody>\n      <tr\n        v-for=\"breakpoint in breakpoints\"\n        :key=\"breakpoint.device\"\n      >\n        <td>\n          <v-icon\n            :icon=\"breakpoint.icon\"\n            color=\"medium-emphasis\"\n            start\n          />\n\n          <span>{{ t(breakpoint.device) }}</span>\n        </td>\n\n        <td>\n          <strong v-text=\"breakpoint.code\" />\n        </td>\n\n        <td>{{ t(breakpoint.type) }}</td>\n\n        <td>{{ breakpoint.range }}</td>\n      </tr>\n    </tbody>\n\n    <tfoot>\n      <tr>\n        <td\n          class=\"text-end text-medium-emphasis\"\n          colspan=\"4\"\n        >\n          <small class=\"d-block me-n1 mb-n1\">\n            <a\n              class=\"text-decoration-none d-inline-flex align-center\"\n              href=\"https://m3.material.io/foundations/layout/applying-layout/window-size-classes\"\n              rel=\"noopener noreferrer\"\n              target=\"_blank\"\n            >\n              <v-icon\n                class=\"me-1\"\n                icon=\"mdi-material-design\"\n                size=\"small\"\n                style=\"color: inherit;\"\n              />\n\n              {{ t('breakpoints-table.spec') }}\n            </a>\n          </small>\n        </td>\n      </tr>\n    </tfoot>\n  </AppTable>\n</template>\n\n<script setup>\n  const breakpoints = [\n    {\n      icon: 'mdi-cellphone',\n      device: 'extra-small',\n      code: 'xs',\n      type: 'breakpoints-table.small-to-large-handset',\n      range: '< 600px',\n    },\n    {\n      icon: 'mdi-tablet',\n      device: 'small',\n      code: 'sm',\n      type: 'breakpoints-table.small-to-medium-tablet',\n      range: '600px > < 840px',\n    },\n    {\n      icon: 'mdi-laptop',\n      device: 'medium',\n      code: 'md',\n      type: 'breakpoints-table.large-tablet-to-laptop',\n      range: '840px > < 1145px',\n    },\n    {\n      icon: 'mdi-monitor-small',\n      device: 'large',\n      code: 'lg',\n      type: 'breakpoints-table.desktop',\n      range: '1145px > < 1545px',\n    },\n    {\n      icon: 'mdi-monitor',\n      device: 'extra-large',\n      code: 'xl',\n      type: 'breakpoints-table.large-to-extra-large',\n      range: '1545px > < 2138px',\n    },\n    {\n      icon: 'mdi-monitor-screenshot',\n      device: 'extra-extra-large',\n      code: 'xxl',\n      type: 'breakpoints-table.extra-large-to-extra-extra-large',\n      range: '> 2138px',\n    },\n  ]\n\n  const headers = [\n    'device',\n    'code',\n    'type',\n    'range',\n  ]\n\n  const { t } = useI18n()\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/features/ColorPalette.vue",
    "content": "<template>\n  <section id=\"material-colors\" class=\"mb-4\">\n    <AppTextField\n      v-model=\"search\"\n      class=\"mb-4\"\n    />\n\n    <v-container\n      class=\"pa-0\"\n    >\n      <v-row>\n        <v-col\n          v-for=\"(color, key) in computedColors\"\n          :key=\"key\"\n          cols=\"12\"\n          lg=\"4\"\n          md=\"6\"\n        >\n          <v-card\n            :color=\"key\"\n            elevation=\"0\"\n            rounded=\"0\"\n          >\n            <v-card-text>\n              <span\n                class=\"text-title-large\"\n                v-text=\"key\"\n              />\n            </v-card-text>\n          </v-card>\n\n          <v-card\n            v-for=\"(subColor, key2) in color\"\n            :key=\"key2\"\n            :color=\"convertToClass(key, key2)\"\n            elevation=\"0\"\n            rounded=\"0\"\n          >\n            <v-card-text>\n              <v-row>\n                <v-col\n                  class=\"text-body-small\"\n                  cols=\"7\"\n                >\n                  {{ convertToClass(key, key2) }}\n                </v-col>\n\n                <v-col\n                  class=\"text-right\"\n                  cols=\"5\"\n                >\n                  <span\n                    v-if=\"subColor !== 'transparent'\"\n                    v-text=\"subColor.toUpperCase()\"\n                  />\n                </v-col>\n              </v-row>\n            </v-card-text>\n          </v-card>\n        </v-col>\n      </v-row>\n    </v-container>\n  </section>\n</template>\n\n<script setup>\n  import colors from 'vuetify/util/colors'\n\n  const search = shallowRef('')\n\n  const computedColors = computed(() => {\n    const _colors = {}\n    const _search = search.value.toLowerCase()\n\n    Object.keys(colors).forEach(key => {\n      const kebabKey = kebabCase(key).toLowerCase()\n\n      if (kebabKey.indexOf(_search) > -1) {\n        _colors[kebabKey] = colors[key]\n      }\n    })\n\n    return _colors\n  })\n\n  function convertToClass (base, variant) {\n    if (variant === 'base') return base\n\n    const lastChar = variant.at(-1)\n\n    if (isNaN(Number(lastChar))) return variant\n\n    return `${base}-${variant.slice(0, -1)}-${lastChar}`\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/features/SassApi.vue",
    "content": "<template>\n  <v-autocomplete\n    v-model=\"model\"\n    :custom-filter=\"customFilter\"\n    :items=\"variables\"\n    base-color=\"disabled\"\n    item-value=\"id\"\n    placeholder=\"Search SASS API\"\n    prepend-inner-icon=\"mdi-database-search-outline\"\n    variant=\"outlined\"\n    auto-select-first\n    chips\n    clearable\n    item-props\n    multiple\n    persistent-clear\n    return-object\n  >\n    <template #chip=\"{ props }\">\n      <v-chip\n        v-bind=\"props\"\n        color=\"primary\"\n        variant=\"flat\"\n        label\n      />\n    </template>\n  </v-autocomplete>\n\n  <AppMarkup\n    v-if=\"model.length > 0\"\n    :code=\"code\"\n    class=\"mb-6\"\n    language=\"scss\"\n    resource=\"src/styles/main.scss\"\n  />\n</template>\n\n<script setup>\n  const files = import.meta.glob('../../../../api-generator/dist/api/*.json')\n\n  const variables = ref([])\n  const model = shallowRef([])\n\n  const code = computed(() => {\n    const $parsed = model.value?.reduce((acc, variable) => {\n      const varString = `  ${variable.title}: ${variable.default.replaceAll('\\n', '\\n  ')}`\n      acc[variable.use].push(varString)\n      return acc\n    }, { vuetify: [], 'vuetify/settings': [] })\n    const useList = []\n\n    for (const [use, value] of Object.entries($parsed)) {\n      if (value.length) {\n        useList.push(`@use '${use}' with (\\n${value.join(',\\n')},\\n);`)\n      }\n    }\n    return useList.join('\\n\\n')\n  })\n\n  async function getVariables (name) {\n    return import(`../../../../api-generator/dist/api/${name}.json`)\n  }\n\n  function customFilter (value, query, item) {\n    console.log(value)\n    return (\n      item.props.title.toLowerCase().indexOf(query.toLowerCase()) > -1 ||\n      item.props.subtitle.toLowerCase().indexOf(query.toLowerCase()) > -1\n    )\n  }\n\n  async function fetchApiData () {\n    try {\n      for (const file in files) {\n        const name = file.split('/').pop().split('.')[0]\n\n        if (!name.startsWith('V') && name !== 'globals') continue\n\n        const component = await getVariables(name)\n\n        for (const variable in component.sass) {\n          variables.value.push({\n            default: component.sass[variable]?.default || null,\n            title: variable,\n            subtitle: name,\n            value: `${variable}-${name}`,\n            use: component.sass[variable]?.use || null,\n          })\n        }\n      }\n    } catch (err) {}\n  }\n\n  fetchApiData()\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/getting-started/WireframeExamples.vue",
    "content": "<template>\n  <v-row>\n    <v-col\n      v-for=\"([name, wireframe], i) in wireframes\"\n      :key=\"i\"\n      cols=\"12\"\n      lg=\"4\"\n      md=\"6\"\n    >\n      <router-link\n        :to=\"rpath(`/wireframes/${wireframe}/`)\"\n        class=\"text-decoration-none\"\n        rel=\"nofollow noopener\"\n        target=\"_blank\"\n      >\n        <AppFigure\n          :alt=\"`${name} layout`\"\n          :aspect-ratio=\"16/9\"\n          :src=\"`https://cdn.vuetifyjs.com/docs/images/wireframes/${wireframe}.svg`\"\n          :title=\"name\"\n          class=\"border\"\n        />\n      </router-link>\n    </v-col>\n  </v-row>\n</template>\n\n<script setup>\n  const wireframes = [\n    'Baseline',\n    'Extended toolbar',\n    'System bar',\n    'Inbox',\n    'Constrained',\n    'Side navigation',\n    'Three column',\n    'Discord',\n    'Steam',\n  ].map(wireframe => ([wireframe, kebabCase(wireframe)]))\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/home/Blogs.vue",
    "content": "<template>\n  <v-responsive class=\"py-16\">\n    <HomeCommonGradient opacity-class=\"opacity-10\" />\n\n    <v-container class=\"pt-0\">\n      <HomeCommonTitle\n        :description=\"t('home.blogs.description')\"\n        :subtitle=\"t('home.blogs.subtitle')\"\n        :title=\"t('home.blogs.title')\"\n        class=\"mb-16\"\n      />\n\n      <v-row class=\"text-left align-center justify-space-between\">\n        <v-col v-if=\"latestBlogs.length\" cols=\"12\" md=\"7\">\n          <v-card\n            v-for=\"(blog, index) in latestBlogs\"\n            :key=\"index\"\n            :class=\"{ 'mb-8': index !== latestBlogs.length - 1 }\"\n            class=\"pr-10 overflow-hidden\"\n            color=\"transparent\"\n            flat\n          >\n\n            <v-card-subtitle class=\"pt-3 pb-1 text-title-small pl-0 text-medium-emphasis d-inline-flex align-center ga-1\">\n              <v-icon icon=\"$calendar\" size=\"small\" />\n\n              {{ blog.date }}\n            </v-card-subtitle>\n\n            <v-card-title class=\"text-pre-wrap pl-0 pt-0\">\n              <router-link :to=\"blog.to\" class=\"text-high-emphasis d-inline-flex\">\n                {{ blog.title }}\n              </router-link>\n            </v-card-title>\n\n            <div class=\"text-medium-emphasis text-body-large pl-0\">\n              {{ blog.shortDescription }}\n            </div>\n\n            <!-- <v-img\n              v-if=\"blog.image\"\n              :src=\"blog.image\"\n              gradient=\"to bottom, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0)\"\n              max-height=\"150\"\n              rounded=\"lg\"\n              width=\"100%\"\n              cover\n            /> -->\n\n            <v-card-text class=\"pl-0 pt-2\">\n              <div class=\"d-flex align-center ga-2 text-title-small text-medium-emphasis\">\n                <v-avatar :image=\"blog.avatar\" size=\"32\" />\n\n                {{ blog.author }}\n\n                <v-spacer />\n\n                <v-btn\n                  :text=\"t('home.blogs.read-more')\"\n                  :to=\"blog.to\"\n                  append-icon=\"mdi-page-next\"\n                  class=\"text-none px-0 ml-5\"\n                  color=\"primary\"\n                  variant=\"plain\"\n                />\n              </div>\n            </v-card-text>\n          </v-card>\n        </v-col>\n\n        <v-col cols=\"12\" md=\"5\">\n          <v-card\n            v-for=\"(item , index) in remainingBlogs\"\n            :key=\"index\"\n            class=\"d-flex flex-column\"\n            color=\"transparent\"\n            rounded=\"lg\"\n            flat\n          >\n            <v-card-subtitle class=\"pt-5 text-body-small text-medium-emphasis d-inline-flex align-center ga-1\">\n              <v-icon icon=\"mdi-calendar\" size=\"16\" /> {{ item.date }}\n            </v-card-subtitle>\n\n            <v-card-title class=\"d-inline-block text-body-large pt-1\">\n              <router-link :to=\"item.to\" class=\"text-high-emphasis d-inline-flex\">\n                {{ item.title }}\n              </router-link>\n            </v-card-title>\n\n            <v-card-text\n              :class=\"{ 'text-truncate': smAndDown }\"\n              class=\"text-medium-emphasis text-body-medium py-0\"\n            >\n              {{ item.shortDescription?.substring(0, 115) + (item.shortDescription?.length > 300 ? '...' : '') }}\n            </v-card-text>\n\n            <v-card-text class=\"text-body-medium text-medium-emphasis pt-2\">\n              <div class=\"d-flex align-center ga-2 text-body-medium text-medium-emphasis\">\n                <v-avatar :image=\"item.avatar\" size=\"22\" />\n\n                {{ item.author }}\n\n                <v-spacer />\n\n                <v-btn\n                  :text=\"t('home.blogs.read-more')\"\n                  :to=\"item.to\"\n                  append-icon=\"mdi-page-next\"\n                  class=\"text-none px-0 ml-5\"\n                  color=\"primary\"\n                  size=\"small\"\n                  variant=\"plain\"\n                />\n              </div>\n            </v-card-text>\n\n            <v-divider v-if=\"index !== remainingBlogs.length - 1\" />\n          </v-card>\n        </v-col>\n      </v-row>\n\n      <v-btn\n        :aria-label=\"t('home.blogs.read-more-posts')\"\n        :text=\"t('home.blogs.read-more-posts')\"\n        :to=\"rpath('/blog/')\"\n        append-icon=\"mdi-open-in-new\"\n        class=\"text-none mt-10\"\n        color=\"primary\"\n        rel=\"noopener noreferrer\"\n        rounded=\"lg\"\n        size=\"large\"\n        target=\"_blank\"\n        variant=\"flat\"\n      />\n    </v-container>\n  </v-responsive>\n</template>\n\n<script setup lang=\"ts\">\n  const { t } = useI18n()\n  const { smAndDown } = useDisplay()\n\n  const items = [\n    {\n      title: 'February 2026 Update',\n      image: 'https://cdn.vuetifyjs.com/docs/images/blog/february-2026-update/february-hero.png',\n      shortDescription: 'February marks Vuetify\\'s most significant milestone—the stable release of Vuetify 4.0.0 (Revisionist) with CSS layers, MD3 design system, and unstyled component foundations. The Vuetify CLI hit v1.0.0, VAvatarGroup shipped as a new component, and Vuetify0 gained createDataTable and Breadcrumbs composables across 390 commits and 68 merged PRs...',\n      date: 'March 9, 2026',\n      author: 'John Leider',\n      avatar: 'https://cdn.vuetifyjs.com/docs/images/team/john.png',\n      to: rpath('/blog/february-2026-update'),\n    },\n    {\n      title: 'Build with Vite and TailwindCSS v4',\n      shortDescription: `In the previous article we explored integrating UnoCSS with Vuetify v3 and Nuxt. This time we take a more direct route: pairing Vuetify v4 with TailwindCSS v4 on a plain Vite setup with both running as Vite plugins. Vuetify v4 ships with CSS layers enabled by default, which makes integrating TailwindCSS significantly smoother than before...`,\n      date: 'February 16, 2026',\n      author: 'Jacek Czarniecki',\n      avatar: 'https://cdn.vuetifyjs.com/docs/images/team/j-sek.png',\n      to: rpath('/blog/building-with-vite-and-tailwindcss'),\n    },\n    {\n      title: 'January 2026 Update',\n      image: 'https://cdn.vuetifyjs.com/docs/images/blog/january-2026-update/january-hero.png',\n      shortDescription: 'January delivered Vuetify 4.0.0-beta.0—the first beta of our next major version—featuring MD3 typography, elevation levels, and a complete grid system overhaul. VCommandPalette lands in labs, Vuetify0 hits v0.1.0 with new Tabs, Radio, and Checkbox components, and the CLI shipped 31 releases with a new analyze command...',\n      date: 'February 11, 2026',\n      author: 'John Leider',\n      avatar: 'https://cdn.vuetifyjs.com/docs/images/team/john.png',\n      to: rpath('/blog/january-2026-update'),\n    },\n    {\n      title: 'December 2025 Update',\n      image: 'https://cdn.vuetifyjs.com/docs/images/blog/december-2025-update/december-hero.png',\n      shortDescription: 'December was our most productive month of 2025 with 522 commits across 16 repositories. The month delivered Vuetify 4.0.0-alpha.0 with CSS layers, six v3.11.x patches, the Vuetify CLI public release, Google OAuth for Vuetify One, PWA support across all ecosystem products, and 6 Vuetify0 releases with new composables including usePagination, useClickOutside, and useVirtual...',\n      date: 'January 12, 2026',\n      author: 'John Leider',\n      avatar: 'https://cdn.vuetifyjs.com/docs/images/team/john.png',\n      to: rpath('/blog/december-2025-update'),\n    },\n    {\n      title: 'Vuetify Project baseline with Nuxt and UnoCSS',\n      shortDescription: `Let's explore a lean, production-ready setup for Nuxt application that combines Vuetify 3 with UnoCSS. By disabling Vuetify's default CSS bundles (basic colors and utility classes) and generating only the styles actually used, the resulting CSS footprint shrinks dramatically. We will ensure the project foundation works with themes, typography, and breakpoints without compromises...`,\n      date: 'December 22, 2025',\n      author: 'Jacek Czarniecki',\n      avatar: 'https://cdn.vuetifyjs.com/docs/images/team/j-sek.png',\n      to: rpath('/blog/building-with-nuxt-and-unocss'),\n    },\n    {\n      title: 'November 2025 Update',\n      image: 'https://cdn.vuetifyjs.com/docs/images/blog/november-2025-update/november-hero.png',\n      shortDescription: 'November delivered Vuetify v3.11.0 (Harbinger) with VCalendar and VHotkey promoted from labs, new VTimePicker input variant, VDatePicker MD3 improvements, and significant CLI progress. J-Sek contributed an impressive 14 PRs while the v0 project hit 109 commits across 5 releases...',\n      date: 'December 10, 2025',\n      author: 'John Leider',\n      avatar: 'https://cdn.vuetifyjs.com/docs/images/team/john.png',\n      to: rpath('/blog/november-2025-update'),\n    },\n    {\n      title: 'October 2025 Update',\n      image: 'https://cdn.vuetifyjs.com/docs/images/blog/october-2025-update/october-hero.png',\n      shortDescription: `October focused on refinement and reliability, delivering critical accessibility improvements with enhanced focus trap functionality, optimized VDataTable performance for large datasets, and refined components across the board. The month also saw the launch of Vuetify Link, our new URL shortening service, and significant updates to the Vuetify MCP server with HTTP transport support. We made substantial progress on v0 composables, laying the groundwork for Vuetify 4.0...`,\n      date: 'Nov 11, 2025',\n      author: 'John Leider',\n      avatar: 'https://cdn.vuetifyjs.com/docs/images/team/john.png',\n      to: rpath('/blog/october-2025-update'),\n    },\n    {\n      title: 'September 2025 Update',\n      image: 'https://cdn.vuetifyjs.com/docs/images/blog/september-2025-update/september-hero.png',\n      shortDescription: `September marks significant progress as we assemble the building blocks for Vuetify's next phase. From revolutionary design-to-development workflows with our new Figma UI Kit to foundational v0 composables, September has been about connecting the pieces that will define the future of Vue development. This update includes the release of v3.10.0 (Argo), updated Figma UI Kit, new Vuetify0 composables, and over 60 bug fixes and features...`,\n      date: 'Oct 12, 2025',\n      author: 'John Leider',\n      avatar: 'https://cdn.vuetifyjs.com/docs/images/team/john.png',\n      to: rpath('/blog/september-2025-update'),\n    },\n    {\n      title: 'August 2025 Update',\n      image: 'https://cdn.vuetifyjs.com/docs/images/blog/august-2025-update/august-hero.png',\n      shortDescription: `August marks a pivotal moment in Vuetify's evolution as we prepare to release the pre-alpha of Vuetify0 (v0), launch our redesigned issues page, and continue delivering powerful components and improvements. This month brings exciting developments including the \"Mastering Vuetify Theming\" webinar recap, VEditor final testing phase, free premium themes for personal use, and significant framework updates with 87 merged pull requests...`,\n      date: 'Sep 9, 2025',\n      author: 'John Leider',\n      avatar: 'https://cdn.vuetifyjs.com/docs/images/team/john.png',\n      to: rpath('/blog/august-2025-update'),\n    },\n    {\n      title: 'July 2025 Update',\n      image: 'https://cdn.vuetifyjs.com/docs/images/blog/july-2025-update/july-hero.png',\n      shortDescription: 'July was a month of significant advancements in the Vuetify ecosystem, highlighted by the release of v3.9.0 (Zealot) and the promotion of VTreeview and VTimePicker from labs to core components. This update also includes a focus on component stability, bug fixes, and developer experience improvements, with subsequent patches up to v3.9.3...',\n      date: 'August 6, 2025',\n      author: 'John Leider',\n      avatar: 'https://cdn.vuetifyjs.com/docs/images/team/john.png',\n      to: rpath('/blog/july-2025-update'),\n    },\n  ]\n\n  const latestBlogs = computed(() => smAndDown.value ? [] : items.slice(0, 2))\n  const remainingBlogs = computed(() => smAndDown.value ? items.slice(0, 4) : items.slice(2, 6))\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/home/Common/Card.vue",
    "content": "<template>\n  <v-card\n    border=\"primary md\"\n    class=\"pa-6 d-md-flex flex-column h-100\"\n    elevation=\"0\"\n    rounded=\"xl\"\n    link\n  >\n    <HomeCommonGradient color=\"primary\" opacity-class=\"opacity-30\" />\n\n    <v-img\n      v-if=\"props.image\"\n      :src=\"props.image\"\n      class=\"mx-auto mb-3\"\n      max-height=\"80\"\n      width=\"120\"\n    />\n\n    <div>\n      <h6 v-if=\"props.title\" class=\"text-body-large font-weight-bold mb-2\">\n        {{ props.title }}\n      </h6>\n\n      <p\n        v-if=\"props.description\"\n        class=\"text-medium-emphasis text-body-medium text-center mb-0 mt-3 my-md-0\"\n        style=\"line-height: 1.6;\"\n      >\n        {{ props.description }}\n      </p>\n    </div>\n  </v-card>\n</template>\n\n<script setup lang=\"ts\">\n  const props = defineProps({\n    image: {\n      type: String,\n      default: undefined,\n    },\n    description: {\n      type: String,\n      default: undefined,\n    },\n    title: {\n      type: String,\n      default: undefined,\n    },\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/home/Common/Gradient.vue",
    "content": "<template>\n  <div class=\"v-bg\">\n    <div\n      :class=\"{\n        [`bg-${props.color || defaultColor}`]: true,\n        [props.opacityClass]: true,\n      }\"\n      :style=\"{ clipPath }\"\n      aria-hidden=\"true\"\n    />\n  </div>\n</template>\n\n<script setup lang=\"ts\">\n  type Position = 'top' | 'bottom' | 'center'\n\n  const theme = useTheme()\n\n  const props = defineProps({\n    color: String,\n    opacityClass: {\n      type: String,\n      default: 'opacity-20',\n    },\n    position: {\n      type: String as PropType<Position>,\n      default: 'top',\n    },\n  })\n\n  const defaultColor = computed(() => {\n    return theme.current.value.dark ? 'grey-darken-3' : 'blue-grey-lighten-3'\n  })\n\n  const clipPath = computed(() => {\n    const paths: Record<Position, string> = {\n      top: 'polygon(0% 0%, 100% 0%, 100% 40%, 0% 40%)',\n      bottom: 'polygon(0% 60%, 100% 60%, 100% 100%, 0% 100%)',\n      center: 'polygon(0% 35%, 100% 35%, 100% 65%, 0% 65%)',\n    }\n    return paths[props.position]\n  })\n</script>\n\n<style scoped>\n@layer base {\n  .v-bg {\n    filter: blur(100px);\n    pointer-events: none;\n    position: absolute;\n    top: 0;\n    right: 0;\n    bottom: 0;\n    left: 0;\n  }\n\n  .v-bg > div {\n    overflow: hidden;\n    height: 100%;\n    width: 100%;\n    background: rgb(var(--v-theme-primary));\n    z-index: -10;\n  }\n}\n</style>\n"
  },
  {
    "path": "packages/docs/src/components/home/Common/Marquee.vue",
    "content": "<template>\n  <div :ref=\"containerResizeRef\" class=\"marquee\" @focusout=\"onFocusOut\">\n    <div :ref=\"contentResizeRef\" class=\"marquee-content\">\n      <div\n        v-for=\"(item, index) in props.items\"\n        :key=\"index\"\n        class=\"marquee-item\"\n      >\n        <slot :item=\"item\" />\n      </div>\n    </div>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\n  // @ts-expect-error\n  import { useResizeObserver } from 'vuetify/lib/composables/resizeObserver'\n\n  const props = defineProps({\n    items: {\n      type: Array as PropType<any[]>,\n      required: true,\n    },\n  })\n\n  const shadowSize = 60 // px\n  const { resizeRef: containerResizeRef } = useResizeObserver(onResize)\n  const { resizeRef: contentResizeRef } = useResizeObserver(onResize)\n  const shift = shallowRef(-50) // percentage\n  const shiftTime = shallowRef(30) // seconds\n  const shiftSpeed = 35 // px per second\n\n  function onResize () {\n    const containerWidth = containerResizeRef.value.offsetWidth - 2 * shadowSize\n    const contentWidth = contentResizeRef.value.offsetWidth\n\n    const shiftPercentage = containerWidth / contentWidth - 1\n    shift.value = Math.min(0, Math.round(shiftPercentage * 100))\n\n    const shiftExact = contentWidth - containerWidth\n    shiftTime.value = Math.max(0, Math.round(shiftExact / shiftSpeed))\n  }\n\n  function onFocusOut (e: FocusEvent) {\n    (e.currentTarget as HTMLElement).scrollLeft = 0\n  }\n</script>\n\n<style scoped>\n.marquee {\n  overflow: hidden;\n  white-space: nowrap;\n  padding: 4px calc(v-bind(shadowSize) * 1px);\n  position: relative;\n  width: 100%;\n}\n\n.marquee::before,\n.marquee::after {\n  content: '';\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  width: calc(v-bind(shadowSize) * 1px);\n  z-index: 2;\n  pointer-events: none;\n}\n\n.marquee::before {\n  left: 0;\n  background: linear-gradient(to right, rgb(var(--v-theme-background)), transparent);\n}\n\n.marquee::after {\n  right: 0;\n  background: linear-gradient(to left, rgb(var(--v-theme-background)), transparent);\n}\n\n.marquee-content {\n  display: inline-flex;\n  align-items: center;\n  animation: scroll calc(v-bind(shiftTime) * 1s) linear infinite alternate;\n  gap: 2rem;\n}\n\n.marquee:has(.marquee-content:focus-within) {\n  .marquee-content {\n    animation-play-state: paused;\n  }\n\n  &::before,\n  &::after {\n    display: none;\n  }\n}\n\n.marquee-item {\n  flex-shrink: 0;\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n}\n\n@keyframes scroll {\n  0% {\n    transform: translateX(calc(1% * v-bind(shift)));\n  }\n  100% {\n    transform: translateX(0);\n  }\n}\n</style>\n"
  },
  {
    "path": "packages/docs/src/components/home/Common/Title.vue",
    "content": "<template>\n  <div>\n    <slot name=\"top\" />\n\n    <slot name=\"subtitle\">\n      <p v-if=\"props.subtitle\" class=\"text-primary font-weight-bold mb-3\">\n        {{ props.subtitle }}\n      </p>\n    </slot>\n\n    <h4 class=\"text-headline-large font-weight-bold mb-5 mt-0\">\n      {{ props.title }}\n    </h4>\n\n    <v-responsive class=\"mx-auto\" max-width=\"700\">\n      <h6 class=\"text-title-large font-weight-regular text-medium-emphasis my-0\">\n        {{ props.description }}\n      </h6>\n    </v-responsive>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\n  const props = defineProps({\n    title: {\n      type: String,\n      required: true,\n    },\n    subtitle: {\n      type: String,\n      default: undefined,\n    },\n    description: {\n      type: String,\n      required: true,\n    },\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/home/Discord.vue",
    "content": "<template>\n  <v-sheet color=\"#5662f6\">\n    <v-container class=\"pa-6 text-left\">\n      <v-row class=\"justify-center\">\n        <v-col\n          class=\"pa-6 pa-md-12 text-center\"\n          cols=\"12\"\n        >\n          <v-icon class=\"mb-5\" size=\"60\">\n            mdi-discord\n          </v-icon>\n\n          <h4 class=\"text-headline-large font-weight-bold mb-5 mt-0\">\n            {{ t('home.discord.title') }}\n          </h4>\n\n          <p class=\"text-title-large font-weight-regular mb-6 w-100 w-md-50 mx-auto\">\n            {{ t('home.discord.description') }}\n          </p>\n\n          <v-btn\n            :text=\"t('home.discord.join')\"\n            append-icon=\"mdi-open-in-new\"\n            class=\"mr-4 text-none\"\n            href=\"https://community.vuetifyjs.com/\"\n            rel=\"noopener noreferrer\"\n            rounded=\"lg\"\n            size=\"large\"\n            target=\"_blank\"\n            variant=\"outlined\"\n          />\n        </v-col>\n      </v-row>\n    </v-container>\n  </v-sheet>\n</template>\n\n<script setup lang=\"ts\">\n  const { t } = useI18n()\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/home/Ecosystem.vue",
    "content": "<template>\n  <v-responsive class=\"py-15\">\n    <HomeCommonGradient opacity-class=\"opacity-10\" />\n\n    <v-container>\n      <HomeCommonTitle\n        :description=\"t('home.ecosystem.description')\"\n        :subtitle=\"t('home.ecosystem.subtitle')\"\n        :title=\"t('home.ecosystem.title')\"\n        class=\"mb-10\"\n      >\n\n        <template #top>\n          <v-img :src=\"`https://cdn.vuetifyjs.com/docs/images/one/logos/vuetify.png`\" class=\"mb-4\" height=\"64\" />\n        </template>\n      </HomeCommonTitle>\n\n      <HomeCommonMarquee :items=\"features\" class=\"my-4\">\n        <template #default=\"{ item }\">\n          <a :href=\"item.href\" :title=\"`Visit ${item.href}`\" target=\"_blank\">\n            <v-img\n              :alt=\"item.image\"\n              :src=\"`https://cdn.vuetifyjs.com/docs/images/one/logos/${item.image}-logo-${theme.current.value.dark ? 'dark' : 'light'}.png`\"\n              height=\"40\"\n              width=\"150\"\n              contain\n            />\n          </a>\n        </template>\n      </HomeCommonMarquee>\n    </v-container>\n  </v-responsive>\n</template>\n\n<script setup lang=\"ts\">\n  const { t } = useI18n()\n  const theme = useTheme()\n  const features = computed(() => [\n    {\n      href: 'https://issues.vuetifyjs.com',\n      image: 'vissues',\n    },\n    {\n      href: 'https://github.com/vuetifyjs/vuetify-loader',\n      image: 'vloader',\n    },\n    {\n      href: 'https://store.vuetifyjs.com',\n      image: 'vstore',\n    },\n    {\n      href: 'https://studio.vuetifyjs.com',\n      image: 'vstudio',\n    },\n    {\n      href: 'https://bin.vuetifyjs.com',\n      image: 'vbin',\n    },\n    {\n      href: 'https://link.vuetifyjs.com',\n      image: 'vlink',\n    },\n    {\n      href: 'https://store.vuetifyjs.com/products/vuetify-ui-kit-figma',\n      image: 'vuikit',\n    },\n    {\n      href: 'https://play.vuetifyjs.com',\n      image: 'vplay',\n    },\n    {\n      href: 'https://snips.vuetifyjs.com',\n      image: 'vsnips',\n    },\n    {\n      href: 'https://github.com/vuetifyjs/mcp/',\n      image: 'vmcp',\n    },\n    {\n      href: 'https://github.com/vuetifyjs/cli/',\n      image: 'vcli',\n    },\n    {\n      href: 'https://github.com/vuetifyjs/eslint-config-vuetify',\n      image: 'veslconfig',\n    },\n    {\n      href: 'https://github.com/vuetifyjs/eslint-plugin-vuetify',\n      image: 'veslplugin',\n    },\n    {\n      href: 'https://github.com/vuetifyjs/unocss-preset-vuetify',\n      image: 'vunopreset',\n    },\n    {\n      href: 'https://vuetifyjs.com/one',\n      image: 'vone',\n    },\n    {\n      href: 'https://github.com/vuetifyjs/create',\n      image: 'vcreate',\n    },\n    {\n      href: 'https://0.vuetifyjs.com',\n      image: 'vzero',\n    },\n  ])\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/home/Entry.vue",
    "content": "<template>\n  <v-responsive class=\"pb-5\">\n    <v-container class=\"text-left position-relative\">\n      <v-row\n        class=\"py-16 align-center justify-center\"\n      >\n        <v-col cols=\"12\" md=\"6\">\n          <v-chip color=\"primary\">\n            {{ t('home.entry.chip') }}\n          </v-chip>\n\n          <h1 class=\"text-display-medium text-md-display-large font-weight-bold my-5\">\n            {{ t('home.entry.title-prefix') }}\n            <br class=\"d-none d-md-block\">\n            <span class=\"text-primary\">{{ t('home.entry.title-highlight') }}</span>\n            <br class=\"d-none d-md-block\">\n            {{ t('home.entry.title-suffix') }}\n          </h1>\n\n          <h2 class=\"text-title-large font-weight-regular text-medium-emphasis mt-5 mb-7\">\n            {{ t('home.entry.subtitle') }}\n          </h2>\n\n          <div class=\"d-flex flex-wrap ga-4 justify-start my-5\">\n            <v-btn\n              :text=\"t('home.get-started')\"\n              :to=\"rpath('/getting-started/installation/')\"\n              class=\"text-none\"\n              color=\"primary\"\n              rounded=\"lg\"\n              size=\"large\"\n              flat\n            />\n\n            <v-btn\n              :text=\"t('home.why-vuetify')\"\n              :to=\"rpath('/getting-started/why-vuetify')\"\n              append-icon=\"$vuetify-outline\"\n              class=\"text-none\"\n              color=\"primary\"\n              rounded=\"lg\"\n              size=\"large\"\n              variant=\"tonal\"\n              flat\n            />\n          </div>\n\n          <div class=\"d-flex flex-wrap ga-4 align-center\">\n            <v-hover v-slot=\"{ isHovering, props }\">\n              <v-sheet\n                class=\"px-2 py-2 d-inline-flex align-center text-mono text-body-medium text-no-wrap\"\n                color=\"surface\"\n                rounded=\"lg\"\n                border\n                v-bind=\"props\"\n              >\n\n                <v-menu offset=\"4\">\n                  <template #activator=\"{ props: iconProps, isActive }\">\n                    <v-icon-btn\n                      v-bind=\"iconProps\"\n                      :rotate=\"isActive ? 180 : 0\"\n                      class=\"mr-2\"\n                      color=\"primary\"\n                      cursor=\"pointer\"\n                      height=\"20\"\n                      icon=\"mdi-chevron-down\"\n                      icon-size=\"16\"\n                      rounded=\"lg\"\n                      variant=\"text\"\n                      width=\"20\"\n                    />\n                  </template>\n\n                  <v-list density=\"compact\" rounded=\"lg\">\n                    <v-list-item\n                      v-for=\"manager in packageManagers\"\n                      :key=\"manager\"\n                      :title=\"manager\"\n                      :value=\"manager\"\n                      @click=\"selectedPackageManager = manager\"\n                    />\n                  </v-list>\n                </v-menu>\n\n                {{ commands[selectedPackageManager] }}\n\n                <span class=\"text-primary font-weight-medium ms-2\">\n                  vuetify\n                </span>\n\n                <v-icon\n                  :color=\"isCopying ? 'success' : 'medium-emphasis'\"\n                  :icon=\"isCopying ? 'mdi-check' : 'mdi-clipboard-text-outline'\"\n                  :style=\"{\n                    opacity: isHovering || isCopying ? 1 : 0,\n                  }\"\n                  class=\"ms-auto\"\n                  size=\"17\"\n                  @click=\"copy\"\n                />\n              </v-sheet>\n            </v-hover>\n\n            <v-sheet\n              class=\"pa-1 ps-3 d-inline-flex align-center justify-space-between\"\n              color=\"surface\"\n              rounded=\"lg\"\n              border\n            >\n              <span class=\"text-body-medium me-2\">{{ t('home.entry.latest') }}</span>\n\n              <AppVersionBtn />\n            </v-sheet>\n          </div>\n\n        </v-col>\n\n        <v-col class=\"d-md-block d-none\" cols=\"12\" md=\"6\">\n          <v-sheet\n            border=\"sm surface-variant-alt\"\n            class=\"rounded-lg overflow-hidden elevation-5\"\n            theme=\"dark\"\n          >\n            <v-toolbar class=\"justify-center\" color=\"surface-variant-alt\" height=\"25\" theme=\"dark\">\n              <div class=\"position-absolute left-0 ml-3\">\n                <v-avatar class=\"mx-1\" color=\"error\" size=\"10\" />\n                <v-avatar class=\"mx-1\" color=\"warning\" size=\"10\" />\n                <v-avatar class=\"mx-1\" color=\"success\" size=\"10\" />\n              </div>\n            </v-toolbar>\n\n            <AppMarkup\n              :code=\"code\"\n              class=\"pa-5 bg-black\"\n            />\n          </v-sheet>\n        </v-col>\n      </v-row>\n    </v-container>\n\n    <HomeCommonGradient color=\"primary\" />\n  </v-responsive>\n</template>\n\n<script setup lang=\"ts\">\n  const { t } = useI18n()\n\n  const code = computed(() => [\n    {\n      name: 'template',\n      content: `<template>\n  <v-app>\n    <v-container>\n      <v-btn color=\"primary\">\n        ${t('home.entry.hello-vuetify')}!\n      </v-btn>\n    </v-container>\n  </v-app>\n</template>`,\n      language: 'html',\n    },\n  ])\n\n  const packageManagers = ['npm', 'pnpm', 'yarn', 'bun']\n  const randomPackageManager = packageManagers[Math.floor(Math.random() * packageManagers.length)]\n\n  const commands: Record<string, string> = {\n    pnpm: 'pnpm create',\n    yarn: 'yarn create',\n    npm: 'npm create',\n    bun: 'bun create',\n  }\n\n  const isCopying = shallowRef(false)\n  const selectedPackageManager = shallowRef(randomPackageManager)\n\n  function copy () {\n    isCopying.value = true\n\n    navigator.clipboard.writeText(`${commands[selectedPackageManager.value]} vuetify`)\n\n    setTimeout(() => {\n      isCopying.value = false\n    }, 1000)\n  }\n</script>\n\n<style lang=\"sass\" scoped>\n  .code-shadow\n    box-shadow: 10px 10px 100px -5px #00000044\n\n  .code-toolbar\n    position: absolute\n    left: 50%\n    transform: translateX(-50%)\n</style>\n"
  },
  {
    "path": "packages/docs/src/components/home/Footer.vue",
    "content": "<template>\n  <v-footer\n    id=\"footer\"\n    class=\"d-block py-6\"\n    color=\"surface-light\"\n  >\n    <v-container class=\"text-center\">\n      <v-img\n        :src=\"`https://cdn.vuetifyjs.com/docs/images/logos/vuetify-logo-${theme.current.value.dark ? 'dark' : 'light'}-slim.svg`\"\n        class=\"mb-6\"\n        height=\"64\"\n      />\n\n      <div class=\"mb-3\">\n\n        <a\n          v-for=\"(social, i) in socials\"\n          :key=\"i\"\n          :aria-label=\"social.title\"\n          :href=\"social.href\"\n          :title=\"t(social.title)\"\n          class=\"ma-3 d-inline-block text-decoration-none\"\n          rel=\"noopener\"\n          target=\"_blank\"\n        >\n          <v-icon\n            :icon=\"social.icon\"\n            color=\"medium-emphasis\"\n          />\n        </a>\n      </div>\n      <v-responsive\n        class=\"mx-auto mb-6\"\n        max-width=\"70%\"\n        width=\"150\"\n      >\n        <v-divider />\n      </v-responsive>\n\n      <div class=\"text-medium-emphasis\">\n        <div>\n          {{ t('released-under-the') }}\n          <a\n            class=\"text-medium-emphasis text-decoration-underline\"\n            href=\"https://github.com/vuetifyjs/vuetify/blob/master/LICENSE.md\"\n            path=\"mit-license\"\n            rel=\"noopener\"\n            target=\"_blank\"\n          >{{ t('mit-license') }}</a>\n        </div>\n\n        <div class=\"mb-4\">\n          {{ t('copyright') }} &copy; 2016-{{ (new Date()).getFullYear() }} {{ t('vuetify') }}\n        </div>\n\n        <template\n          v-for=\"(link, i) in links\"\n          :key=\"i\"\n        >\n          <a\n            :href=\"link.href\"\n            class=\"text-medium-emphasis\"\n            rel=\"noopener\"\n            target=\"_blank\"\n          >{{ t(link.path) }}</a>\n\n          <template v-if=\"i !== links.length - 1\">&nbsp;•&nbsp;</template>\n        </template>\n      </div>\n    </v-container>\n  </v-footer>\n</template>\n\n<script setup>\n  const { t } = useI18n()\n  const theme = useTheme()\n  const links = [\n    {\n      href: 'https://www.iubenda.com/privacy-policy/76325752',\n      path: 'privacy-policy',\n    },\n    {\n      href: 'https://www.iubenda.com/privacy-policy/76325752/cookie-policy',\n      path: 'cookie-policy',\n    },\n    {\n      href: 'mailto:hello@vuetifyjs.com',\n      path: 'contact-us',\n    },\n  ]\n  const socials = [\n    {\n      icon: 'mdi-reddit',\n      href: 'https://www.reddit.com/r/vuetifyjs',\n      title: 'reddit',\n    },\n    {\n      icon: 'mdi-github',\n      href: 'https://github.com/vuetifyjs/vuetify',\n      title: 'github',\n    },\n    {\n      icon: '$x',\n      href: 'https://x.com/vuetifyjs',\n      title: 'x',\n    },\n    {\n      icon: 'mdi-bluesky',\n      href: 'https://bsky.app/profile/vuetify.bsky.social',\n      title: 'bluesky',\n    },\n    {\n      icon: 'mdi-discord',\n      href: 'https://community.vuetifyjs.com',\n      title: 'discord',\n    },\n  ]\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/home/Gallery/Analytics.vue",
    "content": "<template>\n  <div>\n    <v-toolbar color=\"transparent\">\n      <v-toolbar-title class=\"text-title-large\">Analytics</v-toolbar-title>\n\n      <template #append>\n        <v-btn-toggle v-model=\"range\" density=\"compact\" variant=\"outlined\" mandatory>\n          <v-btn size=\"small\" text=\"7D\" value=\"7d\" />\n          <v-btn size=\"small\" text=\"30D\" value=\"30d\" />\n          <v-btn size=\"small\" text=\"90D\" value=\"90d\" />\n        </v-btn-toggle>\n      </template>\n    </v-toolbar>\n\n    <v-container fluid>\n      <v-row>\n        <v-col v-for=\"stat in stats\" :key=\"stat.title\" cols=\"6\" md=\"3\">\n          <v-card elevation=\"0\" rounded=\"lg\" border>\n            <v-card-text class=\"pb-0\">\n              <div class=\"text-body-small text-medium-emphasis\">{{ stat.title }}</div>\n              <div class=\"d-flex align-center justify-space-between\">\n                <span class=\"text-title-large\">{{ stat.value }}</span>\n                <v-chip\n                  :color=\"stat.change > 0 ? 'success' : 'error'\"\n                  :prepend-icon=\"stat.change > 0 ? 'mdi-arrow-up' : 'mdi-arrow-down'\"\n                  :text=\"`${Math.abs(stat.change)}%`\"\n                  size=\"x-small\"\n                  variant=\"tonal\"\n                />\n              </div>\n            </v-card-text>\n\n            <v-sparkline\n              :color=\"stat.change > 0 ? 'success' : 'error'\"\n              :gradient=\"stat.change > 0 ? ['#4CAF50', '#81C784'] : ['#F44336', '#E57373']\"\n              :line-width=\"2\"\n              :model-value=\"stat.data\"\n              height=\"40\"\n              padding=\"8\"\n              fill\n              smooth\n            />\n          </v-card>\n        </v-col>\n      </v-row>\n\n      <v-card\n        class=\"mt-4\"\n        elevation=\"0\"\n        rounded=\"lg\"\n        title=\"Top Pages\"\n        border\n        flat\n      >\n        <template #text>\n          <v-data-table\n            :headers=\"headers\"\n            :items=\"pages\"\n            :items-per-page=\"5\"\n            hide-default-footer\n          >\n            <template #item.page=\"{ item }\">\n              <div class=\"d-flex align-center ga-2\">\n                <v-icon color=\"primary\" icon=\"mdi-file-document-outline\" size=\"small\" />\n                <span>{{ item.page }}</span>\n              </div>\n            </template>\n\n            <template #item.trend=\"{ item }\">\n              <v-sparkline\n                :color=\"item.change >= 0 ? 'success' : 'error'\"\n                :line-width=\"2\"\n                :model-value=\"item.trend\"\n                height=\"24\"\n                padding=\"4\"\n                width=\"80\"\n                smooth\n              />\n            </template>\n\n            <template #item.change=\"{ item }\">\n              <v-chip\n                :color=\"item.change >= 0 ? 'success' : 'error'\"\n                size=\"small\"\n                variant=\"text\"\n              >\n                <v-icon\n                  :icon=\"item.change >= 0 ? 'mdi-trending-up' : 'mdi-trending-down'\"\n                  size=\"small\"\n                  start\n                />\n                {{ item.change >= 0 ? '+' : '' }}{{ item.change }}%\n              </v-chip>\n            </template>\n\n            <template #item.sessions=\"{ item }\">\n              <span class=\"font-weight-medium\">{{ item.sessions.toLocaleString() }}</span>\n            </template>\n          </v-data-table>\n        </template>\n      </v-card>\n    </v-container>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\n  const range = shallowRef('30d')\n\n  const stats = [\n    {\n      title: 'Page Views',\n      value: '24.5K',\n      change: 12,\n      data: [4, 6, 8, 7, 10, 9, 12, 14, 13, 16, 15, 18],\n    },\n    {\n      title: 'Visitors',\n      value: '8,234',\n      change: 8,\n      data: [3, 4, 5, 4, 6, 7, 6, 8, 9, 8, 10, 11],\n    },\n    {\n      title: 'Bounce Rate',\n      value: '42.3%',\n      change: -5,\n      data: [50, 48, 52, 49, 47, 45, 48, 44, 46, 43, 45, 42],\n    },\n    {\n      title: 'Avg. Duration',\n      value: '3m 24s',\n      change: 15,\n      data: [2, 2.2, 2.5, 2.4, 2.8, 2.6, 3, 2.9, 3.2, 3.1, 3.3, 3.4],\n    },\n  ]\n\n  const headers = [\n    { title: 'Page', key: 'page', sortable: false },\n    { title: 'Trend', key: 'trend', sortable: false, width: 100 },\n    { title: 'Sessions', key: 'sessions', align: 'end' as const },\n    { title: 'Change', key: 'change', align: 'end' as const },\n  ]\n\n  const pages = [\n    {\n      page: '/getting-started/installation',\n      sessions: 12453,\n      change: 24,\n      trend: [8, 10, 9, 12, 11, 14, 13, 16],\n    },\n    {\n      page: '/components/buttons',\n      sessions: 8721,\n      change: 18,\n      trend: [6, 7, 8, 7, 9, 10, 11, 12],\n    },\n    {\n      page: '/components/data-tables',\n      sessions: 6534,\n      change: -3,\n      trend: [10, 9, 11, 8, 9, 7, 8, 7],\n    },\n    {\n      page: '/styles/colors',\n      sessions: 5210,\n      change: 7,\n      trend: [4, 5, 4, 6, 5, 7, 6, 7],\n    },\n    {\n      page: '/features/theme',\n      sessions: 4102,\n      change: 31,\n      trend: [3, 4, 5, 6, 7, 8, 10, 12],\n    },\n  ]\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/home/Gallery/Chat/Chat.vue",
    "content": "<template>\n  <v-container class=\"bg-surface-light overflow-hidden\" height=\"100%\" fluid>\n    <v-row class=\"fill-height\">\n      <template v-if=\"!mobile\">\n        <v-col class=\"fill-height\" cols=\"4\">\n          <VChatList\n            :chats=\"chats\"\n            :selected-chat=\"selectedChat\"\n            @select-chat=\"selectChat\"\n          />\n        </v-col>\n\n        <v-col class=\"fill-height\" cols=\"8\">\n          <VChatDetail :chat=\"selectedChat\" :messages=\"messages\" />\n        </v-col>\n      </template>\n\n      <template v-else>\n        <v-col v-if=\"selectedChat\" class=\"fill-height\" cols=\"12\">\n          <VChatDetail\n            :chat=\"selectedChat\"\n            :messages=\"messages\"\n            @back=\"selectedChat = null\"\n          />\n        </v-col>\n\n        <v-col v-else class=\"fill-height\" cols=\"12\">\n          <VChatList\n            :chats=\"chats\"\n            :selected-chat=\"selectedChat\"\n            @select-chat=\"selectChat\"\n          />\n        </v-col>\n      </template>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n  import { useDisplay } from 'vuetify'\n  import VChatList from '@/components/home/Gallery/Chat/List.vue'\n  import VChatDetail from '@/components/home/Gallery/Chat/Detail.vue'\n\n  const chats = [\n    {\n      id: 1,\n      avatar: 'https://cdn.vuetifyjs.com/docs/images/team/john.png',\n      name: 'John Leider',\n      date: '2025-08-05',\n      message: `I'll be in your neighborhood doing errands this weekend. Do you want to hang out?`,\n    },\n    {\n      id: 2,\n      avatar: 'https://cdn.vuetifyjs.com/docs/images/team/heather.jpg',\n      name: 'Heather Leider',\n      date: '2025-08-05',\n      message: `&mdash; Wish I could come, but I'm out of town this weekend.`,\n    },\n    {\n      id: 3,\n      avatar: 'https://cdn.vuetifyjs.com/docs/images/team/kael.jpg',\n      name: 'Kael Watts-Deuchar',\n      date: '2025-08-05',\n      message: 'Do you have Paris recommendations? Have you ever been?',\n    },\n    {\n      id: 12,\n      avatar: 'https://cdn.vuetifyjs.com/docs/images/team/ishin.jpg',\n      name: 'Ishan Subedi',\n      date: '2025-08-05',\n      message: 'We should eat this: Grate, Squash, Corn, and tomatillo Tacos.',\n    },\n    {\n      id: 4,\n      avatar: 'https://cdn.vuetifyjs.com/docs/images/team/andrew.jpg',\n      name: 'Andrew Henry',\n      date: '2025-08-05',\n      message: 'Have any ideas about what we should get Heidi for her birthday?',\n    },\n    {\n      id: 5,\n      avatar: 'https://cdn.vuetifyjs.com/docs/images/team/blaine.jpg',\n      name: 'Blaine Landowski',\n      date: '2025-08-05',\n      message: 'We should eat this: Grate, Squash, Corn, and tomatillo Tacos.',\n    },\n    {\n      id: 8,\n      avatar: 'https://cdn.vuetifyjs.com/docs/images/team/jacek.png',\n      name: 'Jacek Czarniecki',\n      date: '2025-08-05',\n      message: 'We should eat this: Grate, Squash, Corn, and tomatillo Tacos.',\n    },\n    {\n      id: 9,\n      avatar: 'https://cdn.vuetifyjs.com/docs/images/team/shubham.jpg',\n      name: 'Shubham Patlani',\n      date: '2025-08-05',\n      message: 'We should eat this: Grate, Squash, Corn, and tomatillo Tacos.',\n    },\n    {\n      id: 11,\n      avatar: 'https://cdn.vuetifyjs.com/docs/images/team/henry.jpg',\n      name: 'Henry Aviles',\n      date: '2025-08-05',\n      message: 'We should eat this: Grate, Squash, Corn, and tomatillo Tacos.',\n    },\n    {\n      id: 13,\n      avatar: 'https://cdn.vuetifyjs.com/docs/images/team/andrei.jpg',\n      name: 'Andrei Elkin',\n      date: '2025-08-05',\n      message: 'We should eat this: Grate, Squash, Corn, and tomatillo Tacos.',\n    },\n    {\n      id: 14,\n      avatar: 'https://cdn.vuetifyjs.com/docs/images/team/jc.jpg',\n      name: 'JC Puno',\n      date: '2025-08-05',\n      message: 'We should eat this: Grate, Squash, Corn, and tomatillo Tacos.',\n    },\n    {\n      id: 15,\n      avatar: 'https://cdn.vuetifyjs.com/docs/images/team/abe.png',\n      name: 'Abdelouahed Oumoussa',\n      date: '2025-08-05',\n      message: 'We should eat this: Grate, Squash, Corn, and tomatillo Tacos.',\n    },\n  ]\n\n  const { mobile } = useDisplay()\n\n  const messages = ref([\n    {\n      id: 1,\n      date: '2025-08-05',\n      message: `I'll be in your neighborhood doing errands this weekend. Do you want to hang out?`,\n      isMine: true,\n    },\n    {\n      id: 2,\n      date: '2025-08-05',\n      message: `Just finished that book you recommended - it was amazing! We should discuss it over coffee sometime.`,\n    },\n    {\n      id: 3,\n      date: '2025-08-05',\n      message: 'Do you have Paris recommendations? Have you ever been?',\n      isMine: true,\n    },\n    {\n      id: 4,\n      date: '2025-08-05',\n      message: 'Have any ideas about what we should get Heidi for her birthday?',\n    },\n    {\n      id: 5,\n      date: '2025-08-05',\n      isMine: true,\n      message: 'We should eat this: Grate, Squash, Corn, and tomatillo Tacos.',\n    },\n    {\n      id: 6,\n      date: '2025-08-05',\n      message: 'Hey, are you going to the concert next weekend? I have an extra ticket!',\n    },\n    {\n      id: 7,\n      date: '2025-08-05',\n      message: 'Can you send me the notes from yesterday\\'s meeting? I had to leave early.',\n      isMine: true,\n    },\n    {\n      id: 8,\n      date: '2025-08-05',\n      message: 'Check out this new recipe I tried - it turned out incredible!',\n    },\n    {\n      id: 9,\n      date: '2025-08-05',\n      message: 'Remember that cafe we visited last summer? They\\'re opening a new location downtown!',\n      isMine: true,\n    },\n    {\n      id: 11,\n      date: '2025-08-05',\n      message: 'Did you see the season finale last night? We need to talk about that ending!',\n      isMine: true,\n    },\n    {\n      id: 12,\n      date: '2025-08-05',\n      message: 'Thanks for helping me move yesterday. I owe you dinner!',\n    },\n    {\n      id: 13,\n      date: '2025-08-05',\n      message: 'My sister just got engaged! Save the date for the wedding in September.',\n      isMine: true,\n    },\n    {\n      id: 14,\n      date: '2025-08-05',\n      message: 'Found this amazing hiking trail yesterday. We should check it out this weekend!',\n    },\n    {\n      id: 15,\n      date: '2025-08-05',\n      message: 'Can you believe it\\'s been 5 years since college? Time flies!',\n      isMine: true,\n    },\n    {\n      id: 17,\n      date: '2025-08-05',\n      message: 'I just saw this place and thought of you!',\n    },\n  ])\n\n  const selectedChat = ref(chats[0])\n\n  function selectChat (chat) {\n    selectedChat.value = chat\n    messages.value = messages.value.reverse()\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/home/Gallery/Chat/Detail.vue",
    "content": "<template>\n  <v-card\n    class=\"d-flex flex-column\"\n    elevation=\"0\"\n    height=\"100%\"\n    rounded=\"xl\"\n    weight=\"100%\"\n    border\n  >\n    <v-card-title class=\"d-flex align-center\">\n      <v-btn\n        v-if=\"mobile\"\n        size=\"small\"\n        variant=\"text\"\n        icon\n        @click=\"emit('back')\"\n      >\n        <v-icon>mdi-arrow-left</v-icon>\n      </v-btn>\n\n      <v-avatar class=\"mx-2\">\n        <v-img :src=\"chat.avatar\" />\n      </v-avatar>\n\n      <div class=\"text-body-large font-weight-medium\">\n        {{ chat.name }}\n      </div>\n\n      <v-spacer />\n    </v-card-title>\n\n    <v-divider />\n\n    <v-card-text\n      ref=\"messagesContainer\"\n      class=\"d-flex flex-column flex-fill overflow-y-auto\"\n    >\n      <v-spacer />\n\n      <div\n        v-for=\"message in [...props.messages, ...newMessages]\"\n        :key=\"message.id\"\n        class=\"d-flex my-5\"\n      >\n        <v-spacer v-if=\"message.isMine\" />\n\n        <v-sheet\n          :max-width=\"mobile ? '80%' : '50%'\"\n          class=\"d-flex align-center\"\n        >\n          <v-avatar v-if=\"!message.isMine\" class=\"mr-2\" size=\"x-small\">\n            <v-img :src=\"chat.avatar\" />\n          </v-avatar>\n\n          <v-card\n            :color=\"message.isMine ? 'primary' : 'surface-light'\"\n            class=\"rounded-xl px-4 py-2\"\n            elevation=\"0\"\n            border\n          >\n            {{ message.message }}\n          </v-card>\n        </v-sheet>\n      </div>\n    </v-card-text>\n\n    <v-card-actions>\n      <v-text-field\n        v-model=\"newMessage\"\n        bg-color=\"surface-light\"\n        placeholder=\"Type a message\"\n        rounded=\"xl\"\n        variant=\"solo\"\n        flat\n        hide-details\n        @keyup.enter=\"sendMessage\"\n      >\n        <template #append-inner>\n          <v-btn color=\"primary\" icon=\"mdi-send\" @click=\"sendMessage\" />\n        </template>\n      </v-text-field>\n    </v-card-actions>\n  </v-card>\n</template>\n\n<script setup>\n  import { nextTick, onMounted, ref } from 'vue'\n  import { useDisplay } from 'vuetify'\n\n  const { mobile } = useDisplay()\n\n  const props = defineProps({\n    chat: {\n      type: Object,\n      required: true,\n    },\n    messages: {\n      type: Array,\n      required: true,\n    },\n  })\n\n  const emit = defineEmits(['back'])\n\n  const messagesContainer = ref(null)\n  const newMessage = ref('')\n  const newMessages = ref([])\n\n  onMounted(() => {\n    scrollToBottomOfChat()\n  })\n\n  function scrollToBottomOfChat () {\n    const messageListContainerEl = messagesContainer.value.$el\n\n    messageListContainerEl.scrollTop = messageListContainerEl.scrollHeight\n  }\n\n  function sendMessage () {\n    newMessages.value.push({\n      id: Date.now(),\n      message: newMessage.value,\n      isMine: true,\n    })\n\n    newMessage.value = ''\n\n    nextTick(() => {\n      scrollToBottomOfChat()\n    })\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/home/Gallery/Chat/List.vue",
    "content": "<template>\n  <v-card\n    class=\"d-flex flex-column\"\n    elevation=\"0\"\n    height=\"100%\"\n    rounded=\"xl\"\n    weight=\"100%\"\n    border\n  >\n    <v-card-title>\n      <div>Chat</div>\n\n      <v-text-field\n        v-model=\"searchTerm\"\n        autocomplete=\"off\"\n        bg-color=\"surface-light\"\n        class=\"mt-5\"\n        placeholder=\"Search\"\n        prepend-inner-icon=\"mdi-magnify\"\n        rounded=\"xl\"\n        variant=\"solo\"\n        flat\n        hide-details\n      />\n    </v-card-title>\n\n    <v-card-text\n      v-if=\"filteredChats.length\"\n      class=\"d-flex flex-column overflow-hidden px-0\"\n    >\n      <v-list lines=\"three\" item-props>\n        <v-list-item\n          v-for=\"chat in filteredChats\"\n          :key=\"chat.id\"\n          :active=\"selectedChat?.id === chat.id\"\n          :prepend-avatar=\"chat.avatar\"\n          :subtitle=\"chat.message\"\n          :title=\"chat.name\"\n          @click=\"emit('selectChat', chat)\"\n        >\n          <template #subtitle=\"{ subtitle }\">\n            <div>\n              {{ subtitle }} <span class=\"text-grey\">{{ chat.date }}</span>\n            </div>\n          </template>\n        </v-list-item>\n      </v-list>\n    </v-card-text>\n\n    <v-card-text v-else class=\"py-5 text-center\"> No chats found </v-card-text>\n  </v-card>\n</template>\n\n<script setup>\n  import { computed, ref } from 'vue'\n\n  const props = defineProps({\n    chats: {\n      type: Array,\n      required: true,\n    },\n    selectedChat: {\n      type: [Object, null],\n      required: true,\n    },\n  })\n\n  const emit = defineEmits(['selectChat'])\n\n  const searchTerm = ref('')\n\n  const filteredChats = computed(() => props.chats.filter(chat => chat.name.toLowerCase().includes(searchTerm.value.toLowerCase())))\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/home/Gallery/Components.vue",
    "content": "<template>\n  <v-theme-provider :theme=\"currentTheme\">\n    <v-defaults-provider :defaults=\"defaults\">\n      <v-card class=\"py-16\" color=\"background\" elevation=\"0\">\n        <v-container class=\"pt-0\">\n          <HomeCommonTitle\n            :description=\"t('home.gallery.description')\"\n            :title=\"t('home.gallery.title')\"\n            class=\"mb-10\"\n          />\n\n          <v-sheet class=\"mx-auto\" color=\"transparent\" max-width=\"1200\">\n            <v-card\n              class=\"my-1\"\n              color=\"transparent\"\n              elevation=\"0\"\n              rounded=\"lg\"\n            >\n              <div class=\"d-flex flex-wrap align-center justify-center ga-2 mb-2\">\n                <div\n                  v-for=\"(config, themeName) in themeConfigs\"\n                  :key=\"themeName\"\n                  class=\"d-flex flex-column align-center justify-center\"\n                >\n                  <v-avatar\n                    :color=\"config.theme.colors.primary as string\"\n                    class=\"d-flex align-center justify-center cursor-pointer\"\n                    height=\"32\"\n                    size=\"32\"\n                    width=\"32\"\n                    @click=\"currentTheme = themeName\"\n                  >\n                    <v-icon v-if=\"currentTheme === themeName\" icon=\"mdi-check\" />\n                  </v-avatar>\n                </div>\n\n                <v-divider class=\"mx-2 align-self-center\" length=\"18\" vertical />\n\n                <v-avatar\n                  class=\"cursor-pointer\"\n                  size=\"32\"\n                  border\n                  v-tooltip:top=\"density\"\n                  @click=\"cycleDensity\"\n                >\n                  <v-icon :icon=\"densityIcon\" size=\"small\" />\n                </v-avatar>\n              </div>\n            </v-card>\n\n            <v-card class=\"text-left\" elevation=\"1\" rounded=\"lg\">\n              <v-layout height=\"700\">\n                <v-system-bar class=\"justify-center\" theme=\"dark\" window>\n                  <div class=\"position-absolute left-0 ml-3\">\n                    <v-avatar class=\"mx-1\" color=\"error\" size=\"12\" />\n                    <v-avatar class=\"mx-1\" color=\"warning\" size=\"12\" />\n                    <v-avatar class=\"mx-1\" color=\"success\" size=\"12\" />\n                  </div>\n\n                  <v-icon class=\"mx-2\" color=\"primary\" icon=\"$vuetify\" size=\"14\" />\n\n                  <span>{{ t('home.gallery.system-bar') }}</span>\n                </v-system-bar>\n\n                <v-app-bar\n                  v-if=\"!selectedComponent.isNavigationHiden\"\n                  class=\"ps-4\"\n                  color=\"primary\"\n                  elevation=\"0\"\n                  flat\n                >\n                  <v-app-bar-nav-icon class=\"mr-3\" @click=\"drawer = !drawer\" />\n\n                  <v-avatar\n                    class=\"pa-1\"\n                    color=\"surface\"\n                    image=\"https://cdn.vuetifyjs.com/docs/images/logos/v.svg\"\n                    size=\"40\"\n                  />\n\n                  <v-app-bar-title>Vuetify</v-app-bar-title>\n\n                  <template #append>\n                    <v-btn class=\"text-none me-1 px-3\" height=\"48\" slim>\n                      <template #prepend>\n                        <v-avatar color=\"surface-light\" image=\"https://cdn.vuetifyjs.com/docs/images/team/john.png\" size=\"32\" start />\n                      </template>\n\n                      <span class=\"hidden-sm-and-down\">John Leider</span>\n\n                      <v-menu activator=\"parent\">\n                        <v-list density=\"compact\" nav>\n                          <v-list-item :title=\"t('home.gallery.settings')\" link @click=\"selectedComponent = settingsComponent\" />\n\n                          <v-list-item :title=\"t('home.gallery.logout')\" @click=\"selectedComponent = loginComponent\" />\n                        </v-list>\n                      </v-menu>\n\n                      <template #append>\n                        <v-icon icon=\"mdi-chevron-down\" />\n                      </template>\n                    </v-btn>\n                  </template>\n                </v-app-bar>\n\n                <v-navigation-drawer\n                  v-if=\"!selectedComponent.isNavigationHiden\"\n                  v-model=\"drawer\"\n                  :rail=\"hasRailsDrawer\"\n                  color=\"surface\"\n                  width=\"250\"\n                >\n                  <v-list\n                    :items=\"components\"\n                    nav\n                    slim\n                  >\n                    <v-list-subheader v-if=\"!hasRailsDrawer\">\n                      {{ t('home.gallery.application') }}\n                    </v-list-subheader>\n\n                    <v-list-item\n                      v-for=\"(item, i) in components\"\n                      :key=\"i\"\n                      v-bind=\"item\"\n                      :active=\"item.title === selectedComponent.title\"\n                      active-class=\"text-primary\"\n                      nav\n                      @click=\"selectComponent(item)\"\n                    />\n                  </v-list>\n\n                  <template #append>\n                    <v-list-item\n                      :active=\"selectedComponent.title === 'Settings'\"\n                      :title=\"t('home.gallery.settings')\"\n                      active-class=\"text-primary\"\n                      class=\"ma-2\"\n                      prepend-icon=\"mdi-cog-outline\"\n                      link\n                      nav\n                      slim\n                      @click=\"selectedComponent = settingsComponent\"\n                    />\n                  </template>\n                </v-navigation-drawer>\n\n                <v-main scrollable>\n                  <v-slide-x-transition mode=\"out-in\">\n                    <component\n                      :is=\"selectedComponent.component\"\n                      @login=\"selectedComponent = components[0]\"\n                    />\n                  </v-slide-x-transition>\n                </v-main>\n              </v-layout>\n            </v-card>\n          </v-sheet>\n        </v-container>\n      </v-card>\n    </v-defaults-provider>\n  </v-theme-provider>\n</template>\n\n<script setup lang=\"ts\">\n  import { defineAsyncComponent } from 'vue'\n\n  const { t } = useI18n()\n\n  interface SelectedComponent {\n    title: string\n    prependIcon?: string\n    component: Component\n    hasRailsDrawer?: boolean\n    link?: boolean\n    isNavigationHiden?: boolean\n  }\n\n  const Settings = defineAsyncComponent(() => import('@/components/home/Gallery/Settings.vue'))\n  const Dashboard = defineAsyncComponent(() => import('@/components/home/Gallery/Dashboard.vue'))\n  const Chat = defineAsyncComponent(() => import('@/components/home/Gallery/Chat/Chat.vue'))\n  const Analytics = defineAsyncComponent(() => import('@/components/home/Gallery/Analytics.vue'))\n  const Login = defineAsyncComponent(() => import('@/components/home/Gallery/Login.vue'))\n\n  type Density = 'default' | 'comfortable' | 'compact'\n\n  const theme = useTheme()\n  const { mobile } = useDisplay()\n\n  const themeConfigs = {\n    light: { theme: theme.computedThemes.value.light, density: 'default' as Density },\n    dark: { theme: theme.computedThemes.value.dark, density: 'default' as Density },\n    blackguard: { theme: theme.computedThemes.value.blackguard, density: 'comfortable' as Density },\n    polaris: { theme: theme.computedThemes.value.polaris, density: 'comfortable' as Density },\n    nebula: { theme: theme.computedThemes.value.nebula, density: 'compact' as Density },\n    odyssey: { theme: theme.computedThemes.value.odyssey, density: 'compact' as Density },\n  }\n\n  const drawer = ref()\n  const currentTheme = ref(theme.name.value)\n  const density = shallowRef<Density>('default')\n\n  const densities: Density[] = ['default', 'comfortable', 'compact']\n\n  const densityIcon = computed(() => {\n    const icons: Record<Density, string> = {\n      default: 'mdi-unfold-more-horizontal',\n      comfortable: 'mdi-unfold-less-horizontal',\n      compact: 'mdi-arrow-collapse-vertical',\n    }\n    return icons[density.value]\n  })\n\n  function cycleDensity () {\n    const index = densities.indexOf(density.value)\n    density.value = densities[(index + 1) % densities.length]\n  }\n\n  const defaults = computed(() => {\n    const isCompact = density.value === 'compact'\n\n    return {\n      global: { density: density.value },\n      VCard: { elevation: 5 },\n      VAvatar: isCompact ? { size: 32 } : {},\n    }\n  })\n\n  const loginComponent: SelectedComponent = {\n    title: 'Login',\n    component: Login,\n    isNavigationHiden: true,\n  }\n\n  const settingsComponent: SelectedComponent = {\n    title: 'Settings',\n    prependIcon: 'mdi-cog-outline',\n    link: true,\n    component: Settings,\n  }\n\n  const components: SelectedComponent[] = [\n    {\n      title: 'Dashboard',\n      prependIcon: 'mdi-view-dashboard-outline',\n      link: true,\n      component: Dashboard,\n    },\n    {\n      title: 'Analytics',\n      prependIcon: 'mdi-chart-line',\n      link: true,\n      component: Analytics,\n    },\n    {\n      title: 'Chat',\n      component: Chat,\n      link: true,\n      prependIcon: 'mdi-message-outline',\n      hasRailsDrawer: true,\n    },\n  ]\n\n  const hasRailsDrawer = computed(() => {\n    return selectedComponent.value.hasRailsDrawer && !mobile.value\n  })\n\n  const selectedComponent = shallowRef<SelectedComponent>(components[0])\n\n  function selectComponent (item: SelectedComponent) {\n    selectedComponent.value = item\n    drawer.value = !mobile.value\n  }\n</script>\n\n<style scoped>\n  /* Make scrollbar thinner */\n  .overflow-y-auto {\n    scrollbar-width: thin;\n    scrollbar-color: rgba(var(--v-theme-on-surface), 0.3) transparent;\n  }\n\n  .overflow-y-auto::-webkit-scrollbar {\n    width: 6px;\n  }\n\n  .overflow-y-auto::-webkit-scrollbar-track {\n    background: transparent;\n  }\n\n  .overflow-y-auto::-webkit-scrollbar-thumb {\n    background-color: rgba(var(--v-theme-on-surface), 0.3);\n    border-radius: 3px;\n  }\n\n  .overflow-y-auto::-webkit-scrollbar-thumb:hover {\n    background-color: rgba(var(--v-theme-on-surface), 0.5);\n  }\n</style>\n"
  },
  {
    "path": "packages/docs/src/components/home/Gallery/Dashboard.vue",
    "content": "<template>\n  <v-container>\n    <v-row>\n      <v-col\n        v-for=\"(item, i) in statItems\"\n        :key=\"i\"\n        cols=\"6\"\n        md=\"3\"\n      >\n        <v-list\n          elevation=\"0\"\n          lines=\"two\"\n          rounded=\"lg\"\n          border\n        >\n          <v-list-item>\n            <v-list-item-title class=\"text-body-small\">{{ item.subtitle }}</v-list-item-title>\n\n            <v-list-item-title>{{ item.title }}</v-list-item-title>\n\n            <template #append>\n              <v-icon :color=\"item.color\" :icon=\"item.icon\" size=\"30\" />\n            </template>\n          </v-list-item>\n        </v-list>\n      </v-col>\n    </v-row>\n\n    <v-card class=\"my-5\" elevation=\"0\" rounded=\"lg\" title=\"Recent Orders\" border>\n      <template #text>\n        <v-text-field\n          v-model=\"search\"\n          autocomplete=\"off\"\n          placeholder=\"Search\"\n          prepend-inner-icon=\"mdi-magnify\"\n          variant=\"outlined\"\n          hide-details\n          rounded\n        />\n\n        <v-data-table :headers=\"headers\" :items=\"tableItems\" :search=\"search\" hide-default-footer>\n          <template #item.name=\"{ item }\">\n            <div class=\"d-flex align-center ga-4\">\n              <v-avatar :image=\"item.avatar\" color=\"surface-light\" />\n\n              <span>{{ item.name }}</span>\n            </div>\n          </template>\n\n          <template #item.status=\"{ item }\">\n            <v-chip\n              :color=\"item.status === 'Completed' ? 'success' : 'warning'\"\n              :text=\"item.status\"\n              border=\"current sm\"\n              size=\"x-small\"\n              label\n            />\n          </template>\n\n          <template #item.rating=\"{ item }\">\n            <div class=\"d-flex align-center justify-end\">\n              ({{ item.rating }})\n\n              <v-icon color=\"orange\" icon=\"mdi-star\" />\n            </div>\n          </template>\n        </v-data-table>\n      </template>\n    </v-card>\n\n    <v-row>\n      <v-col cols=\"12\" md=\"6\">\n        <v-card elevation=\"0\" rounded=\"lg\" title=\"Transactions\" border>\n          <template #append>\n            <div class=\"my-5\" />\n          </template>\n\n          <template #text>\n            <v-list-item\n              v-for=\"(item, i) in listItems\"\n              :key=\"i\"\n              :class=\"i !== 0 && 'mt-4'\"\n              :subtitle=\"item.subtitle\"\n              :title=\"item.title\"\n              class=\"px-0\"\n              lines=\"one\"\n            >\n              <template #prepend>\n                <v-avatar\n                  :color=\"item.color\"\n                  :icon=\"item.icon\"\n                  :text=\"item.initials\"\n                  variant=\"tonal\"\n                  rounded\n                />\n              </template>\n\n              <template #append>\n                <span class=\"text-body-large font-weight-regular\">\n                  {{ item.amount }}\n                </span>\n              </template>\n            </v-list-item>\n          </template>\n        </v-card>\n      </v-col>\n\n      <v-col cols=\"12\" md=\"6\">\n        <v-card elevation=\"0\" rounded=\"lg\" title=\"Summary\" border>\n          <template #append>\n            <div class=\"my-5\" />\n          </template>\n\n          <template #text>\n            <v-list-item\n              v-for=\"(item, i) in summaryItems\"\n              :key=\"i\"\n              :class=\"i !== 0 && 'mt-4'\"\n              class=\"px-0\"\n            >\n              <template #prepend>\n                <v-avatar :text=\"item.text\" color=\"primary\" size=\"large\" variant=\"tonal\" />\n              </template>\n\n              <template #title>\n                <div class=\"d-flex justify-space-between align-center text-medium-emphasis\">\n                  <span>{{ item.title }}</span>\n\n                  <span>{{ item.value }}</span>\n                </div>\n              </template>\n\n              <template #subtitle>\n                <div class=\"py-1\">\n                  <v-progress-linear\n                    :model-value=\"item.progress\"\n                    bg-color=\"surface-light\"\n                    bg-opacity=\"1\"\n                    color=\"primary\"\n                    height=\"8\"\n                    rounded\n                  />\n                </div>\n              </template>\n            </v-list-item>\n          </template>\n        </v-card>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const search = shallowRef('')\n\n  const headers = [\n    { title: 'Name', key: 'name' },\n    { title: 'Amount', key: 'amount', value: item => `$${item.amount}` },\n    { title: 'Vendor', key: 'vendor' },\n    { title: 'Status', key: 'status' },\n    { title: 'Rating', key: 'rating', align: 'end' },\n  ]\n\n  const tableItems = [\n    {\n      avatar: 'https://vuetifyjs.b-cdn.net/docs/images/graphics/mice/10.png',\n      name: 'G Pro X Superlight',\n      amount: 149,\n      vendor: 'Logitech',\n      status: 'Completed',\n      rating: '5.0',\n    },\n    {\n      avatar: 'https://vuetifyjs.b-cdn.net/docs/images/graphics/mice/7.png',\n      name: 'DeathAdder V3',\n      amount: 79,\n      vendor: 'Razer',\n      status: 'Pending',\n      rating: '4.5',\n    },\n    {\n      avatar: 'https://vuetifyjs.b-cdn.net/docs/images/graphics/mice/3.png',\n      name: 'Pulsefire Haste 2',\n      amount: 299,\n      vendor: 'HyperX',\n      status: 'Completed',\n      rating: '4.8',\n    },\n    {\n      avatar: 'https://vuetifyjs.b-cdn.net/docs/images/graphics/mice/5.png',\n      name: 'Viper V2 Pro',\n      amount: 29,\n      vendor: 'Razer',\n      status: 'Completed',\n      rating: '4.2',\n    },\n    {\n      avatar: 'https://vuetifyjs.b-cdn.net/docs/images/graphics/mice/9.png',\n      name: 'MX Master 3S',\n      amount: 49,\n      vendor: 'Logitech',\n      status: 'Cancelled',\n      rating: '4.0',\n    },\n  ]\n\n  const statItems = [\n    {\n      subtitle: 'Total subscribers',\n      title: '23,412',\n      icon: 'mdi-account-group-outline',\n      color: 'blue',\n    },\n    {\n      subtitle: 'Total revenue',\n      title: '$14,301',\n      icon: 'mdi-star-outline',\n      color: 'green',\n    },\n    {\n      subtitle: 'Total orders',\n      title: '402',\n      icon: 'mdi-cart-outline',\n      color: 'orange',\n    },\n    {\n      subtitle: 'Total products',\n      title: '76',\n      icon: 'mdi-shape-outline',\n      color: 'red',\n    },\n  ]\n\n  const listItems = [\n    {\n      title: 'John Leider',\n      initials: 'JL',\n      amount: '+$36.11',\n      subtitle: '21 Mar 8:00PM',\n      color: 'success',\n    },\n    {\n      title: 'ATM withdrawal',\n      initials: '$',\n      amount: '-$20.00',\n      subtitle: '21 Mar 6:00PM',\n      color: 'warning',\n    },\n    {\n      title: 'Jane Doe',\n      initials: 'JD',\n      amount: '+$45.00',\n      subtitle: '21 Mar 4:00PM',\n      color: 'success',\n    },\n    {\n      title: 'Amazon',\n      initials: 'A',\n      amount: '-$99.99',\n      subtitle: '21 Mar 10:00AM',\n      color: 'orange',\n    },\n    {\n      title: 'Water Bill',\n      initials: 'W',\n      amount: '-$25.00',\n      subtitle: '16 Mar 9:00AM',\n      color: 'info',\n    },\n    {\n      title: 'Electricity Bill',\n      initials: 'E',\n      amount: '-$45.00',\n      subtitle: '14 Mar 8:00AM',\n      color: 'purple',\n    },\n  ]\n\n  const summaryItems = [\n    {\n      title: 'Revenue',\n      progress: 80,\n      text: 'R',\n      value: '$47,230',\n    },\n    {\n      title: 'Sales',\n      progress: 60,\n      text: 'S',\n      value: '$14,345',\n    },\n    {\n      title: 'Cost',\n      progress: 40,\n      text: 'C',\n      value: '$12,345',\n    },\n    {\n      title: 'Profit',\n      progress: 20,\n      text: 'P',\n      value: '$34,567',\n    },\n  ]\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/home/Gallery/Login.vue",
    "content": "<template>\n  <v-container class=\"h-100 pa-4\" fluid>\n    <v-row class=\"h-100 align-center justify-center\">\n      <v-sheet class=\"flex-1-1 px-4\" color=\"transparent\" max-width=\"420\">\n        <v-img\n          class=\"mx-auto mb-4\"\n          height=\"60\"\n          max-width=\"60\"\n          src=\"https://cdn.vuetifyjs.com/docs/images/logos/v.svg\"\n        />\n\n        <div class=\"text-headline-small text-center mb-8 font-weight-medium\">Log into your account</div>\n\n        <v-sheet border=\"opacity-25 thin\" class=\"overflow-hidden\" rounded=\"lg\">\n          <v-text-field\n            placeholder=\"Email\"\n            rounded=\"lg\"\n            value=\"john@vuetifyjs.com\"\n            variant=\"solo\"\n            hide-details\n          />\n\n          <v-divider />\n\n          <v-text-field\n            placeholder=\"Password\"\n            type=\"password\"\n            value=\"vuetify\"\n            variant=\"solo\"\n            hide-details\n          />\n        </v-sheet>\n\n        <div class=\"py-4\">\n          <div class=\"d-flex justify-space-between align-center\">\n            <v-checkbox-btn class=\"ms-n3\" color=\"primary\" label=\"Remember me\">\n              <template #label>\n                <span class=\"text-body-medium\">Remember me</span>\n              </template>\n            </v-checkbox-btn>\n\n            <a\n              class=\"text-decoration-none text-primary text-body-medium font-weight-medium cursor-pointer\"\n              @click=\"emit('login')\"\n            >\n              Forgot password?\n            </a>\n          </div>\n        </div>\n\n        <v-btn\n          class=\"text-none mb-8\"\n          color=\"primary\"\n          rounded=\"lg\"\n          text=\"Log In\"\n          block\n          flat\n          @click=\"emit('login')\"\n        />\n\n        <div class=\"text-center text-body-medium\">\n          Don't have an account?\n          <a\n            class=\"text-decoration-none text-primary font-weight-medium cursor-pointer\"\n            @click=\"emit('login')\"\n          >\n            Sign up\n          </a>\n        </div>\n      </v-sheet>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup lang=\"ts\">\n  const emit = defineEmits(['login'])\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/home/Gallery/Settings.vue",
    "content": "<template>\n  <div>\n    <v-toolbar color=\"transparent\">\n      <v-toolbar-title class=\"text-title-large\">Settings</v-toolbar-title>\n    </v-toolbar>\n\n    <v-tabs v-model=\"tab\" color=\"primary\">\n      <v-tab class=\"text-none\" value=\"profile\">Profile</v-tab>\n      <v-tab class=\"text-none\" value=\"security\">Security</v-tab>\n      <v-tab class=\"text-none\" value=\"notifications\">Notifications</v-tab>\n    </v-tabs>\n\n    <v-divider />\n\n    <v-tabs-window v-model=\"tab\">\n      <v-tabs-window-item value=\"profile\">\n        <v-container class=\"px-md-6 py-5\" fluid>\n          <v-row>\n            <v-col cols=\"12\">\n              <div class=\"d-flex align-center ga-4\">\n                <v-avatar image=\"https://cdn.vuetifyjs.com/docs/images/team/john.png\" rounded=\"lg\" size=\"80\" />\n\n                <div>\n                  <v-btn\n                    :loading=\"saving === 'avatar'\"\n                    class=\"mb-2 text-none\"\n                    color=\"surface-light\"\n                    prepend-icon=\"mdi-camera\"\n                    text=\"Change avatar\"\n                    variant=\"flat\"\n                    @click=\"save('avatar')\"\n                  />\n\n                  <p class=\"text-body-medium text-medium-emphasis\">JPG, GIF or PNG. 1MB max.</p>\n                </div>\n              </div>\n            </v-col>\n\n            <v-col cols=\"12\" sm=\"6\">\n              <v-text-field\n                v-model=\"profile.first\"\n                color=\"primary\"\n                label=\"First name\"\n                variant=\"outlined\"\n                hide-details\n              />\n            </v-col>\n\n            <v-col cols=\"12\" sm=\"6\">\n              <v-text-field\n                v-model=\"profile.last\"\n                color=\"primary\"\n                label=\"Last name\"\n                variant=\"outlined\"\n                hide-details\n              />\n            </v-col>\n\n            <v-col cols=\"12\">\n              <v-text-field\n                v-model=\"profile.email\"\n                color=\"primary\"\n                label=\"Email address\"\n                prepend-inner-icon=\"mdi-email\"\n                type=\"email\"\n                variant=\"outlined\"\n                hide-details\n              />\n            </v-col>\n\n            <v-col cols=\"12\">\n              <v-text-field\n                v-model=\"profile.username\"\n                append-inner-icon=\"mdi-open-in-new\"\n                color=\"primary\"\n                label=\"Username\"\n                prefix=\"github.com/\"\n                prepend-inner-icon=\"mdi-github\"\n                variant=\"outlined\"\n                hide-details\n                @click:append-inner=\"onClickUsername\"\n              />\n            </v-col>\n\n            <v-col cols=\"12\">\n              <v-text-field\n                v-model=\"profile.x\"\n                append-inner-icon=\"mdi-open-in-new\"\n                color=\"primary\"\n                label=\"Socials\"\n                prepend-inner-icon=\"$x\"\n                variant=\"outlined\"\n                hide-details\n                @click:append-inner=\"onClickSocials\"\n              />\n            </v-col>\n\n            <v-col cols=\"12\">\n              <v-select\n                v-model=\"profile.timezone\"\n                :items=\"timezones\"\n                color=\"primary\"\n                label=\"Timezone\"\n                prepend-inner-icon=\"mdi-earth\"\n                variant=\"outlined\"\n                hide-details\n              />\n            </v-col>\n\n            <v-col cols=\"12\">\n              <v-btn\n                :loading=\"saving === 'profile'\"\n                class=\"text-none\"\n                color=\"primary\"\n                text=\"Save changes\"\n                variant=\"flat\"\n                @click=\"save('profile')\"\n              />\n            </v-col>\n          </v-row>\n        </v-container>\n      </v-tabs-window-item>\n\n      <v-tabs-window-item value=\"security\">\n        <v-container class=\"px-md-6 py-5\" fluid>\n          <v-row>\n            <v-col cols=\"12\">\n              <h6 class=\"text-body-large font-weight-medium mb-1\">Change password</h6>\n\n              <p class=\"text-body-medium text-medium-emphasis\">Update your password associated with your account.</p>\n            </v-col>\n\n            <v-col cols=\"12\">\n              <v-text-field\n                color=\"primary\"\n                label=\"Current password\"\n                type=\"password\"\n                variant=\"outlined\"\n                hide-details\n              />\n            </v-col>\n\n            <v-col cols=\"12\" sm=\"6\">\n              <v-text-field\n                color=\"primary\"\n                label=\"New password\"\n                type=\"password\"\n                variant=\"outlined\"\n                hide-details\n              />\n            </v-col>\n\n            <v-col cols=\"12\" sm=\"6\">\n              <v-text-field\n                color=\"primary\"\n                label=\"Confirm password\"\n                type=\"password\"\n                variant=\"outlined\"\n                hide-details\n              />\n            </v-col>\n\n            <v-col cols=\"12\">\n              <v-btn\n                :loading=\"saving === 'password'\"\n                class=\"text-none\"\n                color=\"primary\"\n                text=\"Update password\"\n                variant=\"flat\"\n                @click=\"save('password')\"\n              />\n            </v-col>\n          </v-row>\n\n          <v-divider class=\"my-6\" />\n\n          <v-row>\n            <v-col cols=\"12\">\n              <h6 class=\"text-body-large font-weight-medium mb-1\">Two-factor authentication</h6>\n\n              <p class=\"text-body-medium text-medium-emphasis\">Add an extra layer of security to your account.</p>\n            </v-col>\n\n            <v-col cols=\"12\">\n              <v-switch\n                v-model=\"twoFactor\"\n                color=\"primary\"\n                label=\"Enable two-factor authentication\"\n                hide-details\n              />\n            </v-col>\n          </v-row>\n\n          <v-divider class=\"my-6\" />\n\n          <v-row>\n            <v-col cols=\"12\">\n              <h6 class=\"text-body-large font-weight-medium text-error mb-1\">Danger zone</h6>\n\n              <p class=\"text-body-medium text-medium-emphasis mb-4\">Permanently delete your account and all associated data.</p>\n\n              <v-btn\n                :loading=\"saving === 'delete'\"\n                class=\"text-none\"\n                color=\"error\"\n                prepend-icon=\"mdi-delete\"\n                text=\"Delete account\"\n                variant=\"tonal\"\n                @click=\"save('delete')\"\n              />\n            </v-col>\n          </v-row>\n        </v-container>\n      </v-tabs-window-item>\n\n      <v-tabs-window-item value=\"notifications\">\n        <v-container class=\"px-md-6 py-5\" fluid>\n          <v-row>\n            <v-col cols=\"12\">\n              <h6 class=\"text-body-large font-weight-medium mb-1\">Email notifications</h6>\n\n              <p class=\"text-body-medium text-medium-emphasis\">Manage your email notification preferences.</p>\n\n              <v-list lines=\"two\">\n                <v-list-item>\n                  <template #prepend>\n                    <v-checkbox-btn v-model=\"notifications.marketing\" class=\"me-1\" color=\"primary\" />\n                  </template>\n\n                  <v-list-item-title>Marketing emails</v-list-item-title>\n                  <v-list-item-subtitle>Receive emails about new features and updates.</v-list-item-subtitle>\n                </v-list-item>\n\n                <v-list-item>\n                  <template #prepend>\n                    <v-checkbox-btn v-model=\"notifications.security\" class=\"me-1\" color=\"primary\" />\n                  </template>\n\n                  <v-list-item-title>Security alerts</v-list-item-title>\n                  <v-list-item-subtitle>Get notified about security events on your account.</v-list-item-subtitle>\n                </v-list-item>\n\n                <v-list-item>\n                  <template #prepend>\n                    <v-checkbox-btn v-model=\"notifications.updates\" class=\"me-1\" color=\"primary\" />\n                  </template>\n\n                  <v-list-item-title>Product updates</v-list-item-title>\n                  <v-list-item-subtitle>Stay informed about product changes and improvements.</v-list-item-subtitle>\n                </v-list-item>\n              </v-list>\n            </v-col>\n\n            <v-col cols=\"12\">\n              <v-btn\n                :loading=\"saving === 'notifications'\"\n                class=\"text-none\"\n                color=\"primary\"\n                text=\"Save preferences\"\n                variant=\"flat\"\n                @click=\"save('notifications')\"\n              />\n            </v-col>\n          </v-row>\n        </v-container>\n      </v-tabs-window-item>\n    </v-tabs-window>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\n  const saving = shallowRef('')\n  const tab = shallowRef('profile')\n  const twoFactor = shallowRef(false)\n\n  const profile = ref({\n    first: 'John',\n    last: 'Leider',\n    email: 'john@vuetifyjs.com',\n    username: 'johnleider',\n    x: 'zeroskillz',\n    timezone: 'Central Standard Time',\n  })\n\n  const notifications = ref({\n    marketing: true,\n    security: true,\n    updates: false,\n  })\n\n  const timezones = [\n    'Pacific Standard Time',\n    'Eastern Standard Time',\n    'Central Standard Time',\n    'Greenwich Mean Time',\n  ]\n\n  function save (value: string) {\n    saving.value = value\n\n    setTimeout(() => {\n      saving.value = ''\n    }, 2000)\n  }\n\n  function onClickUsername () {\n    window.open('https://github.com/johnleider')\n  }\n\n  function onClickSocials () {\n    window.open('https://x.com/zeroskillz')\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/home/Logo.vue",
    "content": "<template>\n  <v-img\n    :height=\"size\"\n    :src=\"`https://cdn.vuetifyjs.com/docs/images/logos/${logo}`\"\n    :width=\"size\"\n    alt=\"Vuetify Logo\"\n    class=\"mx-auto\"\n    max-width=\"100%\"\n  />\n</template>\n\n<script setup>\n  defineProps({\n    size: String,\n  })\n\n  const theme = useTheme()\n\n  const logo = computed(() => {\n    return `vuetify-logo-${theme.current.value.dark ? 'dark' : 'light'}-atom.svg`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/home/Snips.vue",
    "content": "<template>\n  <v-img position=\"top\" src=\"https://cdn.vuetifyjs.com/docs/images/one/snips/hero.svg\">\n    <HomeCommonGradient color=\"primary\" opacity-class=\"opacity-10\" />\n\n    <v-container class=\"text-center text-md-left py-16\">\n      <v-row class=\"align-center\">\n        <v-col cols=\"12\" md=\"6\">\n          <v-img\n            :src=\"src\"\n            class=\"mb-4 d-inline-block\"\n            width=\"64\"\n          />\n\n          <p class=\"font-weight-medium d-none d-md-block text-primary\">\n            {{ t('home.snips.subtitle') }}\n          </p>\n\n          <h4 class=\"text-headline-large font-weight-bold my-4\">\n            {{ t('home.snips.title-line1') }}<br>{{ t('home.snips.title-line2') }}\n          </h4>\n\n          <h6 class=\"text-title-large font-weight-regular text-medium-emphasis mt-0 mb-5\">\n            {{ t('home.snips.description') }}\n          </h6>\n\n          <div>\n            <v-btn\n              :text=\"t('home.snips.browse')\"\n              append-icon=\"mdi-open-in-new\"\n              class=\"mr-4 text-none\"\n              color=\"primary\"\n              href=\"https://snips.vuetifyjs.com/\"\n              rounded=\"lg\"\n              size=\"large\"\n              target=\"_blank\"\n              variant=\"flat\"\n            />\n\n            <v-btn\n              :text=\"t('faq')\"\n              class=\"mr-4 text-none\"\n              color=\"primary\"\n              href=\"https://snips.vuetifyjs.com/#faqs\"\n              rounded=\"lg\"\n              size=\"large\"\n              target=\"_blank\"\n              variant=\"text\"\n            />\n          </div>\n\n        </v-col>\n\n        <v-col class=\"mb-n16 d-none d-md-block\" cols=\"12\" md=\"6\">\n          <div class=\"fade-gradient\">\n            <v-responsive max-height=\"500\">\n              <SnipsExample />\n            </v-responsive>\n          </div>\n        </v-col>\n      </v-row>\n    </v-container>\n  </v-img>\n</template>\n\n<script setup lang=\"ts\">\n  import SnipsExample from './SnipsExample.vue'\n\n  const { t } = useI18n()\n  const src = computed(() => `https://cdn.vuetifyjs.com/docs/images/one/logos/vsnips.png`)\n</script>\n\n<style scoped>\n.fade-gradient {\n  position: relative;\n  height: 100%;\n  pointer-events: none;\n}\n\n.fade-gradient::after {\n  content: '';\n  position: absolute;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  height: 50%;\n  background: linear-gradient(to bottom, transparent, rgb(var(--v-theme-background)));\n}\n</style>\n"
  },
  {
    "path": "packages/docs/src/components/home/SnipsExample.vue",
    "content": "<template>\n  <v-container class=\"pa-md-6\" fluid>\n    <v-row>\n      <v-col\n        v-for=\"(item, i) in items\"\n        :key=\"i\"\n        cols=\"12\"\n        md=\"6\"\n        sm=\"6\"\n      >\n        <v-card\n          class=\"mx-auto\"\n          elevation=\"2\"\n          rounded=\"lg\"\n        >\n          <v-img\n            :aspect-ratio=\"16/7\"\n            :src=\"item.image\"\n            class=\"cursor-pointer ma-2 mb-0 rounded-lg\"\n            cover\n          />\n\n          <div class=\"pt-1 pa-3\">\n            <div class=\"d-flex justify-space-between align-center\">\n              <span class=\"text-body-large font-weight-bold text-truncate\">{{ item.title }}</span>\n\n              <v-btn\n                color=\"grey\"\n                icon=\"mdi-heart\"\n                size=\"x-small\"\n                variant=\"text\"\n              />\n            </div>\n\n            <div class=\"d-flex align-center ga-1 text-body-small text-medium-emphasis\">\n              <v-icon icon=\"mdi-calendar-blank-outline\" size=\"small\" />\n              {{ item.createdAt }}\n            </div>\n\n          </div>\n        </v-card>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  const items = [\n    {\n      title: 'Misty Mountains',\n      image: 'https://cdn.vuetifyjs.com/docs/images/cards/mountain.jpg',\n      createdAt: '1st Dec 2025',\n    },\n    {\n      title: 'Lake Reflection',\n      image: 'https://cdn.vuetifyjs.com/docs/images/cards/sky.jpg',\n      createdAt: '2nd Dec 2025',\n    },\n    {\n      title: 'Forest Sunrise',\n      image: 'https://cdn.vuetifyjs.com/docs/images/cards/forest.jpg',\n      createdAt: '3rd Dec 2025',\n    },\n    {\n      title: 'Mountain Vista',\n      image: 'https://cdn.vuetifyjs.com/docs/images/cards/desert.jpg',\n      createdAt: '4th Dec 2025',\n    },\n    {\n      title: 'Lava Dripping',\n      image: 'https://cdn.vuetifyjs.com/docs/images/cards/forest-art.jpg',\n      createdAt: '5th Dec 2025',\n    },\n    {\n      title: 'Lightning Storm',\n      image: 'https://cdn.vuetifyjs.com/docs/images/cards/hands.jpg',\n      createdAt: '6th Dec 2025',\n    },\n    {\n      title: 'Rock Monolith',\n      image: 'https://cdn.vuetifyjs.com/docs/images/cards/sunshine.jpg',\n      creator: 'Natalie Smith',\n      avatar: 'https://randomuser.me/api/portraits/women/24.jpg',\n      createdAt: '7th Dec 2025',\n    },\n    {\n      title: 'Northern Lights',\n      image: 'https://images.unsplash.com/photo-1491466424936-e304919aada7',\n      creator: 'Jason Doe',\n      avatar: 'https://randomuser.me/api/portraits/men/64.jpg',\n      createdAt: '8th Dec 2025',\n    },\n  ]\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/home/SpecialSponsor.vue",
    "content": "<template>\n  <v-responsive v-if=\"specialSponsor\">\n    <v-divider color=\"primary\" />\n\n    <HomeCommonGradient\n      :opacity-class=\"isDark ? 'opacity-40' : 'opacity-20'\"\n      color=\"primary\"\n    />\n\n    <div class=\"d-flex align-center justify-center my-1 px-4\">\n      <small class=\"font-weight-bold text-no-wrap\">{{ t('home.special-sponsor') }}</small>\n\n      <SponsorCard\n        :slug=\"specialSponsor.slug\"\n        min-height=\"64\"\n        width=\"200\"\n      />\n    </div>\n\n    <v-divider color=\"primary\" />\n  </v-responsive>\n</template>\n\n<script setup>\n  const { t } = useI18n()\n  const theme = useTheme()\n  const store = useSponsorsStore()\n\n  const isDark = computed(() => theme.current.value.dark)\n  const specialSponsor = computed(() => store.byTier[-2]?.[0])\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/home/Sponsors.vue",
    "content": "<template>\n  <v-responsive class=\"pb-16\">\n    <HomeCommonGradient opacity-class=\"opacity-10\" />\n\n    <HomeCommonGradient opacity-class=\"opacity-40\" position=\"center\" />\n\n    <v-container class=\"pt-10\">\n\n      <HomeCommonTitle\n        :description=\"t('home.sponsors.description')\"\n        :title=\"t('home.sponsors.title')\"\n        class=\"mb-9\"\n      >\n        <template #subtitle>\n          <v-icon\n            class=\"mb-5\"\n            color=\"red-lighten-2\"\n            icon=\"mdi-heart-outline\"\n            size=\"60\"\n          />\n        </template>\n      </HomeCommonTitle>\n\n      <v-responsive class=\"mx-auto\" max-width=\"800\">\n        <v-row\n          class=\"justify-center\"\n          density=\"comfortable\"\n        >\n          <v-col\n            v-for=\"sponsor in sponsors\"\n            :key=\"sponsor.slug\"\n            class=\"d-flex align-center justify-center ma-1\"\n            cols=\"auto\"\n          >\n            <SponsorCard\n              :comfortable=\"Number(sponsor.metadata.tier) === 2\"\n              :compact=\"Number(sponsor.metadata.tier) > 2\"\n              :sponsor=\"sponsor\"\n              v-bind=\"$attrs\"\n              :width=\"Number(sponsor.metadata.tier) > 1 && smAndDown ? 90 : undefined\"\n            />\n          </v-col>\n        </v-row>\n      </v-responsive>\n\n      <v-hover v-slot=\"{ props: hoverProps, isHovering }\">\n        <v-btn\n          v-bind=\"hoverProps\"\n          :append-icon=\"isHovering ? 'mdi-heart' : 'mdi-heart-outline'\"\n          :text=\"t('home.sponsors.become-sponsor')\"\n          class=\"text-none mt-9\"\n          color=\"primary\"\n          rounded=\"lg\"\n          size=\"large\"\n          flat\n        />\n      </v-hover>\n    </v-container>\n  </v-responsive>\n</template>\n\n<script setup lang=\"ts\">\n  const { t } = useI18n()\n  const { smAndDown } = useDisplay()\n  const sponsorStore = useSponsorsStore()\n\n  const sponsors = computed(() => {\n    return Object.values(sponsorStore.byTier)\n      .reduce((tiers, tier) => {\n        for (const sponsor of tier) {\n          if (Number(sponsor.metadata.tier) < 0) continue\n\n          tiers.push(sponsor)\n        }\n\n        return tiers\n      }, [])\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/home/Store.vue",
    "content": "<template>\n  <v-responsive class=\"py-16\">\n    <HomeCommonGradient opacity-class=\"opacity-10\" />\n\n    <v-container class=\"pt-0\" max-width=\"2000\" fluid>\n      <HomeCommonTitle\n        :description=\"t('home.store.description')\"\n        :subtitle=\"t('home.store.subtitle')\"\n        :title=\"t('home.store.title')\"\n        class=\"mb-10\"\n      >\n        <template #top>\n          <v-img :src=\"`https://cdn.vuetifyjs.com/docs/images/one/logos/vstore.png`\" class=\"mb-4\" height=\"64\" />\n        </template>\n      </HomeCommonTitle>\n\n      <v-row v-if=\"!items.length\">\n        <v-col\n          v-for=\"n in 9\"\n          :key=\"n\"\n          cols=\"12\"\n          md=\"4\"\n        >\n          <v-skeleton-loader class=\"rounded-b-0\" height=\"180\" />\n\n          <v-skeleton-loader class=\"rounded-t-0\" type=\"text\" />\n        </v-col>\n      </v-row>\n\n      <v-slide-group\n        v-else\n        class=\"mb-10\"\n        content-class=\"mx-3 rounded-lg\"\n        show-arrows\n      >\n        <template #next>\n          <v-btn\n            class=\"mb-15\"\n            icon=\"mdi-chevron-right\"\n          />\n        </template>\n        <template #prev>\n          <v-btn\n            class=\"mb-15\"\n            icon=\"mdi-chevron-left\"\n          />\n        </template>\n\n        <v-slide-group-item\n          v-for=\"product in items\"\n          :key=\"product.id\"\n        >\n          <a\n            :href=\"`https://store.vuetifyjs.com/products/${product.handle}`\"\n            class=\"d-block text-decoration-none mx-5\"\n            rel=\"noopener noreferrer\"\n            style=\"width: 300px\"\n            target=\"_blank\"\n          >\n            <DocThemeCard\n              :product=\"{\n                title: product.title,\n                src: product.image,\n              }\"\n              class=\"text-center\"\n            />\n          </a>\n        </v-slide-group-item>\n      </v-slide-group>\n\n      <v-btn\n        :aria-label=\"t('home.store.see-more')\"\n        :text=\"t('home.store.see-more')\"\n        append-icon=\"mdi-open-in-new\"\n        class=\"text-none\"\n        color=\"primary\"\n        href=\"https://store.vuetifyjs.com\"\n        rel=\"noopener noreferrer\"\n        rounded=\"lg\"\n        size=\"large\"\n        target=\"_blank\"\n        variant=\"flat\"\n      />\n    </v-container>\n  </v-responsive>\n</template>\n\n<script setup lang=\"ts\">\n  import type { ShopifyProduct } from '@vuetify/one'\n\n  const { t } = useI18n()\n  const products = useProductsStore()\n\n  const items = shallowRef<ShopifyProduct[]>([])\n\n  onMounted(async () => {\n    await products.index()\n\n    items.value = products.randomize(products.themes)\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/home/Support.vue",
    "content": "<template>\n  <v-responsive class=\"py-5\">\n    <HomeCommonGradient color=\"primary\" opacity-class=\"opacity-10\" />\n\n    <v-container class=\"text-center text-md-left py-16\">\n      <v-row class=\"align-end\">\n        <v-col class=\"pr-md-15\" cols=\"12\" md=\"6\">\n          <p class=\"font-weight-medium text-primary\">\n            {{ t('home.support.subtitle') }}\n          </p>\n\n          <h4 class=\"text-headline-large font-weight-bold my-5\">\n            {{ t('home.support.title') }}\n          </h4>\n\n          <h6 class=\"text-title-large font-weight-regular text-medium-emphasis my-5\">\n            {{ t('home.support.description') }}\n          </h6>\n\n          <div class=\"my-5\">\n            <v-btn\n              :text=\"t('home.support.get-support')\"\n              :to=\"rpath('introduction/enterprise-support/')\"\n              append-icon=\"mdi-open-in-new\"\n              class=\"mr-4 text-none\"\n              color=\"primary\"\n              rounded=\"lg\"\n              size=\"large\"\n              target=\"_blank\"\n              variant=\"flat\"\n            />\n          </div>\n        </v-col>\n\n        <v-col cols=\"12\" md=\"6\">\n          <v-card color=\"transparent\" rounded=\"lg\" flat>\n            <v-defaults-provider\n              :defaults=\"{\n                'VListItem': {\n                  rounded: 'lg'\n                }\n              }\"\n            >\n              <v-list\n                :items=\"supportServices\"\n                class=\"py-3 bg-transparent text-left\"\n                lines=\"two\"\n                item-props\n                rounded\n              >\n                <template #prepend=\"{ item }\">\n                  <v-avatar :image=\"item.avatar\" size=\"small\" />\n                </template>\n\n                <template #append>\n                  <v-icon-btn\n                    class=\"text-none ml-2\"\n                    color=\"primary\"\n                    icon=\"mdi-open-in-new\"\n                    roundeed=\"circle\"\n                    size=\"small\"\n                    variant=\"text\"\n                  />\n                </template>\n              </v-list>\n            </v-defaults-provider>\n          </v-card>\n        </v-col>\n      </v-row>\n    </v-container>\n  </v-responsive>\n</template>\n\n<script setup lang=\"ts\">\n  const { t } = useI18n()\n\n  const supportServices = computed(() => [\n    {\n      avatar: 'https://cdn.vuetifyjs.com/docs/images/logos/v.svg',\n      title: t('home.support.services.developer.title'),\n      subtitle: t('home.support.services.developer.subtitle'),\n      href: rpath('introduction/enterprise-support/'),\n      target: '_blank',\n      rel: 'noopener noreferrer',\n    },\n    { type: 'divider', class: 'my-4', inset: true },\n    {\n      avatar: 'https://cdn.vuetifyjs.com/docs/images/affiliates/epic-max.jpg',\n      title: t('home.support.services.consulting.title'),\n      subtitle: t('home.support.services.consulting.subtitle'),\n      to: rpath('/introduction/enterprise-support/#consulting-services'),\n      target: '_blank',\n      rel: 'noopener noreferrer',\n    },\n    { type: 'divider', class: 'my-4', inset: true },\n    {\n      // TODO: Use proper image URL\n      avatar: 'https://cdn.vuetifyjs.com/docs/images/affiliates/hero-devs.png',\n      title: t('home.support.services.lts.title'),\n      class: 'mb-2',\n      subtitle: t('home.support.services.lts.subtitle'),\n      href: 'https://v2.vuetifyjs.com/about/eol/#consider-herodevs-extended-lts-support',\n      target: '_blank',\n      rel: 'noopener noreferrer',\n    },\n  ])\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/home/Tooling.vue",
    "content": "<template>\n  <v-responsive class=\"py-16\">\n    <HomeCommonGradient opacity-class=\"opacity-10\" />\n\n    <v-container>\n      <HomeCommonTitle\n        :description=\"t('home.tooling.description')\"\n        :subtitle=\"t('home.tooling.subtitle')\"\n        :title=\"t('home.tooling.title')\"\n        class=\"mb-10\"\n      >\n\n        <template #top>\n          <v-img :src=\"`https://cdn.vuetifyjs.com/docs/images/one/logos/vloader.png`\" class=\"mb-4\" height=\"64\" />\n        </template>\n      </HomeCommonTitle>\n\n      <v-card class=\"mx-auto\" max-width=\"900\" rounded=\"xl\" border flat>\n        <v-table density=\"comfortable\" hover>\n          <thead>\n            <tr>\n              <th class=\"text-left\">{{ t('home.tooling.headers.tool') }}</th>\n              <th class=\"text-left\">{{ t('home.tooling.headers.type') }}</th>\n              <th class=\"text-left d-none d-sm-table-cell\">{{ t('home.tooling.headers.description') }}</th>\n            </tr>\n          </thead>\n\n          <tbody class=\"text-start\">\n            <v-hover v-for=\"(item, i) in tools\" :key=\"i\">\n              <template #default=\"{ isHovering, props: hoverProps }\">\n                <tr v-bind=\"hoverProps\">\n                  <td>\n                    <div class=\"d-flex align-center ga-3 py-2\">\n                      <v-avatar :color=\"item.color\" rounded=\"xl\" variant=\"tonal\">\n                        <v-icon :icon=\"item.icon\" />\n                      </v-avatar>\n\n                      <div>\n                        <a\n                          :href=\"item.href\"\n                          class=\"font-weight-medium inline-block on-surface text-decoration-none\"\n                          rel=\"noopener\"\n                          target=\"_blank\"\n                        >\n                          {{ item.title }}\n\n                          <v-icon :class=\"isHovering ? 'opacity-100' : 'opacity-0'\" icon=\"mdi-open-in-new\" size=\"xs\" />\n                        </a>\n                        <div class=\"text-body-small text-medium-emphasis d-sm-none\">{{ item.type }}</div>\n                      </div>\n                    </div>\n                  </td>\n\n                  <td class=\"text-no-wrap\">\n                    <v-chip :color=\"item.color\" :text=\"item.type\" size=\"small\" variant=\"tonal\" />\n                  </td>\n\n                  <td class=\"text-medium-emphasis d-none d-sm-table-cell\">\n                    {{ item.description }}\n                  </td>\n                </tr>\n              </template></v-hover>\n          </tbody>\n        </v-table>\n      </v-card>\n    </v-container>\n  </v-responsive>\n</template>\n\n<script setup lang=\"ts\">\n  const { t } = useI18n()\n\n  const tools = computed(() => [\n    {\n      title: t('home.tooling.tools.create.title'),\n      icon: '$vuetify-create',\n      type: t('home.tooling.tools.create.type'),\n      color: 'info',\n      description: t('home.tooling.tools.create.description'),\n      href: 'https://github.com/vuetifyjs/create/',\n    },\n    {\n      title: t('home.tooling.tools.cli.title'),\n      // TODO: update once cli icon added to @vuetify/one\n      // icon: '$vuetify-cli',\n      icon: 'mdi-console',\n      type: t('home.tooling.tools.cli.type'),\n      color: 'info',\n      description: t('home.tooling.tools.cli.description'),\n      href: 'https://github.com/vuetifyjs/cli/',\n    },\n    {\n      title: t('home.tooling.tools.uikit.title'),\n      icon: '$vuetify-figma',\n      type: t('home.tooling.tools.uikit.type'),\n      color: 'purple',\n      description: t('home.tooling.tools.uikit.description'),\n      href: 'https://store.vuetifyjs.com/products/vuetify-ui-kit-figma',\n    },\n    {\n      title: t('home.tooling.tools.eslint-config.title'),\n      icon: 'mdi-code-tags-check',\n      type: t('home.tooling.tools.eslint-config.type'),\n      color: 'success',\n      description: t('home.tooling.tools.eslint-config.description'),\n      href: 'https://github.com/vuetifyjs/eslint-config-vuetify',\n    },\n    {\n      title: t('home.tooling.tools.eslint-plugin.title'),\n      icon: 'mdi-arrow-up-bold-circle-outline',\n      type: t('home.tooling.tools.eslint-plugin.type'),\n      color: 'info',\n      description: t('home.tooling.tools.eslint-plugin.description'),\n      href: 'https://github.com/vuetifyjs/eslint-plugin-vuetify',\n    },\n    {\n      title: t('home.tooling.tools.loader.title'),\n      icon: 'mdi-package-variant-closed',\n      type: t('home.tooling.tools.loader.type'),\n      color: 'warning',\n      description: t('home.tooling.tools.loader.description'),\n      href: 'https://github.com/vuetifyjs/vuetify-loader',\n    },\n  ])\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/home/VuetifyOne.vue",
    "content": "<template>\n  <v-responsive class=\"py-10\">\n    <HomeCommonGradient opacity-class=\"opacity-10\" />\n\n    <v-container>\n      <HomeCommonTitle\n        :description=\"t('home.one.description')\"\n        :subtitle=\"t('home.one.subtitle')\"\n        :title=\"t('home.one.title')\"\n      >\n        <template #top>\n          <v-img :src=\"`https://cdn.vuetifyjs.com/docs/images/one/logos/vone.png`\" class=\"mb-4\" height=\"88\" />\n        </template>\n      </HomeCommonTitle>\n\n      <v-row class=\"text-left mt-10\">\n        <v-col\n          v-for=\"(item, i) in toolings\"\n          :key=\"i\"\n          cols=\"12\"\n          lg=\"4\"\n          sm=\"6\"\n        >\n          <HomeCommonCard\n            :description=\"item.description\"\n            :href=\"item.href\"\n            :image=\"`https://cdn.vuetifyjs.com/docs/images/one/logos/${item.image}-logo-${isDark ? 'dark' : 'light'}.png`\"\n            target=\"_blank\"\n          />\n        </v-col>\n\n        <v-col class=\"text-center mt-6\" cols=\"12\">\n          <v-btn\n            :text=\"t('home.one.see-benefits')\"\n            :to=\"rpath('/one/')\"\n            append-icon=\"mdi-page-next\"\n            class=\"mr-4 text-none\"\n            color=\"primary\"\n            rounded=\"lg\"\n            size=\"large\"\n            variant=\"flat\"\n          />\n        </v-col>\n      </v-row>\n    </v-container>\n  </v-responsive>\n</template>\n\n<script setup lang=\"ts\">\n  const { t } = useI18n()\n  const theme = useTheme()\n  const isDark = computed(() => theme.current.value.dark)\n\n  const toolings = computed(() => [\n    {\n      name: 'Vuetify Play',\n      image: 'vplay',\n      description: t('home.one.tools.play'),\n      href: 'https://play.vuetifyjs.com',\n    },\n    {\n      name: 'Vuetify Bin',\n      image: 'vbin',\n      description: t('home.one.tools.bin'),\n      href: 'https://bin.vuetifyjs.com',\n    },\n    {\n      name: 'Vuetify Studio',\n      image: 'vstudio',\n      description: t('home.one.tools.studio'),\n      href: 'https://studio.vuetifyjs.com',\n    },\n    {\n      name: 'Vuetify Link',\n      image: 'vlink',\n      description: t('home.one.tools.link'),\n      href: 'https://link.vuetifyjs.com',\n    },\n    {\n      name: 'Vuetify MCP',\n      image: 'vmcp',\n      description: t('home.one.tools.mcp'),\n      href: 'https://github.com/vuetifyjs/mcp/',\n    },\n    {\n      name: 'Vuetify Issues',\n      image: 'vissues',\n      description: t('home.one.tools.issues'),\n      href: 'https://issues.vuetifyjs.com',\n    },\n  ])\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/icons/ChevronDown.vue",
    "content": "<template>\n  <v-icon\n    class=\"hidden-sm-and-down\"\n    icon=\"mdi-chevron-down\"\n    size=\"14\"\n  />\n</template>\n\n<script setup>\n  //\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/introduction/Comparison.vue",
    "content": "<template>\n  <v-sheet\n    id=\"comparison\"\n    class=\"mb-5 text-body-medium mx-auto\"\n    border\n    rounded\n  >\n    <v-table>\n      <AppCaption class=\"pa-4 text-title-large\">\n        {{ t('comparison.caption', { year: (new Date()).getFullYear() }) }}\n      </AppCaption>\n\n      <thead>\n        <tr>\n          <th>\n            <strong class=\"text-title-large\">{{ t('features') }}</strong>\n          </th>\n\n          <th\n            v-for=\"(framework, i) in frameworks\"\n            :key=\"i\"\n            class=\"text-center text-no-wrap\"\n          >\n            <div class=\"d-flex align-center justify-center text-body-medium\">\n              <v-img\n                v-if=\"framework.src\"\n                :src=\"framework.src\"\n                class=\"me-2\"\n                height=\"24\"\n                max-width=\"24\"\n                width=\"24\"\n              />\n\n              <div v-text=\"framework.name\" />\n            </div>\n          </th>\n        </tr>\n      </thead>\n\n      <tbody>\n        <tr\n          v-for=\"(key, i) in features\"\n          :key=\"i\"\n        >\n          <td class=\"text--secondary text-start\">{{ t(`comparison.${key}`) }}</td>\n\n          <td\n            v-for=\"(framework, j) in frameworks\"\n            :key=\"j\"\n            class=\"text-center\"\n          >\n            <template v-if=\"framework[key]\">\n              <v-icon\n                v-if=\"typeof framework[key] === 'boolean'\"\n                color=\"success\"\n              >\n                mdi-record\n              </v-icon>\n\n              <span\n                v-else-if=\"typeof framework[key] === 'string'\"\n                class=\"font-weight-light\"\n                v-text=\"framework[key]\"\n              />\n            </template>\n          </td>\n        </tr>\n      </tbody>\n\n      <tfoot class=\"text-center\">\n        <tr>\n          <td\n            class=\"text-body-small font-italic text-disabled\"\n            colspan=\"7\"\n          >\n            <div>{{ t('comparison.average') }}</div>\n          </td>\n        </tr>\n      </tfoot>\n    </v-table>\n  </v-sheet>\n</template>\n\n<script setup lang=\"ts\">\n  // Types\n  type Framework = {\n    a11y?: boolean,\n    enterprise?: boolean,\n    lts?: boolean,\n    name: string,\n    release: string,\n    rtl?: boolean,\n    src: string,\n    themes?: boolean,\n    tree: string,\n  }\n\n  const features = [\n    'a11y',\n    'enterprise',\n    'lts',\n    'release',\n    'rtl',\n    'themes',\n    'tree',\n  ] as const\n\n  const frameworks: Framework[] = [\n    {\n      a11y: true,\n      enterprise: true,\n      lts: true,\n      name: 'Vuetify',\n      release: 'Weekly',\n      rtl: true,\n      src: 'https://cdn.vuetifyjs.com/docs/images/frameworks/vuetify.svg',\n      themes: true,\n      tree: 'Automatic',\n    },\n    {\n      a11y: true,\n      name: 'BootstrapVue',\n      release: 'Bi-Weekly',\n      rtl: true,\n      src: 'https://cdn.vuetifyjs.com/docs/images/frameworks/bootstrap-vue.svg',\n      themes: true,\n      tree: 'Manual',\n    },\n    {\n      a11y: true,\n      name: 'Buefy',\n      release: 'Bi-Monthly',\n      src: 'https://cdn.vuetifyjs.com/docs/images/frameworks/buefy.svg',\n      tree: 'Manual',\n    },\n    {\n      name: 'Element UI',\n      release: 'Bi-Weekly',\n      rtl: true,\n      src: 'https://cdn.vuetifyjs.com/docs/images/frameworks/element-ui.svg',\n      tree: 'Manual',\n    },\n    {\n      name: 'Quasar',\n      release: 'Bi-Weekly',\n      rtl: true,\n      src: 'https://cdn.vuetifyjs.com/docs/images/frameworks/quasar.svg',\n      tree: 'Automatic',\n    },\n  ]\n\n  const { t } = useI18n()\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/introduction/ConsultingServices.vue",
    "content": "<template>\n  <v-sheet\n    border=\"s e b\"\n    class=\"overflow-hidden\"\n    max-width=\"900\"\n    rounded\n  >\n    <v-divider\n      class=\"border-opacity-100\"\n      color=\"primary\"\n      thickness=\"4\"\n    />\n\n    <v-container class=\"pt-9 px-5\" fluid>\n      <v-row class=\"justify-space-around\" density=\"comfortable\">\n        <template v-for=\"({ text, href, name, btnText, notes, extra }, i) in cards\" :key=\"i\">\n          <v-col cols=\"12\" md=\"6\">\n            <v-responsive class=\"h-100\" content-class=\"d-flex flex-column\">\n              <h3 class=\"d-flex align-center text-title-large font-weight-medium mb-4\">\n                {{ name }}\n              </h3>\n\n              <div class=\"mb-auto text-body-small\">\n                <div class=\"mb-4\">{{ text }}</div>\n                <ul v-if=\"notes && notes.length\" class=\"mb-0 ml-5\">\n                  <li v-for=\"(item, j) in notes\" :key=\"j\">{{ item }}</li>\n                </ul>\n              </div>\n\n              <div v-if=\"extra\" class=\"mb-auto text-body-small mt-4\">\n                {{ extra }}\n              </div>\n\n              <v-btn\n                :href=\"href\"\n                :text=\"btnText\"\n                :variant=\"i === 3 ? 'flat' : 'outlined'\"\n                class=\"text-none mt-8\"\n                color=\"primary\"\n                rel=\"noopener\"\n                target=\"_blank\"\n              />\n\n              <v-divider class=\"my-8\" />\n            </v-responsive>\n          </v-col>\n        </template>\n      </v-row>\n\n      <div class=\"text-medium-emphasis text-body-small\">\n        *View more detailed information on\n        <AppLink href=\"https://www.epicmax.co/\">\n          Epicmax.co\n        </AppLink>\n      </div>\n    </v-container>\n  </v-sheet>\n</template>\n\n<script setup>\n  const cards = [\n    {\n      name: '🧩 Vuetify App Development',\n      href: 'https://calendar.google.com/calendar/u/0/appointments/schedules/AcZssZ1ICL1_pVx87WpbxCeAKPNljw8Wr8Og4-NuzbUV-RHlxs-c_B8s2nYZ0RAWPcVqTx4Dn568c5OA',\n      text: 'Epicmax helps companies build and improve Vuetify apps of any size - from brand-new products to complex legacy systems. Our senior Vue.js team resolves performance issues, modernizes legacy codebases, and develops scalable frontend architectures with clean, intuitive UI/UX designs. If you need reliable Vuetify experts to optimize, upgrade, or extend your app, we’ve got you covered.',\n      btnText: 'Book a Consultation',\n    },\n    {\n      name: '🔁 Vuetify 2 → Vuetify 3 Migration',\n      href: 'https://epicmax.co/vue-3-migration#migration-form',\n      text: 'Still running on Vuetify 2? Our Vuetify migration experts ensure a smooth upgrade to Vuetify 3 - with zero downtime, clear budget estimates, and long-term support.',\n      notes: ['⚙️ Every migration includes a free audit and upgrade plan.'],\n      btnText: 'Request Migration',\n    },\n    {\n      name: '🔍 Frontend Code Audit Services',\n      href: 'https://epicmax.co/code-audit#request_form',\n      text: 'Ensure your app runs at its best with Epicmax’s Vue.js and Vuetify code audit services. We provide a detailed technical review, highlight performance bottlenecks, and deliver a prioritized roadmap with actionable fixes.',\n      notes: ['💡 Use code VUETIFY for 20% off.'],\n      btnText: 'Request an Audit',\n    },\n    {\n      name: '👨‍💻 Hire Senior Vuetify Developers',\n      href: 'https://calendar.google.com/calendar/u/0/appointments/schedules/AcZssZ1ICL1_pVx87WpbxCeAKPNljw8Wr8Og4-NuzbUV-RHlxs-c_B8s2nYZ0RAWPcVqTx4Dn568c5OA',\n      text: 'Scale your team with Epicmax’s senior Vue.js and Vuetify developers. Our engineers seamlessly integrate into your workflow, modernize legacy Vue.js applications, optimize frontend performance, and build scalable web applications with clean, reliable UI/UX.',\n      btnText: 'Hire Developers',\n    },\n    {\n      name: '🤔 Not Sure if You Should Migrate?',\n      href: 'https://calendar.app.google/XwRzASZitZRSVLxq6',\n      text: 'If you\\'re unsure about migrating from Vuetify 2 to Vuetify 3, Epicmax offers a free consultation with our technical lead to help you decide:',\n      notes: [\n        'Is now the best time to migrate?',\n        'What’s the real effort and cost?',\n        'What risks should you prepare for?',\n      ],\n      extra: 'You’ll get a complete technical and business roadmap — so you can migrate now or later with confidence.',\n      btnText: 'Get Free Expert Advice',\n    },\n  ]\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/introduction/DirectSupport.vue",
    "content": "<template>\n  <v-row>\n    <v-col\n      v-for=\"(person, index) in direct\"\n      :key=\"index\"\n      cols=\"12\"\n      md=\"5\"\n      sm=\"6\"\n      xl=\"4\"\n    >\n      <AppSheet class=\"text-center px-10 py-8\">\n        <v-avatar :image=\"person.image\" size=\"x-large\" />\n\n        <div class=\"text-title-large text-high-emphasis mb-8\">\n          {{ person.name }}\n\n          <small class=\"text-body-small d-block text-medium-emphasis\">\n            {{ person.title }}\n          </small>\n        </div>\n\n        <div class=\"text-headline-small font-weight-black\">\n          <span class=\"text-high-emphasis\">${{ person.price }}</span>\n\n          <small class=\"font-weight-regular\"> / {{ person.duration }}mins</small>\n        </div>\n\n        <br>\n        <br>\n\n        <v-btn\n          :href=\"person.link\"\n          append-icon=\"mdi-open-in-new\"\n          color=\"primary\"\n          target=\"_blank\"\n          variant=\"flat\"\n          block\n        >\n          Book Now\n        </v-btn>\n      </AppSheet>\n    </v-col>\n  </v-row>\n</template>\n\n<script setup>\n  const direct = [\n    {\n      name: 'John Leider',\n      title: 'Author of Vuetify',\n      price: 180,\n      duration: 60,\n      link: 'https://l.kintell.com/M9y7D7',\n      image: 'https://cdn.vuetifyjs.com/docs/images/team/john.png',\n    },\n  ]\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/introduction/DiscordDeck.vue",
    "content": "<template>\n  <v-sheet\n    border=\"s e b\"\n    class=\"overflow-hidden\"\n    max-width=\"900\"\n    rounded\n  >\n    <v-divider\n      class=\"border-opacity-100\"\n      color=\"#6458f2\"\n      thickness=\"4\"\n    />\n\n    <v-container class=\"pt-9 px-5\" fluid>\n      <v-row class=\"justify-space-around\" density=\"comfortable\">\n        <template v-for=\"(tier, i) in tiers\" :key=\"i\">\n          <v-col cols=\"12\" md=\"4\">\n            <v-responsive :min-height=\"mdAndUp ? 96 : undefined\" class=\"mb-4\">\n              <h3 class=\"d-flex align-center text-title-large font-weight-medium mb-4\">\n                <v-avatar :image=\"tier.src\" class=\"me-3\" />\n\n                <div>\n                  {{ tier.name }}\n\n                  <div class=\"text-headline-small font-weight-bold\">\n                    {{ tier.price }}<span v-if=\"tier.suffix\" class=\"font-weight-medium text-medium-emphasis text-body-medium\">{{ tier.suffix }}</span>\n                  </div>\n                </div>\n              </h3>\n\n              <v-btn\n                :href=\"tier.href\"\n                :text=\"tierText(tier)\"\n                :variant=\"i === 1 ? 'flat' : 'outlined'\"\n                class=\"mb-6 text-none\"\n                color=\"#6458f2\"\n                rel=\"noopener\"\n                target=\"_blank\"\n                block\n              />\n\n              <div class=\"text-body-small\">{{ tier.text }}</div>\n            </v-responsive>\n\n            <v-divider class=\"mb-4\" />\n\n            <ul class=\"text-body-small ps-1\" style=\"list-style-type: none;\">\n              <li v-for=\"(benefit, k) in tier.benefits\" :key=\"k\" class=\"mb-2 d-flex\">\n                <div class=\"me-2\">{{ benefit.emoji }}</div>\n\n                <div>\n                  <strong>{{ benefit.name }}</strong>\n\n                  <div>\n                    {{ benefit.text }}\n                  </div>\n                </div>\n              </li>\n            </ul>\n          </v-col>\n        </template>\n      </v-row>\n    </v-container>\n\n    <div class=\"px-4 pb-3 text-medium-emphasis text-body-small\">\n      *View more detailed information on our <AppLink\n        href=\"https://discord.com/servers/vuetify-340160225338195969\"\n      >\n        Discord Welcome Page\n      </AppLink>\n    </div>\n  </v-sheet>\n</template>\n\n<script setup>\n  const { mdAndUp } = useDisplay()\n\n  const tiers = [\n    {\n      name: 'Wood Tier',\n      price: '$2.99',\n      suffix: '/mo',\n      trial: true,\n      href: 'https://discord.com/invite/jZq4rzazEr',\n      src: 'https://cdn.vuetifyjs.com/docs/images/discord/tiers/wood.png',\n      text: 'Get access to sponsor only chat and help channels.',\n      benefits: [\n        {\n          name: '#subscribers',\n          text: 'Say hello and talk to other developers in this private subscriber only channel.',\n          emoji: '💪',\n        },\n        {\n          name: '#subscriber-help',\n          text: 'Get priority help in our Subscriber only help channel.',\n          emoji: '🚑',\n        },\n      ],\n    },\n    {\n      name: 'Gold Tier',\n      price: '$19.99',\n      suffix: '/mo',\n      href: 'https://discord.com/invite/jZq4rzazEr',\n      src: 'https://cdn.vuetifyjs.com/docs/images/discord/tiers/gold.png',\n      text: 'Get access to our daily Vuetify development updates.',\n      benefits: [\n        {\n          text: 'Every channel in Wood Tier plus:',\n          emoji: '🪵',\n        },\n        {\n          name: '🔥dev-stream',\n          text: 'Inside peek of current Vuetify development.',\n          emoji: '🎉',\n        },\n      ],\n    },\n    {\n      name: 'Planetary Tier',\n      price: '$99.99',\n      suffix: '/mo',\n      href: 'https://discord.com/invite/jZq4rzazEr',\n      src: 'https://cdn.vuetifyjs.com/docs/images/discord/tiers/planetary.png',\n      text: 'Get help directly from the Core team with a private help channel.',\n      benefits: [\n        {\n          text: 'Every channel in Gold Tier plus:',\n          emoji: '🥇',\n        },\n        {\n          name: 'Private Help Channel',\n          text: 'Get a private help channel where you can ask questions to the Core Team.',\n          emoji: '🔨',\n        },\n      ],\n    },\n  ]\n\n  function tierText (tier) {\n    if (tier.trial) return 'Start free trial'\n    if (tier.price === 'Free') return 'Join Community'\n    if (tier.contact) return 'Contact Us'\n\n    return 'Subscribe'\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/introduction/EnterpriseDeck.vue",
    "content": "<template>\n  <v-sheet\n    border=\"s e b\"\n    class=\"overflow-hidden\"\n    max-width=\"900\"\n    rounded\n  >\n    <v-divider\n      class=\"border-opacity-100\"\n      color=\"primary\"\n      thickness=\"4\"\n    />\n\n    <v-container class=\"pt-9 px-5\" fluid>\n      <v-row>\n        <template v-for=\"(item, i) in items\" :key=\"i\">\n          <v-col cols=\"12\" md=\"4\">\n            <v-responsive :min-height=\"mdAndUp ? 96 : undefined\" class=\"mb-4\">\n              <h3 class=\"text-headline-small font-weight-medium\">\n                {{ item.name }}\n              </h3>\n\n              <div class=\"text-body-small\">\n                {{ item.text }}\n              </div>\n            </v-responsive>\n\n            <div class=\"mb-4\">\n              <span class=\"text-headline-small font-weight-bold\">${{ item.price }} USD</span>\n              <span v-if=\"item.suffix\" class=\"font-weight-medium text-medium-emphasis text-title-large\">{{ item.suffix }}</span>\n            </div>\n\n            <v-btn\n              :href=\"item.href\"\n              :variant=\"i === 0 ? 'flat' : 'outlined'\"\n              class=\"mb-6 text-none\"\n              color=\"primary\"\n              rel=\"noopener\"\n              size=\"x-large\"\n              target=\"_blank\"\n              text=\"Book Now\"\n              block\n            />\n\n            <ul class=\"text-body-small ps-1\" style=\"list-style-type: none;\">\n              <li v-for=\"(benefit, k) in item.benefits\" :key=\"k\" class=\"mb-2 d-flex\">\n                <div class=\"me-2\">{{ benefit.emoji }}</div>\n\n                <div>{{ benefit.text }}</div>\n              </li>\n            </ul>\n          </v-col>\n\n          <v-divider v-if=\"i !== 2\" :vertical=\"mdAndUp\" />\n        </template>\n      </v-row>\n    </v-container>\n\n    <div class=\"px-4 pb-3 text-medium-emphasis text-body-small\">\n      *Cost for initial project review. Upgrade quote provided separately.\n    </div>\n  </v-sheet>\n</template>\n\n<script setup>\n  const { mdAndUp } = useDisplay()\n\n  const items = [\n    {\n      name: 'Direct Support',\n      text: 'Get direct help from the author of Vuetify in a live conference call',\n      price: '120',\n      suffix: '/60m',\n      benefits: [\n        {\n          emoji: '🐛',\n          text: 'Get help debugging your Vue / Vuetify application in a live conference call',\n        },\n        {\n          emoji: '🖥️',\n          text: 'We can collaborate in problem-solving in a personalized training session with you and your team',\n        },\n        {\n          emoji: '👀',\n          text: 'We can review and provide feedback on how to improve your Vuetify implementation',\n        },\n        {\n          emoji: '🧪',\n          text: 'Get help setting up unit tests that ensure your application continues to run as expected',\n        },\n      ],\n      href: 'https://calendly.com/vuetify/vuetify-direct-support',\n    },\n    {\n      name: 'Project Upgrade',\n      text: 'Ready to upgrade to Vuetify 3? Let us help you make the transition as smooth as possible',\n      price: '1,500',\n      suffix: '*',\n      benefits: [\n        {\n          emoji: '📦',\n          text: 'We will conduct a thorough review of your project and provide you with a detailed report of what it would take to upgrade',\n        },\n        {\n          emoji: '⌨️',\n          text: 'Our team will engage with your developers to help them understand the changes that need to be made',\n        },\n        {\n          emoji: '⚡',\n          text: 'Along with the report, we will provide a quote for us to perform the upgrade',\n        },\n        {\n          emoji: '🔐',\n          text: \"Feel secure knowing that you're working with the team that built Vuetify\",\n        },\n      ],\n      href: 'https://calendly.com/vuetify/project-upgrade-consultation',\n    },\n    {\n      name: 'SLA',\n      text: 'Get dedicated support with a customized Service Level Agreement',\n      price: '1,000',\n      suffix: '/mo',\n      benefits: [\n        {\n          emoji: '📝',\n          text: \"We work with your company to forge a customized SLA plan, tailored for your development team's productivity and growth\",\n        },\n        {\n          emoji: '🕒',\n          text: '2x1h live support calls per month with the author of Vuetify',\n        },\n        {\n          emoji: '💬',\n          text: 'Direct chat access to the Vuetify team through Discord with guaranteed response times',\n        },\n        {\n          emoji: '🎯',\n          text: 'Get priority on reported or identified Vuetify GitHub issues and bugs',\n        },\n        {\n          emoji: '🚌',\n          text: 'Great for large teams or companies with 3 or more developers',\n        },\n      ],\n      href: 'https://calendly.com/vuetify/sla-consultation',\n    },\n  ]\n\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/introduction/EnterpriseForm.vue",
    "content": "<template>\n  <v-defaults-provider\n    :defaults=\"{\n      VCheckboxBtn: {\n        color: 'primary',\n        density: 'compact',\n      },\n    }\"\n  >\n    <v-card\n      id=\"request-service\"\n      class=\"pa-2\"\n      title=\"Request Support\"\n      variant=\"flat\"\n      border\n    >\n      <template #append>\n        <v-img\n          :src=\"logo\"\n          width=\"96\"\n        />\n      </template>\n\n      <v-form\n        ref=\"form\"\n        v-model=\"valid\"\n        @submit.prevent=\"onSubmit\"\n      >\n        <v-card-text>\n          <v-label class=\"mb-2 font-weight-bold\">Contact Information</v-label>\n\n          <v-row class=\"mb-4\">\n            <v-col cols=\"12\" md=\"6\">\n              <AppTextField\n                v-model=\"name\"\n                :placeholder=\"t('name')\"\n                :rules=\"[rules.required]\"\n                name=\"name\"\n                prepend-inner-icon=\"mdi-account-circle-outline\"\n              />\n            </v-col>\n\n            <v-col cols=\"12\" md=\"6\">\n              <AppTextField\n                v-model=\"email\"\n                :placeholder=\"t('email-address')\"\n                :rules=\"[rules.required, rules.email]\"\n                name=\"email\"\n                prepend-inner-icon=\"mdi-email-outline\"\n              />\n            </v-col>\n          </v-row>\n\n          <v-label class=\"mb-2 font-weight-bold\">What services are you interested in?</v-label>\n\n          <div class=\"mb-4\">\n            <v-checkbox-btn\n              v-model=\"upgrade\"\n              label=\"Upgrading an existing project\"\n              name=\"upgrade\"\n            />\n\n            <v-checkbox-btn\n              v-model=\"review\"\n              :false-value=\"false\"\n              label=\"Application performance review\"\n              name=\"review\"\n            />\n\n            <v-checkbox-btn\n              v-model=\"sla\"\n              label=\"Direct support or SLA\"\n              name=\"sla\"\n            />\n\n          <!-- <v-checkbox label=\"Training & workshops\" /> -->\n          </div>\n\n          <v-label class=\"font-weight-bold\">\n            Are you currently a sponsor?\n          </v-label>\n\n          <a\n            :href=\"rpath('/introduction/sponsors-and-backers/')\"\n            class=\"ms-2\"\n            target=\"_blank text-body-small\"\n          >\n            <small class=\"text-primary\">More Information</small>\n          </a>\n\n          <v-switch\n            v-model=\"sponsor\"\n            color=\"primary\"\n            density=\"compact\"\n            label=\"Yes\"\n            name=\"sponsor\"\n            hide-details\n            inset\n          />\n\n          <small class=\"text-medium-emphasis\">\n            *All service packages are custom per client with pricing based upon the requested services.\n          </small>\n        </v-card-text>\n\n        <v-card-actions class=\"px-4 pb-4\">\n          <v-spacer />\n\n          <v-btn\n            :append-icon=\"!loading && success ? '$success' : undefined\"\n            :color=\"success ? 'success' : valid ? 'primary' : undefined\"\n            :disabled=\"loading || !valid\"\n            :loading=\"loading\"\n            size=\"large\"\n            type=\"submit\"\n            variant=\"flat\"\n            block\n          >\n            <span v-if=\"!success && !loading\">Submit</span>\n\n            <span v-else-if=\"!loading\">Successful</span>\n          </v-btn>\n        </v-card-actions>\n\n        <div class=\"text-center text-body-small pb-2\">\n          <small>\n            Issues with this form?\n            <a\n              class=\"text-primary\"\n              href=\"mailto:support@vuetifyjs.com?subject=Enterprise Support\"\n              target=\"_blank\"\n            >\n              Contact Us\n            </a>\n          </small>\n        </div>\n      </v-form>\n    </v-card>\n  </v-defaults-provider>\n</template>\n\n<script setup lang=\"ts\">\n  // Utilities\n  import emailjs from '@emailjs/browser'\n\n  const theme = useTheme()\n  const { t } = useI18n()\n\n  const name = shallowRef('')\n  const email = shallowRef('')\n  const upgrade = shallowRef(false)\n  const review = shallowRef(false)\n  const sla = shallowRef(false)\n  const sponsor = shallowRef(false)\n  const loading = shallowRef(false)\n  const valid = shallowRef<boolean | null>(null)\n  const success = shallowRef(false)\n  const form = shallowRef<HTMLFormElement>()\n  const rules = {\n    required: (v: string) => !!v || 'Field is required',\n    email: (v: any) => /.+@.+/.test(v) || 'E-mail must be valid',\n  }\n\n  const logo = computed(() => {\n    const color = theme.current.value.dark ? 'dark' : 'light'\n\n    return `https://cdn.vuetifyjs.com/docs/images/logos/vuetify-logo-v3-slim-text-${color}.svg`\n  })\n\n  watch(success, val => {\n    setTimeout(() => {\n      if (val) {\n        // TODO: bug with resetting checkbox\n        upgrade.value = false\n        review.value = false\n        sla.value = false\n        sponsor.value = false\n\n        // form.value?.reset()\n      }\n\n      success.value = false\n    }, 2000)\n  })\n\n  async function onSubmit () {\n    loading.value = true\n\n    try {\n      const res = await emailjs.sendForm(\n        import.meta.env.VITE_EMAILJS_SERVICE_ID,\n        import.meta.env.VITE_EMAILJS_TEMPLATE_ID,\n        form.value?.$el,\n        import.meta.env.VITE_EMAILJS_PUBLIC_KEY,\n      )\n\n      success.value = res.text === 'OK'\n    } catch (e) {\n      console.log(e)\n    }\n\n    loading.value = false\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/introduction/SlaDeck.vue",
    "content": "<template>\n  <v-sheet\n    border=\"s e b\"\n    class=\"overflow-hidden\"\n    max-width=\"900\"\n    rounded\n  >\n    <v-divider\n      class=\"border-opacity-100\"\n      color=\"primary\"\n      thickness=\"4\"\n    />\n\n    <v-container class=\"py-9 px-5\" fluid>\n      <v-row class=\"justify-space-around\" density=\"comfortable\">\n        <template v-for=\"(tier, i) in tiers\" :key=\"i\">\n          <v-col\n            :class=\"i === 1 && 'bg-primary'\"\n            class=\"position-relative pa-4 rounded-lg\"\n            cols=\"12\"\n            md=\"4\"\n          >\n            <v-responsive :min-height=\"mdAndUp ? 96 : undefined\" class=\"mb-4\">\n              <h3 class=\"d-flex align-center text-title-large font-weight-medium mb-4\">\n                <v-avatar :image=\"tier.src\" class=\"me-3\" />\n\n                <div>\n                  {{ tier.name }}\n\n                  <div class=\"text-headline-small font-weight-bold\">\n                    {{ tier.price }}<span v-if=\"tier.suffix\" class=\"font-weight-medium opacity-60 text-body-medium\">{{ tier.suffix }}</span>\n                  </div>\n                </div>\n              </h3>\n\n              <v-btn\n                :color=\"i === 1 ? 'surface' : 'primary'\"\n                :href=\"tier.href\"\n                :text=\"tierText(tier)\"\n                :variant=\"i === 1 ? 'flat' : 'outlined'\"\n                class=\"mb-6 text-none\"\n                rel=\"noopener\"\n                target=\"_blank\"\n                block\n              />\n\n              <div class=\"text-body-small\">{{ tier.text }}</div>\n            </v-responsive>\n\n            <v-divider class=\"mb-4\" />\n\n            <ul class=\"text-body-small ps-1\" style=\"list-style-type: none;\">\n              <li v-for=\"(benefit, k) in tier.benefits\" :key=\"k\" class=\"mb-2 d-flex\">\n                <div class=\"me-2\">{{ benefit.emoji }}</div>\n\n                <div>\n                  <strong>{{ benefit.name }}</strong>\n\n                  <div class=\"opacity-60\">\n                    {{ benefit.text }}\n                  </div>\n                </div>\n              </li>\n            </ul>\n          </v-col>\n        </template>\n      </v-row>\n    </v-container>\n  </v-sheet>\n</template>\n\n<script setup>\n  const { mdAndUp } = useDisplay()\n\n  const tiers = [\n    {\n      name: 'Galaxy Tier',\n      price: '$250',\n      suffix: '/mo',\n      href: 'https://buy.stripe.com/cN2fZOfIE7xc4iA288',\n      src: 'https://cdn.vuetifyjs.com/docs/images/avatars/galaxy.png',\n      text: '🥉 For 2 developers',\n      benefits: [\n        {\n          name: 'Chat support',\n          text: 'Get a private Discord channel where your developers can ask questions directly to the Core Team.',\n          emoji: '💬',\n        },\n        {\n          name: 'Same day response',\n          text: 'Questions are answered within 24 hours, Monday through Friday.',\n          emoji: '🕒',\n        },\n      ],\n    },\n    {\n      name: 'Cosmic Tier',\n      price: '$500',\n      suffix: '/mo',\n      href: 'https://buy.stripe.com/7sIfZO0NK3gW3ewfYZ',\n      src: 'https://cdn.vuetifyjs.com/docs/images/avatars/cosmic.png',\n      text: '🥈 For up to 5 developers',\n      benefits: [\n        {\n          name: 'Everything in Galaxy Tier, plus:',\n          emoji: '💫',\n        },\n        {\n          name: 'Priority bug fixes',\n          text: 'Get priority on reported or identified Vuetify GitHub issues.',\n          emoji: '🎯',\n        },\n      ],\n    },\n    {\n      name: 'Multiverse Tier',\n      price: '$1,000',\n      suffix: '/mo',\n      href: 'https://buy.stripe.com/8wMeVKeEA04K8yQeUW',\n      src: 'https://cdn.vuetifyjs.com/docs/images/avatars/multiverse.png',\n      text: '🥇 For up to 15 developers',\n      benefits: [\n        {\n          name: 'Everything in Cosmic Tier, plus:',\n          emoji: '💫',\n        },\n        {\n          name: 'Monthly strategy session',\n          text: 'A monthly strategy session to discuss your project and how to best utilize Vuetify.',\n          emoji: '📅',\n        },\n      ],\n    },\n  ]\n\n  function tierText (tier) {\n    if (tier.trial) return 'Start free trial'\n    if (tier.price === 'Free') return 'Join Community'\n    if (tier.contact) return 'Contact Us'\n\n    return 'Subscribe'\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/one/FAQ.vue",
    "content": "<template>\n  <v-container class=\"pa-md-12 pa-4 mx-auto\" max-width=\"700\" fluid>\n    <h2 class=\"text-headline-large text-md-display-medium font-weight-bold mb-2 text-center\">\n      Questions?\n    </h2>\n\n    <p class=\"text-body-large text-medium-emphasis mb-8 text-center\">\n      Everything you need to know about Vuetify One\n    </p>\n\n    <v-expansion-panels class=\"border rounded-xl overflow-hidden\" variant=\"accordion\">\n      <v-expansion-panel v-for=\"item in faq\" :key=\"item.question\" elevation=\"0\">\n        <v-expansion-panel-title class=\"text-body-large font-weight-medium\">\n          {{ item.question }}\n        </v-expansion-panel-title>\n\n        <v-expansion-panel-text class=\"text-body-medium text-medium-emphasis\">\n          {{ item.answer }}\n        </v-expansion-panel-text>\n      </v-expansion-panel>\n    </v-expansion-panels>\n\n    <p class=\"text-body-medium text-medium-emphasis text-center mt-6\">\n      Have other questions? Email us at\n      <AppLink href=\"mailto:hello@vuetifyjs.com\">hello@vuetifyjs.com</AppLink>\n    </p>\n  </v-container>\n</template>\n\n<script setup lang=\"ts\">\n  const faq = [\n    {\n      question: 'What happens to Vuetify if I don\\'t subscribe?',\n      answer: 'Nothing changes. Vuetify remains free and open source forever. Your subscription funds continued development and new features, but the core framework will always be available to everyone.',\n    },\n    {\n      question: 'Can I upgrade from Solo to Team later?',\n      answer: 'Yes. You can upgrade at any time from your account settings. You\\'ll be credited for any remaining time on your current plan.',\n    },\n    {\n      question: 'What\\'s the difference between subscribing and sponsoring?',\n      answer: 'Subscriptions give you access to premium features across Vuetify properties. Sponsoring through GitHub or Open Collective is a way to support development without needing those features. Both help fund the project.',\n    },\n    {\n      question: 'How do team seats work?',\n      answer: 'Team plans include up to 25 seats. You can invite members from your account dashboard. Each member gets their own login and access to all team features.',\n    },\n    {\n      question: 'Is there a free trial?',\n      answer: 'We don\\'t offer a trial, but you can cancel anytime within the first 30 days for a full refund. No questions asked.',\n    },\n    {\n      question: 'What payment methods do you accept?',\n      answer: 'We use Stripe for payments, which supports all major credit cards, Apple Pay, and Google Pay. Annual billing is available for additional savings.',\n    },\n  ]\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/one/Hero.vue",
    "content": "<template>\n  <v-container class=\"one-hero mx-auto text-center pa-md-12 pa-6 pb-7\" fluid>\n    <v-responsive class=\"mx-auto\" max-width=\"700\">\n      <v-img\n        :src=\"logoSrc\"\n        :width=\"$vuetify.display.mdAndUp ? 500 : 300\"\n        alt=\"Vuetify One Logo\"\n        class=\"mb-8 mx-auto\"\n      />\n\n      <h1 class=\"text-headline-large text-md-display-large font-weight-bold mb-4\">\n        Power the Future of Vuetify\n      </h1>\n\n      <p class=\"text-body-large text-md-title-large text-medium-emphasis mb-8\">\n        Your subscription directly funds Vuetify development. Get premium tools, an ad-free experience, and early access to what's next—while keeping the framework free for everyone.\n      </p>\n\n      <div class=\"d-flex ga-4 justify-center flex-wrap\">\n        <v-btn\n          :loading=\"one.isLoading\"\n          class=\"text-none\"\n          color=\"primary\"\n          rounded=\"lg\"\n          size=\"x-large\"\n          text=\"Subscribe Now\"\n          @click=\"one.subscribe('year', 'solo')\"\n        />\n\n        <v-btn\n          class=\"text-none\"\n          color=\"primary\"\n          rounded=\"lg\"\n          size=\"x-large\"\n          text=\"See What's Included\"\n          to=\"#features\"\n          variant=\"outlined\"\n        />\n      </div>\n    </v-responsive>\n  </v-container>\n</template>\n\n<script setup lang=\"ts\">\n  const one = useOneStore()\n  const theme = useTheme()\n\n  const logoSrc = computed(() => {\n    return `https://cdn.vuetifyjs.com/docs/images/one/logos/vone-logo-${theme.current.value.dark ? 'dark' : 'light'}.png`\n  })\n</script>\n\n<style scoped>\n  .one-hero {\n    background: linear-gradient(\n      180deg,\n      rgba(var(--v-theme-primary), 0.38) 0%,\n      rgba(var(--v-theme-background), 1) 100%\n    );\n  }\n</style>\n"
  },
  {
    "path": "packages/docs/src/components/one/Properties.vue",
    "content": "<template>\n  <v-container class=\"pa-4 mx-auto mb-12\" max-width=\"1100\" fluid>\n    <h2 class=\"text-headline-large text-md-display-medium font-weight-bold mb-2 text-center\">\n      Premium Across the Ecosystem\n    </h2>\n\n    <p class=\"text-body-large text-medium-emphasis mb-8 text-center\">\n      Your subscription unlocks features on every Vuetify property\n    </p>\n\n    <v-row>\n      <v-col\n        v-for=\"property in properties\"\n        :key=\"property.name\"\n        cols=\"12\"\n        md=\"4\"\n        sm=\"6\"\n      >\n        <v-card\n          :href=\"property.url\"\n          class=\"pa-4 d-flex align-start\"\n          elevation=\"0\"\n          height=\"100%\"\n          rounded=\"xl\"\n          target=\"_blank\"\n          border\n        >\n          <v-avatar\n            :color=\"property.color\"\n            class=\"mr-4\"\n            rounded=\"lg\"\n            size=\"48\"\n          >\n            <v-icon\n              :icon=\"property.icon\"\n              color=\"white\"\n              size=\"24\"\n            />\n          </v-avatar>\n\n          <div class=\"flex-grow-1\">\n            <div class=\"d-flex align-center mb-1\">\n              <span class=\"text-body-large font-weight-bold\">{{ property.name }}</span>\n\n              <v-icon\n                class=\"ml-1 text-medium-emphasis\"\n                icon=\"mdi-open-in-new\"\n                size=\"14\"\n              />\n            </div>\n\n            <p class=\"text-body-medium text-medium-emphasis mb-2\">\n              {{ property.description }}\n            </p>\n\n            <div class=\"d-flex flex-wrap ga-1 mx-n1 mb-n1 mt-4\">\n              <v-chip\n                v-for=\"feature in property.features\"\n                :key=\"feature\"\n                :text=\"feature\"\n                color=\"primary\"\n                size=\"x-small\"\n                variant=\"tonal\"\n              />\n            </div>\n          </div>\n        </v-card>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup lang=\"ts\">\n  const properties = [\n    {\n      name: 'Vuetify Play',\n      icon: '$vuetify-play',\n      color: 'blue',\n      url: 'https://play.vuetifyjs.com',\n      description: 'Interactive playground for prototyping and sharing Vuetify code.',\n      features: ['Private playgrounds', 'Cloud sync', 'Version history'],\n    },\n    {\n      name: 'Vuetify Bin',\n      icon: '$vuetify-bin',\n      color: 'green',\n      url: 'https://bin.vuetifyjs.com',\n      description: 'Code snippet sharing with syntax highlighting and live collaboration.',\n      features: ['Private bins', 'Embeds', 'Real-time editing'],\n    },\n    {\n      name: 'Vuetify Studio',\n      icon: '$vuetify-studio',\n      color: 'deep-purple',\n      url: 'https://studio.vuetifyjs.com',\n      description: 'Visual design tool for building Vuetify interfaces.',\n      features: ['Visual editor', 'Component library', 'Export code'],\n    },\n    {\n      name: 'Vuetify Link',\n      icon: '$vuetify-link',\n      color: 'purple',\n      url: 'https://link.vuetifyjs.com',\n      description: 'URL shortener with click tracking for the Vuetify ecosystem.',\n      features: ['Click analytics', 'Custom slugs', 'QR codes'],\n    },\n    {\n      name: 'Vuetify Issues',\n      icon: '$vuetify-issues',\n      color: 'orange',\n      url: 'https://issues.vuetifyjs.com',\n      description: 'Structured bug reporting and feature requests for Vuetify.',\n      features: ['Guided forms', 'Auto-validation', 'Issue tracking'],\n    },\n    {\n      name: 'Documentation',\n      icon: '$vuetify-outline',\n      color: 'primary',\n      url: 'https://vuetifyjs.com',\n      description: 'The official Vuetify documentation with enhanced navigation.',\n      features: ['Ad-free', 'Pinned pages', 'Rail nav'],\n    },\n  ]\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/one/Roadmap.vue",
    "content": "<template>\n  <v-container class=\"pa-4 mx-auto text-center\" max-width=\"900\" fluid>\n    <h2 class=\"text-headline-large text-md-display-medium font-weight-bold mb-2 text-center\">\n      What's Coming\n    </h2>\n\n    <p class=\"text-body-large text-medium-emphasis mb-8 text-center\">\n      Your subscription funds these features. Subscribers get early access.\n    </p>\n\n    <v-row>\n      <v-col v-for=\"item in roadmap\" :key=\"item.title\" cols=\"12\" md=\"4\">\n        <v-card class=\"pa-4 h-100 pb-6\" elevation=\"0\" rounded=\"xl\" border>\n          <v-icon :icon=\"item.icon\" class=\"mb-4\" color=\"primary\" size=\"40\" />\n\n          <div class=\"text-body-large font-weight-bold mb-2\">\n            {{ item.title }}\n          </div>\n\n          <p class=\"text-body-medium text-medium-emphasis mb-0\">\n            {{ item.description }}\n          </p>\n        </v-card>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup lang=\"ts\">\n  const roadmap = [\n    {\n      icon: 'mdi-application-brackets-outline',\n      title: 'Embeddable Playgrounds',\n      description: 'Embed playgrounds directly in your own documentation. Share interactive examples anywhere.',\n    },\n    {\n      icon: 'mdi-account-multiple',\n      title: 'Team Shared Workspaces',\n      description: 'Share private bins and playgrounds with your team. Centralized collaboration and usage analytics.',\n    },\n    {\n      icon: 'mdi-lightning-bolt',\n      title: 'Real-Time Collaboration',\n      description: 'Share live updates on bins and playgrounds. See changes instantly as teammates edit.',\n    },\n  ]\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/one/SubscribeCard.vue",
    "content": "<template>\n  <v-container id=\"features\" class=\"pa-md-12 pa-4 mx-auto\" max-width=\"900\" fluid>\n    <h2 class=\"text-headline-large text-md-display-medium font-weight-bold mb-2 text-center\">\n      What You Get\n    </h2>\n\n    <p class=\"text-body-large text-medium-emphasis mb-8 text-center\">\n      Choose the plan that fits your needs\n    </p>\n\n    <v-row>\n      <v-col cols=\"12\" md=\"6\">\n        <v-card\n          :class=\"{ 'border-primary border-opacity-100': type === 'solo' }\"\n          class=\"pa-6 h-100 d-flex flex-column\"\n          elevation=\"0\"\n          rounded=\"xl\"\n          border\n          @click=\"type = 'solo'\"\n        >\n          <div class=\"d-flex align-center mb-4\">\n            <v-icon class=\"mr-3\" color=\"primary\" icon=\"mdi-account\" size=\"32\" />\n\n            <div>\n              <div class=\"text-title-large font-weight-bold\">Solo Developer</div>\n\n              <div class=\"text-body-medium text-medium-emphasis\">For individual developers</div>\n            </div>\n          </div>\n\n          <div class=\"mb-6\">\n            <span class=\"text-headline-large font-weight-bold\">${{ prices.solo[interval].split(' ')[0] }}</span>\n\n            <span class=\"text-body-medium text-medium-emphasis\">{{ interval === 'year' ? '/year' : '/month' }}</span>\n          </div>\n\n          <v-list\n            id=\"subscribe-now\"\n            bg-color=\"transparent\"\n            class=\"flex-grow-1 px-0\"\n            density=\"compact\"\n            slim\n          >\n            <v-list-item v-for=\"item in features.solo\" :key=\"item.text\" class=\"px-0\">\n              <template #prepend>\n                <v-icon\n                  :color=\"item.new ? 'success' : item.soon ? 'warning' : 'info-lighten-3'\"\n                  :icon=\"item.new ? 'mdi-new-box' : item.soon ? 'mdi-clock-outline' : 'mdi-check-circle'\"\n                  size=\"20\"\n                />\n              </template>\n\n              <v-list-item-title class=\"text-wrap text-body-medium\">\n                {{ item.text }}\n              </v-list-item-title>\n\n              <template v-if=\"item.soon\" #append>\n                <v-chip\n                  color=\"warning\"\n                  size=\"x-small\"\n                  text=\"Soon\"\n                  variant=\"tonal\"\n                />\n              </template>\n            </v-list-item>\n          </v-list>\n\n          <v-btn\n            :loading=\"one.isLoading && type === 'solo'\"\n            :text=\"type === 'solo' ? 'Subscribe Now' : 'Select Plan'\"\n            :variant=\"type === 'solo' ? 'flat' : 'outlined'\"\n            class=\"mt-4 text-none\"\n            color=\"primary\"\n            rounded=\"lg\"\n            size=\"large\"\n            block\n            @click.stop=\"type = 'solo'; subscribe()\"\n          />\n        </v-card>\n      </v-col>\n\n      <v-col cols=\"12\" md=\"6\">\n        <v-card\n          :class=\"{ 'border-primary border-opacity-100': type === 'team' }\"\n          class=\"pa-6 h-100 d-flex flex-column\"\n          elevation=\"0\"\n          rounded=\"xl\"\n          border\n          @click=\"type = 'team'\"\n        >\n          <div class=\"d-flex align-center mb-4\">\n            <v-icon\n              class=\"mr-3\"\n              color=\"primary\"\n              icon=\"mdi-account-group\"\n              size=\"32\"\n            />\n\n            <div>\n              <div class=\"text-title-large font-weight-bold\">\n                Team\n\n                <v-chip\n                  class=\"ml-2\"\n                  color=\"primary\"\n                  size=\"x-small\"\n                  text=\"Best Value\"\n                  variant=\"tonal\"\n                />\n              </div>\n\n              <div class=\"text-body-medium text-medium-emphasis\">For teams up to 25 members</div>\n            </div>\n          </div>\n\n          <div class=\"mb-6\">\n            <span class=\"text-headline-large font-weight-bold\">${{ prices.team[interval].split(' ')[0] }}</span>\n\n            <span class=\"text-body-medium text-medium-emphasis\">{{ interval === 'year' ? '/year' : '/month' }}</span>\n          </div>\n\n          <v-list bg-color=\"transparent\" class=\"flex-grow-1 px-0\" density=\"compact\" slim>\n            <v-list-item v-for=\"item in features.team\" :key=\"item.text\" class=\"px-0\">\n              <template #prepend>\n                <v-icon\n                  :color=\"item.new ? 'success' : item.soon ? 'warning' : 'info-lighten-3'\"\n                  :icon=\"item.new ? 'mdi-new-box' : item.soon ? 'mdi-clock-outline' : 'mdi-check-circle'\"\n                  size=\"20\"\n                />\n              </template>\n\n              <v-list-item-title class=\"text-wrap text-body-medium\">\n                {{ item.text }}\n              </v-list-item-title>\n\n              <template v-if=\"item.soon\" #append>\n                <v-chip\n                  color=\"warning\"\n                  size=\"x-small\"\n                  text=\"Soon\"\n                  variant=\"tonal\"\n                />\n              </template>\n            </v-list-item>\n          </v-list>\n\n          <v-btn\n            :loading=\"one.isLoading && type === 'team'\"\n            :text=\"type === 'team' ? 'Subscribe Now' : 'Select Plan'\"\n            :variant=\"type === 'team' ? 'flat' : 'outlined'\"\n            class=\"mt-4 text-none\"\n            color=\"primary\"\n            max-height=\"44\"\n            rounded=\"lg\"\n            size=\"large\"\n            block\n            @click.stop=\"type = 'team'; subscribe()\"\n          />\n        </v-card>\n      </v-col>\n    </v-row>\n\n    <div class=\"d-flex justify-center align-center ga-4 mt-10\">\n      <v-btn-toggle\n        v-model=\"interval\"\n        color=\"primary\"\n        rounded=\"pill\"\n        variant=\"outlined\"\n        mandatory\n      >\n        <v-btn class=\"text-none\" min-width=\"137\" text=\"Monthly\" value=\"month\" />\n\n        <v-btn class=\"text-none\" min-width=\"137\" value=\"year\">\n          Annual\n\n          <v-chip\n            class=\"ml-2\"\n            color=\"success\"\n            size=\"x-small\"\n            text=\"-20%\"\n            variant=\"flat\"\n          />\n        </v-btn>\n      </v-btn-toggle>\n    </div>\n\n    <p class=\"text-body-small text-medium-emphasis text-center mt-4\">\n      Cancel anytime. Secure payment via Stripe.\n    </p>\n  </v-container>\n</template>\n\n<script setup lang=\"ts\">\n  const features = {\n    solo: [\n      { text: 'Ad-free experience across all Vuetify properties' },\n      { text: 'Private playgrounds, bins, links, and studios with cloud sync' },\n      { text: 'Premium documentation features (pinned nav, rail menu, copy page as markdown)' },\n      { text: 'Early access to new tools and features' },\n      { text: 'Vuetify MCP API (access to your one data anywhere that supports MCP)', new: true },\n      { text: 'Share live updates on Bins and Playgrounds', soon: true },\n      { text: 'Embed playgrounds in your own documentation', soon: true },\n    ],\n    team: [\n      { text: 'Everything in Solo, for up to 25 members' },\n      { text: 'Centralized team billing and member management' },\n      { text: 'Shared playgrounds and code snippets', new: false },\n      { text: 'Team shared Private Bins and Playgrounds', soon: true },\n      { text: 'Usage analytics dashboard', soon: true },\n    ],\n  }\n\n  const one = useOneStore()\n  const type = shallowRef<'solo' | 'team'>('solo')\n  const interval = shallowRef<'month' | 'year'>('year')\n\n  const prices = {\n    solo: {\n      month: '2.99 /month',\n      year: '29.99 /year',\n    },\n    team: {\n      month: '29.99 /month',\n      year: '299.99 /year',\n    },\n  }\n\n  async function subscribe () {\n    await one.subscribe(interval.value, type.value)\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/promoted/Base.vue",
    "content": "<template>\n  <v-lazy\n    :min-height=\"minHeight\"\n    class=\"d-flex\"\n  >\n    <v-sheet\n      v-bind=\"$attrs\"\n      :min-height=\"minHeight\"\n      class=\"v-app-ad d-inline-flex flex-child-1 grow-shrink-0\"\n      color=\"surface-bright\"\n      width=\"100%\"\n      rounded\n    >\n      <slot />\n    </v-sheet>\n  </v-lazy>\n</template>\n\n<script setup>\n  const props = defineProps({\n    density: {\n      type: String,\n      default: 'default',\n    },\n    minHeight: [Number, String],\n  })\n\n  const minHeight = computed(() => {\n    if (props.minHeight) return props.minHeight\n    if (props.density === 'compact') return 56\n    if (props.density === 'comfortable') return 74\n\n    return 118\n  })\n</script>\n\n<script>\n  export default {\n    inheritAttrs: false,\n  }\n</script>\n\n<style lang=\"sass\">\n  .v-app-ad\n    a\n      text-decoration: none\n\n    .v-markdown p\n      margin-bottom: 0\n</style>\n"
  },
  {
    "path": "packages/docs/src/components/promoted/Carbon.vue",
    "content": "<template>\n  <v-responsive\n    class=\"align-center\"\n    min-height=\"118\"\n  >\n    <template v-if=\"!error1\">\n      <PromotedBase\n        ref=\"script\"\n        :class=\"[\n          isDark ? 'theme--dark' : 'theme--light',\n        ]\"\n        max-width=\"360\"\n        border\n      >\n        <PromotedScript\n          id=\"carbonads-script\"\n          script-id=\"_carbonads_js\"\n          src=\"//cdn.carbonads.com/carbon.js?serve=CWYDC27W&placement=v3vuetifyjscom\"\n          @script:error=\"error1 = true\"\n        />\n      </PromotedBase>\n    </template>\n\n    <VoPromotionsCardVuetify v-else />\n  </v-responsive>\n</template>\n\n<script setup lang=\"ts\">\n  const error1 = shallowRef(false)\n  const script = shallowRef(null)\n  let timer = -1 as any\n\n  function checkForElement (id: string, cb?: () => void) {\n    return setTimeout(() => {\n      if (document.getElementById(id)) return\n\n      clearTimeout(timer)\n\n      cb?.()\n    }, 2000)\n  }\n\n  onMounted(() => {\n    timer = checkForElement('carbonads', () => {\n      error1.value = true\n    })\n  })\n\n  onBeforeUnmount(() => {\n    document.getElementById('carbonads-script')?.remove()\n  })\n\n  onScopeDispose(() => {\n    clearTimeout(timer)\n  })\n\n  const theme = useTheme()\n\n  const isDark = computed(() => theme.current.value.dark)\n</script>\n\n<style lang=\"sass\">\n  #carbonads-script\n    width: 100%\n\n  #carbonads,\n  #carbonads_1,\n  #carbonads_2\n    width: 100%\n\n    > span\n      display: flex\n      position: relative\n\n    .carbon-wrap\n      display: flex\n\n    .carbon-text,\n    .carbon-poweredby\n      max-width: 200px\n      padding: 0 0 0 16px\n      text-decoration: none\n\n    .carbon-img\n      display: inline-flex\n      margin: 0.5rem\n\n      img\n        border-radius: 4px 0 0 4px\n        max-height: 100px\n\n    .carbon-text\n      color: inherit\n      font-size: 0.75rem\n      padding: 0.475rem\n\n    .carbon-poweredby\n      bottom: 0.5rem\n      font-size: 0.625rem\n      font-weight: 400\n      letter-spacing: 0.09375rem\n      position: absolute\n      right: 0.5rem\n      text-transform: uppercase\n\n  .v-app-ad.theme--light\n    .carbon-poweredby\n      color: rgba(0, 0, 0, .6)\n\n  .v-app-ad.theme--dark\n    .carbon-poweredby\n      color: inherit\n</style>\n"
  },
  {
    "path": "packages/docs/src/components/promoted/Discovery.vue",
    "content": "<template>\n  <PromotedPromoted class=\"mb-5\" medium=\"discovery\" type=\"discovery\" />\n</template>\n"
  },
  {
    "path": "packages/docs/src/components/promoted/Entry.vue",
    "content": "<template>\n  <PromotedCarbon v-if=\"user.one.ads.enabled\" />\n\n  <VoPromotionsCardVuetify v-else-if=\"user.one.ads.house\" />\n\n  <br v-if=\"user.one.ads.enabled || user.one.ads.house\">\n</template>\n\n<script setup>\n  const user = useUserStore()\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/promoted/Inline.vue",
    "content": "<template>\n  <AppMarkdown\n    v-if=\"ad\"\n    :content=\"description\"\n    class=\"v-markdown--inline d-inline\"\n    tag=\"span\"\n  />\n</template>\n\n<script setup>\n  const props = defineProps(createAdProps())\n\n  const { ad, description } = useAd(props)\n</script>\n\n<style lang=\"sass\">\n  .v-markdown--inline\n    a\n      font-weight: 500\n      text-decoration: none\n    p\n      display: inline\n      margin: 0\n</style>\n"
  },
  {
    "path": "packages/docs/src/components/promoted/Promoted.vue",
    "content": "<template>\n  <div v-if=\"ad\" class=\"mb-5\">\n    <a\n      v-if=\"hasPromoted\"\n      class=\"d-block\"\n      style=\"max-width: 640px;\"\n      v-bind=\"attrs\"\n      @click=\"onClick\"\n    >\n      <PromotedBase\n        v-bind=\"$attrs\"\n        class=\"v-vuetify--promoted\"\n        density=\"compact\"\n        max-width=\"640\"\n        outlined\n      >\n        <v-img\n          :src=\"background\"\n          class=\"flex-1-1-auto rounded\"\n          max-height=\"56\"\n          cover\n        >\n          <div class=\"d-flex align-center fill-height pe-3\">\n            <v-img\n              :alt=\"`Link to ${ad.title}`\"\n              :src=\"logo\"\n              class=\"mx-1 mx-md-2\"\n              height=\"56\"\n              max-width=\"56\"\n            />\n\n            <AppMarkdown\n              v-if=\"description\"\n              :content=\"description\"\n              class=\"text-title-small text-sm-title-large font-weight-light text-white\"\n            />\n          </div>\n        </v-img>\n      </PromotedBase>\n    </a>\n\n    <PromotedVuetify v-else />\n  </div>\n</template>\n\n<script setup>\n  const props = defineProps({\n    ...createAdProps(),\n\n    medium: {\n      type: String,\n      default: 'promoted',\n    },\n  })\n\n  const { ad, attrs } = useAd(props)\n  const { name } = useRoute()\n\n  const background = computed(() => ad.value?.metadata?.images?.background?.url)\n  const hasPromoted = computed(() => {\n    return (\n      ad.value?.metadata?.description_short &&\n      background.value\n    )\n  })\n\n  const description = computed(() => ad.value?.metadata?.description_short || ad.value?.metadata?.description)\n  const logo = computed(() => {\n    if (props.medium === 'promoted') {\n      return ad.value?.metadata?.images?.preview?.url || ad.value?.metadata?.images?.logo?.url\n    }\n\n    return ad.value?.metadata?.images?.logo?.url\n  })\n\n  function onClick () {\n    const slug = ad.value?.slug\n\n    if (!slug) return\n\n    sweClick('promoted', slug, name?.toString().toLowerCase())\n  }\n</script>\n\n<script>\n  export default {\n    inheritAttrs: false,\n  }\n</script>\n\n<style lang=\"sass\">\n  .v-vuetify--promoted\n    p\n      line-height: 1.1\n\n    .v-markdown p strong\n      font-weight: 700\n</style>\n"
  },
  {
    "path": "packages/docs/src/components/promoted/Random.vue",
    "content": "<template>\n  <PromotedVuetify class=\"mb-5\" />\n</template>\n"
  },
  {
    "path": "packages/docs/src/components/promoted/Script.vue",
    "content": "<template>\n  <div ref=\"rootEl\" :id=\"id\" />\n</template>\n\n<script setup lang=\"ts\">\n  const props = defineProps({\n    async: {\n      type: Boolean,\n      default: false,\n    },\n    id: {\n      type: String,\n      required: true,\n    },\n    scriptId: {\n      type: String,\n      required: true,\n    },\n    src: {\n      type: String,\n      required: true,\n    },\n  })\n\n  const emit = defineEmits(['script:error', 'script:load'])\n\n  const rootEl = ref<HTMLElement>()\n  const scriptEl = ref<HTMLScriptElement>()\n\n  onBeforeMount(async () => {\n    if (!IN_BROWSER) return\n\n    const script = document.createElement('script')\n    const onError = () => emit('script:error')\n\n    script.type = 'text/javascript'\n    script.id = props.scriptId\n    script.src = props.src\n    script.async = props.async\n    script.onload = () => emit('script:load')\n    script.onerror = onError\n\n    scriptEl.value = script\n  })\n\n  onMounted(() => {\n    scriptEl.value && rootEl.value?.appendChild(scriptEl.value)\n  })\n\n  onBeforeUnmount(() => {\n    scriptEl.value && rootEl.value?.removeChild(scriptEl.value)\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/promoted/Vuetify.vue",
    "content": "<template>\n  <PromotedBase\n    v-if=\"ad\"\n    class=\"v-vuetify\"\n    density=\"comfortable\"\n    border\n  >\n    <v-list-item\n      :append-icon=\"smAndUp ? 'mdi-open-in-new' : undefined\"\n      :prepend-avatar=\"src\"\n      :title=\"ad.title\"\n      style=\"min-height: inherit; width: 100%\"\n      v-bind=\"attrs\"\n    >\n      <template #subtitle>\n        <AppMarkdown\n          v-if=\"description\"\n          :content=\"description\"\n          class=\"text-body-small\"\n        />\n      </template>\n    </v-list-item>\n  </PromotedBase>\n</template>\n\n<script setup>\n  const props = defineProps({\n    color: String,\n\n    ...createAdProps(),\n  })\n\n  const { ad, attrs, src, description } = useAd(props)\n  const { smAndUp } = useDisplay()\n</script>\n\n<style lang=\"sass\">\n  .v-vuetify\n    .powered-by\n      color: rgba(0, 0, 0, .6)\n      font-size: 0.625rem\n      font-weight: 400\n      letter-spacing: 0.09375rem\n      text-transform: uppercase\n\n    &.theme--dark .powered-by\n      color: inherit\n</style>\n"
  },
  {
    "path": "packages/docs/src/components/promotions/PromotionCard.vue",
    "content": "<template>\n  <PromotedBase\n    v-if=\"promotion\"\n    class=\"v-promotion-card\"\n    max-width=\"360\"\n    border\n  >\n    <a\n      :href=\"promotion.metadata.url\"\n      class=\"d-inline-block text-medium-emphasis\"\n      rel=\"noopener\"\n      target=\"_blank\"\n    >\n      <v-container class=\"pa-2\">\n        <v-row density=\"comfortable\">\n          <v-col cols=\"auto\">\n            <v-img\n              :src=\"promotion.metadata.images.default.url\"\n              class=\"rounded-s\"\n              width=\"130\"\n            />\n          </v-col>\n\n          <v-col>\n            <div class=\"px-2\">\n              <AppMarkdown :content=\"promotion.metadata.text\" />\n            </div>\n          </v-col>\n        </v-row>\n      </v-container>\n\n      <span class=\"v-promotion-card__via text-medium-emphasis\">\n        ADS VIA VUETIFY\n      </span>\n    </a>\n  </PromotedBase>\n</template>\n\n<script setup>\n  const props = defineProps({\n    color: String,\n    slug: String,\n  })\n\n  const store = usePromotionsStore()\n\n  const promotions = computed(() => {\n    return store.promotions.filter(promotion => promotion.metadata?.discoverable)\n  })\n\n  const promotion = computed(() => {\n    if (props.slug) return store.promotions?.find(ad => ad.slug === props.slug)\n\n    return promotions.value[Math.floor(Math.random() * promotions.value.length)]\n  })\n</script>\n\n<style lang=\"sass\">\n  .v-promotion-card\n    font-size: 0.75rem\n    position: relative\n\n    &__via\n      position: absolute\n      display: inline-block\n      bottom: .5rem\n      right: .5rem\n      font-size: 0.625rem\n      letter-spacing: 0.09375rem\n      font-weight: 400\n</style>\n"
  },
  {
    "path": "packages/docs/src/components/resources/ColorPalette.vue",
    "content": "<template>\n  <v-container class=\"px-0\">\n    <div class=\"font-weight-bold mb-3\">{{ t('colors') }}</div>\n\n    <v-row>\n      <v-col v-for=\"(color, i) in colors\" :key=\"i\" cols=\"3\">\n        <v-sheet\n          :color=\"color\"\n          class=\"d-flex align-center justify-center text-mono\"\n          height=\"150\"\n          border\n          rounded\n        >\n          {{ color }}\n        </v-sheet>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  const { t } = useI18n()\n\n  const colors = [\n    '#1867C0',\n    '#1697F6',\n    '#7BC6FF',\n    '#AEDDFF',\n  ]\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/resources/Logos.vue",
    "content": "<template>\n  <AppBtn\n    href=\"https://cdn.vuetifyjs.com/docs/images/brand-kit/vuetify-brand-kit.zip\"\n    prepend-icon=\"mdi-download-box-outline\"\n    target=\"_blank\"\n    text=\"download-brand-kit\"\n    border\n  />\n\n  <v-container class=\"px-0\">\n    <div class=\"font-weight-bold mb-3\">{{ t('logo') }}</div>\n\n    <v-row class=\"mb-6\">\n      <v-col v-for=\"logo in logos\" :key=\"logo.title\" cols=\"auto\">\n        <v-sheet class=\"pa-4\" border rounded>\n          <AppFigure\n            :src=\"`${logo.src}.svg`\"\n            :title=\"logo.title\"\n            class=\"mb-4 mx-auto\"\n            width=\"125\"\n          />\n\n          <div class=\"d-flex justify-center mt-4\">\n            <v-btn\n              :href=\"`${logo.src}.svg`\"\n              class=\"mx-1\"\n              color=\"medium-emphasis\"\n              size=\"x-small\"\n              target=\"_blank\"\n              text=\"SVG\"\n              variant=\"outlined\"\n            />\n\n            <v-btn\n              :href=\"`${logo.src}.png`\"\n              class=\"mx-1\"\n              color=\"medium-emphasis\"\n              size=\"x-small\"\n              target=\"_blank\"\n              text=\"PNG\"\n              variant=\"outlined\"\n            />\n          </div>\n        </v-sheet>\n      </v-col>\n    </v-row>\n\n    <div class=\"font-weight-bold mb-3\">{{ t('text') }}</div>\n\n    <v-row class=\"mb-6\">\n      <v-col v-for=\"logo in text\" :key=\"logo.title\" cols=\"auto\">\n        <v-sheet\n          :theme=\"logo.src.indexOf('dark') > -1 ? 'dark' : 'light'\"\n          class=\"pa-4\"\n          width=\"300\"\n          border\n          rounded\n        >\n          <AppFigure\n            :src=\"`${logo.src}.svg`\"\n            :title=\"logo.title\"\n            class=\"mb-4\"\n            cover\n          />\n\n          <div class=\"d-flex justify-center mt-4\">\n            <v-btn\n              :href=\"`${logo.src}.svg`\"\n              class=\"mx-1\"\n              color=\"medium-emphasis\"\n              size=\"x-small\"\n              target=\"_blank\"\n              text=\"SVG\"\n              variant=\"outlined\"\n            />\n\n            <v-btn\n              :href=\"`${logo.src}.png`\"\n              class=\"mx-1\"\n              color=\"medium-emphasis\"\n              size=\"x-small\"\n              target=\"_blank\"\n              text=\"PNG\"\n              variant=\"outlined\"\n            />\n          </div>\n        </v-sheet>\n      </v-col>\n    </v-row>\n\n    <div class=\"font-weight-bold my-3\">{{ t('icon') }}</div>\n\n    <v-row class=\"mb-3\">\n      <v-col\n        v-for=\"icon in icons\"\n        :key=\"icon.title\"\n        cols=\"12\"\n        sm=\"6\"\n      >\n        <v-sheet\n          class=\"pa-2\"\n          border\n          rounded\n        >\n          <div class=\"text-center\">\n            <v-icon\n              :color=\"icon.color\"\n              :icon=\"icon.icon\"\n              size=\"88\"\n            />\n          </div>\n\n          <figcaption class=\"text-body-small font-weight-bold text-center text-medium-emphasis mb-2\">\n            {{ icon.title }}\n          </figcaption>\n\n          <AppMarkup :code=\"icon.code\" />\n        </v-sheet>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  const { t } = useI18n()\n\n  const logos = [\n    {\n      title: 'Vuetify Logo',\n      src: 'https://cdn.vuetifyjs.com/docs/images/brand-kit/v-logo',\n    },\n    {\n      title: 'Vuetify Atom Logo',\n      src: 'https://cdn.vuetifyjs.com/docs/images/brand-kit/v-logo-atom',\n    },\n    {\n      title: 'Vuetify Circle Logo',\n      src: 'https://cdn.vuetifyjs.com/docs/images/brand-kit/v-logo-circle',\n    },\n  ]\n\n  const text = [\n    {\n      title: 'Vuetify Light Text Logo',\n      src: 'https://cdn.vuetifyjs.com/docs/images/brand-kit/v-text-logo-light',\n    },\n    {\n      title: 'Vuetify Dark Text Logo',\n      src: 'https://cdn.vuetifyjs.com/docs/images/brand-kit/v-text-logo-dark',\n    },\n  ]\n\n  const icons = [\n    {\n      title: 'Vuetify Icon',\n      icon: '$vuetify',\n      code: '<v-icon icon=\"$vuetify\" />',\n    },\n    {\n      title: 'Vuetify Outlined Icon',\n      icon: '$vuetify-outline',\n      code: '<v-icon icon=\"$vuetify-outline\" />',\n    },\n  ]\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/sponsor/Card.vue",
    "content": "<template>\n  <v-card\n    :aria-label=\"sponsor?.metadata.name\"\n    :href=\"sponsor?.metadata.href\"\n    :ripple=\"false\"\n    class=\"d-inline-flex align-center pa-2\"\n    color=\"transparent\"\n    rel=\"noopener\"\n    target=\"_blank\"\n    variant=\"flat\"\n    rounded\n    @click=\"onClick\"\n  >\n    <v-img\n      :alt=\"sponsor?.metadata.name\"\n      :src=\"src\"\n      :width=\"imgWidth\"\n      max-height=\"64\"\n    />\n  </v-card>\n</template>\n\n<script setup>\n  const props = defineProps({\n    slug: String,\n    sponsor: Object,\n    compact: Boolean,\n    comfortable: Boolean,\n    width: [Number, String],\n  })\n\n  const { name } = useRoute()\n  const theme = useTheme()\n  const sponsorStore = useSponsorsStore()\n  const sponsor = shallowRef(props.sponsor)\n\n  const src = computed(() => {\n    const {\n      logodark = { url: '' },\n      darkLogo = '',\n      logolight = { url: '' },\n      lightLogo = '',\n    } = sponsor?.value?.metadata ?? {}\n\n    const current = theme.current.value\n    return !current.dark ? logolight.url || lightLogo : logodark.url || darkLogo\n  })\n\n  const imgWidth = computed(() => {\n    if (props.width) return props.width\n    if (props.compact) return 112\n    if (props.comfortable) return 148\n\n    return 212\n  })\n\n  if (props.slug && !props.sponsor) {\n    watch(() => sponsorStore.sponsors, val => {\n      if (sponsor.value || !val.length) return\n\n      sponsor.value = sponsorStore.bySlug(props.slug)\n    }, { immediate: true })\n  }\n\n  function onClick () {\n    const slug = sponsor.value?.slug ?? props.slug\n\n    if (!slug) return\n\n    sweClick('sponsor-card', slug, name)\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/sponsor/Link.vue",
    "content": "<template>\n  <v-btn\n    :aria-label=\"t('become-a-sponsor')\"\n    :size=\"size\"\n    :to=\"rpath('/introduction/sponsors-and-backers/')\"\n    color=\"primary\"\n    variant=\"outlined\"\n    @click=\"sweClick('button', 'sponsors', name)\"\n  >\n    <span\n      class=\"text-capitalize font-weight-regular\"\n      v-text=\"t('become-a-sponsor')\"\n    />\n  </v-btn>\n</template>\n\n<script setup>\n  defineProps({\n    size: String,\n  })\n\n  const { name } = useRoute()\n  const { t } = useI18n()\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/sponsor/SnackbarPopup.vue",
    "content": "<template>\n  <v-snackbar\n    v-model=\"showSnackbar\"\n    color=\"background\"\n    content-class=\"mb-10 border-sm border-primary border-opacity-25\"\n    rounded=\"xl\"\n    timeout=\"-1\"\n  >\n    <template #default>\n      <div class=\"pl-4\">\n        <div class=\"d-flex flex-row justify-space-between w-100 mb-6\">\n          <h5 class=\"my-0 text-headline-medium\">Love Vuetify?</h5>\n        </div>\n        <p style=\"text-wrap: pretty;\">\n          This project is maintained in the spare time of our core team.\n          If it is useful to you or your team, consider sponsoring to\n          help support ongoing development and new features.\n        </p>\n      </div>\n    </template>\n\n    <template #actions>\n      <div class=\"d-flex flex-column py-6 pr-4\">\n        <v-btn\n          v-for=\"link in supportLinks\"\n          :key=\"link.title\"\n          :append-icon=\"link.icon\"\n          :href=\"link.link\"\n          class=\"mb-2 px-3\"\n          color=\"primary\"\n          height=\"60\"\n          min-width=\"220\"\n          spaced=\"end\"\n          target=\"_blank\"\n          variant=\"tonal\"\n          @click=\"linkClick\"\n        >\n          <span>\n            <div class=\"mb-1\">{{ link.title }}</div>\n            <small class=\"text-medium-emphasis\">{{ link.subtitle }}</small>\n          </span>\n          <template #append>\n            <v-icon size=\"24\" />\n          </template>\n        </v-btn>\n        <v-btn class=\"text-none border\" text=\"Dismiss\" @click=\"dismiss\" />\n      </div>\n    </template>\n\n  </v-snackbar>\n</template>\n<script setup lang=\"ts\">\n  import { track } from 'swetrix'\n\n  const one = useOneStore()\n  const showSnackbar = shallowRef(false)\n  const dismissed = shallowRef(false)\n  const route = useRoute()\n  watch(() => route.path, () => {\n    if (\n      !dismissed.value &&\n      !one.isSubscriber &&\n      Math.random() > 0.5 &&\n      Number(window.localStorage.getItem('userSessions')) >= 5 &&\n      !window.localStorage.getItem('sponsorPopupDismissed')\n    ) {\n      showSnackbar.value = true\n      track({\n        ev: 'sponsorPopupShown',\n      })\n    }\n  })\n\n  function linkClick () {\n    showSnackbar.value = false\n    dismissed.value = true // for this session only\n    track({\n      ev: 'sponsorPopupClick',\n    })\n  }\n\n  function dismiss () {\n    showSnackbar.value = false\n    dismissed.value = true\n    window.localStorage.setItem('sponsorPopupDismissed', new Date().toISOString())\n    track({\n      ev: 'sponsorPopupDismissed',\n    })\n  }\n\n  const supportLinks =\n    [{\n      title: 'Github',\n      subtitle: 'Become a sponsor',\n      link: 'https://github.com/sponsors/johnleider',\n      icon: 'mdi-github',\n    }, {\n      title: 'Open Collective',\n      subtitle: 'Monthly donation',\n      link: 'https://opencollective.com/vuetify',\n      icon: 'svg:M12 0C5.373 0 0 5.373 0 12s5.373 12 12 12c2.54 0 4.894-.79 6.834-2.135l-3.107-3.109a7.715 7.715 0 1 1 0-13.512l3.107-3.109A11.943 11.943 0 0 0 12 0zm9.865 5.166l-3.109 3.107A7.67 7.67 0 0 1 19.715 12a7.682 7.682 0 0 1-.959 3.727l3.109 3.107A11.943 11.943 0 0 0 24 12c0-2.54-.79-4.894-2.135-6.834z',\n    }, {\n      title: 'Discord',\n      subtitle: 'Sponsor channel',\n      link: 'https://discord.com/servers/vuetify-340160225338195969',\n      icon: 'mdi-discord',\n    }]\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/sponsor/Sponsors.vue",
    "content": "<template>\n  <v-row\n    v-if=\"sponsors?.length\"\n    class=\"v-sponsors align-center justify-start\"\n  >\n    <v-col\n      v-for=\"sponsor in sponsors\"\n      :key=\"sponsor.slug\"\n      cols=\"auto\"\n    >\n      <SponsorCard\n        :comfortable=\"Number(tier) === 2\"\n        :compact=\"Number(tier) > 2\"\n        :sponsor=\"sponsor\"\n        v-bind=\"$attrs\"\n      />\n    </v-col>\n  </v-row>\n\n  <div v-else class=\"mb-4\">\n    <AppBtn\n      append-icon=\"mdi-open-in-new\"\n      href=\"https://github.com/sponsors/johnleider\"\n      rel=\"noopener\"\n      target=\"_blank\"\n      text=\"become-a-sponsor\"\n      border\n    />\n  </div>\n</template>\n\n<script setup lang=\"ts\">\n  const props = defineProps({\n    tier: {\n      type: [Number, String],\n      required: true,\n    },\n  })\n\n  const sponsorStore = useSponsorsStore()\n\n  const sponsors = computed(() => {\n    return sponsorStore.byTier[props.tier]\n  })\n</script>\n\n<script lang=\"ts\">\n  export default {\n    inheritAttrs: false,\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/user/OneSubCard.vue",
    "content": "<template>\n  <v-card\n    v-if=\"one.isSubscriber\"\n    class=\"pa-4 text-white font-weight-bold d-flex align-start flex-column mt-2\"\n    image=\"https://cdn.vuetifyjs.com/docs/images/one/banners/one-sub-banner.png\"\n    width=\"250\"\n    flat\n  >\n    <div>\n      Vuetify One\n\n      <span class=\"font-weight-light\">Subscriber</span>\n    </div>\n\n    <div class=\"text-body-small font-weight-regular text-grey-lighten-2\">\n      Since {{ memberSince }}\n    </div>\n  </v-card>\n</template>\n\n<script setup>\n  const adapter = useDate()\n  const one = useOneStore()\n\n  const memberSince = computed(() => {\n    if (!one.subscription) return ''\n\n    const createdAt = one.subscription.createdAt\n\n    if (!adapter.isValid(createdAt)) return ''\n\n    return adapter.format(adapter.date(createdAt), 'monthAndYear')\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/user/UserTabs.vue",
    "content": "<template>\n  <v-tabs color=\"primary\">\n    <v-tab\n      v-for=\"(tab, i) in tabs\"\n      :key=\"i\"\n      class=\"text-none text-body-medium font-weight-regular\"\n      v-bind=\"tab\"\n    />\n  </v-tabs>\n</template>\n\n<script setup>\n  const tabs = computed(() => {\n    return [\n      {\n        prependIcon: 'mdi-view-dashboard-outline',\n        text: 'My Dashboard',\n        to: rpath('/user/dashboard/'),\n      },\n    ]\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/user/badges/UserAdminBadge.vue",
    "content": "<template>\n  <v-tooltip\n    v-if=\"auth.isAdmin\"\n    location=\"bottom\"\n    text=\"Admin\"\n  >\n    <template #activator=\"{ props: activatorProps }\">\n      <v-icon\n        v-bind=\"activatorProps\"\n        color=\"primary\"\n        icon=\"$vuetify\"\n      />\n    </template>\n  </v-tooltip>\n</template>\n\n<script setup>\n  const auth = useAuthStore()\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/user/badges/UserOneBadge.vue",
    "content": "<template>\n  <v-tooltip\n    v-if=\"one.isSubscriber\"\n    location=\"bottom\"\n    text=\"Vuetify One Subscriber\"\n  >\n    <template #activator=\"{ props: activatorProps }\">\n      <v-icon\n        v-bind=\"activatorProps\"\n        color=\"primary\"\n        icon=\"mdi-numeric-1-box\"\n      />\n    </template>\n  </v-tooltip>\n</template>\n\n<script setup>\n  const one = useOneStore()\n</script>\n"
  },
  {
    "path": "packages/docs/src/components/user/badges/UserSponsorBadge.vue",
    "content": "<template>\n  <v-tooltip\n    v-if=\"one.isSubscriber\"\n    location=\"bottom\"\n    text=\"Sponsor\"\n  >\n    <template #activator=\"{ props: activatorProps }\">\n      <v-icon\n        v-bind=\"activatorProps\"\n        color=\"#e98b20\"\n        icon=\"mdi-crown\"\n      />\n    </template>\n  </v-tooltip>\n</template>\n\n<script setup>\n  const one = useOneStore()\n</script>\n"
  },
  {
    "path": "packages/docs/src/composables/ad.ts",
    "content": "interface AdProps {\n  medium: string\n  slug?: string\n  type?: string\n  compact?: boolean\n  permanent?: boolean\n}\n\nexport const createAdProps = () => ({\n  medium: {\n    type: String,\n    default: 'docs',\n  },\n  slug: String,\n  type: String,\n  compact: Boolean,\n  permanent: Boolean,\n})\n\nexport const useAd = (props: AdProps) => {\n  const { locale } = useI18n()\n  const store = useAdsStore()\n  const user = useUserStore()\n\n  const ads = computed(() => {\n    return store.ads.filter(ad => ad.metadata?.discoverable && (props.type ? props.type === kebabCase(ad.metadata.type) : true))\n  })\n\n  const ad = computed(() => {\n    if (!user.one.ads.enabled && !props.permanent) return undefined\n    if (props.slug) return store.ads?.find(ad => ad.slug === props.slug)\n\n    return ads.value[Math.floor(Math.random() * ads.value.length)]\n  })\n\n  const href = computed(() => {\n    if (!ad.value) return undefined\n\n    const [url, query] = ad.value.metadata!.url.split('?')\n\n    if (!url.startsWith('http')) {\n      return leadingSlash(trailingSlash(`${locale.value}${url}`))\n    }\n\n    if (query && query.includes('utm_source')) {\n      return `${url}?${query}`\n    }\n\n    return `${url}?utm_source=vuetifyads&utm_medium=${props.medium}` + (query ? `&${query}` : '')\n  })\n\n  const isSponsored = computed(() => {\n    return ad.value?.metadata?.sponsored\n  })\n\n  const attrs = computed(() => {\n    if (!ad.value) return undefined\n\n    return {\n      class: 'text-decoration-none',\n      href: href.value,\n      rel: `noopener${isSponsored.value ? ' sponsored' : ''}`,\n      target: '_blank',\n    }\n  })\n\n  const description = computed(() => {\n    return ad.value?.metadata!.description\n  })\n\n  const src = computed(() => {\n    if (props.compact) return undefined\n\n    return (\n      ad.value?.metadata?.images?.logo?.url ||\n      ad.value?.metadata?.src\n    )\n  })\n\n  return { ad, attrs, description, src }\n}\n"
  },
  {
    "path": "packages/docs/src/composables/bin.ts",
    "content": "// Utilities\nimport { unzlibSync, zlibSync } from 'fflate'\n\nexport function compressAndEncode (str: string) {\n  // Convert the string to a Uint8Array\n  const u8 = new TextEncoder().encode(str)\n\n  // Compress the Uint8Array using zlib\n  const compressed = zlibSync(u8)\n\n  // Convert the compressed data to a binary string\n  const binary = String.fromCodePoint(...compressed)\n\n  // Base64 encode the binary string\n  const encoded = btoa(binary)\n\n  // Make it URL-safe by replacing '+' with '-', '/' with '_', and removing '='\n  return encoded.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '')\n}\n\nexport function decodeAndDecompress (encoded: string) {\n  // Make the encoded string URL-safe again by reversing previous replacements\n  const urlSafeEncoded = encoded.replace(/-/g, '+').replace(/_/g, '/')\n\n  // Decode the Base64 encoded string to binary\n  const binary = atob(urlSafeEncoded)\n\n  // Convert the binary string to a Uint8Array\n  const compressed = new Uint8Array([...binary].map(c => c.codePointAt(0)!))\n\n  // Decompress the Uint8Array using zlib\n  const decompressed = unzlibSync(compressed)\n\n  // Convert the decompressed data back to a string\n  return new TextDecoder().decode(decompressed)\n}\n\nexport function useBin (code: string, language: string, _title?: string) {\n  const hash = compressAndEncode(code)\n  const map: { [key: string]: string } = {\n    bash: 'markdown',\n    js: 'javascript',\n    ts: 'typescript',\n  }\n\n  const title = _title ? `&title=${_title}` : ''\n  return `https://bin.vuetifyjs.com?code=${hash}&lang=${map[language] ?? language}${title}`\n}\n"
  },
  {
    "path": "packages/docs/src/composables/cosmic.ts",
    "content": "// Imports\nimport { createBucketClient } from '@cosmicjs/sdk'\n\nexport function useCosmic<T> (\n  bucketSlug = import.meta.env.VITE_COSMIC_2_BUCKET_SLUG as string | undefined,\n  readKey = import.meta.env.VITE_COSMIC_2_BUCKET_READ_KEY as string | undefined,\n) {\n  return {\n    bucket: (readKey && bucketSlug)\n      ? createBucketClient({ bucketSlug, readKey })\n      : undefined,\n  }\n}\n"
  },
  {
    "path": "packages/docs/src/composables/frontmatter.ts",
    "content": "type Frontmatter = {\n  meta: {\n    nav?: string\n    title: string\n    description?: string\n    keywords?: string[]\n  }\n  assets?: string[]\n  backmatter?: boolean\n  features?: {\n    figma?: boolean\n    label?: string\n    report?: string\n    github?: string\n    spec?: string\n  }\n  fluid?: boolean\n  related?: string[]\n  toc?: TocItem[]\n}\n\ntype TocItem = {\n  to: string\n  text: string\n  level: number\n}\n\nexport function useFrontmatter () {\n  const router = useRouter()\n\n  const frontmatter = shallowRef<Frontmatter>()\n  let timeout = 750\n  watch(router.currentRoute, route => {\n    setTimeout(() => {\n      frontmatter.value = (route.matched.at(-1)!.instances.default as any)?.frontmatter\n      timeout = 1\n    }, timeout)\n  }, { immediate: true })\n\n  return readonly(frontmatter)\n}\n"
  },
  {
    "path": "packages/docs/src/composables/markdown.ts",
    "content": "import octokit from '@/plugins/octokit'\n\nexport function useMarkdown () {\n  const one = useOneStore()\n  const route = useRoute()\n  const frontmatter = useFrontmatter()\n  const copied = shallowRef(false)\n  const isClipboardSupported = !!navigator.clipboard\n\n  const branch = getBranch()\n\n  async function copyPageAsMarkdown () {\n    if (!isClipboardSupported) {\n      console.error('Native Clipboard API is not supported.')\n      return\n    }\n\n    if (!one.isSubscriber) {\n      console.error('You must be a subscriber to use this feature.')\n      return\n    }\n\n    let markdownContent = `# ${frontmatter.value?.meta.title || 'Page Title'}\\n\\n`\n    markdownContent += `Source: ${window.location.origin}${route.path}\\n\\n`\n\n    try {\n      const path = `packages/docs/src/pages${route.path.replace(/\\/$/, '')}.md`\n\n      const response = await octokit.request('GET /repos/{owner}/{repo}/contents/{path}', {\n        owner: 'vuetifyjs',\n        repo: 'vuetify',\n        path,\n        ref: branch,\n      })\n\n      if (response.data && 'content' in response.data) {\n        const rawMd = atob(response.data.content)\n        let processedMd = rawMd\n\n        // Remove <ApiInline /> and <ExamplesUsage /> tags completely\n        processedMd = processedMd\n          .replace(/<ApiInline[\\s\\S]*?>([\\s\\S]*?\\/>\\n\\n)?/g, '')\n          .replace(/<ExamplesUsage[\\s\\S]*?>([\\s\\S]*?\\/>\\n\\n)?/g, '')\n\n        // Replace every <ExamplesExample ...> tag with the raw Vue source of its file\n        if (processedMd.includes('<ExamplesExample')) {\n          const tagRegex = /<ExamplesExample\\b([^>]*?)>(?:[\\s\\S]*?<\\/ExamplesExample>)|<ExamplesExample\\b([^>]*?)\\/>/g\n          const matches = [...processedMd.matchAll(tagRegex)]\n\n          for (const m of matches) {\n            const attrs = m[1] ?? m[2] ?? ''\n            const fileMatch = attrs.match(/\\bfile\\s*=\\s*\"([^\"]+)\"/)\n            if (!fileMatch) {\n              // Remove tag if no file attribute\n              processedMd = processedMd.replace(m[0], '')\n              continue\n            }\n\n            const filePath = fileMatch[1].replace(/\\\\+/g, '/').replace(/\\/$/, '')\n            const pathExamples = `packages/docs/src/examples/${filePath}.vue`\n\n            try {\n              const responseExamples = await octokit.request('GET /repos/{owner}/{repo}/contents/{path}', {\n                owner: 'vuetifyjs',\n                repo: 'vuetify',\n                path: pathExamples,\n                ref: branch,\n              })\n\n              if (responseExamples.data && 'content' in responseExamples.data) {\n                const rawVue = atob(responseExamples.data.content)\n                // Replace whole tag with fenced code block of the example source\n                processedMd = processedMd.replace(m[0], `\\n\\`\\`\\`vue\\n${rawVue}\\n\\`\\`\\`\\n`)\n              } else {\n                // If fetch fails, strip the tag to avoid leaving placeholders\n                processedMd = processedMd.replace(m[0], '')\n              }\n            } catch (e) {\n              console.error('Error fetching example file', filePath, e)\n              processedMd = processedMd.replace(m[0], '')\n            }\n          }\n        }\n\n        const contentWithoutFrontmatter = processedMd.replace(/---[\\s\\S]*?---/, '').trim()\n        markdownContent += contentWithoutFrontmatter\n      } else {\n        markdownContent += 'Could not fetch page content.'\n      }\n    } catch (error) {\n      console.error('Error fetching page content from GitHub:', error)\n      markdownContent += 'Error fetching page content.'\n    }\n\n    try {\n      await navigator.clipboard.writeText(markdownContent)\n      copied.value = true\n      setTimeout(() => (copied.value = false), 2000)\n    } catch (err) {\n      console.error('Failed to copy text: ', err)\n    }\n  }\n\n  return {\n    copyPageAsMarkdown,\n    copied,\n    isClipboardSupported,\n  }\n}\n"
  },
  {
    "path": "packages/docs/src/composables/playground.ts",
    "content": "// Utilities\nimport { strFromU8, strToU8, zlibSync } from 'fflate'\nimport { version as vuetifyVersion } from 'vuetify'\nimport { version as vueVersion } from 'vue'\n\nexport type CodeSection = {\n  name: string\n  content: string\n  language: string\n}\n\n// This is copied directly from playground\nfunction utoa (data: string): string {\n  const buffer = strToU8(data)\n  const zipped = zlibSync(buffer, { level: 9 })\n  const binary = strFromU8(zipped, true)\n  return btoa(binary)\n}\n\nexport function usePlayground (\n  sections: CodeSection[] = [],\n  css: string[] = [],\n  imports: Record<string, string> = {},\n  setup?: string,\n) {\n  const files: Record<string, string> = {\n    'App.vue': sections\n      .filter(section => ['script', 'template', 'style'].includes(section.name))\n      .map(section => section.content)\n      .join('\\n\\n'),\n    'links.json': JSON.stringify({ css }),\n    'import-map.json': JSON.stringify({ imports }),\n  }\n\n  if (setup) {\n    files['vuetify.js'] = setup\n  }\n\n  const hash = utoa(JSON.stringify([files, vueVersion, vuetifyVersion, true]))\n\n  return `https://play.vuetifyjs.com#${hash}`\n}\n"
  },
  {
    "path": "packages/docs/src/data/301.json",
    "content": "{\n  \"components/dropdowns\": \"/components/menus\",\n  \"quick-start\": \"/getting-started/installation\",\n  \"vuetify/quick-start\": \"/getting-started/installation\",\n  \"getting-started/quick-start/\": \"/getting-started/installation\",\n  \"motion\": \"/styles/transitions\",\n  \"components/sidebars\": \"/components/navigation-drawers\",\n  \"components/v-navigation-drawer\": \"/components/navigation-drawers\",\n  \"components/collapsible\": \"/components/expansion-panels\",\n  \"components/navbars\": \"/components/toolbars\",\n  \"components/toasts\": \"/components/snackbars\",\n  \"components/carousel\": \"/components/carousels\",\n  \"components/datatables\": \"/components/data-tables/basics\",\n  \"components/expansion-panel\": \"/components/expansion-panels\",\n  \"components/footer\": \"/components/footers\",\n  \"directives/badges\": \"/components/badges\",\n  \"vuetify/why-vuetify\": \"/getting-started/why-vuetify\",\n  \"vuetify/frequently-asked-questions\": \"/getting-started/frequently-asked-questions\",\n  \"vuetify/sponsors-and-backers\": \"/introduction/sponsors-and-backers\",\n  \"getting-started/releases-and-migrations/\": \"/getting-started/upgrade-guide\",\n  \"vuetify/releases-and-migrations\": \"/getting-started/upgrade-guide\",\n  \"vuetify/contributing\": \"/getting-started/contributing\",\n  \"vuetify/roadmap\": \"/getting-started/roadmap\",\n  \"vuetify/a-la-carte\": \"/features/treeshaking\",\n  \"getting-started/a-la-carte\": \"/features/treeshaking\",\n  \"guides/a-la-carte\": \"/features/treeshaking\",\n  \"customization/a-la-carte\": \"/features/treeshaking\",\n  \"pre-made-themes\": \"/resources/themes\",\n  \"layout/pre-made-themes\": \"/resources/themes\",\n  \"themes/premium\": \"/resources/themes\",\n  \"layout/grid\": \"/components/grids\",\n  \"layout/pre-defined\": \"/getting-started/wireframes\",\n  \"getting-started/pre-made-layouts\": \"/getting-started/wireframes\",\n  \"layout/breakpoints\": \"/features/display-and-platform\",\n  \"layout/aspect-ratios\": \"/components/aspect-ratios\",\n  \"layout/spacing\": \"/styles/spacing\",\n  \"layout/alignment\": \"/styles/alignment\",\n  \"layout/display\": \"/styles/display\",\n  \"layout/elevation\": \"/styles/elevation\",\n  \"style/colors\": \"/styles/colors\",\n  \"style/theme\": \"/customization/theme\",\n  \"style/typography\": \"/styles/text-and-typography\",\n  \"styles/typography\": \"/styles/text-and-typography\",\n  \"styles/text\": \"/styles/text-and-typography\",\n  \"style/content\": \"/styles/content\",\n  \"motion/scroll\": \"/customization/scrolling\",\n  \"styles/scroll\": \"/customization/scrolling\",\n  \"motion/transitions\": \"/styles/transitions\",\n  \"components/form\": \"/components/forms\",\n  \"components/selection-controls\": \"/components/checkboxes\",\n  \"components/slide-toggles\": \"/components/switches\",\n  \"components/buttons-and-indicators\": \"/components/buttons\",\n  \"framework/pre-defined\": \"/getting-started/pre-made-layouts\",\n  \"framework/pre-made\": \"/getting-started/pre-made-layouts\",\n  \"framework/pre-defined-layouts\": \"/getting-started/pre-made-layouts\",\n  \"components/data-iterator\": \"/components/data-iterators\",\n  \"framework/a-la-carte\": \"/customization/a-la-carte\",\n  \"framework/grid\": \"/components/grids\",\n  \"framework/application\": \"/components/application\",\n  \"framework/breakpoints\": \"/features/display-and-platform\",\n  \"framework/icons\": \"/customization/icons\",\n  \"framework/i18n\": \"/customization/internationalization\",\n  \"framework/theme\": \"/customization/theme\",\n  \"framework/scroll\": \"/customization/scrolling\",\n  \"framework/aspect-ratios\": \"/components/aspect-ratios\",\n  \"framework/pre-made-layouts\": \"/getting-started/pre-made-layouts\",\n  \"framework/colors\": \"/styles/colors\",\n  \"framework/content\": \"/styles/content\",\n  \"framework/typography\": \"/styles/typography\",\n  \"framework/display\": \"/styles/display\",\n  \"framework/elevation\": \"/styles/elevation\",\n  \"framework/spacing\": \"/styles/spacing\",\n  \"styles/alignment\": \"/styles/text\",\n  \"framework/text-alignment\": \"/styles/text-and-typography\",\n  \"styles/text-alignment\": \"/styles/text-and-typography\",\n  \"framework/transitions\": \"/styles/transitions\",\n  \"customizing/sandbox\": \"/customization/sandbox\",\n  \"customizing/a-la-carte\": \"/customization/a-la-carte\",\n  \"customizing/breakpoints\": \"/features/display-and-platform\",\n  \"customizing/theme\": \"/customization/theme\",\n  \"customizing/icons\": \"/customization/icons\",\n  \"customizing/i18n\": \"/customization/internationalization\",\n  \"getting-started/why-vuetify\": \"/introduction/why-vuetify\",\n  \"getting-started/meet-the-team\": \"/about/meet-the-team\",\n  \"getting-started/sponsors-and-backers\": \"/introduction/sponsors-and-backers\",\n  \"getting-started/roadmap\": \"/introduction/roadmap\",\n  \"getting-started/long-term-support\": \"/introduction/long-term-support\",\n  \"getting-started/consulting-and-support\": \"/introduction/enterprise-support\",\n  \"getting-started/support/enterprise\": \"/introduction/enterprise-support\",\n  \"components/textarea\": \"/components/textareas\",\n  \"components/virtual-scrollers\": \"/components/virtual-scroller\",\n  \"directives/resizing\": \"/directives/resize\",\n  \"directives/ripples\": \"/directives/ripple\",\n  \"directives/scrolling\": \"/directives/scroll\",\n  \"directives/touch-support\": \"/directives/touch\",\n  \"introduction/frequently-asked-questions\": \"/getting-started/frequently-asked-questions\",\n  \"professional-support/consulting\": \"/introduction/enterprise-support\",\n  \"professional-support/enterprise\": \"/introduction/enterprise-support\",\n  \"introduction/support\": \"/introduction/enterprise-support\",\n  \"introduction/enterprise\": \"/introduction/enterprise-support\",\n  \"introduction/consulting\": \"/introduction/enterprise-support\",\n  \"customization/accessibility\": \"/features/accessibility\",\n  \"customization/rtl\": \"/features/bidirectionality\",\n  \"features/rtl\": \"/features/bidirectionality\",\n  \"features/breakpoints\": \"/features/display-and-platform\",\n  \"features/bidirectionality\": \"/features/internationalization\",\n  \"customization/bidirectionality\": \"/features/bidirectionality\",\n  \"customization/breakpoints\": \"/features/display-and-platform\",\n  \"customization/global-config\": \"/features/global-config\",\n  \"customization/scrolling\": \"/features/scrolling\",\n  \"customization/icons\": \"/features/icon-fonts\",\n  \"customization/internationalization\": \"/features/internationalization\",\n  \"customization/presets\": \"/features/presets\",\n  \"customization/sass-variables\": \"/features/sass-variables\",\n  \"customization/theme\": \"/features/theme\",\n  \"about/sponsors-and-backers\": \"/introduction/sponsors-and-backers\",\n  \"components/simple-tables\": \"/components/tables\",\n  \"components/data-tables\": \"/components/data-tables/basics\",\n  \"components/date-pickers-month\": \"/introduction/roadmap\",\n  \"components/overflow-btns\": \"/introduction/roadmap\",\n  \"components/server-side-data-tables\": \"/components/data-tables/server-side-tables\",\n  \"components/virtual-data-tables\": \"/components/data-tables/virtual-tables\",\n  \"api/v-click-outside\": \"/api/v-click-outside-directive\",\n  \"api/v-intersect\": \"/api/v-intersect-directive\",\n  \"api/v-mutate\": \"/api/v-mutate-directive\",\n  \"api/v-resize\": \"/api/v-resize-directive\",\n  \"api/v-ripple\": \"/api/v-ripple-directive\",\n  \"api/v-scroll\": \"/api/v-scroll-directive\",\n  \"api/v-touch\": \"/api/v-touch-directive\"\n}\n"
  },
  {
    "path": "packages/docs/src/data/metadata.json",
    "content": "{\n  \"title\": \"Vuetify — A Vue Component Framework\",\n  \"description\": \"Vuetify is a no design skills required UI Component Framework for Vue. It provides you with all of the tools necessary to create beautiful content rich web applications.\",\n  \"keywords\": \"vue, material design components, vue components, material design components, vuetify, vuetify, component framework\"\n}\n"
  },
  {
    "path": "packages/docs/src/data/nav.json",
    "content": "[\n  {\n    \"title\": \"introduction\",\n    \"inactiveIcon\": \"mdi-script-text-outline\",\n    \"activeIcon\": \"mdi-script-text\",\n    \"items\": [\n      \"why-vuetify\",\n      \"long-term-support\",\n      \"roadmap\",\n      \"sponsors-and-backers\",\n      { \"divider\": true },\n      { \"subheader\": \"professional-support\" },\n      \"enterprise-support\"\n    ]\n  },\n  {\n    \"title\": \"getting-started\",\n    \"inactiveIcon\": \"mdi-speedometer-medium\",\n    \"activeIcon\": \"mdi-speedometer\",\n    \"items\": [\n      \"installation\",\n      \"frequently-asked-questions\",\n      \"wireframes\",\n      \"unit-testing\",\n      \"browser-support\",\n      \"upgrade-guide\",\n      \"release-notes\",\n      \"contributing\"\n    ]\n  },\n  {\n    \"title\": \"features\",\n    \"inactiveIcon\": \"mdi-image-edit-outline\",\n    \"activeIcon\": \"mdi-image-edit\",\n    \"items\": [\n      \"accessibility\",\n      \"aliasing\",\n      \"application-layout\",\n      \"blueprints\",\n      {\n        \"title\": \"css-utilities\",\n        \"subfolder\": \"features\",\n        \"activeIcon\": \"\",\n        \"inactiveIcon\": \"\",\n        \"items\": [\n          \"overview\",\n          \"unocss-vuetify-preset\",\n          \"unocss-tailwind-preset\",\n          \"tailwindcss\"\n        ]\n      },\n      \"dates\",\n      \"display-and-platform\",\n      \"global-configuration\",\n      \"hotkey\",\n      \"icon-fonts\",\n      \"internationalization\",\n      \"scrolling\",\n      \"sass-variables\",\n      \"theme\",\n      \"treeshaking\"\n    ]\n  },\n  {\n    \"title\": \"styles\",\n    \"inactiveIcon\": \"mdi-palette-outline\",\n    \"activeIcon\": \"mdi-palette\",\n    \"items\": [\n      \"entry-points\",\n      \"css-reset\",\n      \"layers\",\n      \"transitions\",\n      \"colors\",\n      { \"divider\": true },\n      {\n        \"subheader\": \"utility-classes\"\n      },\n      \"borders\",\n      \"border-radius\",\n      \"content\",\n      \"cursor\",\n      \"display\",\n      \"elevation\",\n      \"flex\",\n      \"float\",\n      \"opacity\",\n      \"overflow\",\n      \"position\",\n      \"sizing\",\n      \"spacing\",\n      \"text-and-typography\"\n    ]\n  },\n  {\n    \"title\": \"concepts\",\n    \"inactiveIcon\": \"mdi-puzzle-outline\",\n    \"activeIcon\": \"mdi-puzzle\",\n    \"items\": [\n      \"density-and-sizing\",\n      \"items\",\n      \"routing\",\n      \"v-model\",\n      \"variants\"\n    ]\n  },\n  {\n    \"title\": \"components\",\n    \"inactiveIcon\": \"mdi-view-dashboard-outline\",\n    \"activeIcon\": \"mdi-view-dashboard\",\n    \"items\": [\n      \"all\",\n      {\n        \"title\": \"explorer\",\n        \"routeMatch\": \"explorer/:name(.*)\",\n        \"routePath\": \"explorer\",\n        \"subtitle\": \"browse-components\"\n      },\n      \"application\",\n      { \"divider\": true },\n      { \"subheader\": \"containment\" },\n      \"bottom-sheets\",\n      \"buttons\",\n      \"cards\",\n      \"chips\",\n      \"dialogs\",\n      \"dividers\",\n      \"expansion-panels\",\n      \"lists\",\n      \"menus\",\n      \"overlays\",\n      \"sheets\",\n      \"toolbars\",\n      \"tooltips\",\n      { \"divider\": true },\n      { \"subheader\": \"navigation\" },\n      \"app-bars\",\n      \"bottom-navigation\",\n      \"breadcrumbs\",\n      \"floating-action-buttons\",\n      \"footers\",\n      \"navigation-drawers\",\n      \"paginations\",\n      \"speed-dials\",\n      \"system-bars\",\n      \"tabs\",\n      { \"divider\": true },\n      { \"subheader\": \"form-inputs-and-controls\" },\n      \"autocompletes\",\n      \"checkboxes\",\n      \"combobox\",\n      \"file-inputs\",\n      \"forms\",\n      \"inputs\",\n      \"number-inputs\",\n      \"otp-input\",\n      \"radio-buttons\",\n      \"range-sliders\",\n      \"selects\",\n      \"sliders\",\n      \"switches\",\n      \"text-fields\",\n      \"textareas\",\n      { \"divider\": true },\n      { \"subheader\": \"data-and-display\" },\n      \"calendars\",\n      \"confirm-edit\",\n      \"data-iterators\",\n      {\n        \"title\": \"data-tables\",\n        \"subfolder\": \"components\",\n        \"activeIcon\": \"\",\n        \"inactiveIcon\": \"\",\n        \"items\": [\n          \"introduction\",\n          { \"subheader\": \"guide\" },\n          \"basics\",\n          \"data-and-display\",\n          { \"subheader\": \"types\" },\n          \"server-side-tables\",\n          \"virtual-tables\"\n        ]\n      },\n      \"hotkeys\",\n      \"sparklines\",\n      \"infinite-scroller\",\n      \"tables\",\n      \"treeview\",\n      \"virtual-scroller\",\n      { \"divider\": true },\n      { \"subheader\": \"grids\" },\n      \"grids\",\n      { \"divider\": true },\n      { \"subheader\": \"selection\" },\n      \"button-groups\",\n      \"carousels\",\n      \"chip-groups\",\n      \"item-groups\",\n      \"slide-groups\",\n      \"steppers\",\n      \"windows\",\n      { \"divider\": true },\n      { \"subheader\": \"feedback\" },\n      \"alerts\",\n      \"badges\",\n      \"banners\",\n      \"empty-states\",\n      \"hover\",\n      \"progress-circular\",\n      \"progress-linear\",\n      \"ratings\",\n      \"skeleton-loaders\",\n      \"snackbars\",\n      \"snackbar-queue\",\n      \"timelines\",\n      { \"divider\": true },\n      { \"subheader\": \"images-and-icons\" },\n      \"aspect-ratios\",\n      \"avatars\",\n      \"icons\",\n      \"images\",\n      \"parallax\",\n      { \"divider\": true },\n      { \"subheader\": \"pickers\" },\n      \"color-pickers\",\n      \"date-pickers\",\n      \"time-pickers\",\n      { \"divider\": true },\n      { \"subheader\": \"providers\" },\n      \"defaults-providers\",\n      \"locale-providers\",\n      \"theme-providers\",\n      { \"divider\": true },\n      { \"subheader\": \"miscellaneous\" },\n      \"lazy\",\n      \"no-ssr\"\n    ]\n  },\n  {\n    \"title\": \"api\",\n    \"inactiveIcon\": \"mdi-flask-empty-outline\",\n    \"activeIcon\": \"mdi-flask-outline\",\n    \"items\": [\n      \"hotkey\"\n    ]\n  },\n  {\n    \"title\": \"directives\",\n    \"inactiveIcon\": \"mdi-function\",\n    \"activeIcon\": \"mdi-function\",\n    \"items\": [\n      \"click-outside\",\n      \"intersect\",\n      \"mutate\",\n      \"resize\",\n      \"ripple\",\n      \"scroll\",\n      \"tooltip\",\n      \"touch\"\n    ]\n  },\n  {\n    \"title\": \"labs\",\n    \"inactiveIcon\": \"mdi-beaker-outline\",\n    \"activeIcon\": \"mdi-beaker\",\n    \"items\": [\n      \"introduction\",\n      {\n        \"title\": \"avatar-groups\",\n        \"subfolder\": \"components\"\n      },\n      {\n        \"title\": \"color-inputs\",\n        \"subfolder\": \"components\"\n      },\n      {\n        \"title\": \"command-palettes\",\n        \"subfolder\": \"components\"\n      },\n      {\n        \"title\": \"date-inputs\",\n        \"subfolder\": \"components\"\n      },\n      {\n        \"title\": \"file-upload\",\n        \"subfolder\": \"components\"\n      },\n      {\n        \"title\": \"icon-buttons\",\n        \"subfolder\": \"components\"\n      },\n      {\n        \"title\": \"pie-charts\",\n        \"subfolder\": \"components\"\n      },\n      {\n        \"title\": \"progress\",\n        \"subfolder\": \"components\"\n      },\n      {\n        \"title\": \"pull-to-refresh\",\n        \"subfolder\": \"components\"\n      },\n      {\n        \"title\": \"vertical-steppers\",\n        \"subfolder\": \"components\"\n      },\n      {\n        \"title\": \"mask-inputs\",\n        \"subfolder\": \"components\"\n      },\n      {\n        \"title\": \"videos\",\n        \"subfolder\": \"components\"\n      },\n      {\n        \"title\": \"rules\",\n        \"subfolder\": \"features\"\n      }\n    ]\n  },\n  {\n    \"title\": \"resources\",\n    \"inactiveIcon\": \"mdi-human-male-board\",\n    \"activeIcon\": \"mdi-human-male-board\",\n    \"items\": [\n      \"brand-kit\",\n      \"jobs-for-vue\",\n      \"made-with-vuetify\",\n      \"themes\",\n      { \"divider\": true },\n      { \"subheader\": \"guides\" },\n      \"search-engine\",\n      \"ui-kits\"\n    ]\n  },\n  {\n    \"title\": \"about\",\n    \"inactiveIcon\": \"$vuetify-outline\",\n    \"activeIcon\": \"$vuetify\",\n    \"items\": [\n      \"code-of-conduct\",\n      \"licensing\",\n      \"meet-the-team\",\n      \"security-disclosure\"\n    ]\n  }\n]\n"
  },
  {
    "path": "packages/docs/src/data/new-in.json",
    "content": "{\n  \"useTheme\": {\n    \"exposed\": {\n      \"change\": \"3.9.0\",\n      \"toggle\": \"3.9.0\",\n      \"cycle\": \"3.9.0\"\n    }\n  },\n  \"VAppBar\": {\n    \"props\": {\n      \"scrollBehavior\": \"3.2.0\"\n    }\n  },\n  \"VAutocomplete\": {\n    \"props\": {\n      \"autocomplete\": \"3.10.0\",\n      \"autoSelectFirst\": \"3.3.0\",\n      \"clearOnSelect\": \"3.5.0\",\n      \"listProps\": \"3.5.0\",\n      \"menuElevation\": \"4.0.0\"\n    },\n    \"slots\": {\n      \"menu-header\": \"3.12.0\",\n      \"menu-footer\": \"3.12.0\"\n    }\n  },\n  \"VAvatar\": {\n    \"props\": {\n      \"text\": \"3.4.0\",\n      \"border\": \"3.7.0\",\n      \"badge\": \"4.0.0\"\n    },\n    \"slots\": {\n      \"badge\": \"4.0.0\"\n    }\n  },\n  \"VBadge\": {\n    \"props\": {\n      \"dotSize\": \"4.0.0\"\n    }\n  },\n  \"VBanner\": {\n    \"props\": {\n      \"bgColor\": \"3.4.0\"\n    }\n  },\n  \"VBreadcrumbsItem\": {\n    \"props\": {\n      \"width\": \"3.11.0\",\n      \"maxWidth\": \"3.11.0\"\n    }\n  },\n  \"VBtn\": {\n    \"props\": {\n      \"text\": \"3.2.0\",\n      \"slim\": \"3.4.0\",\n      \"readonly\": \"3.6.0\",\n      \"activeColor\": \"3.7.0\",\n      \"spaced\": \"3.10.0\"\n    }\n  },\n  \"VCarousel\": {\n    \"props\": {\n      \"crossfade\": \"3.10.0\",\n      \"transitionDuration\": \"3.10.0\"\n    }\n  },\n  \"VChip\": {\n    \"props\": {\n      \"baseColor\": \"3.8.0\"\n    }\n  },\n  \"VChipGroup\": {\n    \"props\": {\n      \"scrollToActive\": \"3.10.6\"\n    }\n  },\n  \"VColorPicker\": {\n    \"props\": {\n      \"hideEyeDropper\": \"3.10.0\",\n      \"eyeDropperIcon\": \"3.10.0\",\n      \"hideTitle\": \"3.10.0\"\n    }\n  },\n  \"VCombobox\": {\n    \"props\": {\n      \"alwaysFilter\": \"3.10.4\",\n      \"autocomplete\": \"3.10.0\",\n      \"clearOnSelect\": \"3.5.0\",\n      \"listProps\": \"3.5.0\",\n      \"menuElevation\": \"4.0.0\"\n    },\n    \"slots\": {\n      \"menu-header\": \"3.12.0\",\n      \"menu-footer\": \"3.12.0\"\n    }\n  },\n  \"VConfirmEdit\": {\n    \"props\": {\n      \"hideActions\": \"3.8.0\"\n    }\n  },\n  \"VDatePicker\": {\n    \"props\": {\n      \"events\": \"3.11.0\",\n      \"eventColor\": \"3.11.0\",\n      \"controlHeight\": \"3.8.0\",\n      \"controlVariant\": \"3.11.0\",\n      \"firstDayOfYear\": \"3.10.0\",\n      \"headerColor\": \"3.8.0\",\n      \"headerDateFormat\": \"3.11.0\",\n      \"hideTitle\": \"3.10.0\",\n      \"landscape\": \"3.11.0\",\n      \"landscapeHeaderWidth\": \"3.11.0\",\n      \"noMonthPicker\": \"3.11.0\"\n    },\n    \"slots\": {\n      \"controls\": \"3.11.0\"\n    }\n  },\n  \"VDataIterator\": {\n    \"props\": {\n      \"initialSortOrder\": \"3.11.0\"\n    }\n  },\n  \"VDataTable\": {\n    \"props\": {\n      \"collapseIcon\": \"3.10.0\",\n      \"expandIcon\": \"3.10.0\",\n      \"groupCollapseIcon\": \"3.10.0\",\n      \"groupExpandIcon\": \"3.10.0\",\n      \"headerProps\": \"3.5.0\",\n      \"initialSortOrder\": \"3.11.0\",\n      \"pageBy\": \"3.12.0\",\n      \"sortIcon\": \"3.12.0\"\n    },\n    \"slots\": {\n      \"group-summary\": \"3.10.0\"\n    }\n  },\n  \"VDataTableServer\": {\n    \"props\": {\n      \"collapseIcon\": \"3.10.0\",\n      \"expandIcon\": \"3.10.0\",\n      \"groupCollapseIcon\": \"3.10.0\",\n      \"groupExpandIcon\": \"3.10.0\",\n      \"initialSortOrder\": \"3.11.0\",\n      \"pageBy\": \"3.12.0\",\n      \"sortIcon\": \"3.12.0\"\n    },\n    \"slots\": {\n      \"group-summary\": \"3.10.0\"\n    }\n  },\n  \"VDataTableVirtual\": {\n    \"props\": {\n      \"collapseIcon\": \"3.10.0\",\n      \"expandIcon\": \"3.10.0\",\n      \"groupCollapseIcon\": \"3.10.0\",\n      \"groupExpandIcon\": \"3.10.0\",\n      \"initialSortOrder\": \"3.11.0\",\n      \"sortIcon\": \"3.12.0\"\n    },\n    \"slots\": {\n      \"group-summary\": \"3.10.0\"\n    }\n  },\n  \"VDialog\": {\n    \"props\": {\n      \"captureFocus\": \"3.11.0\",\n      \"retainFocus\": \"3.11.0\",\n      \"stickToTarget\": \"3.10.0\",\n      \"viewportMargin\": \"3.11.0\"\n    }\n  },\n  \"VDivider\": {\n    \"props\": {\n      \"gradient\": \"3.11.0\",\n      \"contentOffset\": \"3.11.0\",\n      \"variant\": \"3.11.0\"\n    }\n  },\n  \"VExpansionPanels\": {\n    \"props\": {\n      \"static\": \"3.4.0\"\n    }\n  },\n  \"VField\": {\n    \"props\": {\n      \"iconColor\": \"3.8.0\",\n      \"glow\": \"3.8.0\"\n    }\n  },\n  \"VFileInput\": {\n    \"props\": {\n      \"filterByType\": \"3.10.0\",\n      \"truncateLength\": \"3.10.0\"\n    }\n  },\n  \"VFileUpload\": {\n    \"props\": {\n      \"filterByType\": \"3.10.0\"\n    }\n  },\n  \"VIcon\": {\n    \"props\": {\n      \"opacity\": \"3.8.0\"\n    }\n  },\n  \"VImg\": {\n    \"props\": {\n      \"position\": \"3.4.0\",\n      \"draggable\": \"3.4.0\",\n      \"referrerpolicy\": \"3.4.0\",\n      \"crossorigin\": \"3.4.0\",\n      \"absolute\": \"3.7.0\",\n      \"imageClass\": \"3.12.0\"\n    }\n  },\n  \"VInput\": {\n    \"props\": {\n      \"iconColor\": \"3.8.0\",\n      \"glow\": \"3.8.0\"\n    }\n  },\n  \"VList\": {\n    \"props\": {\n      \"indent\": \"3.11.0\",\n      \"itemsRegistration\": \"3.11.0\",\n      \"prependGap\": \"3.11.0\"\n    }\n  },\n  \"VListItem\": {\n    \"props\": {\n      \"baseColor\": \"3.3.0\",\n      \"prependGap\": \"3.11.0\",\n      \"slim\": \"3.4.0\"\n    }\n  },\n  \"VMenu\": {\n    \"props\": {\n      \"captureFocus\": \"3.11.0\",\n      \"retainFocus\": \"3.11.0\",\n      \"stickToTarget\": \"3.10.0\",\n      \"submenu\": \"3.7.0\",\n      \"viewportMargin\": \"3.11.0\"\n    }\n  },\n  \"VNavigationDrawer\": {\n    \"props\": {\n      \"captureFocus\": \"3.11.0\",\n      \"retainFocus\": \"3.11.0\",\n      \"persistent\": \"3.6.0\"\n    }\n  },\n  \"VNumberInput\": {\n    \"props\": {\n      \"autocomplete\": \"3.10.0\"\n    }\n  },\n  \"VOtpInput\": {\n    \"props\": {\n      \"density\": \"3.12.0\",\n      \"masked\": \"3.12.0\"\n    }\n  },\n  \"VOverlay\": {\n    \"props\": {\n      \"captureFocus\": \"3.11.0\",\n      \"retainFocus\": \"3.11.0\",\n      \"stickToTarget\": \"3.10.0\",\n      \"viewportMargin\": \"3.11.0\"\n    }\n  },\n  \"VPicker\": {\n    \"props\": {\n      \"hideTitle\": \"3.10.0\"\n    }\n  },\n  \"VProgressCircular\": {\n    \"props\": {\n      \"reveal\": \"3.12.0\",\n      \"rounded\": \"3.11.0\"\n    }\n  },\n  \"VProgressLinear\": {\n    \"props\": {\n      \"chunkCount\": \"3.10.0\",\n      \"chunkGap\": \"3.10.0\",\n      \"chunkWidth\": \"3.10.0\"\n    }\n  },\n  \"VRow\": {\n    \"props\": {\n      \"size\": \"4.0.0\"\n    }\n  },\n  \"VSelect\": {\n    \"props\": {\n      \"autocomplete\": \"3.10.0\",\n      \"listProps\": \"3.5.0\",\n      \"menuElevation\": \"4.0.0\",\n      \"noAutoScroll\": \"3.9.0\"\n    },\n    \"slots\": {\n      \"menu-header\": \"3.12.0\",\n      \"menu-footer\": \"3.12.0\"\n    }\n  },\n  \"VSlider\": {\n    \"events\": {\n      \"start\": \"3.2.0\",\n      \"end\": \"3.2.0\"\n    }\n  },\n  \"VSlideGroup\": {\n    \"props\": {\n      \"contentClass\": \"3.9.0\",\n      \"scrollToActive\": \"3.10.6\"\n    }\n  },\n  \"VSnackbar\": {\n    \"props\": {\n      \"loading\": \"4.0.0\",\n      \"prependAvatar\": \"4.0.0\",\n      \"prependIcon\": \"4.0.0\",\n      \"reverseTimer\": \"4.0.0\",\n      \"timer\": \"3.4.0\",\n      \"timerColor\": \"4.0.0\",\n      \"text\": \"3.4.0\"\n    },\n    \"slots\": {\n      \"header\": \"4.0.0\",\n      \"prepend\": \"4.0.0\"\n    }\n  },\n  \"VSnackbarQueue\": {\n    \"props\": {\n      \"closable\": \"4.0.0\",\n      \"closeText\": \"4.0.0\",\n      \"gap\": \"4.0.0\",\n      \"totalVisible\": \"3.11.0\"\n    }\n  },\n  \"VStepper\": {\n    \"props\": {\n      \"itemProps\": \"3.11.0\"\n    }\n  },\n  \"VSwitch\": {\n    \"slots\": {\n      \"thumb\": \"3.5.0\",\n      \"track-false\": \"3.5.0\",\n      \"track-true\": \"3.5.0\"\n    }\n  },\n  \"VTab\": {\n    \"props\": {\n      \"inset\": \"3.11.2\",\n      \"text\": \"3.2.0\",\n      \"spaced\": \"3.10.0\",\n      \"sliderTransition\": \"3.11.0\",\n      \"sliderTransitionDuration\": \"3.11.0\"\n    }\n  },\n  \"VTabs\": {\n    \"props\": {\n      \"inset\": \"3.11.0\",\n      \"insetPadding\": \"3.11.0\",\n      \"insetRadius\": \"3.11.0\",\n      \"spaced\": \"3.10.0\",\n      \"sliderTransition\": \"3.11.0\",\n      \"sliderTransitionDuration\": \"3.11.0\"\n    },\n    \"slots\": {\n      \"next\": \"3.11.0\",\n      \"prev\": \"3.11.0\"\n    }\n  },\n  \"VTextarea\": {\n    \"props\": {\n      \"maxHeight\": \"3.11.0\"\n    }\n  },\n  \"VTextField\": {\n    \"props\": {\n      \"autocomplete\": \"3.10.0\"\n    }\n  },\n  \"VTimePicker\": {\n    \"props\": {\n      \"density\": \"3.11.0\",\n      \"hideTitle\": \"3.10.0\",\n      \"period\": \"3.10.0\",\n      \"variant\": \"3.11.0\"\n    }\n  },\n  \"VTreeview\": {\n    \"props\": {\n      \"hideActions\": \"3.9.0\",\n      \"hideNoData\": \"3.10.0\",\n      \"noDataText\": \"3.10.0\",\n      \"separateRoots\": \"3.9.0\",\n      \"indentLines\": \"3.9.0\",\n      \"indentLinesColor\": \"3.12.0\",\n      \"indentLinesOpacity\": \"3.12.0\",\n      \"itemsRegistration\": \"3.11.0\"\n    },\n    \"slots\": {\n      \"header\": \"3.10.0\",\n      \"footer\": \"3.11.0\",\n      \"no-data\": \"3.11.0\",\n      \"toggle\": \"3.10.0\"\n    }\n  },\n  \"VTreeviewItem\": {\n    \"props\": {\n      \"hideActions\": \"3.9.0\",\n      \"indentLines\": \"3.9.0\"\n    },\n    \"slots\": {\n      \"toggle\": \"3.10.0\"\n    }\n  },\n  \"VToolbar\": {\n    \"props\": {\n      \"collapsePosition\": \"3.11.0\",\n      \"location\": \"3.12.0\"\n    }\n  },\n  \"VTooltip\": {\n    \"props\": {\n      \"eager\": \"3.2.0\",\n      \"interactive\": \"3.8.0\",\n      \"stickToTarget\": \"3.10.0\",\n      \"viewportMargin\": \"3.11.0\",\n      \"persistent\": \"3.11.3\"\n    }\n  },\n  \"VVirtualScroll\": {\n    \"props\": {\n      \"itemKey\": \"3.8.0\"\n    }\n  },\n  \"VWindow\": {\n    \"props\": {\n      \"crossfade\": \"3.10.0\",\n      \"transitionDuration\": \"3.10.0\"\n    }\n  }\n}\n"
  },
  {
    "path": "packages/docs/src/data/page-to-api.json",
    "content": "{\n  \"components/alerts\": [\"VAlert\", \"VAlertTitle\"],\n  \"components/app-bars\": [\n    \"VAppBar\",\n    \"VAppBarNavIcon\",\n    \"VAppBarTitle\"\n  ],\n  \"components/application\": [\n    \"VApp\",\n    \"VLayout\",\n    \"VLayoutItem\",\n    \"VMain\"\n  ],\n  \"components/aspect-ratios\": [\"VResponsive\"],\n  \"components/autocompletes\": [\"VAutocomplete\"],\n  \"components/avatars\": [\"VAvatar\"],\n  \"components/avatar-groups\": [\"VAvatarGroup\"],\n  \"components/badges\": [\"VBadge\"],\n  \"components/banners\": [\n    \"VBanner\",\n    \"VBannerActions\",\n    \"VBannerText\"\n  ],\n  \"components/bottom-navigation\": [\"VBottomNavigation\"],\n  \"components/bottom-sheets\": [\"VBottomSheet\"],\n  \"components/breadcrumbs\": [\n    \"VBreadcrumbs\",\n    \"VBreadcrumbsDivider\",\n    \"VBreadcrumbsItem\"\n  ],\n  \"components/button-groups\": [\n    \"VBtn\",\n    \"VBtnGroup\",\n    \"VBtnToggle\"\n  ],\n  \"components/buttons\": [\n    \"VBtn\",\n    \"VBtnGroup\",\n    \"VBtnToggle\"\n  ],\n  \"components/calendars\": [\n    \"VCalendar\",\n    \"VCalendarDay\",\n    \"VCalendarHeader\",\n    \"VCalendarInterval\",\n    \"VCalendarIntervalEvent\",\n    \"VCalendarMonthDay\"\n  ],\n  \"components/cards\": [\n    \"VCard\",\n    \"VCardActions\",\n    \"VCardItem\",\n    \"VCardSubtitle\",\n    \"VCardText\",\n    \"VCardTitle\"\n  ],\n  \"components/carousels\": [\"VCarousel\", \"VCarouselItem\"],\n  \"components/checkboxes\": [\"VCheckbox\", \"VCheckboxBtn\"],\n  \"components/chip-groups\": [\"VChip\", \"VChipGroup\"],\n  \"components/chips\": [\"VChip\", \"VChipGroup\"],\n  \"components/color-inputs\": [\"VColorInput\", \"VColorPicker\"],\n  \"components/color-pickers\": [\"VColorPicker\"],\n  \"components/combobox\": [\"VCombobox\"],\n  \"components/command-palettes\": [\"VCommandPalette\"],\n  \"components/confirm-edit\": [\"VConfirmEdit\"],\n  \"components/data-iterators\": [\"VDataIterator\"],\n  \"components/date-inputs\": [\"VDateInput\", \"VDatePicker\"],\n  \"components/date-pickers-month\": [\"VDatePicker\"],\n  \"components/date-pickers\": [\"VDatePicker\", \"VDateInput\"],\n  \"components/defaults-providers\": [\"VDefaultsProvider\"],\n  \"components/data-tables\": [\n    \"VDataTable\",\n    \"VDataTableFooter\",\n    \"VDataTableRow\",\n    \"VDataTableRows\",\n    \"VDataTableServer\",\n    \"VDataTableVirtual\"\n  ],\n  \"components/data-tables/server-side-tables\": [\n    \"VDataTableServer\"\n  ],\n  \"components/data-tables/virtual-tables\": [\n    \"VDataTableVirtual\"\n  ],\n  \"components/dialogs\": [\"VDialog\", \"VOverlay\"],\n  \"components/dividers\": [\"VDivider\"],\n  \"components/empty-states\": [\"VEmptyState\"],\n  \"components/expansion-panels\": [\n    \"VExpansionPanel\",\n    \"VExpansionPanels\",\n    \"VExpansionPanelText\",\n    \"VExpansionPanelTitle\"\n  ],\n  \"components/file-inputs\": [\"VFileInput\"],\n  \"components/file-upload\": [\"VFileUpload\"],\n  \"components/floating-action-buttons\": [\"VFab\"],\n  \"components/footers\": [\"VFooter\"],\n  \"components/forms\": [\"VForm\"],\n  \"components/grids\": [\"VCol\", \"VContainer\", \"VRow\", \"VSpacer\"],\n  \"components/hotkeys\": [\"VHotkey\"],\n  \"components/hover\": [\"VHover\"],\n  \"components/icon-buttons\": [\"VIconBtn\"],\n  \"components/icons\": [\"VIcon\"],\n  \"components/images\": [\"VImg\"],\n  \"components/infinite-scroller\": [\"VInfiniteScroll\"],\n  \"components/inputs\": [\"VInput\"],\n  \"components/item-groups\": [\"VItem\", \"VItemGroup\"],\n  \"components/lazy\": [\"VLazy\"],\n  \"components/lists\": [\n    \"VList\",\n    \"VListGroup\",\n    \"VListItem\",\n    \"VListItemAction\",\n    \"VListItemMedia\",\n    \"VListItemSubtitle\",\n    \"VListItemTitle\",\n    \"VListSubheader\",\n    \"VListImg\"\n  ],\n  \"components/locale-providers\": [\"VLocaleProvider\"],\n  \"components/mask-inputs\": [\"VMaskInput\"],\n  \"components/menus\": [\"VMenu\"],\n  \"components/navigation-drawers\": [\"VNavigationDrawer\"],\n  \"components/no-ssr\": [\"VNoSsr\"],\n  \"components/number-inputs\": [\"VNumberInput\"],\n  \"components/otp-input\": [\"VOtpInput\"],\n  \"components/overflow-btns\": [\"VOverflowBtn\"],\n  \"components/overlays\": [\"VOverlay\"],\n  \"components/paginations\": [\"VPagination\"],\n  \"components/parallax\": [\"VParallax\"],\n  \"components/pie-charts\": [\"VPie\", \"VPieSegment\", \"VPieTooltip\"],\n  \"components/progress\": [\"VProgress\"],\n  \"components/progress-circular\": [\"VProgressCircular\"],\n  \"components/progress-linear\": [\"VProgressLinear\"],\n  \"components/pull-to-refresh\": [\"VPullToRefresh\"],\n  \"components/radio-buttons\": [\"VRadio\", \"VRadioGroup\"],\n  \"components/range-sliders\": [\"VRangeSlider\", \"VSlider\"],\n  \"components/ratings\": [\"VRating\"],\n  \"components/selects\": [\"VSelect\"],\n  \"components/sheets\": [\"VSheet\"],\n  \"components/skeleton-loaders\": [\"VSkeletonLoader\"],\n  \"components/slide-groups\": [\"VSlideGroup\", \"VSlideGroupItem\"],\n  \"components/sliders\": [\"VRangeSlider\", \"VSlider\"],\n  \"components/snackbar-queue\": [\"VSnackbarQueue\", \"VSnackbar\"],\n  \"components/snackbars\": [\"VSnackbar\"],\n  \"components/sparklines\": [\"VSparkline\"],\n  \"components/speed-dials\": [\"VSpeedDial\"],\n  \"components/steppers\": [\n    \"VStepper\",\n    \"VStepperHeader\",\n    \"VStepperItem\",\n    \"VStepperWindow\",\n    \"VStepperWindowItem\"\n  ],\n  \"components/switches\": [\"VSwitch\"],\n  \"components/system-bars\": [\"VSystemBar\"],\n  \"components/tables\": [\"VTable\"],\n  \"components/tabs\": [\"VTabs\", \"VTab\"],\n  \"components/text-fields\": [\"VTextField\"],\n  \"components/textareas\": [\"VTextarea\"],\n  \"components/theme-providers\": [\"VThemeProvider\"],\n  \"components/time-pickers\": [\"VTimePicker\"],\n  \"components/timelines\": [\"VTimeline\", \"VTimelineItem\"],\n  \"components/toolbars\": [\"VToolbar\", \"VToolbarItems\", \"VToolbarTitle\"],\n  \"components/tooltips\": [\"VTooltip\"],\n  \"components/treeview\": [\n    \"VTreeview\",\n    \"VTreeviewItem\",\n    \"VTreeviewChildren\",\n    \"VTreeviewGroup\"\n  ],\n  \"components/vertical-steppers\": [\"VStepperVertical\", \"VStepperVerticalActions\", \"VStepperVerticalItem\"],\n  \"components/videos\": [\"VVideo\", \"VVideoControls\", \"VVideoVolume\"],\n  \"components/virtual-scroller\": [\"VVirtualScroll\"],\n  \"components/windows\": [\"VWindow\", \"VWindowItem\"],\n  \"directives/click-outside\": [\"v-click-outside\"],\n  \"directives/intersect\": [\"v-intersect\"],\n  \"directives/mutate\": [\"v-mutate\"],\n  \"directives/resize\": [\"v-resize\"],\n  \"directives/ripple\": [\"v-ripple\"],\n  \"directives/scroll\": [\"v-scroll\"],\n  \"directives/touch\": [\"v-touch\"],\n  \"directives/tooltip\": [\"v-tooltip\"],\n  \"features/dates\": [\"useDate\"],\n  \"features/display-and-platform\": [\"useDisplay\"],\n  \"features/hotkey\": [\"useHotkey\"],\n  \"features/scrolling\": [\"useGoTo\"],\n  \"features/global-configuration\": [\"VDefaultsProvider\"],\n  \"features/internationalization\": [\"useLocale\", \"VLocaleProvider\"],\n  \"features/theme\": [\"useTheme\", \"VThemeProvider\"],\n  \"styles/transitions\": [\n    \"VDialogBottomTransition\",\n    \"VDialogTopTransition\",\n    \"VDialogTransition\",\n    \"VExpandTransition\",\n    \"VExpandXTransition\",\n    \"VFabTransition\",\n    \"VFadeTransition\",\n    \"VScaleTransition\",\n    \"VScrollXTransition\",\n    \"VScrollXReverseTransition\",\n    \"VScrollYTransition\",\n    \"VScrollYReverseTransition\",\n    \"VSlideXTransition\",\n    \"VSlideXReverseTransition\",\n    \"VSlideYTransition\",\n    \"VSlideYReverseTransition\"\n  ]\n}\n"
  },
  {
    "path": "packages/docs/src/data/team.json",
    "content": "{\n  \"johnleider\": {\n    \"discord\": \"johnleider\",\n    \"focus\": [\n      \"[vuetifyjs/*](https://github.com/vuetifyjs)\"\n    ],\n    \"funding\": [\n      \"[GitHub Sponsors](https://github.com/sponsors/johnleider)\",\n      \"[Paypal](https://paypal.me/vuetify)\"\n    ],\n    \"languages\": [\n      \"English\"\n    ],\n    \"linkedin\": \"john-leider-626183a2\",\n    \"location\": \"Keller, TX, USA\",\n    \"name\": \"John Leider\",\n    \"team\": \"company\",\n    \"twitter\": \"zeroskillz\",\n    \"work\": \"Engineer @ Vuetify\",\n    \"joined\": \"Jun 2016\"\n  },\n  \"heatherleider\": {\n    \"discord\": \"heatherleider\",\n    \"focus\": [\n      \"[vuetifyjs/*](https://github.com/vuetifyjs)\"\n    ],\n    \"languages\": [\n      \"English\"\n    ],\n    \"location\": \"Keller, TX, USA\",\n    \"name\": \"Heather Leider\",\n    \"team\": \"company\",\n    \"twitter\": \"grneyedgrl01\",\n    \"work\": \"COO @ Vuetify\",\n    \"joined\": \"Nov 2019\"\n  },\n  \"KaelWD\": {\n    \"discord\": \"kaelwd\",\n    \"focus\": [\n      \"[vuetifyjs/*](https://github.com/vuetifyjs)\",\n      \"[vuetify-loader](https://github.com/vuetifyjs/vuetify-loader)\",\n      \"[eslint-plugin-vuetify](https://github.com/vuetifyjs/eslint-plugin-vuetify)\"\n    ],\n    \"funding\": [\n      \"[GitHub Sponsors](https://github.com/sponsors/kaelwd)\",\n      \"[Patreon](https://patreon.com/kaelwd)\",\n      \"[Open Collective](https://opencollective.com/vuetify)\"\n    ],\n    \"languages\": [\n      \"English\"\n    ],\n    \"location\": \"Melbourne, Australia\",\n    \"name\": \"Kael Watts-Deuchar\",\n    \"team\": \"core\",\n    \"joined\": \"Oct 2017\"\n  },\n  \"nekosaur\": {\n    \"discord\": \".nekosaur\",\n    \"languages\": [\n      \"Swedish\",\n      \"English\"\n    ],\n    \"location\": \"Malmö, Sweden\",\n    \"name\": \"Albert Kaaman\",\n    \"team\": \"legends\",\n    \"joined\": \"Jun 2017\"\n  },\n  \"MajesticPotatoe\": {\n    \"discord\": \"majesticpotatoe\",\n    \"focus\": [\n      \"[vuetifyjs](https://github.com/vuetifyjs)\",\n      \"[vuetifyjs/docs](https://github.com/vuetifyjs/vuetify/tree/master/packages/docs)\"\n    ],\n    \"funding\": [\n      \"[GitHub Sponsors](https://github.com/sponsors/majesticpotatoe)\",\n      \"[Open Collective](https://opencollective.com/vuetify)\"\n    ],\n    \"languages\": [\n      \"English\"\n    ],\n    \"linkedin\": \"andrew-henry-01049830\",\n    \"location\": \"Rochester, NY, USA\",\n    \"name\": \"Andrew Henry\",\n    \"team\": \"core\",\n    \"twitter\": \"SeeMWhyK\",\n    \"joined\": \"Dec 2018\"\n  },\n  \"blalan05\": {\n    \"discord\": \"blalan05\",\n    \"focus\": [\n      \"[vuetifyjs](https://github.com/vuetifyjs)\"\n    ],\n    \"languages\": [\n      \"English\"\n    ],\n    \"linkedin\": \"blalan05\",\n    \"location\": \"Wisconsin, USA\",\n    \"name\": \"Blaine Landowski\",\n    \"team\": \"core\",\n    \"work\": \"CEO at Foundational Technologies LLC\",\n    \"joined\": \"Feb 2021\"\n  },\n  \"userquin\": {\n    \"discord\": \"userquin\",\n    \"focus\": [\n      \"[vuetifyjs/create](https://github.com/vuetifyjs/create)\",\n      \"[Nuxt](https://github.com/userquin/vuetify-nuxt-module)\"\n    ],\n    \"languages\": [\n      \"Spanish\",\n      \"English\"\n    ],\n    \"location\": \"Madrid, Spain\",\n    \"name\": \"Joaquín Sánchez\",\n    \"twitter\": \"userquin\",\n    \"team\": \"core\",\n    \"joined\": \"Mar 2024\"\n  },\n  \"MatthewAry\": {\n    \"discord\": \"bitshift_\",\n    \"focus\": [\n      \"[vuetifyjs/*](https://github.com/vuetifyjs)\"\n    ],\n    \"languages\": [\n      \"English\"\n    ],\n    \"location\": \"Spokane, WA, USA\",\n    \"name\": \"Matthew Ary\",\n    \"twitter\": \"MatthewAry\",\n    \"linkedin\": \"matthewary\",\n    \"work\": \"Director of Product Development at Symplsoft Inc.\",\n    \"team\": \"core\",\n    \"joined\": \"May 2024\"\n  },\n  \"J-Sek\": {\n    \"avatar\": \"https://cdn.vuetifyjs.com/docs/images/team/j-sek.png\",\n    \"discord\": \"jacek#1420\",\n    \"focus\": [\n      \"[vuetifyjs/vuetify](https://github.com/vuetifyjs/vuetify)\"\n    ],\n    \"languages\": [\n      \"Polish\",\n      \"English\"\n    ],\n    \"location\": \"Gdańsk, Poland\",\n    \"name\": \"Jacek Czarniecki\",\n    \"team\": \"core\",\n    \"joined\": \"Nov 2024\"\n  },\n  \"Spatlani\": {\n    \"name\": \"Shubham Patlani\",\n    \"team\": \"core\",\n    \"discord\": \"spatlani\",\n    \"focus\": [\"[vuetifyjs/*](https://github.com/vuetifyjs)\"],\n    \"languages\": [\"English\", \"Hindi\", \"Punjabi\"],\n    \"linkedin\": \"spatlani\",\n    \"github\": \"spatlani\",\n    \"avatar\": \"https://avatars.githubusercontent.com/u/11574195\",\n    \"location\": \"Delhi, India\",\n    \"joined\": \"March 2025\"\n  },\n  \"Haviles04\": {\n    \"name\": \"Henry Aviles\",\n    \"team\": \"core\",\n    \"discord\": \"hankthetank4\",\n    \"linkedin\": \"henry-aviles\",\n    \"focus\": [\"[One](https://github.com/vuetifyjs/one)\"],\n    \"languages\": [\"English\"],\n    \"joined\": \"March 2025\",\n    \"location\": \"Huntington, NY, USA\"\n  },\n  \"ikushum\": {\n    \"name\": \"Ishan Subedi\",\n    \"team\": \"core\",\n    \"focus\": [\n      \"[vuetifyjs/*](https://github.com/vuetifyjs)\"\n    ],\n    \"languages\": [\n      \"Nepali\",\n      \"English\"\n    ],\n    \"discord\": \"ikushum\",\n    \"linkedin\": \"ikushum\",\n    \"joined\": \"March 2025\",\n    \"location\": \"Kathmandu, Nepal\",\n    \"avatar\": \"https://avatars.githubusercontent.com/u/17315781\"\n  },\n  \"AndreyYolkin\": {\n    \"name\": \"Andrei Elkin\",\n    \"team\": \"core\",\n    \"discord\": \"yol_kin\",\n    \"focus\": [\n      \"[vuetifyjs/create](https://github.com/vuetifyjs/create)\",\n      \"[vuetify-loader](https://github.com/vuetifyjs/vuetify-loader)\",\n      \"[Nuxt](https://github.com/vuetifyjs/nuxt-module)\"\n    ],\n    \"languages\": [\n      \"Polish\",\n      \"English\",\n      \"Russian\"\n    ],\n    \"location\": \"Kraków, Poland\",\n    \"linkedin\": \"yolkin\",\n    \"joined\": \"March 2025\"\n  },\n  \"jcjp\": {\n    \"name\": \"JC Puno\",\n    \"team\": \"core\",\n    \"discord\": \"psi#8085\",\n    \"focus\": [\n      \"[vuetifyjs](https://github.com/vuetifyjs)\",\n      \"[Nuxt](https://github.com/userquin/vuetify-nuxt-module)\"\n    ],\n    \"languages\": [\n      \"Tagalog / Filipino\",\n      \"English\"\n    ],\n    \"location\": \"Manila, Philipines\",\n    \"joined\": \"March 2025\"\n  },\n  \"oumoussa98\": {\n    \"name\": \"Abdelouahed Oumoussa\",\n    \"team\": \"core\",\n    \"discord\": \"oumoussa\",\n    \"twitter\": \"oumoussa_\",\n    \"github\": \"oumoussa98\",\n    \"linkedin\": \"aoumoussa\",\n    \"avatar\": \"https://gravatar.com/avatar/7d1a8ba680ab9d49bd9cdaeff05d0e76\",\n    \"focus\": [\n      \"[vuetifyjs/*](https://github.com/vuetifyjs)\"\n    ],\n    \"languages\": [\n      \"Arabic\",\n      \"English\"\n    ],\n    \"joined\": \"March 2025\",\n    \"location\": \"Casablanca, Morocco\"\n  },\n  \"yuwu9145\": {\n    \"discord\": \"yuwu9145\",\n    \"focus\": [\n      \"[vuetifyjs](https://github.com/vuetifyjs)\"\n    ],\n    \"languages\": [\n      \"English\",\n      \"Chinese(Mandarin)\"\n    ],\n    \"location\": \"Melbourne, Australia\",\n    \"name\": \"Yuchao Wu\",\n    \"team\": \"legends\",\n    \"joined\": \"Mar 2023\"\n  },\n  \"kieuminhcanh\": {\n    \"discord\": \"kieuminhcanh\",\n    \"focus\": [\n      \"[vuetifyjs/studio](https://github.com/vuetifyjs/studio)\"\n    ],\n    \"funding\": [\n      \"[GitHub Sponsors](https://github.com/sponsors/kieuminhcanh)\",\n      \"[Patreon](https://patreon.com/kieuminhcanh)\",\n      \"[Open Collective](https://opencollective.com/vuetify)\"\n    ],\n    \"languages\": [\n      \"English\",\n      \"Vietnamese\"\n    ],\n    \"location\": \"California, US\",\n    \"name\": \"Ken Kieu\",\n    \"team\": \"legends\",\n    \"twitter\": \"kieuminhcanh\",\n    \"joined\": \"April 2024\"\n  },\n  \"jacekkarczmarczyk\": {\n    \"discord\": \"jacek#3542\",\n    \"languages\": [\n      \"Polish\",\n      \"English\"\n    ],\n    \"location\": \"Warsaw, Poland\",\n    \"name\": \"Jacek Karczmarczyk\",\n    \"team\": \"legends\"\n  },\n  \"chewy94\": {\n    \"avatar\": \"https://cdn.vuetifyjs.com/docs/images/team/chewy94.jpg\",\n    \"discord\": \"Sean Kimball#0001\",\n    \"languages\": [\n      \"English\"\n    ],\n    \"linkedin\": \"sean-kimball-b50922126\",\n    \"location\": \"Goodyear, Arizona, USA\",\n    \"name\": \"Sean Kimball\",\n    \"team\": \"legends\"\n  },\n  \"bdeo\": {\n    \"avatar\": \"https://cdn.vuetifyjs.com/docs/images/team/bdeo.jpg\",\n    \"discord\": \"brandondeo#0001\",\n    \"languages\": [\n      \"English\"\n    ],\n    \"linkedin\": \"brandondeo\",\n    \"location\": \"Philadelphia, PA, USA\",\n    \"name\": \"Brandon Deo\",\n    \"team\": \"legends\"\n  },\n  \"ElijahKotyluk\": {\n    \"avatar\": \"https://cdn.vuetifyjs.com/docs/images/team/ElijahKotyluk.jpg\",\n    \"discord\": \"edk#4363\",\n    \"languages\": [\n      \"English\"\n    ],\n    \"location\": \"USA\",\n    \"name\": \"Elijah Kotyluk\",\n    \"team\": \"legends\"\n  },\n  \"santiagoaloi\": {\n    \"avatar\": \"https://cdn.vuetifyjs.com/docs/images/team/santiagoaloi.jpg\",\n    \"discord\": \"lannnister\",\n    \"languages\": [\n      \"Swedish\",\n      \"English\",\n      \"Spanish\"\n    ],\n    \"linkedin\": \"santiagoaloi\",\n    \"location\": \"Stockholm, Sweden\",\n    \"name\": \"Santiago Aloi\",\n    \"team\": \"legends\",\n    \"joined\": \"Feb 2023\"\n  },\n  \"yooneskh\": {\n    \"avatar\": \"https://cdn.vuetifyjs.com/docs/images/team/yooneskh.png\",\n    \"discord\": \"YoonesKh#7826\",\n    \"languages\": [\n      \"English\",\n      \"Persian\"\n    ],\n    \"twitter\": \"yooneskh\",\n    \"linkedin\": \"yooneskh \",\n    \"location\": \"Iran\",\n    \"name\": \"Yoones Khoshghadam\",\n    \"team\": \"legends\",\n    \"joined\": \"January 2023\"\n  },\n  \"elvinagarcia\": {\n    \"avatar\": \"https://cdn.vuetifyjs.com/docs/images/team/elvinagarcia.png\",\n    \"discord\": \"elvinagarcia\",\n    \"focus\": [\n      \"Design/Animations\"\n    ],\n    \"languages\": [\n      \"English\"\n    ],\n    \"location\": \"Virginia, USA\",\n    \"name\": \"Elvina Garcia\",\n    \"team\": \"legends\",\n    \"joined\": \"Feb 2023\"\n  }\n}\n"
  },
  {
    "path": "packages/docs/src/examples/accessibility/list-item-group.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"500\"\n  >\n    <v-list v-model=\"model\">\n      <v-list-item\n        v-for=\"(item, i) in items\"\n        :key=\"i\"\n        :disabled=\"item.disabled\"\n        :title=\"item.text\"\n        :value=\"item\"\n      ></v-list-item>\n    </v-list>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const items = [\n    {\n      text: 'Item 1',\n      disabled: false,\n    },\n    {\n      text: 'Item 2',\n      disabled: true,\n    },\n    {\n      text: 'Item 3',\n      disabled: false,\n    },\n  ]\n\n  const model = ref(0)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        {\n          text: 'Item 1',\n          disabled: false,\n        },\n        {\n          text: 'Item 2',\n          disabled: true,\n        },\n        {\n          text: 'Item 3',\n          disabled: false,\n        },\n      ],\n      model: 0,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/accessibility/menu.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-menu>\n      <template v-slot:activator=\"{ props: activatorProps }\">\n        <v-btn text=\"Click me\" v-bind=\"activatorProps\"></v-btn>\n      </template>\n\n      <v-list>\n        <v-list-item @click=\"onClick\">\n          <v-list-item-title>Option 1</v-list-item-title>\n        </v-list-item>\n\n        <v-list-item disabled>\n          <v-list-item-title>Option 2</v-list-item-title>\n        </v-list-item>\n\n        <v-list-item @click=\"onClick\">\n          <v-list-item-title>Option 3</v-list-item-title>\n        </v-list-item>\n      </v-list>\n    </v-menu>\n  </div>\n</template>\n\n<script setup>\n  function onClick () {\n    // Perform an action\n  }\n</script>\n\n<script>\n  export default {\n    methods: {\n      onClick () {\n        // Perform an action\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/accessibility/select-list-item.vue",
    "content": "<template>\n  <v-select\n    :items=\"['Foo', 'Bar', 'Fizz', 'Buzz']\"\n    label=\"Fizzbuzz\"\n  >\n    <template v-slot:item=\"{ item, props }\">\n      <v-list-item v-bind=\"props\">\n        <template v-slot:title>\n          {{ item }}\n        </template>\n      </v-list-item>\n    </template>\n  </v-select>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/application/app-bar-drawer.vue",
    "content": "<template>\n  <v-responsive class=\"border rounded\" max-height=\"300\">\n    <v-app>\n      <v-app-bar title=\"App bar\"></v-app-bar>\n\n      <v-navigation-drawer>\n        <v-list>\n          <v-list-item title=\"Navigation drawer\"></v-list-item>\n        </v-list>\n      </v-navigation-drawer>\n\n      <v-main>\n        <v-container>\n          <h1 class=\"my-0\">Main Content</h1>\n        </v-container>\n      </v-main>\n    </v-app>\n  </v-responsive>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/application/drawer-app-bar.vue",
    "content": "<template>\n  <v-responsive class=\"border rounded\" max-height=\"300\">\n    <v-app>\n      <v-navigation-drawer>\n        <v-list>\n          <v-list-item title=\"Navigation drawer\"></v-list-item>\n        </v-list>\n      </v-navigation-drawer>\n\n      <v-app-bar title=\"App bar\"></v-app-bar>\n\n      <v-main>\n        <v-container>\n          <h1 class=\"my-0\">Main Content</h1>\n        </v-container>\n      </v-main>\n    </v-app>\n  </v-responsive>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/application/theme.vue",
    "content": "<template>\n  <v-responsive class=\"border rounded\" max-height=\"300\">\n    <v-app :theme=\"theme\">\n      <v-app-bar class=\"px-3\">\n        <v-spacer></v-spacer>\n\n        <v-btn\n          :prepend-icon=\"theme === 'light' ? 'mdi-weather-sunny' : 'mdi-weather-night'\"\n          text=\"Toggle Theme\"\n          slim\n          @click=\"onClick\"\n        ></v-btn>\n      </v-app-bar>\n\n      <v-main>\n        <v-container>\n          <h1 class=\"my-0\">Main Content</h1>\n        </v-container>\n      </v-main>\n    </v-app>\n  </v-responsive>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const theme = ref('light')\n\n  function onClick () {\n    theme.value = theme.value === 'light' ? 'dark' : 'light'\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/application-layout/app-bar-first.vue",
    "content": "<template>\n  <v-layout class=\"rounded rounded-md border\">\n    <v-app-bar title=\"Application bar\"></v-app-bar>\n\n    <v-navigation-drawer>\n      <v-list nav>\n        <v-list-item title=\"Navigation drawer\" link></v-list-item>\n      </v-list>\n    </v-navigation-drawer>\n\n    <v-main class=\"d-flex align-center justify-center\" height=\"300\">\n      <v-container>\n        <v-sheet\n          border=\"dashed md\"\n          color=\"surface-light\"\n          height=\"200\"\n          rounded=\"lg\"\n          width=\"100%\"\n        ></v-sheet>\n      </v-container>\n    </v-main>\n  </v-layout>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/application-layout/discord.vue",
    "content": "<template>\n  <v-layout class=\"rounded rounded-md\">\n    <v-system-bar color=\"grey-darken-3\"></v-system-bar>\n\n    <v-navigation-drawer\n      color=\"grey-darken-2\"\n      width=\"72\"\n      permanent\n    ></v-navigation-drawer>\n\n    <v-navigation-drawer\n      color=\"grey-darken-1\"\n      width=\"150\"\n      permanent\n    ></v-navigation-drawer>\n\n    <v-app-bar\n      color=\"grey\"\n      height=\"48\"\n      flat\n    ></v-app-bar>\n\n    <v-navigation-drawer\n      color=\"grey-lighten-1\"\n      location=\"right\"\n      width=\"150\"\n      permanent\n    ></v-navigation-drawer>\n\n    <v-app-bar\n      color=\"grey-lighten-2\"\n      height=\"48\"\n      location=\"bottom\"\n      flat\n    ></v-app-bar>\n\n    <v-main class=\"d-flex align-center justify-center\" height=\"300\">\n      <v-container>\n        <v-sheet\n          border=\"dashed md\"\n          color=\"surface-light\"\n          height=\"150\"\n          rounded=\"lg\"\n          width=\"100%\"\n        ></v-sheet>\n      </v-container>\n    </v-main>\n  </v-layout>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/application-layout/dynamic.vue",
    "content": "<template>\n  <v-layout class=\"rounded rounded-md border\">\n    <v-navigation-drawer color=\"surface-variant\" permanent></v-navigation-drawer>\n\n    <v-app-bar\n      :order=\"order\"\n      color=\"grey-lighten-2\"\n      title=\"Application bar\"\n      flat\n    >\n      <template v-slot:append>\n        <v-switch\n          v-model=\"order\"\n          class=\"me-2\"\n          false-value=\"0\"\n          label=\"Toggle order\"\n          true-value=\"-1\"\n          hide-details\n          inset\n        ></v-switch>\n      </template>\n    </v-app-bar>\n\n    <v-main class=\"d-flex align-center justify-center\" height=\"300\">\n      <v-container>\n        <v-sheet\n          border=\"dashed md\"\n          color=\"surface-light\"\n          height=\"200\"\n          rounded=\"lg\"\n          width=\"100%\"\n        ></v-sheet>\n      </v-container>\n    </v-main>\n  </v-layout>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const order = shallowRef(0)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      order: 0,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/application-layout/layout-information-composable.vue",
    "content": "<template>\n  <v-layout ref=\"app\" class=\"rounded rounded-md border\">\n    <v-app-bar color=\"surface-variant\" name=\"app-bar\">\n      <child v-slot=\"{ print }\">\n        <v-btn class=\"mx-auto\" @click=\"print('app-bar')\">Get data</v-btn>\n      </child>\n    </v-app-bar>\n\n    <v-navigation-drawer\n      color=\"surface-light\"\n      name=\"drawer\"\n      permanent\n    >\n      <div class=\"d-flex justify-center align-center h-100\">\n        <child v-slot=\"{ print }\">\n          <v-btn variant=\"text\" @click=\"print('drawer')\">Get data</v-btn>\n        </child>\n      </div>\n    </v-navigation-drawer>\n\n    <v-main class=\"d-flex align-center justify-center\" height=\"300\">\n      <v-container>\n        <v-sheet\n          border=\"dashed md\"\n          color=\"surface-light\"\n          height=\"150\"\n          rounded=\"lg\"\n          width=\"100%\"\n        ></v-sheet>\n      </v-container>\n    </v-main>\n\n    <v-footer color=\"surface-light\" name=\"footer\" app>\n      <child v-slot=\"{ print }\">\n        <v-btn\n          class=\"mx-auto\"\n          text=\"Get data\"\n          variant=\"text\"\n          @click=\"print('footer')\"\n        ></v-btn>\n      </child>\n    </v-footer>\n  </v-layout>\n</template>\n\n<script setup>\n  import { useLayout } from 'vuetify'\n\n  const Child = {\n    setup (props, ctx) {\n      const { getLayoutItem } = useLayout()\n\n      function print (key) {\n        alert(JSON.stringify(getLayoutItem(key), null, 2))\n      }\n\n      return () => ctx.slots.default({ print })\n    },\n  }\n</script>\n\n<script>\n  import { useLayout } from 'vuetify'\n\n  const Child = {\n    setup (props, ctx) {\n      const { getLayoutItem } = useLayout()\n\n      function print (key) {\n        alert(JSON.stringify(getLayoutItem(key), null, 2))\n      }\n\n      return () => ctx.slots.default({ print })\n    },\n  }\n\n  export default {\n    components: { Child },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/application-layout/layout-information-ref.vue",
    "content": "<template>\n  <v-layout ref=\"app\" class=\"rounded rounded-md border\">\n    <v-app-bar color=\"surface-light\" name=\"app-bar\">\n      <v-btn class=\"mx-auto\" @click=\"print('app-bar')\">Get data</v-btn>\n    </v-app-bar>\n\n    <v-navigation-drawer\n      color=\"surface-variant\"\n      location=\"end\"\n      name=\"drawer\"\n      permanent\n    >\n      <div class=\"d-flex justify-center align-center h-100\">\n        <v-btn variant=\"text\" @click=\"print('drawer')\">Get data</v-btn>\n      </div>\n    </v-navigation-drawer>\n\n    <v-main class=\"d-flex align-center justify-center\" height=\"300\">\n      <v-container>\n        <v-sheet\n          border=\"dashed md\"\n          color=\"surface-light\"\n          height=\"150\"\n          rounded=\"lg\"\n          width=\"100%\"\n        ></v-sheet>\n      </v-container>\n    </v-main>\n\n    <v-footer color=\"surface-light\" name=\"footer\" app>\n      <v-btn\n        class=\"mx-auto\"\n        text=\"Get data\"\n        variant=\"text\"\n        @click=\"print('footer')\"\n      ></v-btn>\n    </v-footer>\n  </v-layout>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const app = ref()\n\n  function print (key) {\n    alert(JSON.stringify(app.value.getLayoutItem(key), null, 2))\n  }\n</script>\n\n<script>\n  export default {\n    methods: {\n      print (key) {\n        alert(JSON.stringify(this.$refs.app.getLayoutItem(key), null, 2))\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/application-layout/location.vue",
    "content": "<template>\n  <v-layout class=\"rounded rounded-md border\">\n    <v-app-bar color=\"surface-variant\" title=\"Application bar\"></v-app-bar>\n\n    <v-navigation-drawer>\n      <v-list nav>\n        <v-list-item title=\"Drawer left\" link></v-list-item>\n      </v-list>\n    </v-navigation-drawer>\n\n    <v-navigation-drawer location=\"right\">\n      <v-list nav>\n        <v-list-item title=\"Drawer right\" link></v-list-item>\n      </v-list>\n    </v-navigation-drawer>\n\n    <v-main class=\"d-flex align-center justify-center\" height=\"300\">\n      <v-container>\n        <v-sheet\n          border=\"dashed md\"\n          color=\"surface-light\"\n          height=\"200\"\n          rounded=\"lg\"\n          width=\"100%\"\n        ></v-sheet>\n      </v-container>\n    </v-main>\n  </v-layout>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/application-layout/nav-drawer-first.vue",
    "content": "<template>\n  <v-layout class=\"rounded rounded-md border\">\n    <v-navigation-drawer>\n      <v-list nav>\n        <v-list-item title=\"Navigation drawer\" link></v-list-item>\n      </v-list>\n    </v-navigation-drawer>\n\n    <v-app-bar title=\"Application bar\"></v-app-bar>\n\n    <v-main class=\"d-flex align-center justify-center\" height=\"300\">\n      <v-container>\n        <v-sheet\n          border=\"dashed md\"\n          color=\"surface-light\"\n          height=\"200\"\n          rounded=\"lg\"\n          width=\"100%\"\n        ></v-sheet>\n      </v-container>\n    </v-main>\n  </v-layout>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/blueprints/md1.vue",
    "content": "<template>\n  <div>\n    <v-defaults-provider :defaults=\"md1.defaults\">\n      <div class=\"d-flex align-center\">\n        <v-btn :color=\"color\" class=\"me-6 text-white\">Button</v-btn>\n\n        <v-tabs :color=\"color\">\n          <v-tab>Tab One</v-tab>\n          <v-tab>Tab Two</v-tab>\n          <v-tab>Tab Three</v-tab>\n        </v-tabs>\n      </div>\n\n      <br>\n\n      <v-banner\n        :color=\"color\"\n        text=\"Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!\"\n      >\n        <template v-slot:prepend>\n          <!-- rounded added due to bug -->\n          <v-avatar\n            class=\"text-white\"\n            icon=\"$vuetify\"\n            rounded=\"circle\"\n          ></v-avatar>\n        </template>\n      </v-banner>\n\n      <br>\n\n      <v-text-field\n        :color=\"color\"\n        label=\"Text field\"\n        model-value=\"Material Design 1\"\n      ></v-text-field>\n    </v-defaults-provider>\n  </div>\n</template>\n\n<script setup>\n  import { md1 } from 'vuetify/blueprints'\n\n  const color = md1.theme.themes.light.colors.primary\n</script>\n\n<style scoped>\n.v-btn {\n  /* for demo, normally handled by global typography */\n  letter-spacing: normal;\n}\n</style>\n"
  },
  {
    "path": "packages/docs/src/examples/blueprints/md2.vue",
    "content": "<template>\n  <div>\n    <v-defaults-provider :defaults=\"md2.defaults\">\n      <div class=\"d-flex align-center\">\n        <v-btn :color=\"color\" class=\"me-6 text-white\">Button</v-btn>\n\n        <v-tabs :color=\"color\">\n          <v-tab>Tab One</v-tab>\n          <v-tab>Tab Two</v-tab>\n          <v-tab>Tab Three</v-tab>\n        </v-tabs>\n      </div>\n\n      <br>\n\n      <v-banner\n        :color=\"color\"\n        text=\"Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!\"\n      >\n        <template v-slot:prepend>\n          <!-- rounded added due to bug -->\n          <v-avatar\n            class=\"text-white\"\n            icon=\"$vuetify\"\n            rounded=\"circle\"\n          ></v-avatar>\n        </template>\n      </v-banner>\n\n      <br>\n\n      <v-text-field\n        :color=\"color\"\n        label=\"Text field\"\n        model-value=\"Material Design 2\"\n      ></v-text-field>\n    </v-defaults-provider>\n  </div>\n</template>\n\n<script setup>\n  import { md2 } from 'vuetify/blueprints'\n\n  const color = md2.theme.themes.light.colors.primary\n</script>\n\n<style scoped>\n.v-btn {\n  /* for demo, normally handled by global typography */\n  letter-spacing: .0892857143em;\n}\n</style>\n"
  },
  {
    "path": "packages/docs/src/examples/blueprints/md3.vue",
    "content": "<template>\n  <div>\n    <v-defaults-provider :defaults=\"md3.defaults\">\n      <div class=\"d-flex align-center\">\n        <v-btn :color=\"color\" class=\"me-6 text-white\">Button</v-btn>\n\n        <v-tabs :color=\"color\">\n          <v-tab>Tab One</v-tab>\n          <v-tab>Tab Two</v-tab>\n          <v-tab>Tab Three</v-tab>\n        </v-tabs>\n      </div>\n\n      <br>\n\n      <v-banner\n        :color=\"color\"\n        text=\"Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!\"\n      >\n        <template v-slot:prepend>\n          <!-- rounded added due to bug -->\n          <v-avatar\n            class=\"text-white\"\n            icon=\"$vuetify\"\n            rounded=\"circle\"\n          ></v-avatar>\n        </template>\n      </v-banner>\n\n      <br>\n\n      <v-text-field\n        :color=\"color\"\n        label=\"Text field\"\n        model-value=\"Material Design 3\"\n      ></v-text-field>\n    </v-defaults-provider>\n  </div>\n</template>\n\n<script setup>\n  import { md3 } from 'vuetify/blueprints'\n\n  const color = md3.theme.themes.light.colors.primary\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/border/all.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"justify-space-around\">\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <div class=\"border-thin\" style=\"height: 64px; width: 64px;\"></div>\n          <div class=\"text-body-small\">border-thin</div>\n        </div>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <div class=\"border-sm\" style=\"height: 64px; width: 64px;\"></div>\n          <div class=\"text-body-small\">border-sm</div>\n        </div>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <div class=\"border-md\" style=\"height: 64px; width: 64px;\"></div>\n          <div class=\"text-body-small\">border-md</div>\n        </div>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <div class=\"border-lg\" style=\"height: 64px; width: 64px;\"></div>\n          <div class=\"text-body-small\">border-lg</div>\n        </div>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <div class=\"border-xl\" style=\"height: 64px; width: 64px;\"></div>\n          <div class=\"text-body-small\">border-xl</div>\n        </div>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/border/card.vue",
    "content": "<template>\n  <v-container>\n    <v-card\n      border=\"opacity-50 sm\"\n      class=\"mx-auto\"\n      max-width=\"360\"\n      rounded=\"xl\"\n      variant=\"text\"\n    >\n      <template v-slot:title>\n        <div class=\"text-body-small font-weight-bold\">Revenue</div>\n      </template>\n\n      <template v-slot:append>\n        <v-chip\n          border=\"success sm opacity-100\"\n          color=\"green\"\n          size=\"small\"\n          variant=\"text\"\n        >\n          <v-icon icon=\"mdi-arrow-up\" start></v-icon> 13%\n        </v-chip>\n      </template>\n\n      <template v-slot:text>\n        <div class=\"text-headline-large font-weight-black\">$ 9,232,215</div>\n\n        <small class=\"text-body-small text-medium-emphasis d-flex justify-space-between align-center\">\n          <div>\n            <span class=\"text-green\">\n              <v-avatar icon=\"mdi-arrow-up\" size=\"small\" variant=\"tonal\"></v-avatar>\n              + $ 3,295\n            </span>\n\n            in the last week\n          </div>\n\n          <v-btn\n            icon=\"mdi-arrow-right\"\n            size=\"x-small\"\n            variant=\"text\"\n            border\n          ></v-btn>\n        </small>\n      </template>\n    </v-card>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/border/colors.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"justify-space-around\">\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <v-sheet border=\"primary thin\" class=\"mx-auto\" height=\"64\" width=\"64\" rounded></v-sheet>\n          <div class=\"text-body-small\">\"primary thin\"</div>\n        </div>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <v-sheet border=\"success sm\" height=\"64\" width=\"64\" rounded></v-sheet>\n          <div class=\"text-body-small\">\"success sm\"</div>\n        </div>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <v-sheet border=\"info md\" height=\"64\" width=\"64\" rounded></v-sheet>\n          <div class=\"text-body-small\">\"info md\"</div>\n        </div>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <v-sheet border=\"warning lg\" height=\"64\" width=\"64\" rounded></v-sheet>\n          <div class=\"text-body-small\">\"warning lg\"</div>\n        </div>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <v-sheet border=\"error xl\" height=\"64\" width=\"64\" rounded></v-sheet>\n          <div class=\"text-body-small\">\"error xl\"</div>\n        </div>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/border/sides.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"justify-space-around\">\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <div class=\"border border-t-lg\" style=\"height: 64px; width: 64px;\"></div>\n          <div class=\"text-body-small\">border-t-lg</div>\n        </div>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <div class=\"border border-e-lg\" style=\"height: 64px; width: 64px;\"></div>\n          <div class=\"text-body-small\">border-e-lg</div>\n        </div>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <div class=\"border border-b-lg\" style=\"height: 64px; width: 64px;\"></div>\n          <div class=\"text-body-small\">border-b-lg</div>\n        </div>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <div class=\"border border-s-lg\" style=\"height: 64px; width: 64px;\"></div>\n          <div class=\"text-body-small\">border-s-lg</div>\n        </div>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/border/styles.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"justify-space-around\">\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <v-btn text=\"Button A\" variant=\"text\" border></v-btn>\n          <div class=\"text-body-small\">border</div>\n        </div>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <v-btn border=\"dashed thin\" text=\"Button A\" variant=\"text\"></v-btn>\n          <div class=\"text-body-small\">border-dashed</div>\n        </div>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <v-btn border=\"dotted thin\" text=\"Button A\" variant=\"text\"></v-btn>\n          <div class=\"text-body-small\">border-dotted</div>\n        </div>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <v-btn border=\"double lg\" text=\"Button A\" variant=\"text\"></v-btn>\n          <div class=\"text-body-small\">border-double</div>\n        </div>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/border-radius/misc-components.vue",
    "content": "<template>\n  <v-container class=\"text-center\">\n    <v-btn\n      color=\"primary\"\n      rounded=\"pill\"\n      text=\"Update Account\"\n      variant=\"flat\"\n    ></v-btn>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/border-radius/misc-pill-and-circle.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"justify-space-around\">\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <div class=\"bg-surface-variant rounded-pill mx-auto\" style=\"height: 64px; width: 164px;\"></div>\n          <div class=\"text-body-small\">rounded-pill</div>\n        </div>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <div class=\"bg-surface-variant rounded-circle mx-auto\" style=\"height: 64px; width: 64px;\"></div>\n          <div class=\"text-body-small\">rounded-circle</div>\n        </div>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/border-radius/misc-removing-border-radius.vue",
    "content": "<template>\n  <v-container class=\"text-center\">\n    <v-btn\n      color=\"primary\"\n      rounded=\"0\"\n      text=\"Update Account\"\n      variant=\"flat\"\n    ></v-btn>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/border-radius/misc-rounded-corners.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"justify-space-around\">\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <div class=\"bg-surface-variant rounded-sm mx-auto\" style=\"height: 64px; width: 64px;\"></div>\n          <div class=\"text-body-small\">rounded-sm</div>\n        </div>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <div class=\"bg-surface-variant rounded mx-auto\" style=\"height: 64px; width: 64px;\"></div>\n          <div class=\"text-body-small\">rounded</div>\n        </div>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <div class=\"bg-surface-variant rounded-md mx-auto\" style=\"height: 64px; width: 64px;\"></div>\n          <div class=\"text-body-small\">rounded-md</div>\n        </div>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <div class=\"bg-surface-variant rounded-lg mx-auto\" style=\"height: 64px; width: 64px;\"></div>\n          <div class=\"text-body-small\">rounded-lg</div>\n        </div>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <div class=\"bg-surface-variant rounded-xl mx-auto\" style=\"height: 64px; width: 64px;\"></div>\n          <div class=\"text-body-small\">rounded-xl</div>\n        </div>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/border-radius/misc-rounding-by-corner.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"justify-space-around\">\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <div class=\"bg-surface-variant rounded-ts-lg mx-auto\" style=\"height: 64px; width: 64px;\"></div>\n          <div class=\"text-body-small\">rounded-ts-lg</div>\n        </div>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <div class=\"bg-surface-variant rounded-te-lg mx-auto\" style=\"height: 64px; width: 64px;\"></div>\n          <div class=\"text-body-small\">rounded-te-lg</div>\n        </div>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <div class=\"bg-surface-variant rounded-be-lg mx-auto\" style=\"height: 64px; width: 64px;\"></div>\n          <div class=\"text-body-small\">rounded-be-lg</div>\n        </div>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <div class=\"bg-surface-variant rounded-bs-lg mx-auto\" style=\"height: 64px; width: 64px;\"></div>\n          <div class=\"text-body-small\">rounded-bs-lg</div>\n        </div>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/border-radius/misc-rounding-by-side.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"justify-space-around\">\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <div class=\"bg-surface-variant rounded-t-lg mx-auto\" style=\"height: 64px; width: 64px;\"></div>\n          <div class=\"text-body-small\">rounded-t-lg</div>\n        </div>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <div class=\"bg-surface-variant rounded-e-lg mx-auto\" style=\"height: 64px; width: 64px;\"></div>\n          <div class=\"text-body-small\">rounded-e-lg</div>\n        </div>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <div class=\"bg-surface-variant rounded-b-lg mx-auto\" style=\"height: 64px; width: 64px;\"></div>\n          <div class=\"text-body-small\">rounded-b-lg</div>\n        </div>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <div class=\"bg-surface-variant rounded-s-lg mx-auto\" style=\"height: 64px; width: 64px;\"></div>\n          <div class=\"text-body-small\">rounded-s-lg</div>\n        </div>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/color/classes.vue",
    "content": "<template>\n  <div class=\"bg-purple-darken-2 text-center\">\n    <span>Lorem ipsum</span>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/color/text-classes.vue",
    "content": "<template>\n  <div>\n    Lorem ipsum dolor sit amet, <strong class=\"text-red-lighten-1\">inciderint</strong> definitionem est ea, explicari prodesset eam id. Mazim doctus vix an. <span class=\"text-indigo-darken-2\">Amet causae probatus nec ex</span>.\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/concepts/density-and-size.vue",
    "content": "<template>\n  <v-container class=\"pa-4\">\n    <v-row>\n      <v-col cols=\"12\" md=\"6\">\n        <v-slider\n          v-model=\"size\"\n          class=\"pt-6\"\n          label=\"Size\"\n          max=\"4\"\n          min=\"0\"\n          step=\"1\"\n          thumb-label=\"always\"\n          hide-details\n        >\n          <template v-slot:thumb-label=\"{ modelValue }\">\n            <div class=\"text-no-wrap\">\n              {{ sizes[modelValue] }}\n            </div>\n          </template>\n        </v-slider>\n      </v-col>\n\n      <v-col cols=\"12\" md=\"6\">\n        <v-slider\n          v-model=\"density\"\n          class=\"pt-6\"\n          label=\"Density\"\n          max=\"2\"\n          min=\"0\"\n          step=\"1\"\n          thumb-label=\"always\"\n          hide-details\n        >\n          <template v-slot:thumb-label=\"{ modelValue }\">\n            <div class=\"text-no-wrap\">\n              {{ densities[modelValue] }}\n            </div>\n          </template>\n        </v-slider>\n      </v-col>\n\n      <v-divider class=\"flex-grow-1 my-2 mx-n1\"></v-divider>\n\n      <v-col cols=\"12\">\n        <v-list-subheader>Buttons</v-list-subheader>\n\n        <v-btn\n          :density=\"densities[density]\"\n          :size=\"sizes[size]\"\n          class=\"me-2 mb-2\"\n          prepend-icon=\"$vuetify\"\n          text=\"Default Button\"\n        ></v-btn>\n\n        <v-btn\n          :density=\"densities[density]\"\n          :size=\"sizes[size]\"\n          append-icon=\"mdi-account-outline\"\n          class=\"me-2 mb-2\"\n          text=\"User Profile\"\n          variant=\"tonal\"\n        ></v-btn>\n\n        <v-btn\n          :density=\"densities[density]\"\n          :size=\"sizes[size]\"\n          class=\"me-2 mb-2\"\n          icon=\"$vuetify\"\n        ></v-btn>\n      </v-col>\n\n      <v-col cols=\"12\">\n        <v-list-subheader>Chips</v-list-subheader>\n\n        <v-chip\n          :density=\"densities[density]\"\n          :size=\"sizes[size]\"\n          class=\"me-2 mb-2\"\n\n          text=\"Complete\"\n        ></v-chip>\n\n        <v-chip\n          :density=\"densities[density]\"\n          :size=\"sizes[size]\"\n          class=\"me-2 mb-2\"\n          text=\"Reset\"\n          variant=\"outlined\"\n        ></v-chip>\n\n        <v-chip\n          :density=\"densities[density]\"\n          :size=\"sizes[size]\"\n          class=\"me-2 mb-2\"\n          text=\"Disabled\"\n          disabled\n        ></v-chip>\n      </v-col>\n\n      <v-col cols=\"12\">\n        <v-list-subheader>Avatars</v-list-subheader>\n\n        <v-avatar\n          :density=\"densities[density]\"\n          :size=\"sizes[size]\"\n          color=\"surface-variant\"\n          image=\"https://cdn.vuetifyjs.com/docs/images/avatars/grass.png\"\n        ></v-avatar>\n\n        <v-avatar\n          :density=\"densities[density]\"\n          :size=\"sizes[size]\"\n          class=\"ms-2\"\n          image=\"https://cdn.vuetifyjs.com/docs/images/avatars/gold.png\"\n        ></v-avatar>\n\n        <v-avatar\n          :density=\"densities[density]\"\n          :size=\"sizes[size]\"\n          class=\"ms-2\"\n          color=\"surface-variant\"\n          image=\"https://cdn.vuetifyjs.com/docs/images/avatars/planet.png\"\n        ></v-avatar>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const size = shallowRef(2)\n  const density = shallowRef(2)\n\n  const densities = ['compact', 'comfortable', 'default']\n  const sizes = ['x-small', 'small', 'default', 'large', 'x-large']\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/concepts/density.vue",
    "content": "<template>\n  <v-container class=\"pa-2\">\n    <v-row>\n      <v-col cols=\"12\">\n        <v-label class=\"d-block mb-4\">Density Scale</v-label>\n\n        <v-btn-toggle\n          v-model=\"density\"\n          class=\"overflow-auto\"\n          color=\"primary\"\n          density=\"compact\"\n          variant=\"outlined\"\n          divided\n        >\n          <v-btn text=\"Default\" value=\"default\"></v-btn>\n\n          <v-btn text=\"Comfortable\" value=\"comfortable\"></v-btn>\n\n          <v-btn text=\"Compact\" value=\"compact\"></v-btn>\n        </v-btn-toggle>\n      </v-col>\n\n      <v-divider class=\"flex-grow-1 mt-1 mx-n1\"></v-divider>\n\n      <v-col cols=\"12\">\n        <v-list-subheader>Buttons</v-list-subheader>\n\n        <v-btn\n          :density=\"density\"\n          class=\"me-2 mb-2\"\n          text=\"Submit\"\n        ></v-btn>\n\n        <v-btn\n          :density=\"density\"\n          class=\"me-2 mb-2\"\n          text=\"Load More\"\n          variant=\"text\"\n        ></v-btn>\n\n        <v-btn\n          :density=\"density\"\n          class=\"me-2 mb-2\"\n          text=\"Cancel\"\n          variant=\"outlined\"\n        ></v-btn>\n      </v-col>\n\n      <v-col cols=\"12\">\n        <v-list-subheader>Chips</v-list-subheader>\n\n        <v-chip\n          :density=\"density\"\n          class=\"me-2 mb-2\"\n          text=\"In Progress\"\n        ></v-chip>\n\n        <v-chip\n          :density=\"density\"\n          class=\"me-2 mb-2\"\n          text=\"High Priority\"\n        ></v-chip>\n\n        <v-chip\n          :density=\"density\"\n          class=\"me-2 mb-2\"\n          text=\"Assigned\"\n        ></v-chip>\n      </v-col>\n\n      <v-col cols=\"12\">\n        <v-list-subheader>Toolbars</v-list-subheader>\n\n        <v-toolbar\n          :density=\"density\"\n          class=\"mb-2\"\n          elevation=\"1\"\n          title=\"Daily Reports\"\n        ></v-toolbar>\n\n        <v-toolbar\n          :density=\"density\"\n          class=\"mb-2\"\n          title=\"User Dashboard\"\n        ></v-toolbar>\n\n        <v-toolbar\n          :density=\"density\"\n          color=\"transparent\"\n          title=\"Project Settings\"\n          border\n        ></v-toolbar>\n      </v-col>\n\n      <v-col cols=\"12\">\n        <v-list-subheader>Text Fields</v-list-subheader>\n\n        <v-text-field\n          :density=\"density\"\n          label=\"Search Query\"\n          model-value=\"Data tables\"\n          prepend-inner-icon=\"mdi-magnify\"\n          variant=\"solo\"\n        ></v-text-field>\n\n        <v-text-field\n          :density=\"density\"\n          label=\"Email Address\"\n          model-value=\"hello@vuetifyjs.com\"\n          prepend-inner-icon=\"mdi-email-outline\"\n        ></v-text-field>\n\n        <v-text-field\n          :density=\"density\"\n          label=\"Username\"\n          model-value=\"John Leider\"\n          prepend-inner-icon=\"mdi-account-outline\"\n          variant=\"outlined\"\n          hide-details\n        ></v-text-field>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const density = shallowRef('default')\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/concepts/size.vue",
    "content": "<template>\n  <v-container class=\"pa-2\">\n    <v-row>\n      <v-col cols=\"12\">\n        <v-label class=\"d-block mb-4\">Size Scale</v-label>\n\n        <v-btn-toggle\n          v-model=\"size\"\n          class=\"overflow-auto\"\n          color=\"primary\"\n          density=\"compact\"\n          direction=\"vertical\"\n          variant=\"outlined\"\n          divided\n        >\n          <v-btn text=\"X-small\" value=\"x-small\"></v-btn>\n\n          <v-btn text=\"Small\" value=\"small\"></v-btn>\n\n          <v-btn text=\"Default\" value=\"default\"></v-btn>\n\n          <v-btn text=\"Large\" value=\"large\"></v-btn>\n\n          <v-btn text=\"x-large\" value=\"x-large\"></v-btn>\n        </v-btn-toggle>\n      </v-col>\n\n      <v-divider class=\"flex-grow-1 my-2 mx-n1\"></v-divider>\n\n      <v-col cols=\"12\">\n        <v-list-subheader>Buttons</v-list-subheader>\n\n        <v-btn\n          :size=\"size\"\n          class=\"me-2 mb-2\"\n          text=\"Export\"\n        ></v-btn>\n\n        <v-btn\n          :size=\"size\"\n          class=\"me-2 mb-2\"\n          text=\"Edit\"\n          variant=\"text\"\n        ></v-btn>\n\n        <v-btn\n          :size=\"size\"\n          class=\"me-2 mb-2\"\n          text=\"Preview\"\n          variant=\"outlined\"\n        ></v-btn>\n      </v-col>\n\n      <v-col cols=\"12\">\n        <v-list-subheader>Chips</v-list-subheader>\n\n        <v-chip\n          :size=\"size\"\n          class=\"me-2 mb-2\"\n          text=\"Completed\"\n        ></v-chip>\n\n        <v-chip\n          :size=\"size\"\n          class=\"me-2 mb-2\"\n          text=\"Archived\"\n        ></v-chip>\n\n        <v-chip\n          :size=\"size\"\n          class=\"me-2 mb-2\"\n          text=\"New\"\n        ></v-chip>\n      </v-col>\n\n      <v-col cols=\"12\">\n        <v-list-subheader>Ratings</v-list-subheader>\n\n        <v-rating\n          :size=\"size\"\n          label=\"Customer Satisfaction\"\n          length=\"3\"\n        ></v-rating>\n\n        <br>\n\n        <v-rating\n          :size=\"size\"\n          label=\"Ease of Use\"\n          length=\"4\"\n        ></v-rating>\n\n        <br>\n\n        <v-rating\n          :size=\"size\"\n          label=\"Quality\"\n        ></v-rating>\n      </v-col>\n\n      <v-col cols=\"12\">\n        <v-list-subheader>Avatars</v-list-subheader>\n\n        <v-avatar\n          :size=\"size\"\n          class=\"mb-2 me-2\"\n          image=\"https://cdn.vuetifyjs.com/docs/images/avatars/dark.png\"\n        ></v-avatar>\n\n        <v-avatar\n          :size=\"size\"\n          class=\"mb-2 me-2\"\n          image=\"https://cdn.vuetifyjs.com/docs/images/avatars/blackhole.png\"\n        ></v-avatar>\n\n        <v-avatar\n          :size=\"size\"\n          class=\"mb-2 me-2\"\n          image=\"https://cdn.vuetifyjs.com/docs/images/avatars/meteor.png\"\n        ></v-avatar>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const size = shallowRef('default')\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/cursor/usage.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"justify-space-between\">\n      <v-col v-for=\"cursor in cursors\" :key=\"cursor\" cols=\"3\">\n        <v-btn\n          :class=\"`cursor-${cursor}`\"\n          :text=\"cursor\"\n          block\n        ></v-btn>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  const cursors = [\n    'auto',\n    'default',\n    'grab',\n    'grabbing',\n    'help',\n    'move',\n    'none',\n    'not-allowed',\n    'pointer',\n    'progress',\n    'text',\n    'wait',\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      cursors: [\n        'auto',\n        'default',\n        'grab',\n        'grabbing',\n        'help',\n        'move',\n        'none',\n        'not-allowed',\n        'pointer',\n        'progress',\n        'text',\n        'wait',\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/display/display-block.vue",
    "content": "<template>\n  <div>\n    <div class=\"d-block pa-2 bg-deep-purple\">\n      d-block\n    </div>\n    <div class=\"d-block pa-2 bg-black\">\n      d-block\n    </div>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/display/display-inline.vue",
    "content": "<template>\n  <div>\n    <div class=\"d-inline pa-2 bg-deep-purple\">\n      d-inline\n    </div>\n    <div class=\"d-inline pa-2 bg-black\">\n      d-inline\n    </div>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/display/hidden-elements.vue",
    "content": "<template>\n  <v-toolbar light>\n    <v-toolbar-title>Title</v-toolbar-title>\n    <v-toolbar-items\n      v-for=\"item in items\"\n      :key=\"item.text\"\n      class=\"hidden-sm-and-down\"\n    >\n      <v-btn variant=\"text\">\n        {{ item.text }}\n      </v-btn>\n    </v-toolbar-items>\n  </v-toolbar>\n</template>\n\n<script setup>\n  const items = [\n    {\n      text: 'Link One',\n    },\n    {\n      text: 'Link Two',\n    },\n    {\n      text: 'Link Three',\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        items: [\n          {\n            text: 'Link One',\n          },\n          {\n            text: 'Link Two',\n          },\n          {\n            text: 'Link Three',\n          },\n        ],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/display/print.vue",
    "content": "<template>\n  <div>\n    <div class=\"d-print-none\">\n      Screen Only (Hide on print only)\n    </div>\n    <div class=\"d-none d-print-block\">\n      Print Only (Hide on screen only)\n    </div>\n    <div class=\"d-none d-lg-block d-print-block\">\n      Hide up to large on screen, but always show on print\n    </div>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/display/visibility.vue",
    "content": "<template>\n  <div>\n    <div class=\"d-lg-none\">\n      hide on screens wider than lg\n    </div>\n    <div class=\"d-none d-lg-block\">\n      hide on screens smaller than lg\n    </div>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/elevation/prop-dynamic.vue",
    "content": "<template>\n  <div class=\"text--primary\">\n    <!-- Using the elevation prop -->\n    <v-hover v-slot=\"{ isHovering, props }\">\n      <v-card\n        v-bind=\"props\"\n        :elevation=\"isHovering ? 5 : 1\"\n        class=\"mx-auto pa-6\"\n      >\n        Prop based elevation\n      </v-card>\n    </v-hover>\n\n    <div class=\"my-6\"></div>\n\n    <!-- Using a dynamic class -->\n    <v-hover v-slot=\"{ isHovering, props }\">\n      <div\n        v-bind=\"props\"\n        :class=\"`bg-surface elevation-${isHovering ? 5 : 1}`\"\n        class=\"mx-auto pa-6\"\n      >\n        Class based elevation\n      </div>\n    </v-hover>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/elevation/usage.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"justify-center\">\n      <v-col\n        v-for=\"(_, n) in 6\"\n        :key=\"n\"\n        cols=\"auto\"\n      >\n        <v-card\n          :elevation=\"n\"\n          class=\"d-flex justify-center align-center elevation-overlay\"\n          height=\"100\"\n          rounded=\"xl\"\n          width=\"100\"\n        >\n          <div>{{ n }}</div>\n        </v-card>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/flex/flex-align-content.vue",
    "content": "<template>\n  <v-container class=\"d-flex flex-wrap ga-6\" fluid>\n    <div v-for=\"variant in variants\" :key=\"variant.value\">\n      <div class=\"text-body-small mb-2\">align-content-{{ variant.value }}</div>\n      <v-sheet\n        :class=\"`d-flex align-content-${variant.value} flex-wrap bg-surface-variant`\"\n        height=\"200\"\n        width=\"300\"\n      >\n        <v-sheet v-for=\"n in 5\" :key=\"n\" class=\"ma-2 pa-2\">\n          Flex item\n        </v-sheet>\n      </v-sheet>\n    </div>\n  </v-container>\n</template>\n\n<script setup>\n  const variants = [\n    { value: 'start' },\n    { value: 'center' },\n    { value: 'end' },\n    { value: 'space-between' },\n    { value: 'space-around' },\n  ]\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/flex/flex-align-self.vue",
    "content": "<template>\n  <div>\n    <v-sheet\n      class=\"d-flex mb-6 bg-surface-variant\"\n      height=\"100\"\n    >\n      <v-sheet class=\"ma-2 pa-2\">Flex item</v-sheet>\n      <v-sheet class=\"ma-2 pa-2 align-self-start\">align-self-start</v-sheet>\n      <v-sheet class=\"ma-2 pa-2\">Flex item</v-sheet>\n    </v-sheet>\n\n    <v-sheet\n      class=\"d-flex mb-6 bg-surface-variant\"\n      height=\"100\"\n    >\n      <v-sheet class=\"ma-2 pa-2\">Flex item</v-sheet>\n      <v-sheet class=\"ma-2 pa-2 align-self-end\">align-self-end</v-sheet>\n      <v-sheet class=\"ma-2 pa-2\">Flex item</v-sheet>\n    </v-sheet>\n\n    <v-sheet\n      class=\"d-flex mb-6 bg-surface-variant\"\n      height=\"100\"\n    >\n      <v-sheet class=\"ma-2 pa-2\">Flex item</v-sheet>\n      <v-sheet class=\"ma-2 pa-2 align-self-center\">align-self-center</v-sheet>\n      <v-sheet class=\"ma-2 pa-2\">Flex item</v-sheet>\n    </v-sheet>\n\n    <v-sheet\n      class=\"d-flex mb-6 bg-surface-variant\"\n      height=\"100\"\n    >\n      <v-sheet class=\"ma-2 pa-2\">Flex item</v-sheet>\n      <v-sheet class=\"ma-2 pa-2 align-self-baseline\">align-self-baseline</v-sheet>\n      <v-sheet class=\"ma-2 pa-2\">Flex item</v-sheet>\n    </v-sheet>\n\n    <v-sheet\n      class=\"d-flex mb-6 bg-surface-variant\"\n      height=\"100\"\n    >\n      <v-sheet class=\"ma-2 pa-2\">Flex item</v-sheet>\n      <v-sheet class=\"ma-2 pa-2 align-self-auto\">align-self-auto</v-sheet>\n      <v-sheet class=\"ma-2 pa-2\">Flex item</v-sheet>\n    </v-sheet>\n\n    <v-sheet\n      class=\"d-flex mb-6 bg-surface-variant\"\n      height=\"100\"\n    >\n      <v-sheet class=\"ma-2 pa-2\">Flex item</v-sheet>\n      <v-sheet class=\"ma-2 pa-2 align-self-stretch\">align-self-stretch</v-sheet>\n      <v-sheet class=\"ma-2 pa-2\">Flex item</v-sheet>\n    </v-sheet>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/flex/flex-align.vue",
    "content": "<template>\n  <div>\n    <v-sheet\n      class=\"d-flex align-start mb-6 bg-surface-variant\"\n      height=\"100\"\n    >\n      <v-sheet\n        v-for=\"n in 3\"\n        :key=\"n\"\n        class=\"ma-2 pa-2\"\n      >\n        align-start\n      </v-sheet>\n    </v-sheet>\n\n    <v-sheet\n      class=\"d-flex align-end mb-6 bg-surface-variant\"\n      height=\"100\"\n    >\n      <v-sheet\n        v-for=\"n in 3\"\n        :key=\"n\"\n        class=\"ma-2 pa-2\"\n      >\n        align-end\n      </v-sheet>\n    </v-sheet>\n\n    <v-sheet\n      class=\"d-flex align-center mb-6 bg-surface-variant\"\n      height=\"100\"\n    >\n      <v-sheet\n        v-for=\"n in 3\"\n        :key=\"n\"\n        class=\"ma-2 pa-2\"\n      >\n        align-center\n      </v-sheet>\n    </v-sheet>\n\n    <v-sheet\n      class=\"d-flex align-baseline mb-6 bg-surface-variant\"\n      height=\"100\"\n    >\n      <v-sheet\n        v-for=\"n in 3\"\n        :key=\"n\"\n        class=\"ma-2 pa-2\"\n      >\n        align-baseline\n      </v-sheet>\n    </v-sheet>\n\n    <v-sheet\n      class=\"d-flex align-stretch mb-6 bg-surface-variant\"\n      height=\"100\"\n    >\n      <v-sheet\n        v-for=\"n in 3\"\n        :key=\"n\"\n        class=\"ma-2 pa-2\"\n      >\n        align-stretch\n      </v-sheet>\n    </v-sheet>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/flex/flex-column.vue",
    "content": "<template>\n  <div>\n    <div class=\"d-flex flex-column mb-6 bg-surface-variant\">\n      <v-sheet class=\"ma-2 pa-2\">Flex item 1</v-sheet>\n      <v-sheet class=\"ma-2 pa-2\">Flex item 2</v-sheet>\n      <v-sheet class=\"ma-2 pa-2\">Flex item 3</v-sheet>\n    </div>\n\n    <div class=\"d-flex flex-column-reverse mb-6 bg-surface-variant\">\n      <v-sheet class=\"ma-2 pa-2\">Flex item 1</v-sheet>\n      <v-sheet class=\"ma-2 pa-2\">Flex item 2</v-sheet>\n      <v-sheet class=\"ma-2 pa-2\">Flex item 3</v-sheet>\n    </div>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/flex/flex-direction.vue",
    "content": "<template>\n  <div>\n    <div class=\"d-flex flex-row mb-6 bg-surface-variant\">\n      <v-sheet class=\"ma-2 pa-2\">Flex item 1</v-sheet>\n      <v-sheet class=\"ma-2 pa-2\">Flex item 2</v-sheet>\n      <v-sheet class=\"ma-2 pa-2\">Flex item 3</v-sheet>\n    </div>\n\n    <div class=\"d-flex flex-row-reverse mb-6 bg-surface-variant\">\n      <v-sheet class=\"ma-2 pa-2\">Flex item 1</v-sheet>\n      <v-sheet class=\"ma-2 pa-2\">Flex item 2</v-sheet>\n      <v-sheet class=\"ma-2 pa-2\">Flex item 3</v-sheet>\n    </div>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/flex/flex-flex.vue",
    "content": "<template>\n  <v-sheet class=\"d-flex flex-wrap bg-surface-variant\">\n    <v-sheet class=\"flex-1-0 ma-2 pa-2\">\n      I'm an element in an inline flexbox container!\n    </v-sheet>\n\n    <v-sheet class=\"ma-2 pa-2\">\n      I'm a single element in an inline flexbox container!\n    </v-sheet>\n\n    <v-sheet class=\"flex-1-1-100 ma-2 pa-2\">\n      I'm a single element in an inline flexbox container!\n    </v-sheet>\n  </v-sheet>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/flex/flex-justify.vue",
    "content": "<template>\n  <div>\n    <div class=\"d-flex justify-start mb-6 bg-surface-variant\">\n      <v-sheet\n        v-for=\"n in 3\"\n        :key=\"n\"\n        class=\"ma-2 pa-2\"\n      >\n        justify-start\n      </v-sheet>\n    </div>\n\n    <div class=\"d-flex justify-end mb-6 bg-surface-variant\">\n      <v-sheet\n        v-for=\"n in 3\"\n        :key=\"n\"\n        class=\"ma-2 pa-2\"\n      >\n        justify-end\n      </v-sheet>\n    </div>\n\n    <div class=\"d-flex justify-center mb-6 bg-surface-variant\">\n      <v-sheet\n        v-for=\"n in 3\"\n        :key=\"n\"\n        class=\"ma-2 pa-2\"\n      >\n        justify-center\n      </v-sheet>\n    </div>\n\n    <div class=\"d-flex justify-space-between mb-6 bg-surface-variant\">\n      <v-sheet\n        v-for=\"n in 3\"\n        :key=\"n\"\n        class=\"ma-2 pa-2\"\n      >\n        justify-space-between\n      </v-sheet>\n    </div>\n\n    <div class=\"d-flex justify-space-around mb-6 bg-surface-variant\">\n      <v-sheet\n        v-for=\"n in 3\"\n        :key=\"n\"\n        class=\"ma-2 pa-2\"\n      >\n        justify-space-around\n      </v-sheet>\n    </div>\n\n    <div class=\"d-flex justify-space-evenly mb-6 bg-surface-variant\">\n      <v-sheet\n        v-for=\"n in 3\"\n        :key=\"n\"\n        class=\"ma-2 pa-2\"\n      >\n        justify-space-evenly\n      </v-sheet>\n    </div>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/flex/flex-nowrap.vue",
    "content": "<template>\n  <v-sheet\n    class=\"d-flex flex-nowrap py-3 bg-surface-variant\"\n    width=\"125\"\n  >\n    <v-sheet\n      v-for=\"n in 5\"\n      :key=\"n\"\n      class=\"ma-2 pa-2\"\n    >\n      Flex item\n    </v-sheet>\n  </v-sheet>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/flex/flex-order.vue",
    "content": "<template>\n  <v-sheet class=\"d-flex flex-wrap-reverse bg-surface-variant\">\n    <v-sheet class=\"order-3 pa-2 ma-2\">\n      First flex item\n    </v-sheet>\n\n    <v-sheet class=\"order-2 pa-2 ma-2\">\n      Second flex item\n    </v-sheet>\n\n    <v-sheet class=\"order-1 pa-2 ma-2\">\n      Third flex item\n    </v-sheet>\n  </v-sheet>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/flex/flex-wrap-reverse.vue",
    "content": "<template>\n  <v-sheet class=\"d-flex flex-wrap-reverse bg-surface-variant\">\n    <v-sheet\n      v-for=\"n in 20\"\n      :key=\"n\"\n      class=\"ma-2 pa-2\"\n    >\n      Flex item {{ n }}\n    </v-sheet>\n  </v-sheet>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/flex/flex-wrap.vue",
    "content": "<template>\n  <v-sheet class=\"d-flex flex-wrap bg-surface-variant\">\n    <v-sheet\n      v-for=\"n in 20\"\n      :key=\"n\"\n      class=\"ma-2 pa-2\"\n    >\n      Flex item {{ n }}\n    </v-sheet>\n  </v-sheet>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/flex/flexbox-inline.vue",
    "content": "<template>\n  <v-sheet class=\"d-inline-flex bg-surface-variant\">\n    <v-sheet class=\"ma-2 pa-2\">\n      I'm a single element in an inline flexbox container!\n    </v-sheet>\n  </v-sheet>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/flex/flexbox.vue",
    "content": "<template>\n  <v-sheet class=\"d-flex bg-surface-variant\">\n    <v-sheet class=\"ma-2 pa-2\">\n      I'm a single element in a flexbox container!\n    </v-sheet>\n  </v-sheet>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/flex/grow-shrink.vue",
    "content": "<template>\n  <v-container>\n    <v-row\n      class=\"flex-nowrap bg-surface-variant\"\n      density=\"compact\"\n    >\n      <v-col\n        class=\"flex-grow-0 flex-shrink-0\"\n        cols=\"2\"\n      >\n        <v-sheet class=\"ma-2 pa-2\">\n          I'm 2 column wide\n        </v-sheet>\n      </v-col>\n\n      <v-col\n        class=\"flex-grow-1 flex-shrink-0\"\n        cols=\"1\"\n        style=\"min-width: 100px; max-width: 100%;\"\n      >\n        <v-sheet class=\"ma-2 pa-2\">\n          I'm 1 column wide and I grow to take all the space\n        </v-sheet>\n      </v-col>\n\n      <v-col\n        class=\"flex-grow-0 flex-shrink-1\"\n        cols=\"5\"\n        style=\"min-width: 100px;\"\n      >\n        <v-sheet class=\"ma-2 pa-2\">\n          I'm 5 column wide and I shrink if there's not enough space\n        </v-sheet>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/flex/margins-align-items.vue",
    "content": "<template>\n  <div>\n    <v-sheet\n      class=\"d-flex align-start flex-column mb-6 bg-surface-variant\"\n      height=\"200\"\n    >\n      <v-sheet class=\"ma-2 pa-2 mb-auto\">Flex item</v-sheet>\n      <v-sheet class=\"ma-2 pa-2\">Flex item</v-sheet>\n      <v-sheet class=\"ma-2 pa-2\">Flex item</v-sheet>\n    </v-sheet>\n\n    <v-sheet\n      class=\"d-flex align-end flex-column bg-surface-variant\"\n      height=\"200\"\n    >\n      <v-sheet class=\"ma-2 pa-2\">Flex item</v-sheet>\n      <v-sheet class=\"ma-2 pa-2\">Flex item</v-sheet>\n      <v-sheet class=\"ma-2 pa-2 mt-auto\">Flex item</v-sheet>\n    </v-sheet>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/flex/margins.vue",
    "content": "<template>\n  <div>\n    <v-sheet class=\"d-flex mb-6 bg-surface-variant\">\n      <v-sheet class=\"ma-2 pa-2\">Flex item</v-sheet>\n      <v-sheet class=\"ma-2 pa-2\">Flex item</v-sheet>\n      <v-sheet class=\"ma-2 pa-2\">Flex item</v-sheet>\n    </v-sheet>\n\n    <v-sheet class=\"d-flex mb-6 bg-surface-variant\">\n      <v-sheet class=\"ma-2 pa-2 me-auto\">Flex item</v-sheet>\n      <v-sheet class=\"ma-2 pa-2\">Flex item</v-sheet>\n      <v-sheet class=\"ma-2 pa-2\">Flex item</v-sheet>\n    </v-sheet>\n\n    <v-sheet class=\"d-flex mb-6 bg-surface-variant\">\n      <v-sheet class=\"ma-2 pa-2\">Flex item</v-sheet>\n      <v-sheet class=\"ma-2 pa-2\">Flex item</v-sheet>\n      <v-sheet class=\"ma-2 pa-2\">Flex item</v-sheet>\n    </v-sheet>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/float/classes.vue",
    "content": "<template>\n  <div>\n    <div class=\"float-left\">\n      Float left on all viewport sizes\n    </div>\n    <br>\n    <div class=\"float-right\">\n      Float right on all viewport sizes\n    </div>\n    <br>\n    <div class=\"float-none\">\n      Don't float on all viewport sizes\n    </div>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/float/responsive.vue",
    "content": "<template>\n  <div>\n    <div class=\"float-sm-left\">\n      Float left on viewports sized SM (small) or wider\n    </div>\n    <br>\n    <div class=\"float-md-left\">\n      Float left on viewports sized MD (medium) or wider\n    </div>\n    <br>\n    <div class=\"float-lg-left\">\n      Float left on viewports sized LG (large) or wider\n    </div>\n    <br>\n    <div class=\"float-xl-left\">\n      Float left on viewports sized XL (extra-large) or wider\n    </div>\n    <br>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/grid/misc-column-wrapping.vue",
    "content": "<template>\n  <v-container class=\"bg-surface-variant\">\n    <v-row>\n      <v-col cols=\"9\">\n        <v-sheet class=\"pa-2\">\n          v-col-9\n        </v-sheet>\n      </v-col>\n      <v-col cols=\"4\">\n        <v-sheet class=\"pa-2\">\n          v-col-4\n        </v-sheet>\n      </v-col>\n      <v-col cols=\"6\">\n        <v-sheet class=\"pa-2\">\n          v-col-6\n        </v-sheet>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/grid/misc-equal-width-columns.vue",
    "content": "<template>\n  <v-container class=\"bg-surface-variant\">\n    <v-row gap=\"0\">\n      <v-col>\n        <v-sheet class=\"pa-2 ma-2\">\n          v-col\n        </v-sheet>\n      </v-col>\n      <v-col>\n        <v-sheet class=\"pa-2 ma-2\">\n          v-col\n        </v-sheet>\n      </v-col>\n\n      <v-responsive width=\"100%\"></v-responsive>\n\n      <v-col>\n        <v-sheet class=\"pa-2 ma-2\">\n          v-col\n        </v-sheet>\n      </v-col>\n\n      <v-col>\n        <v-sheet class=\"pa-2 ma-2\">\n          v-col\n        </v-sheet>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/grid/misc-grow-and-shrink.vue",
    "content": "<template>\n  <v-container class=\"bg-surface-variant\">\n    <v-row class=\"mb-6\">\n      <v-col>\n        <v-sheet class=\"pa-2\">\n          v-col-auto\n        </v-sheet>\n      </v-col>\n\n      <v-col>\n        <v-sheet class=\"pa-2\">\n          v-col-auto\n        </v-sheet>\n      </v-col>\n\n      <v-col>\n        <v-sheet class=\"pa-2\">\n          v-col-auto\n        </v-sheet>\n      </v-col>\n\n      <v-col>\n        <v-sheet class=\"pa-2\">\n          v-col-auto\n        </v-sheet>\n      </v-col>\n    </v-row>\n\n    <v-row>\n      <v-col cols=\"8\">\n        <v-sheet class=\"pa-2\">\n          v-col-8\n        </v-sheet>\n      </v-col>\n\n      <v-col cols=\"4\">\n        <v-sheet class=\"pa-2\">\n          v-col-4\n        </v-sheet>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/grid/misc-margin-helpers.vue",
    "content": "<template>\n  <v-container class=\"bg-surface-variant\">\n    <v-row>\n      <v-col md=\"4\">\n        <v-sheet class=\"pa-2\">\n          v-col-md-4\n        </v-sheet>\n      </v-col>\n      <v-col\n        class=\"ms-auto\"\n        md=\"4\"\n      >\n        <v-sheet class=\"pa-2\">\n          v-col-md-4 .ms-auto\n        </v-sheet>\n      </v-col>\n    </v-row>\n\n    <v-row>\n      <v-col\n        class=\"ms-md-auto\"\n        md=\"4\"\n      >\n        <v-sheet class=\"pa-2\">\n          v-col-md-4 .ms-md-auto\n        </v-sheet>\n      </v-col>\n      <v-col\n        class=\"ms-md-auto\"\n        md=\"4\"\n      >\n        <v-sheet class=\"pa-2\">\n          v-col-md-4 .ms-md-auto\n        </v-sheet>\n      </v-col>\n    </v-row>\n\n    <v-row>\n      <v-col\n        class=\"me-auto\"\n        cols=\"auto\"\n      >\n        <v-sheet class=\"pa-2\">\n          v-col-auto .me-auto\n        </v-sheet>\n      </v-col>\n      <v-col cols=\"auto\">\n        <v-sheet class=\"pa-2\">\n          v-col-auto\n        </v-sheet>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/grid/misc-nested-grid.vue",
    "content": "<template>\n  <v-container class=\"pa-0\">\n    <v-row class=\"bg-green pa-3\">\n      <v-col cols=\"8\">\n        <v-sheet class=\"pa-2 ma-2\">\n          Level 1: v-col-8\n        </v-sheet>\n\n        <v-row class=\"bg-red\" gap=\"0\">\n          <v-col\n            cols=\"8\"\n          >\n            <v-sheet class=\"pa-2 ma-2\">\n              Level 2: v-col-8\n            </v-sheet>\n          </v-col>\n\n          <v-col\n            cols=\"4\"\n          >\n            <v-sheet class=\"pa-2 ma-2\">\n              Level 2: v-col-4\n            </v-sheet>\n          </v-col>\n        </v-row>\n      </v-col>\n\n      <v-col cols=\"4\">\n        <v-sheet class=\"pa-2 ma-2\">\n          Level 1: v-col-4\n        </v-sheet>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/grid/misc-one-column-width.vue",
    "content": "<template>\n  <v-container class=\"bg-surface-variant\">\n    <v-row>\n      <v-col>\n        <v-sheet class=\"pa-2\">\n          v-col-auto\n        </v-sheet>\n      </v-col>\n\n      <v-col cols=\"6\">\n        <v-sheet class=\"pa-2\">\n          v-col-6\n        </v-sheet>\n      </v-col>\n\n      <v-col>\n        <v-sheet class=\"pa-2\">\n          v-col-auto\n        </v-sheet>\n      </v-col>\n    </v-row>\n\n    <v-row>\n      <v-col>\n        <v-sheet class=\"pa-2\">\n          v-col-auto\n        </v-sheet>\n      </v-col>\n\n      <v-col cols=\"2\">\n        <v-sheet class=\"pa-2\">\n          v-col-2\n        </v-sheet>\n      </v-col>\n\n      <v-col>\n        <v-sheet class=\"pa-2\">\n          v-col-auto\n        </v-sheet>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/grid/misc-row-and-column-breakpoints.vue",
    "content": "<template>\n  <v-container class=\"bg-surface-variant\">\n    <v-row class=\"mb-6\">\n      <v-col :cols=\"cols[0]\">\n        <v-sheet class=\"pa-2\">\n          v-col-{{ cols[0] }}\n        </v-sheet>\n      </v-col>\n\n      <v-col :cols=\"cols[1]\">\n        <v-sheet class=\"pa-2\">\n          v-col-{{ cols[1] }}\n        </v-sheet>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { computed } from 'vue'\n  import { useDisplay } from 'vuetify'\n\n  const { lg, sm } = useDisplay()\n\n  const cols = computed(() => {\n    return lg.value ? [3, 9]\n      : sm.value ? [9, 3]\n        : [6, 6]\n  })\n</script>\n\n<script>\n  export default {\n    computed: {\n      cols () {\n        const { lg, sm } = this.$vuetify.display\n        return lg ? [3, 9]\n          : sm ? [9, 3]\n            : [6, 6]\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/grid/misc-size-overrides.vue",
    "content": "<template>\n  <v-container class=\"bg-surface-variant\">\n    <v-row class=\"mb-6\">\n      <v-col cols=\"2/5\">\n        <v-sheet class=\"pa-2 text-center\" color=\"purple-accent-4\">2/5</v-sheet>\n      </v-col>\n      <v-col cols=\"1/2\">\n        <v-sheet class=\"pa-2 text-center\" color=\"brown-darken-1\">1/2</v-sheet>\n      </v-col>\n      <v-col cols=\"1/10\">\n        <v-sheet class=\"pa-2 text-center\" color=\"teal-darken-1\">1/10</v-sheet>\n      </v-col>\n    </v-row>\n\n    <v-row>\n      <v-col\n        offset=\"1/2\"\n        offset-lg=\"0\"\n        offset-md=\"1/3\"\n      >\n        <v-sheet class=\"pa-2\" color=\"blue-darken-2\">grow | offset:1/2<br>grow | offset-md:1/3<br>grow | offset-lg:0</v-sheet>\n      </v-col>\n\n      <v-col\n        cols=\"1/2\"\n        lg=\"1/4\"\n        md=\"1/3\"\n      >\n        <v-sheet class=\"pa-2\" color=\"yellow-darken-3\">1/2<br>md:1/3<br>lg:1/4</v-sheet>\n      </v-col>\n\n      <v-col\n        cols=\"1/4\"\n        lg=\"1/2\"\n        md=\"1/3\"\n        offset=\"1/8\"\n        offset-lg=\"0\"\n        offset-md=\"1/6\"\n      >\n        <v-sheet class=\"pa-2\" color=\"green-darken-1\">1/4 | offset:1/8<br>md:1/3 | offset-md:1/6<br>lg:1/2 | offset-lg:0</v-sheet>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/grid/misc-spacer.vue",
    "content": "<template>\n  <v-container class=\"bg-surface-variant\">\n    <v-row>\n      <v-col>\n        <v-sheet class=\"pa-2\">\n          v-col-auto\n        </v-sheet>\n      </v-col>\n\n      <v-spacer></v-spacer>\n\n      <v-col>\n        <v-sheet class=\"pa-2\">\n          v-col-auto\n        </v-sheet>\n      </v-col>\n    </v-row>\n\n    <v-row>\n      <v-col>\n        <v-sheet class=\"pa-2\">\n          v-col-auto\n        </v-sheet>\n      </v-col>\n\n      <v-spacer></v-spacer>\n\n      <v-col>\n        <v-sheet class=\"pa-2\">\n          v-col-auto\n        </v-sheet>\n      </v-col>\n\n      <v-spacer></v-spacer>\n\n      <v-col>\n        <v-sheet class=\"pa-2\">\n          v-col-auto\n        </v-sheet>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/grid/misc-unique-layouts.vue",
    "content": "<template>\n  <v-container class=\"bg-surface-variant\">\n    <!-- Stack the columns on mobile by making one full-width and the other half-width -->\n    <v-row>\n      <v-col\n        cols=\"12\"\n        md=\"8\"\n      >\n        <v-card\n          class=\"pa-2\"\n          rounded=\"0\"\n          variant=\"outlined\"\n        >\n          v-col-12 v-col-md-8\n        </v-card>\n      </v-col>\n      <v-col\n        cols=\"6\"\n        md=\"4\"\n      >\n        <v-card\n          class=\"pa-2\"\n          rounded=\"0\"\n          variant=\"outlined\"\n        >\n          v-col-6 v-col-md-4\n        </v-card>\n      </v-col>\n    </v-row>\n\n    <!-- Columns start at 50% wide on mobile and bump up to 33.3% wide on desktop -->\n    <v-row>\n      <v-col\n        v-for=\"n in 3\"\n        :key=\"n\"\n        cols=\"6\"\n        md=\"4\"\n      >\n        <v-card\n          class=\"pa-2\"\n          rounded=\"0\"\n          variant=\"outlined\"\n        >\n          v-col-6 v-col-md-4\n        </v-card>\n      </v-col>\n    </v-row>\n\n    <!-- Columns are always 50% wide, on mobile and desktop -->\n    <v-row>\n      <v-col\n        v-for=\"n in 2\"\n        :key=\"n\"\n        cols=\"6\"\n      >\n        <v-card\n          class=\"pa-2\"\n          rounded=\"0\"\n          variant=\"outlined\"\n        >\n          v-col-6\n        </v-card>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/grid/misc-variable-content.vue",
    "content": "<template>\n  <v-container class=\"bg-surface-variant\">\n    <v-row class=\"mb-6 justify-center\">\n      <v-col lg=\"2\">\n        <v-card\n          class=\"pa-2\"\n          rounded=\"0\"\n          variant=\"outlined\"\n        >\n          1 of 3\n        </v-card>\n      </v-col>\n      <v-col md=\"auto\">\n        <v-card\n          class=\"pa-2\"\n          rounded=\"0\"\n          variant=\"outlined\"\n        >\n          Variable width content\n        </v-card>\n      </v-col>\n      <v-col lg=\"2\">\n        <v-card\n          class=\"pa-2\"\n          rounded=\"0\"\n          variant=\"outlined\"\n        >\n          3 of 3\n        </v-card>\n      </v-col>\n    </v-row>\n    <v-row>\n      <v-col>\n        <v-card\n          class=\"pa-2\"\n          rounded=\"0\"\n          variant=\"outlined\"\n        >\n          1 of 3\n        </v-card>\n      </v-col>\n      <v-col md=\"auto\">\n        <v-card\n          class=\"pa-2\"\n          rounded=\"0\"\n          variant=\"outlined\"\n        >\n          Variable width content\n        </v-card>\n      </v-col>\n      <v-col lg=\"2\">\n        <v-card\n          class=\"pa-2\"\n          rounded=\"0\"\n          variant=\"outlined\"\n        >\n          3 of 3\n        </v-card>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/grid/prop-align.vue",
    "content": "<template>\n  <div>\n    <v-container\n      class=\"bg-surface-variant mb-6\"\n    >\n      <v-row\n        class=\"align-start\"\n        style=\"height: 150px;\"\n      >\n        <v-col\n          v-for=\"n in 3\"\n          :key=\"n\"\n        >\n          <v-sheet class=\"pa-2\">\n            align-start\n          </v-sheet>\n        </v-col>\n      </v-row>\n    </v-container>\n\n    <v-container\n      class=\"bg-surface-variant mb-6\"\n    >\n      <v-row\n        class=\"align-center\"\n        style=\"height: 150px;\"\n      >\n        <v-col\n          v-for=\"n in 3\"\n          :key=\"n\"\n        >\n          <v-sheet class=\"pa-2\">\n            align-center\n          </v-sheet>\n        </v-col>\n      </v-row>\n    </v-container>\n\n    <v-container\n      class=\"bg-surface-variant mb-6\"\n    >\n      <v-row\n        class=\"align-end\"\n        style=\"height: 150px;\"\n      >\n        <v-col\n          v-for=\"n in 3\"\n          :key=\"n\"\n        >\n          <v-sheet class=\"pa-2\">\n            align-end\n          </v-sheet>\n        </v-col>\n      </v-row>\n    </v-container>\n\n    <v-container class=\"bg-surface-variant\">\n      <v-row style=\"height: 150px;\">\n        <v-col class=\"align-self-start\">\n          <v-sheet class=\"pa-2\">\n            align-self-start\n          </v-sheet>\n        </v-col>\n\n        <v-col class=\"align-self-center\">\n          <v-sheet class=\"pa-2\">\n            align-self-center\n          </v-sheet>\n        </v-col>\n\n        <v-col class=\"align-self-end\">\n          <v-sheet class=\"pa-2\">\n            align-self-end\n          </v-sheet>\n        </v-col>\n      </v-row>\n    </v-container>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/grid/prop-breakpoint-sizing.vue",
    "content": "<template>\n  <v-container class=\"bg-surface-variant\">\n    <v-row>\n      <v-col>\n        <v-sheet class=\"pa-2\">\n          v-col-auto\n        </v-sheet>\n      </v-col>\n      <v-col>\n        <v-sheet class=\"pa-2\">\n          v-col-auto\n        </v-sheet>\n      </v-col>\n    </v-row>\n\n    <v-row>\n      <v-col>\n        <v-sheet class=\"pa-2\">\n          v-col-auto\n        </v-sheet>\n      </v-col>\n      <v-col>\n        <v-sheet class=\"pa-2\">\n          v-col-auto\n        </v-sheet>\n      </v-col>\n      <v-col>\n        <v-sheet class=\"pa-2\">\n          v-col-auto\n        </v-sheet>\n      </v-col>\n    </v-row>\n\n    <v-row>\n      <v-col cols=\"2\">\n        <v-sheet class=\"pa-2\">\n          v-col-2\n        </v-sheet>\n      </v-col>\n      <v-col>\n        <v-sheet class=\"pa-2\">\n          v-col-auto\n        </v-sheet>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/grid/prop-density-compact.vue",
    "content": "<template>\n  <v-container class=\"bg-surface-variant\">\n    <v-row density=\"compact\">\n      <v-col cols=\"12\">\n        <v-sheet class=\"pa-2\">\n          v-col-12\n        </v-sheet>\n      </v-col>\n      <v-col cols=\"6\">\n        <v-sheet class=\"pa-2\">\n          v-col-6\n        </v-sheet>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/grid/prop-justify.vue",
    "content": "<template>\n  <v-container class=\"bg-surface-variant\">\n    <v-row class=\"justify-start\">\n      <v-col\n        v-for=\"k in 2\"\n        :key=\"k\"\n        cols=\"4\"\n      >\n        <v-sheet class=\"pa-2\">\n          justify-start\n        </v-sheet>\n      </v-col>\n    </v-row>\n\n    <v-row class=\"justify-center\">\n      <v-col\n        v-for=\"k in 2\"\n        :key=\"k\"\n        cols=\"4\"\n      >\n        <v-sheet class=\"pa-2\">\n          justify-center\n        </v-sheet>\n      </v-col>\n    </v-row>\n\n    <v-row class=\"justify-end\">\n      <v-col\n        v-for=\"k in 2\"\n        :key=\"k\"\n        cols=\"4\"\n      >\n        <v-sheet class=\"pa-2\">\n          justify-end\n        </v-sheet>\n      </v-col>\n    </v-row>\n\n    <v-row class=\"justify-space-around\">\n      <v-col\n        v-for=\"k in 2\"\n        :key=\"k\"\n        cols=\"4\"\n      >\n        <v-sheet class=\"pa-2\">\n          justify-space-around\n        </v-sheet>\n      </v-col>\n    </v-row>\n\n    <v-row class=\"justify-space-between\">\n      <v-col\n        v-for=\"k in 2\"\n        :key=\"k\"\n        cols=\"4\"\n      >\n        <v-sheet class=\"pa-2\">\n          justify-space-between\n        </v-sheet>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/grid/prop-offset-breakpoint.vue",
    "content": "<template>\n  <v-container class=\"bg-surface-variant\">\n    <v-row class=\"mb-6\">\n      <v-col\n        md=\"6\"\n        sm=\"5\"\n      >\n        <v-sheet class=\"pa-2\">\n          v-col-sm-5 v-col-md-6\n        </v-sheet>\n      </v-col>\n      <v-col\n        md=\"6\"\n        offset-md=\"0\"\n        offset-sm=\"2\"\n        sm=\"5\"\n      >\n        <v-sheet class=\"pa-2\">\n          v-col-sm-5 offset-sm-2 v-col-md-6 offset-md-0\n        </v-sheet>\n      </v-col>\n    </v-row>\n    <v-row>\n      <v-col\n        lg=\"6\"\n        md=\"5\"\n        sm=\"6\"\n      >\n        <v-sheet class=\"pa-2\">\n          sm-6 md-5 lg-6\n        </v-sheet>\n      </v-col>\n      <v-col\n        lg=\"6\"\n        md=\"5\"\n        offset-lg=\"0\"\n        offset-md=\"2\"\n        sm=\"6\"\n      >\n        <v-sheet class=\"pa-2\">\n          v-col-sm-6 md-5 offset-md-2 v-col-lg-6 offset-lg-0\n        </v-sheet>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/grid/prop-offset.vue",
    "content": "<template>\n  <v-container class=\"bg-surface-variant\">\n    <v-row\n      class=\"mb-6\"\n      gap=\"0\"\n    >\n      <v-col cols=\"4\">\n        <v-sheet class=\"pa-2 ma-2\">\n          .v-col-4\n        </v-sheet>\n      </v-col>\n      <v-col\n        cols=\"4\"\n        offset=\"4\"\n      >\n        <v-sheet class=\"pa-2 ma-2\">\n          .v-col-4 .offset-4\n        </v-sheet>\n      </v-col>\n    </v-row>\n    <v-row\n      class=\"mb-6\"\n      gap=\"0\"\n    >\n      <v-col\n        cols=\"3\"\n        offset=\"3\"\n      >\n        <v-sheet class=\"pa-2 ma-2\">\n          .v-col-3 .offset-3\n        </v-sheet>\n      </v-col>\n      <v-col\n        cols=\"3\"\n        offset=\"3\"\n      >\n        <v-sheet class=\"pa-2 ma-2\">\n          .v-col-3 .offset-3\n        </v-sheet>\n      </v-col>\n    </v-row>\n    <v-row gap=\"0\">\n      <v-col\n        cols=\"6\"\n        offset=\"3\"\n      >\n        <v-sheet class=\"pa-2 ma-2\">\n          .v-col-6 .offset-3\n        </v-sheet>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/grid/prop-order-first-and-last.vue",
    "content": "<template>\n  <v-container class=\"bg-surface-variant\">\n    <v-row>\n      <v-col class=\"order-last\">\n        <v-sheet class=\"pa-2\">\n          First, but last\n        </v-sheet>\n      </v-col>\n      <v-col>\n        <v-sheet class=\"pa-2\">\n          Second, but unordered\n        </v-sheet>\n      </v-col>\n      <v-col class=\"order-first\">\n        <v-sheet class=\"pa-2\">\n          Third, but first\n        </v-sheet>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/grid/prop-order.vue",
    "content": "<template>\n  <v-container class=\"bg-surface-variant\">\n    <v-row>\n      <v-col class=\"order-6\">\n        <v-sheet class=\"pa-2\">\n          First in markup, but middle in row\n        </v-sheet>\n      </v-col>\n      <v-col class=\"order-12\">\n        <v-sheet class=\"pa-2\">\n          Second in markup, but last in row\n        </v-sheet>\n      </v-col>\n      <v-col class=\"order-1\">\n        <v-sheet class=\"pa-2\">\n          Third in markup, but first in row\n        </v-sheet>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/grid/prop-size.vue",
    "content": "<template>\n  <v-container class=\"bg-surface-variant\">\n    <v-row size=\"5\">\n      <v-col cols=\"2\">\n        <v-sheet class=\"pa-2 text-center\">v-col-2</v-sheet>\n      </v-col>\n      <v-col cols=\"1\">\n        <v-sheet class=\"pa-2 text-center\">v-col-1</v-sheet>\n      </v-col>\n      <v-col cols=\"2\">\n        <v-sheet class=\"pa-2 text-center\">v-col-2</v-sheet>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/grid/usage.vue",
    "content": "<template>\n  <v-container class=\"bg-surface-variant\">\n    <v-row gap=\"16\">\n      <v-col\n        v-for=\"n in 3\"\n        :key=\"n\"\n        cols=\"12\"\n        sm=\"4\"\n      >\n        <v-sheet class=\"pa-2\">\n          One of three columns\n        </v-sheet>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/hotkey/basic.vue",
    "content": "<template>\n  <v-container>\n    <v-row>\n      <v-col cols=\"12\">\n        <v-card>\n          <v-card-text>\n            <p class=\"text-body-medium mb-4\">\n              Press the keyboard shortcuts below to trigger actions:\n            </p>\n\n            <v-table>\n              <thead>\n                <tr>\n                  <th>Hotkey</th>\n                  <th>Action</th>\n                  <th>Description</th>\n                </tr>\n              </thead>\n              <tbody>\n                <tr>\n                  <td><v-hotkey keys=\"cmd+s\"></v-hotkey></td>\n                  <td>Save Document</td>\n                  <td>Cross-platform save shortcut</td>\n                </tr>\n                <tr>\n                  <td><v-hotkey keys=\"ctrl+z\"></v-hotkey></td>\n                  <td>Undo Action</td>\n                  <td>Standard undo shortcut</td>\n                </tr>\n              </tbody>\n            </v-table>\n\n            <v-divider class=\"my-4\"></v-divider>\n\n            <div class=\"activity-log pa-3 border rounded\">\n              <h4 class=\"text-body-large mt-0 mb-2\">Activity Log:</h4>\n              <div v-if=\"messages.length === 0\" class=\"text-grey\">\n                No hotkeys triggered yet...\n              </div>\n              <div v-for=\"message in messages\" :key=\"message.id\" class=\"text-body-medium mb-1\">\n                <span class=\"text-grey text-body-small\">{{ message.time }}</span> - {{ message.text }}\n              </div>\n              <v-btn v-if=\"messages.length > 0\" class=\"mt-2\" size=\"small\" @click=\"clearMessages\">\n                Clear Log\n              </v-btn>\n            </div>\n          </v-card-text>\n        </v-card>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n  import { useHotkey } from 'vuetify'\n\n  const messages = ref([])\n\n  const addMessage = text => {\n    messages.value.push({\n      id: Date.now(),\n      text,\n      time: new Date().toLocaleTimeString(),\n    })\n\n    if (messages.value.length > 5) {\n      messages.value = messages.value.slice(-5)\n    }\n  }\n\n  const clearMessages = () => {\n    messages.value = []\n  }\n\n  useHotkey('cmd+s', () => {\n    addMessage('💾 Document saved!')\n  })\n\n  useHotkey('ctrl+z', () => {\n    addMessage('↶ Action undone!')\n  })\n</script>\n\n<script>\n  import { useHotkey } from 'vuetify'\n\n  export default {\n    data () {\n      return {\n        messages: [],\n      }\n    },\n    mounted () {\n      // Register basic hotkeys\n      this.cleanupSave = useHotkey('cmd+s', () => {\n        this.addMessage('💾 Document saved!')\n      })\n\n      this.cleanupUndo = useHotkey('ctrl+z', () => {\n        this.addMessage('↶ Action undone!')\n      })\n    },\n    beforeUnmount () {\n      // Clean up hotkeys\n      this.cleanupSave?.()\n      this.cleanupUndo?.()\n    },\n    methods: {\n      addMessage (text) {\n        this.messages.push({\n          id: Date.now(),\n          text,\n          time: new Date().toLocaleTimeString(),\n        })\n\n        // Keep only last 5 messages\n        if (this.messages.length > 5) {\n          this.messages = this.messages.slice(-5)\n        }\n      },\n      clearMessages () {\n        this.messages = []\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/hotkey/options.vue",
    "content": "<template>\n  <v-container>\n    <v-row>\n      <v-col cols=\"12\">\n        <v-card>\n          <v-card-text>\n            <p class=\"text-body-medium mb-4\">\n              Customize hotkey behavior with various options.\n              Change the settings below and test the hotkeys:\n            </p>\n\n            <v-row>\n              <v-col cols=\"12\" md=\"6\">\n                <h4 class=\"text-body-large mt-0 mb-3\">Options Configuration</h4>\n\n                <v-select\n                  v-model=\"eventType\"\n                  :items=\"['keydown', 'keyup']\"\n                  class=\"mb-3\"\n                  hint=\"When to trigger the hotkey\"\n                  label=\"Event Type\"\n                  persistent-hint\n                ></v-select>\n\n                <v-switch\n                  v-model=\"allowInInputs\"\n                  class=\"mb-3\"\n                  color=\"primary\"\n                  label=\"Allow hotkeys in input fields\"\n                  hide-details\n                ></v-switch>\n\n                <v-switch\n                  v-model=\"preventDefault\"\n                  class=\"mb-3\"\n                  color=\"primary\"\n                  label=\"Prevent default browser behavior\"\n                  hide-details\n                ></v-switch>\n\n                <v-slider\n                  v-model=\"sequenceTimeout\"\n                  :label=\"`Sequence Timeout (${sequenceTimeout}ms)`\"\n                  class=\"mb-3\"\n                  max=\"3000\"\n                  min=\"500\"\n                  step=\"100\"\n                  hide-details\n                  thumb-label\n                ></v-slider>\n              </v-col>\n\n              <v-col cols=\"12\" md=\"6\">\n                <h4 class=\"text-body-large mt-0 mb-3\">Test Hotkeys</h4>\n                <v-table density=\"compact\">\n                  <thead>\n                    <tr>\n                      <th>Hotkey</th>\n                      <th>Action</th>\n                      <th>Settings</th>\n                    </tr>\n                  </thead>\n                  <tbody>\n                    <tr>\n                      <td><v-hotkey keys=\"cmd+j\"></v-hotkey></td>\n                      <td>Test Basic Hotkey</td>\n                      <td>Event: {{ eventType }}</td>\n                    </tr>\n                    <tr>\n                      <td><v-hotkey keys=\"ctrl+x-e\"></v-hotkey></td>\n                      <td>Test Sequence</td>\n                      <td>Timeout: {{ sequenceTimeout }}ms</td>\n                    </tr>\n                    <tr>\n                      <td><v-hotkey keys=\"enter\"></v-hotkey></td>\n                      <td>Test in Input</td>\n                      <td>{{ allowInInputs ? 'Enabled in inputs' : 'Disabled in inputs' }}</td>\n                    </tr>\n                  </tbody>\n                </v-table>\n\n                <v-text-field\n                  v-model=\"testInput\"\n                  :hint=\"allowInInputs ? 'Try pressing Enter or Cmd+J while focused here' : 'Hotkeys disabled in inputs - try pressing them outside this field'\"\n                  class=\"mt-4\"\n                  label=\"Test Input Field\"\n                  persistent-hint\n                ></v-text-field>\n              </v-col>\n            </v-row>\n\n            <v-divider class=\"my-4\"></v-divider>\n\n            <h4 class=\"text-body-large mt-0 mb-3\">Current Configuration</h4>\n            <v-table density=\"compact\">\n              <thead>\n                <tr>\n                  <th>Option</th>\n                  <th>Value</th>\n                  <th>Description</th>\n                </tr>\n              </thead>\n              <tbody>\n                <tr>\n                  <td><code>event</code></td>\n                  <td><v-chip size=\"small\">{{ eventType }}</v-chip></td>\n                  <td>When to trigger the hotkey callback</td>\n                </tr>\n                <tr>\n                  <td><code>inputs</code></td>\n                  <td><v-chip :color=\"allowInInputs ? 'success' : 'error'\" size=\"small\">\n                    {{ allowInInputs }}\n                  </v-chip></td>\n                  <td>Allow hotkeys when input elements are focused</td>\n                </tr>\n                <tr>\n                  <td><code>preventDefault</code></td>\n                  <td><v-chip :color=\"preventDefault ? 'success' : 'error'\" size=\"small\">\n                    {{ preventDefault }}\n                  </v-chip></td>\n                  <td>Prevent default browser behavior</td>\n                </tr>\n                <tr>\n                  <td><code>sequenceTimeout</code></td>\n                  <td><v-chip size=\"small\">{{ sequenceTimeout }}ms</v-chip></td>\n                  <td>Time limit for completing key sequences</td>\n                </tr>\n              </tbody>\n            </v-table>\n\n            <v-divider class=\"my-4\"></v-divider>\n\n            <div class=\"activity-log pa-3 border rounded\">\n              <h4 class=\"text-body-large mt-0 mb-2\">Activity Log:</h4>\n              <div v-if=\"messages.length === 0\" class=\"text-grey\">\n                No hotkeys with options triggered yet...\n              </div>\n              <div v-for=\"message in messages\" :key=\"message.id\" class=\"text-body-medium mb-1\">\n                <span class=\"text-grey text-body-small\">{{ message.time }}</span> - {{ message.text }}\n              </div>\n              <v-btn v-if=\"messages.length > 0\" class=\"mt-2\" size=\"small\" @click=\"clearMessages\">\n                Clear Log\n              </v-btn>\n            </div>\n          </v-card-text>\n        </v-card>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { onBeforeUnmount, ref, watch } from 'vue'\n  import { useHotkey } from 'vuetify'\n\n  const messages = ref([])\n  const testInput = ref('')\n  const eventType = ref('keydown')\n  const allowInInputs = ref(true)\n  const preventDefault = ref(true)\n  const sequenceTimeout = ref(2000)\n  const cleanupFunctions = ref([])\n\n  const addMessage = text => {\n    messages.value.push({\n      id: Date.now(),\n      text,\n      time: new Date().toLocaleTimeString(),\n    })\n\n    if (messages.value.length > 10) {\n      messages.value = messages.value.slice(-10)\n    }\n  }\n\n  const clearMessages = () => {\n    messages.value = []\n  }\n\n  const setupHotkeys = () => {\n    cleanupFunctions.value.forEach(cleanup => cleanup())\n    cleanupFunctions.value = []\n\n    const options = {\n      event: eventType.value,\n      inputs: allowInInputs.value,\n      preventDefault: preventDefault.value,\n      sequenceTimeout: sequenceTimeout.value,\n    }\n\n    cleanupFunctions.value.push(\n      useHotkey('cmd+j', event => {\n        const target = event.target?.tagName || 'unknown'\n        addMessage(`🔧 Test hotkey (${eventType.value}) - Target: ${target}`)\n      }, options)\n    )\n    cleanupFunctions.value.push(\n      useHotkey('ctrl+x-e', () => {\n        addMessage(`⏱️ Sequence completed within ${sequenceTimeout.value}ms`)\n      }, options)\n    )\n\n    cleanupFunctions.value.push(\n      useHotkey('enter', event => {\n        const inInput = event.target?.tagName === 'INPUT' || event.target?.tagName === 'TEXTAREA'\n        addMessage(`⏎ Enter pressed ${inInput ? 'in input field' : 'outside input'}`)\n      }, options)\n    )\n  }\n\n  setupHotkeys()\n\n  // Watch all hotkey options and re-setup hotkeys automatically\n  watch([\n    eventType,\n    allowInInputs,\n    preventDefault,\n    sequenceTimeout,\n  ], setupHotkeys)\n\n  onBeforeUnmount(() => {\n    cleanupFunctions.value.forEach(cleanup => cleanup())\n  })\n</script>\n\n<script>\n  import { useHotkey } from 'vuetify'\n\n  export default {\n    data () {\n      return {\n        messages: [],\n        testInput: '',\n        eventType: 'keydown',\n        allowInInputs: true,\n        preventDefault: true,\n        sequenceTimeout: 1000,\n        cleanupFunctions: [],\n      }\n    },\n    mounted () {\n      this.setupHotkeys()\n    },\n    beforeUnmount () {\n      this.cleanupFunctions.forEach(cleanup => cleanup())\n    },\n    methods: {\n      addMessage (text) {\n        this.messages.push({\n          id: Date.now(),\n          text,\n          time: new Date().toLocaleTimeString(),\n        })\n\n        if (this.messages.length > 10) {\n          this.messages = this.messages.slice(-10)\n        }\n      },\n      clearMessages () {\n        this.messages = []\n      },\n      setupHotkeys () {\n        this.cleanupFunctions.forEach(cleanup => cleanup())\n        this.cleanupFunctions = []\n\n        const options = {\n          event: this.eventType,\n          inputs: this.allowInInputs,\n          preventDefault: this.preventDefault,\n          sequenceTimeout: this.sequenceTimeout,\n        }\n\n        this.cleanupFunctions.push(\n          useHotkey('cmd+j', event => {\n            const target = event.target?.tagName || 'unknown'\n            this.addMessage(`🔧 Test hotkey (${this.eventType}) - Target: ${target}`)\n          }, options)\n        )\n\n        this.cleanupFunctions.push(\n          useHotkey('ctrl+x-e', () => {\n            this.addMessage(`⏱️ Sequence completed within ${this.sequenceTimeout}ms`)\n          }, options)\n        )\n\n        this.cleanupFunctions.push(\n          useHotkey('enter', event => {\n            const inInput = event.target?.tagName === 'INPUT' || event.target?.tagName === 'TEXTAREA'\n            this.addMessage(`⏎ Enter pressed ${inInput ? 'in input field' : 'outside input'}`)\n          }, options)\n        )\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/hotkey/platform.vue",
    "content": "<template>\n  <v-container>\n    <v-row>\n      <v-col cols=\"12\">\n        <v-card>\n          <v-card-text>\n            <v-alert class=\"mb-4\" color=\"info\" variant=\"tonal\">\n              <v-alert-title>Current Platform: {{ platformName }}</v-alert-title>\n              The useHotkey composable automatically adapts to your platform.\n            </v-alert>\n\n            <p class=\"text-body-medium mb-4\">\n              Try the hotkeys below to see how they adapt to your platform:\n            </p>\n\n            <v-row>\n              <v-col cols=\"12\">\n                <h4 class=\"text-body-large mt-0 mb-3\">Available Hotkeys</h4>\n                <v-table>\n                  <thead>\n                    <tr>\n                      <th>Hotkey</th>\n                      <th>Action</th>\n                      <th>Platform Behavior</th>\n                    </tr>\n                  </thead>\n                  <tbody>\n                    <tr>\n                      <td><v-hotkey keys=\"cmd+c\"></v-hotkey></td>\n                      <td>Copy</td>\n                      <td>{{ isMac ? '⌘ on Mac' : 'Ctrl on PC' }}</td>\n                    </tr>\n                    <tr>\n                      <td><v-hotkey keys=\"cmd+v\"></v-hotkey></td>\n                      <td>Paste</td>\n                      <td>{{ isMac ? '⌘ on Mac' : 'Ctrl on PC' }}</td>\n                    </tr>\n                    <tr>\n                      <td><v-hotkey keys=\"cmd+shift+z\"></v-hotkey></td>\n                      <td>Redo</td>\n                      <td>{{ isMac ? '⌘⇧ on Mac' : 'Ctrl+Shift on PC' }}</td>\n                    </tr>\n                    <tr>\n                      <td><v-hotkey keys=\"ctrl+a\"></v-hotkey></td>\n                      <td>Select All (Explicit Ctrl)</td>\n                      <td>Always Ctrl, even on Mac</td>\n                    </tr>\n                    <tr>\n                      <td><v-hotkey keys=\"meta+f\"></v-hotkey></td>\n                      <td>Find in Page</td>\n                      <td>{{ isMac ? 'Cmd on Mac' : 'Ctrl key on PC' }}</td>\n                    </tr>\n                  </tbody>\n                </v-table>\n              </v-col>\n            </v-row>\n\n            <v-divider class=\"my-4\"></v-divider>\n\n            <div class=\"activity-log pa-3 border rounded\">\n              <h4 class=\"text-body-large mt-0 mb-2\">Activity Log:</h4>\n              <div v-if=\"messages.length === 0\" class=\"text-grey\">\n                No platform-aware hotkeys triggered yet...\n              </div>\n              <div v-for=\"message in messages\" :key=\"message.id\" class=\"text-body-medium mb-1\">\n                <span class=\"text-grey text-body-small\">{{ message.time }}</span> - {{ message.text }}\n              </div>\n              <v-btn v-if=\"messages.length > 0\" class=\"mt-2\" size=\"small\" @click=\"clearMessages\">\n                Clear Log\n              </v-btn>\n            </div>\n\n            <v-divider class=\"my-4\"></v-divider>\n\n            <h4 class=\"text-body-large mt-0 mb-3\">Platform Detection Details</h4>\n            <v-table density=\"compact\">\n              <thead>\n                <tr>\n                  <th>Property</th>\n                  <th>Value</th>\n                </tr>\n              </thead>\n              <tbody>\n                <tr>\n                  <td>Platform Detected</td>\n                  <td>{{ platformName }}</td>\n                </tr>\n                <tr>\n                  <td>User Agent</td>\n                  <td class=\"text-truncate\" style=\"max-width: 200px;\">{{ userAgent }}</td>\n                </tr>\n                <tr>\n                  <td>cmd maps to</td>\n                  <td>{{ isMac ? 'Meta key (⌘)' : 'Control key (Ctrl)' }}</td>\n                </tr>\n              </tbody>\n            </v-table>\n          </v-card-text>\n        </v-card>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { computed, ref } from 'vue'\n  import { useHotkey } from 'vuetify'\n\n  const messages = ref([])\n\n  const isMac = computed(() => {\n    return typeof navigator !== 'undefined' && /macintosh/i.test(navigator.userAgent)\n  })\n\n  const platformName = computed(() => {\n    return isMac.value ? 'macOS' : 'Windows/Linux'\n  })\n\n  const userAgent = computed(() => {\n    return typeof navigator !== 'undefined' ? navigator.userAgent : 'Unknown'\n  })\n\n  const addMessage = text => {\n    messages.value.push({\n      id: Date.now(),\n      text,\n      time: new Date().toLocaleTimeString(),\n    })\n\n    if (messages.value.length > 6) {\n      messages.value = messages.value.slice(-6)\n    }\n  }\n\n  const clearMessages = () => {\n    messages.value = []\n  }\n\n  useHotkey('cmd+c', () => {\n    addMessage(`📋 Copy action (${isMac.value ? 'Cmd' : 'Ctrl'}+C)`)\n  })\n\n  useHotkey('cmd+v', () => {\n    addMessage(`📄 Paste action (${isMac.value ? 'Cmd' : 'Ctrl'}+V)`)\n  })\n\n  useHotkey('cmd+shift+z', () => {\n    addMessage(`↷ Redo action (${isMac.value ? 'Cmd+Shift' : 'Ctrl+Shift'}+Z)`)\n  })\n\n  useHotkey('ctrl+a', () => {\n    addMessage('🔘 Select All (explicit Ctrl+A)')\n  })\n\n  useHotkey('meta+f', () => {\n    addMessage(`🔍 Find in Page (${isMac.value ? 'Cmd' : 'Win'}+F)`)\n  })\n</script>\n\n<script>\n  import { useHotkey } from 'vuetify'\n\n  export default {\n    data () {\n      return {\n        messages: [],\n      }\n    },\n    computed: {\n      isMac () {\n        return typeof navigator !== 'undefined' && /macintosh/i.test(navigator.userAgent)\n      },\n      platformName () {\n        return this.isMac ? 'macOS' : 'Windows/Linux'\n      },\n      userAgent () {\n        return typeof navigator !== 'undefined' ? navigator.userAgent : 'Unknown'\n      },\n    },\n    mounted () {\n      this.cleanupCopy = useHotkey('cmd+c', () => {\n        this.addMessage(`📋 Copy action (${this.isMac ? 'Cmd' : 'Ctrl'}+C)`)\n      })\n\n      this.cleanupPaste = useHotkey('cmd+v', () => {\n        this.addMessage(`📄 Paste action (${this.isMac ? 'Cmd' : 'Ctrl'}+V)`)\n      })\n\n      this.cleanupRedo = useHotkey('cmd+shift+z', () => {\n        this.addMessage(`↷ Redo action (${this.isMac ? 'Cmd+Shift' : 'Ctrl+Shift'}+Z)`)\n      })\n\n      this.cleanupSelectAll = useHotkey('ctrl+a', () => {\n        this.addMessage('🔘 Select All (explicit Ctrl+A)')\n      })\n\n      this.cleanupFind = useHotkey('meta+f', () => {\n        this.addMessage(`🔍 Find in Page (${this.isMac ? 'Cmd' : 'Win'}+F)`)\n      })\n    },\n    beforeUnmount () {\n      this.cleanupCopy?.()\n      this.cleanupPaste?.()\n      this.cleanupRedo?.()\n      this.cleanupSelectAll?.()\n      this.cleanupFind?.()\n    },\n    methods: {\n      addMessage (text) {\n        this.messages.push({\n          id: Date.now(),\n          text,\n          time: new Date().toLocaleTimeString(),\n        })\n\n        if (this.messages.length > 6) {\n          this.messages = this.messages.slice(-6)\n        }\n      },\n      clearMessages () {\n        this.messages = []\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/hotkey/reactive.vue",
    "content": "<template>\n  <v-container>\n    <v-row>\n      <v-col cols=\"12\">\n        <v-card>\n          <v-card-text>\n            <p class=\"text-body-medium mb-4\">\n              Hotkey combinations can be reactive, allowing you to change them dynamically.\n              Try changing the hotkey combinations below:\n            </p>\n\n            <v-row>\n              <v-col cols=\"12\" md=\"6\">\n                <v-text-field\n                  v-model=\"saveHotkey\"\n                  class=\"mb-3\"\n                  hint=\"e.g., cmd+s, ctrl+shift+s\"\n                  label=\"Save Hotkey\"\n                  persistent-hint\n                ></v-text-field>\n\n                <v-text-field\n                  v-model=\"undoHotkey\"\n                  class=\"mb-3\"\n                  hint=\"e.g., cmd+z, ctrl+z\"\n                  label=\"Undo Hotkey\"\n                  persistent-hint\n                ></v-text-field>\n\n                <v-text-field\n                  v-model=\"customHotkey\"\n                  class=\"mb-3\"\n                  hint=\"e.g., alt+shift+x, f5\"\n                  label=\"Custom Action Hotkey\"\n                  persistent-hint\n                ></v-text-field>\n\n                <v-switch\n                  v-model=\"hotkeyEnabled\"\n                  class=\"mb-3\"\n                  label=\"Enable hotkeys\"\n                ></v-switch>\n              </v-col>\n\n              <v-col cols=\"12\" md=\"6\">\n                <h4 class=\"text-body-large mt-0 mb-3\">Current Active Hotkeys</h4>\n                <v-table density=\"compact\">\n                  <thead>\n                    <tr>\n                      <th>Hotkey</th>\n                      <th>Action</th>\n                      <th>Status</th>\n                    </tr>\n                  </thead>\n                  <tbody>\n                    <tr>\n                      <td><v-hotkey :keys=\"saveHotkey\"></v-hotkey></td>\n                      <td>Save Document</td>\n                      <td>\n                        <v-chip :color=\"hotkeyEnabled ? 'success' : 'grey'\" size=\"small\">\n                          {{ hotkeyEnabled ? 'Active' : 'Disabled' }}\n                        </v-chip>\n                      </td>\n                    </tr>\n                    <tr>\n                      <td><v-hotkey :keys=\"undoHotkey\"></v-hotkey></td>\n                      <td>Undo Action</td>\n                      <td>\n                        <v-chip :color=\"hotkeyEnabled ? 'success' : 'grey'\" size=\"small\">\n                          {{ hotkeyEnabled ? 'Active' : 'Disabled' }}\n                        </v-chip>\n                      </td>\n                    </tr>\n                    <tr>\n                      <td><v-hotkey :keys=\"customHotkey\"></v-hotkey></td>\n                      <td>Custom Action</td>\n                      <td>\n                        <v-chip :color=\"hotkeyEnabled ? 'success' : 'grey'\" size=\"small\">\n                          {{ hotkeyEnabled ? 'Active' : 'Disabled' }}\n                        </v-chip>\n                      </td>\n                    </tr>\n                  </tbody>\n                </v-table>\n\n                <v-btn class=\"mt-3\" @click=\"resetToDefaults\">\n                  Reset to Defaults\n                </v-btn>\n              </v-col>\n            </v-row>\n\n            <v-divider class=\"my-4\"></v-divider>\n\n            <div class=\"activity-log pa-3 border rounded\">\n              <h4 class=\"text-body-large mt-0 mb-2\">Activity Log:</h4>\n              <div v-if=\"messages.length === 0\" class=\"text-grey\">\n                No reactive hotkeys triggered yet...\n              </div>\n              <div v-for=\"message in messages\" :key=\"message.id\" class=\"text-body-medium mb-1\">\n                <span class=\"text-grey text-body-small\">{{ message.time }}</span> - {{ message.text }}\n              </div>\n              <v-btn v-if=\"messages.length > 0\" class=\"mt-2\" size=\"small\" @click=\"clearMessages\">\n                Clear Log\n              </v-btn>\n            </div>\n          </v-card-text>\n        </v-card>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { computed, ref, watch } from 'vue'\n  import { useHotkey } from 'vuetify'\n\n  const messages = ref([])\n  const saveHotkey = ref('cmd+s')\n  const undoHotkey = ref('cmd+z')\n  const customHotkey = ref('alt+shift+x')\n  const hotkeyEnabled = ref(true)\n\n  const activeSaveHotkey = computed(() => hotkeyEnabled.value ? saveHotkey.value : undefined)\n  const activeUndoHotkey = computed(() => hotkeyEnabled.value ? undoHotkey.value : undefined)\n  const activeCustomHotkey = computed(() => hotkeyEnabled.value ? customHotkey.value : undefined)\n\n  const addMessage = text => {\n    messages.value.push({\n      id: Date.now(),\n      text,\n      time: new Date().toLocaleTimeString(),\n    })\n\n    if (messages.value.length > 8) {\n      messages.value = messages.value.slice(-8)\n    }\n  }\n\n  const clearMessages = () => {\n    messages.value = []\n  }\n\n  const resetToDefaults = () => {\n    saveHotkey.value = 'cmd+s'\n    undoHotkey.value = 'cmd+z'\n    customHotkey.value = 'alt+shift+x'\n    hotkeyEnabled.value = true\n    addMessage('🔄 Reset hotkeys to defaults')\n  }\n\n  useHotkey(activeSaveHotkey, () => {\n    addMessage(`💾 Save triggered with: ${saveHotkey.value}`)\n  })\n\n  useHotkey(activeUndoHotkey, () => {\n    addMessage(`↶ Undo triggered with: ${undoHotkey.value}`)\n  })\n\n  useHotkey(activeCustomHotkey, () => {\n    addMessage(`⚡ Custom action triggered with: ${customHotkey.value}`)\n  })\n\n  watch([saveHotkey, undoHotkey, customHotkey, hotkeyEnabled], () => {\n    if (hotkeyEnabled.value) {\n      addMessage('⚙️ Hotkey configuration updated')\n    } else {\n      addMessage('⏸️ Hotkeys disabled')\n    }\n  })\n</script>\n\n<script>\n  import { useHotkey } from 'vuetify'\n\n  export default {\n    data () {\n      return {\n        messages: [],\n        saveHotkey: 'cmd+s',\n        undoHotkey: 'cmd+z',\n        customHotkey: 'alt+shift+x',\n        hotkeyEnabled: true,\n        cleanupFunctions: [],\n      }\n    },\n    computed: {\n      activeSaveHotkey () {\n        return this.hotkeyEnabled ? this.saveHotkey : undefined\n      },\n      activeUndoHotkey () {\n        return this.hotkeyEnabled ? this.undoHotkey : undefined\n      },\n      activeCustomHotkey () {\n        return this.hotkeyEnabled ? this.customHotkey : undefined\n      },\n    },\n    watch: {\n      saveHotkey () { this.logConfigChange() },\n      undoHotkey () { this.logConfigChange() },\n      customHotkey () { this.logConfigChange() },\n      hotkeyEnabled () { this.logConfigChange() },\n    },\n    mounted () {\n      this.setupReactiveHotkeys()\n    },\n    beforeUnmount () {\n      this.cleanupFunctions.forEach(cleanup => cleanup())\n    },\n    methods: {\n      addMessage (text) {\n        this.messages.push({\n          id: Date.now(),\n          text,\n          time: new Date().toLocaleTimeString(),\n        })\n\n        if (this.messages.length > 8) {\n          this.messages = this.messages.slice(-8)\n        }\n      },\n      clearMessages () {\n        this.messages = []\n      },\n      resetToDefaults () {\n        this.saveHotkey = 'cmd+s'\n        this.undoHotkey = 'cmd+z'\n        this.customHotkey = 'alt+shift+x'\n        this.hotkeyEnabled = true\n        this.addMessage('🔄 Reset hotkeys to defaults')\n      },\n      setupReactiveHotkeys () {\n        this.cleanupFunctions.forEach(cleanup => cleanup())\n        this.cleanupFunctions = []\n\n        this.cleanupFunctions.push(\n          useHotkey(() => this.activeSaveHotkey, () => {\n            this.addMessage(`💾 Save triggered with: ${this.saveHotkey}`)\n          })\n        )\n\n        this.cleanupFunctions.push(\n          useHotkey(() => this.activeUndoHotkey, () => {\n            this.addMessage(`↶ Undo triggered with: ${this.undoHotkey}`)\n          })\n        )\n\n        this.cleanupFunctions.push(\n          useHotkey(() => this.activeCustomHotkey, () => {\n            this.addMessage(`⚡ Custom action triggered with: ${this.customHotkey}`)\n          })\n        )\n      },\n      logConfigChange () {\n        if (this.hotkeyEnabled) {\n          this.addMessage('⚙️ Hotkey configuration updated')\n        } else {\n          this.addMessage('⏸️ Hotkeys disabled')\n        }\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/hotkey/sequences.vue",
    "content": "<template>\n  <v-container>\n    <v-row>\n      <v-col cols=\"12\">\n        <v-card>\n          <v-card-text>\n            <p class=\"text-body-medium mb-4\">\n              Key sequences require pressing keys in order within the timeout period.\n              Try the sequences below:\n            </p>\n\n            <v-table>\n              <thead>\n                <tr>\n                  <th>Hotkey</th>\n                  <th>Action</th>\n                  <th>Description</th>\n                </tr>\n              </thead>\n              <tbody>\n                <tr>\n                  <td><v-hotkey keys=\"ctrl+x-p\"></v-hotkey></td>\n                  <td>Command Palette</td>\n                  <td>Press Ctrl+X, then P (within timeout)</td>\n                </tr>\n                <tr>\n                  <td><v-hotkey keys=\"g-g\"></v-hotkey></td>\n                  <td>Go to Top</td>\n                  <td>Press G, then G (Vim-style navigation)</td>\n                </tr>\n                <tr>\n                  <td><v-hotkey keys=\"ctrl+x-ctrl+s\"></v-hotkey></td>\n                  <td>Save File</td>\n                  <td>Press Ctrl+X, then Ctrl+S (Emacs-style)</td>\n                </tr>\n              </tbody>\n            </v-table>\n\n            <v-alert class=\"my-4\" color=\"info\" variant=\"tonal\">\n              <v-alert-title>Sequence Timeout</v-alert-title>\n              You have {{ sequenceTimeout }}ms to complete each sequence.\n              If you wait too long, the sequence will reset.\n            </v-alert>\n\n            <v-slider\n              v-model=\"sequenceTimeout\"\n              :label=\"`Sequence Timeout (${sequenceTimeout}ms)`\"\n              class=\"mb-4\"\n              max=\"3000\"\n              min=\"500\"\n              step=\"100\"\n              thumb-label\n              @update:model-value=\"updateTimeout\"\n            >\n            </v-slider>\n\n            <v-divider class=\"my-4\"></v-divider>\n\n            <div class=\"activity-log pa-3 border rounded\">\n              <h4 class=\"text-body-large mt-0 mb-2\">Activity Log:</h4>\n              <div v-if=\"messages.length === 0\" class=\"text-grey\">\n                No sequences triggered yet...\n              </div>\n              <div v-for=\"message in messages\" :key=\"message.id\" class=\"text-body-medium mb-1\">\n                <span class=\"text-grey text-body-small\">{{ message.time }}</span> - {{ message.text }}\n              </div>\n              <v-btn v-if=\"messages.length > 0\" class=\"mt-2\" size=\"small\" @click=\"clearMessages\">\n                Clear Log\n              </v-btn>\n            </div>\n          </v-card-text>\n        </v-card>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { onBeforeUnmount, ref } from 'vue'\n  import { useHotkey } from 'vuetify'\n\n  const messages = ref([])\n  const sequenceTimeout = ref(2000)\n  const cleanupFunctions = ref([])\n\n  const addMessage = text => {\n    messages.value.push({\n      id: Date.now(),\n      text,\n      time: new Date().toLocaleTimeString(),\n    })\n\n    if (messages.value.length > 8) {\n      messages.value = messages.value.slice(-8)\n    }\n  }\n\n  const clearMessages = () => {\n    messages.value = []\n  }\n\n  const setupSequences = () => {\n    cleanupFunctions.value.forEach(cleanup => cleanup())\n    cleanupFunctions.value = []\n\n    cleanupFunctions.value.push(\n      useHotkey('ctrl+x-p', () => {\n        addMessage('🎨 Command Palette opened!')\n      }, { sequenceTimeout: sequenceTimeout.value })\n    )\n\n    cleanupFunctions.value.push(\n      useHotkey('g-g', () => {\n        addMessage('⬆️ Navigated to top!')\n      }, { sequenceTimeout: sequenceTimeout.value })\n    )\n\n    cleanupFunctions.value.push(\n      useHotkey('ctrl+x-ctrl+s', () => {\n        addMessage('💾 File saved (Emacs style)!')\n      }, { sequenceTimeout: sequenceTimeout.value })\n    )\n  }\n\n  const updateTimeout = () => {\n    setupSequences()\n  }\n\n  setupSequences()\n\n  onBeforeUnmount(() => {\n    cleanupFunctions.value.forEach(cleanup => cleanup())\n  })\n</script>\n\n<script>\n  import { useHotkey } from 'vuetify'\n\n  export default {\n    data () {\n      return {\n        messages: [],\n        sequenceTimeout: 2000,\n        cleanupFunctions: [],\n      }\n    },\n    mounted () {\n      this.setupSequences()\n    },\n    beforeUnmount () {\n      this.cleanupFunctions.forEach(cleanup => cleanup())\n    },\n    methods: {\n      addMessage (text) {\n        this.messages.push({\n          id: Date.now(),\n          text,\n          time: new Date().toLocaleTimeString(),\n        })\n\n        if (this.messages.length > 8) {\n          this.messages = this.messages.slice(-8)\n        }\n      },\n      clearMessages () {\n        this.messages = []\n      },\n      setupSequences () {\n        this.cleanupFunctions.forEach(cleanup => cleanup())\n        this.cleanupFunctions = []\n\n        this.cleanupFunctions.push(\n          useHotkey('ctrl+x-p', () => {\n            this.addMessage('🎨 Command Palette opened!')\n          }, { sequenceTimeout: this.sequenceTimeout })\n        )\n\n        this.cleanupFunctions.push(\n          useHotkey('g-g', () => {\n            this.addMessage('⬆️ Navigated to top!')\n          }, { sequenceTimeout: this.sequenceTimeout })\n        )\n\n        this.cleanupFunctions.push(\n          useHotkey('ctrl+x-ctrl+s', () => {\n            this.addMessage('💾 File saved (Emacs style)!')\n          }, { sequenceTimeout: this.sequenceTimeout })\n        )\n      },\n      updateTimeout () {\n        this.setupSequences()\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/hotkey/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n    :script=\"script\"\n  >\n    <v-card class=\"my-n9\" title=\"Activity log\" border flat>\n      <v-divider></v-divider>\n      <template v-slot:text>\n        <v-text-field v-model=\"keys\" label=\"Hotkey command\" variant=\"outlined\"></v-text-field>\n\n        <v-sheet\n          class=\"pa-2 d-flex flex-column ga-2 overflow-y-auto\"\n          color=\"surface-light\"\n          height=\"212\"\n          rounded\n        >\n          <v-empty-state v-if=\"!logs.length\" icon=\"mdi-calendar\" text=\"No Events\"></v-empty-state>\n          <div\n            v-for=\"(log, i) in logs.slice().reverse()\"\n            :key=\"i\"\n            class=\"log-entry pa-2 border rounded\"\n          >\n            <span class=\"text-body-small text-grey\">{{ log.timestamp }}</span>\n            <span class=\"ml-2\">{{ log.message }}</span>\n          </div>\n        </v-sheet>\n      </template>\n\n      <template v-slot:actions>\n        <span class=\"ps-2\">Current hotkey:</span> <v-hotkey :keys></v-hotkey>\n\n        <v-spacer></v-spacer>\n\n        <v-btn size=\"small\" text=\"Clear\" @click=\"logs = []\"></v-btn>\n      </template>\n    </v-card>\n\n    <template v-slot:configuration>\n      <v-checkbox v-model=\"allowInputs\" label=\"Allow inputs\"></v-checkbox>\n      <div class=\"text-body-large mt-3\">Sequence Timeout <span class=\"text-body-small text-medium-emphasis\">({{ sequenceTimeout }}ms)</span></div>\n      <v-slider\n        v-model=\"sequenceTimeout\"\n        max=\"3000\"\n        min=\"500\"\n        step=\"100\"\n      ></v-slider>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  // Utilities\n  import { useHotkey } from 'vuetify'\n\n  const name = 'hotkey'\n  const model = ref('default')\n  const options = []\n  const logs = ref([])\n  const keys = shallowRef('cmd+b')\n  const binding = shallowRef(false)\n  const allowInputs = shallowRef(false)\n  const sequenceTimeout = shallowRef(2000)\n\n  const and = computed(() => sequenceTimeout.value && allowInputs.value ? '\\n  ' : '')\n\n  const args = computed(() => {\n    return sequenceTimeout.value || allowInputs.value ? `, {\n  ${sequenceTimeout.value > 0 ? `sequenceTimeout: ${sequenceTimeout.value},` : ''}${allowInputs.value ? `${and.value}inputs: true,` : ''}\n}` : ''\n  })\n\n  const code = toRef(() => `<span>Current hotkey:</span>\n<v-hotkey keys=\"${keys.value}\" />\n<pre>log: {{ log }}</pre>`)\n\n  const script = toRef(() => {\n    return `<script setup>\n  import { shallowRef } from 'vue'\n  import { useHotkey } from 'vuetify'\n\n  const log = shallowRef('')\n\n  function onHotkey () {\n    log.value += '\\\\n- Hotkey pressed'\n  }\n\n  useHotkey('${keys.value}', onHotkey${args.value})\n<\\\\/script>`.replace('\\\\/', '/')\n  })\n\n  let unwatch = useHotkey(keys.value, onHotkey)\n  let timeout = null\n\n  watch(keys, val => {\n    binding.value = true\n    clearTimeout(timeout)\n    timeout = setTimeout(() => {\n      unwatch?.()\n\n      unwatch = useHotkey(val, onHotkey)\n\n      binding.value = false\n      logs.value.push({\n        message: `⚙️ Hotkey updated`,\n        timestamp: new Date().toLocaleTimeString(),\n      })\n    }, 500)\n  })\n\n  function onHotkey () {\n    logs.value.push({\n      message: `⌨️ Hotkey pressed`,\n      timestamp: new Date().toLocaleTimeString(),\n    })\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/opacity/misc-hover.vue",
    "content": "<template>\n  <v-container>\n    <v-hover v-slot=\"{ props: hoverProps, isHovering }\">\n      <v-card\n        v-bind=\"hoverProps\"\n        :class=\"[\n          'mx-auto',\n          isHovering ? 'opacity-100' : 'opacity-50'\n        ]\"\n        color=\"secondary\"\n        height=\"128\"\n        width=\"256\"\n        flat\n      ></v-card>\n    </v-hover>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/opacity/misc-opacity.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"justify-space-around\">\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <div class=\"bg-primary opacity-100\" style=\"height: 64px; width: 64px;\"></div>\n          <div class=\"text-body-small\">opacity-100</div>\n        </div>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <div class=\"bg-primary opacity-80\" style=\"height: 64px; width: 64px;\"></div>\n          <div class=\"text-body-small\">opacity-80</div>\n        </div>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <div class=\"bg-primary opacity-60\" style=\"height: 64px; width: 64px;\"></div>\n          <div class=\"text-body-small\">opacity-60</div>\n        </div>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <div class=\"bg-primary opacity-40\" style=\"height: 64px; width: 64px;\"></div>\n          <div class=\"text-body-small\">opacity-40</div>\n        </div>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <div class=\"text-center\">\n          <div class=\"bg-primary opacity-20\" style=\"height: 64px; width: 64px;\"></div>\n          <div class=\"text-body-small\">opacity-20</div>\n        </div>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/overflow/overflow-x.vue",
    "content": "<template>\n  <div style=\"width: 300px\">\n    <h3 class=\"mt-0 mb-3\">Overflow Auto</h3>\n    <p class=\"overflow-x-auto bg-purple-lighten-5\">\n      QrLmmW69vMQDtCOg48jidqvvWD2FzDt7I7bBoDc98SRP5OwvOScVYbRzFdfp540eF5v1pjogYkyI8NXqu4wY8chgsXIV0LU7XQKWJ98wLaBSHWiBhvkEU1T3sd6KEFo53CLjVjIz8UvZajb8sbsu62xTsF9cRtFdwEvusq6zJHvedymDCUkY6qXHsuL6fOmHo4KKMurZuJZrK3plRPUaI8XVciz8dVq5CEUXjMrTcB76H1w90CnkRER3nYjs3suTa3223xs8aL97m0peQfjlvKbF8HcmQG5mHEitCn1QZnbMZUK3zE9AIjwcVXP7R9V4fw2A93cZD7wj333X6aaiHZdkkTPtst0u05KSob5c0ZuKQi4D3V395NfFKKr8cR27jmpB7dqK2GiWXeOQUFcjmFVwlHWSlH8ZdUoVJpXf1xL6CRUxwZP4EhBbqQZaJm26ijWII6LRxJ5eVU9Y7KKvQsUeX5BawtgeMWRmjeCwQadTLTQG8gLpi2DvGpMtPWCdqHgEglVSB1ZlDrjEEsXYrNx1IOY0053K3pWNaR1ezyz8kahRfNs3byaHcIQu9tWTrcMpBWhZ45DzLjVV1N8Zt96uLnNWK5DvbKW8GgMuwY7fHkZFz85MN4d2gL0j85HmXGx9oPTFRkPWsmMOHUvm5IhB7QqGSAwT1uL7HgBrNX9a1BAWrp9zV1IWAd1q65sKOOCxTZrXJDpxBxYE4rJAGU6pcri9mUf4g49ZiIAwfu9njtZyYimmImCa6TFhk2jQcSmFDHacExxqC2BfYATHFrKSy94dbw6uWT52nM7MSM9JDu4cs9cbfnaf6amt4hTUotCTONg604b8JKPI1sfd4CG36fBNcnErhpllfRlXkY1xFwmwZT7IJV8okPGNQdTKpdPJOBGw3LHMKojPJl1nPiQB5C9bdePFMNLejSXY5DDvO70ehOCJpBtKZY2quoFJJjGfXe8T4DuGYGmM6JYd5DNinWZuUWXGvfIlJRHgf8BQNQvtmEzqGXIeQZitiq9F\n    </p>\n    <h3 class=\"mt-0 mb-3\">Overflow Hidden</h3>\n    <p class=\"overflow-x-hidden bg-deep-purple-lighten-5\">\n      QrLmmW69vMQDtCOg48jidqvvWD2FzDt7I7bBoDc98SRP5OwvOScVYbRzFdfp540eF5v1pjogYkyI8NXqu4wY8chgsXIV0LU7XQKWJ98wLaBSHWiBhvkEU1T3sd6KEFo53CLjVjIz8UvZajb8sbsu62xTsF9cRtFdwEvusq6zJHvedymDCUkY6qXHsuL6fOmHo4KKMurZuJZrK3plRPUaI8XVciz8dVq5CEUXjMrTcB76H1w90CnkRER3nYjs3suTa3223xs8aL97m0peQfjlvKbF8HcmQG5mHEitCn1QZnbMZUK3zE9AIjwcVXP7R9V4fw2A93cZD7wj333X6aaiHZdkkTPtst0u05KSob5c0ZuKQi4D3V395NfFKKr8cR27jmpB7dqK2GiWXeOQUFcjmFVwlHWSlH8ZdUoVJpXf1xL6CRUxwZP4EhBbqQZaJm26ijWII6LRxJ5eVU9Y7KKvQsUeX5BawtgeMWRmjeCwQadTLTQG8gLpi2DvGpMtPWCdqHgEglVSB1ZlDrjEEsXYrNx1IOY0053K3pWNaR1ezyz8kahRfNs3byaHcIQu9tWTrcMpBWhZ45DzLjVV1N8Zt96uLnNWK5DvbKW8GgMuwY7fHkZFz85MN4d2gL0j85HmXGx9oPTFRkPWsmMOHUvm5IhB7QqGSAwT1uL7HgBrNX9a1BAWrp9zV1IWAd1q65sKOOCxTZrXJDpxBxYE4rJAGU6pcri9mUf4g49ZiIAwfu9njtZyYimmImCa6TFhk2jQcSmFDHacExxqC2BfYATHFrKSy94dbw6uWT52nM7MSM9JDu4cs9cbfnaf6amt4hTUotCTONg604b8JKPI1sfd4CG36fBNcnErhpllfRlXkY1xFwmwZT7IJV8okPGNQdTKpdPJOBGw3LHMKojPJl1nPiQB5C9bdePFMNLejSXY5DDvO70ehOCJpBtKZY2quoFJJjGfXe8T4DuGYGmM6JYd5DNinWZuUWXGvfIlJRHgf8BQNQvtmEzqGXIeQZitiq9F\n    </p>\n    <h3 class=\"mt-0 mb-3\">Overflow visible</h3>\n    <p class=\"overflow-x-visible bg-indigo-lighten-5\">\n      QrLmmW69vMQDtCOg48jidqvvWD2FzDt7I7bBoDc98SRP5OwvOScVYbRzFdfp540eF5v1pjogYkyI8NXqu4wY8chgsXIV0LU7XQKWJ98wLaBSHWiBhvkEU1T3sd6KEFo53CLjVjIz8UvZajb8sbsu62xTsF9cRtFdwEvusq6zJHvedymDCUkY6qXHsuL6fOmHo4KKMurZuJZrK3plRPUaI8XVciz8dVq5CEUXjMrTcB76H1w90CnkRER3nYjs3suTa3223xs8aL97m0peQfjlvKbF8HcmQG5mHEitCn1QZnbMZUK3zE9AIjwcVXP7R9V4fw2A93cZD7wj333X6aaiHZdkkTPtst0u05KSob5c0ZuKQi4D3V395NfFKKr8cR27jmpB7dqK2GiWXeOQUFcjmFVwlHWSlH8ZdUoVJpXf1xL6CRUxwZP4EhBbqQZaJm26ijWII6LRxJ5eVU9Y7KKvQsUeX5BawtgeMWRmjeCwQadTLTQG8gLpi2DvGpMtPWCdqHgEglVSB1ZlDrjEEsXYrNx1IOY0053K3pWNaR1ezyz8kahRfNs3byaHcIQu9tWTrcMpBWhZ45DzLjVV1N8Zt96uLnNWK5DvbKW8GgMuwY7fHkZFz85MN4d2gL0j85HmXGx9oPTFRkPWsmMOHUvm5IhB7QqGSAwT1uL7HgBrNX9a1BAWrp9zV1IWAd1q65sKOOCxTZrXJDpxBxYE4rJAGU6pcri9mUf4g49ZiIAwfu9njtZyYimmImCa6TFhk2jQcSmFDHacExxqC2BfYATHFrKSy94dbw6uWT52nM7MSM9JDu4cs9cbfnaf6amt4hTUotCTONg604b8JKPI1sfd4CG36fBNcnErhpllfRlXkY1xFwmwZT7IJV8okPGNQdTKpdPJOBGw3LHMKojPJl1nPiQB5C9bdePFMNLejSXY5DDvO70ehOCJpBtKZY2quoFJJjGfXe8T4DuGYGmM6JYd5DNinWZuUWXGvfIlJRHgf8BQNQvtmEzqGXIeQZitiq9F\n    </p>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/overflow/overflow.vue",
    "content": "<template>\n  <v-row>\n    <v-col cols=\"auto\">\n      <v-card class=\"overflow-auto\" height=\"200\" width=\"200\">\n        <v-card-text>\n          <h3 class=\"my-0\">Overflow Auto</h3>\n          Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis\n          facilis dicta esse molestias vero hic laudantium provident nisi eos\n          quasi iusto alias sequi, aut aliquid voluptatibus commodi! Minima, eum\n          voluptates?\n        </v-card-text>\n      </v-card>\n    </v-col>\n\n    <v-col cols=\"auto\">\n      <v-card class=\"overflow-hidden\" height=\"200\" width=\"200\">\n        <v-card-text>\n          <h3 class=\"my-0\">Overflow Hidden</h3>\n          Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis\n          facilis dicta esse molestias vero hic laudantium provident nisi eos\n          quasi iusto alias sequi, aut aliquid voluptatibus commodi! Minima, eum\n          voluptates?\n        </v-card-text>\n      </v-card>\n    </v-col>\n\n    <v-col cols=\"auto\">\n      <v-card class=\"overflow-visible\" height=\"200\" width=\"200\">\n        <v-card-text>\n          <h3 class=\"my-0\">Overflow visible</h3>\n          Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis\n          facilis dicta esse molestias vero hic laudantium provident nisi eos\n          quasi iusto alias sequi, aut aliquid voluptatibus commodi! Minima, eum\n          voluptates?\n        </v-card-text>\n      </v-card>\n    </v-col>\n  </v-row>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/position/absolute.vue",
    "content": "<template>\n  <div class=\"text-body-small px-4 mb-2\">With static child</div>\n\n  <div class=\"bg-surface-variant pa-4 position-relative rounded-lg mx-2 mb-2\">\n    <div class=\"mb-2\">Relative parent</div>\n\n    <div class=\"bg-surface-light position-static pa-3\">\n      <div class=\"mb-2\">Static parent</div>\n\n      <div class=\"position-static bg-primary rounded-lg pa-3 d-inline-block me-2\">\n        Static child\n      </div>\n\n      <div class=\"position-static bg-blue rounded-lg pa-3 d-inline-block\">\n        Static sibling\n      </div>\n    </div>\n  </div>\n\n  <div class=\"text-body-small px-4 mb-2\">With absolute child</div>\n\n  <div class=\"bg-surface-variant pa-4 position-relative rounded-lg mx-2 mb-2\">\n    <div class=\"mb-2\">Relative parent</div>\n\n    <div class=\"bg-surface-light position-static pa-3\">\n      <div class=\"mb-3\">Static parent</div>\n\n      <div class=\"position-absolute top-0 right-0 bg-primary rounded-lg pa-3 d-inline-block\">\n        Absolute child\n      </div>\n\n      <div class=\"position-static bg-blue rounded-lg pa-3 d-inline-block\">\n        Static sibling\n      </div>\n    </div>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/position/fixed.vue",
    "content": "<template>\n  <div class=\"bg-surface-variant pa-4 position-relative rounded-lg ma-2\">\n    <div class=\"bg-surface-light position-relative py-3 ps-3\">\n      <!-- position-absolute used for demonstration purposes -->\n      <div class=\"position-absolute top-0 left-0 right-0 bg-primary pa-3 w-100\">\n        Fixed child\n      </div>\n\n      <div class=\"overflow-y-auto pe-3\" style=\"max-height: 250px\">\n        <div class=\"mt-12\">Relative parent</div>\n\n        <div\n          v-for=\"n in 10\"\n          :key=\"n\"\n          class=\"bg-info rounded-lg pa-3 mt-2\"\n        >\n          Static child\n        </div>\n      </div>\n    </div>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/position/relative.vue",
    "content": "<template>\n  <div class=\"bg-surface-variant pa-4 position-relative rounded-lg ma-2\">\n    <div class=\"bg-surface-light position-relative pa-3 pb-16\">\n      <div class=\"mb-2\">Relative parent</div>\n\n      <div class=\"position-absolute bottom-0 right-0 bg-primary rounded-lg pa-3\">\n        Absolute child\n      </div>\n    </div>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/position/static.vue",
    "content": "<template>\n  <div class=\"bg-surface-variant pa-4 position-relative rounded-lg ma-2\">\n    <div class=\"bg-surface-light position-static pa-3 pb-16\">\n      <div class=\"mb-2\">Static parent</div>\n\n      <div class=\"position-absolute bottom-0 right-0 bg-primary rounded-lg pa-3\">\n        Absolute child\n      </div>\n    </div>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/position/sticky.vue",
    "content": "<template>\n  <div class=\"bg-surface-variant pa-4 position-relative rounded-lg ma-2\">\n    <div class=\"bg-surface-light position-relative py-3 ps-3\">\n      <div class=\"overflow-y-auto pe-3\" style=\"max-height: 250px\">\n        <div>Relative parent</div>\n\n        <div\n          v-for=\"n in 5\"\n          :key=\"n\"\n        >\n          <div class=\"bg-primary position-sticky top-0 pa-3 mt-2\">\n            Sticky header {{ n }}\n          </div>\n\n          <div\n            v-for=\"k in 8\"\n            :key=\"k\"\n            class=\"bg-info rounded-lg pa-3 mt-2\"\n          >\n            Static child\n          </div>\n\n        </div>\n      </div>\n    </div>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/scroll/usage.vue",
    "content": "<template>\n  <v-sheet rounded=\"b\" border>\n    <v-container fluid>\n      <v-row>\n        <v-col cols=\"12\" md=\"6\">\n          <v-select\n            v-model=\"target\"\n            :items=\"targets\"\n            label=\"Target\"\n            prepend-inner-icon=\"mdi-bullseye\"\n            variant=\"outlined\"\n            hide-details\n          ></v-select>\n        </v-col>\n\n        <v-col cols=\"12\" md=\"6\">\n          <v-text-field\n            v-if=\"target === 'By Number'\"\n            v-model.number=\"number\"\n            label=\"Number\"\n            max=\"2000\"\n            min=\"0\"\n            prepend-inner-icon=\"mdi-numeric\"\n            step=\"1\"\n            type=\"number\"\n            variant=\"outlined\"\n            hide-details\n            @keydown.enter=\"onClick\"\n          ></v-text-field>\n\n          <v-select\n            v-else-if=\"target === 'By Query Selector'\"\n            v-model=\"query\"\n            :items=\"queries\"\n            label=\"Query Selector\"\n            prepend-inner-icon=\"mdi-format-header-1\"\n            variant=\"outlined\"\n            hide-details\n          ></v-select>\n\n          <v-select\n            v-else\n            v-model=\"component\"\n            :items=\"components\"\n            label=\"Component / Element\"\n            prepend-inner-icon=\"mdi-card-bulleted\"\n            variant=\"outlined\"\n            hide-details\n          ></v-select>\n        </v-col>\n\n        <v-col cols=\"12\" md=\"6\">\n          <v-select\n            v-model=\"easing\"\n            :items=\"easings\"\n            label=\"Easing\"\n            prepend-inner-icon=\"mdi-sine-wave\"\n            variant=\"outlined\"\n            hide-details\n          ></v-select>\n        </v-col>\n\n        <v-col cols=\"12\" md=\"6\">\n          <v-text-field\n            v-model.number=\"duration\"\n            label=\"Duration\"\n            max=\"2000\"\n            min=\"50\"\n            prepend-inner-icon=\"mdi-timer-sand\"\n            step=\"1\"\n            type=\"number\"\n            variant=\"outlined\"\n            hide-details\n          ></v-text-field>\n        </v-col>\n\n        <v-col cols=\"12\">\n          <v-slider\n            v-model=\"offset\"\n            append-icon=\"mdi-axis-arrow\"\n            label=\"Offset\"\n            max=\"100\"\n            min=\"-100\"\n            step=\"1\"\n            hide-details\n            thumb-label\n          ></v-slider>\n        </v-col>\n\n        <v-divider class=\"my-3 mx-n1\"></v-divider>\n\n        <v-col class=\"mt-n2\" cols=\"10\">\n          <v-btn\n            color=\"surface-variant\"\n            text=\"Go To\"\n            variant=\"flat\"\n            block\n            @click=\"onClick\"\n          ></v-btn>\n        </v-col>\n\n        <v-col class=\"mt-n2\" cols=\"2\">\n          <v-btn\n            color=\"error\"\n            text=\"Reset\"\n            variant=\"outlined\"\n            block\n            @click=\"onClickReset\"\n          ></v-btn>\n        </v-col>\n      </v-row>\n    </v-container>\n\n    <v-divider></v-divider>\n\n    <div\n      id=\"goto-container-example\"\n      class=\"overflow-auto\"\n      style=\"max-height: 400px;\"\n    >\n      <v-sheet\n        class=\"pa-4\"\n        color=\"surface-light\"\n      >\n        <div id=\"heading-1\" class=\"text-headline-small\">Heading 1</div>\n\n        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!</p>\n\n        <br>\n\n        <v-card\n          :ref=\"instance => cards.card1 = instance\"\n          text=\"Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem! Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!\"\n          title=\"Card 1\"\n          flat\n        ></v-card>\n\n        <div style=\"height: 420px;\"></div>\n\n        <div id=\"heading-2\" class=\"text-headline-small\">Heading 2</div>\n\n        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!</p>\n\n        <br>\n\n        <v-card\n          :ref=\"instance => cards.card2 = instance\"\n          text=\"Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem! Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!\"\n          title=\"Card 2\"\n          flat\n        ></v-card>\n\n        <div style=\"height: 420px;\"></div>\n\n        <div id=\"heading-3\" class=\"text-headline-small\">Heading 3</div>\n\n        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!</p>\n\n        <br>\n\n        <v-card\n          :ref=\"instance => cards.card3 = instance\"\n          text=\"Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem! Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!\"\n          title=\"Card 3\"\n          flat\n        ></v-card>\n\n        <div style=\"height: 420px;\"></div>\n\n        <div id=\"heading-4\" class=\"text-headline-small\">Heading 4</div>\n\n        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!</p>\n\n        <br>\n\n        <v-card\n          :ref=\"instance => cards.card4 = instance\"\n          text=\"Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem! Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!\"\n          title=\"Card 4\"\n          flat\n        ></v-card>\n\n        <div style=\"height: 180px;\"></div>\n\n        <v-btn\n          append-icon=\"mdi-arrow-up-bold\"\n          text=\"Back to Top\"\n          variant=\"tonal\"\n          @click=\"goTo(0, { container: '#goto-container-example' })\"\n        ></v-btn>\n      </v-sheet>\n    </div>\n  </v-sheet>\n</template>\n\n<script setup>\n  import { computed, ref } from 'vue'\n  import { useGoTo } from 'vuetify'\n\n  const goTo = useGoTo()\n\n  const duration = ref(300)\n  const number = ref(500)\n  const offset = ref(0)\n  const cards = {\n    card1: ref(null),\n    card2: ref(null),\n    card3: ref(null),\n    card4: ref(null),\n  }\n  const component = ref('card3')\n  const components = [\n    { title: 'Card 1', value: 'card1' },\n    { title: 'Card 2', value: 'card2' },\n    { title: 'Card 3', value: 'card3' },\n    { title: 'Card 4', value: 'card4' },\n  ]\n  const query = ref('#heading-3')\n  const queries = [\n    '#heading-1',\n    '#heading-2',\n    '#heading-3',\n    '#heading-4',\n  ]\n  const target = ref('By Number')\n  const targets = [\n    'By Number',\n    'By Query Selector',\n    'By Component / Element',\n  ]\n  const easing = ref('easeInOutCubic')\n  const easings = [\n    'linear',\n    'easeInQuad',\n    'easeOutQuad',\n    'easeInOutQuad',\n    'easeInCubic',\n    'easeOutCubic',\n    'easeInOutCubic',\n    'easeInQuart',\n    'easeOutQuart',\n    'easeInOutQuart',\n    'easeInQuint',\n    'easeOutQuint',\n    'easeInOutQuint',\n  ]\n\n  const options = computed(() => ({\n    container: '#goto-container-example',\n    duration: duration.value,\n    easing: easing.value,\n    offset: offset.value,\n  }))\n\n  function onClick () {\n    if (target.value === 'By Number') {\n      goTo(number.value, options.value)\n    } else if (target.value === 'By Query Selector') {\n      goTo(query.value, options.value)\n    } else if (target.value === 'By Component / Element') {\n      goTo(cards[component.value].$el, options.value)\n    }\n  }\n\n  function onClickReset () {\n    component.value = 'card3'\n    duration.value = 300\n    easing.value = 'easeInOutCubic'\n    number.value = 500\n    offset.value = 0\n    query.value = '#heading-3'\n    target.value = 'By Number'\n\n    goTo(0, { container: '#goto-container-example' })\n  }\n</script>\n\n<script>\n  import { useGoTo } from 'vuetify'\n\n  export default {\n    setup () {\n      const goTo = useGoTo()\n      return { goTo }\n    },\n    data () {\n      return {\n        duration: 300,\n        number: 500,\n        offset: 0,\n        cards: {\n          card1: null,\n          card2: null,\n          card3: null,\n          card4: null,\n        },\n        component: 'card3',\n        components: [\n          { title: 'Card 1', value: 'card1' },\n          { title: 'Card 2', value: 'card2' },\n          { title: 'Card 3', value: 'card3' },\n          { title: 'Card 4', value: 'card4' },\n        ],\n        query: '#heading-3',\n        queries: [\n          '#heading-1',\n          '#heading-2',\n          '#heading-3',\n          '#heading-4',\n        ],\n        target: 'By Number',\n        targets: [\n          'By Number',\n          'By Query Selector',\n          'By Component / Element',\n        ],\n        easing: 'easeInOutCubic',\n        easings: [\n          'linear',\n          'easeInQuad',\n          'easeOutQuad',\n          'easeInOutQuad',\n          'easeInCubic',\n          'easeOutCubic',\n          'easeInOutCubic',\n          'easeInQuart',\n          'easeOutQuart',\n          'easeInOutQuart',\n          'easeInQuint',\n          'easeOutQuint',\n          'easeInOutQuint',\n        ],\n      }\n    },\n    computed: {\n      options () {\n        return {\n          container: '#goto-container-example',\n          duration: this.duration,\n          easing: this.easing,\n          offset: this.offset,\n        }\n      },\n    },\n    methods: {\n      onClick () {\n        if (this.target === 'By Number') {\n          this.goTo(this.number, this.options)\n        } else if (this.target === 'By Query Selector') {\n          this.goTo(this.query, this.options)\n        } else if (this.target === 'By Component / Element') {\n          this.goTo(this.cards[this.component].$el, this.options)\n        }\n      },\n      onClickReset () {\n        this.component = 'card3'\n        this.duration = 300\n        this.easing = 'easeInOutCubic'\n        this.number = 500\n        this.offset = 0\n        this.query = '#heading-3'\n        this.target = 'By Number'\n\n        this.goTo(0, { container: '#goto-container-example' })\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/sizing/height.vue",
    "content": "<template>\n  <div class=\"d-flex justify-center align-end ga-2 text-body-small pa-4\" style=\"height: 300px;\">\n    <div class=\"d-flex align-end bg-surface-variant pa-2 rounded h-25\">.h-25</div>\n\n    <div class=\"d-flex align-end bg-surface-variant pa-2 rounded h-50\">.h-50</div>\n\n    <div class=\"d-flex align-end bg-surface-variant pa-2 rounded h-75\">.h-75</div>\n\n    <div class=\"d-flex align-end bg-surface-variant pa-2 rounded h-100\">.h-100</div>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/sizing/width.vue",
    "content": "<template>\n  <div class=\"d-flex flex-column ga-2 text-body-small pa-4\">\n    <div class=\"d-flex align-end bg-surface-variant pa-2 rounded w-25\">.w-25</div>\n\n    <div class=\"d-flex align-end bg-surface-variant pa-2 rounded w-33\">.w-33</div>\n\n    <div class=\"d-flex align-end bg-surface-variant pa-2 rounded w-50\">.w-50</div>\n\n    <div class=\"d-flex align-end bg-surface-variant pa-2 rounded w-66\">.w-66</div>\n\n    <div class=\"d-flex align-end bg-surface-variant pa-2 rounded w-75\">.w-75</div>\n\n    <div class=\"d-flex align-end bg-surface-variant pa-2 rounded w-100\">.w-100</div>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/spacing/breakpoints.vue",
    "content": "<template>\n  <v-card\n    class=\"pa-md-4 mx-lg-auto\"\n    color=\"secondary\"\n    width=\"250px\"\n  >\n    <v-card-text>\n      Adjust screen size to see spacing changes\n    </v-card-text>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/spacing/gap.vue",
    "content": "<template>\n  <div class=\"d-flex flex-wrap ga-3\">\n    <v-card\n      v-for=\"n in 8\"\n      :key=\"n\"\n      color=\"secondary\"\n      width=\"200px\"\n    >\n      <v-card-text>\n        Gapped\n      </v-card-text>\n    </v-card>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/spacing/horizontal.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    color=\"secondary\"\n    width=\"200px\"\n  >\n    <v-card-text>\n      Centered\n    </v-card-text>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/spacing/negative-margin.vue",
    "content": "<template>\n  <div>\n    <v-card\n      class=\"mx-auto\"\n      color=\"secondary\"\n      height=\"100\"\n      max-width=\"200\"\n    ></v-card>\n    <v-card\n      class=\"mt-n12 mx-auto\"\n      color=\"secondary\"\n      elevation=\"4\"\n      height=\"200\"\n      max-width=\"300\"\n    >\n      <v-card-text>This card has negative top margin applied</v-card-text>\n    </v-card>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/spacing/usage.vue",
    "content": "<template>\n  <v-container\n    class=\"spacing-playground pa-6\"\n    fluid\n  >\n    <v-row>\n      <v-col\n        class=\"d-flex align-center\"\n        cols=\"12\"\n        sm=\"6\"\n      >\n        <v-select\n          v-model=\"paddingDirection\"\n          :items=\"directions\"\n          class=\"pe-2\"\n          label=\"Padding\"\n        >\n          <template v-slot:prepend>\n            <strong class=\"text-primary py-1\">p</strong>\n          </template>\n\n          <template v-slot:append-outer>\n            <div class=\"py-1\">\n              -\n            </div>\n          </template>\n        </v-select>\n\n        <v-select\n          v-model=\"paddingSize\"\n          :items=\"paddingSizes.slice(1)\"\n          label=\"Size\"\n        ></v-select>\n      </v-col>\n\n      <v-col\n        class=\"d-flex\"\n        cols=\"12\"\n        sm=\"6\"\n      >\n        <v-select\n          v-model=\"marginDirection\"\n          :items=\"directions\"\n          class=\"pe-2\"\n          label=\"Margin\"\n        >\n          <template v-slot:prepend>\n            <strong class=\"text-primary py-1\">m</strong>\n          </template>\n\n          <template v-slot:append-outer>\n            <div class=\"py-1\">\n              -\n            </div>\n          </template>\n        </v-select>\n\n        <v-select\n          v-model=\"marginSize\"\n          :items=\"marginSizes\"\n          label=\"Size\"\n        ></v-select>\n      </v-col>\n\n      <v-col\n        class=\"bg-orange-lighten-3 pa-0\"\n        cols=\"12\"\n      >\n        <v-sheet\n          :class=\"[computedMargin]\"\n          elevation=\"2\"\n          rounded\n        >\n          <div\n            :class=\"[computedPadding]\"\n            class=\"bg-light-green-lighten-3\"\n          >\n            <div\n              class=\"bg-white text-center py-6\"\n              v-text=\"playgroundText\"\n            ></div>\n          </div>\n        </v-sheet>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script>\n  export default {\n    data () {\n      const spacers = Array.from({ length: 17 }, (val, i) => `${i}`)\n      const nspacers = Array.from({ length: 16 }, (val, i) => `n${i + 1}`)\n      const defaults = ['auto', ...spacers]\n\n      return {\n        directions: ['t', 'b', 'l', 'r', 's', 'e', 'x', 'y', 'a'],\n        marginDirection: 'a',\n        marginSize: '2',\n        marginSizes: [...defaults, ...nspacers],\n        paddingDirection: 'a',\n        paddingSize: '6',\n        paddingSizes: defaults,\n        playgroundText: 'Use the controls above to try out the different spacing helpers.',\n      }\n    },\n\n    computed: {\n      computedPadding () {\n        return `p${this.paddingDirection}-${this.paddingSize}`\n      },\n      computedMargin () {\n        return `m${this.marginDirection}-${this.marginSize}`\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/text-and-typography/font-emphasis.vue",
    "content": "<template>\n  <div>\n    <p class=\"font-weight-black\">\n      Black text.\n    </p>\n    <p class=\"font-weight-bold\">\n      Bold text.\n    </p>\n    <p class=\"font-weight-semibold\">\n      Semibold text.\n    </p>\n    <p class=\"font-weight-medium\">\n      Medium weight text.\n    </p>\n    <p class=\"font-weight-regular\">\n      Normal weight text.\n    </p>\n    <p class=\"font-weight-light\">\n      Light weight text.\n    </p>\n    <p class=\"font-weight-thin\">\n      Thin weight text.\n    </p>\n    <p class=\"font-italic\">\n      Italic text.\n    </p>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/text-and-typography/text-alignment-responsive.vue",
    "content": "<template>\n  <div>\n    <p class=\"text-left\">\n      Left aligned on all viewport sizes.\n    </p>\n    <p class=\"text-center\">\n      Center aligned on all viewport sizes.\n    </p>\n    <p class=\"text-right\">\n      Right aligned on all viewport sizes.\n    </p>\n\n    <p class=\"text-sm-left\">\n      Left aligned on viewports SM (small) or wider.\n    </p>\n    <p class=\"text-right text-md-left\">\n      Left aligned on viewports MD (medium) or wider.\n    </p>\n    <p class=\"text-right text-lg-left\">\n      Left aligned on viewports LG (large) or wider.\n    </p>\n    <p class=\"text-right text-xl-left\">\n      Left aligned on viewports XL (extra-large) or wider.\n    </p>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/text-and-typography/text-alignment.vue",
    "content": "<template>\n  <div>\n    <p class=\"text-left\">\n      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n    </p>\n\n    <p class=\"text-right\">\n      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n    </p>\n\n    <p class=\"text-center\">\n      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n    </p>\n\n    <p class=\"text-justify\">\n      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n    </p>\n\n    <p class=\"text-start\">\n      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n    </p>\n\n    <p class=\"text-end\">\n      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n    </p>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/text-and-typography/text-break.vue",
    "content": "<template>\n  <div>\n    <p class=\"custom-transform-class text-none\">\n      Random TEXT cApitaLization\n    </p>\n    <p\n      class=\"text-break\"\n      style=\"max-width: 4rem;\"\n    >\n      SUBDERMATOGLYPHIC\n    </p>\n  </div>\n</template>\n\n<style lang=\"sass\">\n  .custom-transform-class\n    text-transform: uppercase\n</style>\n"
  },
  {
    "path": "packages/docs/src/examples/text-and-typography/text-decoration.vue",
    "content": "<template>\n  <div class=\"d-flex justify-space-between flex-row\">\n    <a\n      class=\"text-decoration-none\"\n      href=\"#\"\n    >\n      Non-underlined link\n    </a>\n\n    <div class=\"text-decoration-line-through\">\n      Line-through text\n    </div>\n\n    <div class=\"text-decoration-overline\">\n      Overline text\n    </div>\n\n    <div class=\"text-decoration-underline\">\n      Underline text\n    </div>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/text-and-typography/text-no-wrap.vue",
    "content": "<template>\n  <div\n    class=\"text-no-wrap bg-secondary\"\n    style=\"width: 8rem;\"\n  >\n    This text should overflow the parent.\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/text-and-typography/text-opacity.vue",
    "content": "<template>\n  <div>\n    <p class=\"text-high-emphasis\">\n      High-emphasis has an opacity of 87% in light theme and 100% in dark.\n    </p>\n    <p class=\"text-medium-emphasis\">\n      Medium-emphasis text and hint text have opacities of 60% in light theme and 70% in dark.\n    </p>\n    <p class=\"text-disabled\">\n      Disabled text has an opacity of 38% in light theme and 50% in dark.\n    </p>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/text-and-typography/text-rtl.vue",
    "content": "<template>\n  <div>\n    <p class=\"text-title-small text-center\">\n      Agnostic RTL Alignment\n    </p>\n\n    <p class=\"text-left\">\n      Left aligned text, irrespective of RTL or LTR.\n    </p>\n    <p class=\"text-right\">\n      Right aligned text, irrespective of RTL or LTR.\n    </p>\n\n    <p class=\"text-title-small text-center\">\n      Responsive RTL Alignment\n    </p>\n\n    <p class=\"text-start\">\n      Left aligned text on LTR and right aligned on RTL.\n    </p>\n    <p class=\"text-end\">\n      Right aligned text on LTR and left aligned on RTL.\n    </p>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/text-and-typography/text-transform.vue",
    "content": "<template>\n  <div>\n    <p class=\"text-lowercase\">\n      Lowercased text.\n    </p>\n    <p class=\"text-uppercase\">\n      Uppercased text.\n    </p>\n    <p class=\"text-capitalize\">\n      capitalized text.\n    </p>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/text-and-typography/text-truncate.vue",
    "content": "<template>\n  <div>\n    <span\n      class=\"d-inline-block text-truncate\"\n      style=\"max-width: 150px;\"\n    >\n      Suspendisse faucibus, nunc et pellentesque egestas, lacus ante convallis tellus.\n    </span>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/text-and-typography/typography-breakpoints.vue",
    "content": "<template>\n  <div class=\"d-flex justify-center\">\n    <v-card width=\"300px\">\n      <v-card-title class=\"text-headline-small text-md-headline-medium text-lg-headline-large\">Title</v-card-title>\n      <v-card-text>\n        Body text\n      </v-card-text>\n    </v-card>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/text-and-typography/typography.vue",
    "content": "<template>\n  <div>\n    <v-card v-for=\"[name, cls] in classes\" :key=\"name\" class=\"my-4\">\n      <div :class=\"[cls, 'pa-2']\">{{ name }}</div>\n      <div class=\"text-label-medium pa-2 border-t\">\n        <v-code>{{ cls }}</v-code>\n      </div>\n    </v-card>\n  </div>\n</template>\n\n<script setup>\n  const classes = [\n    ['Display Large', 'text-display-large'],\n    ['Display Medium', 'text-display-medium'],\n    ['Display Small', 'text-display-small'],\n    ['Headline Large', 'text-headline-large'],\n    ['Headline Medium', 'text-headline-medium'],\n    ['Headline Small', 'text-headline-small'],\n    ['Title Large', 'text-title-large'],\n    ['Title Medium', 'text-title-medium'],\n    ['Title Small', 'text-title-small'],\n    ['Body Large', 'text-body-large'],\n    ['Body Medium', 'text-body-medium'],\n    ['Body Small', 'text-body-small'],\n    ['Label Large', 'text-label-large'],\n    ['Label Medium', 'text-label-medium'],\n    ['Label Small', 'text-label-small'],\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      classes: [\n        ['Display Large', 'text-display-large'],\n        ['Display Medium', 'text-display-medium'],\n        ['Display Small', 'text-display-small'],\n        ['Headline Large', 'text-headline-large'],\n        ['Headline Medium', 'text-headline-medium'],\n        ['Headline Small', 'text-headline-small'],\n        ['Title Large', 'text-title-large'],\n        ['Title Medium', 'text-title-medium'],\n        ['Title Small', 'text-title-small'],\n        ['Body Large', 'text-body-large'],\n        ['Body Medium', 'text-body-medium'],\n        ['Body Small', 'text-body-small'],\n        ['Label Large', 'text-label-large'],\n        ['Label Medium', 'text-label-medium'],\n        ['Label Small', 'text-label-small'],\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/transitions/create-css-transition-component.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"justify-center\" style=\"min-height: 160px;\">\n      <v-col class=\"text-center\">\n        <v-btn\n          color=\"primary\"\n          @click=\"show = !show\"\n        >\n          Component Transition\n        </v-btn>\n\n        <ComponentTransition>\n          <v-card\n            v-show=\"show\"\n            class=\"mx-auto mt-5\"\n            color=\"secondary\"\n            height=\"100\"\n            width=\"100\"\n          ></v-card>\n        </ComponentTransition>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n  import { createCssTransition } from 'vuetify/util/transitions'\n\n  const ComponentTransition = createCssTransition('component-transition')\n\n  const show = ref(false)\n</script>\n\n<style lang=\"scss\">\n  .component-transition {\n    &-enter-active,\n    &-leave-active {\n      transition: 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55);\n    }\n\n    &-enter-from,\n    &-leave-to {\n      opacity: 0;\n      transform: rotate(180deg) scale(0.2) skew(20deg);\n      filter: hue-rotate(90deg);\n    }\n  }\n</style>\n"
  },
  {
    "path": "packages/docs/src/examples/transitions/create-css-transition-prop.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"justify-center\">\n      <v-col class=\"text-center\">\n        <v-menu transition=\"custom-prop-transition\">\n          <template v-slot:activator=\"{ props }\">\n            <v-btn\n              color=\"primary\"\n              v-bind=\"props\"\n            >\n              Prop Transition\n            </v-btn>\n          </template>\n\n          <v-list>\n            <v-list-item\n              v-for=\"n in 5\"\n              :key=\"n\"\n            >\n              <v-list-item-title>\n                Item {{ n }}\n              </v-list-item-title>\n            </v-list-item>\n          </v-list>\n        </v-menu>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { createCssTransition } from 'vuetify/util/transitions'\n\n  createCssTransition('custom-prop-transition')\n</script>\n\n<style lang=\"scss\">\n.custom-prop-transition {\n  &-enter-active,\n  &-leave-active {\n    transition: 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55);\n    transform-origin: top center;\n  }\n\n  &-enter-from,\n  &-leave-to {\n    opacity: 0;\n    transform: scaleY(0) rotateX(-60deg);\n    transform-origin: top center;\n    filter: saturate(2) hue-rotate(90deg);\n  }\n}\n</style>\n"
  },
  {
    "path": "packages/docs/src/examples/transitions/misc-expand-x-padding.vue",
    "content": "<template>\n  <v-container>\n    <v-btn class=\"ma-2\" color=\"primary\" @click=\"expand = !expand\">\n      Expand Transition\n    </v-btn>\n\n    <v-expand-x-transition>\n      <v-responsive v-show=\"expand\" width=\"fit-content\">\n        <v-alert\n          class=\"text-no-wrap\"\n          text=\"Smooth transition here\"\n          type=\"info\"\n        ></v-alert>\n      </v-responsive>\n    </v-expand-x-transition>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const expand = ref(false)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      expand: false,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/transitions/misc-expand-x.vue",
    "content": "<template>\n  <v-row\n    class=\"justify-center\"\n    style=\"min-height: 160px;\"\n  >\n    <v-col class=\"shrink\">\n      <v-btn\n        class=\"ma-2\"\n        color=\"primary\"\n        @click=\"expand = !expand\"\n      >\n        Expand Transition\n      </v-btn>\n\n      <v-expand-transition>\n        <v-card\n          v-show=\"expand\"\n          class=\"mx-auto bg-secondary\"\n          height=\"100\"\n          width=\"100\"\n        ></v-card>\n      </v-expand-transition>\n    </v-col>\n\n    <div class=\"mx-4 hidden-sm-and-down\"></div>\n\n    <v-col class=\"shrink\">\n      <v-btn\n        class=\"ma-2\"\n        color=\"secondary\"\n        @click=\"expand2 = !expand2\"\n      >\n        Expand X Transition\n      </v-btn>\n\n      <v-expand-x-transition>\n        <v-card\n          v-show=\"expand2\"\n          class=\"mx-auto bg-secondary\"\n          height=\"100\"\n          width=\"100\"\n        ></v-card>\n      </v-expand-x-transition>\n    </v-col>\n  </v-row>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const expand = ref(false)\n  const expand2 = ref(false)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      expand: false,\n      expand2: false,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/transitions/misc-fab.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-menu transition=\"fab-transition\">\n      <template v-slot:activator=\"{ props }\">\n        <v-btn\n          color=\"primary\"\n          v-bind=\"props\"\n        >\n          Fab Transition\n        </v-btn>\n      </template>\n      <v-list>\n        <v-list-item\n          v-for=\"n in 5\"\n          :key=\"n\"\n        >\n          <v-list-item-title v-text=\"'Item ' + n\"></v-list-item-title>\n        </v-list-item>\n      </v-list>\n    </v-menu>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/transitions/misc-fade.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-menu transition=\"fade-transition\">\n      <template v-slot:activator=\"{ props }\">\n        <v-btn\n          color=\"primary\"\n          v-bind=\"props\"\n        >\n          Fade Transition\n        </v-btn>\n      </template>\n      <v-list>\n        <v-list-item\n          v-for=\"n in 5\"\n          :key=\"n\"\n        >\n          <v-list-item-title v-text=\"'Item ' + n\"></v-list-item-title>\n        </v-list-item>\n      </v-list>\n    </v-menu>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/transitions/misc-scale.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-menu transition=\"scale-transition\">\n      <template v-slot:activator=\"{ props }\">\n        <v-btn\n          color=\"primary\"\n          v-bind=\"props\"\n        >\n          Scale Transition\n        </v-btn>\n      </template>\n      <v-list>\n        <v-list-item\n          v-for=\"n in 5\"\n          :key=\"n\"\n        >\n          <v-list-item-title v-text=\"'Item ' + n\"></v-list-item-title>\n        </v-list-item>\n      </v-list>\n    </v-menu>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/transitions/misc-scroll-x.vue",
    "content": "<template>\n  <v-row class=\"justify-center\">\n    <v-menu transition=\"scroll-x-transition\">\n      <template v-slot:activator=\"{ props }\">\n        <v-btn\n          class=\"ma-2\"\n          color=\"primary\"\n          v-bind=\"props\"\n        >\n          Scroll X Transition\n        </v-btn>\n      </template>\n      <v-list>\n        <v-list-item\n          v-for=\"n in 5\"\n          :key=\"n\"\n          link\n        >\n          <v-list-item-title v-text=\"'Item ' + n\"></v-list-item-title>\n        </v-list-item>\n      </v-list>\n    </v-menu>\n\n    <div class=\"mx-4 hidden-sm-and-down\"></div>\n\n    <v-menu transition=\"scroll-x-reverse-transition\">\n      <template v-slot:activator=\"{ props }\">\n        <v-btn\n          class=\"ma-2\"\n          color=\"secondary\"\n          v-bind=\"props\"\n        >\n          Scroll X Reverse Transition\n        </v-btn>\n      </template>\n      <v-list>\n        <v-list-item\n          v-for=\"n in 5\"\n          :key=\"n\"\n          link\n        >\n          <v-list-item-title v-text=\"'Item ' + n\"></v-list-item-title>\n        </v-list-item>\n      </v-list>\n    </v-menu>\n  </v-row>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/transitions/misc-scroll-y.vue",
    "content": "<template>\n  <v-row class=\"justify-center\">\n    <v-menu transition=\"scroll-y-transition\">\n      <template v-slot:activator=\"{ props }\">\n        <v-btn\n          class=\"ma-2\"\n          color=\"primary\"\n          v-bind=\"props\"\n        >\n          Scroll Y Transition\n        </v-btn>\n      </template>\n      <v-list>\n        <v-list-item\n          v-for=\"n in 5\"\n          :key=\"n\"\n          link\n        >\n          <v-list-item-title v-text=\"'Item ' + n\"></v-list-item-title>\n        </v-list-item>\n      </v-list>\n    </v-menu>\n\n    <div class=\"mx-4 hidden-sm-and-down\"></div>\n\n    <v-menu transition=\"scroll-y-reverse-transition\">\n      <template v-slot:activator=\"{ props }\">\n        <v-btn\n          class=\"ma-2\"\n          color=\"secondary\"\n          v-bind=\"props\"\n        >\n          Scroll Y Reverse Transition\n        </v-btn>\n      </template>\n      <v-list>\n        <v-list-item\n          v-for=\"n in 5\"\n          :key=\"n\"\n          link\n        >\n          <v-list-item-title v-text=\"'Item ' + n\"></v-list-item-title>\n        </v-list-item>\n      </v-list>\n    </v-menu>\n  </v-row>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/transitions/misc-slide-x.vue",
    "content": "<template>\n  <v-row class=\"justify-center\">\n    <v-menu transition=\"slide-x-transition\">\n      <template v-slot:activator=\"{ props }\">\n        <v-btn\n          class=\"ma-2\"\n          color=\"primary\"\n          v-bind=\"props\"\n        >\n          Slide X Transition\n        </v-btn>\n      </template>\n      <v-list>\n        <v-list-item\n          v-for=\"n in 5\"\n          :key=\"n\"\n          link\n        >\n          <v-list-item-title v-text=\"'Item ' + n\"></v-list-item-title>\n        </v-list-item>\n      </v-list>\n    </v-menu>\n\n    <div class=\"mx-4 hidden-sm-and-down\"></div>\n\n    <v-menu transition=\"slide-x-reverse-transition\">\n      <template v-slot:activator=\"{ props }\">\n        <v-btn\n          class=\"ma-2\"\n          color=\"secondary\"\n          v-bind=\"props\"\n        >\n          Slide X Reverse Transition\n        </v-btn>\n      </template>\n      <v-list>\n        <v-list-item\n          v-for=\"n in 5\"\n          :key=\"n\"\n          link\n        >\n          <v-list-item-title v-text=\"'Item ' + n\"></v-list-item-title>\n        </v-list-item>\n      </v-list>\n    </v-menu>\n  </v-row>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/transitions/misc-slide-y.vue",
    "content": "<template>\n  <v-row class=\"justify-center\">\n    <v-menu transition=\"slide-y-transition\">\n      <template v-slot:activator=\"{ props }\">\n        <v-btn\n          class=\"ma-2\"\n          color=\"primary\"\n          v-bind=\"props\"\n        >\n          Slide Y Transition\n        </v-btn>\n      </template>\n      <v-list>\n        <v-list-item\n          v-for=\"n in 5\"\n          :key=\"n\"\n          link\n        >\n          <v-list-item-title v-text=\"'Item ' + n\"></v-list-item-title>\n        </v-list-item>\n      </v-list>\n    </v-menu>\n\n    <div class=\"mx-4 hidden-sm-and-down\"></div>\n\n    <v-menu transition=\"slide-y-reverse-transition\">\n      <template v-slot:activator=\"{ props }\">\n        <v-btn\n          class=\"ma-2\"\n          color=\"secondary\"\n          v-bind=\"props\"\n        >\n          Slide Y Reverse Transition\n        </v-btn>\n      </template>\n      <v-list>\n        <v-list-item\n          v-for=\"n in 5\"\n          :key=\"n\"\n          link\n        >\n          <v-list-item-title v-text=\"'Item ' + n\"></v-list-item-title>\n        </v-list-item>\n      </v-list>\n    </v-menu>\n  </v-row>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/transitions/misc-todo.vue",
    "content": "<template>\n  <v-container style=\"max-width: 500px\">\n    <v-text-field\n      v-model=\"newTask\"\n      label=\"What are you working on?\"\n      variant=\"solo\"\n      @keydown.enter=\"create\"\n    >\n      <template v-slot:append-inner>\n        <v-fade-transition>\n          <v-btn\n            v-show=\"newTask\"\n            icon=\"mdi-plus-circle\"\n            variant=\"text\"\n            @click=\"create\"\n          ></v-btn>\n        </v-fade-transition>\n      </template>\n    </v-text-field>\n\n    <h2 class=\"text-headline-large text-success ps-4 my-0\">\n      Tasks:&nbsp;\n      <v-fade-transition leave-absolute>\n        <span :key=\"`tasks-${tasks.length}`\">\n          {{ tasks.length }}\n        </span>\n      </v-fade-transition>\n    </h2>\n\n    <v-divider class=\"mt-4\"></v-divider>\n\n    <v-row class=\"my-1 align-center\">\n      <strong class=\"mx-4 text-info-darken-2\">\n        Remaining: {{ remainingTasks }}\n      </strong>\n\n      <v-divider vertical></v-divider>\n\n      <strong class=\"mx-4 text-success-darken-2\">\n        Completed: {{ completedTasks }}\n      </strong>\n\n      <v-spacer></v-spacer>\n\n      <v-progress-circular\n        v-model=\"progress\"\n        class=\"me-2\"\n      ></v-progress-circular>\n    </v-row>\n\n    <v-divider class=\"mb-4\"></v-divider>\n\n    <v-card v-if=\"tasks.length > 0\">\n      <v-slide-y-transition\n        class=\"py-0\"\n        tag=\"v-list\"\n        group\n      >\n        <template v-for=\"(task, i) in tasks\" :key=\"`${i}-${task.text}`\">\n          <v-divider\n            v-if=\"i !== 0\"\n            :key=\"`${i}-divider`\"\n          ></v-divider>\n\n          <v-list-item @click=\"task.done = !task.done\">\n            <template v-slot:prepend>\n              <v-checkbox-btn v-model=\"task.done\" color=\"grey\"></v-checkbox-btn>\n            </template>\n\n            <v-list-item-title>\n              <span :class=\"task.done ? 'text-grey' : 'text-primary'\">{{ task.text }}</span>\n            </v-list-item-title>\n\n            <template v-slot:append>\n              <v-expand-x-transition>\n                <v-icon v-if=\"task.done\" color=\"success\">\n                  mdi-check\n                </v-icon>\n              </v-expand-x-transition>\n            </template>\n          </v-list-item>\n        </template>\n      </v-slide-y-transition>\n    </v-card>\n  </v-container>\n</template>\n<script setup>\n  import { computed, ref } from 'vue'\n\n  const tasks = ref([\n    {\n      done: false,\n      text: 'Foobar',\n    },\n    {\n      done: false,\n      text: 'Fizzbuzz',\n    },\n  ])\n  const newTask = ref(null)\n\n  const completedTasks = computed(() => {\n    return tasks.value.filter(task => task.done).length\n  })\n  const progress = computed(() => {\n    return completedTasks.value / tasks.value.length * 100\n  })\n  const remainingTasks = computed(() => {\n    return tasks.value.length - completedTasks.value\n  })\n\n  function create () {\n    tasks.value.push({\n      done: false,\n      text: newTask.value,\n    })\n    newTask.value = null\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      tasks: [\n        {\n          done: false,\n          text: 'Foobar',\n        },\n        {\n          done: false,\n          text: 'Fizzbuzz',\n        },\n      ],\n      newTask: null,\n    }),\n\n    computed: {\n      completedTasks () {\n        return this.tasks.filter(task => task.done).length\n      },\n      progress () {\n        return this.completedTasks / this.tasks.length * 100\n      },\n      remainingTasks () {\n        return this.tasks.length - this.completedTasks\n      },\n    },\n\n    methods: {\n      create () {\n        this.tasks.push({\n          done: false,\n          text: this.newTask,\n        })\n\n        this.newTask = null\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/transitions/prop-custom-origin.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-menu\n      origin=\"center center\"\n      transition=\"scale-transition\"\n    >\n      <template v-slot:activator=\"{ props }\">\n        <v-btn\n          color=\"primary\"\n          v-bind=\"props\"\n        >\n          Scale Transition\n        </v-btn>\n      </template>\n      <v-list>\n        <v-list-item\n          v-for=\"n in 5\"\n          :key=\"n\"\n          @click=\"() => {}\"\n        >\n          <v-list-item-title v-text=\"'Item ' + n\"></v-list-item-title>\n        </v-list-item>\n      </v-list>\n    </v-menu>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/transitions/usage.vue",
    "content": "<template>\n  <v-row class=\"justify-center\">\n    <v-menu transition=\"slide-x-transition\">\n      <template v-slot:activator=\"{ props }\">\n        <v-btn\n          class=\"ma-2\"\n          color=\"primary\"\n          v-bind=\"props\"\n        >\n          Slide X Transition\n        </v-btn>\n      </template>\n      <v-list>\n        <v-list-item\n          v-for=\"n in 5\"\n          :key=\"n\"\n          link\n        >\n          <v-list-item-title v-text=\"'Item ' + n\"></v-list-item-title>\n        </v-list-item>\n      </v-list>\n    </v-menu>\n\n    <div class=\"mx-6 hidden-sm-and-down\"></div>\n\n    <v-menu transition=\"scroll-y-transition\">\n      <template v-slot:activator=\"{ props }\">\n        <v-btn\n          class=\"ma-2\"\n          color=\"secondary\"\n          v-bind=\"props\"\n        >\n          Scroll Y Transition\n        </v-btn>\n      </template>\n      <v-list>\n        <v-list-item\n          v-for=\"n in 5\"\n          :key=\"n\"\n          link\n        >\n          <v-list-item-title v-text=\"'Item ' + n\"></v-list-item-title>\n        </v-list-item>\n      </v-list>\n    </v-menu>\n  </v-row>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-alert/prop-border-color.vue",
    "content": "<template>\n  <div>\n    <v-alert\n      border=\"start\"\n      border-color=\"deep-purple accent-4\"\n      elevation=\"1\"\n    >\n      Aliquam eu nunc. Fusce commodo aliquam arcu. In consectetuer turpis ut velit. Nulla facilisi..\n\n      Morbi mollis tellus ac sapien. Fusce vel dui. Praesent ut ligula non mi varius sagittis. Vivamus consectetuer hendrerit lacus. Suspendisse enim turpis, dictum sed, iaculis a, condimentum nec, nisi.\n    </v-alert>\n\n    <br>\n\n    <v-alert\n      border=\"top\"\n      border-color=\"success\"\n      elevation=\"1\"\n    >\n      Vestibulum ullamcorper mauris at ligula. Nam pretium turpis et arcu. Ut varius tincidunt libero. Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo. Morbi nec metus.\n    </v-alert>\n\n    <br>\n\n    <v-alert\n      border=\"bottom\"\n      border-color=\"warning\"\n      elevation=\"1\"\n    >\n      Sed in libero ut nibh placerat accumsan. Phasellus leo dolor, tempus non, auctor et, hendrerit quis, nisi. Phasellus leo dolor, tempus non, auctor et, hendrerit quis, nisi. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc, quis gravida magna mi a libero. Donec elit libero, sodales nec, volutpat a, suscipit non, turpis.\n    </v-alert>\n\n    <br>\n\n    <v-alert\n      border=\"end\"\n      border-color=\"error\"\n      elevation=\"1\"\n    >\n      Fusce commodo aliquam arcu. Pellentesque posuere. Phasellus tempus. Donec posuere vulputate arcu.\n    </v-alert>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-alert/prop-border.vue",
    "content": "<template>\n  <div>\n    <v-alert\n      border=\"top\"\n      color=\"primary\"\n    >\n      I'm an alert with a top border and primary color\n    </v-alert>\n\n    <br>\n\n    <v-alert\n      border=\"end\"\n      color=\"secondary\"\n    >\n      I'm an alert with an end border and secondary color\n    </v-alert>\n\n    <br>\n\n    <v-alert\n      border=\"bottom\"\n      color=\"success\"\n    >\n      I'm an alert with a bottom border and success color\n    </v-alert>\n\n    <br>\n\n    <v-alert\n      border=\"start\"\n      color=\"error\"\n    >\n      I'm an alert with a start border and error color\n    </v-alert>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-alert/prop-closable.vue",
    "content": "<template>\n  <div>\n    <v-alert\n      v-model=\"alert\"\n      border=\"start\"\n      close-label=\"Close Alert\"\n      color=\"deep-purple-accent-4\"\n      title=\"Closable Alert\"\n      variant=\"tonal\"\n      closable\n    >\n      Aenean imperdiet. Quisque id odio. Cras dapibus. Pellentesque ut neque. Cras dapibus.\n\n      Vivamus consectetuer hendrerit lacus. Sed mollis, eros et ultrices tempus, mauris ipsum aliquam libero, non adipiscing dolor urna a orci. Sed mollis, eros et ultrices tempus, mauris ipsum aliquam libero, non adipiscing dolor urna a orci. Curabitur blandit mollis lacus. Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo.\n    </v-alert>\n\n    <div\n      v-if=\"!alert\"\n      class=\"text-center\"\n    >\n      <v-btn @click=\"alert = true\">\n        Reset\n      </v-btn>\n    </div>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const alert = ref(true)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      alert: true,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-alert/prop-content.vue",
    "content": "<template>\n  <v-alert\n    text=\"Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!\"\n    title=\"Alert title\"\n  ></v-alert>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-alert/prop-density.vue",
    "content": "<template>\n  <v-alert\n    density=\"compact\"\n    text=\"Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!\"\n    title=\"Alert title\"\n    type=\"warning\"\n  ></v-alert>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-alert/prop-icon.vue",
    "content": "<template>\n  <div>\n    <v-alert\n      color=\"#2A3B4D\"\n      density=\"compact\"\n      icon=\"mdi-firework\"\n      theme=\"dark\"\n    >\n      Suspendisse enim turpis, dictum sed, iaculis a, condimentum nec, nisi. Vivamus quis mi. Quisque ut nisi. Maecenas malesuada.\n    </v-alert>\n\n    <br>\n\n    <v-alert\n      color=\"#C51162\"\n      icon=\"mdi-material-design\"\n      theme=\"dark\"\n      border\n    >\n      Phasellus blandit leo ut odio. Morbi mattis ullamcorper velit. Donec orci lectus, aliquam ut, faucibus non, euismod id, nulla. In ut quam vitae odio lacinia tincidunt.\n    </v-alert>\n\n    <br>\n\n    <v-alert\n      color=\"primary\"\n      icon=\"$vuetify\"\n      theme=\"dark\"\n      prominent\n    >\n      Praesent congue erat at massa. Nullam vel sem. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Proin viverra, ligula sit amet ultrices semper, ligula arcu tristique sapien, a accumsan nisi mauris ac eros. Curabitur at lacus ac velit ornare lobortis.\n    </v-alert>\n  </div>\n</template>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2747-66100&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-alert/prop-outlined.vue",
    "content": "<template>\n  <div>\n    <v-alert\n      color=\"purple\"\n      variant=\"outlined\"\n    >\n      <template v-slot:title>\n        Outlined Alert\n      </template>\n\n      Maecenas ullamcorper, dui et placerat feugiat, eros pede varius nisi, condimentum viverra felis nunc et lorem. Duis vel nibh at velit scelerisque suscipit. Praesent blandit laoreet nibh. Aenean posuere, tortor sed cursus feugiat, nunc augue blandit nunc, eu sollicitudin urna dolor sagittis lacus. Etiam sollicitudin, ipsum eu pulvinar rutrum, tellus ipsum laoreet sapien, quis venenatis ante odio sit amet eros.\n    </v-alert>\n\n    <br>\n\n    <v-alert\n      type=\"success\"\n      variant=\"outlined\"\n    >\n      Praesent venenatis metus at tortor pulvinar varius. Aenean commodo ligula eget dolor. Praesent ac massa at ligula laoreet iaculis. Vestibulum ullamcorper mauris at ligula.\n    </v-alert>\n\n    <br>\n\n    <v-alert\n      border=\"top\"\n      type=\"warning\"\n      variant=\"outlined\"\n      prominent\n    >\n      Duis arcu tortor, suscipit eget, imperdiet nec, imperdiet iaculis, ipsum. Suspendisse non nisl sit amet velit hendrerit rutrum. Nullam vel sem. Pellentesque dapibus hendrerit tortor.\n    </v-alert>\n  </div>\n</template>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2747-66101&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-alert/prop-prominent.vue",
    "content": "<template>\n  <div>\n    <v-alert\n      type=\"error\"\n      prominent\n    >\n      <template v-slot:text>\n        Nunc nonummy metus. Nunc interdum lacus sit amet orci Nullam dictum felis eu pede.\n      </template>\n\n      <template v-slot:append>\n        <v-btn size=\"small\" variant=\"text\">Take action</v-btn>\n      </template>\n    </v-alert>\n\n    <br>\n\n    <v-alert\n      color=\"blue-grey-darken-2\"\n      density=\"compact\"\n      icon=\"mdi-school\"\n      prominent\n    >\n      Sed augue ipsum, egestas nec, vestibulum et, malesuada adipiscing, dui. Aenean ut eros et nisl sagittis vestibulum. Sed aliquam ultrices mauris. Donec vitae orci sed dolor rutrum auctor.\n    </v-alert>\n\n    <br>\n\n    <v-alert\n      icon=\"mdi-shield-lock-outline\"\n      type=\"info\"\n      prominent\n    >\n      Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Sed in libero ut nibh placerat accumsan.. Curabitur blandit mollis lacus. Curabitur blandit mollis lacus.\n    </v-alert>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-alert/prop-rounded.vue",
    "content": "<template>\n  <div>\n    <v-alert\n      rounded=\"0\"\n      title=\"Info\"\n      type=\"info\"\n    >\n      I'm an alert with no rounded borders. Lorem ipsum dolor sit, amet consectetur adipisicing elit. Aspernatur recusandae, est itaque laboriosam amet officia? Officia repellat provident sed est adipisci voluptatibus, voluptas reprehenderit dicta voluptatum, optio enim, placeat nostrum.\n    </v-alert>\n\n    <br>\n\n    <v-alert\n      rounded=\"xl\"\n      title=\"Success\"\n      type=\"success\"\n      variant=\"outlined\"\n    >\n      I'm an alert with extra large rounded borders. Lorem ipsum dolor, sit amet consectetur adipisicing elit. Enim cumque vel sapiente suscipit officia ullam quam possimus provident id neque, cupiditate fuga animi expedita, beatae ipsam in veniam inventore totam.\n    </v-alert>\n\n    <br>\n\n    <v-alert\n      rounded=\"pill\"\n      title=\"Warning\"\n      type=\"warning\"\n      prominent\n    >\n      I'm an alert with pill rounded borders. Lorem ipsum dolor sit amet consectetur adipisicing elit. Laudantium ex excepturi ea odio cum libero animi vitae repellat fuga velit explicabo quae, ducimus.\n    </v-alert>\n\n    <br>\n\n    <v-alert\n      rounded=\"t-xl b-lg\"\n      title=\"Error\"\n      type=\"error\"\n      prominent\n    >\n      I'm an alert with top and bottom borders. Lorem, ipsum dolor sit amet consectetur adipisicing elit. Rerum esse quis eius delectus odio repellat voluptates ullam doloribus eaque dignissimos\n    </v-alert>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-alert/prop-type.vue",
    "content": "<template>\n  <v-alert\n    text=\"Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!\"\n    title=\"Alert title\"\n    type=\"success\"\n  ></v-alert>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-alert/prop-variant.vue",
    "content": "<template>\n  <v-alert\n    text=\"Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!\"\n    title=\"Alert title\"\n    type=\"info\"\n    variant=\"tonal\"\n  ></v-alert>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-alert/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div>\n      <v-alert\n        v-if=\"alert\"\n        v-model=\"alert\"\n        v-bind=\"props\"\n      >\n        <template v-slot:text>\n          Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!\n        </template>\n      </v-alert>\n\n      <div class=\"text-center\">\n        <v-btn v-if=\"!alert\" @click=\"alert = true\">\n          Show Alert\n        </v-btn>\n      </div>\n    </div>\n\n    <template v-slot:configuration>\n      <v-select\n        v-model=\"type\"\n        :items=\"[\n          'success',\n          'info',\n          'warning',\n          'error',\n        ]\"\n        label=\"Type\"\n        clearable\n      ></v-select>\n\n      <v-checkbox v-model=\"title\" label=\"Show title\"></v-checkbox>\n\n      <v-checkbox v-model=\"closable\" label=\"Closable\"></v-checkbox>\n\n      <v-checkbox v-model=\"icon\" label=\"Custom icon\"></v-checkbox>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-alert'\n  const model = ref('default')\n  const alert = ref(true)\n  const closable = ref(false)\n  const icon = ref(false)\n  const title = ref(false)\n  const type = ref()\n  const options = ['outlined', 'tonal']\n  const props = computed(() => {\n    return {\n      closable: closable.value || undefined,\n      icon: icon.value ? '$vuetify' : undefined,\n      title: title.value ? 'Alert title' : undefined,\n      text: '...',\n      type: type.value || undefined,\n      variant: ['outlined', 'tonal'].includes(model.value) ? model.value : undefined,\n    }\n  })\n\n  const slots = computed(() => {\n    return ''\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-app-bar/misc-app-bar-nav.vue",
    "content": "<template>\n  <v-layout style=\"overflow: hidden\">\n    <v-app-bar\n      color=\"deep-purple\"\n      absolute\n    >\n      <v-app-bar-nav-icon @click=\"drawer = !drawer\"></v-app-bar-nav-icon>\n\n      <v-toolbar-title>Title</v-toolbar-title>\n    </v-app-bar>\n    <v-navigation-drawer\n      v-model=\"drawer\"\n      absolute\n      temporary\n    >\n      <v-list\n        v-model=\"group\"\n        color=\"deep-purple-accent-4\"\n        density=\"compact\"\n        nav\n      >\n        <v-list-item prepend-icon=\"mdi-home\" title=\"Home\" value=\"home\"></v-list-item>\n\n        <v-list-item prepend-icon=\"mdi-account\" title=\"Account\" value=\"account\"></v-list-item>\n      </v-list>\n    </v-navigation-drawer>\n    <v-main>\n      <v-card\n        class=\"mx-auto overflow-hidden\"\n        height=\"400\"\n      ></v-card>\n    </v-main>\n  </v-layout>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const drawer = ref(false)\n  const group = ref(null)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      drawer: false,\n      group: null,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-app-bar/misc-menu.vue",
    "content": "<template>\n  <v-layout>\n    <v-app-bar\n      color=\"#6A76AB\"\n      scroll-behavior=\"shrink fade-image\"\n      scroll-target=\"#scrolling-techniques-4\"\n      src=\"https://picsum.photos/1920/1080?random\"\n      absolute\n    >\n      <template v-slot:image>\n        <v-img gradient=\"to top right, rgba(100,115,201,.7), rgba(25,32,72,.7)\"></v-img>\n      </template>\n\n      <v-app-bar-nav-icon></v-app-bar-nav-icon>\n\n      <v-toolbar-title>Title</v-toolbar-title>\n\n      <v-btn icon>\n        <v-icon>mdi-magnify</v-icon>\n      </v-btn>\n\n      <v-btn icon>\n        <v-icon>mdi-heart</v-icon>\n      </v-btn>\n\n      <v-menu>\n        <template v-slot:activator=\"{ props }\">\n          <v-btn\n            color=\"yellow\"\n            icon\n            v-bind=\"props\"\n          >\n            <v-icon>mdi-dots-vertical</v-icon>\n          </v-btn>\n        </template>\n\n        <v-list>\n          <v-list-item>\n            <v-list-item-title>Click Me 1</v-list-item-title>\n          </v-list-item>\n\n          <v-list-item>\n            <v-list-item-title>Click Me 2</v-list-item-title>\n          </v-list-item>\n\n          <v-list-item>\n            <v-list-item-title>Click Me 3</v-list-item-title>\n          </v-list-item>\n\n          <v-list-item>\n            <v-list-item-title>Click Me 4</v-list-item-title>\n          </v-list-item>\n        </v-list>\n      </v-menu>\n\n      <template v-slot:extension>\n        <v-tabs align-tabs=\"title\">\n          <v-tab>Tab 1</v-tab>\n\n          <v-tab>Tab 2</v-tab>\n\n          <v-tab>Tab 3</v-tab>\n        </v-tabs>\n      </template>\n    </v-app-bar>\n    <v-sheet\n      id=\"scrolling-techniques-4\"\n      class=\"overflow-y-auto\"\n      max-height=\"600\"\n      width=\"100%\"\n    >\n      <v-container style=\"height: 1000px;\"></v-container>\n    </v-sheet>\n  </v-layout>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-app-bar/prop-dense.vue",
    "content": "<template>\n  <div>\n    <v-app-bar\n      color=\"deep-purple-accent-4\"\n      dense\n    >\n      <v-app-bar-nav-icon></v-app-bar-nav-icon>\n\n      <v-toolbar-title>Page title</v-toolbar-title>\n\n      <v-btn icon>\n        <v-icon>mdi-heart</v-icon>\n      </v-btn>\n\n      <v-btn icon>\n        <v-icon>mdi-magnify</v-icon>\n      </v-btn>\n\n      <v-menu>\n        <template v-slot:activator=\"{ props }\">\n          <v-btn\n            icon\n            v-bind=\"props\"\n          >\n            <v-icon>mdi-dots-vertical</v-icon>\n          </v-btn>\n        </template>\n\n        <v-list>\n          <v-list-item\n            v-for=\"n in 5\"\n            :key=\"n\"\n            @click=\"() => {}\"\n          >\n            <v-list-item-title>Option {{ n }}</v-list-item-title>\n          </v-list-item>\n        </v-list>\n      </v-menu>\n    </v-app-bar>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-app-bar/prop-density.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"448\"\n  >\n    <v-layout>\n      <v-app-bar\n        color=\"primary\"\n        density=\"compact\"\n      >\n        <template v-slot:prepend>\n          <v-app-bar-nav-icon></v-app-bar-nav-icon>\n        </template>\n\n        <v-app-bar-title>Photos</v-app-bar-title>\n\n        <template v-slot:append>\n          <v-btn icon=\"mdi-dots-vertical\"></v-btn>\n        </template>\n      </v-app-bar>\n\n      <v-main>\n        <v-container fluid>\n          <v-row density=\"comfortable\">\n            <v-col\n              v-for=\"n in 8\"\n              :key=\"n\"\n              cols=\"3\"\n            >\n              <v-sheet\n                color=\"surface-variant-alt\"\n                height=\"96\"\n              ></v-sheet>\n            </v-col>\n          </v-row>\n        </v-container>\n      </v-main>\n    </v-layout>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-app-bar/prop-image.vue",
    "content": "<template>\n  <v-card class=\"mx-auto\" color=\"grey-lighten-3\" max-width=\"448\">\n    <v-layout>\n      <v-app-bar\n        color=\"teal-darken-4\"\n        image=\"https://picsum.photos/1920/1080?random\"\n      >\n        <template v-slot:image>\n          <v-img\n            gradient=\"to top right, rgba(19,84,122,.8), rgba(128,208,199,.8)\"\n          ></v-img>\n        </template>\n\n        <template v-slot:prepend>\n          <v-app-bar-nav-icon></v-app-bar-nav-icon>\n        </template>\n\n        <v-app-bar-title>Title</v-app-bar-title>\n\n        <v-btn icon>\n          <v-icon>mdi-magnify</v-icon>\n        </v-btn>\n\n        <v-btn icon>\n          <v-icon>mdi-heart</v-icon>\n        </v-btn>\n\n        <v-btn icon>\n          <v-icon>mdi-dots-vertical</v-icon>\n        </v-btn>\n      </v-app-bar>\n\n      <v-main>\n        <v-container fluid>\n          <v-row density=\"comfortable\">\n            <v-col\n              v-for=\"n in 4\"\n              :key=\"n\"\n              cols=\"12\"\n            >\n              <v-card\n                :subtitle=\"`Subtitle for Content ${n}`\"\n                :title=\"`Content ${n}`\"\n                text=\"Lorem ipsum dolor sit amet consectetur, adipisicing elit.?\"\n              ></v-card>\n            </v-col>\n          </v-row>\n        </v-container>\n      </v-main>\n    </v-layout>\n  </v-card>\n</template>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=1647-144928&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-app-bar/prop-prominent.vue",
    "content": "<template>\n  <v-card class=\"mx-auto\" max-width=\"448\">\n    <v-layout>\n      <v-app-bar\n        color=\"info\"\n        density=\"prominent\"\n      >\n        <template v-slot:prepend>\n          <v-app-bar-nav-icon></v-app-bar-nav-icon>\n        </template>\n\n        <v-app-bar-title>My Recent Trips</v-app-bar-title>\n\n        <template v-slot:append>\n          <v-btn icon>\n            <v-icon>mdi-dots-vertical</v-icon>\n          </v-btn>\n        </template>\n      </v-app-bar>\n\n      <v-main>\n        <v-container fluid>\n          <v-card\n            class=\"mb-2\"\n            density=\"compact\"\n            prepend-avatar=\"https://randomuser.me/api/portraits/women/10.jpg\"\n            subtitle=\"Salsa, merengue, y cumbia\"\n            title=\"Cuba\"\n            variant=\"text\"\n            border\n          >\n            <v-img height=\"128\" src=\"https://picsum.photos/512/128?image=660\" cover></v-img>\n\n            <v-card-text>\n              During my last trip to South America, I spent 2 weeks traveling through Patagonia in Chile.\n            </v-card-text>\n\n            <template v-slot:actions>\n              <v-btn color=\"primary\" variant=\"text\">View More</v-btn>\n\n              <v-btn color=\"primary\" variant=\"text\">See in Map</v-btn>\n            </template>\n          </v-card>\n\n          <v-card\n            density=\"comfortable\"\n            prepend-avatar=\"https://randomuser.me/api/portraits/women/17.jpg\"\n            subtitle=\"Salsa, merengue, y cumbia\"\n            title=\"Florida\"\n            variant=\"text\"\n            border\n          >\n            <v-img height=\"128\" src=\"https://picsum.photos/512/128?random\" cover></v-img>\n\n            <v-card-text>\n              During my last trip to Florida, I spent 2 weeks traveling through the Everglades.\n            </v-card-text>\n\n            <template v-slot:actions>\n              <v-btn color=\"primary\" variant=\"text\">View More</v-btn>\n\n              <v-btn color=\"primary\" variant=\"text\">See in Map</v-btn>\n            </template>\n          </v-card>\n        </v-container>\n      </v-main>\n    </v-layout>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-app-bar/prop-scroll-behavior.vue",
    "content": "<template>\n  <AppSheet class=\"mb-6\">\n    <ExamplesUsageExample\n      v-model=\"model\"\n      :code=\"code\"\n      :name=\"name\"\n      :options=\"options\"\n    >\n      <v-layout style=\"height: 300px\">\n        <v-main id=\"scroll-behavior-layout\" class=\"pt-0\" scrollable>\n          <v-app-bar\n            v-bind=\"props\"\n            color=\"secondary\"\n            scroll-target=\"#scroll-behavior-layout > .v-main__scroller\"\n            style=\"position: sticky\"\n          >\n            <template v-slot:prepend>\n              <v-app-bar-nav-icon></v-app-bar-nav-icon>\n            </template>\n\n            <v-app-bar-title>Application Bar</v-app-bar-title>\n\n            <template v-if=\"actions\" v-slot:append>\n              <v-btn icon=\"mdi-heart\"></v-btn>\n\n              <v-btn icon=\"mdi-magnify\"></v-btn>\n\n              <v-btn icon=\"mdi-dots-vertical\"></v-btn>\n            </template>\n          </v-app-bar>\n\n          <div style=\"height: 1000px\"></div>\n        </v-main>\n      </v-layout>\n\n      <template v-slot:configuration>\n        <v-checkbox v-for=\"option in behaviors\" :key=\"option.value\" v-model=\"selectedBehaviors\" :label=\"option.title\" :value=\"option.value\"></v-checkbox>\n        <v-divider></v-divider>\n        <v-checkbox v-model=\"selectedBehaviors\" label=\"Inverted\" value=\"inverted\"></v-checkbox>\n        <v-slider v-model=\"scrollThreshold\" label=\"Threshold\" max=\"1000\" min=\"0\" step=\"1\"></v-slider>\n      </template>\n    </ExamplesUsageExample>\n  </AppSheet>\n</template>\n\n<script setup>\n  const name = 'v-app-bar'\n  const model = ref('default')\n  const options = []\n\n  const actions = ref(false)\n  const scrollThreshold = ref(300)\n  const selectedBehaviors = ref([])\n  const behaviors = [\n    { value: 'hide', title: 'Hide' },\n    { value: 'collapse', title: 'Collapse' },\n    { value: 'elevate', title: 'Elevate' },\n    { value: 'fade-image', title: 'Fade image' },\n  ]\n\n  const props = computed(() => {\n    return {\n      'scroll-behavior': selectedBehaviors.value.join(' ') || undefined,\n      'scroll-threshold': scrollThreshold.value === 300 ? undefined : String(scrollThreshold.value),\n      image: selectedBehaviors.value.includes('fade-image') ? 'https://picsum.photos/1920/1080?random' : undefined,\n    }\n  })\n\n  const slots = computed(() => {\n    let str = ''\n\n    if (actions.value) {\n      str += `\n  <template v-slot:append>\n    <v-btn icon=\"mdi-heart\"></v-btn>\n\n    <v-btn icon=\"mdi-magnify\"></v-btn>\n\n    <v-btn icon=\"mdi-dots-vertical\"></v-btn>\n  </template>\n`\n    }\n\n    return str\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-app-bar/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <v-layout class=\"border\" style=\"height: 150px;\">\n      <v-app-bar v-bind=\"props\">\n        <template v-slot:prepend>\n          <v-app-bar-nav-icon></v-app-bar-nav-icon>\n        </template>\n\n        <v-app-bar-title>Application Bar</v-app-bar-title>\n\n        <template v-if=\"actions\" v-slot:append>\n          <v-btn icon=\"mdi-heart\"></v-btn>\n\n          <v-btn icon=\"mdi-magnify\"></v-btn>\n\n          <v-btn icon=\"mdi-dots-vertical\"></v-btn>\n        </template>\n      </v-app-bar>\n\n      <v-main style=\"height: 75px;\"></v-main>\n    </v-layout>\n\n    <template v-slot:configuration>\n      <v-checkbox v-model=\"actions\" label=\"Actions\"></v-checkbox>\n\n      <v-slider v-model=\"elevation\" label=\"Elevation\" max=\"5\" min=\"0\" step=\"1\"></v-slider>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-app-bar'\n  const model = ref('default')\n  const actions = ref(false)\n  const elevation = ref(1)\n  const options = ['collapse', 'rounded']\n\n  const props = computed(() => {\n    return {\n      collapse: model.value === 'collapse' ? true : undefined,\n      elevation: elevation.value === 1 ? undefined : elevation.value,\n      rounded: model.value === 'rounded' ? true : undefined,\n    }\n  })\n\n  const slots = computed(() => {\n    let str = ''\n\n    str += `\n  <template v-slot:prepend>\n    <v-app-bar-nav-icon></v-app-bar-nav-icon>\n  </template>\n\n  <v-app-bar-title>Application Bar</v-app-bar-title>\n`\n\n    if (actions.value) {\n      str += `\n  <template v-slot:append>\n    <v-btn icon=\"mdi-heart\"></v-btn>\n\n    <v-btn icon=\"mdi-magnify\"></v-btn>\n\n    <v-btn icon=\"mdi-dots-vertical\"></v-btn>\n  </template>\n`\n    }\n\n    return str\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-autocomplete/misc-asynchronous-items.vue",
    "content": "<template>\n  <v-toolbar color=\"teal\">\n    <v-toolbar-title>State selection</v-toolbar-title>\n\n    <v-autocomplete\n      v-model=\"select\"\n      v-model:search=\"search\"\n      :items=\"items\"\n      :loading=\"loading\"\n      autocomplete=\"off\"\n      class=\"mx-4\"\n      density=\"comfortable\"\n      label=\"What state are you from?\"\n      placeholder=\"Start typing...\"\n      style=\"max-width: 300px\"\n      hide-details\n      hide-no-data\n    ></v-autocomplete>\n\n    <v-btn icon=\"mdi-dots-vertical\"></v-btn>\n  </v-toolbar>\n</template>\n\n<script setup>\n  import { ref, watch } from 'vue'\n\n  const states = [\n    'Alabama',\n    'Alaska',\n    'American Samoa',\n    'Arizona',\n    'Arkansas',\n    'California',\n    'Colorado',\n    'Connecticut',\n    'Delaware',\n    'District of Columbia',\n    'Federated States of Micronesia',\n    'Florida',\n    'Georgia',\n    'Guam',\n    'Hawaii',\n    'Idaho',\n    'Illinois',\n    'Indiana',\n    'Iowa',\n    'Kansas',\n    'Kentucky',\n    'Louisiana',\n    'Maine',\n    'Marshall Islands',\n    'Maryland',\n    'Massachusetts',\n    'Michigan',\n    'Minnesota',\n    'Mississippi',\n    'Missouri',\n    'Montana',\n    'Nebraska',\n    'Nevada',\n    'New Hampshire',\n    'New Jersey',\n    'New Mexico',\n    'New York',\n    'North Carolina',\n    'North Dakota',\n    'Northern Mariana Islands',\n    'Ohio',\n    'Oklahoma',\n    'Oregon',\n    'Palau',\n    'Pennsylvania',\n    'Puerto Rico',\n    'Rhode Island',\n    'South Carolina',\n    'South Dakota',\n    'Tennessee',\n    'Texas',\n    'Utah',\n    'Vermont',\n    'Virgin Island',\n    'Virginia',\n    'Washington',\n    'West Virginia',\n    'Wisconsin',\n    'Wyoming',\n  ]\n\n  const loading = ref(false)\n  const items = ref([])\n  const search = ref(null)\n  const select = ref(null)\n\n  // recommended to use debounce here\n  watch(search, val => {\n    if (!val) {\n      setTimeout(() => items.value = [], 300)\n    } else {\n      val !== select.value && querySelections(val)\n    }\n  })\n\n  function querySelections (v) {\n    loading.value = true\n    setTimeout(() => {\n      if (v !== search.value) {\n        return // drop responce, avoid race condition\n      }\n      items.value = states.filter(e => {\n        return (e || '').toLowerCase().indexOf((v || '').toLowerCase()) > -1\n      })\n      loading.value = false\n    }, 500)\n  }\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        loading: false,\n        items: [],\n        search: null,\n        select: null,\n        states: [\n          'Alabama',\n          'Alaska',\n          'American Samoa',\n          'Arizona',\n          'Arkansas',\n          'California',\n          'Colorado',\n          'Connecticut',\n          'Delaware',\n          'District of Columbia',\n          'Federated States of Micronesia',\n          'Florida',\n          'Georgia',\n          'Guam',\n          'Hawaii',\n          'Idaho',\n          'Illinois',\n          'Indiana',\n          'Iowa',\n          'Kansas',\n          'Kentucky',\n          'Louisiana',\n          'Maine',\n          'Marshall Islands',\n          'Maryland',\n          'Massachusetts',\n          'Michigan',\n          'Minnesota',\n          'Mississippi',\n          'Missouri',\n          'Montana',\n          'Nebraska',\n          'Nevada',\n          'New Hampshire',\n          'New Jersey',\n          'New Mexico',\n          'New York',\n          'North Carolina',\n          'North Dakota',\n          'Northern Mariana Islands',\n          'Ohio',\n          'Oklahoma',\n          'Oregon',\n          'Palau',\n          'Pennsylvania',\n          'Puerto Rico',\n          'Rhode Island',\n          'South Carolina',\n          'South Dakota',\n          'Tennessee',\n          'Texas',\n          'Utah',\n          'Vermont',\n          'Virgin Island',\n          'Virginia',\n          'Washington',\n          'West Virginia',\n          'Wisconsin',\n          'Wyoming',\n        ],\n      }\n    },\n    watch: {\n      // recommended to use debounce here\n      search (val) {\n        if (!val) {\n          setTimeout(() => this.items = [], 300)\n        } else {\n          val !== this.select && querySelections(val)\n        }\n      },\n    },\n    methods: {\n      querySelections (v) {\n        this.loading = true\n        // Simulated ajax query\n        setTimeout(() => {\n          if (v !== this.search) {\n            return // drop responce, avoid race condition\n          }\n          this.items = this.states.filter(e => {\n            return (e || '').toLowerCase().indexOf((v || '').toLowerCase()) > -1\n          })\n          this.loading = false\n        }, 500)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-autocomplete/misc-new-tab.vue",
    "content": "<template>\n  <v-card class=\"pa-8 d-flex justify-center flex-wrap\" theme=\"dark\">\n    <v-container class=\"text-center\">\n      <v-row class=\"justify-center\" density=\"comfortable\">\n        <v-col cols=\"12\">\n          <v-img\n            class=\"mx-auto mt-12 mb-16\"\n            max-height=\"140\"\n            max-width=\"240\"\n            src=\"https://cdn.vuetifyjs.com/docs/images/logos/vuetify-logo-dark-text.svg\"\n          ></v-img>\n        </v-col>\n\n        <v-col cols=\"12\">\n          <v-autocomplete\n            :items=\"items\"\n            append-inner-icon=\"mdi-microphone\"\n            class=\"mx-auto\"\n            density=\"comfortable\"\n            menu-icon=\"\"\n            placeholder=\"Search Google or type a URL\"\n            prepend-inner-icon=\"mdi-magnify\"\n            style=\"max-width: 350px;\"\n            theme=\"light\"\n            variant=\"solo\"\n            auto-select-first\n            item-props\n            rounded\n          ></v-autocomplete>\n        </v-col>\n\n        <v-col\n          v-for=\"(shortcut, i) in shortcuts\"\n          :key=\"i\"\n          cols=\"auto\"\n        >\n          <v-card\n            :href=\"shortcut.href\"\n            class=\"pa-4\"\n            rel=\"noopener noreferrer\"\n            target=\"_blank\"\n            width=\"112\"\n            flat\n          >\n            <v-avatar :icon=\"shortcut.icon\" class=\"mb-2\" color=\"white\" variant=\"tonal\"></v-avatar>\n\n            <div class=\"text-body-small text-truncate\" v-text=\"shortcut.title\"></div>\n          </v-card>\n        </v-col>\n\n        <v-col cols=\"auto\">\n          <v-dialog v-model=\"dialog\" max-width=\"500\">\n            <template v-slot:activator=\"{ props }\">\n              <v-card v-bind=\"props\" class=\"pa-4\" width=\"112\" flat>\n\n                <v-avatar class=\"mb-2\" color=\"white\" icon=\"mdi-plus\" variant=\"tonal\"></v-avatar>\n\n                <div class=\"text-body-small text-truncate\">Add shortcut</div>\n              </v-card>\n            </template>\n\n            <v-card rounded=\"lg\" title=\"Add shortcut\">\n              <template v-slot:text>\n                <v-label class=\"text-body-small\">Name</v-label>\n\n                <v-text-field density=\"compact\" variant=\"solo-filled\" flat></v-text-field>\n\n                <v-label class=\"text-body-small\">URL</v-label>\n\n                <v-text-field density=\"compact\" variant=\"solo-filled\" flat></v-text-field>\n              </template>\n\n              <div class=\"py-4 px-5 text-end\">\n                <v-btn\n                  class=\"text-none me-2\"\n                  color=\"blue\"\n                  text=\"Cancel\"\n                  variant=\"text\"\n                  border\n                  @click=\"dialog = false\"\n                ></v-btn>\n\n                <v-btn\n                  class=\"text-none\"\n                  color=\"blue\"\n                  text=\"Done\"\n                  variant=\"flat\"\n                  @click=\"dialog = false\"\n                ></v-btn>\n              </div>\n            </v-card>\n          </v-dialog>\n        </v-col>\n      </v-row>\n    </v-container>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const items = [\n    {\n      prependIcon: 'mdi-clock-outline',\n      title: 'recipe with chicken',\n    },\n    {\n      prependIcon: 'mdi-clock-outline',\n      title: 'best hiking trails near me',\n    },\n    {\n      prependIcon: 'mdi-clock-outline',\n      title: 'how to learn a new language',\n    },\n    {\n      prependIcon: 'mdi-clock-outline',\n      title: 'DIY home organization ideas',\n    },\n    {\n      prependIcon: 'mdi-clock-outline',\n      title: 'latest fashion trends',\n    },\n  ]\n  const shortcuts = [\n    {\n      icon: 'mdi-github',\n      title: 'Master ',\n      href: 'https://github.com/vuetifyjs/vuetify',\n    },\n    {\n      icon: 'mdi-github',\n      title: 'Dev',\n      href: 'https://github.com/vuetifyjs/vuetify/tree/dev',\n    },\n    {\n      icon: 'mdi-github',\n      title: 'Stable',\n      href: 'https://github.com/vuetifyjs/vuetify/tree/v2-stable',\n    },\n    {\n      icon: 'mdi-github',\n      title: 'My Pull Requests',\n      href: 'https://github.com/vuetifyjs/vuetify/pulls/johnleider',\n    },\n  ]\n\n  const dialog = ref(false)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      dialog: false,\n      items: [\n        {\n          prependIcon: 'mdi-clock-outline',\n          title: 'recipe with chicken',\n        },\n        {\n          prependIcon: 'mdi-clock-outline',\n          title: 'best hiking trails near me',\n        },\n        {\n          prependIcon: 'mdi-clock-outline',\n          title: 'how to learn a new language',\n        },\n        {\n          prependIcon: 'mdi-clock-outline',\n          title: 'DIY home organization ideas',\n        },\n        {\n          prependIcon: 'mdi-clock-outline',\n          title: 'latest fashion trends',\n        },\n      ],\n      shortcuts: [\n        {\n          icon: 'mdi-github',\n          title: 'Master ',\n          href: 'https://github.com/vuetifyjs/vuetify',\n        },\n        {\n          icon: 'mdi-github',\n          title: 'Dev',\n          href: 'https://github.com/vuetifyjs/vuetify/tree/dev',\n        },\n        {\n          icon: 'mdi-github',\n          title: 'Stable',\n          href: 'https://github.com/vuetifyjs/vuetify/tree/v2-stable',\n        },\n        {\n          icon: 'mdi-github',\n          title: 'My Pull Requests',\n          href: 'https://github.com/vuetifyjs/vuetify/pulls/johnleider',\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-autocomplete/misc-state-selector.vue",
    "content": "<template>\n  <v-card>\n    <v-card-title class=\"font-weight-regular bg-blue-grey py-3\">\n      Profile\n    </v-card-title>\n\n    <v-card-text>\n      <div class=\"text-body-small pa-3\">Where do you live?</div>\n\n      <v-autocomplete\n        v-model=\"model\"\n        :hint=\"!isEditing ? 'Click the icon to edit' : 'Click the icon to save'\"\n        :items=\"states\"\n        :label=\"`State — ${isEditing ? 'Editable' : 'Readonly'}`\"\n        :readonly=\"!isEditing\"\n        prepend-icon=\"mdi-city\"\n        persistent-hint\n      >\n        <template v-slot:append>\n          <v-slide-x-reverse-transition mode=\"out-in\">\n            <v-icon\n              :key=\"`icon-${isEditing}`\"\n              :color=\"isEditing ? 'success' : 'info'\"\n              :icon=\"isEditing ? 'mdi-check-outline' : 'mdi-circle-edit-outline'\"\n              @click=\"isEditing = !isEditing\"\n            ></v-icon>\n          </v-slide-x-reverse-transition>\n        </template>\n      </v-autocomplete>\n    </v-card-text>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const isEditing = ref(false)\n  const model = ref(null)\n\n  const states = [\n    'Alabama',\n    'Alaska',\n    'American Samoa',\n    'Arizona',\n    'Arkansas',\n    'California',\n    'Colorado',\n    'Connecticut',\n    'Delaware',\n    'District of Columbia',\n    'Federated States of Micronesia',\n    'Florida',\n    'Georgia',\n    'Guam',\n    'Hawaii',\n    'Idaho',\n    'Illinois',\n    'Indiana',\n    'Iowa',\n    'Kansas',\n    'Kentucky',\n    'Louisiana',\n    'Maine',\n    'Marshall Islands',\n    'Maryland',\n    'Massachusetts',\n    'Michigan',\n    'Minnesota',\n    'Mississippi',\n    'Missouri',\n    'Montana',\n    'Nebraska',\n    'Nevada',\n    'New Hampshire',\n    'New Jersey',\n    'New Mexico',\n    'New York',\n    'North Carolina',\n    'North Dakota',\n    'Northern Mariana Islands',\n    'Ohio',\n    'Oklahoma',\n    'Oregon',\n    'Palau',\n    'Pennsylvania',\n    'Puerto Rico',\n    'Rhode Island',\n    'South Carolina',\n    'South Dakota',\n    'Tennessee',\n    'Texas',\n    'Utah',\n    'Vermont',\n    'Virgin Island',\n    'Virginia',\n    'Washington',\n    'West Virginia',\n    'Wisconsin',\n    'Wyoming',\n  ]\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        isEditing: false,\n        model: null,\n        states: [\n          'Alabama', 'Alaska', 'American Samoa', 'Arizona',\n          'Arkansas', 'California', 'Colorado', 'Connecticut',\n          'Delaware', 'District of Columbia', 'Federated States of Micronesia',\n          'Florida', 'Georgia', 'Guam', 'Hawaii', 'Idaho',\n          'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky',\n          'Louisiana', 'Maine', 'Marshall Islands', 'Maryland',\n          'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi',\n          'Missouri', 'Montana', 'Nebraska', 'Nevada',\n          'New Hampshire', 'New Jersey', 'New Mexico', 'New York',\n          'North Carolina', 'North Dakota', 'Northern Mariana Islands', 'Ohio',\n          'Oklahoma', 'Oregon', 'Palau', 'Pennsylvania', 'Puerto Rico',\n          'Rhode Island', 'South Carolina', 'South Dakota', 'Tennessee',\n          'Texas', 'Utah', 'Vermont', 'Virgin Island', 'Virginia',\n          'Washington', 'West Virginia', 'Wisconsin', 'Wyoming',\n        ],\n      }\n    },\n  }\n</script>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2039-72488&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-autocomplete/prop-density.vue",
    "content": "<template>\n  <v-card>\n    <v-container fluid>\n      <v-row>\n        <v-col cols=\"12\">\n          <v-autocomplete\n            v-model=\"values\"\n            :items=\"items\"\n            label=\"Default\"\n          ></v-autocomplete>\n        </v-col>\n\n        <v-col cols=\"12\">\n          <v-autocomplete\n            v-model=\"values\"\n            :items=\"items\"\n            density=\"comfortable\"\n            label=\"Comfortable\"\n          ></v-autocomplete>\n        </v-col>\n\n        <v-col cols=\"12\">\n          <v-autocomplete\n            v-model=\"values\"\n            :items=\"items\"\n            density=\"compact\"\n            label=\"Compact\"\n          ></v-autocomplete>\n        </v-col>\n      </v-row>\n    </v-container>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const items = ['foo', 'bar', 'fizz', 'buzz']\n\n  const values = ref('foo')\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: ['foo', 'bar', 'fizz', 'buzz'],\n      values: 'foo',\n    }),\n  }\n</script>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2723-29554&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-autocomplete/prop-filter-keys.vue",
    "content": "<template>\n  <v-container fluid>\n    <v-autocomplete\n      :filter-keys=\"['title', 'raw.abbr']\"\n      :items=\"states\"\n      item-title=\"name\"\n      label=\"State\"\n    ></v-autocomplete>\n  </v-container>\n</template>\n\n<script setup>\n  const states = [\n    { name: 'Florida', abbr: 'FL' },\n    { name: 'Georgia', abbr: 'GA' },\n    { name: 'Nebraska', abbr: 'NE' },\n    { name: 'California', abbr: 'CA' },\n    { name: 'New York', abbr: 'NY' },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      states: [\n        { name: 'Florida', abbr: 'FL' },\n        { name: 'Georgia', abbr: 'GA' },\n        { name: 'Nebraska', abbr: 'NE' },\n        { name: 'California', abbr: 'CA' },\n        { name: 'New York', abbr: 'NY' },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-autocomplete/prop-filter.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    color=\"purple-lighten-1\"\n    max-width=\"500\"\n  >\n    <v-toolbar color=\"purple\" flat>\n      <v-btn icon=\"mdi-account\"></v-btn>\n\n      <v-toolbar-title class=\"font-weight-light\">\n        User Profile\n      </v-toolbar-title>\n\n      <v-btn\n        icon\n        @click=\"isEditing = !isEditing\"\n      >\n        <v-fade-transition leave-absolute>\n          <v-icon v-if=\"isEditing\">mdi-close</v-icon>\n\n          <v-icon v-else>mdi-pencil</v-icon>\n        </v-fade-transition>\n      </v-btn>\n    </v-toolbar>\n\n    <v-card-text>\n      <v-text-field\n        :disabled=\"!isEditing\"\n        base-color=\"white\"\n        label=\"Name\"\n      ></v-text-field>\n\n      <v-autocomplete\n        :custom-filter=\"customFilter\"\n        :disabled=\"!isEditing\"\n        :items=\"states\"\n        base-color=\"white\"\n        item-title=\"name\"\n        item-value=\"abbr\"\n        label=\"State\"\n      ></v-autocomplete>\n    </v-card-text>\n\n    <v-divider></v-divider>\n\n    <v-card-actions>\n      <v-spacer></v-spacer>\n\n      <v-btn\n        :disabled=\"!isEditing\"\n        @click=\"save\"\n      >\n        Save\n      </v-btn>\n    </v-card-actions>\n\n    <v-snackbar\n      v-model=\"hasSaved\"\n      :timeout=\"2000\"\n      location=\"bottom left\"\n      position=\"absolute\"\n      attach\n    >\n      Your profile has been updated\n    </v-snackbar>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const states = [\n    { name: 'Florida', abbr: 'FL', id: 1 },\n    { name: 'Georgia', abbr: 'GA', id: 2 },\n    { name: 'Nebraska', abbr: 'NE', id: 3 },\n    { name: 'California', abbr: 'CA', id: 4 },\n    { name: 'New York', abbr: 'NY', id: 5 },\n  ]\n\n  const hasSaved = ref(false)\n  const isEditing = ref(null)\n\n  function customFilter (itemTitle, queryText, item) {\n    const textOne = item.raw.name.toLowerCase()\n    const textTwo = item.raw.abbr.toLowerCase()\n    const searchText = queryText.toLowerCase()\n    return textOne.indexOf(searchText) > -1 || textTwo.indexOf(searchText) > -1\n  }\n  function save () {\n    isEditing.value = !isEditing.value\n    hasSaved.value = true\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      hasSaved: false,\n      isEditing: null,\n      states: [\n        { name: 'Florida', abbr: 'FL', id: 1 },\n        { name: 'Georgia', abbr: 'GA', id: 2 },\n        { name: 'Nebraska', abbr: 'NE', id: 3 },\n        { name: 'California', abbr: 'CA', id: 4 },\n        { name: 'New York', abbr: 'NY', id: 5 },\n      ],\n    }),\n\n    methods: {\n      customFilter (itemTitle, queryText, item) {\n        const textOne = item.raw.name.toLowerCase()\n        const textTwo = item.raw.abbr.toLowerCase()\n        const searchText = queryText.toLowerCase()\n\n        return textOne.indexOf(searchText) > -1 ||\n          textTwo.indexOf(searchText) > -1\n      },\n      save () {\n        this.isEditing = !this.isEditing\n        this.hasSaved = true\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-autocomplete/prop-items.vue",
    "content": "<template>\n  <v-container>\n    <v-autocomplete :items=\"items\" label=\"Special items like in VList\" chips multiple></v-autocomplete>\n\n    <v-autocomplete :items=\"items\" label=\"I have custom divider\" chips multiple>\n      <template v-slot:divider=\"{ props }\">\n        <div class=\"d-flex ga-4 align-center\">\n          <v-divider></v-divider>\n          {{ props.text }}\n          <v-divider></v-divider>\n        </div>\n      </template>\n    </v-autocomplete>\n\n    <v-autocomplete :items=\"items\" label=\"I have custom subheader\" chips multiple>\n      <template v-slot:subheader=\"{ props }\">\n        <v-list-subheader class=\"font-weight-bold bg-primary\">{{ props.title }}</v-list-subheader>\n      </template>\n    </v-autocomplete>\n  </v-container>\n</template>\n\n<script setup>\n  const items = [\n    { type: 'subheader', title: 'Group 1' },\n    { title: 'Item 1.1', value: 11 },\n    { title: 'Item 1.2', value: 12 },\n    { title: 'Item 1.3', value: 13 },\n    { title: 'Item 1.4', value: 14 },\n    { type: 'divider', text: 'or' },\n    { type: 'subheader', title: 'Group 2' },\n    { title: 'Item 2.1', value: 21 },\n    { title: 'Item 2.2', value: 22 },\n    { title: 'Item 2.3', value: 23 },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        { type: 'subheader', title: 'Group 1' },\n        { title: 'Item 1.1', value: 11 },\n        { title: 'Item 1.2', value: 12 },\n        { title: 'Item 1.3', value: 13 },\n        { title: 'Item 1.4', value: 14 },\n        { type: 'divider', text: 'or' },\n        { type: 'subheader', title: 'Group 2' },\n        { title: 'Item 2.1', value: 21 },\n        { title: 'Item 2.2', value: 22 },\n        { title: 'Item 2.3', value: 23 },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-autocomplete/slot-item-and-selection.vue",
    "content": "<template>\n  <v-card\n    :loading=\"isUpdating\"\n    class=\"mx-auto\"\n    color=\"blue-grey-darken-1\"\n    max-width=\"420\"\n  >\n    <template v-slot:loader=\"{ isActive }\">\n      <v-progress-linear\n        :active=\"isActive\"\n        color=\"green-lighten-3\"\n        height=\"4\"\n        indeterminate\n      ></v-progress-linear>\n    </template>\n\n    <v-img\n      height=\"200\"\n      src=\"https://cdn.vuetifyjs.com/images/cards/dark-beach.jpg\"\n      cover\n    >\n      <v-row class=\"pa-3\">\n        <v-col cols=\"12\">\n          <v-menu\n            location=\"bottom start\"\n            origin=\"overlap\"\n            transition=\"slide-y-transition\"\n          >\n            <template v-slot:activator=\"{ props }\">\n              <v-btn\n                v-bind=\"props\"\n                density=\"comfortable\"\n                icon=\"mdi-dots-vertical\"\n                variant=\"tonal\"\n              ></v-btn>\n            </template>\n\n            <v-list :lines=\"false\">\n              <v-list-item\n                title=\"Update\"\n                @click=\"isUpdating = true\"\n              ></v-list-item>\n            </v-list>\n          </v-menu>\n        </v-col>\n\n        <v-row>\n          <v-col class=\"text-center\">\n            <h3 class=\"text-headline-small my-0\">{{ name }}</h3>\n\n            <span class=\"text-grey-lighten-1\">{{ title }}</span>\n          </v-col>\n        </v-row>\n      </v-row>\n    </v-img>\n\n    <v-form>\n      <v-container>\n        <v-row density=\"comfortable\">\n          <v-col cols=\"12\" md=\"6\">\n            <v-text-field\n              v-model=\"name\"\n              :disabled=\"isUpdating\"\n              color=\"blue-grey-lighten-2\"\n              label=\"Name\"\n            ></v-text-field>\n          </v-col>\n\n          <v-col cols=\"12\" md=\"6\">\n            <v-text-field\n              v-model=\"title\"\n              :disabled=\"isUpdating\"\n              color=\"blue-grey-lighten-2\"\n              label=\"Title\"\n            ></v-text-field>\n          </v-col>\n\n          <v-col cols=\"12\">\n            <v-autocomplete\n              v-model=\"friends\"\n              :disabled=\"isUpdating\"\n              :items=\"people\"\n              color=\"blue-grey-lighten-2\"\n              item-title=\"name\"\n              item-value=\"name\"\n              label=\"Select\"\n              chips\n              closable-chips\n              multiple\n            >\n              <template v-slot:chip=\"{ props, item }\">\n                <v-chip\n                  v-bind=\"props\"\n                  :prepend-avatar=\"item.avatar\"\n                  :text=\"item.name\"\n                ></v-chip>\n              </template>\n\n              <template v-slot:item=\"{ props, item }\">\n                <v-list-item\n                  v-bind=\"props\"\n                  :prepend-avatar=\"item.avatar\"\n                  :subtitle=\"item.group\"\n                  :title=\"item.name\"\n                ></v-list-item>\n              </template>\n            </v-autocomplete>\n          </v-col>\n        </v-row>\n      </v-container>\n    </v-form>\n\n    <v-divider></v-divider>\n\n    <v-card-actions>\n      <v-switch\n        v-model=\"autoUpdate\"\n        :disabled=\"isUpdating\"\n        class=\"mt-0 ms-2\"\n        color=\"green-lighten-2\"\n        density=\"compact\"\n        label=\"Auto Update\"\n        hide-details\n      ></v-switch>\n\n      <v-spacer></v-spacer>\n\n      <v-btn\n        :disabled=\"autoUpdate\"\n        :loading=\"isUpdating\"\n        :variant=\"isUpdating ? 'tonal' : undefined\"\n        color=\"blue-grey-lighten-3\"\n        prepend-icon=\"mdi-update\"\n        @click=\"isUpdating = true\"\n      >\n        Update Now\n      </v-btn>\n    </v-card-actions>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref, watch } from 'vue'\n\n  const srcs = {\n    1: 'https://cdn.vuetifyjs.com/images/lists/1.jpg',\n    2: 'https://cdn.vuetifyjs.com/images/lists/2.jpg',\n    3: 'https://cdn.vuetifyjs.com/images/lists/3.jpg',\n    4: 'https://cdn.vuetifyjs.com/images/lists/4.jpg',\n    5: 'https://cdn.vuetifyjs.com/images/lists/5.jpg',\n  }\n  const people = [\n    { name: 'Sandra Adams', group: 'Group 1', avatar: srcs[1] },\n    { name: 'Ali Connors', group: 'Group 1', avatar: srcs[2] },\n    { name: 'Trevor Hansen', group: 'Group 1', avatar: srcs[3] },\n    { name: 'Tucker Smith', group: 'Group 1', avatar: srcs[2] },\n    { name: 'Britta Holt', group: 'Group 2', avatar: srcs[4] },\n    { name: 'Jane Smith ', group: 'Group 2', avatar: srcs[5] },\n    { name: 'John Smith', group: 'Group 2', avatar: srcs[1] },\n    { name: 'Sandra Williams', group: 'Group 2', avatar: srcs[3] },\n  ]\n\n  const autoUpdate = ref(true)\n  const friends = ref(['Sandra Adams', 'Britta Holt'])\n  const isUpdating = ref(false)\n  const name = ref('Midnight Crew')\n  const title = ref('The summer breeze')\n\n  let timeout = -1\n  watch(isUpdating, val => {\n    clearTimeout(timeout)\n    if (val) {\n      timeout = setTimeout(() => (isUpdating.value = false), 3000)\n    }\n  })\n</script>\n\n<script>\n  export default {\n    data () {\n      const srcs = {\n        1: 'https://cdn.vuetifyjs.com/images/lists/1.jpg',\n        2: 'https://cdn.vuetifyjs.com/images/lists/2.jpg',\n        3: 'https://cdn.vuetifyjs.com/images/lists/3.jpg',\n        4: 'https://cdn.vuetifyjs.com/images/lists/4.jpg',\n        5: 'https://cdn.vuetifyjs.com/images/lists/5.jpg',\n      }\n\n      return {\n        autoUpdate: true,\n        friends: ['Sandra Adams', 'Britta Holt'],\n        isUpdating: false,\n        name: 'Midnight Crew',\n        people: [\n          // TODO: https://github.com/vuetifyjs/vuetify/issues/15721\n          // { header: 'Group 1' },\n          { name: 'Sandra Adams', group: 'Group 1', avatar: srcs[1] },\n          { name: 'Ali Connors', group: 'Group 1', avatar: srcs[2] },\n          { name: 'Trevor Hansen', group: 'Group 1', avatar: srcs[3] },\n          { name: 'Tucker Smith', group: 'Group 1', avatar: srcs[2] },\n          // { divider: true },\n          // { header: 'Group 2' },\n          { name: 'Britta Holt', group: 'Group 2', avatar: srcs[4] },\n          { name: 'Jane Smith ', group: 'Group 2', avatar: srcs[5] },\n          { name: 'John Smith', group: 'Group 2', avatar: srcs[1] },\n          { name: 'Sandra Williams', group: 'Group 2', avatar: srcs[3] },\n        ],\n        title: 'The summer breeze',\n        timeout: null,\n      }\n    },\n\n    watch: {\n      isUpdating (val) {\n        clearTimeout(this.timeout)\n\n        if (val) {\n          this.timeout = setTimeout(() => (this.isUpdating = false), 3000)\n        }\n      },\n    },\n\n    methods: {\n      remove (item) {\n        const index = this.friends.indexOf(item.name)\n        if (index >= 0) this.friends.splice(index, 1)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-autocomplete/slot-item-and-vbind-props.vue",
    "content": "<template>\n  <v-container>\n    <v-autocomplete :items=\"items\">\n      <template v-slot:item=\"{ props }\">\n        <v-list-item v-bind=\"props\"></v-list-item>\n      </template>\n    </v-autocomplete>\n  </v-container>\n</template>\n\n<script setup>\n  const items = [\n    ...Array.from({ length: 50 }, (_, i) => ({\n      value: (i + 3).toString().padStart(19, '0'),\n      title: `Mock  ${i + 1}`,\n    })),\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: Array.from({ length: 50 }, (_, i) => ({\n        value: (i + 3).toString().padStart(19, '0'),\n        title: `Mock ${i + 1}`,\n      })),\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-autocomplete/slot-menu-footer.vue",
    "content": "<template>\n  <v-container>\n    <v-autocomplete\n      v-model=\"model\"\n      v-model:menu=\"menu\"\n      :items=\"items\"\n      item-title=\"value\"\n      item-value=\"id\"\n      hide-details\n      multiple\n    >\n      <template v-slot:menu-footer>\n        <div class=\"d-flex justify-space-between pa-2 border-t\">\n          <v-btn text=\"Clear\" variant=\"text\" @click=\"model = []\"></v-btn>\n          <v-btn text=\"Done\" variant=\"tonal\" @click=\"menu = false\"></v-btn>\n        </div>\n      </template>\n    </v-autocomplete>\n  </v-container>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const items = Array.from({ length: 50 }, (_, i) => ({ id: i, value: `Item ${i + 1}` }))\n\n  const model = shallowRef([])\n  const menu = shallowRef(false)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: Array.from({ length: 50 }, (_, i) => ({ id: i, value: `Item ${i + 1}` })),\n      model: [],\n      menu: false,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-autocomplete/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div>\n      <v-autocomplete v-bind=\"props\"></v-autocomplete>\n    </div>\n\n    <template v-slot:configuration>\n      <v-checkbox v-model=\"clear\" label=\"Clearable\"></v-checkbox>\n\n      <v-checkbox v-model=\"chips\" label=\"Chips\"></v-checkbox>\n\n      <v-checkbox v-model=\"multiple\" label=\"Multiple\"></v-checkbox>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-autocomplete'\n  const model = ref('default')\n  const clear = ref(false)\n  const chips = ref(false)\n  const multiple = ref(false)\n  const options = ['outlined', 'underlined', 'solo', 'solo-filled', 'solo-inverted']\n  const props = computed(() => {\n    return {\n      clearable: clear.value || undefined,\n      chips: chips.value || undefined,\n      label: 'Autocomplete',\n      items: ['California', 'Colorado', 'Florida', 'Georgia', 'Texas', 'Wyoming'],\n      multiple: multiple.value || undefined,\n      variant: model.value === 'default' ? undefined : model.value,\n    }\n  })\n\n  const slots = computed(() => {\n    return ``\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-avatar/misc-advanced.vue",
    "content": "<template>\n  <v-expansion-panels class=\"pa-4\" variant=\"popout\">\n    <v-expansion-panel\n      v-for=\"(message, i) in messages\"\n      :key=\"i\"\n      hide-actions\n    >\n      <v-expansion-panel-title>\n        <v-row\n          class=\"spacer align-center\"\n          density=\"compact\"\n        >\n          <v-col\n            cols=\"4\"\n            md=\"1\"\n            sm=\"2\"\n          >\n            <v-avatar\n              size=\"36px\"\n            >\n              <v-img\n                v-if=\"message.avatar\"\n                alt=\"Avatar\"\n                src=\"https://avatars0.githubusercontent.com/u/9064066?v=4&s=460\"\n              ></v-img>\n              <v-icon\n                v-else\n                :color=\"message.color\"\n                :icon=\"message.icon\"\n              ></v-icon>\n            </v-avatar>\n          </v-col>\n\n          <v-col\n            class=\"hidden-xs text-left ms-2\"\n            md=\"3\"\n            sm=\"5\"\n          >\n            <strong v-html=\"message.name\"></strong>\n            <span\n              v-if=\"message.total\"\n              class=\"text-grey\"\n            >\n              &nbsp;({{ message.total }})\n            </span>\n          </v-col>\n\n          <v-col\n            class=\"text-no-wrap text-left\"\n            cols=\"5\"\n            sm=\"3\"\n          >\n            <v-chip\n              v-if=\"message.new\"\n              :color=\"`${message.color}-lighten-1`\"\n              class=\"ms-0 me-2\"\n              size=\"small\"\n              label\n            >\n              {{ message.new }} new\n            </v-chip>\n            <strong v-html=\"message.title\"></strong>\n          </v-col>\n\n          <v-col\n            v-if=\"message.excerpt\"\n            class=\"text-medium-emphasis text-truncate hidden-sm-and-down\"\n          >\n            &mdash;\n            {{ message.excerpt }}\n          </v-col>\n        </v-row>\n      </v-expansion-panel-title>\n\n      <v-expansion-panel-text>\n        <v-card-text v-text=\"lorem\"></v-card-text>\n      </v-expansion-panel-text>\n    </v-expansion-panel>\n  </v-expansion-panels>\n</template>\n\n<script setup>\n  const messages = [\n    {\n      avatar: 'https://avatars0.githubusercontent.com/u/9064066?v=4&s=460',\n      name: 'John Leider',\n      title: 'Welcome to Vuetify!',\n      excerpt: 'Thank you for joining our community...',\n    },\n    {\n      color: 'red',\n      icon: 'mdi-account-multiple',\n      name: 'Social',\n      new: 1,\n      total: 3,\n      title: 'Twitter',\n    },\n    {\n      color: 'teal',\n      icon: 'mdi-tag',\n      name: 'Promos',\n      new: 2,\n      total: 4,\n      title: 'Shop your way',\n      excerpt: 'New deals available, Join Today',\n    },\n  ]\n  const lorem = 'Lorem ipsum dolor sit amet, at aliquam vivendum vel, everti delicatissimi cu eos. Dico iuvaret debitis mel an, et cum zril menandri. Eum in consul legimus accusam. Ea dico abhorreant duo, quo illum minimum incorrupte no, nostro voluptaria sea eu. Suas eligendi ius at, at nemore equidem est. Sed in error hendrerit, in consul constituam cum.'\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      messages: [\n        {\n          avatar: 'https://avatars0.githubusercontent.com/u/9064066?v=4&s=460',\n          name: 'John Leider',\n          title: 'Welcome to Vuetify!',\n          excerpt: 'Thank you for joining our community...',\n        },\n        {\n          color: 'red',\n          icon: 'mdi-account-multiple',\n          name: 'Social',\n          new: 1,\n          total: 3,\n          title: 'Twitter',\n        },\n        {\n          color: 'teal',\n          icon: 'mdi-tag',\n          name: 'Promos',\n          new: 2,\n          total: 4,\n          title: 'Shop your way',\n          excerpt: 'New deals available, Join Today',\n        },\n      ],\n      lorem: 'Lorem ipsum dolor sit amet, at aliquam vivendum vel, everti delicatissimi cu eos. Dico iuvaret debitis mel an, et cum zril menandri. Eum in consul legimus accusam. Ea dico abhorreant duo, quo illum minimum incorrupte no, nostro voluptaria sea eu. Suas eligendi ius at, at nemore equidem est. Sed in error hendrerit, in consul constituam cum.',\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-avatar/misc-avatar-menu.vue",
    "content": "<template>\n  <v-container\n    style=\"height: 300px\"\n    fluid\n  >\n    <v-row class=\"justify-center\">\n      <v-menu min-width=\"200px\">\n        <template v-slot:activator=\"{ props }\">\n          <v-btn\n            icon\n            v-bind=\"props\"\n          >\n            <v-avatar\n              color=\"brown\"\n              size=\"large\"\n            >\n              <span class=\"text-headline-small\">{{ user.initials }}</span>\n            </v-avatar>\n          </v-btn>\n        </template>\n        <v-card>\n          <v-card-text>\n            <div class=\"mx-auto text-center\">\n              <v-avatar\n                color=\"brown\"\n              >\n                <span class=\"text-headline-small\">{{ user.initials }}</span>\n              </v-avatar>\n              <h3 class=\"my-0\">{{ user.fullName }}</h3>\n              <p class=\"text-body-small mt-1\">\n                {{ user.email }}\n              </p>\n              <v-divider class=\"my-3\"></v-divider>\n              <v-btn\n                variant=\"text\"\n                rounded\n              >\n                Edit Account\n              </v-btn>\n              <v-divider class=\"my-3\"></v-divider>\n              <v-btn\n                variant=\"text\"\n                rounded\n              >\n                Disconnect\n              </v-btn>\n            </div>\n          </v-card-text>\n        </v-card>\n      </v-menu>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  const user = {\n    initials: 'JD',\n    fullName: 'John Doe',\n    email: 'john.doe@doe.com',\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      user: {\n        initials: 'JD',\n        fullName: 'John Doe',\n        email: 'john.doe@doe.com',\n      },\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-avatar/misc-profile-card.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"434\"\n    rounded=\"0\"\n  >\n    <v-img\n      height=\"100%\"\n      src=\"https://cdn.vuetifyjs.com/images/cards/server-room.jpg\"\n      cover\n    >\n      <v-avatar\n        color=\"grey\"\n        rounded=\"0\"\n        size=\"150\"\n      >\n        <v-img src=\"https://cdn.vuetifyjs.com/images/profiles/marcus.jpg\" cover></v-img>\n      </v-avatar>\n      <v-list-item\n        class=\"text-white\"\n        subtitle=\"Network Engineer\"\n        title=\"Marcus Obrien\"\n      ></v-list-item>\n    </v-img>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-avatar/prop-badge.vue",
    "content": "<template>\n  <div class=\"py-6\">\n    <v-row class=\"ga-6 align-end justify-center\">\n      <v-avatar\n        v-for=\"(img, i) in users\"\n        :key=\"i\"\n        :badge=\"colors[i]\"\n        :image=\"img\"\n        :size=\"sizes[i]\"\n      ></v-avatar>\n    </v-row>\n\n    <v-row class=\"ga-6 mt-6 align-end justify-center\">\n      <v-avatar\n        v-for=\"(img, i) in users\"\n        :key=\"i\"\n        :badge=\"{ color: colors[i], location: 'bottom end', floating: true }\"\n        :image=\"img\"\n        :size=\"sizes[i]\"\n        rounded=\"lg\"\n      ></v-avatar>\n    </v-row>\n\n    <v-row class=\"ga-6 mt-6 align-end justify-center\">\n      <v-avatar\n        v-for=\"(img, i) in users\"\n        :key=\"i\"\n        :badge=\"{ color: colors[i], location: 'bottom end', floating: true }\"\n        :image=\"img\"\n        :size=\"sizes[i]\"\n        rounded=\"lg\"\n      >\n        <template v-slot:badge>\n          <v-icon :icon=\"icons[i]\"></v-icon>\n        </template>\n      </v-avatar>\n    </v-row>\n  </div>\n</template>\n\n<script setup>\n  const sizes = ['x-small', 'small', 'default', 'large', 'x-large']\n  const colors = ['primary', 'red', 'success', 'purple', 'warning']\n  const icons = ['mdi-star', '$close', '$complete', 'mdi-reply', 'mdi-thumb-up']\n  const users = Array.from({ length: 5 })\n    .map((_, i) => `https://vuetifyjs.b-cdn.net/docs/images/one/snips/avatars/${2 + i}.jpg`)\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-avatar/prop-size.vue",
    "content": "<template>\n  <div class=\"d-flex align-center justify-space-around\">\n    <v-avatar color=\"primary\" size=\"x-small\">\n      32\n    </v-avatar>\n\n    <v-avatar color=\"secondary\">\n      48\n    </v-avatar>\n\n    <v-avatar color=\"info\" size=\"x-large\">\n      64\n    </v-avatar>\n  </div>\n</template>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2766-83743&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-avatar/prop-tile.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-avatar\n      color=\"blue-darken-2\"\n      rounded=\"0\"\n    >\n      <v-icon icon=\"mdi-alarm\"></v-icon>\n    </v-avatar>\n  </div>\n</template>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2766-83749&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-avatar/slot-default.vue",
    "content": "<template>\n  <div class=\"d-flex align-center justify-space-around\">\n    <v-avatar color=\"info\">\n      <v-icon icon=\"mdi-account-circle\"></v-icon>\n    </v-avatar>\n\n    <v-avatar>\n      <v-img\n        alt=\"John\"\n        src=\"https://cdn.vuetifyjs.com/images/john.jpg\"\n      ></v-img>\n    </v-avatar>\n\n    <v-avatar color=\"red\">\n      <span class=\"text-headline-small\">CJ</span>\n    </v-avatar>\n  </div>\n</template>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2771-90954&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-avatar/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :options=\"options\"\n    name=\"v-avatar\"\n  >\n    <div class=\"text-center\">\n      <v-avatar\n        v-bind=\"props\"\n        :image=\"image ? 'https://cdn.vuetifyjs.com/images/john-smirk.png' : undefined\"\n      ></v-avatar>\n    </div>\n\n    <template v-slot:configuration>\n      <v-checkbox v-model=\"icon\" label=\"Icon\"></v-checkbox>\n\n      <v-checkbox v-model=\"image\" label=\"Image\"></v-checkbox>\n\n      <v-slider\n        v-model=\"size\"\n        label=\"Size\"\n        max=\"80\"\n        min=\"40\"\n        step=\"1\"\n      ></v-slider>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const model = ref('default')\n  const icon = ref(false)\n  const image = ref(false)\n  const size = ref(40)\n  const options = ['tile']\n  const props = computed(() => {\n    return {\n      color: !image.value && !icon.value ? 'surface-variant' : undefined,\n      icon: icon.value ? '$vuetify' : undefined,\n      image: image.value ? 'smirk.png' : undefined,\n      rounded: model.value === 'tile' ? '0' : undefined,\n      size: size.value === 40 ? undefined : `${size.value}`,\n    }\n  })\n\n  const slots = computed(() => {\n    return ''\n  })\n\n  const code = computed(() => {\n    return `<v-avatar${propsToString(props.value)}>${slots.value}</v-avatar>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-avatar-group/misc-hoverable.vue",
    "content": "<template>\n  <v-sheet class=\"bg-indigo py-6 px-4\">\n    <v-avatar-group\n      :gap=\"-8\"\n      :item-props=\"item => ({ image: item.avatarUrl })\"\n      :items=\"users\"\n      border=\"sm opacity-100\"\n      hoverable\n      reverse\n    >\n      <template v-slot:item=\"{ props, index }\">\n        <v-avatar\n          v-bind=\"props\"\n          rounded=\"lg\"\n          v-tooltip=\"{ text: `User #100${index}`, location: 'bottom' }\"\n        ></v-avatar>\n      </template>\n      <template v-slot:append>\n        <v-chip text=\"+ 48,233\"></v-chip>\n      </template>\n    </v-avatar-group>\n  </v-sheet>\n</template>\n\n<script setup>\n  const users = Array.from({ length: 7 })\n    .map((_, i) => ({ avatarUrl: `https://vuetifyjs.b-cdn.net/docs/images/one/snips/avatars/${i}.jpg` }))\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      users: Array.from({ length: 7 })\n        .map((_, i) => ({ avatarUrl: `https://vuetifyjs.b-cdn.net/docs/images/one/snips/avatars/${i}.jpg` })),\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-avatar-group/prop-items.vue",
    "content": "<template>\n  <v-container class=\"d-flex justify-center\">\n    <v-avatar-group\n      :items=\"items\"\n      border=\"md surface opacity-100\"\n    ></v-avatar-group>\n  </v-container>\n</template>\n\n<script setup>\n  const items = [\n    { image: 'https://vuetifyjs.b-cdn.net/docs/images/one/snips/avatars/3.jpg' },\n    { image: 'https://vuetifyjs.b-cdn.net/docs/images/one/snips/avatars/4.jpg' },\n    { icon: 'mdi-account', color: 'info' },\n    { text: 'JD', color: 'primary' },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        { image: 'https://vuetifyjs.b-cdn.net/docs/images/one/snips/avatars/3.jpg' },\n        { image: 'https://vuetifyjs.b-cdn.net/docs/images/one/snips/avatars/4.jpg' },\n        { icon: 'mdi-account', color: 'info' },\n        { text: 'JD', color: 'primary' },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-avatar-group/prop-reverse.vue",
    "content": "<template>\n  <v-container class=\"d-flex justify-center ga-12\">\n    <v-avatar-group :items=\"items\" reverse></v-avatar-group>\n    <v-avatar-group reverse>\n      <v-avatar v-for=\"(item, i) in items2.toReversed()\" :key=\"i\" v-bind=\"item\"></v-avatar>\n    </v-avatar-group>\n  </v-container>\n</template>\n\n<script setup>\n  const items = [\n    { text: 'BK', color: 'primary' },\n    { text: 'RF', color: 'secondary' },\n    { text: 'CA', color: '#E91E63' },\n    { text: 'PE', color: '#9C27B0' },\n    { text: 'WA', color: '#00BCD4' },\n  ]\n  const items2 = [\n    { text: '#1', color: 'primary' },\n    { text: '#2', color: 'secondary' },\n    { text: '#3', color: '#E91E63' },\n    { text: '#4', color: '#00BCD4' },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        { text: 'BK', color: 'primary' },\n        { text: 'RF', color: 'secondary' },\n        { text: 'CA', color: '#E91E63' },\n        { text: 'PE', color: '#9C27B0' },\n        { text: 'WA', color: '#00BCD4' },\n      ],\n      items2: [\n        { text: '#1', color: 'primary' },\n        { text: '#2', color: 'secondary' },\n        { text: '#3', color: '#E91E63' },\n        { text: '#4', color: '#00BCD4' },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-avatar-group/prop-size.vue",
    "content": "<template>\n  <div class=\"d-flex flex-column ga-4 align-center py-3\">\n    <v-avatar-group\n      v-for=\"{ size, gap } in sizeGroups\"\n      :key=\"size\"\n      :gap=\"gap\"\n      :items=\"items\"\n      :size=\"size\"\n    ></v-avatar-group>\n  </div>\n</template>\n\n<script setup>\n  const items = Array.from({ length: 5 })\n    .map((_, i) => ({ image: `https://vuetifyjs.b-cdn.net/docs/images/one/snips/avatars/${i}.jpg` }))\n\n  const sizeGroups = [\n    { size: 'x-small', gap: -6 },\n    { size: 'small', gap: -8 },\n    { size: 'default', gap: -12 },\n    { size: 'large', gap: -16 },\n    { size: 'x-large', gap: -20 },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: Array.from({ length: 5 })\n        .map((_, i) => ({ image: `https://vuetifyjs.b-cdn.net/docs/images/one/snips/avatars/${i}.jpg` })),\n      sizeGroups: [\n        { size: 'x-small', gap: -6 },\n        { size: 'small', gap: -8 },\n        { size: 'default', gap: -12 },\n        { size: 'large', gap: -16 },\n        { size: 'x-large', gap: -20 },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-avatar-group/prop-vertical.vue",
    "content": "<template>\n  <div class=\"d-flex ga-8 justify-center py-3\">\n    <v-avatar-group\n      :items=\"items\"\n      border=\"md surface-variant opacity-100\"\n      vertical\n    ></v-avatar-group>\n\n    <v-avatar-group\n      :items=\"items\"\n      border=\"md surface-variant opacity-100\"\n      reverse\n      vertical\n    ></v-avatar-group>\n  </div>\n</template>\n\n<script setup>\n  const items = Array.from({ length: 4 })\n    .map((_, i) => ({ image: `https://vuetifyjs.b-cdn.net/docs/images/one/snips/avatars/${i}.jpg` }))\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: Array.from({ length: 4 })\n        .map((_, i) => ({ image: `https://vuetifyjs.b-cdn.net/docs/images/one/snips/avatars/${i}.jpg` })),\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-avatar-group/slot-overflow.vue",
    "content": "<template>\n  <v-container class=\"d-flex justify-center\">\n    <v-avatar-group\n      :items=\"items\"\n      :limit=\"3\"\n    >\n      <template v-slot:overflow=\"{ overflow }\">\n        <v-avatar color=\"grey-lighten-1\">\n          <v-icon icon=\"mdi-dots-horizontal\"></v-icon>\n\n          <v-tooltip activator=\"parent\" location=\"bottom\">\n            {{ overflow }} more users\n          </v-tooltip>\n        </v-avatar>\n      </template>\n    </v-avatar-group>\n  </v-container>\n</template>\n\n<script setup>\n  const items = [\n    { text: 'MG', color: 'primary' },\n    { text: 'RF', color: 'secondary' },\n    { text: 'CA', color: '#E91E63' },\n    { text: 'PE', color: '#9C27B0' },\n    { text: 'WA', color: '#00BCD4' },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        { text: 'MG', color: 'primary' },\n        { text: 'RF', color: 'secondary' },\n        { text: 'CA', color: '#E91E63' },\n        { text: 'PE', color: '#9C27B0' },\n        { text: 'WA', color: '#00BCD4' },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-avatar-group/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"[]\"\n    :script=\"script\"\n  >\n    <div class=\"d-flex justify-center\">\n      <v-avatar-group v-bind=\"props\" :items=\"items\"></v-avatar-group>\n    </div>\n\n    <template v-slot:configuration>\n      <v-slider\n        v-model=\"limit\"\n        label=\"Limit\"\n        max=\"5\"\n        min=\"1\"\n        step=\"1\"\n        thumb-label\n      ></v-slider>\n      <v-slider\n        v-model=\"gap\"\n        label=\"Gap\"\n        max=\"8\"\n        min=\"-24\"\n        step=\"4\"\n        thumb-label\n      ></v-slider>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-avatar-group'\n  const model = ref('default')\n  const limit = ref(3)\n  const gap = ref(-12)\n\n  const items = [\n    { image: 'https://vuetifyjs.b-cdn.net/docs/images/one/snips/avatars/3.jpg' },\n    { image: 'https://vuetifyjs.b-cdn.net/docs/images/one/snips/avatars/4.jpg' },\n    { icon: 'mdi-account', color: 'info' },\n    { text: 'JD', color: 'primary' },\n    { icon: 'mdi-account', color: 'success' },\n  ]\n\n  const props = computed(() => {\n    return {\n      border: 'md surface opacity-100',\n      items: 'items',\n      limit: limit.value === 5 ? undefined : limit.value,\n      gap: gap.value === -12 ? undefined : gap.value,\n    }\n  })\n\n  // eslint doesn't like the script tag inside the template\n  const script = computed(() => {\n    return `<script setup>\n  const items = [\n    { image: 'https://vuetifyjs.b-cdn.net/docs/images/one/snips/avatars/3.jpg' },\n    { image: 'https://vuetifyjs.b-cdn.net/docs/images/one/snips/avatars/4.jpg' },\n    { icon: 'mdi-account', color: 'info' },\n    { text: 'JD', color: 'primary' },\n    { icon: 'mdi-account', color: 'success' },\n  ]\n<` + '/script>'\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value, ['items'])}></${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-badge/misc-customization.vue",
    "content": "<template>\n  <div class=\"d-flex justify-space-around align-center flex-column flex-md-row fill-height\">\n    <v-badge\n      color=\"error\"\n      icon=\"mdi-lock\"\n      bordered\n    >\n      <v-btn\n        color=\"error\"\n        variant=\"flat\"\n      >\n        Lock Account\n      </v-btn>\n    </v-badge>\n\n    <v-badge\n      color=\"deep-purple-accent-4\"\n      location=\"bottom end\"\n      offset-x=\"2\"\n      offset-y=\"4\"\n      bordered\n      dot\n    >\n      <v-avatar size=\"large\">\n        <v-img src=\"https://cdn.vuetifyjs.com/images/lists/2.jpg\"></v-img>\n      </v-avatar>\n    </v-badge>\n\n    <div class=\"mx-3\"></div>\n\n    <v-badge\n      bordered\n    >\n      <template v-slot:badge>\n        <v-avatar size=\"x-small\">\n          <v-img src=\"https://cdn.vuetifyjs.com/images/logos/v.png\"></v-img>\n        </v-avatar>\n      </template>\n\n      <v-avatar size=\"large\">\n        <v-img src=\"https://cdn.vuetifyjs.com/images/john.png\"></v-img>\n      </v-avatar>\n    </v-badge>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-badge/misc-dynamic.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"justify-space-around\">\n      <div>\n        <v-btn\n          class=\"mx-1\"\n          color=\"primary\"\n          @click=\"messages++\"\n        >\n          Send Message\n        </v-btn>\n\n        <v-btn\n          class=\"mx-1\"\n          color=\"error\"\n          @click=\"messages = 0\"\n        >\n          Clear Notifications\n        </v-btn>\n      </div>\n\n      <v-badge\n        :content=\"messages\"\n        :model-value=\"!!messages\"\n        color=\"green\"\n      >\n        <v-icon size=\"large\">\n          $vuetify\n        </v-icon>\n      </v-badge>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const messages = ref(0)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        messages: 0,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-badge/misc-hover.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-badge\n      :model-value=\"hover\"\n      color=\"deep-purple\"\n      content=\"9999+\"\n      location=\"top-end\"\n      transition=\"slide-x-transition\"\n    >\n      <v-hover v-slot=\"{ props }\" v-model=\"hover\">\n        <v-icon\n          color=\"grey-lighten-1\"\n          size=\"large\"\n          v-bind=\"props\"\n        >\n          mdi-account\n        </v-icon>\n      </v-hover>\n    </v-badge>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const hover = ref(false)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      hover: false,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-badge/misc-tabs.vue",
    "content": "<template>\n  <v-tabs\n    bg-color=\"primary\"\n    grow\n  >\n    <v-tab>\n      <v-badge\n        color=\"pink\"\n        dot\n      >\n        Item One\n      </v-badge>\n    </v-tab>\n\n    <v-tab>\n      <v-badge\n        color=\"green\"\n        content=\"6\"\n      >\n        Item Two\n      </v-badge>\n    </v-tab>\n\n    <v-tab>\n      <v-badge\n        color=\"deep-purple-accent-4\"\n        icon=\"$vuetify\"\n      >\n        Item Three\n      </v-badge>\n    </v-tab>\n  </v-tabs>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-badge/prop-content.vue",
    "content": "<template>\n  <v-toolbar color=\"blue-grey-darken-3\">\n    <v-spacer></v-spacer>\n\n    <v-btn class=\"text-none\" stacked>\n      <v-badge color=\"success\" dot>\n        <v-icon>mdi-home-outline</v-icon>\n      </v-badge>\n    </v-btn>\n\n    <v-btn class=\"text-none\" stacked>\n      <v-icon>mdi-account-multiple-outline</v-icon>\n    </v-btn>\n\n    <v-btn class=\"text-none\" stacked>\n      <v-badge color=\"error\" content=\"9+\">\n        <v-icon>mdi-store-outline</v-icon>\n      </v-badge>\n    </v-btn>\n\n    <v-btn class=\"text-none\" stacked>\n      <v-badge color=\"error\" content=\"2\">\n        <v-icon>mdi-bell-outline</v-icon>\n      </v-badge>\n    </v-btn>\n\n    <v-btn class=\"text-none\" stacked>\n      <v-icon>mdi-menu</v-icon>\n    </v-btn>\n\n    <v-spacer></v-spacer>\n  </v-toolbar>\n</template>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2239-35932&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-badge/prop-dot.vue",
    "content": "<template>\n  <v-toolbar color=\"grey-lighten-3\" title=\"Application\">\n    <v-btn stacked>\n      <v-badge\n        color=\"error\"\n        dot\n      >\n        <v-icon icon=\"mdi-newspaper-variant-outline\"></v-icon>\n      </v-badge>\n\n      News\n    </v-btn>\n\n    <v-btn stacked>\n      <v-badge\n        color=\"error\"\n        dot\n      >\n        <v-icon icon=\"mdi-post\"></v-icon>\n      </v-badge>\n\n      Blog\n    </v-btn>\n\n    <v-btn\n      variant=\"tonal\"\n      stacked\n    >\n      <v-icon icon=\"mdi-login\"></v-icon>\n\n      Login\n    </v-btn>\n  </v-toolbar>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-badge/prop-inline.vue",
    "content": "<template>\n  <v-list\n    class=\"mx-auto\"\n    max-width=\"256\"\n    border\n  >\n    <v-list-item\n      prepend-icon=\"mdi-inbox-arrow-down\"\n      title=\"Inbox\"\n      link\n    >\n      <template v-slot:append>\n        <v-badge\n          color=\"error\"\n          content=\"6\"\n          inline\n        ></v-badge>\n      </template>\n    </v-list-item>\n\n    <v-list-item\n      prepend-icon=\"mdi-send\"\n      title=\"Sent Mail\"\n      link\n    ></v-list-item>\n\n    <v-list-item\n      prepend-icon=\"mdi-delete\"\n      title=\"Trash\"\n      link\n    >\n      <template v-slot:append>\n        <v-badge\n          color=\"info\"\n          content=\"12\"\n          inline\n        ></v-badge>\n      </template>\n    </v-list-item>\n\n    <v-list-item\n      prepend-icon=\"mdi-alert-circle\"\n      title=\"Spam\"\n      link\n    ></v-list-item>\n  </v-list>\n</template>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2239-83228&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-badge/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div class=\"d-flex ga-12 justify-center\">\n      <v-badge v-bind=\"props\" color=\"warning\" dot>\n        <v-icon icon=\"mdi-bell\"></v-icon>\n      </v-badge>\n\n      <v-badge v-bind=\"props\" color=\"error\" content=\"1\">\n        <v-icon icon=\"mdi-cog\"></v-icon>\n      </v-badge>\n\n      <v-badge v-bind=\"props\" color=\"success\" content=\"25\">\n        <v-icon icon=\"mdi-calendar\"></v-icon>\n      </v-badge>\n\n      <v-badge v-bind=\"props\" color=\"primary\" content=\"99+\">\n        <v-icon icon=\"mdi-cart\"></v-icon>\n      </v-badge>\n    </div>\n\n    <template v-slot:configuration>\n      <v-checkbox\n        v-model=\"bordered\"\n        label=\"Bordered\"\n        hide-details\n      ></v-checkbox>\n\n      <div v-if=\"model !== 'inline'\">\n        <h5 class=\"pl-2 my-0\">Location</h5>\n        <v-radio-group\n          v-model=\"location\"\n          class=\"pa-1 mb-2\"\n          density=\"compact\"\n          hide-details\n        >\n          <div class=\"d-flex\">\n            <v-radio value=\"top left\"></v-radio>\n            <v-radio value=\"top center\"></v-radio>\n            <v-radio value=\"top right\"></v-radio>\n          </div>\n          <div class=\"d-flex\">\n            <v-radio value=\"left center\"></v-radio>\n            <v-radio class=\"opacity-0\" disabled></v-radio>\n            <v-radio value=\"right center\"></v-radio>\n          </div>\n          <div class=\"d-flex\">\n            <v-radio value=\"bottom left\"></v-radio>\n            <v-radio value=\"bottom center\"></v-radio>\n            <v-radio value=\"bottom right\"></v-radio>\n          </div>\n        </v-radio-group>\n        <v-slider\n          v-if=\"location !== 'top center' && location !== 'bottom center'\"\n          v-model=\"offsetX\"\n          label=\"Offset (x)\"\n          max=\"20\"\n          min=\"-20\"\n          step=\"5\"\n          hide-details\n        ></v-slider>\n        <v-slider\n          v-if=\"location !== 'right center' && location !== 'left center'\"\n          v-model=\"offsetY\"\n          label=\"Offset (y)\"\n          max=\"20\"\n          min=\"-20\"\n          step=\"5\"\n          hide-details\n        ></v-slider>\n      </div>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-badge'\n  const model = ref('default')\n  const content = ref(0)\n  const dot = ref(false)\n  const bordered = ref(false)\n  const options = ['floating', 'inline']\n  const location = ref('top right')\n  const offsetX = ref(0)\n  const offsetY = ref(0)\n  const props = computed(() => {\n    return {\n      content: content.value || undefined,\n      dot: dot.value || undefined,\n      bordered: bordered.value || undefined,\n      floating: model.value === 'floating' || undefined,\n      inline: model.value === 'inline' || undefined,\n      location: location.value,\n      'offset-x': offsetX.value || undefined,\n      'offset-y': offsetY.value || undefined,\n    }\n  })\n\n  const code = computed(() => {\n    return `<div class=\"d-flex ga-12 justify-center\">\n  <v-badge${propsToString(props.value)} color=\"warning\" dot>\n    <v-icon icon=\"mdi-bell\"></v-icon>\n  </v-badge>\n\n  <v-badge${propsToString(props.value)} color=\"error\" content=\"1\">\n    <v-icon icon=\"mdi-cog\"></v-icon>\n  </v-badge>\n\n  <v-badge${propsToString(props.value)} color=\"success\" content=\"25\">\n    <v-icon icon=\"mdi-calendar\"></v-icon>\n  </v-badge>\n\n  <v-badge${propsToString(props.value)} color=\"primary\" content=\"99+\">\n    <v-icon icon=\"mdi-cart\"></v-icon>\n  </v-badge>\n</div>`\n  })\n</script>\n\n<style scoped>\n  ::v-deep(.v-radio) {\n    flex-grow: 0 !important;\n  }\n</style>\n"
  },
  {
    "path": "packages/docs/src/examples/v-banner/prop-lines.vue",
    "content": "<template>\n  <div>\n    <v-banner\n      class=\"my-4\"\n      color=\"deep-purple-accent-4\"\n      icon=\"mdi-lock\"\n      lines=\"one\"\n    >\n      <v-banner-text>\n        Banner with one line of text.\n      </v-banner-text>\n\n      <template v-slot:actions>\n        <v-btn>Action</v-btn>\n      </template>\n    </v-banner>\n\n    <v-banner\n      class=\"my-4\"\n      color=\"error\"\n      icon=\"mdi-weather-hurricane\"\n      lines=\"two\"\n    >\n      <v-banner-text>\n        Banner with two lines of text. If the text is too long to fit on two lines then an ellipsis will be used to hide the remaining content. So this next line will be hidden.\n      </v-banner-text>\n\n      <template v-slot:actions>\n        <v-btn>Action</v-btn>\n      </template>\n    </v-banner>\n\n    <v-banner\n      class=\"my-4\"\n      color=\"warning\"\n      icon=\"$warning\"\n      lines=\"three\"\n    >\n      <v-banner-text>\n        Banner with three lines of text. One or two lines is preferable. Three lines should be considered the absolute maximum length on desktop in order to keep messages short and actionable.\n      </v-banner-text>\n\n      <template v-slot:actions>\n        <v-btn>Action</v-btn>\n      </template>\n    </v-banner>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-banner/prop-sticky.vue",
    "content": "<template>\n  <v-card\n    class=\"overflow-auto mx-auto\"\n    max-height=\"300\"\n    width=\"448\"\n  >\n    <v-toolbar color=\"primary\">\n      <v-toolbar-title>My Document</v-toolbar-title>\n\n      <template v-slot:append>\n        <v-switch\n          v-model=\"sticky\"\n          color=\"secondary\"\n          label=\"Sticky Banner\"\n          hide-details\n        ></v-switch>\n      </template>\n    </v-toolbar>\n\n    <v-banner\n      :sticky=\"sticky\"\n      lines=\"one\"\n    >\n      <template v-slot:text>\n        We can't save your edits while you are in offline mode.\n      </template>\n\n      <template v-slot:actions>\n        <v-btn color=\"deep-purple-accent-4\">\n          Go Online\n        </v-btn>\n      </template>\n    </v-banner>\n\n    <v-card-text class=\"bg-grey-lighten-4\">\n      <v-sheet\n        class=\"mx-auto\"\n        height=\"300\"\n      ></v-sheet>\n    </v-card-text>\n\n    <v-footer\n      class=\"justify-center\"\n      color=\"primary\"\n    >\n      End of Content\n    </v-footer>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const sticky = ref(false)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      sticky: false,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-banner/slot-actions.vue",
    "content": "<template>\n  <v-banner\n    color=\"warning\"\n    icon=\"mdi-wifi-strength-alert-outline\"\n    lines=\"one\"\n  >\n    <template v-slot:text>\n      No Internet connection\n    </template>\n\n    <template v-slot:actions>\n      <v-btn>\n        Dismiss\n      </v-btn>\n\n      <v-btn>\n        Retry\n      </v-btn>\n    </template>\n  </v-banner>\n</template>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2239-85204&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-banner/slot-icon.vue",
    "content": "<template>\n  <v-banner\n    color=\"pink-darken-1\"\n    icon=\"mdi-account-box\"\n    lines=\"two\"\n  >\n    <template v-slot:prepend>\n      <v-avatar></v-avatar>\n    </template>\n\n    <v-banner-text>\n      Banner with two lines of text. If the text is too long to fit on two lines then an ellipsis will be used to hide the remaining content. So this next line will be hidden.\n    </v-banner-text>\n\n    <v-banner-actions>\n      <v-btn>Action Button</v-btn>\n    </v-banner-actions>\n  </v-banner>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-banner/slot-prepend.vue",
    "content": "<template>\n  <v-banner\n    color=\"deep-purple-accent-4\"\n    lines=\"two\"\n  >\n    <template v-slot:prepend>\n      <v-avatar\n        color=\"deep-purple-accent-4\"\n        icon=\"mdi-account-filter\"\n      ></v-avatar>\n    </template>\n\n    <v-banner-text>\n      Banner with two lines of text. If the text is too long to fit on two lines then an ellipsis will be used to hide the remaining content. So this next line will be hidden.\n    </v-banner-text>\n\n    <v-banner-actions>\n      <v-btn>Action</v-btn>\n\n      <v-btn>Action</v-btn>\n    </v-banner-actions>\n  </v-banner>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-banner/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div>\n      <v-banner\n        v-bind=\"props\"\n        :avatar=\"avatar ? 'https://cdn.vuetifyjs.com/images/john-smirk.png' : undefined\"\n      >\n        <template v-slot:text>\n          Lorem ipsum dolor sit amet consectetur adipisicing elit. Aliquam earum, est illo quae fugit voluptatum fuga magni hic maiores ipsa, illum, tenetur accusamus cupiditate? Dolorem ad nisi eveniet officia voluptatibus.\n        </template>\n\n        <template v-if=\"actions\" v-slot:actions>\n          <v-btn>Click me</v-btn>\n        </template>\n      </v-banner>\n    </div>\n\n    <template v-slot:configuration>\n      <v-select\n        v-model=\"color\"\n        :items=\"[\n          'success',\n          'info',\n          'warning',\n          'error',\n        ]\"\n        label=\"Color\"\n        clearable\n      ></v-select>\n\n      <v-checkbox v-model=\"avatar\" label=\"Avatar\"></v-checkbox>\n\n      <v-checkbox v-model=\"icon\" label=\"Icon\"></v-checkbox>\n\n      <v-checkbox v-model=\"actions\" label=\"Actions\"></v-checkbox>\n\n      <v-checkbox v-if=\"actions\" v-model=\"stacked\" label=\"Stacked\"></v-checkbox>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-banner'\n  const model = ref('default')\n  const options = ['One line', 'Two lines', 'Three lines']\n  const icon = ref(false)\n  const avatar = ref(false)\n  const actions = ref(false)\n  const stacked = ref(false)\n  const color = ref()\n\n  const props = computed(() => {\n    return {\n      avatar: avatar.value ? 'smirk.png' : undefined,\n      color: color.value ? color.value : undefined,\n      icon: icon.value ? '$vuetify' : undefined,\n      lines: model.value !== 'default' ? model.value.toLocaleLowerCase().split(' ')[0] : undefined,\n      text: '...',\n      stacked: stacked.value,\n    }\n  })\n\n  const slots = computed(() => {\n    return `\n  <template v-slot:actions>\n    <v-btn>Click me</v-btn>\n  </template>\n`\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-bottom-navigation/prop-color.vue",
    "content": "<template>\n  <v-layout style=\"height: 56px;\">\n    <v-bottom-navigation\n      v-model=\"value\"\n      color=\"primary\"\n      active\n    >\n      <v-btn>\n        <v-icon>mdi-history</v-icon>\n\n        Recents\n      </v-btn>\n\n      <v-btn>\n        <v-icon>mdi-heart</v-icon>\n\n        Favorites\n      </v-btn>\n\n      <v-btn>\n        <v-icon>mdi-map-marker</v-icon>\n\n        <span>Nearby</span>\n      </v-btn>\n    </v-bottom-navigation>\n  </v-layout>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const value = ref(0)\n</script>\n\n<script>\n  export default {\n    data: () => ({ value: 0 }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-bottom-navigation/prop-grow.vue",
    "content": "<template>\n  <v-layout style=\"height: 56px;\">\n    <v-bottom-navigation\n      v-model=\"value\"\n      color=\"teal\"\n      grow\n    >\n      <v-btn>\n        <v-icon>mdi-history</v-icon>\n\n        Recents\n      </v-btn>\n\n      <v-btn>\n        <v-icon>mdi-heart</v-icon>\n\n        Favorites\n      </v-btn>\n\n      <v-btn>\n        <v-icon>mdi-map-marker</v-icon>\n\n        Nearby\n      </v-btn>\n    </v-bottom-navigation>\n  </v-layout>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const value = ref(1)\n</script>\n\n<script>\n  export default {\n    data: () => ({ value: 1 }),\n  }\n</script>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2441-27203&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-bottom-navigation/prop-hide-on-scroll.vue",
    "content": "<template>\n  <v-card\n    class=\"overflow-hidden mx-auto\"\n    height=\"200\"\n    max-width=\"500\"\n  >\n    <v-bottom-navigation\n      scroll-target=\"#hide-on-scroll-example\"\n      absolute\n      hide-on-scroll\n      horizontal\n    >\n      <v-btn\n        color=\"deep-purple-accent-4\"\n        variant=\"text\"\n      >\n        <span>Recents</span>\n\n        <v-icon>mdi-history</v-icon>\n      </v-btn>\n\n      <v-btn\n        color=\"deep-purple-accent-4\"\n        variant=\"text\"\n      >\n        <span>Favorites</span>\n\n        <v-icon>mdi-heart</v-icon>\n      </v-btn>\n\n      <v-btn\n        color=\"deep-purple-accent-4\"\n        variant=\"text\"\n      >\n        <span>Nearby</span>\n\n        <v-icon>mdi-map-marker</v-icon>\n      </v-btn>\n    </v-bottom-navigation>\n\n    <v-responsive\n      id=\"hide-on-scroll-example\"\n      class=\"overflow-y-auto\"\n      max-height=\"600\"\n    >\n      <v-responsive height=\"1500\"></v-responsive>\n    </v-responsive>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-bottom-navigation/prop-horizontal.vue",
    "content": "<template>\n\n  <v-layout style=\"height: 56px;\">\n    <v-bottom-navigation\n      v-model=\"value\"\n      color=\"primary\"\n      horizontal\n    >\n      <v-btn>\n        <v-icon>mdi-history</v-icon>\n\n        Recents\n      </v-btn>\n\n      <v-btn>\n        <v-icon>mdi-heart</v-icon>\n\n        Favorites\n      </v-btn>\n\n      <v-btn>\n        <v-icon>mdi-map-marker</v-icon>\n\n        Nearby\n      </v-btn>\n    </v-bottom-navigation>\n  </v-layout>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const value = ref(1)\n</script>\n\n<script>\n  export default {\n    data: () => ({ value: 1 }),\n  }\n</script>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=1655-146658&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-bottom-navigation/prop-scroll-threshold.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto overflow-hidden\"\n    height=\"200\"\n    max-width=\"500\"\n  >\n    <v-bottom-navigation\n      color=\"white\"\n      scroll-target=\"#scroll-threshold-example\"\n      scroll-threshold=\"500\"\n      absolute\n      hide-on-scroll\n      horizontal\n    >\n      <v-btn>\n        <span>Recents</span>\n\n        <v-icon>mdi-history</v-icon>\n      </v-btn>\n\n      <v-btn>\n        <span>Favorites</span>\n\n        <v-icon>mdi-heart</v-icon>\n      </v-btn>\n\n      <v-btn>\n        <span>Nearby</span>\n\n        <v-icon>mdi-map-marker</v-icon>\n      </v-btn>\n    </v-bottom-navigation>\n\n    <v-sheet\n      id=\"scroll-threshold-example\"\n      class=\"overflow-y-auto pb-16\"\n      max-height=\"600\"\n    >\n      <v-responsive height=\"1500\"></v-responsive>\n    </v-sheet>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-bottom-navigation/prop-shift.vue",
    "content": "<template>\n\n  <v-layout style=\"height: 56px;\">\n    <v-bottom-navigation\n      v-model=\"value\"\n      :bg-color=\"color\"\n      mode=\"shift\"\n    >\n      <v-btn>\n        <v-icon>mdi-television-play</v-icon>\n\n        <span>Video</span>\n      </v-btn>\n\n      <v-btn>\n        <v-icon>mdi-music-note</v-icon>\n\n        <span>Music</span>\n      </v-btn>\n\n      <v-btn>\n        <v-icon>mdi-book</v-icon>\n\n        <span>Book</span>\n      </v-btn>\n\n      <v-btn>\n        <v-icon>mdi-image</v-icon>\n\n        <span>Image</span>\n      </v-btn>\n    </v-bottom-navigation>\n  </v-layout>\n</template>\n\n<script setup>\n  import { computed, ref } from 'vue'\n\n  const value = ref(1)\n  const color = computed(() => {\n    switch (value.value) {\n      case 0: return 'blue-grey'\n      case 1: return 'teal'\n      case 2: return 'brown'\n      case 3: return 'indigo'\n      default: return 'blue-grey'\n    }\n  })\n</script>\n\n<script>\n  export default {\n    data: () => ({ value: 1 }),\n\n    computed: {\n      color () {\n        switch (this.value) {\n          case 0: return 'blue-grey'\n          case 1: return 'teal'\n          case 2: return 'brown'\n          case 3: return 'indigo'\n          default: return 'blue-grey'\n        }\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-bottom-navigation/prop-toggle.vue",
    "content": "<template>\n  <v-layout class=\"border rounded\" style=\"height: 128px;\">\n    <div class=\"mx-auto my-4\">\n      <v-btn\n        color=\"deep-purple\"\n        variant=\"outlined\"\n        @click=\"active = !active\"\n      >\n        Toggle Navigation\n      </v-btn>\n    </div>\n\n    <v-bottom-navigation\n      :active=\"active\"\n      color=\"indigo\"\n    >\n      <v-btn>\n        <v-icon>mdi-history</v-icon>\n\n        Recents\n      </v-btn>\n\n      <v-btn>\n        <v-icon>mdi-heart</v-icon>\n\n        Favorites\n      </v-btn>\n\n      <v-btn>\n        <v-icon>mdi-map-marker</v-icon>\n\n        Nearby\n      </v-btn>\n    </v-bottom-navigation>\n\n  </v-layout>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const active = ref(true)\n</script>\n\n<script>\n  export default {\n    data: () => ({ active: true }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-bottom-navigation/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <v-layout class=\"border\" style=\"height: 150px;\">\n      <v-main></v-main>\n      <v-bottom-navigation v-bind=\"props\">\n        <v-btn value=\"history\">\n          <v-icon>mdi-history</v-icon>\n\n          <span>Recent</span>\n        </v-btn>\n\n        <v-btn value=\"favorites\">\n          <v-icon>mdi-heart</v-icon>\n\n          <span>Favorites</span>\n        </v-btn>\n\n        <v-btn value=\"nearby\">\n          <v-icon>mdi-map-marker</v-icon>\n\n          <span>Nearby</span>\n        </v-btn>\n      </v-bottom-navigation>\n    </v-layout>\n\n    <template v-slot:configuration>\n      <v-slider v-model=\"elevation\" label=\"Elevation\" max=\"24\" min=\"0\" step=\"1\"></v-slider>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-bottom-navigation'\n  const model = ref('default')\n  const options = ['grow', 'shift']\n  const elevation = ref(4)\n\n  const props = computed(() => {\n    return {\n      elevation: elevation.value === 4 ? undefined : elevation.value,\n      grow: model.value === 'grow' || undefined,\n      mode: model.value === 'shift' ? 'shift' : undefined,\n    }\n  })\n\n  const slots = computed(() => {\n    let str = ''\n\n    str += `\n  <v-btn value=\"recent\">\n    <v-icon>mdi-history</v-icon>\n\n    <span>Recent</span>\n  </v-btn>\n\n  <v-btn value=\"favorites\">\n    <v-icon>mdi-heart</v-icon>\n\n    <span>Favorites</span>\n  </v-btn>\n\n  <v-btn value=\"nearby\">\n    <v-icon>mdi-map-marker</v-icon>\n\n    <span>Nearby</span>\n  </v-btn>\n`\n\n    return str\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-bottom-sheet/misc-open-in-list.vue",
    "content": "<template>\n  <v-bottom-sheet v-model=\"sheet\">\n    <template v-slot:activator=\"{ props: activatorProps }\">\n      <div class=\"text-center pa-8\">\n        <v-btn\n          v-bind=\"activatorProps\"\n          color=\"purple\"\n          size=\"x-large\"\n          text=\"Click Me\"\n        ></v-btn>\n      </div>\n    </template>\n\n    <v-list>\n      <v-list-subheader title=\"Open in\"></v-list-subheader>\n\n      <v-list-item\n        v-for=\"tile in tiles\"\n        :key=\"tile.title\"\n        :prepend-avatar=\"`https://cdn.vuetifyjs.com/images/bottom-sheets/${tile.img}`\"\n        :title=\"tile.title\"\n        @click=\"sheet = false\"\n      ></v-list-item>\n    </v-list>\n  </v-bottom-sheet>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const sheet = shallowRef(false)\n  const tiles = [\n    { img: 'keep.png', title: 'Keep' },\n    { img: 'inbox.png', title: 'Inbox' },\n    { img: 'hangouts.png', title: 'Hangouts' },\n    { img: 'messenger.png', title: 'Messenger' },\n    { img: 'google.png', title: 'Google+' },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      sheet: false,\n      tiles: [\n        { img: 'keep.png', title: 'Keep' },\n        { img: 'inbox.png', title: 'Inbox' },\n        { img: 'hangouts.png', title: 'Hangouts' },\n        { img: 'messenger.png', title: 'Messenger' },\n        { img: 'google.png', title: 'Google+' },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-bottom-sheet/misc-player.vue",
    "content": "<template>\n  <v-bottom-sheet inset>\n    <template v-slot:activator=\"{ props: activatorProps }\">\n      <div class=\"text-center pa-8\">\n        <v-btn\n          v-bind=\"activatorProps\"\n          color=\"red\"\n          size=\"x-large\"\n          text=\"Click Me\"\n        ></v-btn>\n      </div>\n    </template>\n\n    <v-sheet>\n      <v-progress-linear model-value=\"50\"></v-progress-linear>\n\n      <v-list>\n        <v-list-item subtitle=\"Fitz & The Trantrums\" title=\"The Walker\">\n          <template v-slot:append>\n            <div class=\"d-flex ga-1\">\n              <v-btn icon=\"mdi-rewind\" variant=\"text\"></v-btn>\n\n              <v-btn icon=\"mdi-pause\" variant=\"text\"></v-btn>\n\n              <v-btn icon=\"mdi-fast-forward\" variant=\"text\"></v-btn>\n            </div>\n          </template>\n        </v-list-item>\n      </v-list>\n    </v-sheet>\n  </v-bottom-sheet>\n</template>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2305-13764&t=tWnPBMI0RfGlNRgq-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-bottom-sheet/prop-inset.vue",
    "content": "<template>\n  <div class=\"text-center pa-8\">\n    <v-btn\n      class=\"ma-auto\"\n      size=\"x-large\"\n      text=\"Click Me\"\n      @click=\"sheet = !sheet\"\n    ></v-btn>\n\n    <v-bottom-sheet v-model=\"sheet\" inset>\n      <v-card class=\"text-center\" height=\"200\">\n        <v-card-text>\n          <v-btn\n            text=\"Close\"\n            variant=\"text\"\n            @click=\"sheet = !sheet\"\n          ></v-btn>\n\n          <br>\n          <br>\n\n          <div>\n            This is a bottom sheet that is using the inset prop\n          </div>\n        </v-card-text>\n      </v-card>\n    </v-bottom-sheet>\n  </div>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const sheet = shallowRef(false)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      sheet: false,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-bottom-sheet/prop-model.vue",
    "content": "<template>\n  <div class=\"pa-8 text-center\">\n    <v-btn\n      class=\"ma-auto\"\n      size=\"x-large\"\n      text=\"Click Me\"\n      @click=\"sheet = !sheet\"\n    ></v-btn>\n\n    <v-bottom-sheet v-model=\"sheet\">\n      <v-card class=\"text-center\" height=\"200\">\n        <v-card-text>\n          <v-btn\n            text=\"Close\"\n            variant=\"text\"\n            @click=\"sheet = !sheet\"\n          ></v-btn>\n\n          <br>\n          <br>\n\n          <div>\n            This is a bottom sheet using the controlled by v-model instead of activator\n          </div>\n        </v-card-text>\n      </v-card>\n    </v-bottom-sheet>\n  </div>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const sheet = shallowRef(false)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      sheet: false,\n    }),\n  }\n</script>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2305-15953&t=tWnPBMI0RfGlNRgq-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-bottom-sheet/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <v-bottom-sheet v-bind=\"props\">\n      <template v-slot:activator=\"{ props: activatorProps }\">\n        <div class=\"pa-2 text-center\">\n          <v-btn\n            v-bind=\"activatorProps\"\n            size=\"x-large\"\n            text=\"Click Me\"\n          ></v-btn>\n        </div>\n      </template>\n\n      <v-card\n        text=\"Lorem ipsum dolor sit amet consectetur, adipisicing elit. Ut, eos? Nulla aspernatur odio rem, culpa voluptatibus eius debitis dolorem perspiciatis asperiores sed consectetur praesentium! Delectus et iure maxime eaque exercitationem!\"\n        title=\"Bottom Sheet\"\n      ></v-card>\n    </v-bottom-sheet>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-bottom-sheet'\n  const model = ref('default')\n  const options = ['inset']\n\n  const props = computed(() => {\n    return {\n      inset: model.value === 'inset' || undefined,\n    }\n  })\n\n  const slots = computed(() => {\n    return `\n  <template v-slot:activator=\"{ props: activatorProps }\">\n    <v-btn v-bind=\"activatorProps\" text=\"Click Me\"></v-btn>\n  </template>\n\n  <v-card\n    title=\"Bottom Sheet\"\n    text=\"Lorem ipsum dolor sit amet consectetur, adipisicing elit. Ut, eos? Nulla aspernatur odio rem, culpa voluptatibus eius debitis dolorem perspiciatis asperiores sed consectetur praesentium! Delectus et iure maxime eaque exercitationem!\"\n  ></v-card>\n`\n  })\n\n  const code = computed(() => {\n    return `<v-bottom-sheet${propsToString(props.value)}>${slots.value}</v-bottom-sheet>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-breadcrumbs/prop-divider.vue",
    "content": "<template>\n  <div>\n    <v-breadcrumbs\n      :items=\"items\"\n      divider=\"-\"\n    ></v-breadcrumbs>\n\n    <v-breadcrumbs\n      :items=\"items\"\n      divider=\".\"\n    ></v-breadcrumbs>\n  </div>\n</template>\n\n<script setup>\n  const items = [\n    {\n      title: 'Dashboard',\n      disabled: false,\n      href: 'breadcrumbs_dashboard',\n    },\n    {\n      title: 'Link 1',\n      disabled: false,\n      href: 'breadcrumbs_link_1',\n    },\n    {\n      title: 'Link 2',\n      disabled: true,\n      href: 'breadcrumbs_link_2',\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        {\n          title: 'Dashboard',\n          disabled: false,\n          href: 'breadcrumbs_dashboard',\n        },\n        {\n          title: 'Link 1',\n          disabled: false,\n          href: 'breadcrumbs_link_1',\n        },\n        {\n          title: 'Link 2',\n          disabled: true,\n          href: 'breadcrumbs_link_2',\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-breadcrumbs/slot-icon-dividers.vue",
    "content": "<template>\n  <div>\n    <v-breadcrumbs :items=\"items\">\n      <template v-slot:divider>\n        <v-icon icon=\"mdi-forward\"></v-icon>\n      </template>\n    </v-breadcrumbs>\n\n    <v-breadcrumbs :items=\"items\">\n      <template v-slot:divider>\n        <v-icon icon=\"mdi-chevron-right\"></v-icon>\n      </template>\n    </v-breadcrumbs>\n  </div>\n</template>\n\n<script setup>\n  const items = [\n    {\n      title: 'Dashboard',\n      disabled: false,\n      href: 'breadcrumbs_dashboard',\n    },\n    {\n      title: 'Link 1',\n      disabled: false,\n      href: 'breadcrumbs_link_1',\n    },\n    {\n      title: 'Link 2',\n      disabled: true,\n      href: 'breadcrumbs_link_2',\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        {\n          title: 'Dashboard',\n          disabled: false,\n          href: 'breadcrumbs_dashboard',\n        },\n        {\n          title: 'Link 1',\n          disabled: false,\n          href: 'breadcrumbs_link_1',\n        },\n        {\n          title: 'Link 2',\n          disabled: true,\n          href: 'breadcrumbs_link_2',\n        },\n      ],\n    }),\n  }\n</script>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2441-27794&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-breadcrumbs/slot-prepend.vue",
    "content": "<template>\n  <v-breadcrumbs :items=\"items\">\n    <template v-slot:prepend>\n      <v-icon icon=\"$vuetify\" size=\"small\"></v-icon>\n    </template>\n  </v-breadcrumbs>\n</template>\n\n<script setup>\n  const items = [\n    {\n      title: 'Dashboard',\n      disabled: false,\n      href: 'breadcrumbs_dashboard',\n    },\n    {\n      title: 'Link 1',\n      disabled: false,\n      href: 'breadcrumbs_link_1',\n    },\n    {\n      title: 'Link 2',\n      disabled: true,\n      href: 'breadcrumbs_link_2',\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        {\n          title: 'Dashboard',\n          disabled: false,\n          href: 'breadcrumbs_dashboard',\n        },\n        {\n          title: 'Link 1',\n          disabled: false,\n          href: 'breadcrumbs_link_1',\n        },\n        {\n          title: 'Link 2',\n          disabled: true,\n          href: 'breadcrumbs_link_2',\n        },\n      ],\n    }),\n  }\n</script>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=1655-147100&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-breadcrumbs/slot-title.vue",
    "content": "<template>\n  <v-breadcrumbs :items=\"items\">\n    <template v-slot:title=\"{ item }\">\n      {{ item.title.toUpperCase() }}\n    </template>\n  </v-breadcrumbs>\n</template>\n\n<script setup>\n  const items = [\n    {\n      title: 'Dashboard',\n      disabled: false,\n      href: 'breadcrumbs_dashboard',\n    },\n    {\n      title: 'Link 1',\n      disabled: false,\n      href: 'breadcrumbs_link_1',\n    },\n    {\n      title: 'Link 2',\n      disabled: true,\n      href: 'breadcrumbs_link_2',\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        {\n          title: 'Dashboard',\n          disabled: false,\n          href: 'breadcrumbs_dashboard',\n        },\n        {\n          title: 'Link 1',\n          disabled: false,\n          href: 'breadcrumbs_link_1',\n        },\n        {\n          title: 'Link 2',\n          disabled: true,\n          href: 'breadcrumbs_link_2',\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-breadcrumbs/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div>\n      <v-breadcrumbs v-bind=\"props\">\n        <!-- <v-breadcrumbs-item>Item</v-breadcrumbs-item>\n\n        <v-breadcrumbs-divider></v-breadcrumbs-divider>\n\n        <v-breadcrumbs-item active>Item 2</v-breadcrumbs-item>\n\n        <v-breadcrumbs-divider></v-breadcrumbs-divider>\n\n        <v-breadcrumbs-item disabled>Item 3</v-breadcrumbs-item> -->\n      </v-breadcrumbs>\n    </div>\n\n    <template v-slot:configuration>\n      <v-select v-model=\"color\" :items=\"['primary', 'success', 'info']\" label=\"Background color\" clearable></v-select>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-breadcrumbs'\n  const model = ref('default')\n  const options = []\n  const color = ref()\n  const props = computed(() => {\n    return {\n      'bg-color': color.value || undefined,\n      items: ['Foo', 'Bar', 'Fizz'],\n    }\n  })\n\n  const slots = computed(() => {\n    return ``\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn/defaults-banner-actions.vue",
    "content": "<template>\n  <v-banner\n    lines=\"one\"\n  >\n    <template v-slot:text>\n      Banner with one line of text.\n    </template>\n\n    <template v-slot:actions>\n      <v-btn>\n        Action\n      </v-btn>\n\n      <v-btn>\n        Action\n      </v-btn>\n    </template>\n  </v-banner>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn/defaults-bottom-navigation.vue",
    "content": "<template>\n  <v-layout\n    class=\"overflow-visible\"\n    style=\"height: 56px;\"\n  >\n    <v-bottom-navigation\n      v-model=\"value\"\n      active\n    >\n      <v-btn>Home</v-btn>\n\n      <v-btn>Recents</v-btn>\n\n      <v-btn>Favorites</v-btn>\n    </v-bottom-navigation>\n  </v-layout>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const value = ref(0)\n</script>\n\n<script>\n  export default {\n    data: () => ({ value: 0 }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn/defaults-btn-group.vue",
    "content": "<template>\n  <div class=\"d-flex align-center flex-column pa-6\">\n    <v-btn-group\n      variant=\"outlined\"\n      divided\n    >\n      <v-btn icon=\"mdi-format-align-left\"></v-btn>\n      <v-btn icon=\"mdi-format-align-center\"></v-btn>\n      <v-btn icon=\"mdi-format-align-right\"></v-btn>\n      <v-btn icon=\"mdi-format-align-justify\"></v-btn>\n    </v-btn-group>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn/defaults-card-actions.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"500\"\n    text=\"Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!\"\n    title=\"Card title\"\n  >\n    <v-card-actions>\n      <v-btn>Action Button</v-btn>\n    </v-card-actions>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn/defaults-snackbar.vue",
    "content": "<template>\n  <v-sheet\n    class=\"position-relative\"\n    min-height=\"100\"\n  >\n    <div class=\"position-absolute d-flex align-center justify-center w-100 h-100\">\n      <v-btn\n        size=\"x-large\"\n        @click=\"snackbar = !snackbar\"\n      >\n        Toggle Snackbar\n      </v-btn>\n    </div>\n\n    <v-snackbar\n      v-model=\"snackbar\"\n      location=\"center\"\n    >\n      Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!\n\n      <template v-slot:actions>\n        <v-btn @click=\"onClick\">Close</v-btn>\n      </template>\n    </v-snackbar>\n  </v-sheet>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const snackbar = ref(false)\n\n  function onClick () {\n    snackbar.value = false\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      snackbar: false,\n    }),\n\n    methods: {\n      onClick () {\n        this.snackbar = false\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn/defaults-toolbar.vue",
    "content": "<template>\n  <v-toolbar title=\"Toolbar\">\n    <v-toolbar-items>\n      <v-btn>Dashboard</v-btn>\n\n      <v-btn>Resources</v-btn>\n    </v-toolbar-items>\n\n    <v-divider class=\"mx-2\" vertical></v-divider>\n\n    <v-btn icon=\"mdi-dots-vertical\"></v-btn>\n  </v-toolbar>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn/misc-cookie-settings.vue",
    "content": "<template>\n  <v-banner\n    avatar=\"https://cdn.vuetifyjs.com/docs/images/logos/v.svg\"\n    stacked\n  >\n    <template v-slot:text>\n      Vuetify uses cookies to enable and import the use of the website. Please see our <a href=\"https://www.iubenda.com/privacy-policy/76325752/cookie-policy\" target=\"_blank\">Privacy Policy</a> for more information. By clicking \"Accept Cookies\" or continuing to use the site, you agree to the use of cookies.\n    </template>\n\n    <template v-slot:actions>\n      <v-dialog v-model=\"dialog\" max-width=\"500\">\n        <template v-slot:activator=\"{ props }\">\n          <v-btn\n            class=\"text-none\"\n            color=\"blue-darken-4\"\n            rounded=\"0\"\n            variant=\"outlined\"\n            v-bind=\"props\"\n          >\n            Manage Cookies\n          </v-btn>\n        </template>\n\n        <v-card title=\"Cookie Settings\">\n          <v-card-text>\n            <p class=\"pb-4\">\n              Vuetify websites use cookies to deliver and improve the visitor experience. Learn more about the cookies we use on our Cookie Policy page.\n            </p>\n\n            <v-list-subheader class=\"font-weight-black text-high-emphasis\">Required Cookies</v-list-subheader>\n\n            <p class=\"mb-4\">These cookies are required for the site to function and cannot be turned off.</p>\n\n            <v-list-subheader class=\"font-weight-black text-high-emphasis\">Performance Cookies</v-list-subheader>\n\n            <v-switch\n              v-model=\"performance\"\n              :label=\"performance ? 'On' : 'Off'\"\n              color=\"blue-darken-4\"\n              density=\"compact\"\n              hide-details\n              inline\n              inset\n            ></v-switch>\n\n            <p class=\"mb-4\">Counts website visits and clicks to understand where people most engage with links to make the experience better.</p>\n\n            <v-list-subheader class=\"font-weight-black text-high-emphasis\">Advertising Cookies</v-list-subheader>\n\n            <v-switch\n              v-model=\"advertising\"\n              :label=\"advertising ? 'On' : 'Off'\"\n              color=\"blue-darken-4\"\n              density=\"compact\"\n              hide-details\n              inline\n              inset\n            ></v-switch>\n\n            <p class=\"mb-16\">Set by our advertising partners, these cookies are used to build a profile of your interests and show you relevant ads on other sites. They do not store personal information, but are based on uniquely identifying your browser and internet device.</p>\n          </v-card-text>\n\n          <v-divider></v-divider>\n\n          <v-card-actions class=\"justify-center px-6 py-3\">\n            <v-btn\n              class=\"flex-grow-1 text-none\"\n              color=\"blue-darken-4\"\n              rounded=\"0\"\n              variant=\"plain\"\n              @click=\"dialog=false\"\n            >\n              Decline All\n            </v-btn>\n\n            <v-btn\n              class=\"text-white flex-grow-1 text-none\"\n              color=\"blue-darken-4\"\n              rounded=\"0\"\n              variant=\"flat\"\n              @click=\"dialog=false\"\n            >\n              Save and Accept\n            </v-btn>\n          </v-card-actions>\n        </v-card>\n      </v-dialog>\n\n      <v-btn\n        class=\"text-none ms-4 text-white\"\n        color=\"blue-darken-4\"\n        rounded=\"0\"\n        variant=\"flat\"\n      >\n        Accept Cookies\n      </v-btn>\n    </template>\n  </v-banner>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const dialog = ref(false)\n  const advertising = ref(true)\n  const performance = ref(true)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      dialog: false,\n      advertising: true,\n      performance: true,\n    }),\n  }\n</script>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=1488-93288&t=tWnPBMI0RfGlNRgq-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn/misc-dialog-action.vue",
    "content": "<template>\n  <v-sheet\n    class=\"position-relative\"\n    min-height=\"450\"\n  >\n    <div class=\"position-absolute d-flex align-center justify-center w-100 h-100\">\n      <v-btn\n        color=\"deep-purple-darken-2\"\n        size=\"x-large\"\n        @click=\"dialog = !dialog\"\n      >\n        Open Dialog\n      </v-btn>\n    </div>\n\n    <v-fade-transition hide-on-leave>\n      <v-card\n        v-if=\"dialog\"\n        append-icon=\"$close\"\n        class=\"mx-auto\"\n        elevation=\"4\"\n        max-width=\"500\"\n        title=\"Send a receipt\"\n      >\n        <template v-slot:append>\n          <v-btn icon=\"$close\" variant=\"text\" @click=\"dialog = false\"></v-btn>\n        </template>\n\n        <v-divider></v-divider>\n\n        <div class=\"py-12 text-center\">\n          <v-icon\n            class=\"mb-6\"\n            color=\"success\"\n            icon=\"mdi-check-circle-outline\"\n            size=\"128\"\n          ></v-icon>\n\n          <div class=\"text-headline-large font-weight-bold\">This receipt was sent</div>\n        </div>\n\n        <v-divider></v-divider>\n\n        <div class=\"pa-4 text-end\">\n          <v-btn\n            class=\"text-none\"\n            color=\"medium-emphasis\"\n            min-width=\"92\"\n            variant=\"outlined\"\n            rounded\n            @click=\"dialog = false\"\n          >\n            Close\n          </v-btn>\n        </div>\n      </v-card>\n    </v-fade-transition>\n  </v-sheet>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const dialog = ref(true)\n</script>\n\n<example-meta lang=\"json\">\n{\n  \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2383-26533&t=tWnPBMI0RfGlNRgq-4\"\n}\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn/misc-discord-event.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    color=\"#36393f\"\n    max-width=\"650\"\n    min-height=\"350\"\n    theme=\"dark\"\n    variant=\"flat\"\n  >\n    <v-sheet color=\"#202225\">\n      <v-card-item>\n        <template v-slot:prepend>\n          <v-card-title>\n            <v-icon\n              icon=\"mdi-calendar\"\n              start\n            ></v-icon>\n\n            1 Event\n          </v-card-title>\n        </template>\n\n        <v-divider class=\"mx-2\" vertical></v-divider>\n\n        <v-btn\n          class=\"text-none text-body-large\"\n          color=\"#5865f2\"\n          size=\"small\"\n          variant=\"flat\"\n        >\n          Create Event\n        </v-btn>\n\n        <template v-slot:append>\n          <v-btn\n            icon=\"$close\"\n            size=\"large\"\n            variant=\"text\"\n          ></v-btn>\n        </template>\n      </v-card-item>\n    </v-sheet>\n\n    <v-card\n      class=\"ma-4\"\n      color=\"#2f3136\"\n      rounded=\"lg\"\n      variant=\"flat\"\n    >\n      <v-card-item>\n        <v-card-title class=\"text-body-medium d-flex align-center\">\n          <v-icon\n            color=\"#949cf7\"\n            icon=\"mdi-calendar\"\n            start\n          ></v-icon>\n\n          <span class=\"text-medium-emphasis font-weight-bold\">1 Fri Dec 16th - 9:00 PM</span>\n\n          <v-spacer></v-spacer>\n\n          <v-avatar\n            image=\"https://cdn.vuetifyjs.com/images/john-smirk.png\"\n            size=\"x-small\"\n          ></v-avatar>\n\n          <v-chip\n            class=\"ms-2 text-medium-emphasis\"\n            color=\"grey-darken-4\"\n            prepend-icon=\"mdi-account-multiple\"\n            size=\"small\"\n            text=\"81\"\n            variant=\"flat\"\n          ></v-chip>\n        </v-card-title>\n\n        <div class=\"py-2\">\n          <div class=\"text-title-large\">Live Q&A</div>\n\n          <div class=\"font-weight-light text-medium-emphasis\">\n            Join the Vuetify team for a live Question and Answer session.\n          </div>\n        </div>\n      </v-card-item>\n\n      <v-divider></v-divider>\n\n      <div class=\"pa-4 d-flex align-center\">\n        <v-icon\n          color=\"disabled\"\n          icon=\"mdi-broadcast\"\n          start\n        ></v-icon>\n\n        <v-icon\n          color=\"#949cf7\"\n          icon=\"mdi-video-vintage\"\n          size=\"x-small\"\n        ></v-icon>\n\n        <span class=\"text-body-small text-medium-emphasis ms-1 font-weight-light\">\n          streaming\n        </span>\n\n        <v-spacer></v-spacer>\n\n        <v-btn\n          icon=\"mdi-dots-horizontal\"\n          variant=\"text\"\n        ></v-btn>\n\n        <v-btn\n          class=\"me-2 text-none\"\n          color=\"#4f545c\"\n          prepend-icon=\"mdi-export-variant\"\n          variant=\"flat\"\n        >\n          Share\n        </v-btn>\n\n        <v-btn\n          class=\"text-none\"\n          prepend-icon=\"mdi-check\"\n          variant=\"text\"\n          border\n        >\n          Interested\n        </v-btn>\n      </div>\n    </v-card>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn/misc-group-survey.vue",
    "content": "<template>\n  <v-card\n    class=\"px-2 mx-auto\"\n    max-width=\"300\"\n    rounded=\"lg\"\n    text=\"How satisfied are you with developing using Vuetify?\"\n    theme=\"dark\"\n    title=\"SURVEY\"\n    variant=\"flat\"\n  >\n    <template v-slot:append>\n      <div class=\"me-n2\">\n        <v-btn\n          density=\"comfortable\"\n          icon=\"$close\"\n          variant=\"plain\"\n        ></v-btn>\n      </div>\n    </template>\n\n    <v-item-group\n      v-model=\"model\"\n      class=\"d-flex justify-sm-space-between px-6 pt-2 pb-6\"\n    >\n      <v-item\n        v-for=\"n in 5\"\n        :key=\"n\"\n      >\n        <template v-slot:default=\"{ toggle }\">\n          <v-btn\n            :active=\"model != null && model + 1 >= n\"\n            :icon=\"`mdi-numeric-${n}`\"\n            height=\"40\"\n            variant=\"text\"\n            width=\"40\"\n            border\n            @click=\"toggle\"\n          ></v-btn>\n        </template>\n      </v-item>\n    </v-item-group>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const model = ref(null)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      model: null,\n    }),\n  }\n</script>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=1479-4851&t=tWnPBMI0RfGlNRgq-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn/misc-raised.vue",
    "content": "<template>\n  <v-row class=\"align-center justify-space-around\">\n    <v-btn>Normal</v-btn>\n    <v-btn color=\"primary\">\n      Primary\n    </v-btn>\n    <v-btn color=\"error\">\n      Error\n    </v-btn>\n    <v-btn disabled>\n      Disabled\n    </v-btn>\n  </v-row>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn/misc-readonly.vue",
    "content": "<template>\n  <v-list-item\n    base-color=\"surface-light\"\n    border=\"opacity-50 md\"\n    lines=\"two\"\n    max-width=\"796\"\n    prepend-avatar=\"https://cdn.vuetifyjs.com/docs/images/one/logos/one.png\"\n    rounded=\"lg\"\n    variant=\"flat\"\n  >\n    <v-list-item-title>\n      <span class=\"text-title-large\">Vuetify One Subscriber</span>\n    </v-list-item-title>\n\n    <v-list-item-subtitle :opacity=\"isSubscriber ? .8 : undefined\">\n      <v-scroll-y-reverse-transition mode=\"out-in\">\n        <div\n          v-if=\"isSubscriber\"\n          key=\"subscribed\"\n          class=\"text-success text-body-small\"\n        >\n          <v-icon icon=\"mdi-medal\" size=\"1em\"></v-icon>\n          $2.99 /month\n        </div>\n\n        <div\n          v-else\n          key=\"not-subscribed\"\n          class=\"text-body-small\"\n        >\n          Support Vuetify by becoming a Subscriber\n        </div>\n      </v-scroll-y-reverse-transition>\n    </v-list-item-subtitle>\n\n    <template v-slot:append>\n      <v-fade-transition mode=\"out-in\">\n        <v-btn\n          :key=\"`subscribe-${isSubscriber}`\"\n          :border=\"`thin ${isSubscriber ? 'error' : 'success'}`\"\n          :color=\"isSubscriber ? 'error' : 'success'\"\n          :prepend-icon=\"isSubscriber ? 'mdi-close' : 'mdi-email'\"\n          :slim=\"isSubscriber\"\n          :text=\"isSubscriber ? 'Cancel' : 'Subscribe'\"\n          :variant=\"isSubscriber ? 'plain' : 'tonal'\"\n          class=\"me-2 text-none\"\n          size=\"small\"\n          @click=\"isSubscriber = !isSubscriber\"\n        ></v-btn>\n      </v-fade-transition>\n\n      <v-fade-transition mode=\"out-in\">\n        <v-btn\n          :key=\"`info-${isSubscriber}`\"\n          :color=\"isSubscriber ? 'success' : 'primary'\"\n          :prepend-icon=\"isSubscriber ? 'mdi-check' : 'mdi-open-in-new'\"\n          :readonly=\"isSubscriber\"\n          :text=\"isSubscriber ? 'Subscribed' : 'More Info'\"\n          class=\"text-none\"\n          size=\"small\"\n          variant=\"flat\"\n        ></v-btn>\n      </v-fade-transition>\n    </template>\n  </v-list-item>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const isSubscriber = shallowRef(false)\n</script>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=1489-93848&t=igC9QPO7ZOgBrTij-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn/misc-tax-form.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    elevation=\"1\"\n    max-width=\"500\"\n  >\n    <v-card-title class=\"py-5 font-weight-black\">Securely access your tax form</v-card-title>\n\n    <v-card-text>\n      To download your tax form from GitHub Sponsors on Stripe Express, you must also verify the Tax ID number used on your tax forms, as they contain sensitive personal information.\n    </v-card-text>\n\n    <v-card-text>\n      <div class=\"text-title-small font-weight-black mb-1\">Last 4 digits of your SSN</div>\n\n      <v-text-field\n        label=\"Enter value here\"\n        variant=\"outlined\"\n        single-line\n      ></v-text-field>\n\n      <v-btn\n        :disabled=\"loading\"\n        :loading=\"loading\"\n        class=\"text-none mb-4\"\n        color=\"indigo-darken-3\"\n        size=\"x-large\"\n        variant=\"flat\"\n        block\n        @click=\"loading = !loading\"\n      >\n        Verify and continue\n      </v-btn>\n\n      <v-btn\n        class=\"text-none\"\n        color=\"grey-lighten-3\"\n        size=\"x-large\"\n        variant=\"flat\"\n        block\n      >\n        Cancel\n      </v-btn>\n    </v-card-text>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref, watch } from 'vue'\n\n  const loading = ref(false)\n\n  watch(loading, val => {\n    if (!val) return\n    setTimeout(() => (loading.value = false), 2000)\n  })\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      loading: false,\n    }),\n\n    watch: {\n      loading (val) {\n        if (!val) return\n\n        setTimeout(() => (this.loading = false), 2000)\n      },\n    },\n  }\n</script>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=1479-92504&t=tWnPBMI0RfGlNRgq-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn/misc-toolbar.vue",
    "content": "<template>\n  <v-toolbar>\n    <template v-slot:prepend>\n      <v-btn icon=\"mdi-arrow-left\"></v-btn>\n    </template>\n\n    <v-btn class=\"ms-5\" icon=\"mdi-archive-plus-outline\"></v-btn>\n\n    <v-btn icon=\"mdi-alert-circle-outline\"></v-btn>\n\n    <v-btn icon=\"mdi-delete-outline\"></v-btn>\n\n    <template v-if=\"$vuetify.display.smAndUp\">\n      <v-divider\n        class=\"mx-3 align-self-center\"\n        length=\"24\"\n        thickness=\"2\"\n        vertical\n      ></v-divider>\n\n      <v-btn icon=\"mdi-folder-outline\"></v-btn>\n\n      <v-btn icon=\"mdi-tag-outline\"></v-btn>\n\n      <v-btn icon=\"mdi-dots-vertical\"></v-btn>\n    </template>\n  </v-toolbar>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn/prop-block.vue",
    "content": "<template>\n  <v-btn block>Block Button</v-btn>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn/prop-density.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"align-center justify-center\">\n      <v-col cols=\"auto\">\n        <v-btn density=\"compact\">Compact Button</v-btn>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <v-btn density=\"comfortable\">Comfortable Button</v-btn>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <v-btn density=\"default\">Default Button</v-btn>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn/prop-elevation.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"align-center justify-center\">\n      <v-col class=\"text-center\" cols=\"12\">\n        <v-btn size=\"x-large\">Default Elevation (2)</v-btn>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <v-btn elevation=\"3\" size=\"x-large\">Elevation 3</v-btn>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <v-btn elevation=\"4\" size=\"x-large\">Elevation 4</v-btn>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <v-btn elevation=\"5\" size=\"x-large\">Elevation 5</v-btn>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn/prop-flat.vue",
    "content": "<template>\n  <div class=\"d-flex justify-space-around align-center flex-column flex-sm-row fill-height\">\n    <v-btn variant=\"flat\">\n      Normal\n    </v-btn>\n\n    <v-btn\n      color=\"secondary\"\n      variant=\"flat\"\n    >\n      Secondary\n    </v-btn>\n\n    <v-btn\n      color=\"error\"\n      variant=\"flat\"\n    >\n      Error\n    </v-btn>\n\n    <v-btn\n      variant=\"flat\"\n      disabled\n    >\n      Disabled\n    </v-btn>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn/prop-floating.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-btn\n      class=\"mx-2\"\n      color=\"primary\"\n      size=\"small\"\n      icon\n    >\n      <v-icon>\n        mdi-minus\n      </v-icon>\n    </v-btn>\n\n    <v-btn\n      class=\"mx-2\"\n      color=\"pink\"\n      size=\"small\"\n      icon\n    >\n      <v-icon>\n        mdi-heart\n      </v-icon>\n    </v-btn>\n\n    <v-btn\n      class=\"mx-2\"\n      color=\"indigo\"\n      icon\n    >\n      <v-icon>\n        mdi-plus\n      </v-icon>\n    </v-btn>\n\n    <v-btn\n      class=\"mx-2\"\n      color=\"teal\"\n      icon\n    >\n      <v-icon>\n        mdi-format-list-bulleted-square\n      </v-icon>\n    </v-btn>\n\n    <v-btn\n      class=\"mx-2\"\n      color=\"cyan\"\n      size=\"large\"\n      icon\n    >\n      <v-icon>\n        mdi-pencil\n      </v-icon>\n    </v-btn>\n\n    <v-btn\n      class=\"mx-2\"\n      color=\"purple\"\n      size=\"large\"\n      icon\n    >\n      <v-icon>\n        mdi-android\n      </v-icon>\n    </v-btn>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn/prop-icon.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"align-center justify-center\">\n      <v-col cols=\"auto\">\n        <v-btn density=\"compact\" icon=\"mdi-plus\"></v-btn>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <v-btn density=\"comfortable\" icon=\"mdi-tag\"></v-btn>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <v-btn density=\"default\" icon=\"mdi-open-in-new\"></v-btn>\n      </v-col>\n    </v-row>\n\n    <v-row class=\"align-center justify-center\">\n      <v-col cols=\"auto\">\n        <v-btn icon=\"mdi-account\" size=\"x-small\"></v-btn>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <v-btn icon=\"mdi-plus\" size=\"small\"></v-btn>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <v-btn icon=\"mdi-tag\"></v-btn>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <v-btn icon=\"mdi-open-in-new\" size=\"large\"></v-btn>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <v-btn icon=\"mdi-calendar\" size=\"x-large\"></v-btn>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn/prop-loaders.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"450\"\n    text=\"Update your weak or re-used passwords with Password Checkup. It's free and only takes a few minutes. Click the Take Checkup button to get started.\"\n    title=\"Strengthen your passwords\"\n  >\n\n    <template v-slot:actions>\n      <v-btn height=\"48\">\n        No Thanks\n      </v-btn>\n\n      <v-btn\n        :loading=\"loading\"\n        class=\"flex-grow-1\"\n        height=\"48\"\n        variant=\"tonal\"\n        @click=\"load\"\n      >\n        Take Checkup\n      </v-btn>\n    </template>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const loading = ref(false)\n  function load () {\n    loading.value = true\n    setTimeout(() => (loading.value = false), 3000)\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({ loading: false }),\n\n    methods: {\n      load () {\n        this.loading = true\n        setTimeout(() => (this.loading = false), 3000)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn/prop-outlined.vue",
    "content": "<template>\n  <div class=\"d-flex justify-space-around align-center flex-column flex-sm-row\">\n    <v-btn\n      color=\"primary\"\n      variant=\"outlined\"\n    >\n      Outlined Button\n    </v-btn>\n    <v-btn\n      color=\"secondary\"\n      variant=\"outlined\"\n      icon\n    >\n      <v-icon>mdi-format-list-bulleted-square</v-icon>\n    </v-btn>\n    <v-btn\n      color=\"info\"\n      size=\"large\"\n      variant=\"outlined\"\n      icon\n    >\n      <v-icon>mdi-pencil</v-icon>\n    </v-btn>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn/prop-plain.vue",
    "content": "<template>\n  <div class=\"d-flex justify-space-around\">\n    <v-btn\n      color=\"grey\"\n      variant=\"plain\"\n    >\n      Cancel\n    </v-btn>\n\n    <v-btn\n      color=\"error\"\n      variant=\"plain\"\n    >\n      Delete\n    </v-btn>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn/prop-ripple.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"justify-center\">\n      <v-col cols=\"auto\">\n        <v-btn\n          height=\"72\"\n          min-width=\"164\"\n        >\n          With Ripple\n        </v-btn>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <v-btn\n          :ripple=\"false\"\n          height=\"72\"\n          min-width=\"164\"\n        >\n          Without Ripple\n        </v-btn>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn/prop-rounded.vue",
    "content": "<template>\n  <v-container class=\"text-center\">\n    <v-row class=\"justify-center\">\n      <v-col cols=\"12\" md=\"4\" sm=\"6\">\n        <v-btn rounded=\"0\" size=\"x-large\" block>Rounded 0</v-btn>\n      </v-col>\n\n      <v-col cols=\"12\" md=\"4\" sm=\"6\">\n        <v-btn rounded=\"xs\" size=\"x-large\" block>Rounded xs</v-btn>\n      </v-col>\n\n      <v-col cols=\"12\" md=\"4\" sm=\"6\">\n        <v-btn rounded=\"sm\" size=\"x-large\" block>Rounded sm</v-btn>\n      </v-col>\n\n      <v-col cols=\"12\" md=\"4\" sm=\"6\">\n        <v-btn size=\"x-large\" block>Button</v-btn>\n      </v-col>\n\n      <v-col cols=\"12\" md=\"4\" sm=\"6\">\n        <v-btn rounded=\"lg\" size=\"x-large\" block>Rounded lg</v-btn>\n      </v-col>\n\n      <v-col cols=\"12\" md=\"4\" sm=\"6\">\n        <v-btn rounded=\"xl\" size=\"x-large\" block>Rounded xl</v-btn>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn/prop-size.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"align-center justify-center\">\n      <v-col cols=\"auto\">\n        <v-btn size=\"x-small\">Extra small Button</v-btn>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <v-btn size=\"small\">Small Button</v-btn>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <v-btn>Regular Button</v-btn>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <v-btn size=\"large\">Large Button</v-btn>\n      </v-col>\n\n      <v-col cols=\"auto\">\n        <v-btn size=\"x-large\">X-Large Button</v-btn>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn/prop-spaced.vue",
    "content": "<template>\n  <v-container class=\"d-flex flex-wrap align-center justify-center ga-3\">\n    <v-btn height=\"70\" prepend-icon=\"$prev\" spaced=\"start\" width=\"220\">\n      <span class=\"text-right\">\n        <div class=\"mb-1\">Previous</div>\n        <small class=\"text-medium-emphasis\">spaced: start</small>\n      </span>\n    </v-btn>\n\n    <v-btn append-icon=\"$next\" height=\"70\" prepend-icon=\"$prev\" spaced=\"both\" width=\"220\">\n      <span>\n        <div class=\"mb-1\">Navigate</div>\n        <small class=\"text-medium-emphasis\">spaced: both</small>\n      </span>\n    </v-btn>\n\n    <v-btn append-icon=\"$next\" height=\"70\" spaced=\"end\" width=\"220\">\n      <span class=\"text-left\">\n        <div class=\"mb-1\">Next</div>\n        <small class=\"text-medium-emphasis\">spaced: end</small>\n      </span>\n    </v-btn>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn/prop-tile.vue",
    "content": "<template>\n  <v-row class=\"align-center justify-space-around\">\n    <v-btn\n      color=\"success\"\n      tile\n    >\n      <v-icon start>\n        mdi-pencil\n      </v-icon>\n      Edit\n    </v-btn>\n  </v-row>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn/prop-variant.vue",
    "content": "<template>\n  <div class=\"d-flex justify-space-between\">\n    <v-btn>elevated (default)</v-btn>\n    <v-btn variant=\"flat\">flat</v-btn>\n    <v-btn variant=\"tonal\">tonal</v-btn>\n    <v-btn variant=\"outlined\">outlined</v-btn>\n    <v-btn variant=\"text\">text</v-btn>\n    <v-btn variant=\"plain\">plain</v-btn>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn/slot-loader.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-btn\n      :loading=\"loading\"\n      @click=\"loading = !loading\"\n    >\n      Custom loader\n\n      <template v-slot:loader>\n        <v-progress-linear indeterminate></v-progress-linear>\n      </template>\n    </v-btn>\n  </div>\n</template>\n\n<script setup>\n  import { ref, watch } from 'vue'\n\n  const loading = ref(false)\n  watch(loading, val => {\n    if (!val) return\n    setTimeout(() => (loading.value = false), 2000)\n  })\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      loading: false,\n    }),\n\n    watch: {\n      loading (val) {\n        if (!val) return\n\n        setTimeout(() => (this.loading = false), 2000)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn/slot-prepend-append.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-btn\n      append-icon=\"mdi-account-circle\"\n      prepend-icon=\"mdi-check-circle\"\n    >\n      <template v-slot:prepend>\n        <v-icon color=\"success\"></v-icon>\n      </template>\n\n      Button\n\n      <template v-slot:append>\n        <v-icon color=\"warning\"></v-icon>\n      </template>\n    </v-btn>\n  </div>\n</template>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=1481-93004&t=tWnPBMI0RfGlNRgq-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div class=\"text-center\">\n      <v-btn v-bind=\"props\">\n        <template v-if=\"!icon\" v-slot:default>Button</template>\n      </v-btn>\n    </div>\n\n    <template v-slot:configuration>\n      <v-checkbox v-model=\"icon\" label=\"Icon\"></v-checkbox>\n      <v-checkbox v-model=\"prepend\" label=\"Prepend icon\"></v-checkbox>\n      <v-checkbox v-model=\"append\" label=\"Append icon\"></v-checkbox>\n      <v-checkbox v-model=\"stacked\" label=\"Stacked\"></v-checkbox>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const variants = ['outlined', 'tonal', 'text', 'plain']\n  const name = 'v-btn'\n  const model = ref('default')\n  const icon = ref(false)\n  const options = [...variants]\n  const block = ref(false)\n  const stacked = ref(false)\n  const prepend = ref(false)\n  const append = ref(false)\n  const props = computed(() => {\n    return {\n      block: block.value || undefined,\n      'prepend-icon': prepend.value ? '$vuetify' : undefined,\n      'append-icon': append.value ? '$vuetify' : undefined,\n      icon: icon.value ? '$vuetify' : undefined,\n      stacked: stacked.value || undefined,\n      variant: variants.includes(model.value) ? model.value : undefined,\n    }\n  })\n\n  watch(stacked, val => {\n    if (val) {\n      prepend.value = true\n      append.value = false\n      icon.value = false\n    }\n  })\n\n  watch(prepend, val => {\n    if (val) {\n      icon.value = false\n\n      if (stacked.value) (append.value = false)\n    }\n  })\n\n  watch(append, val => {\n    if (val) {\n      icon.value = false\n\n      if (stacked.value) (prepend.value = false)\n    }\n  })\n  watch(icon, val => val && (prepend.value = false, append.value = false, stacked.value = false))\n\n  const slots = computed(() => {\n    return icon.value ? '' : `\n  Button\n`\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn-toggle/misc-toolbar.vue",
    "content": "<template>\n  <v-toolbar>\n    <!-- <v-overflow-btn\n      :items=\"dropdown_font\"\n      label=\"Select font\"\n      hide-details\n      class=\"pa-0\"\n    ></v-overflow-btn>\n\n    <v-divider vertical></v-divider>\n\n    <v-overflow-btn\n      :items=\"dropdown_edit\"\n      editable\n      label=\"Select size\"\n      hide-details\n      class=\"pa-0\"\n      overflow\n    ></v-overflow-btn>\n\n    <v-divider vertical></v-divider> -->\n\n    <v-spacer></v-spacer>\n\n    <v-btn-toggle\n      v-model=\"toggleMultiple\"\n      color=\"primary\"\n      variant=\"plain\"\n      multiple\n    >\n      <v-btn\n        :value=\"1\"\n        icon=\"mdi-format-bold\"\n      ></v-btn>\n\n      <v-btn\n        :value=\"2\"\n        icon=\"mdi-format-italic\"\n      ></v-btn>\n\n      <v-btn\n        :value=\"3\"\n        icon=\"mdi-format-underline\"\n      ></v-btn>\n\n      <v-btn\n        :value=\"4\"\n        icon=\"mdi-format-color-fill\"\n      ></v-btn>\n    </v-btn-toggle>\n\n    <div class=\"mx-4\"></div>\n\n    <v-btn-toggle\n      v-model=\"toggleExclusive\"\n      color=\"primary\"\n      density=\"compact\"\n      variant=\"plain\"\n    >\n      <v-btn\n        :value=\"1\"\n        icon=\"mdi-format-align-left\"\n      ></v-btn>\n\n      <v-btn\n        :value=\"2\"\n        icon=\"mdi-format-align-center\"\n      ></v-btn>\n\n      <v-btn\n        :value=\"3\"\n        icon=\"mdi-format-align-right\"\n      ></v-btn>\n\n      <v-btn\n        :value=\"4\"\n        icon=\"mdi-format-align-justify\"\n      ></v-btn>\n    </v-btn-toggle>\n  </v-toolbar>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const toggleExclusive = ref(2)\n  const toggleMultiple = ref([1, 2, 3])\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        toggleExclusive: 2,\n        toggleMultiple: [1, 2, 3],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn-toggle/misc-wysiwyg.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"600\"\n  >\n    <div class=\"d-flex justify-space-between pa-4 pb-0\">\n      <v-btn-toggle\n        v-model=\"formatting\"\n        variant=\"outlined\"\n        divided\n        multiple\n      >\n        <v-btn>\n          <v-icon icon=\"mdi-format-italic\"></v-icon>\n        </v-btn>\n\n        <v-btn>\n          <v-icon icon=\"mdi-format-bold\"></v-icon>\n        </v-btn>\n\n        <v-btn>\n          <v-icon icon=\"mdi-format-underline\"></v-icon>\n        </v-btn>\n\n        <v-btn>\n          <div class=\"d-flex align-center flex-column justify-center\">\n            <v-icon icon=\"mdi-format-color-text\"></v-icon>\n\n            <v-sheet\n              color=\"purple\"\n              height=\"4\"\n              width=\"26\"\n              tile\n            ></v-sheet>\n          </div>\n        </v-btn>\n      </v-btn-toggle>\n\n      <v-btn-toggle\n        v-model=\"alignment\"\n        variant=\"outlined\"\n        divided\n      >\n        <v-btn>\n          <v-icon icon=\"mdi-format-align-center\"></v-icon>\n        </v-btn>\n\n        <v-btn>\n          <v-icon icon=\"mdi-format-align-left\"></v-icon>\n        </v-btn>\n\n        <v-btn>\n          <v-icon icon=\"mdi-format-align-right\"></v-icon>\n        </v-btn>\n      </v-btn-toggle>\n    </div>\n\n    <v-sheet class=\"pa-4 text-center\">\n      <v-textarea\n        v-model=\"value\"\n        rows=\"2\"\n        variant=\"outlined\"\n        auto-grow\n        hide-details\n      ></v-textarea>\n    </v-sheet>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const alignment = ref(1)\n  const formatting = ref([])\n  const value = ref('Toggle button requirements.\\n\\nHave at least three toggle buttons in a group\\nLabel buttons with text, an icon, or')\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      alignment: 1,\n      formatting: [],\n      value: 'Toggle button requirements.\\n\\nHave at least three toggle buttons in a group\\nLabel buttons with text, an icon, or',\n    }),\n  }\n</script>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2219-13727&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn-toggle/prop-divided.vue",
    "content": "<template>\n  <div class=\"d-flex align-center flex-column pa-6\">\n    <v-btn-toggle\n      v-model=\"toggle\"\n      border\n      divided\n    >\n      <v-btn icon=\"mdi-format-align-left\"></v-btn>\n      <v-btn icon=\"mdi-format-align-center\"></v-btn>\n      <v-btn icon=\"mdi-format-align-right\"></v-btn>\n      <v-btn icon=\"mdi-format-align-justify\"></v-btn>\n    </v-btn-toggle>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const toggle = ref(null)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      toggle: null,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn-toggle/prop-mandatory.vue",
    "content": "<template>\n  <div class=\"d-flex flex-column align-center pa-6\">\n    <v-btn-toggle\n      v-model=\"toggle\"\n      color=\"primary\"\n      border\n      mandatory\n    >\n      <v-btn icon=\"mdi-format-align-left\" value=\"left\"></v-btn>\n      <v-btn icon=\"mdi-format-align-center\" value=\"center\"></v-btn>\n      <v-btn icon=\"mdi-format-align-right\" value=\"right\"></v-btn>\n      <v-btn icon=\"mdi-format-align-justify\" value=\"justify\"></v-btn>\n    </v-btn-toggle>\n    <pre class=\"pt-2\">{{ toggle }}</pre>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const toggle = ref()\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        toggle: undefined,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn-toggle/prop-multiple.vue",
    "content": "<template>\n  <div class=\"d-flex flex-column align-center pa-6\">\n    <v-btn-toggle\n      v-model=\"toggle\"\n      border\n      multiple\n    >\n      <v-btn icon=\"mdi-format-align-left\" value=\"left\"></v-btn>\n      <v-btn icon=\"mdi-format-align-center\" value=\"center\"></v-btn>\n      <v-btn icon=\"mdi-format-align-right\" value=\"right\"></v-btn>\n      <v-btn icon=\"mdi-format-align-justify\" value=\"justify\"></v-btn>\n    </v-btn-toggle>\n\n    <pre class=\"pt-2\">{{ toggle }}</pre>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const toggle = ref([])\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        toggle: [],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn-toggle/prop-rounded.vue",
    "content": "<template>\n  <div class=\"d-flex justify-space-around pa-6\">\n    <v-btn-toggle\n      rounded=\"0\"\n      border\n    >\n      <v-btn icon=\"mdi-format-align-left\"></v-btn>\n      <v-btn icon=\"mdi-format-align-center\"></v-btn>\n      <v-btn icon=\"mdi-format-align-right\"></v-btn>\n      <v-btn icon=\"mdi-format-align-justify\"></v-btn>\n    </v-btn-toggle>\n\n    <v-btn-toggle\n      rounded=\"xl\"\n      border\n    >\n      <v-btn icon=\"mdi-format-align-left\"></v-btn>\n      <v-btn icon=\"mdi-format-align-center\"></v-btn>\n      <v-btn icon=\"mdi-format-align-right\"></v-btn>\n      <v-btn icon=\"mdi-format-align-justify\"></v-btn>\n    </v-btn-toggle>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn-toggle/prop-variant.vue",
    "content": "<template>\n  <div class=\"d-flex align-center flex-column pa-6\">\n    <div class=\"text-title-small\">Default</div>\n    <v-btn-toggle\n      v-model=\"toggle\"\n      color=\"primary\"\n    >\n      <v-btn icon=\"mdi-format-align-left\"></v-btn>\n      <v-btn icon=\"mdi-format-align-center\"></v-btn>\n      <v-btn icon=\"mdi-format-align-right\"></v-btn>\n      <v-btn icon=\"mdi-format-align-justify\"></v-btn>\n    </v-btn-toggle>\n\n    <div class=\"mt-6 text-title-small\">Text</div>\n    <v-btn-toggle\n      v-model=\"toggle\"\n      color=\"primary\"\n      variant=\"text\"\n    >\n      <v-btn icon=\"mdi-format-align-left\"></v-btn>\n      <v-btn icon=\"mdi-format-align-center\"></v-btn>\n      <v-btn icon=\"mdi-format-align-right\"></v-btn>\n      <v-btn icon=\"mdi-format-align-justify\"></v-btn>\n    </v-btn-toggle>\n\n    <div class=\"mt-6 text-title-small\">Plain</div>\n    <v-btn-toggle\n      v-model=\"toggle\"\n      color=\"primary\"\n      variant=\"plain\"\n    >\n      <v-btn icon=\"mdi-format-align-left\"></v-btn>\n      <v-btn icon=\"mdi-format-align-center\"></v-btn>\n      <v-btn icon=\"mdi-format-align-right\"></v-btn>\n      <v-btn icon=\"mdi-format-align-justify\"></v-btn>\n    </v-btn-toggle>\n\n    <div class=\"mt-6 text-title-small\">Outlined</div>\n    <v-btn-toggle\n      v-model=\"toggle\"\n      color=\"primary\"\n      variant=\"outlined\"\n    >\n      <v-btn icon=\"mdi-format-align-left\"></v-btn>\n      <v-btn icon=\"mdi-format-align-center\"></v-btn>\n      <v-btn icon=\"mdi-format-align-right\"></v-btn>\n      <v-btn icon=\"mdi-format-align-justify\"></v-btn>\n    </v-btn-toggle>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const toggle = ref(null)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      toggle: null,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-btn-toggle/usage.vue",
    "content": "<template>\n  <v-container>\n    <v-row>\n      <v-col\n        class=\"py-2\"\n        cols=\"12\"\n        sm=\"6\"\n      >\n        <p>Exclusive</p>\n\n        <v-btn-toggle v-model=\"toggle_exclusive\">\n          <v-btn>\n            <v-icon>mdi-format-align-left</v-icon>\n          </v-btn>\n\n          <v-btn>\n            <v-icon>mdi-format-align-center</v-icon>\n          </v-btn>\n\n          <v-btn>\n            <v-icon>mdi-format-align-right</v-icon>\n          </v-btn>\n\n          <v-btn>\n            <v-icon>mdi-format-align-justify</v-icon>\n          </v-btn>\n        </v-btn-toggle>\n      </v-col>\n\n      <v-col\n        class=\"py-2\"\n        cols=\"12\"\n        sm=\"6\"\n      >\n        <p>Multiple</p>\n\n        <v-btn-toggle\n          v-model=\"toggle_multiple\"\n          color=\"primary\"\n          multiple\n        >\n          <v-btn>\n            <v-icon>mdi-format-bold</v-icon>\n          </v-btn>\n\n          <v-btn>\n            <v-icon>mdi-format-italic</v-icon>\n          </v-btn>\n\n          <v-btn>\n            <v-icon>mdi-format-underline</v-icon>\n          </v-btn>\n\n          <v-btn>\n            <v-icon>mdi-format-color-fill</v-icon>\n          </v-btn>\n        </v-btn-toggle>\n      </v-col>\n\n      <v-col\n        class=\"py-2\"\n        cols=\"12\"\n        sm=\"6\"\n      >\n        <p>No Options Selected</p>\n\n        <v-btn-toggle v-model=\"toggle_none\">\n          <v-btn>\n            <v-icon>mdi-format-align-left</v-icon>\n          </v-btn>\n\n          <v-btn>\n            <v-icon>mdi-format-align-center</v-icon>\n          </v-btn>\n          <v-btn>\n            <v-icon>mdi-format-align-right</v-icon>\n          </v-btn>\n\n          <v-btn>\n            <v-icon>mdi-format-align-justify</v-icon>\n          </v-btn>\n        </v-btn-toggle>\n      </v-col>\n\n      <v-col\n        class=\"py-2\"\n        cols=\"12\"\n        sm=\"6\"\n      >\n        <p>Mandatory</p>\n\n        <v-btn-toggle v-model=\"toggle_one\" mandatory>\n          <v-btn>\n            <v-icon>mdi-format-align-left</v-icon>\n          </v-btn>\n\n          <v-btn>\n            <v-icon>mdi-format-align-center</v-icon>\n          </v-btn>\n\n          <v-btn>\n            <v-icon>mdi-format-align-right</v-icon>\n          </v-btn>\n\n          <v-btn>\n            <v-icon>mdi-format-align-justify</v-icon>\n          </v-btn>\n        </v-btn-toggle>\n      </v-col>\n\n      <v-col\n        class=\"py-2\"\n        cols=\"12\"\n      >\n        <p>Text Options</p>\n\n        <v-btn-toggle\n          v-model=\"text\"\n          color=\"deep-purple-accent-3\"\n          rounded=\"0\"\n          group\n        >\n          <v-btn value=\"left\">\n            Left\n          </v-btn>\n\n          <v-btn value=\"center\">\n            Center\n          </v-btn>\n\n          <v-btn value=\"right\">\n            Right\n          </v-btn>\n\n          <v-btn value=\"justify\">\n            Justify\n          </v-btn>\n        </v-btn-toggle>\n      </v-col>\n\n      <v-col\n        class=\"py-2\"\n        cols=\"12\"\n      >\n        <p>Text &amp; Icon Options</p>\n\n        <v-btn-toggle v-model=\"icon\" divided>\n          <v-btn value=\"left\">\n            <span class=\"hidden-sm-and-down\">Left</span>\n\n            <v-icon end>\n              mdi-format-align-left\n            </v-icon>\n          </v-btn>\n\n          <v-btn value=\"center\">\n            <span class=\"hidden-sm-and-down\">Center</span>\n\n            <v-icon end>\n              mdi-format-align-center\n            </v-icon>\n          </v-btn>\n\n          <v-btn value=\"right\">\n            <span class=\"hidden-sm-and-down\">Right</span>\n\n            <v-icon end>\n              mdi-format-align-right\n            </v-icon>\n          </v-btn>\n\n          <v-btn value=\"justify\">\n            <span class=\"hidden-sm-and-down\">Justify</span>\n\n            <v-icon end>\n              mdi-format-align-justify\n            </v-icon>\n          </v-btn>\n        </v-btn-toggle>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script>\n  export default {\n    data () {\n      return {\n        text: 'center',\n        icon: 'justify',\n        toggle_none: null,\n        toggle_one: 0,\n        toggle_exclusive: 2,\n        toggle_multiple: [0, 1, 2],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-calendar/event-click.vue",
    "content": "<template>\n  <v-row class=\"fill-height\">\n    <v-col>\n      <v-sheet height=\"64\">\n        <v-toolbar flat>\n          <v-btn\n            class=\"me-4\"\n            color=\"grey-darken-2\"\n            variant=\"outlined\"\n            @click=\"setToday\"\n          >\n            Today\n          </v-btn>\n          <v-btn\n            color=\"grey-darken-2\"\n            size=\"small\"\n            variant=\"text\"\n            icon\n            @click=\"prev\"\n          >\n            <v-icon size=\"small\">\n              mdi-chevron-left\n            </v-icon>\n          </v-btn>\n          <v-btn\n            color=\"grey-darken-2\"\n            size=\"small\"\n            variant=\"text\"\n            icon\n            @click=\"next\"\n          >\n            <v-icon size=\"small\">\n              mdi-chevron-right\n            </v-icon>\n          </v-btn>\n          <v-toolbar-title v-if=\"calendar\">\n            {{ calendar.title }}\n          </v-toolbar-title>\n          <v-menu location=\"bottom end\">\n            <template v-slot:activator=\"{ props }\">\n              <v-btn\n                color=\"grey-darken-2\"\n                variant=\"outlined\"\n                v-bind=\"props\"\n              >\n                <span>{{ typeToLabel[type] }}</span>\n                <v-icon end>\n                  mdi-menu-down\n                </v-icon>\n              </v-btn>\n            </template>\n            <v-list>\n              <v-list-item @click=\"type = 'day'\">\n                <v-list-item-title>Day</v-list-item-title>\n              </v-list-item>\n              <v-list-item @click=\"type = 'week'\">\n                <v-list-item-title>Week</v-list-item-title>\n              </v-list-item>\n              <v-list-item @click=\"type = 'month'\">\n                <v-list-item-title>Month</v-list-item-title>\n              </v-list-item>\n              <v-list-item @click=\"type = '4day'\">\n                <v-list-item-title>4 days</v-list-item-title>\n              </v-list-item>\n            </v-list>\n          </v-menu>\n        </v-toolbar>\n      </v-sheet>\n      <v-sheet height=\"600\">\n        <v-calendar\n          ref=\"calendar\"\n          v-model=\"focus\"\n          :event-color=\"getEventColor\"\n          :events=\"events\"\n          :type=\"type\"\n          color=\"primary\"\n          @change=\"updateRange\"\n          @click:date=\"viewDay\"\n          @click:event=\"showEvent\"\n          @click:more=\"viewDay\"\n        ></v-calendar>\n        <v-menu\n          v-model=\"selectedOpen\"\n          :activator=\"selectedElement\"\n          :close-on-content-click=\"false\"\n          location=\"end\"\n        >\n          <v-card\n            color=\"grey-lighten-4\"\n            min-width=\"350px\"\n            flat\n          >\n            <v-toolbar\n              :color=\"selectedEvent.color\"\n              dark\n            >\n              <v-btn icon>\n                <v-icon>mdi-pencil</v-icon>\n              </v-btn>\n              <v-toolbar-title v-html=\"selectedEvent.name\"></v-toolbar-title>\n              <v-btn icon>\n                <v-icon>mdi-heart</v-icon>\n              </v-btn>\n              <v-btn icon>\n                <v-icon>mdi-dots-vertical</v-icon>\n              </v-btn>\n            </v-toolbar>\n            <v-card-text>\n              <span v-html=\"selectedEvent.details\"></span>\n            </v-card-text>\n            <v-card-actions>\n              <v-btn\n                color=\"secondary\"\n                variant=\"text\"\n                @click=\"selectedOpen = false\"\n              >\n                Cancel\n              </v-btn>\n            </v-card-actions>\n          </v-card>\n        </v-menu>\n      </v-sheet>\n    </v-col>\n  </v-row>\n</template>\n\n<script setup>\n  import { onMounted, ref } from 'vue'\n\n  const calendar = ref()\n\n  const typeToLabel = {\n    month: 'Month',\n    week: 'Week',\n    day: 'Day',\n    '4day': '4 Days',\n  }\n  const colors = ['blue', 'indigo', 'deep-purple', 'cyan', 'green', 'orange', 'grey darken-1']\n  const names = ['Meeting', 'Holiday', 'PTO', 'Travel', 'Event', 'Birthday', 'Conference', 'Party']\n\n  const focus = ref('')\n  const type = ref('month')\n  const selectedEvent = ref({})\n  const selectedElement = ref(null)\n  const selectedOpen = ref(false)\n  const events = ref([])\n\n  onMounted(() => {\n    calendar.value.checkChange()\n  })\n\n  function viewDay (nativeEvent, { date }) {\n    focus.value = date\n    type.value = 'day'\n  }\n  function getEventColor (event) {\n    return event.color\n  }\n  function setToday () {\n    focus.value = ''\n  }\n  function prev () {\n    calendar.value.prev()\n  }\n  function next () {\n    calendar.value.next()\n  }\n  function showEvent (nativeEvent, { event }) {\n    const open = () => {\n      selectedEvent.value = event\n      selectedElement.value = nativeEvent.target\n      requestAnimationFrame(() => requestAnimationFrame(() => selectedOpen.value = true))\n    }\n    if (selectedOpen.value) {\n      selectedOpen.value = false\n      requestAnimationFrame(() => requestAnimationFrame(() => open()))\n    } else {\n      open()\n    }\n    nativeEvent.stopPropagation()\n  }\n  function updateRange ({ start, end }) {\n    const _events = []\n    const min = new Date(`${start.date}T00:00:00`)\n    const max = new Date(`${end.date}T23:59:59`)\n    const days = (max.getTime() - min.getTime()) / 86400000\n    const eventCount = rnd(days, days + 20)\n    for (let i = 0; i < eventCount; i++) {\n      const allDay = rnd(0, 3) === 0\n      const firstTimestamp = rnd(min.getTime(), max.getTime())\n      const first = new Date(firstTimestamp - (firstTimestamp % 900000))\n      const secondTimestamp = rnd(2, allDay ? 288 : 8) * 900000\n      const second = new Date(first.getTime() + secondTimestamp)\n      _events.push({\n        name: names[rnd(0, names.length - 1)],\n        start: first,\n        end: second,\n        color: colors[rnd(0, colors.length - 1)],\n        timed: !allDay,\n      })\n    }\n    events.value = _events\n  }\n  function rnd (a, b) {\n    return Math.floor((b - a + 1) * Math.random()) + a\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      focus: '',\n      type: 'month',\n      typeToLabel: {\n        month: 'Month',\n        week: 'Week',\n        day: 'Day',\n        '4day': '4 Days',\n      },\n      selectedEvent: {},\n      selectedElement: null,\n      selectedOpen: false,\n      events: [],\n      colors: ['blue', 'indigo', 'deep-purple', 'cyan', 'green', 'orange', 'grey darken-1'],\n      names: ['Meeting', 'Holiday', 'PTO', 'Travel', 'Event', 'Birthday', 'Conference', 'Party'],\n    }),\n    mounted () {\n      this.$refs.calendar.checkChange()\n    },\n    methods: {\n      viewDay (nativeEvent, { date }) {\n        this.focus = date\n        this.type = 'day'\n      },\n      getEventColor (event) {\n        return event.color\n      },\n      setToday () {\n        this.focus = ''\n      },\n      prev () {\n        this.$refs.calendar.prev()\n      },\n      next () {\n        this.$refs.calendar.next()\n      },\n      showEvent (nativeEvent, { event }) {\n        const open = () => {\n          this.selectedEvent = event\n          this.selectedElement = nativeEvent.target\n          requestAnimationFrame(() => requestAnimationFrame(() => this.selectedOpen = true))\n        }\n\n        if (this.selectedOpen) {\n          this.selectedOpen = false\n          requestAnimationFrame(() => requestAnimationFrame(() => open()))\n        } else {\n          open()\n        }\n\n        nativeEvent.stopPropagation()\n      },\n      updateRange ({ start, end }) {\n        const events = []\n\n        const min = new Date(`${start.date}T00:00:00`)\n        const max = new Date(`${end.date}T23:59:59`)\n        const days = (max.getTime() - min.getTime()) / 86400000\n        const eventCount = this.rnd(days, days + 20)\n\n        for (let i = 0; i < eventCount; i++) {\n          const allDay = this.rnd(0, 3) === 0\n          const firstTimestamp = this.rnd(min.getTime(), max.getTime())\n          const first = new Date(firstTimestamp - (firstTimestamp % 900000))\n          const secondTimestamp = this.rnd(2, allDay ? 288 : 8) * 900000\n          const second = new Date(first.getTime() + secondTimestamp)\n\n          events.push({\n            name: this.names[this.rnd(0, this.names.length - 1)],\n            start: first,\n            end: second,\n            color: this.colors[this.rnd(0, this.colors.length - 1)],\n            timed: !allDay,\n          })\n        }\n\n        this.events = events\n      },\n      rnd (a, b) {\n        return Math.floor((b - a + 1) * Math.random()) + a\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-calendar/misc-drag-and-drop.vue",
    "content": "<template>\n  <v-row class=\"fill-height\">\n    <v-col>\n      <v-sheet height=\"600\">\n        <v-calendar\n          ref=\"calendar\"\n          v-model=\"value\"\n          :event-color=\"getEventColor\"\n          :event-ripple=\"false\"\n          :events=\"events\"\n          color=\"primary\"\n          type=\"4day\"\n          @change=\"getEvents\"\n          @mousedown:event=\"startDrag\"\n          @mousedown:time=\"startTime\"\n          @mouseleave=\"cancelDrag\"\n          @mousemove:time=\"mouseMove\"\n          @mouseup:time=\"endDrag\"\n        >\n          <template v-slot:event=\"{ event, timed, eventSummary }\">\n            <div class=\"v-event-draggable\">\n              <component :is=\"eventSummary\"></component>\n            </div>\n            <div\n              v-if=\"timed\"\n              class=\"v-event-drag-bottom\"\n              @mousedown.stop=\"extendBottom(event)\"\n            ></div>\n          </template>\n        </v-calendar>\n      </v-sheet>\n    </v-col>\n  </v-row>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const value = ref('')\n  const events = ref([])\n  const colors = [\n    '#2196F3', '#3F51B5', '#673AB7', '#00BCD4', '#4CAF50', '#FF9800', '#757575',\n  ]\n  const names = [\n    'Meeting', 'Holiday', 'PTO', 'Travel', 'Event', 'Birthday', 'Conference', 'Party',\n  ]\n  const dragEvent = ref(null)\n  const dragTime = ref(null)\n  const createEvent = ref(null)\n  const createStart = ref(null)\n  const extendOriginal = ref(null)\n\n  function startDrag (nativeEvent, { event, timed }) {\n    if (event && timed) {\n      dragEvent.value = event\n      dragTime.value = null\n      extendOriginal.value = null\n    }\n  }\n\n  function startTime (nativeEvent, tms) {\n    const mouse = toTime(tms)\n\n    if (dragEvent.value && dragTime.value === null) {\n      const start = dragEvent.value.start\n      dragTime.value = mouse - start\n    } else {\n      createStart.value = roundTime(mouse)\n      createEvent.value = {\n        name: `Event #${events.value.length}`,\n        color: rndElement(colors),\n        start: createStart.value,\n        end: createStart.value,\n        timed: true,\n      }\n      events.value.push(createEvent.value)\n    }\n  }\n\n  function extendBottom (event) {\n    createEvent.value = event\n    createStart.value = event.start\n    extendOriginal.value = event.end\n  }\n\n  function mouseMove (nativeEvent, tms) {\n    const mouse = toTime(tms)\n\n    if (dragEvent.value && dragTime.value !== null) {\n      const start = dragEvent.value.start\n      const end = dragEvent.value.end\n      const duration = end - start\n      const newStartTime = mouse - dragTime.value\n      const newStart = roundTime(newStartTime)\n      const newEnd = newStart + duration\n\n      dragEvent.value.start = newStart\n      dragEvent.value.end = newEnd\n    } else if (createEvent.value && createStart.value !== null) {\n      const mouseRounded = roundTime(mouse, false)\n      const min = Math.min(mouseRounded, createStart.value)\n      const max = Math.max(mouseRounded, createStart.value)\n\n      createEvent.value.start = min\n      createEvent.value.end = max\n    }\n  }\n\n  function endDrag () {\n    dragTime.value = null\n    dragEvent.value = null\n    createEvent.value = null\n    createStart.value = null\n    extendOriginal.value = null\n  }\n\n  function cancelDrag () {\n    if (createEvent.value) {\n      if (extendOriginal.value) {\n        createEvent.value.end = extendOriginal.value\n      } else {\n        const i = events.value.indexOf(createEvent.value)\n        if (i !== -1) {\n          events.value.splice(i, 1)\n        }\n      }\n    }\n\n    createEvent.value = null\n    createStart.value = null\n    dragTime.value = null\n    dragEvent.value = null\n  }\n\n  function roundTime (time, down = true) {\n    const roundTo = 15 // minutes\n    const roundDownTime = roundTo * 60 * 1000\n\n    return down\n      ? time - time % roundDownTime\n      : time + (roundDownTime - (time % roundDownTime))\n  }\n\n  function toTime (tms) {\n    return new Date(tms.year, tms.month - 1, tms.day, tms.hour, tms.minute).getTime()\n  }\n\n  function getEventColor (event) {\n    const rgb = parseInt(event.color.substring(1), 16)\n    const r = (rgb >> 16) & 0xFF\n    const g = (rgb >> 8) & 0xFF\n    const b = (rgb >> 0) & 0xFF\n\n    return event === dragEvent.value\n      ? `rgba(${r}, ${g}, ${b}, 0.7)`\n      : event === createEvent.value\n        ? `rgba(${r}, ${g}, ${b}, 0.7)`\n        : event.color\n  }\n\n  function getEvents ({ start, end }) {\n    const newEvents = []\n\n    const min = new Date(`${start.date}T00:00:00`).getTime()\n    const max = new Date(`${end.date}T23:59:59`).getTime()\n    const days = (max - min) / 86400000\n    const eventCount = rnd(days, days + 20)\n\n    for (let i = 0; i < eventCount; i++) {\n      const timed = rnd(0, 3) !== 0\n      const firstTimestamp = rnd(min, max)\n      const secondTimestamp = rnd(2, timed ? 8 : 288) * 900000\n      const startTime = firstTimestamp - (firstTimestamp % 900000)\n      const endTime = startTime + secondTimestamp\n\n      newEvents.push({\n        name: rndElement(names),\n        color: rndElement(colors),\n        start: startTime,\n        end: endTime,\n        timed,\n      })\n    }\n\n    events.value = newEvents\n  }\n\n  function rnd (a, b) {\n    return Math.floor((b - a + 1) * Math.random()) + a\n  }\n\n  function rndElement (arr) {\n    return arr[rnd(0, arr.length - 1)]\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      value: '',\n      events: [],\n      colors: ['#2196F3', '#3F51B5', '#673AB7', '#00BCD4', '#4CAF50', '#FF9800', '#757575'],\n      names: ['Meeting', 'Holiday', 'PTO', 'Travel', 'Event', 'Birthday', 'Conference', 'Party'],\n      dragEvent: null,\n      dragStart: null,\n      createEvent: null,\n      createStart: null,\n      extendOriginal: null,\n    }),\n    methods: {\n      startDrag (nativeEvent, { event, timed }) {\n        if (event && timed) {\n          this.dragEvent = event\n          this.dragTime = null\n          this.extendOriginal = null\n        }\n      },\n      startTime (nativeEvent, tms) {\n        const mouse = this.toTime(tms)\n\n        if (this.dragEvent && this.dragTime === null) {\n          const start = this.dragEvent.start\n\n          this.dragTime = mouse - start\n        } else {\n          this.createStart = this.roundTime(mouse)\n          this.createEvent = {\n            name: `Event #${this.events.length}`,\n            color: this.rndElement(this.colors),\n            start: this.createStart,\n            end: this.createStart,\n            timed: true,\n          }\n\n          this.events.push(this.createEvent)\n        }\n      },\n      extendBottom (event) {\n        this.createEvent = event\n        this.createStart = event.start\n        this.extendOriginal = event.end\n      },\n      mouseMove (nativeEvent, tms) {\n        const mouse = this.toTime(tms)\n\n        if (this.dragEvent && this.dragTime !== null) {\n          const start = this.dragEvent.start\n          const end = this.dragEvent.end\n          const duration = end - start\n          const newStartTime = mouse - this.dragTime\n          const newStart = this.roundTime(newStartTime)\n          const newEnd = newStart + duration\n\n          this.dragEvent.start = newStart\n          this.dragEvent.end = newEnd\n        } else if (this.createEvent && this.createStart !== null) {\n          const mouseRounded = this.roundTime(mouse, false)\n          const min = Math.min(mouseRounded, this.createStart)\n          const max = Math.max(mouseRounded, this.createStart)\n\n          this.createEvent.start = min\n          this.createEvent.end = max\n        }\n      },\n      endDrag () {\n        this.dragTime = null\n        this.dragEvent = null\n        this.createEvent = null\n        this.createStart = null\n        this.extendOriginal = null\n      },\n      cancelDrag () {\n        if (this.createEvent) {\n          if (this.extendOriginal) {\n            this.createEvent.end = this.extendOriginal\n          } else {\n            const i = this.events.indexOf(this.createEvent)\n            if (i !== -1) {\n              this.events.splice(i, 1)\n            }\n          }\n        }\n\n        this.createEvent = null\n        this.createStart = null\n        this.dragTime = null\n        this.dragEvent = null\n      },\n      roundTime (time, down = true) {\n        const roundTo = 15 // minutes\n        const roundDownTime = roundTo * 60 * 1000\n\n        return down\n          ? time - time % roundDownTime\n          : time + (roundDownTime - (time % roundDownTime))\n      },\n      toTime (tms) {\n        return new Date(tms.year, tms.month - 1, tms.day, tms.hour, tms.minute).getTime()\n      },\n      getEventColor (event) {\n        const rgb = parseInt(event.color.substring(1), 16)\n        const r = (rgb >> 16) & 0xFF\n        const g = (rgb >> 8) & 0xFF\n        const b = (rgb >> 0) & 0xFF\n\n        return event === this.dragEvent\n          ? `rgba(${r}, ${g}, ${b}, 0.7)`\n          : event === this.createEvent\n            ? `rgba(${r}, ${g}, ${b}, 0.7)`\n            : event.color\n      },\n      getEvents ({ start, end }) {\n        const events = []\n\n        const min = new Date(`${start.date}T00:00:00`).getTime()\n        const max = new Date(`${end.date}T23:59:59`).getTime()\n        const days = (max - min) / 86400000\n        const eventCount = this.rnd(days, days + 20)\n\n        for (let i = 0; i < eventCount; i++) {\n          const timed = this.rnd(0, 3) !== 0\n          const firstTimestamp = this.rnd(min, max)\n          const secondTimestamp = this.rnd(2, timed ? 8 : 288) * 900000\n          const start = firstTimestamp - (firstTimestamp % 900000)\n          const end = start + secondTimestamp\n\n          events.push({\n            name: this.rndElement(this.names),\n            color: this.rndElement(this.colors),\n            start,\n            end,\n            timed,\n          })\n        }\n\n        this.events = events\n      },\n      rnd (a, b) {\n        return Math.floor((b - a + 1) * Math.random()) + a\n      },\n      rndElement (arr) {\n        return arr[this.rnd(0, arr.length - 1)]\n      },\n    },\n  }\n</script>\n\n<style scoped>\n.v-event-draggable {\n  padding-left: 6px;\n}\n\n.v-event-timed {\n  user-select: none;\n  -webkit-user-select: none;\n}\n\n.v-event-drag-bottom {\n  position: absolute;\n  left: 0;\n  right: 0;\n  bottom: 4px;\n  height: 4px;\n  cursor: ns-resize;\n\n  &::after {\n    display: none;\n    position: absolute;\n    left: 50%;\n    height: 4px;\n    border-top: 1px solid white;\n    border-bottom: 1px solid white;\n    width: 16px;\n    margin-left: -8px;\n    opacity: 0.8;\n    content: '';\n  }\n\n  &:hover::after {\n    display: block;\n  }\n}\n</style>\n"
  },
  {
    "path": "packages/docs/src/examples/v-calendar/prop-type-category.vue",
    "content": "<template>\n  <v-row class=\"fill-height\">\n    <v-col>\n      <v-sheet height=\"64\">\n        <v-toolbar flat>\n          <v-btn\n            class=\"mr-4\"\n            color=\"grey-darken-2\"\n            variant=\"outlined\"\n            @click=\"setToday\"\n          >\n            Today\n          </v-btn>\n          <v-btn\n            color=\"grey-darken-2\"\n            size=\"small\"\n            variant=\"text\"\n            icon\n            @click=\"prev\"\n          >\n            <v-icon size=\"small\">\n              mdi-chevron-left\n            </v-icon>\n          </v-btn>\n          <v-btn\n            color=\"grey-darken-2\"\n            size=\"small\"\n            variant=\"text\"\n            icon\n            @click=\"next\"\n          >\n            <v-icon size=\"small\">\n              mdi-chevron-right\n            </v-icon>\n          </v-btn>\n          <v-toolbar-title v-if=\"calendar\">\n            {{ calendar.title }}\n          </v-toolbar-title>\n        </v-toolbar>\n      </v-sheet>\n      <v-sheet height=\"600\">\n        <v-calendar\n          ref=\"calendar\"\n          v-model=\"focus\"\n          :categories=\"categories\"\n          :event-color=\"getEventColor\"\n          :events=\"events\"\n          color=\"primary\"\n          type=\"category\"\n          category-show-all\n          @change=\"fetchEvents\"\n        ></v-calendar>\n      </v-sheet>\n    </v-col>\n  </v-row>\n</template>\n\n<script setup>\n  import { onMounted, ref } from 'vue'\n\n  const calendar = ref()\n\n  const focus = ref('')\n  const events = ref([])\n  const colors = ['blue', 'indigo', 'deep-purple', 'cyan', 'green', 'orange', 'grey-darken-1']\n  const names = ['Meeting', 'Holiday', 'PTO', 'Travel', 'Event', 'Birthday', 'Conference', 'Party']\n  const categories = ['John Smith', 'Tori Walker']\n\n  function getEventColor (event) {\n    return event.color\n  }\n\n  function setToday () {\n    focus.value = ''\n  }\n\n  function prev () {\n    calendar.value.prev()\n  }\n\n  function next () {\n    calendar.value.next()\n  }\n\n  function fetchEvents ({ start, end }) {\n    const evts = []\n\n    const min = new Date(`${start.date}T00:00:00`)\n    const max = new Date(`${end.date}T23:59:59`)\n    const days = (max.getTime() - min.getTime()) / 86400000\n    const eventCount = rnd(days, days + 20)\n\n    for (let i = 0; i < eventCount; i++) {\n      const allDay = rnd(0, 3) === 0\n      const firstTimestamp = rnd(min.getTime(), max.getTime())\n      const first = new Date(firstTimestamp - (firstTimestamp % 900000))\n      const secondTimestamp = rnd(2, allDay ? 288 : 8) * 900000\n      const second = new Date(first.getTime() + secondTimestamp)\n\n      evts.push({\n        name: names[rnd(0, names.length - 1)],\n        start: first,\n        end: second,\n        color: colors[rnd(0, colors.length - 1)],\n        timed: !allDay,\n        category: categories[rnd(0, categories.length - 1)],\n      })\n    }\n\n    events.value = evts\n  }\n\n  function rnd (a, b) {\n    return Math.floor((b - a + 1) * Math.random()) + a\n  }\n\n  onMounted(() => {\n    calendar.value.checkChange()\n  })\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      focus: '',\n      events: [],\n      colors: ['blue', 'indigo', 'deep-purple', 'cyan', 'green', 'orange', 'grey-darken-1'],\n      names: ['Meeting', 'Holiday', 'PTO', 'Travel', 'Event', 'Birthday', 'Conference', 'Party'],\n      categories: ['John Smith', 'Tori Walker'],\n    }),\n    mounted () {\n      this.$refs.calendar.checkChange()\n    },\n    methods: {\n      getEventColor (event) {\n        return event.color\n      },\n      setToday () {\n        this.focus = ''\n      },\n      prev () {\n        this.$refs.calendar.prev()\n      },\n      next () {\n        this.$refs.calendar.next()\n      },\n      fetchEvents ({ start, end }) {\n        const events = []\n\n        const min = new Date(`${start.date}T00:00:00`)\n        const max = new Date(`${end.date}T23:59:59`)\n        const days = (max.getTime() - min.getTime()) / 86400000\n        const eventCount = this.rnd(days, days + 20)\n\n        for (let i = 0; i < eventCount; i++) {\n          const allDay = this.rnd(0, 3) === 0\n          const firstTimestamp = this.rnd(min.getTime(), max.getTime())\n          const first = new Date(firstTimestamp - (firstTimestamp % 900000))\n          const secondTimestamp = this.rnd(2, allDay ? 288 : 8) * 900000\n          const second = new Date(first.getTime() + secondTimestamp)\n\n          events.push({\n            name: this.names[this.rnd(0, this.names.length - 1)],\n            start: first,\n            end: second,\n            color: this.colors[this.rnd(0, this.colors.length - 1)],\n            timed: !allDay,\n            category: this.categories[this.rnd(0, this.categories.length - 1)],\n          })\n        }\n\n        this.events = events\n      },\n      rnd (a, b) {\n        return Math.floor((b - a + 1) * Math.random()) + a\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-calendar/prop-type-day.vue",
    "content": "<template>\n  <v-row>\n    <v-col>\n      <v-sheet height=\"400\">\n        <v-calendar\n          color=\"primary\"\n          type=\"day\"\n        >\n          <template v-slot:day-header=\"{ present }\">\n            <div v-if=\"present\" class=\"text-center\">\n              Today\n            </div>\n          </template>\n\n          <template v-slot:interval=\"{ hour }\">\n            <div class=\"text-center\">\n              {{ hour }} o'clock\n            </div>\n          </template>\n        </v-calendar>\n      </v-sheet>\n    </v-col>\n  </v-row>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-calendar/prop-type-week.vue",
    "content": "<template>\n  <v-row>\n    <v-col>\n      <v-sheet height=\"400\">\n        <v-calendar\n          ref=\"calendar\"\n          :events=\"events\"\n          :model-value=\"today\"\n          :now=\"today\"\n          color=\"primary\"\n          type=\"week\"\n        ></v-calendar>\n      </v-sheet>\n    </v-col>\n  </v-row>\n</template>\n\n<script setup>\n  import { onMounted, ref } from 'vue'\n\n  const calendar = ref()\n\n  const today = ref('2019-01-08')\n  const events = [\n    {\n      name: 'Weekly Meeting',\n      start: '2019-01-07 09:00',\n      end: '2019-01-07 10:00',\n    },\n    {\n      name: `Thomas' Birthday`,\n      start: '2019-01-10',\n    },\n    {\n      name: 'Mash Potatoes',\n      start: '2019-01-09 12:30',\n      end: '2019-01-09 15:30',\n    },\n  ]\n\n  onMounted(() => {\n    calendar.value.scrollToTime('08:00')\n  })\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      today: '2019-01-08',\n      events: [\n        {\n          name: 'Weekly Meeting',\n          start: '2019-01-07 09:00',\n          end: '2019-01-07 10:00',\n        },\n        {\n          name: `Thomas' Birthday`,\n          start: '2019-01-10',\n        },\n        {\n          name: 'Mash Potatoes',\n          start: '2019-01-09 12:30',\n          end: '2019-01-09 15:30',\n        },\n      ],\n    }),\n    mounted () {\n      this.$refs.calendar.scrollToTime('08:00')\n    },\n  }\n</script>\n\n<style scoped>\n.my-event {\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n  border-radius: 2px;\n  background-color: #1867c0;\n  color: #ffffff;\n  border: 1px solid #1867c0;\n  font-size: 12px;\n  padding: 3px;\n  cursor: pointer;\n  margin-bottom: 1px;\n  left: 4px;\n  margin-right: 8px;\n  position: relative;\n}\n\n.my-event.with-time {\n  position: absolute;\n  right: 4px;\n  margin-right: 0px;\n}\n</style>\n"
  },
  {
    "path": "packages/docs/src/examples/v-calendar/slot-day-body.vue",
    "content": "<template>\n  <v-row>\n    <v-col>\n      <v-sheet height=\"500\">\n        <v-calendar\n          ref=\"calendar\"\n          v-model=\"value\"\n          type=\"week\"\n        >\n          <template v-slot:day-body=\"{ date, week }\">\n            <div\n              :class=\"{ first: date === week[0].date }\"\n              :style=\"{ top: nowY() }\"\n              class=\"v-current-time\"\n            ></div>\n          </template>\n        </v-calendar>\n      </v-sheet>\n    </v-col>\n  </v-row>\n</template>\n\n<script setup>\n  import { onMounted, onUnmounted, ref } from 'vue'\n\n  const calendar = ref()\n\n  const value = ref('')\n\n  function nowY () {\n    return calendar.value ? calendar.value.timeToY(calendar.value.times.now) + 'px' : '-10px'\n  }\n\n  let updateInterval = -1\n  onMounted(() => {\n    scrollToTime()\n    updateInterval = setInterval(() => calendar.value?.updateTimes(), 60_000)\n  })\n\n  onUnmounted(() => {\n    clearInterval(updateInterval)\n  })\n\n  function getCurrentTime () {\n    return calendar.value ? calendar.value.times.now.hour * 60 + calendar.value.times.now.minute : 0\n  }\n  function scrollToTime () {\n    const time = getCurrentTime()\n    const first = Math.max(0, time - (time % 30) - 30)\n    calendar.value?.scrollToTime(first)\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      value: '',\n      ready: false,\n    }),\n    computed: {\n      cal () {\n        return this.ready ? this.$refs.calendar : null\n      },\n    },\n    mounted () {\n      this.ready = true\n      this.scrollToTime()\n      this.updateTime()\n    },\n    methods: {\n      nowY () {\n        return this.cal ? this.cal.timeToY(this.cal.times.now) + 'px' : '-10px'\n      },\n      getCurrentTime () {\n        return this.cal ? this.cal.times.now.hour * 60 + this.cal.times.now.minute : 0\n      },\n      scrollToTime () {\n        const time = this.getCurrentTime()\n        const first = Math.max(0, time - (time % 30) - 30)\n\n        this.cal.scrollToTime(first)\n      },\n      updateTime () {\n        setInterval(() => this.cal.updateTimes(), 60 * 1000)\n      },\n    },\n  }\n</script>\n\n<style>\n.v-current-time {\n  height: 2px;\n  background-color: #ea4335;\n  position: absolute;\n  left: -1px;\n  right: 0;\n  pointer-events: none;\n\n  &.first::before {\n    content: '';\n    position: absolute;\n    background-color: #ea4335;\n    width: 12px;\n    height: 12px;\n    border-radius: 50%;\n    margin-top: -5px;\n    margin-left: -6.5px;\n  }\n}\n</style>\n"
  },
  {
    "path": "packages/docs/src/examples/v-calendar/slot-day.vue",
    "content": "<template>\n  <v-row>\n    <v-col>\n      <v-sheet height=\"500\">\n        <v-calendar\n          :model-value=\"today\"\n          :now=\"today\"\n          color=\"primary\"\n        >\n          <template v-slot:day=\"{ past, date }\">\n            <v-row class=\"fill-height\">\n              <template v-if=\"past && tracked[date]\">\n                <v-sheet\n                  v-for=\"(percent, i) in tracked[date]\"\n                  :key=\"i\"\n                  :color=\"colors[i]\"\n                  :title=\"category[i]\"\n                  :width=\"`${percent}%`\"\n                  height=\"100%\"\n                  tile\n                ></v-sheet>\n              </template>\n            </v-row>\n          </template>\n        </v-calendar>\n      </v-sheet>\n    </v-col>\n  </v-row>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const today = ref('2019-01-10')\n  const tracked = {\n    '2019-01-09': [23, 45, 10],\n    '2019-01-08': [10],\n    '2019-01-07': [0, 78, 5],\n    '2019-01-06': [0, 0, 50],\n    '2019-01-05': [0, 10, 23],\n    '2019-01-04': [2, 90],\n    '2019-01-03': [10, 32],\n    '2019-01-02': [80, 10, 10],\n    '2019-01-01': [20, 25, 10],\n  }\n  const colors = ['#1867c0', '#fb8c00', '#000000']\n  const category = ['Development', 'Meetings', 'Slacking']\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      today: '2019-01-10',\n      tracked: {\n        '2019-01-09': [23, 45, 10],\n        '2019-01-08': [10],\n        '2019-01-07': [0, 78, 5],\n        '2019-01-06': [0, 0, 50],\n        '2019-01-05': [0, 10, 23],\n        '2019-01-04': [2, 90],\n        '2019-01-03': [10, 32],\n        '2019-01-02': [80, 10, 10],\n        '2019-01-01': [20, 25, 10],\n      },\n      colors: ['#1867c0', '#fb8c00', '#000000'],\n      category: ['Development', 'Meetings', 'Slacking'],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-calendar/usage.vue",
    "content": "<template>\n  <div>\n    <v-sheet class=\"d-flex\" tile>\n      <v-btn\n        class=\"ma-2\"\n        variant=\"text\"\n        icon\n        @click=\"$refs.calendar.prev()\"\n      >\n        <v-icon>mdi-chevron-left</v-icon>\n      </v-btn>\n      <v-select\n        v-model=\"type\"\n        :items=\"types\"\n        class=\"ma-2\"\n        density=\"comfortable\"\n        label=\"type\"\n        variant=\"outlined\"\n        hide-details\n      ></v-select>\n      <v-select\n        v-model=\"mode\"\n        :items=\"modes\"\n        class=\"ma-2\"\n        density=\"comfortable\"\n        label=\"event-overlap-mode\"\n        variant=\"outlined\"\n        hide-details\n      ></v-select>\n      <v-select\n        v-model=\"weekday\"\n        :items=\"weekdays\"\n        class=\"ma-2\"\n        density=\"comfortable\"\n        label=\"weekdays\"\n        variant=\"outlined\"\n        hide-details\n      ></v-select>\n      <v-spacer></v-spacer>\n      <v-btn\n        class=\"ma-2\"\n        variant=\"text\"\n        icon\n        @click=\"$refs.calendar.next()\"\n      >\n        <v-icon>mdi-chevron-right</v-icon>\n      </v-btn>\n    </v-sheet>\n    <v-sheet height=\"600\">\n      <v-calendar\n        ref=\"calendar\"\n        v-model=\"value\"\n        :event-color=\"getEventColor\"\n        :event-overlap-mode=\"mode\"\n        :event-overlap-threshold=\"30\"\n        :events=\"events\"\n        :type=\"type\"\n        :weekdays=\"weekday\"\n        @change=\"getEvents\"\n      ></v-calendar>\n    </v-sheet>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const type = ref('month')\n  const types = ['month', 'week', 'day', '4day']\n  const mode = ref('stack')\n  const modes = ['stack', 'column']\n  const weekday = ref([0, 1, 2, 3, 4, 5, 6])\n  const weekdays = [\n    { title: 'Sun - Sat', value: [0, 1, 2, 3, 4, 5, 6] },\n    { title: 'Mon - Sun', value: [1, 2, 3, 4, 5, 6, 0] },\n    { title: 'Mon - Fri', value: [1, 2, 3, 4, 5] },\n    { title: 'Mon, Wed, Fri', value: [1, 3, 5] },\n  ]\n  const value = ref('')\n  const events = ref([])\n  const colors = ['blue', 'indigo', 'deep-purple', 'cyan', 'green', 'orange', 'grey-darken-1']\n  const names = ['Meeting', 'Holiday', 'PTO', 'Travel', 'Event', 'Birthday', 'Conference', 'Party']\n\n  function rnd (a, b) {\n    return Math.floor((b - a + 1) * Math.random()) + a\n  }\n\n  function getEvents ({ start, end }) {\n    const evts = []\n\n    const min = new Date(`${start.date}T00:00:00`)\n    const max = new Date(`${end.date}T23:59:59`)\n    const days = (max.getTime() - min.getTime()) / 86400000\n    const eventCount = rnd(days, days + 20)\n\n    for (let i = 0; i < eventCount; i++) {\n      const allDay = rnd(0, 3) === 0\n      const firstTimestamp = rnd(min.getTime(), max.getTime())\n      const first = new Date(firstTimestamp - (firstTimestamp % 900000))\n      const secondTimestamp = rnd(2, allDay ? 288 : 8) * 900000\n      const second = new Date(first.getTime() + secondTimestamp)\n\n      evts.push({\n        name: names[rnd(0, names.length - 1)],\n        start: first,\n        end: second,\n        color: colors[rnd(0, colors.length - 1)],\n        timed: !allDay,\n      })\n    }\n\n    events.value = evts\n  }\n\n  function getEventColor (event) {\n    return event.color\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      type: 'month',\n      types: ['month', 'week', 'day', '4day'],\n      mode: 'stack',\n      modes: ['stack', 'column'],\n      weekday: [0, 1, 2, 3, 4, 5, 6],\n      weekdays: [\n        { title: 'Sun - Sat', value: [0, 1, 2, 3, 4, 5, 6] },\n        { title: 'Mon - Sun', value: [1, 2, 3, 4, 5, 6, 0] },\n        { title: 'Mon - Fri', value: [1, 2, 3, 4, 5] },\n        { title: 'Mon, Wed, Fri', value: [1, 3, 5] },\n      ],\n      value: '',\n      events: [],\n      colors: ['blue', 'indigo', 'deep-purple', 'cyan', 'green', 'orange', 'grey-darken-1'],\n      names: ['Meeting', 'Holiday', 'PTO', 'Travel', 'Event', 'Birthday', 'Conference', 'Party'],\n    }),\n    methods: {\n      getEvents ({ start, end }) {\n        const events = []\n\n        const min = new Date(`${start.date}T00:00:00`)\n        const max = new Date(`${end.date}T23:59:59`)\n        const days = (max.getTime() - min.getTime()) / 86400000\n        const eventCount = this.rnd(days, days + 20)\n\n        for (let i = 0; i < eventCount; i++) {\n          const allDay = this.rnd(0, 3) === 0\n          const firstTimestamp = this.rnd(min.getTime(), max.getTime())\n          const first = new Date(firstTimestamp - (firstTimestamp % 900000))\n          const secondTimestamp = this.rnd(2, allDay ? 288 : 8) * 900000\n          const second = new Date(first.getTime() + secondTimestamp)\n\n          events.push({\n            name: this.names[this.rnd(0, this.names.length - 1)],\n            start: first,\n            end: second,\n            color: this.colors[this.rnd(0, this.colors.length - 1)],\n            timed: !allDay,\n          })\n        }\n\n        this.events = events\n      },\n      getEventColor (event) {\n        return event.color\n      },\n      rnd (a, b) {\n        return Math.floor((b - a + 1) * Math.random()) + a\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-card/basics-combine.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    prepend-icon=\"$vuetify\"\n    subtitle=\"The #1 Vue UI Library\"\n    width=\"400\"\n  >\n    <template v-slot:title>\n      <span class=\"font-weight-black\">Welcome to Vuetify</span>\n    </template>\n\n    <v-card-text class=\"bg-surface-light pt-4\">\n      Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!\n    </v-card-text>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-card/basics-content.vue",
    "content": "<template>\n  <v-row>\n    <v-col cols=\"12\" md=\"4\">\n      <v-card\n        subtitle=\"This is a card subtitle\"\n        text=\"Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus!\"\n        title=\"This is a title\"\n      ></v-card>\n\n      <div class=\"text-center text-body-small\">Using Props Only</div>\n    </v-col>\n\n    <v-col cols=\"12\" md=\"4\">\n      <v-card>\n        <template v-slot:title>\n          This is a title\n        </template>\n\n        <template v-slot:subtitle>\n          This is a card subtitle\n        </template>\n\n        <template v-slot:text>\n          Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus!\n        </template>\n      </v-card>\n\n      <div class=\"text-center text-body-small\">Using Slots Only</div>\n    </v-col>\n\n    <v-col cols=\"12\" md=\"4\">\n      <v-card>\n        <v-card-item>\n          <v-card-title>This is a title</v-card-title>\n\n          <v-card-subtitle>This is a card subtitle</v-card-subtitle>\n        </v-card-item>\n\n        <v-card-text>\n          Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus!\n        </v-card-text>\n      </v-card>\n\n      <div class=\"text-center text-body-small\">Using Markup Only</div>\n    </v-col>\n  </v-row>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-card/misc-card-reveal.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"344\"\n  >\n    <v-card-text>\n      <div>Word of the Day</div>\n\n      <div class=\"text-headline-large font-weight-black mb-4\">el·ee·mos·y·nar·y</div>\n\n      <div class=\"mb-4\">adjective</div>\n\n      <div class=\"text-medium-emphasis\">\n        relating to or dependent on charity; charitable; charitable donations. Pertaining to alms.<br>\n        \"an eleemosynary educational institution.\"\n      </div>\n    </v-card-text>\n\n    <v-card-actions>\n      <v-btn\n        color=\"teal-accent-4\"\n        text=\"Learn More\"\n        variant=\"text\"\n        @click=\"reveal = true\"\n      ></v-btn>\n    </v-card-actions>\n\n    <v-expand-transition>\n      <v-card\n        v-if=\"reveal\"\n        class=\"position-absolute w-100\"\n        height=\"100%\"\n        style=\"bottom: 0;\"\n      >\n        <v-card-text class=\"pb-0\">\n          <p class=\"text-headline-large\">Origin</p>\n\n          <p class=\"text-medium-emphasis\">\n            late 16th century (as a noun denoting a place where alms were distributed): from medieval Latin eleemosynarius, from late Latin eleemosyna ‘alms’, from Greek eleēmosunē ‘compassion’\n          </p>\n        </v-card-text>\n\n        <v-card-actions class=\"pt-0\">\n          <v-btn\n            color=\"teal-accent-4\"\n            text=\"Close\"\n            variant=\"text\"\n            @click=\"reveal = false\"\n          ></v-btn>\n        </v-card-actions>\n      </v-card>\n    </v-expand-transition>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const reveal = ref(false)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      reveal: false,\n    }),\n  }\n</script>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=1490-94081&t=tWnPBMI0RfGlNRgq-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-card/misc-content-wrapping.vue",
    "content": "<template>\n  <v-card class=\"mx-auto\" max-width=\"400\">\n    <v-img\n      color=\"surface-variant\"\n      height=\"200\"\n      src=\"https://cdn.vuetifyjs.com/docs/images/cards/purple-flowers.jpg\"\n      cover\n    >\n      <v-toolbar color=\"transparent\">\n        <template v-slot:prepend>\n          <v-btn icon=\"$menu\"></v-btn>\n        </template>\n\n        <v-toolbar-title class=\"text-title-large\" text=\"Messages\"></v-toolbar-title>\n\n        <template v-slot:append>\n          <v-btn icon=\"mdi-dots-vertical\"></v-btn>\n        </template>\n      </v-toolbar>\n    </v-img>\n\n    <v-card-text>\n      <div class=\"font-weight-bold ms-1 mb-2\">Today</div>\n\n      <v-timeline align=\"start\" density=\"compact\">\n        <v-timeline-item\n          v-for=\"message in messages\"\n          :key=\"message.time\"\n          :dot-color=\"message.color\"\n          size=\"x-small\"\n        >\n          <div class=\"mb-4\">\n            <div class=\"font-weight-normal\">\n              <strong>{{ message.from }}</strong> @{{ message.time }}\n            </div>\n\n            <div>{{ message.message }}</div>\n          </div>\n        </v-timeline-item>\n      </v-timeline>\n    </v-card-text>\n  </v-card>\n</template>\n\n<script setup>\n  const messages = [\n    {\n      from: 'You',\n      message: `Sure, I'll see you later.`,\n      time: '10:42am',\n      color: 'deep-purple-lighten-1',\n    },\n    {\n      from: 'John Doe',\n      message: 'Yeah, sure. Does 1:00pm work?',\n      time: '10:37am',\n      color: 'green',\n    },\n    {\n      from: 'You',\n      message: 'Did you still want to grab lunch today?',\n      time: '9:47am',\n      color: 'deep-purple-lighten-1',\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      messages: [\n        {\n          from: 'You',\n          message: `Sure, I'll see you later.`,\n          time: '10:42am',\n          color: 'deep-purple-lighten-1',\n        },\n        {\n          from: 'John Doe',\n          message: 'Yeah, sure. Does 1:00pm work?',\n          time: '10:37am',\n          color: 'green',\n        },\n        {\n          from: 'You',\n          message: 'Did you still want to grab lunch today?',\n          time: '9:47am',\n          color: 'deep-purple-lighten-1',\n        },\n      ],\n    }),\n  }\n</script>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=1514-95995&t=tWnPBMI0RfGlNRgq-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-card/misc-custom-actions.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"344\"\n  >\n    <v-img\n      height=\"200px\"\n      src=\"https://cdn.vuetifyjs.com/images/cards/sunshine.jpg\"\n      cover\n    ></v-img>\n\n    <v-card-title>\n      Top western road trips\n    </v-card-title>\n\n    <v-card-subtitle>\n      1,000 miles of wonder\n    </v-card-subtitle>\n\n    <v-card-actions>\n      <v-btn\n        color=\"orange-lighten-2\"\n        text=\"Explore\"\n      ></v-btn>\n\n      <v-spacer></v-spacer>\n\n      <v-btn\n        :icon=\"show ? 'mdi-chevron-up' : 'mdi-chevron-down'\"\n        @click=\"show = !show\"\n      ></v-btn>\n    </v-card-actions>\n\n    <v-expand-transition>\n      <div v-show=\"show\">\n        <v-divider></v-divider>\n\n        <v-card-text>\n          I'm a thing. But, like most politicians, he promised more than he could deliver. You won't have time for sleeping, soldier, not with all the bed making you'll be doing. Then we'll go with that data file! Hey, you add a one and two zeros to that or we walk! You're going to do his laundry? I've got to find a way to escape.\n        </v-card-text>\n      </div>\n    </v-expand-transition>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const show = ref(false)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      show: false,\n    }),\n  }\n</script>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=1514-96232&t=tWnPBMI0RfGlNRgq-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-card/misc-earnings-goal.vue",
    "content": "<template>\n  <v-card class=\"mx-auto\" max-width=\"500\" border flat>\n    <v-list-item class=\"px-6\" height=\"88\">\n      <template v-slot:prepend>\n        <v-avatar color=\"surface-light\" size=\"32\">🎯</v-avatar>\n      </template>\n\n      <template v-slot:title> Set an earnings goal. </template>\n\n      <template v-slot:append>\n        <v-btn\n          class=\"text-none\"\n          color=\"primary\"\n          text=\"Create goal\"\n          variant=\"text\"\n          slim\n        ></v-btn>\n      </template>\n    </v-list-item>\n\n    <v-divider></v-divider>\n\n    <v-card-text class=\"text-medium-emphasis pa-6\">\n      <div class=\"text-title-large mb-6\">Earn my first $100</div>\n\n      <div class=\"text-headline-large font-weight-black mb-4\">0%</div>\n\n      <v-progress-linear\n        bg-color=\"surface-variant\"\n        class=\"mb-6\"\n        color=\"primary\"\n        height=\"10\"\n        model-value=\"2\"\n        rounded=\"pill\"\n      ></v-progress-linear>\n\n      <div>$0 of $100 earned — 7 days left</div>\n    </v-card-text>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-card/misc-grids.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"500\"\n  >\n    <v-container fluid>\n      <v-row density=\"comfortable\">\n        <v-col\n          v-for=\"card in cards\"\n          :key=\"card.title\"\n          :cols=\"card.flex\"\n        >\n          <v-card>\n            <v-img\n              :src=\"card.src\"\n              class=\"align-end\"\n              gradient=\"to bottom, rgba(0,0,0,.1), rgba(0,0,0,.5)\"\n              height=\"200px\"\n              cover\n            >\n              <v-card-title class=\"text-white\" v-text=\"card.title\"></v-card-title>\n            </v-img>\n\n            <v-card-actions>\n              <v-spacer></v-spacer>\n\n              <v-btn\n                color=\"medium-emphasis\"\n                icon=\"mdi-heart\"\n                size=\"small\"\n              ></v-btn>\n\n              <v-btn\n                color=\"medium-emphasis\"\n                icon=\"mdi-bookmark\"\n                size=\"small\"\n              ></v-btn>\n\n              <v-btn\n                color=\"medium-emphasis\"\n                icon=\"mdi-share-variant\"\n                size=\"small\"\n              ></v-btn>\n            </v-card-actions>\n          </v-card>\n        </v-col>\n      </v-row>\n    </v-container>\n  </v-card>\n</template>\n\n<script setup>\n  const cards = [\n    { title: 'Pre-fab homes', src: 'https://cdn.vuetifyjs.com/images/cards/house.jpg', flex: 12 },\n    { title: 'Favorite road trips', src: 'https://cdn.vuetifyjs.com/images/cards/road.jpg', flex: 6 },\n    { title: 'Best airlines', src: 'https://cdn.vuetifyjs.com/images/cards/plane.jpg', flex: 6 },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      cards: [\n        { title: 'Pre-fab homes', src: 'https://cdn.vuetifyjs.com/images/cards/house.jpg', flex: 12 },\n        { title: 'Favorite road trips', src: 'https://cdn.vuetifyjs.com/images/cards/road.jpg', flex: 6 },\n        { title: 'Best airlines', src: 'https://cdn.vuetifyjs.com/images/cards/plane.jpg', flex: 6 },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-card/misc-horizontal-cards.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"400\"\n  >\n    <v-layout>\n      <v-system-bar color=\"pink-darken-2\">\n        <v-spacer></v-spacer>\n\n        <v-icon>mdi-window-minimize</v-icon>\n\n        <v-icon>mdi-window-maximize</v-icon>\n\n        <v-icon>mdi-close</v-icon>\n      </v-system-bar>\n\n      <v-app-bar color=\"pink\">\n        <v-app-bar-nav-icon></v-app-bar-nav-icon>\n\n        <v-toolbar-title>My Music</v-toolbar-title>\n\n        <v-btn icon=\"mdi-magnify\"></v-btn>\n      </v-app-bar>\n\n      <v-main>\n        <v-container>\n          <v-row density=\"comfortable\">\n            <v-col cols=\"12\">\n              <v-card color=\"#385F73\">\n                <v-card-title class=\"text-headline-small\">\n                  Unlimited music now\n                </v-card-title>\n\n                <v-card-subtitle>\n                  Listen to your favorite artists and albums whenever and wherever, online and offline.\n                </v-card-subtitle>\n\n                <v-card-actions>\n                  <v-btn text=\"Listen Now\" variant=\"text\"></v-btn>\n                </v-card-actions>\n              </v-card>\n            </v-col>\n\n            <v-col cols=\"12\">\n              <v-card color=\"#1F7087\">\n                <div class=\"d-flex flex-no-wrap justify-space-between\">\n                  <div>\n                    <v-card-title class=\"text-headline-small\">\n                      Supermodel\n                    </v-card-title>\n\n                    <v-card-subtitle>Foster the People</v-card-subtitle>\n\n                    <v-card-actions>\n                      <v-btn\n                        class=\"ms-2\"\n                        size=\"small\"\n                        text=\"START RADIO\"\n                        variant=\"outlined\"\n                      ></v-btn>\n                    </v-card-actions>\n                  </div>\n\n                  <v-avatar\n                    class=\"ma-3\"\n                    rounded=\"0\"\n                    size=\"125\"\n                  >\n                    <v-img src=\"https://cdn.vuetifyjs.com/images/cards/foster.jpg\"></v-img>\n                  </v-avatar>\n                </div>\n              </v-card>\n            </v-col>\n\n            <v-col cols=\"12\">\n              <v-card color=\"#952175\">\n                <div class=\"d-flex flex-no-wrap justify-space-between\">\n                  <div>\n                    <v-card-title class=\"text-headline-small\">\n                      Halcyon Days\n                    </v-card-title>\n\n                    <v-card-subtitle>Ellie Goulding</v-card-subtitle>\n\n                    <v-card-actions>\n                      <v-btn\n                        class=\"ms-2\"\n                        icon=\"mdi-play\"\n                        variant=\"text\"\n                      ></v-btn>\n                    </v-card-actions>\n                  </div>\n\n                  <v-avatar\n                    class=\"ma-3\"\n                    rounded=\"0\"\n                    size=\"125\"\n                  >\n                    <v-img src=\"https://cdn.vuetifyjs.com/images/cards/halcyon.png\"></v-img>\n                  </v-avatar>\n                </div>\n              </v-card>\n            </v-col>\n          </v-row>\n        </v-container>\n      </v-main>\n    </v-layout>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-card/misc-information-card.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"344\"\n  >\n    <v-card-text>\n      <div>Word of the Day</div>\n\n      <div class=\"text-headline-large font-weight-black mb-4\">be•nev•o•lent</div>\n\n      <div class=\"mb-4\">adjective</div>\n\n      <div class=\"text-medium-emphasis\">\n        well meaning and kindly.<br>\n        \"a benevolent smile\"\n      </div>\n    </v-card-text>\n\n    <v-card-actions>\n      <v-btn\n        color=\"deep-purple-accent-4\"\n        text=\"Learn More\"\n        variant=\"text\"\n      ></v-btn>\n    </v-card-actions>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-card/misc-intermediate.vue",
    "content": "<template>\n  <v-card class=\"d-inline-block mx-auto\">\n    <v-container>\n      <v-row class=\"justify-space-between\">\n        <v-col cols=\"auto\">\n          <v-img\n            height=\"200\"\n            src=\"https://cdn.vuetifyjs.com/images/cards/store.jpg\"\n            width=\"200\"\n          ></v-img>\n        </v-col>\n\n        <v-col\n          class=\"text-center\"\n          cols=\"auto\"\n        >\n          <v-row class=\"flex-column fill-height justify-center\" gap=\"0\">\n            <v-col>\n              <v-btn icon>\n                <v-icon>mdi-heart</v-icon>\n              </v-btn>\n            </v-col>\n\n            <v-col>\n              <v-btn icon>\n                <v-icon>mdi-bookmark</v-icon>\n              </v-btn>\n            </v-col>\n\n            <v-col>\n              <v-btn icon>\n                <v-icon>mdi-share-variant</v-icon>\n              </v-btn>\n            </v-col>\n          </v-row>\n        </v-col>\n      </v-row>\n    </v-container>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-card/misc-media-with-text.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"400\"\n  >\n    <v-img\n      class=\"align-end text-white\"\n      height=\"200\"\n      src=\"https://cdn.vuetifyjs.com/images/cards/docks.jpg\"\n      cover\n    >\n      <v-card-title>Top 10 Australian beaches</v-card-title>\n    </v-img>\n\n    <v-card-subtitle class=\"pt-4\">\n      Number 10\n    </v-card-subtitle>\n\n    <v-card-text>\n      <div>Whitehaven Beach</div>\n\n      <div>Whitsunday Island, Whitsunday Islands</div>\n    </v-card-text>\n\n    <v-card-actions>\n      <v-btn color=\"orange\" text=\"Share\"></v-btn>\n\n      <v-btn color=\"orange\" text=\"Explore\"></v-btn>\n    </v-card-actions>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-card/misc-shopify-funding.vue",
    "content": "<template>\n  <v-container>\n    <v-card>\n      <v-card-title>\n        <div class=\"text-label-medium text-uppercase my-1\">Progress</div>\n\n        <div class=\"text-green-darken-3 text-display-medium font-weight-bold\">90%</div>\n\n        <div class=\"text-title-large text-medium-emphasis font-weight-regular\">\n          $2,938.00 remaining\n        </div>\n      </v-card-title>\n      <v-card-text class=\"pt-2 mt-8\">\n        <div\n          :style=\"`right: calc(${review} - 32px)`\"\n          class=\"position-absolute mt-n8 text-body-small text-green-darken-3\"\n        >\n          Eligibility review\n        </div>\n        <v-progress-linear\n          color=\"green-darken-3\"\n          height=\"22\"\n          model-value=\"90\"\n          rounded=\"lg\"\n        >\n          <v-badge\n            :style=\"`right: ${review}`\"\n            class=\"position-absolute\"\n            color=\"white\"\n            dot\n            inline\n          ></v-badge>\n        </v-progress-linear>\n\n        <div class=\"d-flex justify-space-between py-3\">\n          <span class=\"text-green-darken-3 font-weight-medium\">\n            $26,442.00 remitted\n          </span>\n\n          <span class=\"text-medium-emphasis\"> $29,380.00 total </span>\n        </div>\n      </v-card-text>\n\n      <v-divider></v-divider>\n\n      <v-list-item\n        append-icon=\"mdi-chevron-right\"\n        lines=\"two\"\n        subtitle=\"Details and agreement\"\n        link\n      ></v-list-item>\n    </v-card>\n  </v-container>\n</template>\n\n<script setup>\n  const review = '30%'\n</script>\n\n<script>\n  export default {\n    data: () => ({ review: '30%' }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-card/misc-twitter-card.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto text-white\"\n    color=\"#26c6da\"\n    max-width=\"400\"\n    prepend-icon=\"mdi-twitter\"\n    title=\"Twitter\"\n  >\n    <template v-slot:prepend>\n      <v-icon size=\"x-large\"></v-icon>\n    </template>\n\n    <v-card-text class=\"text-headline-small py-2\">\n      \"Turns out semicolon-less style is easier and safer in TS because most gotcha edge cases are type invalid as well.\"\n    </v-card-text>\n\n    <v-card-actions>\n      <v-list-item class=\"w-100\">\n        <template v-slot:prepend>\n          <v-avatar\n            color=\"grey-darken-3\"\n            image=\"https://avataaars.io/?avatarStyle=Transparent&topType=ShortHairShortCurly&accessoriesType=Prescription02&hairColor=Black&facialHairType=Blank&clotheType=Hoodie&clotheColor=White&eyeType=Default&eyebrowType=DefaultNatural&mouthType=Default&skinColor=Light\"\n          ></v-avatar>\n        </template>\n\n        <v-list-item-title>Evan You</v-list-item-title>\n\n        <v-list-item-subtitle>Vue Creator</v-list-item-subtitle>\n\n        <template v-slot:append>\n          <div class=\"justify-self-end\">\n            <v-icon class=\"me-1\" icon=\"mdi-heart\"></v-icon>\n            <span class=\"subheading me-2\">256</span>\n            <span class=\"me-1\">·</span>\n            <v-icon class=\"me-1\" icon=\"mdi-share-variant\"></v-icon>\n            <span class=\"subheading\">45</span>\n          </div>\n        </template>\n      </v-list-item>\n    </v-card-actions>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-card/misc-weather-card.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"368\"\n  >\n    <v-card-item title=\"Florida\">\n      <template v-slot:subtitle>\n        <v-icon\n          class=\"me-1 pb-1\"\n          color=\"error\"\n          icon=\"mdi-alert\"\n          size=\"18\"\n        ></v-icon>\n\n        Extreme Weather Alert\n      </template>\n    </v-card-item>\n\n    <v-card-text class=\"py-0\">\n      <v-row class=\"align-center\" density=\"compact\">\n        <v-col\n          class=\"text-display-large font-weight-light\"\n          cols=\"6\"\n        >\n          64&deg;F\n        </v-col>\n\n        <v-col class=\"text-right\" cols=\"6\">\n          <v-icon\n            color=\"error\"\n            icon=\"mdi-weather-hurricane\"\n            size=\"88\"\n          ></v-icon>\n        </v-col>\n      </v-row>\n    </v-card-text>\n\n    <div class=\"d-flex py-3 justify-space-between\">\n      <v-list-item\n        density=\"compact\"\n        prepend-icon=\"mdi-weather-windy\"\n      >\n        <v-list-item-subtitle>123 km/h</v-list-item-subtitle>\n      </v-list-item>\n\n      <v-list-item\n        density=\"compact\"\n        prepend-icon=\"mdi-weather-pouring\"\n      >\n        <v-list-item-subtitle>48%</v-list-item-subtitle>\n      </v-list-item>\n    </div>\n\n    <v-expand-transition>\n      <div v-if=\"expand\">\n        <div class=\"py-2\">\n          <v-slider\n            v-model=\"time\"\n            :max=\"6\"\n            :step=\"1\"\n            :ticks=\"labels\"\n            class=\"mx-4\"\n            color=\"primary\"\n            density=\"compact\"\n            show-ticks=\"always\"\n            thumb-size=\"10\"\n            hide-details\n          ></v-slider>\n        </div>\n\n        <v-list class=\"bg-transparent\">\n          <v-list-item\n            v-for=\"item in forecast\"\n            :key=\"item.day\"\n            :append-icon=\"item.icon\"\n            :subtitle=\"item.temp\"\n            :title=\"item.day\"\n          >\n          </v-list-item>\n        </v-list>\n      </div>\n    </v-expand-transition>\n\n    <v-divider></v-divider>\n\n    <v-card-actions>\n      <v-btn\n        :text=\"!expand ? 'Full Report' : 'Hide Report'\"\n        @click=\"expand = !expand\"\n      ></v-btn>\n    </v-card-actions>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const labels = { 0: 'SU', 1: 'MO', 2: 'TU', 3: 'WED', 4: 'TH', 5: 'FR', 6: 'SA' }\n  const forecast = [\n    { day: 'Tuesday', icon: 'mdi-white-balance-sunny', temp: '24\\u00B0/12\\u00B0' },\n    { day: 'Wednesday', icon: 'mdi-white-balance-sunny', temp: '22\\u00B0/14\\u00B0' },\n    { day: 'Thursday', icon: 'mdi-cloud', temp: '25\\u00B0/15\\u00B0' },\n  ]\n\n  const expand = ref(false)\n  const time = ref(0)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      labels: { 0: 'SU', 1: 'MO', 2: 'TU', 3: 'WED', 4: 'TH', 5: 'FR', 6: 'SA' },\n      expand: false,\n      time: 0,\n      forecast: [\n        { day: 'Tuesday', icon: 'mdi-white-balance-sunny', temp: '24\\xB0/12\\xB0' },\n        { day: 'Wednesday', icon: 'mdi-white-balance-sunny', temp: '22\\xB0/14\\xB0' },\n        { day: 'Thursday', icon: 'mdi-cloud', temp: '25\\xB0/15\\xB0' },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-card/prop-color.vue",
    "content": "<template>\n  <v-row class=\"justify-center\">\n    <v-col cols=\"auto\">\n      <v-radio-group\n        v-model=\"color\"\n        hide-details\n        inline\n      >\n        <v-radio\n          color=\"indigo\"\n          label=\"indigo\"\n          value=\"indigo\"\n        ></v-radio>\n\n        <v-radio\n          color=\"indigo-darken-3\"\n          label=\"indigo-darken-3\"\n          value=\"indigo-darken-3\"\n        ></v-radio>\n\n        <v-radio\n          color=\"primary\"\n          label=\"primary\"\n          value=\"primary\"\n        ></v-radio>\n\n        <v-radio\n          color=\"secondary\"\n          label=\"secondary\"\n          value=\"secondary\"\n        ></v-radio>\n      </v-radio-group>\n    </v-col>\n\n    <v-col\n      v-for=\"(variant, i) in variants\"\n      :key=\"i\"\n      cols=\"12\"\n      md=\"6\"\n    >\n      <v-card\n        :color=\"color\"\n        :variant=\"variant\"\n        class=\"mx-auto\"\n      >\n        <v-card-item>\n          <div>\n            <div class=\"text-label-medium text-uppercase mt-2 mb-3\">\n              {{ variant }}\n            </div>\n            <div class=\"text-title-large mb-1\">\n              Headline\n            </div>\n            <div class=\"text-body-small\">Greyhound divisely hello coldly fonwderfully</div>\n          </div>\n        </v-card-item>\n\n        <v-card-actions>\n          <v-btn>\n            Button\n          </v-btn>\n        </v-card-actions>\n      </v-card>\n    </v-col>\n  </v-row>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const variants = ['elevated', 'flat', 'tonal', 'outlined']\n  const color = ref('indigo')\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-card/prop-disabled.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"344\"\n    subtitle=\"The card stays disabled\"\n    title=\"Disabled card\"\n    disabled\n    link\n  ></v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-card/prop-elevated.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"344\"\n    variant=\"elevated\"\n  >\n    <v-card-item>\n      <div>\n        <div class=\"text-label-medium mb-1\">\n          OVERLINE\n        </div>\n\n        <div class=\"text-title-large mb-1\">\n          Headline\n        </div>\n\n        <div class=\"text-body-small\">Greyhound divisely hello coldly fonwderfully</div>\n      </div>\n    </v-card-item>\n\n    <v-card-actions>\n      <v-btn text=\"Button\" variant=\"outlined\">\n\n      </v-btn>\n    </v-card-actions>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-card/prop-elevation.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto my-8\"\n    elevation=\"4\"\n    max-width=\"344\"\n  >\n    <v-card-item>\n      <v-card-title>\n        Card title\n      </v-card-title>\n\n      <v-card-subtitle>\n        Card subtitle secondary text\n      </v-card-subtitle>\n    </v-card-item>\n\n    <v-card-text>\n      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n    </v-card-text>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-card/prop-hover.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"344\"\n    hover\n  >\n    <v-card-item>\n      <v-card-title>\n        Card title\n      </v-card-title>\n\n      <v-card-subtitle>\n        Card subtitle secondary text\n      </v-card-subtitle>\n    </v-card-item>\n\n    <v-card-text>\n      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n    </v-card-text>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-card/prop-href.vue",
    "content": "<template>\n  <v-card\n    append-icon=\"mdi-open-in-new\"\n    class=\"mx-auto\"\n    href=\"https://github.com/vuetifyjs/vuetify/\"\n    max-width=\"344\"\n    prepend-icon=\"mdi-github\"\n    rel=\"noopener\"\n    subtitle=\"Check out the official repository\"\n    target=\"_blank\"\n    title=\"Vuetify on GitHub\"\n  ></v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-card/prop-image.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    color=\"surface-variant\"\n    image=\"https://cdn.vuetifyjs.com/docs/images/cards/dark-beach.jpg\"\n    max-width=\"340\"\n    subtitle=\"Take a walk down the beach\"\n    title=\"Evening sunset\"\n  >\n    <template v-slot:actions>\n      <v-btn\n        append-icon=\"mdi-chevron-right\"\n        color=\"red-lighten-2\"\n        text=\"Book Activity\"\n        variant=\"outlined\"\n        block\n      ></v-btn>\n    </template>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-card/prop-link.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"344\"\n    subtitle=\"Same looks, no anchor\"\n    title=\"Hover and click me\"\n    link\n  ></v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-card/prop-loading.vue",
    "content": "<template>\n  <v-card\n    :disabled=\"loading\"\n    :loading=\"loading\"\n    class=\"mx-auto my-12\"\n    max-width=\"374\"\n  >\n    <template v-slot:loader=\"{ isActive }\">\n      <v-progress-linear\n        :active=\"isActive\"\n        color=\"deep-purple\"\n        height=\"4\"\n        indeterminate\n      ></v-progress-linear>\n    </template>\n\n    <v-img\n      height=\"250\"\n      src=\"https://cdn.vuetifyjs.com/images/cards/cooking.png\"\n      cover\n    ></v-img>\n\n    <v-card-item>\n      <v-card-title>Cafe Badilico</v-card-title>\n\n      <v-card-subtitle>\n        <span class=\"me-1\">Local Favorite</span>\n\n        <v-icon\n          color=\"error\"\n          icon=\"mdi-fire-circle\"\n          size=\"small\"\n        ></v-icon>\n      </v-card-subtitle>\n    </v-card-item>\n\n    <v-card-text>\n      <v-row class=\"align-center\">\n        <v-rating\n          :model-value=\"4.5\"\n          color=\"amber\"\n          density=\"compact\"\n          size=\"small\"\n          half-increments\n          readonly\n        ></v-rating>\n\n        <div class=\"text-grey ms-4\">\n          4.5 (413)\n        </div>\n      </v-row>\n\n      <div class=\"my-4 text-body-large\">\n        $ • Italian, Cafe\n      </div>\n\n      <div>Small plates, salads & sandwiches - an intimate setting with 12 indoor seats plus patio seating.</div>\n    </v-card-text>\n\n    <v-divider class=\"mx-4 mb-1\"></v-divider>\n\n    <v-card-title>Tonight's availability</v-card-title>\n\n    <div class=\"px-4 mb-2\">\n      <v-chip-group v-model=\"selection\" selected-class=\"bg-deep-purple-lighten-2\">\n        <v-chip>5:30PM</v-chip>\n\n        <v-chip>7:30PM</v-chip>\n\n        <v-chip>8:00PM</v-chip>\n\n        <v-chip>9:00PM</v-chip>\n      </v-chip-group>\n    </div>\n\n    <v-card-actions>\n      <v-btn\n        color=\"deep-purple-lighten-2\"\n        text=\"Reserve\"\n        block\n        border\n        @click=\"reserve\"\n      ></v-btn>\n    </v-card-actions>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const loading = ref(false)\n  const selection = ref(1)\n  function reserve () {\n    loading.value = true\n    setTimeout(() => (loading.value = false), 2000)\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      loading: false,\n      selection: 1,\n    }),\n\n    methods: {\n      reserve () {\n        this.loading = true\n\n        setTimeout(() => (this.loading = false), 2000)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-card/prop-outlined.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"344\"\n    variant=\"outlined\"\n  >\n    <v-card-item>\n      <div>\n        <div class=\"text-label-medium mb-1\">\n          OVERLINE\n        </div>\n\n        <div class=\"text-title-large mb-1\">\n          Headline\n        </div>\n\n        <div class=\"text-body-small\">Greyhound divisely hello coldly fonwderfully</div>\n      </div>\n    </v-card-item>\n\n    <v-card-actions>\n      <v-btn text=\"Button\" variant=\"outlined\"></v-btn>\n    </v-card-actions>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-card/prop-variant.vue",
    "content": "<template>\n  <v-row density=\"comfortable\">\n    <v-col\n      v-for=\"(variant, i) in variants\"\n      :key=\"i\"\n      cols=\"12\"\n      md=\"4\"\n    >\n      <v-card\n        :variant=\"variant\"\n        class=\"mx-auto\"\n        color=\"surface-variant\"\n        max-width=\"344\"\n        subtitle=\"Greyhound divisely hello coldly fonwderfully\"\n        title=\"Headline\"\n      >\n        <template v-slot:actions>\n          <v-btn text=\"Button\"></v-btn>\n        </template>\n      </v-card>\n\n      <div class=\"text-center text-body-small\">{{ variant }}</div>\n    </v-col>\n  </v-row>\n</template>\n\n<script setup>\n  const variants = ['elevated', 'flat', 'tonal', 'outlined', 'text', 'plain']\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      variants: ['elevated', 'flat', 'tonal', 'outlined', 'text', 'plain'],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-card/slot-prepend-append.vue",
    "content": "<template>\n  <v-row class=\"align-center justify-center\" density=\"comfortable\">\n    <v-col cols=\"12\" md=\"6\">\n      <v-card\n        append-icon=\"mdi-check\"\n        class=\"mx-auto\"\n        prepend-icon=\"mdi-account\"\n        subtitle=\"prepend-icon and append-icon\"\n        title=\"Icons\"\n      >\n        <v-card-text>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod.</v-card-text>\n      </v-card>\n    </v-col>\n\n    <v-col cols=\"12\" md=\"6\">\n      <v-card\n        class=\"mx-auto\"\n        subtitle=\"prepend and append\"\n        title=\"Icons\"\n      >\n        <template v-slot:prepend>\n          <v-icon color=\"primary\" icon=\"mdi-account\"></v-icon>\n        </template>\n        <template v-slot:append>\n          <v-icon color=\"success\" icon=\"mdi-check\"></v-icon>\n        </template>\n        <v-card-text>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod.</v-card-text>\n      </v-card>\n    </v-col>\n\n    <v-col cols=\"12\" md=\"6\">\n      <v-card\n        append-avatar=\"https://cdn.vuetifyjs.com/images/john.jpg\"\n        class=\"mx-auto\"\n        prepend-avatar=\"https://cdn.vuetifyjs.com/images/logos/v-alt.svg\"\n        subtitle=\"prepend-avatar and append-avatar\"\n        title=\"Avatars\"\n      >\n        <v-card-text>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod.</v-card-text>\n      </v-card>\n    </v-col>\n\n    <v-col cols=\"12\" md=\"6\">\n      <v-card\n        class=\"mx-auto\"\n        subtitle=\"prepend and append\"\n        title=\"Avatars\"\n      >\n        <template v-slot:prepend>\n          <v-avatar color=\"blue-darken-2\">\n            <v-icon icon=\"mdi-alarm\"></v-icon>\n          </v-avatar>\n        </template>\n        <template v-slot:append>\n          <v-avatar size=\"24\">\n            <v-img\n              alt=\"John\"\n              src=\"https://cdn.vuetifyjs.com/images/john.png\"\n            ></v-img>\n          </v-avatar>\n        </template>\n        <v-card-text>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod.</v-card-text>\n      </v-card>\n    </v-col>\n  </v-row>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-card/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div>\n\n      <v-card v-bind=\"props\">\n        <template v-slot:text>\n          Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!\n        </template>\n\n        <v-card-actions v-if=\"actions\">\n          <v-btn>Click me</v-btn>\n        </v-card-actions>\n      </v-card>\n    </div>\n\n    <template v-slot:configuration>\n      <v-checkbox v-model=\"title\" label=\"Show title\"></v-checkbox>\n\n      <v-checkbox v-model=\"subtitle\" label=\"Show subtitle\"></v-checkbox>\n\n      <v-checkbox v-model=\"actions\" label=\"Show actions\"></v-checkbox>\n\n      <v-checkbox v-model=\"loading\" label=\"Loading\"></v-checkbox>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-card'\n  const model = ref('default')\n  const actions = ref(false)\n  const loading = ref(false)\n  const subtitle = ref(false)\n  const title = ref(false)\n  const options = ['outlined', 'tonal']\n  const props = computed(() => {\n    return {\n      loading: loading.value || undefined,\n      title: title.value ? 'Card title' : undefined,\n      subtitle: subtitle.value ? 'Subtitle' : undefined,\n      text: '...',\n      variant: ['outlined', 'tonal'].includes(model.value) ? model.value : undefined,\n    }\n  })\n\n  const slots = computed(() => {\n    let str = ''\n\n    if (actions.value) {\n      str += `\n  <v-card-actions>\n    <v-btn>Click me</v-btn>\n  </v-card-actions>\n`\n    }\n\n    return str\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-carousel/misc-vertical.vue",
    "content": "<template>\n  <v-defaults-provider :defaults=\"{ VBtn: { variant: 'outlined', color: '#eee' } }\">\n    <v-sheet class=\"overflow-hidden\" max-width=\"700\" rounded=\"xl\">\n      <v-carousel\n        v-model=\"currentIndex\"\n        direction=\"vertical\"\n        height=\"400\"\n        progress=\"red\"\n        vertical-arrows=\"left\"\n        vertical-delimiters=\"right\"\n        hide-delimiter-background\n      >\n        <v-carousel-item\n          v-for=\"(item, i) in items\"\n          :key=\"i\"\n          :src=\"item.src\"\n          cover\n        ></v-carousel-item>\n\n        <v-overlay\n          :scrim=\"false\"\n          content-class=\"w-100 h-100 d-flex flex-column align-center justify-space-between pointer-pass-through py-3\"\n          contained\n          model-value\n          no-click-animation\n          persistent\n        >\n          <v-scroll-x-transition mode=\"out-in\" appear>\n            <v-sheet\n              :key=\"currentIndex\"\n              rounded=\"xl\"\n            >\n              <v-list-item\n                :prepend-avatar=\"`https://randomuser.me/api/portraits/${currentItem.avatarId}.jpg`\"\n                :subtitle=\"currentItem.subtitle\"\n                :title=\"currentItem.authorName\"\n                class=\"pa-1 pr-6\"\n              ></v-list-item>\n            </v-sheet>\n          </v-scroll-x-transition>\n          <v-chip\n            :text=\"`${ currentIndex + 1 } / ${items.length }`\"\n            color=\"#eee\"\n            size=\"small\"\n            variant=\"flat\"\n          ></v-chip>\n        </v-overlay>\n      </v-carousel>\n    </v-sheet>\n  </v-defaults-provider>\n</template>\n\n<script setup>\n  import { shallowRef, toRef } from 'vue'\n\n  const currentIndex = shallowRef(0)\n  const currentItem = toRef(() => items[currentIndex.value])\n  const items = [\n    {\n      authorName: 'Bettany Nichols',\n      avatarId: 'women/31',\n      subtitle: '31k followers',\n      src: 'https://cdn.vuetifyjs.com/images/carousel/squirrel.jpg',\n    },\n    {\n      authorName: 'Greg Kovalsky',\n      avatarId: 'men/61',\n      subtitle: '412 followers',\n      src: 'https://cdn.vuetifyjs.com/images/carousel/sky.jpg',\n    },\n    {\n      authorName: 'Emma Kathleen',\n      avatarId: 'women/34',\n      subtitle: '521 followers',\n      src: 'https://cdn.vuetifyjs.com/images/carousel/bird.jpg',\n    },\n    {\n      authorName: 'Anthony McKenzie',\n      avatarId: 'men/78',\n      subtitle: '6k followers',\n      src: 'https://cdn.vuetifyjs.com/images/carousel/planet.jpg',\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        currentIndex: 0,\n        items: [\n          {\n            authorName: 'Bettany Nichols',\n            avatarId: 'women/31',\n            subtitle: '31k followers',\n            src: 'https://cdn.vuetifyjs.com/images/carousel/squirrel.jpg',\n          },\n          {\n            authorName: 'Greg Kovalsky',\n            avatarId: 'men/61',\n            subtitle: '412 followers',\n            src: 'https://cdn.vuetifyjs.com/images/carousel/sky.jpg',\n          },\n          {\n            authorName: 'Emma Kathleen',\n            avatarId: 'women/34',\n            subtitle: '521 followers',\n            src: 'https://cdn.vuetifyjs.com/images/carousel/bird.jpg',\n          },\n          {\n            authorName: 'Anthony McKenzie',\n            avatarId: 'men/78',\n            subtitle: '6k followers',\n            src: 'https://cdn.vuetifyjs.com/images/carousel/planet.jpg',\n          },\n        ],\n      }\n    },\n    computed: {\n      currentItem () {\n        return this.items[this.currentIndex]\n      },\n    },\n  }\n</script>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2224-45589&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-carousel/prop-custom-icons.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    elevation=\"5\"\n    max-width=\"444\"\n  >\n    <v-carousel\n      :continuous=\"false\"\n      :show-arrows=\"false\"\n      delimiter-icon=\"mdi-square\"\n      height=\"300\"\n      hide-delimiter-background\n    >\n      <v-carousel-item\n        v-for=\"(slide, i) in slides\"\n        :key=\"i\"\n      >\n        <v-sheet\n          :color=\"colors[i]\"\n          height=\"100%\"\n          tile\n        >\n          <div class=\"d-flex fill-height justify-center align-center\">\n            <div class=\"text-display-large\">\n              {{ slide }} Slide\n            </div>\n          </div>\n        </v-sheet>\n      </v-carousel-item>\n    </v-carousel>\n  </v-card>\n</template>\n\n<script setup>\n  const colors = [\n    'green',\n    'secondary',\n    'yellow darken-4',\n    'red lighten-2',\n    'orange darken-1',\n  ]\n  const slides = [\n    'First',\n    'Second',\n    'Third',\n    'Fourth',\n    'Fifth',\n  ]\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        colors: [\n          'green',\n          'secondary',\n          'yellow darken-4',\n          'red lighten-2',\n          'orange darken-1',\n        ],\n        slides: [\n          'First',\n          'Second',\n          'Third',\n          'Fourth',\n          'Fifth',\n        ],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-carousel/prop-custom-transition.vue",
    "content": "<template>\n  <v-container max-width=\"600\">\n    <div class=\"mb-1 mt-6\">\n      <v-code class=\"bg-purple-darken-2\">default, slower</v-code>\n    </div>\n    <div class=\"my-1 reduced-motion-info\">\n      <v-code class=\"bg-red\">duration change suppressed - prefers-reduced-motion: reduce</v-code>\n    </div>\n    <v-carousel height=\"200\" transition-duration=\"600\">\n      <v-carousel-item v-for=\"(src, i) in items\" :key=\"i\" :src=\"src\" cover></v-carousel-item>\n    </v-carousel>\n\n    <div class=\"mb-1 mt-6\">\n      <v-code class=\"bg-purple-darken-2\">crossfade</v-code>\n    </div>\n    <v-carousel height=\"200\" transition-duration=\"700\" crossfade>\n      <v-carousel-item v-for=\"(src, i) in items\" :key=\"i\" :src=\"src\" cover></v-carousel-item>\n    </v-carousel>\n\n    <div class=\"mb-1 mt-6\">\n      <v-code class=\"bg-purple-darken-2\">cross-scale (custom)</v-code>\n    </div>\n    <div class=\"my-1 reduced-motion-info\">\n      <v-code class=\"bg-red\">scale suppressed - prefers-reduced-motion: reduce</v-code>\n    </div>\n    <v-carousel height=\"200\">\n      <v-carousel-item\n        v-for=\"(src, i) in items\"\n        :key=\"i\"\n        :src=\"src\"\n        reverse-transition=\"cross-scale\"\n        transition=\"cross-scale\"\n        cover\n      ></v-carousel-item>\n    </v-carousel>\n  </v-container>\n</template>\n\n<script setup>\n  const items = [\n    'https://cdn.vuetifyjs.com/images/carousel/squirrel.jpg',\n    'https://cdn.vuetifyjs.com/images/carousel/sky.jpg',\n    'https://cdn.vuetifyjs.com/images/carousel/bird.jpg',\n    'https://cdn.vuetifyjs.com/images/carousel/planet.jpg',\n  ]\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        items: [\n          'https://cdn.vuetifyjs.com/images/carousel/squirrel.jpg',\n          'https://cdn.vuetifyjs.com/images/carousel/sky.jpg',\n          'https://cdn.vuetifyjs.com/images/carousel/bird.jpg',\n          'https://cdn.vuetifyjs.com/images/carousel/planet.jpg',\n        ],\n      }\n    },\n  }\n</script>\n\n<style>\n  .cross-scale-enter-active,\n  .cross-scale-leave-active {\n    transition: .5s cubic-bezier(0.25, 0.8, 0.5, 1);\n    transition-property: opacity, transform;\n  }\n\n  .cross-scale-leave-from,\n  .cross-scale-leave-to {\n    position: absolute !important;\n    top: 0;\n    width: 100%;\n  }\n\n  .cross-scale-enter-from,\n  .cross-scale-leave-to {\n    opacity: 0;\n    transform: scale(0.9);\n  }\n\n  @media (prefers-reduced-motion: reduce) {\n    .cross-scale-enter-from,\n    .cross-scale-leave-to {\n      transform: none;\n    }\n  }\n</style>\n\n<style scoped>\n  .reduced-motion-info {\n    display: none;\n  }\n  @media (prefers-reduced-motion: reduce) {\n    .reduced-motion-info {\n      display: block;\n    }\n  }\n</style>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2220-34681&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-carousel/prop-cycle.vue",
    "content": "<template>\n  <v-carousel\n    height=\"400\"\n    show-arrows=\"hover\"\n    cycle\n    hide-delimiter-background\n  >\n    <v-carousel-item\n      v-for=\"(slide, i) in slides\"\n      :key=\"i\"\n    >\n      <v-sheet\n        :color=\"colors[i]\"\n        height=\"100%\"\n      >\n        <div class=\"d-flex fill-height justify-center align-center\">\n          <div class=\"text-display-large\">\n            {{ slide }} Slide\n          </div>\n        </div>\n      </v-sheet>\n    </v-carousel-item>\n  </v-carousel>\n</template>\n\n<script setup>\n  const colors = [\n    'indigo',\n    'warning',\n    'pink darken-2',\n    'red lighten-1',\n    'deep-purple accent-4',\n  ]\n  const slides = [\n    'First',\n    'Second',\n    'Third',\n    'Fourth',\n    'Fifth',\n  ]\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        colors: [\n          'indigo',\n          'warning',\n          'pink darken-2',\n          'red lighten-1',\n          'deep-purple accent-4',\n        ],\n        slides: [\n          'First',\n          'Second',\n          'Third',\n          'Fourth',\n          'Fifth',\n        ],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-carousel/prop-hide-controls.vue",
    "content": "<template>\n  <v-carousel :show-arrows=\"false\">\n    <v-carousel-item\n      v-for=\"(item,i) in items\"\n      :key=\"i\"\n      :src=\"item.src\"\n      cover\n    ></v-carousel-item>\n  </v-carousel>\n</template>\n\n<script setup>\n  const items = [\n    {\n      src: 'https://cdn.vuetifyjs.com/images/carousel/squirrel.jpg',\n    },\n    {\n      src: 'https://cdn.vuetifyjs.com/images/carousel/sky.jpg',\n    },\n    {\n      src: 'https://cdn.vuetifyjs.com/images/carousel/bird.jpg',\n    },\n    {\n      src: 'https://cdn.vuetifyjs.com/images/carousel/planet.jpg',\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        items: [\n          {\n            src: 'https://cdn.vuetifyjs.com/images/carousel/squirrel.jpg',\n          },\n          {\n            src: 'https://cdn.vuetifyjs.com/images/carousel/sky.jpg',\n          },\n          {\n            src: 'https://cdn.vuetifyjs.com/images/carousel/bird.jpg',\n          },\n          {\n            src: 'https://cdn.vuetifyjs.com/images/carousel/planet.jpg',\n          },\n        ],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-carousel/prop-hide-delimiters.vue",
    "content": "<template>\n  <v-carousel hide-delimiters>\n    <v-carousel-item\n      v-for=\"(item,i) in items\"\n      :key=\"i\"\n      :src=\"item.src\"\n      cover\n    ></v-carousel-item>\n  </v-carousel>\n</template>\n\n<script setup>\n  const items = [\n    {\n      src: 'https://cdn.vuetifyjs.com/images/carousel/squirrel.jpg',\n    },\n    {\n      src: 'https://cdn.vuetifyjs.com/images/carousel/sky.jpg',\n    },\n    {\n      src: 'https://cdn.vuetifyjs.com/images/carousel/bird.jpg',\n    },\n    {\n      src: 'https://cdn.vuetifyjs.com/images/carousel/planet.jpg',\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        items: [\n          {\n            src: 'https://cdn.vuetifyjs.com/images/carousel/squirrel.jpg',\n          },\n          {\n            src: 'https://cdn.vuetifyjs.com/images/carousel/sky.jpg',\n          },\n          {\n            src: 'https://cdn.vuetifyjs.com/images/carousel/bird.jpg',\n          },\n          {\n            src: 'https://cdn.vuetifyjs.com/images/carousel/planet.jpg',\n          },\n        ],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-carousel/prop-model.vue",
    "content": "<template>\n  <div>\n    <div class=\"d-flex justify-space-around align-center py-4\">\n      <v-btn\n        icon=\"mdi-minus\"\n        variant=\"text\"\n        @click=\"model = Math.max(model - 1, 0)\"\n      ></v-btn>\n      {{ model }}\n      <v-btn\n        icon=\"mdi-plus\"\n        variant=\"text\"\n        @click=\"model = Math.min(model + 1, 4)\"\n      ></v-btn>\n    </div>\n    <v-carousel v-model=\"model\">\n      <v-carousel-item\n        v-for=\"(color, i) in colors\"\n        :key=\"color\"\n        :value=\"i\"\n      >\n        <v-sheet\n          :color=\"color\"\n          height=\"100%\"\n          tile\n        >\n          <div class=\"d-flex fill-height justify-center align-center\">\n            <div class=\"text-display-large\">\n              Slide {{ i + 1 }}\n            </div>\n          </div>\n        </v-sheet>\n      </v-carousel-item>\n    </v-carousel>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const colors = [\n    'primary',\n    'secondary',\n    'yellow darken-2',\n    'red',\n    'orange',\n  ]\n\n  const model = ref(0)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        colors: [\n          'primary',\n          'secondary',\n          'yellow darken-2',\n          'red',\n          'orange',\n        ],\n        model: 0,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-carousel/prop-progress.vue",
    "content": "<template>\n  <v-carousel\n    height=\"400\"\n    progress=\"primary\"\n    hide-delimiters\n  >\n    <v-carousel-item\n      v-for=\"(slide, i) in slides\"\n      :key=\"i\"\n    >\n      <v-sheet\n        height=\"100%\"\n      >\n        <div class=\"d-flex fill-height justify-center align-center\">\n          <div class=\"text-display-large\">\n            {{ slide }} Slide\n          </div>\n        </div>\n      </v-sheet>\n    </v-carousel-item>\n  </v-carousel>\n</template>\n\n<script setup>\n  const slides = [\n    'First',\n    'Second',\n    'Third',\n    'Fourth',\n    'Fifth',\n  ]\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        slides: [\n          'First',\n          'Second',\n          'Third',\n          'Fourth',\n          'Fifth',\n        ],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-carousel/slots-next-prev.vue",
    "content": "<template>\n  <v-carousel\n    height=\"400\"\n    hide-delimiter-background\n    show-arrows\n  >\n    <template v-slot:prev=\"{ props }\">\n      <v-btn\n        color=\"success\"\n        variant=\"elevated\"\n        @click=\"props.onClick\"\n      >Previous slide</v-btn>\n    </template>\n    <template v-slot:next=\"{ props }\">\n      <v-btn\n        color=\"info\"\n        variant=\"elevated\"\n        @click=\"props.onClick\"\n      >Next slide</v-btn>\n    </template>\n    <v-carousel-item\n      v-for=\"(slide, i) in slides\"\n      :key=\"i\"\n    >\n      <v-sheet\n        :color=\"colors[i]\"\n        height=\"100%\"\n      >\n        <div class=\"d-flex fill-height justify-center align-center\">\n          <div class=\"text-display-large\">\n            {{ slide }} Slide\n          </div>\n        </div>\n      </v-sheet>\n    </v-carousel-item>\n  </v-carousel>\n</template>\n\n<script setup>\n  const colors = [\n    'indigo',\n    'warning',\n    'pink darken-2',\n    'red lighten-1',\n    'deep-purple accent-4',\n  ]\n  const slides = [\n    'First',\n    'Second',\n    'Third',\n    'Fourth',\n    'Fifth',\n  ]\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        colors: [\n          'indigo',\n          'warning',\n          'pink darken-2',\n          'red lighten-1',\n          'deep-purple accent-4',\n        ],\n        slides: [\n          'First',\n          'Second',\n          'Third',\n          'Fourth',\n          'Fifth',\n        ],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-carousel/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div>\n      <v-carousel v-bind=\"props\">\n        <v-carousel-item\n          src=\"https://cdn.vuetifyjs.com/images/cards/docks.jpg\"\n          cover\n        ></v-carousel-item>\n\n        <v-carousel-item\n          src=\"https://cdn.vuetifyjs.com/images/cards/hotel.jpg\"\n          cover\n        ></v-carousel-item>\n\n        <v-carousel-item\n          src=\"https://cdn.vuetifyjs.com/images/cards/sunshine.jpg\"\n          cover\n        ></v-carousel-item>\n      </v-carousel>\n    </div>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-carousel'\n  const model = ref('default')\n  const options = ['Hide delimiters', 'Show arrows on hover']\n  const props = computed(() => {\n    return {\n      'hide-delimiters': model.value === 'Hide delimiters' || undefined,\n      'show-arrows': model.value === 'Show arrows on hover' ? 'hover' : undefined,\n    }\n  })\n\n  const slots = computed(() => {\n    return `\n  <v-carousel-item\n    src=\"https://cdn.vuetifyjs.com/images/cards/docks.jpg\"\n    cover\n  ></v-carousel-item>\n\n  <v-carousel-item\n    src=\"https://cdn.vuetifyjs.com/images/cards/hotel.jpg\"\n    cover\n  ></v-carousel-item>\n\n  <v-carousel-item\n    src=\"https://cdn.vuetifyjs.com/images/cards/sunshine.jpg\"\n    cover\n  ></v-carousel-item>\n`\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-checkbox/misc-inline-textfield.vue",
    "content": "<template>\n  <v-card>\n    <v-card-text>\n      <div class=\"d-flex pa-4\">\n        <v-checkbox-btn\n          v-model=\"includeFiles\"\n          class=\"pe-2\"\n        ></v-checkbox-btn>\n        <v-text-field\n          label=\"Include files\"\n          hide-details\n        ></v-text-field>\n      </div>\n      <div class=\"d-flex pa-4\">\n        <v-checkbox-btn\n          v-model=\"enabled\"\n          class=\"pe-2\"\n        ></v-checkbox-btn>\n        <v-text-field\n          :disabled=\"!enabled\"\n          label=\"I only work if you check the box\"\n          hide-details\n        ></v-text-field>\n      </div>\n    </v-card-text>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const includeFiles = ref(true)\n  const enabled = ref(false)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      includeFiles: true,\n      enabled: false,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-checkbox/prop-colors.vue",
    "content": "<template>\n  <div>\n    <v-container fluid>\n      <v-row>\n        <v-col\n          cols=\"12\"\n          md=\"4\"\n          sm=\"4\"\n        >\n          <v-checkbox\n            v-model=\"ex4\"\n            color=\"red\"\n            label=\"red\"\n            value=\"red\"\n            hide-details\n          ></v-checkbox>\n          <v-checkbox\n            v-model=\"ex4\"\n            color=\"red-darken-3\"\n            label=\"red-darken-3\"\n            value=\"red-darken-3\"\n            hide-details\n          ></v-checkbox>\n        </v-col>\n        <v-col\n          cols=\"12\"\n          md=\"4\"\n          sm=\"4\"\n        >\n          <v-checkbox\n            v-model=\"ex4\"\n            color=\"indigo\"\n            label=\"indigo\"\n            value=\"indigo\"\n            hide-details\n          ></v-checkbox>\n          <v-checkbox\n            v-model=\"ex4\"\n            color=\"indigo-darken-3\"\n            label=\"indigo-darken-3\"\n            value=\"indigo-darken-3\"\n            hide-details\n          ></v-checkbox>\n        </v-col>\n        <v-col\n          cols=\"12\"\n          md=\"4\"\n          sm=\"4\"\n        >\n          <v-checkbox\n            v-model=\"ex4\"\n            color=\"orange\"\n            label=\"orange\"\n            value=\"orange\"\n            hide-details\n          ></v-checkbox>\n          <v-checkbox\n            v-model=\"ex4\"\n            color=\"orange-darken-3\"\n            label=\"orange-darken-3\"\n            value=\"orange-darken-3\"\n            hide-details\n          ></v-checkbox>\n        </v-col>\n      </v-row>\n\n      <v-row class=\"mt-12\">\n        <v-col\n          cols=\"12\"\n          md=\"4\"\n          sm=\"4\"\n        >\n          <v-checkbox\n            v-model=\"ex4\"\n            color=\"primary\"\n            label=\"primary\"\n            value=\"primary\"\n            hide-details\n          ></v-checkbox>\n          <v-checkbox\n            v-model=\"ex4\"\n            color=\"secondary\"\n            label=\"secondary\"\n            value=\"secondary\"\n            hide-details\n          ></v-checkbox>\n        </v-col>\n        <v-col\n          cols=\"12\"\n          md=\"4\"\n          sm=\"4\"\n        >\n          <v-checkbox\n            v-model=\"ex4\"\n            color=\"success\"\n            label=\"success\"\n            value=\"success\"\n            hide-details\n          ></v-checkbox>\n          <v-checkbox\n            v-model=\"ex4\"\n            color=\"info\"\n            label=\"info\"\n            value=\"info\"\n            hide-details\n          ></v-checkbox>\n        </v-col>\n        <v-col\n          cols=\"12\"\n          md=\"4\"\n          sm=\"4\"\n        >\n          <v-checkbox\n            v-model=\"ex4\"\n            color=\"warning\"\n            label=\"warning\"\n            value=\"warning\"\n            hide-details\n          ></v-checkbox>\n          <v-checkbox\n            v-model=\"ex4\"\n            color=\"error\"\n            label=\"error\"\n            value=\"error\"\n            hide-details\n          ></v-checkbox>\n        </v-col>\n      </v-row>\n    </v-container>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const ex4 = ref(['red', 'indigo', 'orange', 'primary', 'secondary', 'success', 'info', 'warning', 'error', 'red darken-3', 'indigo darken-3', 'orange darken-3'])\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        ex4: ['red', 'indigo', 'orange', 'primary', 'secondary', 'success', 'info', 'warning', 'error', 'red darken-3', 'indigo darken-3', 'orange darken-3'],\n      }\n    },\n  }\n</script>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2043-81380&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-checkbox/prop-model-as-array.vue",
    "content": "<template>\n  <v-container fluid>\n    <p>{{ selected }}</p>\n    <v-checkbox\n      v-model=\"selected\"\n      label=\"John\"\n      value=\"John\"\n    ></v-checkbox>\n    <v-checkbox\n      v-model=\"selected\"\n      label=\"Jacob\"\n      value=\"Jacob\"\n    ></v-checkbox>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const selected = ref(['John'])\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        selected: ['John'],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-checkbox/prop-model-as-boolean.vue",
    "content": "<template>\n  <v-container fluid>\n    <v-checkbox\n      v-model=\"checkbox1\"\n      :label=\"`Checkbox 1: ${checkbox1.toString()}`\"\n    ></v-checkbox>\n    <v-checkbox\n      v-model=\"checkbox2\"\n      :label=\"`Checkbox 2: ${checkbox2.toString()}`\"\n    ></v-checkbox>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const checkbox1 = ref(true)\n  const checkbox2 = ref(false)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        checkbox1: true,\n        checkbox2: false,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-checkbox/prop-states.vue",
    "content": "<template>\n  <v-container fluid>\n    <v-row>\n      <v-col cols=\"4\">\n        on\n      </v-col>\n      <v-col cols=\"4\">\n        off\n      </v-col>\n      <v-col cols=\"4\">\n        indeterminate\n      </v-col>\n    </v-row>\n    <v-row>\n      <v-col cols=\"4\">\n        <v-checkbox\n          :model-value=\"true\"\n        ></v-checkbox>\n      </v-col>\n      <v-col cols=\"4\">\n        <v-checkbox :model-value=\"false\"></v-checkbox>\n      </v-col>\n      <v-col cols=\"4\">\n        <v-checkbox\n          indeterminate\n        ></v-checkbox>\n      </v-col>\n    </v-row>\n    <v-row>\n      <v-col cols=\"4\">\n        on disabled\n      </v-col>\n      <v-col cols=\"4\">\n        off disabled\n      </v-col>\n    </v-row>\n    <v-row>\n      <v-col cols=\"4\">\n        <v-checkbox\n          :model-value=\"true\"\n          disabled\n        ></v-checkbox>\n      </v-col>\n      <v-col cols=\"4\">\n        <v-checkbox\n          :model-value=\"false\"\n          disabled\n        ></v-checkbox>\n      </v-col>\n      <v-col cols=\"4\">\n        <v-checkbox\n          disabled\n          indeterminate\n        ></v-checkbox>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-checkbox/slot-label.vue",
    "content": "<template>\n  <v-container fluid>\n    <v-checkbox v-model=\"checkbox\">\n      <template v-slot:label>\n        <div>\n          I agree that\n          <v-tooltip location=\"bottom\">\n            <template v-slot:activator=\"{ props }\">\n              <a\n                href=\"https://vuetifyjs.com\"\n                target=\"_blank\"\n                v-bind=\"props\"\n                @click.stop\n              >\n                Vuetify\n              </a>\n            </template>\n            Opens in new window\n          </v-tooltip>\n          is awesome\n        </div>\n      </template>\n    </v-checkbox>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const checkbox = ref(false)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        checkbox: false,\n      }\n    },\n  }\n</script>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2045-82647&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-checkbox/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div>\n      <v-checkbox v-bind=\"props\" hide-details></v-checkbox>\n    </div>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-checkbox'\n  const model = ref('default')\n  const options = []\n  const props = computed(() => {\n    return {\n      label: 'Checkbox',\n    }\n  })\n\n  const slots = computed(() => {\n    return ``\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-chip/event-action-chips.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"450\"\n  >\n    <v-img\n      :aspect-ratio=\"16/9\"\n      src=\"https://cdn.vuetifyjs.com/images/cards/house.jpg\"\n      cover\n    >\n    </v-img>\n    <v-card-title class=\"flex-column align-start\">\n      <div class=\"text-headline-large mb-2\">\n        Welcome Home...\n      </div>\n      <div class=\"text-title-large font-weight-regular text-grey\">\n        Monday, 12:30 PM, Mostly Sunny\n      </div>\n      <div class=\"d-flex align-center\">\n        <v-avatar\n          class=\"me-4\"\n          size=\"24\"\n        >\n          <v-img src=\"https://cdn.vuetifyjs.com/images/weather/part-cloud-48px.png\"></v-img>\n        </v-avatar>\n\n        <span class=\"text-body-medium text-grey\">81° / 62°</span>\n      </div>\n    </v-card-title>\n\n    <v-divider class=\"mx-4\"></v-divider>\n\n    <v-card-text class=\"d-flex justify-space-between\">\n      <v-chip\n        prepend-icon=\"mdi-brightness-5\"\n        @click=\"lights\"\n      >\n        Turn on lights\n      </v-chip>\n      <v-chip\n        prepend-icon=\"mdi-alarm-check\"\n        @click=\"alarm\"\n      >\n        Set alarm\n      </v-chip>\n      <v-chip\n        icon=\"mdi-blinds\"\n        @click=\"blinds\"\n      >\n        Close blinds\n      </v-chip>\n    </v-card-text>\n  </v-card>\n</template>\n\n<script>\n  export default {\n    methods: {\n      alarm () {\n        alert('Turning on alarm...')\n      },\n      blinds () {\n        alert('Toggling blinds...')\n      },\n      lights () {\n        alert('Toggling lights...')\n      },\n    },\n  }\n</script>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=1632-99053&t=tWnPBMI0RfGlNRgq-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-chip/misc-custom-list.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"500\"\n  >\n    <v-toolbar\n      color=\"transparent\"\n      flat\n    >\n      <v-app-bar-nav-icon></v-app-bar-nav-icon>\n\n      <v-toolbar-title>Photo Info</v-toolbar-title>\n\n      <v-btn\n        icon=\"mdi-magnify\"\n        @click=\"searchField.focus()\"\n      >\n      </v-btn>\n    </v-toolbar>\n\n    <v-container>\n      <v-row class=\"align-center justify-start\" gap=\"8\">\n        <v-col\n          v-for=\"(selection, i) in selections\"\n          :key=\"selection.text\"\n          cols=\"auto\"\n        >\n          <v-chip\n            :disabled=\"loading\"\n            closable\n            @click:close=\"selected.splice(i, 1)\"\n          >\n            <v-icon\n              :icon=\"selection.icon\"\n              start\n            ></v-icon>\n\n            {{ selection.text }}\n          </v-chip>\n        </v-col>\n\n        <v-col\n          v-if=\"!allSelected\"\n          cols=\"12\"\n        >\n          <v-text-field\n            ref=\"searchField\"\n            v-model=\"search\"\n            label=\"Search\"\n            hide-details\n            single-line\n          ></v-text-field>\n        </v-col>\n      </v-row>\n    </v-container>\n\n    <v-divider v-if=\"!allSelected\"></v-divider>\n\n    <v-list>\n      <template v-for=\"item in categories\">\n        <v-list-item\n          v-if=\"!selected.includes(item)\"\n          :key=\"item.text\"\n          :disabled=\"loading\"\n          @click=\"selected.push(item)\"\n        >\n          <template v-slot:prepend>\n            <v-icon\n              :disabled=\"loading\"\n              :icon=\"item.icon\"\n            ></v-icon>\n          </template>\n\n          <v-list-item-title v-text=\"item.text\"></v-list-item-title>\n        </v-list-item>\n      </template>\n    </v-list>\n\n    <v-divider></v-divider>\n\n    <v-card-actions>\n      <v-spacer></v-spacer>\n\n      <v-btn\n        :disabled=\"!selected.length\"\n        :loading=\"loading\"\n        color=\"purple\"\n        variant=\"text\"\n        @click=\"next\"\n      >\n        Next\n      </v-btn>\n    </v-card-actions>\n  </v-card>\n</template>\n\n<script setup>\n  import { computed, ref, watch } from 'vue'\n\n  const items = [\n    {\n      text: 'Nature',\n      icon: 'mdi-nature',\n    },\n    {\n      text: 'Nightlife',\n      icon: 'mdi-glass-wine',\n    },\n    {\n      text: 'November',\n      icon: 'mdi-calendar-range',\n    },\n    {\n      text: 'Portland',\n      icon: 'mdi-map-marker',\n    },\n    {\n      text: 'Biking',\n      icon: 'mdi-bike',\n    },\n  ]\n  const searchField = ref()\n\n  const loading = ref(false)\n  const search = ref('')\n  const selected = ref([])\n\n  const allSelected = computed(() => {\n    return selected.value.length === items.length\n  })\n  const categories = computed(() => {\n    const _search = search.value.toLowerCase()\n    if (!_search) return items\n    return items.filter(item => {\n      const text = item.text.toLowerCase()\n      return text.indexOf(_search) > -1\n    })\n  })\n  const selections = computed(() => {\n    const selections = []\n    for (const selection of selected.value) {\n      selections.push(selection)\n    }\n    return selections\n  })\n\n  watch(selected, () => {\n    search.value = ''\n  })\n\n  function next () {\n    loading.value = true\n    setTimeout(() => {\n      search.value = ''\n      selected.value = []\n      loading.value = false\n    }, 2000)\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        {\n          text: 'Nature',\n          icon: 'mdi-nature',\n        },\n        {\n          text: 'Nightlife',\n          icon: 'mdi-glass-wine',\n        },\n        {\n          text: 'November',\n          icon: 'mdi-calendar-range',\n        },\n        {\n          text: 'Portland',\n          icon: 'mdi-map-marker',\n        },\n        {\n          text: 'Biking',\n          icon: 'mdi-bike',\n        },\n      ],\n      loading: false,\n      search: '',\n      selected: [],\n    }),\n\n    computed: {\n      allSelected () {\n        return this.selected.length === this.items.length\n      },\n      categories () {\n        const search = this.search.toLowerCase()\n\n        if (!search) return this.items\n\n        return this.items.filter(item => {\n          const text = item.text.toLowerCase()\n\n          return text.indexOf(search) > -1\n        })\n      },\n      selections () {\n        const selections = []\n\n        for (const selection of this.selected) {\n          selections.push(selection)\n        }\n\n        return selections\n      },\n    },\n\n    watch: {\n      selected () {\n        this.search = ''\n      },\n    },\n\n    methods: {\n      next () {\n        this.loading = true\n\n        setTimeout(() => {\n          this.search = ''\n          this.selected = []\n          this.loading = false\n        }, 2000)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-chip/misc-expandable.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"400\"\n  >\n    <v-row class=\"pa-6 align-center\">\n      <span class=\"me-4\">To</span>\n\n      <v-menu\n        v-model=\"menu\"\n        location=\"top start\"\n        origin=\"top start\"\n        transition=\"scale-transition\"\n      >\n        <template v-slot:activator=\"{ props }\">\n          <v-chip\n            v-bind=\"props\"\n            link\n            pill\n          >\n            <v-avatar start>\n              <v-img src=\"https://cdn.vuetifyjs.com/images/john.png\"></v-img>\n            </v-avatar>\n\n            John Leider\n          </v-chip>\n        </template>\n\n        <v-card width=\"300\">\n          <v-list bg-color=\"black\">\n            <v-list-item>\n              <template v-slot:prepend>\n                <v-avatar image=\"https://cdn.vuetifyjs.com/images/john.png\"></v-avatar>\n              </template>\n\n              <v-list-item-title>John Leider</v-list-item-title>\n\n              <v-list-item-subtitle>john@google.com</v-list-item-subtitle>\n\n              <template v-slot:append>\n                <v-list-item-action>\n                  <v-btn\n                    variant=\"text\"\n                    icon\n                    @click=\"menu = false\"\n                  >\n                    <v-icon>mdi-close-circle</v-icon>\n                  </v-btn>\n                </v-list-item-action>\n              </template>\n            </v-list-item>\n          </v-list>\n\n          <v-list>\n            <v-list-item prepend-icon=\"mdi-briefcase\" link>\n              <v-list-item-subtitle>john@gmail.com</v-list-item-subtitle>\n            </v-list-item>\n          </v-list>\n        </v-card>\n      </v-menu>\n    </v-row>\n\n    <v-divider></v-divider>\n\n    <div class=\"pa-3\">\n      <v-text-field\n        label=\"Subject\"\n        model-value=\"Re: Vacation Request\"\n        variant=\"underlined\"\n        single-line\n      ></v-text-field>\n\n      <v-textarea\n        label=\"Message\"\n        variant=\"underlined\"\n        single-line\n      ></v-textarea>\n    </div>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const menu = ref(false)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      menu: false,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-chip/misc-filtering.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"450\"\n  >\n    <v-toolbar\n      color=\"primary\"\n      height=\"88\"\n      flat\n    >\n      <template v-slot:prepend>\n        <v-btn icon=\"mdi-arrow-left\">\n        </v-btn>\n      </template>\n\n      <v-text-field\n        v-model=\"search\"\n        label=\"Search News\"\n        prepend-inner-icon=\"mdi-magnify\"\n        clearable\n        hide-details\n        single-line\n      ></v-text-field>\n\n      <template v-slot:append>\n        <v-btn icon=\"mdi-dots-vertical\"></v-btn>\n      </template>\n    </v-toolbar>\n\n    <div v-if=\"keywords.length > 0\" class=\"py-3 px-4\">\n      <v-chip\n        v-for=\"(keyword, i) in keywords\"\n        :key=\"i\"\n        class=\"me-2\"\n      >\n        {{ keyword }}\n      </v-chip>\n\n    </div>\n\n    <v-divider></v-divider>\n\n    <v-list lines=\"three\">\n      <v-list-item\n        v-for=\"(item, i) in searching\"\n        :key=\"i\"\n        link\n      >\n        <template v-slot:prepend>\n          <v-avatar\n            class=\"me-4 mt-2\"\n            rounded=\"0\"\n          >\n            <v-img :src=\"item.image\" cover></v-img>\n          </v-avatar>\n        </template>\n\n        <v-list-item-title\n          class=\"text-uppercase font-weight-regular text-body-small\"\n          v-text=\"item.category\"\n        ></v-list-item-title>\n\n        <div v-text=\"item.title\"></div>\n      </v-list-item>\n    </v-list>\n  </v-card>\n</template>\n\n<script setup>\n  import { computed, ref } from 'vue'\n\n  const items = [\n    {\n      image: 'https://cdn.vuetifyjs.com/docs/images/chips/globe.png',\n      title: 'TBI\\u2019s 5 Best: SF Mocktails to Finish Dry January Strong',\n      category: 'Travel',\n      keyword: 'Drinks',\n    },\n    {\n      image: 'https://cdn.vuetifyjs.com/docs/images/chips/cpu.png',\n      title: 'PWAs on iOS 12.2 beta: the good, the bad, and the \\u201Cnot sure yet if good\\u201D',\n      category: 'Technology',\n      keyword: 'Phones',\n    },\n    {\n      image: 'https://cdn.vuetifyjs.com/docs/images/chips/rocket.png',\n      title: 'How to Get Media Mentions for Your Business',\n      category: 'Media',\n      keyword: 'Social',\n    },\n    {\n      image: 'https://cdn.vuetifyjs.com/docs/images/chips/bulb.png',\n      title: 'The Pitfalls Of Outsourcing Self-Awareness To Artificial Intelligence',\n      category: 'Technology',\n      keyword: 'Military',\n    },\n    {\n      image: 'https://cdn.vuetifyjs.com/docs/images/chips/raft.png',\n      title: 'Degrees of Freedom and Sudoko',\n      category: 'Travel',\n      keyword: 'Social',\n    },\n  ]\n\n  const search = ref('')\n\n  const keywords = computed(() => {\n    if (!search.value) return []\n\n    const keywords = []\n\n    for (const search of searching.value) {\n      keywords.push(search.keyword)\n    }\n\n    return keywords\n  })\n  const searching = computed(() => {\n    if (!search.value) return items\n\n    const _search = search.value.toLowerCase()\n\n    return items.filter(item => {\n      const text = item.title.toLowerCase()\n      return text.indexOf(_search) > -1\n    })\n  })\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        {\n          image: 'https://cdn.vuetifyjs.com/docs/images/chips/globe.png',\n          title: 'TBI’s 5 Best: SF Mocktails to Finish Dry January Strong',\n          category: 'Travel',\n          keyword: 'Drinks',\n\n        },\n        {\n          image: 'https://cdn.vuetifyjs.com/docs/images/chips/cpu.png',\n          title: 'PWAs on iOS 12.2 beta: the good, the bad, and the “not sure yet if good”',\n          category: 'Technology',\n          keyword: 'Phones',\n        },\n        {\n          image: 'https://cdn.vuetifyjs.com/docs/images/chips/rocket.png',\n          title: 'How to Get Media Mentions for Your Business',\n          category: 'Media',\n          keyword: 'Social',\n        },\n        {\n          image: 'https://cdn.vuetifyjs.com/docs/images/chips/bulb.png',\n          title: 'The Pitfalls Of Outsourcing Self-Awareness To Artificial Intelligence',\n          category: 'Technology',\n          keyword: 'Military',\n        },\n        {\n          image: 'https://cdn.vuetifyjs.com/docs/images/chips/raft.png',\n          title: 'Degrees of Freedom and Sudoko',\n          category: 'Travel',\n          keyword: 'Social',\n        },\n      ],\n      search: '',\n    }),\n\n    computed: {\n      keywords () {\n        if (!this.search) return []\n\n        const keywords = []\n\n        for (const search of this.searching) {\n          keywords.push(search.keyword)\n        }\n\n        return keywords\n      },\n      searching () {\n        if (!this.search) return this.items\n\n        const search = this.search.toLowerCase()\n\n        return this.items.filter(item => {\n          const text = item.title.toLowerCase()\n\n          return text.indexOf(search) > -1\n        })\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-chip/misc-in-selects.vue",
    "content": "<template>\n  <v-combobox\n    v-model=\"chips\"\n    :items=\"items\"\n    label=\"Your favorite hobbies\"\n    prepend-icon=\"mdi-filter-variant\"\n    variant=\"solo\"\n    chips\n    clearable\n    closable-chips\n    multiple\n  >\n    <template v-slot:chip=\"{ props, item }\">\n      <v-chip v-bind=\"props\">\n        <strong>{{ item }}</strong>&nbsp;\n        <span>(interest)</span>\n      </v-chip>\n    </template>\n  </v-combobox>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const items = ['Streaming', 'Eating']\n\n  const chips = ref(['Programming', 'Playing video games', 'Watching movies', 'Sleeping'])\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        chips: ['Programming', 'Playing video games', 'Watching movies', 'Sleeping'],\n        items: ['Streaming', 'Eating'],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-chip/prop-closable.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-chip\n      v-if=\"chip\"\n      class=\"ma-2\"\n      closable\n      @click:close=\"chip = false\"\n    >\n      Closable\n    </v-chip>\n\n    <v-btn\n      v-if=\"!chip\"\n      color=\"primary\"\n      @click=\"chip = true\"\n    >\n      Reset Chip\n    </v-btn>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const chip = ref(true)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        chip: true,\n      }\n    },\n  }\n</script>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2690-8443&t=tWnPBMI0RfGlNRgq-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-chip/prop-colored.vue",
    "content": "<template>\n  <div class=\"d-flex justify-center ga-2\">\n    <v-chip>\n      Default\n    </v-chip>\n\n    <v-chip color=\"primary\">\n      Primary\n    </v-chip>\n\n    <v-chip color=\"secondary\">\n      Secondary\n    </v-chip>\n\n    <v-chip color=\"red\">\n      Red\n    </v-chip>\n\n    <v-chip color=\"green\">\n      Green\n    </v-chip>\n  </div>\n  <div class=\"d-flex justify-center ga-2 mt-2\">\n    <v-chip variant=\"flat\">\n      Default flat\n    </v-chip>\n\n    <v-chip color=\"primary\" variant=\"flat\">\n      Primary flat\n    </v-chip>\n\n    <v-chip color=\"secondary\" variant=\"flat\">\n      Secondary flat\n    </v-chip>\n\n    <v-chip color=\"red\" variant=\"flat\">\n      Red flat\n    </v-chip>\n\n    <v-chip color=\"green\" variant=\"flat\">\n      Green flat\n    </v-chip>\n  </div>\n</template>\n<script setup lang=\"ts\">\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-chip/prop-draggable.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-chip draggable>\n      Default\n    </v-chip>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-chip/prop-filter.vue",
    "content": "<template>\n  <v-row class=\"align-center justify-space-around\">\n    <v-chip\n      :model-value=\"active\"\n      class=\"ma-2\"\n      filter\n    >\n      I'm v-chip\n    </v-chip>\n\n    <v-chip\n      :model-value=\"active\"\n      class=\"ma-2\"\n      filter-icon=\"mdi-plus\"\n      filter\n    >\n      I'm v-chip\n    </v-chip>\n\n    <v-chip\n      :model-value=\"active\"\n      class=\"ma-2\"\n      filter-icon=\"mdi-minus\"\n      filter\n    >\n      I'm v-chip\n    </v-chip>\n\n    <v-switch\n      v-model=\"active\"\n      label=\"Active\"\n    ></v-switch>\n  </v-row>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const active = ref(false)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      active: false,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-chip/prop-label.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-chip\n      class=\"ma-2\"\n      label\n    >\n      Label\n    </v-chip>\n\n    <v-chip\n      class=\"ma-2\"\n      color=\"pink\"\n      label\n    >\n      <v-icon icon=\"mdi-label\" start></v-icon>\n      Tags\n    </v-chip>\n\n    <v-chip\n      class=\"ma-2\"\n      color=\"primary\"\n      label\n    >\n      <v-icon icon=\"mdi-account-circle-outline\" start></v-icon>\n      John Leider\n    </v-chip>\n\n    <v-chip\n      class=\"ma-2\"\n      color=\"cyan\"\n      closable\n      label\n    >\n      <v-icon icon=\"mdi-twitter\" start></v-icon>\n      New Tweets\n    </v-chip>\n  </div>\n</template>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=1632-103309&t=tWnPBMI0RfGlNRgq-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-chip/prop-no-ripple.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-chip :ripple=\"false\" link>\n      Default\n    </v-chip>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-chip/prop-outlined.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-chip\n      class=\"ma-2\"\n      color=\"success\"\n      variant=\"outlined\"\n    >\n      <v-icon icon=\"mdi-server-plus\" start></v-icon>\n      Server Status\n    </v-chip>\n\n    <v-chip\n      class=\"ma-2\"\n      color=\"primary\"\n      variant=\"outlined\"\n    >\n      User Account\n      <v-icon icon=\"mdi-account-outline\" end></v-icon>\n    </v-chip>\n  </div>\n</template>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2690-8212&t=tWnPBMI0RfGlNRgq-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-chip/prop-sizes.vue",
    "content": "<template>\n  <div class=\"d-flex justify-center align-center ga-2\">\n    <v-label style=\"width: 100px\">default</v-label>\n\n    <v-chip size=\"x-small\">\n      x-small\n    </v-chip>\n\n    <v-chip size=\"small\">\n      small\n    </v-chip>\n\n    <v-chip>\n      default\n    </v-chip>\n\n    <v-chip size=\"large\">\n      large\n    </v-chip>\n\n    <v-chip size=\"x-large\">\n      x-large\n    </v-chip>\n  </div>\n  <div class=\"d-flex justify-center align-center ga-2 mt-2\">\n    <v-label style=\"width: 100px\">comfortable</v-label>\n\n    <v-chip density=\"comfortable\" size=\"x-small\">\n      x-small\n    </v-chip>\n\n    <v-chip density=\"comfortable\" size=\"small\">\n      small\n    </v-chip>\n\n    <v-chip density=\"comfortable\">\n      default\n    </v-chip>\n\n    <v-chip density=\"comfortable\" size=\"large\">\n      large\n    </v-chip>\n\n    <v-chip density=\"comfortable\" size=\"x-large\">\n      x-large\n    </v-chip>\n  </div>\n  <div class=\"d-flex justify-center align-center ga-2 mt-2\">\n    <v-label style=\"width: 100px\">compact</v-label>\n\n    <v-chip density=\"compact\" size=\"x-small\">\n      x-small\n    </v-chip>\n\n    <v-chip density=\"compact\" size=\"small\">\n      small\n    </v-chip>\n\n    <v-chip density=\"compact\">\n      default\n    </v-chip>\n\n    <v-chip density=\"compact\" size=\"large\">\n      large\n    </v-chip>\n\n    <v-chip density=\"compact\" size=\"x-large\">\n      x-large\n    </v-chip>\n  </div>\n</template>\n<script setup lang=\"ts\">\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-chip/slot-icon.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-chip\n      class=\"ma-2\"\n      color=\"indigo\"\n      prepend-icon=\"mdi-account-circle\"\n    >\n      Mike\n    </v-chip>\n\n    <v-chip\n      append-icon=\"mdi-star\"\n      class=\"ma-2\"\n      color=\"orange\"\n    >\n      Premium\n    </v-chip>\n\n    <v-chip\n      append-icon=\"mdi-cake-variant\"\n      class=\"ma-2\"\n      color=\"primary\"\n    >\n      1 Year\n    </v-chip>\n\n    <v-chip\n      class=\"ma-2\"\n      color=\"green\"\n    >\n      <template v-slot:prepend>\n        <v-avatar\n          class=\"green-darken-4\"\n        >\n          1\n        </v-avatar>\n      </template>\n      Years\n    </v-chip>\n\n    <v-chip\n      :model-value=\"true\"\n      class=\"ma-2\"\n      color=\"teal\"\n      prepend-icon=\"mdi-checkbox-marked-circle\"\n      closable\n    >\n      Confirmed\n    </v-chip>\n\n    <v-chip\n      :model-value=\"true\"\n      class=\"ma-2\"\n      close-icon=\"mdi-delete\"\n      color=\"teal\"\n      prepend-icon=\"mdi-checkbox-marked-circle\"\n      closable\n    >\n      Confirmed\n    </v-chip>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-chip/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div class=\"text-center\">\n      <v-chip v-bind=\"props\" v-model=\"chipModel\">\n        Chip\n      </v-chip>\n    </div>\n\n    <template v-slot:configuration>\n      <v-checkbox v-model=\"prepend\" label=\"Prepend icon\"></v-checkbox>\n      <v-checkbox v-model=\"append\" label=\"Append icon\"></v-checkbox>\n      <v-checkbox v-model=\"closable\" label=\"Closable\">\n        <template v-slot:append>\n          <v-fade-transition>\n            <v-btn v-if=\"!chipModel\" variant=\"plain\" @click=\"chipModel = true\">Reset</v-btn>\n          </v-fade-transition>\n        </template>\n      </v-checkbox>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const variants = ['outlined', 'elevated', 'text', 'plain']\n  const name = 'v-chip'\n  const model = ref('default')\n  const options = [...variants]\n  const block = ref(false)\n  const stacked = ref(false)\n  const prepend = ref(false)\n  const append = ref(false)\n  const closable = ref(false)\n  const props = computed(() => {\n    return {\n      block: block.value || undefined,\n      closable: closable.value || undefined,\n      stacked: stacked.value || undefined,\n      'prepend-icon': prepend.value ? '$vuetify' : undefined,\n      'append-icon': append.value ? '$vuetify' : undefined,\n      variant: variants.includes(model.value) ? model.value : undefined,\n    }\n  })\n\n  const chipModel = ref(true)\n\n  watch(stacked, val => val && (prepend.value = true))\n\n  const slots = computed(() => {\n    return `\n  Chip\n`\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-chip-group/misc-product-card.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"400\"\n  >\n    <v-card-title class=\"d-flex\">\n      <h2 class=\"text-headline-large my-0\">Shirt Blouse</h2>\n\n      <v-spacer></v-spacer>\n\n      <span class=\"text-title-large\">$44.50</span>\n    </v-card-title>\n\n    <v-card-text>\n      Our blouses are available in 8 colors. You can custom order a built-in arch support for any of the models.\n    </v-card-text>\n\n    <v-divider class=\"mx-4\"></v-divider>\n\n    <v-card-text>\n      <span class=\"subheading\">Select size</span>\n\n      <v-chip-group\n        v-model=\"selection\"\n        selected-class=\"v-chip--selected v-chip--variant-tonal text-deep-purple-accent-4\"\n        variant=\"outlined\"\n        mandatory\n      >\n        <v-chip\n          v-for=\"size in sizes\"\n          :key=\"size\"\n          :text=\"size\"\n          :value=\"size\"\n        ></v-chip>\n      </v-chip-group>\n    </v-card-text>\n\n    <v-card-actions>\n      <v-btn\n        color=\"deep-purple-accent-4\"\n        text=\"Add to Cart\"\n        variant=\"flat\"\n        block\n      ></v-btn>\n    </v-card-actions>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const sizes = [\n    '04',\n    '06',\n    '08',\n    '10',\n    '12',\n    '14',\n  ]\n\n  const selection = ref('08')\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      selection: '08',\n      sizes: [\n        '04', '06', '08', '10', '12', '14',\n      ],\n    }),\n  }\n</script>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2226-46981&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-chip-group/misc-reddit-categories.vue",
    "content": "<template>\n  <v-sheet\n    class=\"mx-auto\"\n    max-width=\"400\"\n    rounded=\"xl\"\n    border\n  >\n    <div class=\"pa-4\">\n      <div class=\"text-title-large\">What are you into?</div>\n\n      <div class=\"text-body-large\">Select topics to continue</div>\n\n      <v-responsive class=\"overflow-y-auto\" max-height=\"280\">\n        <v-chip-group class=\"mt-3\" column>\n          <v-chip\n            v-for=\"topic in topics\"\n            :key=\"topic\"\n            :text=\"topic\"\n            :value=\"topic\"\n          ></v-chip>\n        </v-chip-group>\n      </v-responsive>\n    </div>\n\n    <v-divider></v-divider>\n\n    <div class=\"pa-2\">\n      <v-btn\n        color=\"orange-darken-1\"\n        rounded=\"t-0 b-xl\"\n        size=\"x-large\"\n        text=\"Continue\"\n        variant=\"flat\"\n        block\n      ></v-btn>\n    </div>\n  </v-sheet>\n</template>\n\n<script setup>\n  const topics = [\n    '🎤 Advice',\n    '🐕 Animals',\n    '🤖 Anime',\n    '🎨 Art & Design',\n    '💄 Beauty',\n    '🏢 Business',\n    '📚 Books',\n    '💡 Damn That\\'s Interesting',\n    '💃 Hobbies',\n    '🎮 Gaming',\n    '🎥 Movies',\n    '🎵 Music',\n    '📺 TV',\n    '🌮 Food',\n    '😂 Funny',\n    '💖 Health & Lifestyle',\n    '🎓 School',\n    '📰 News',\n    '🌲 Nature',\n    '🎨 Photography',\n    '🎏 Sports',\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      topics: [\n        '🎤 Advice',\n        '🐕 Animals',\n        '🤖 Anime',\n        '🎨 Art & Design',\n        '💄 Beauty',\n        '🏢 Business',\n        '📚 Books',\n        '💡 Damn That\\'s Interesting',\n        '💃 Hobbies',\n        '🎮 Gaming',\n        '🎥 Movies',\n        '🎵 Music',\n        '📺 TV',\n        '🌮 Food',\n        '😂 Funny',\n        '💖 Health & Lifestyle',\n        '🎓 School',\n        '📰 News',\n        '🌲 Nature',\n        '🎨 Photography',\n        '🎏 Sports',\n      ],\n    }),\n  }\n</script>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2226-49680&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-chip-group/misc-toothbrush-card.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"400\"\n  >\n    <v-card-title class=\"d-flex\">\n      <h2 class=\"text-headline-large my-0\">Toothbrush</h2>\n\n      <v-spacer></v-spacer>\n\n      <span class=\"text-title-large\">$4.99</span>\n    </v-card-title>\n\n    <v-card-text>\n      Our company takes pride in making handmade brushes.\n      Our toothbrushes are available in 4 different bristel types, from extra soft to hard.\n    </v-card-text>\n\n    <v-divider class=\"mx-4\"></v-divider>\n\n    <v-card-text>\n      <span class=\"subheading\">Select type</span>\n\n      <v-chip-group\n        v-model=\"selection\"\n        selected-class=\"v-chip--selected v-chip--variant-flat\"\n        variant=\"outlined\"\n        mandatory\n      >\n        <v-chip text=\"Extra Soft\"></v-chip>\n        <v-chip text=\"Soft\"></v-chip>\n        <v-chip text=\"Medium\"></v-chip>\n        <v-chip text=\"Hard\"></v-chip>\n      </v-chip-group>\n    </v-card-text>\n\n    <v-card-actions>\n      <v-btn\n        color=\"secondary\"\n        text=\"Add to Cart\"\n        variant=\"flat\"\n        block\n      ></v-btn>\n    </v-card-actions>\n  </v-card>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const selection = shallowRef(2)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      selection: 2,\n    }),\n  }\n</script>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2226-48225&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-chip-group/prop-column.vue",
    "content": "<template>\n  <v-sheet\n    class=\"mx-auto\"\n    elevation=\"3\"\n    max-width=\"300\"\n    rounded=\"xl\"\n  >\n    <v-sheet\n      class=\"pa-3 bg-primary text-right\"\n      rounded=\"t-xl\"\n    >\n      <v-btn icon=\"mdi-content-save-cog-outline\"></v-btn>\n\n      <v-btn\n        class=\"ms-2\"\n        icon=\"mdi-check-bold\"\n      ></v-btn>\n    </v-sheet>\n\n    <div class=\"pa-4\">\n      <v-chip-group\n        selected-class=\"text-primary\"\n        column\n      >\n        <v-chip\n          v-for=\"tag in tags\"\n          :key=\"tag\"\n        >\n          {{ tag }}\n        </v-chip>\n      </v-chip-group>\n    </div>\n  </v-sheet>\n</template>\n\n<script setup>\n  const tags = [\n    'Work',\n    'Home Improvement',\n    'Vacation',\n    'Food',\n    'Drawers',\n    'Shopping',\n    'Art',\n    'Tech',\n    'Creative Writing',\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      tags: [\n        'Work',\n        'Home Improvement',\n        'Vacation',\n        'Food',\n        'Drawers',\n        'Shopping',\n        'Art',\n        'Tech',\n        'Creative Writing',\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-chip-group/prop-filter.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"400\"\n  >\n    <v-toolbar color=\"deep-purple-accent-4\">\n      <v-btn icon=\"mdi-close\"></v-btn>\n\n      <v-toolbar-title>Filter results</v-toolbar-title>\n    </v-toolbar>\n\n    <v-card-text>\n      <h2 class=\"text-title-large mt-0 mb-2\">Choose amenities</h2>\n\n      <v-chip-group\n        v-model=\"amenities\"\n        column\n        multiple\n      >\n        <v-chip\n          text=\"Elevator\"\n          variant=\"outlined\"\n          filter\n        ></v-chip>\n\n        <v-chip\n          text=\"Washer / Dryer\"\n          variant=\"outlined\"\n          filter\n        ></v-chip>\n\n        <v-chip\n          text=\"Fireplace\"\n          variant=\"outlined\"\n          filter\n        ></v-chip>\n\n        <v-chip\n          text=\"Wheelchair access\"\n          variant=\"outlined\"\n          filter\n        ></v-chip>\n\n        <v-chip\n          text=\"Dogs ok\"\n          variant=\"outlined\"\n          filter\n        ></v-chip>\n\n        <v-chip\n          text=\"Cats ok\"\n          variant=\"outlined\"\n          filter\n        ></v-chip>\n      </v-chip-group>\n    </v-card-text>\n\n    <v-card-text>\n      <h2 class=\"text-title-large mt-0 mb-2\">Choose neighborhoods</h2>\n\n      <v-chip-group\n        v-model=\"neighborhoods\"\n        column\n        multiple\n      >\n        <v-chip\n          text=\"Snowy Rock Place\"\n          variant=\"outlined\"\n          filter\n        ></v-chip>\n\n        <v-chip\n          text=\"Honeylane Circle\"\n          variant=\"outlined\"\n          filter\n        ></v-chip>\n\n        <v-chip\n          text=\"Donna Drive\"\n          variant=\"outlined\"\n          filter\n        ></v-chip>\n\n        <v-chip\n          text=\"Elaine Street\"\n          variant=\"outlined\"\n          filter\n        ></v-chip>\n\n        <v-chip\n          text=\"Court Street\"\n          variant=\"outlined\"\n          filter\n        ></v-chip>\n\n        <v-chip\n          text=\"Kennedy Park\"\n          variant=\"outlined\"\n          filter\n        ></v-chip>\n      </v-chip-group>\n    </v-card-text>\n  </v-card>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const amenities = shallowRef([1, 4])\n  const neighborhoods = shallowRef([1])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      amenities: [1, 4],\n      neighborhoods: [1],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-chip-group/prop-mandatory.vue",
    "content": "<template>\n  <v-sheet class=\"py-4 px-1\">\n    <v-chip-group\n      selected-class=\"text-primary\"\n      mandatory\n    >\n      <v-chip\n        v-for=\"tag in tags\"\n        :key=\"tag\"\n        :text=\"tag\"\n      ></v-chip>\n    </v-chip-group>\n  </v-sheet>\n</template>\n\n<script setup>\n  const tags = [\n    'Work',\n    'Home Improvement',\n    'Vacation',\n    'Food',\n    'Drawers',\n    'Shopping',\n    'Art',\n    'Tech',\n    'Creative Writing',\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      tags: [\n        'Work',\n        'Home Improvement',\n        'Vacation',\n        'Food',\n        'Drawers',\n        'Shopping',\n        'Art',\n        'Tech',\n        'Creative Writing',\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-chip-group/prop-multiple.vue",
    "content": "<template>\n  <v-sheet class=\"py-4 px-1\">\n    <v-chip-group\n      selected-class=\"text-primary\"\n      multiple\n    >\n      <v-chip\n        v-for=\"tag in tags\"\n        :key=\"tag\"\n        :text=\"tag\"\n      ></v-chip>\n    </v-chip-group>\n  </v-sheet>\n</template>\n\n<script setup>\n  const tags = [\n    'Work',\n    'Home Improvement',\n    'Vacation',\n    'Food',\n    'Drawers',\n    'Shopping',\n    'Art',\n    'Tech',\n    'Creative Writing',\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      tags: [\n        'Work',\n        'Home Improvement',\n        'Vacation',\n        'Food',\n        'Drawers',\n        'Shopping',\n        'Art',\n        'Tech',\n        'Creative Writing',\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-chip-group/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div>\n      <v-chip-group v-bind=\"props\">\n        <v-chip>Chip 1</v-chip>\n\n        <v-chip>Chip 2</v-chip>\n\n        <v-chip>Chip 3</v-chip>\n      </v-chip-group>\n    </div>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-chip-group'\n  const model = ref('default')\n  const options = ['filter']\n  const props = computed(() => {\n    return {\n      filter: model.value === 'filter' || undefined,\n    }\n  })\n\n  const slots = computed(() => {\n    return `\n  <v-chip>Chip 1</v-chip>\n\n  <v-chip>Chip 2</v-chip>\n\n  <v-chip>Chip 3</v-chip>\n`\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-click-outside/option-close-on-outside-click.vue",
    "content": "<template>\n  <v-switch v-model=\"clickOutsideEnabled\" :label=\"`Click outside ${clickOutsideEnabled ? 'enabled' : 'disabled'}`\"></v-switch>\n  <v-card\n    :color=\"active ? 'primary' : undefined\"\n    :dark=\"active\"\n    class=\"mx-auto\"\n    height=\"256\"\n    rounded=\"xl\"\n    width=\"256\"\n    v-click-outside=\"{\n      handler: onClickOutside,\n      closeConditional: onCloseConditional\n    }\"\n    @click=\"active = true\"\n  >\n    <div class=\"text-title-large text-md-headline-large fill-height d-flex align-center justify-center\">\n      {{ active ? 'Click Outside' : 'Click Me' }}\n    </div>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const active = ref(false)\n  const clickOutsideEnabled = ref(false)\n\n  function onClickOutside () {\n    active.value = false\n  }\n  function onCloseConditional (e) {\n    return clickOutsideEnabled.value\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      active: false,\n      clickOutsideEnabled: false,\n    }),\n\n    methods: {\n      onClickOutside () {\n        this.active = false\n      },\n      onCloseConditional (e) {\n        return this.clickOutsideEnabled\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-click-outside/option-include.vue",
    "content": "<template>\n  <v-card\n    :color=\"active ? 'primary' : undefined\"\n    :dark=\"active\"\n    class=\"mx-auto\"\n    height=\"256\"\n    rounded=\"xl\"\n    width=\"256\"\n    v-click-outside=\"{\n      handler: onClickOutside,\n      include\n    }\"\n    @click=\"active = true\"\n  >\n    <div class=\"text-title-large text-md-headline-large fill-height d-flex align-center justify-center\">\n      {{ active ? 'Click Outside' : 'Click Me' }}\n    </div>\n  </v-card>\n\n  <div class=\"d-flex justify-center\">\n    <v-card\n      class=\"ma-2 included\"\n      rounded=\"lg\"\n    >\n      <v-card-text class=\"text-title-large\">\n        This element is included\n      </v-card-text>\n    </v-card>\n\n    <v-card\n      class=\"ma-2\"\n      rounded=\"lg\"\n    >\n      <v-card-text class=\"text-title-large\">\n        This element is not included\n      </v-card-text>\n    </v-card>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const active = ref(false)\n\n  function onClickOutside () {\n    active.value = false\n  }\n  function include () {\n    return [document.querySelector('.included')]\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      active: false,\n    }),\n    methods: {\n      onClickOutside () {\n        this.active = false\n      },\n      include () {\n        return [document.querySelector('.included')]\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-click-outside/usage.vue",
    "content": "<template>\n  <v-card\n    :color=\"active ? 'primary' : undefined\"\n    :dark=\"active\"\n    class=\"mx-auto\"\n    height=\"256\"\n    rounded=\"xl\"\n    width=\"256\"\n    v-click-outside=\"onClickOutside\"\n    @click=\"active = true\"\n  >\n    <div class=\"text-title-large text-md-headline-large fill-height d-flex align-center justify-center\">\n      {{ active ? 'Click Outside' : 'Click Me' }}\n    </div>\n  </v-card>\n</template>\n\n<script>\n  export default {\n    data: () => ({\n      active: false,\n    }),\n\n    methods: {\n      onClickOutside () {\n        this.active = false\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-color-input/prop-color-pip.vue",
    "content": "<template>\n  <v-container>\n    <v-row>\n      <v-col cols=\"12\" sm=\"6\">\n        <v-color-input\n          hide-details=\"auto\"\n          label=\"Colored Pip\"\n          model-value=\"#7C0799\"\n          color-pip\n          hide-actions\n        ></v-color-input>\n      </v-col>\n      <v-col cols=\"12\" sm=\"6\">\n        <v-color-input\n          hide-details=\"auto\"\n          label=\"Colored Pip (tonal)\"\n          model-value=\"#1493DB\"\n          pip-variant=\"tonal\"\n          color-pip\n          hide-actions\n        ></v-color-input>\n      </v-col>\n      <v-col cols=\"12\" sm=\"6\">\n        <v-color-input\n          hide-details=\"auto\"\n          label=\"Colored Pip (flat)\"\n          model-value=\"#74DB14\"\n          pip-variant=\"flat\"\n          color-pip\n          hide-actions\n        ></v-color-input>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-color-input/prop-model.vue",
    "content": "<template>\n  <div class=\"d-flex justify-center\">\n    <v-color-input\n      v-model=\"model\"\n      label=\"Select a color\"\n      max-width=\"368\"\n    ></v-color-input>\n  </div>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const model = shallowRef(null)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      model: null,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-color-input/prop-pip-location.vue",
    "content": "<template>\n  <v-container>\n    <v-row>\n      <v-col cols=\"12\" sm=\"6\">\n        <v-color-input\n          hide-details=\"auto\"\n        ></v-color-input>\n      </v-col>\n      <v-col cols=\"12\" sm=\"6\">\n        <v-color-input\n          hide-details=\"auto\"\n          pip-location=\"prepend-inner\"\n        ></v-color-input>\n      </v-col>\n      <v-col cols=\"12\" sm=\"6\">\n        <v-color-input\n          hide-details=\"auto\"\n          pip-location=\"append-inner\"\n        ></v-color-input>\n      </v-col>\n      <v-col cols=\"12\" sm=\"6\">\n        <v-color-input\n          hide-details=\"auto\"\n          pip-location=\"append\"\n        ></v-color-input>\n      </v-col>\n      <v-col cols=\"12\" sm=\"6\">\n        <v-color-input\n          hide-details=\"auto\"\n          label=\"I need no icon\"\n          hide-pip\n        ></v-color-input>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-color-input/prop-pip-variant.vue",
    "content": "<template>\n  <v-container>\n    <v-row>\n      <v-col cols=\"12\" sm=\"6\">\n        <v-color-input\n          hide-details=\"auto\"\n          pip-variant=\"tonal\"\n        ></v-color-input>\n      </v-col>\n      <v-col cols=\"12\" sm=\"6\">\n        <v-color-input\n          hide-details=\"auto\"\n          pip-variant=\"outlined\"\n        ></v-color-input>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-color-input/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div>\n      <v-color-input model-value=\"#14BCD3\" v-bind=\"props\"></v-color-input>\n    </div>\n\n    <template v-slot:configuration>\n      <v-select v-model=\"pipVariant\" :items=\"pipVariants\" label=\"Pip variant\" clearable></v-select>\n\n      <v-checkbox v-model=\"colorPip\" label=\"Color Pip\"></v-checkbox>\n      <v-checkbox v-model=\"clearable\" label=\"Clearable\"></v-checkbox>\n      <v-checkbox v-model=\"disabled\" label=\"Disabled\"></v-checkbox>\n      <v-checkbox v-model=\"hideActions\" label=\"Hide picker actions\"></v-checkbox>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-color-input'\n\n  const pipVariants = ['flat', 'tonal', 'outlined']\n\n  const model = ref('default')\n  const options = ['outlined', 'underlined', 'solo', 'solo-filled', 'solo-inverted']\n  const clearable = ref(false)\n  const hideActions = ref(false)\n  const pipVariant = ref()\n  const colorPip = ref(true)\n  const disabled = ref(false)\n  const props = computed(() => {\n    return {\n      clearable: clearable.value || undefined,\n      'color-pip': colorPip.value || undefined,\n      'pip-variant': pipVariant.value || undefined,\n      'hide-actions': hideActions.value || undefined,\n      disabled: disabled.value || undefined,\n      label: 'Color input',\n      variant: model.value === 'default' ? undefined : model.value,\n    }\n  })\n\n  const slots = computed(() => {\n    return ``\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-color-picker/prop-canvas.vue",
    "content": "<template>\n  <div class=\"d-flex justify-space-around\">\n    <v-color-picker\n      v-model=\"c1\"\n      hide-canvas\n      hide-sliders\n    ></v-color-picker>\n\n    <v-color-picker\n      v-model=\"c2\"\n      hide-inputs\n      show-swatches\n    ></v-color-picker>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const c1 = ref('#ff00ff')\n  const c2 = ref('#00ff00')\n</script>\n\n<script>\n\n  export default {\n    data: () => ({\n      c1: '#ff00ff',\n      c2: '#00ff00',\n    }),\n  }\n</script>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2496-13259&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-color-picker/prop-elevation.vue",
    "content": "<template>\n  <div class=\"d-flex justify-space-around\">\n    <v-color-picker\n      v-model=\"picker\"\n      elevation=\"0\"\n    ></v-color-picker>\n\n    <v-color-picker\n      v-model=\"picker\"\n      elevation=\"4\"\n    ></v-color-picker>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const picker = ref(null)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        picker: null,\n      }\n    },\n  }\n</script>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2771-94625&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-color-picker/prop-mode.vue",
    "content": "<template>\n  <div class=\"d-flex justify-space-around\">\n    <v-color-picker\n      v-model=\"color\"\n      :modes=\"['rgba']\"\n    ></v-color-picker>\n\n    <div class=\"d-flex flex-column\">\n      <v-color-picker\n        v-model=\"color\"\n        v-model:mode=\"mode\"\n      ></v-color-picker>\n      <v-select\n        v-model=\"mode\"\n        :items=\"modes\"\n        style=\"max-width: 300px\"\n      ></v-select>\n    </div>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const color = ref('#ff00ff')\n  const mode = ref('hsla')\n  const modes = ref(['hsla', 'rgba', 'hexa'])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      color: '#ff00ff',\n      mode: 'hsla',\n      modes: ['hsla', 'rgba', 'hexa'],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-color-picker/prop-model.vue",
    "content": "<template>\n  <v-container>\n    <v-row>\n      <v-col\n        cols=\"12\"\n        md=\"4\"\n      >\n        <v-btn class=\"my-4\" block @click=\"color = null\">null</v-btn>\n        <v-btn class=\"my-4\" block @click=\"color = '#ff00ff'\">hex</v-btn>\n        <v-btn class=\"my-4\" block @click=\"color = '#ff00ffff'\">hexa</v-btn>\n        <v-btn class=\"my-4\" block @click=\"color = { r: 255, g: 0, b: 255, a: 1 }\">rgba</v-btn>\n        <v-btn class=\"my-4\" block @click=\"color = { h: 300, s: 1, l: 0.5, a: 1 }\">hsla</v-btn>\n        <v-btn class=\"my-4\" block @click=\"color = { h: 300, s: 1, v: 1, a: 1 }\">hsva</v-btn>\n      </v-col>\n      <v-col\n        class=\"d-flex justify-center\"\n      >\n        <v-color-picker v-model=\"color\"></v-color-picker>\n      </v-col>\n      <v-col\n        cols=\"12\"\n        md=\"4\"\n      >\n        <v-sheet\n          class=\"pa-4\"\n        >\n          <pre>{{ color }}</pre>\n        </v-sheet>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const color = ref(null)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      color: null,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-color-picker/prop-swatches.vue",
    "content": "<template>\n  <div class=\"d-flex justify-space-around\">\n    <v-color-picker\n      class=\"ma-2\"\n      swatches-max-height=\"400px\"\n      show-swatches\n    ></v-color-picker>\n    <v-color-picker\n      :swatches=\"swatches\"\n      class=\"ma-2\"\n      show-swatches\n    ></v-color-picker>\n  </div>\n</template>\n\n<script setup>\n  const swatches = [\n    ['#FF0000', '#AA0000', '#550000'],\n    ['#FFFF00', '#AAAA00', '#555500'],\n    ['#00FF00', '#00AA00', '#005500'],\n    ['#00FFFF', '#00AAAA', '#005555'],\n    ['#0000FF', '#0000AA', '#000055'],\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      swatches: [\n        ['#FF0000', '#AA0000', '#550000'],\n        ['#FFFF00', '#AAAA00', '#555500'],\n        ['#00FF00', '#00AA00', '#005500'],\n        ['#00FFFF', '#00AAAA', '#005555'],\n        ['#0000FF', '#0000AA', '#000055'],\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-color-picker/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div class=\"d-flex justify-center\">\n      <v-color-picker v-bind=\"props\"></v-color-picker>\n    </div>\n\n    <template v-slot:configuration>\n      <v-checkbox v-model=\"hideCanvas\" label=\"Hide canvas\"></v-checkbox>\n\n      <v-checkbox v-model=\"hideInputs\" label=\"Hide inputs\"></v-checkbox>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-color-picker'\n  const model = ref('default')\n  const options = ['Disabled', 'Show swatches']\n  const hideCanvas = ref()\n  const hideInputs = ref()\n  const props = computed(() => {\n    return {\n      disabled: model.value === 'Disabled' ? true : undefined,\n      'hide-canvas': hideCanvas.value || undefined,\n      'hide-inputs': hideInputs.value || undefined,\n      'show-swatches': model.value === 'Show swatches' ? true : undefined,\n    }\n  })\n\n  const slots = computed(() => {\n    return ``\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-combobox/misc-advanced.vue",
    "content": "<template>\n  <v-container fluid>\n    <v-combobox\n      v-model=\"model\"\n      v-model:search=\"search\"\n      :custom-filter=\"filter\"\n      :items=\"items\"\n      label=\"Search for an option\"\n      variant=\"solo\"\n      hide-selected\n      multiple\n    >\n      <template v-slot:selection=\"{ item, index }\">\n        <v-chip\n          v-if=\"item === Object(item)\"\n          :color=\"`${item.color}-lighten-3`\"\n          :text=\"item.title\"\n          size=\"small\"\n          variant=\"flat\"\n          closable\n          label\n          @click:close=\"removeSelection(index)\"\n        ></v-chip>\n      </template>\n      <template v-slot:item=\"{ props, item }\">\n        <template v-if=\"item.header\">\n          <v-list-item\n            v-if=\"alreadySelected\"\n            title=\"Item is already selected\"\n          ></v-list-item>\n          <v-list-item v-else-if=\"search\">\n            <span class=\"mr-3\">Create</span>\n            <v-chip\n              :color=\"`${colors[nonce - 1]}-lighten-3`\"\n              size=\"small\"\n              variant=\"flat\"\n              label\n            >\n              {{ search }}\n            </v-chip>\n          </v-list-item>\n          <v-list-subheader v-else :title=\"item.title\"></v-list-subheader>\n        </template>\n        <v-list-item v-else @click=\"props.onClick\">\n          <v-text-field\n            v-if=\"editingItem === item\"\n            v-model=\"editingItem.title\"\n            bg-color=\"transparent\"\n            class=\"mr-3\"\n            density=\"compact\"\n            variant=\"plain\"\n            autofocus\n            hide-details\n            @click.stop\n            @keydown.stop\n            @keyup.enter=\"edit(item)\"\n            @mousedown.stop\n          ></v-text-field>\n          <v-chip\n            v-else\n            :color=\"`${item.color}-lighten-3`\"\n            :text=\"item.title\"\n            variant=\"flat\"\n            label\n          ></v-chip>\n          <template v-slot:append>\n            <v-btn\n              :color=\"editingItem !== item ? 'primary' : 'success'\"\n              :icon=\"editingItem !== item ? 'mdi-pencil' : 'mdi-check'\"\n              size=\"small\"\n              variant=\"text\"\n              @click.stop.prevent=\"edit(item)\"\n            ></v-btn>\n            <v-btn\n              v-if=\"editingItem !== item.raw\"\n              color=\"error\"\n              icon=\"mdi-trash-can\"\n              size=\"small\"\n              variant=\"text\"\n              @click.stop.prevent=\"removeItem(item.raw)\"\n            ></v-btn>\n          </template>\n        </v-list-item>\n      </template>\n    </v-combobox>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref, toRef, watch } from 'vue'\n\n  const colors = ['green', 'purple', 'indigo', 'cyan', 'teal', 'orange']\n  const editingItem = ref(null)\n  const items = ref([\n    { header: true, title: 'Select an option or create one' },\n    { title: 'Foo', color: 'blue' },\n    { title: 'Bar', color: 'red' },\n  ])\n  const model = ref([\n    { title: 'Foo', color: 'blue' },\n  ])\n  const search = ref(null)\n\n  const alreadySelected = toRef(() => model.value.some(x => x.title === search.value))\n\n  let nonce = 1\n  watch(model, val => {\n    const newValue = []\n    let changed = false\n    for (const v of val) {\n      if (typeof v === 'string') {\n        changed = true\n        const existingItem = items.value.find(x => x.title === v)\n        if (existingItem) {\n          newValue.push(existingItem)\n        } else {\n          const newIitem = {\n            title: v,\n            color: colors[nonce],\n          }\n          newValue.push(newIitem)\n          items.value.push(newIitem)\n          nonce = (nonce + 1) % colors.length\n        }\n      } else {\n        newValue.push(v)\n      }\n    }\n    if (changed) {\n      model.value = newValue\n    }\n  })\n\n  function edit (item) {\n    if (!editingItem.value) {\n      editingItem.value = item\n    } else {\n      editingItem.value = null\n    }\n  }\n\n  function filter (value, queryText, item) {\n    const toLowerCaseString = val =>\n      String(val != null ? val : '').toLowerCase()\n\n    const query = toLowerCaseString(queryText)\n\n    const isSelected = text => model.value.some(x => x.title === text)\n    const availableOptions = items.value.filter(x => !isSelected(x.title))\n    const hasAnyMatch = availableOptions.some(\n      x => !x.header && toLowerCaseString(x.title).includes(query)\n    )\n    if (item.raw.header) return !hasAnyMatch\n\n    const text = toLowerCaseString(item.raw.title)\n\n    return text.includes(query)\n  }\n\n  function removeSelection (index) {\n    model.value.splice(index, 1)\n  }\n\n  function removeItem (item) {\n    const index = items.value.findIndex(x => x.title === item.title)\n    items.value.splice(index, 1)\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      colors: ['green', 'purple', 'indigo', 'cyan', 'teal', 'orange'],\n      editingItem: null,\n      items: [\n        { header: true, title: 'Select an option or create one' },\n        {\n          title: 'Foo',\n          color: 'blue',\n        },\n        {\n          title: 'Bar',\n          color: 'red',\n        },\n      ],\n      nonce: 1,\n      model: [\n        { title: 'Foo', color: 'blue' },\n      ],\n      search: null,\n    }),\n\n    computed: {\n      alreadySelected () {\n        return this.model.some(x => x.title === this.search)\n      },\n    },\n\n    watch: {\n      model (val) {\n        const newValue = []\n        let changed = false\n        for (const v of val) {\n          if (typeof v === 'string') {\n            changed = true\n            const existingItem = this.items.find(x => x.title === v)\n            if (existingItem) {\n              newValue.push(existingItem)\n            } else {\n              const newIitem = {\n                title: v,\n                color: this.colors[this.nonce],\n              }\n              newValue.push(newIitem)\n              this.items.push(newIitem)\n              this.nonce = (this.nonce + 1) % this.colors.length\n            }\n          } else {\n            newValue.push(v)\n          }\n        }\n        if (changed) {\n          this.model = newValue\n        }\n      },\n    },\n\n    methods: {\n      edit (item) {\n        if (!this.editingItem) {\n          this.editingItem = item\n        } else {\n          this.editingItem = null\n        }\n      },\n      filter (value, queryText, item) {\n        const toLowerCaseString = val =>\n          String(val != null ? val : '').toLowerCase()\n\n        const query = toLowerCaseString(queryText)\n\n        const isSelected = text => this.model.some(x => x.title === text)\n        const availableOptions = this.items.filter(x => !isSelected(x.title))\n        const hasAnyMatch = availableOptions.some(\n          x => !x.header && toLowerCaseString(x.title).includes(query)\n        )\n        if (item.raw.header) return !hasAnyMatch\n\n        const text = toLowerCaseString(item.raw.title)\n\n        return text.includes(query)\n      },\n      removeSelection (index) {\n        this.model.splice(index, 1)\n      },\n      removeItem (item) {\n        const index = this.items.findIndex(x => x.title === item.title)\n        this.items.splice(index, 1)\n      },\n    },\n  }\n</script>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2047-82949&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-combobox/prop-density.vue",
    "content": "<template>\n  <v-card>\n    <v-container fluid>\n      <v-row>\n        <v-col cols=\"12\">\n          <v-combobox\n            v-model=\"value\"\n            :items=\"items\"\n            label=\"Default\"\n          ></v-combobox>\n        </v-col>\n        <v-col cols=\"12\">\n          <v-combobox\n            v-model=\"value\"\n            :items=\"items\"\n            density=\"comfortable\"\n            label=\"Comfortable\"\n          ></v-combobox>\n        </v-col>\n        <v-col cols=\"12\">\n          <v-combobox\n            v-model=\"value\"\n            :items=\"items\"\n            density=\"compact\"\n            label=\"Compact\"\n          ></v-combobox>\n        </v-col>\n      </v-row>\n    </v-container>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const items = ['foo', 'bar', 'fizz', 'buzz']\n\n  const value = ref('foo')\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: ['foo', 'bar', 'fizz', 'buzz'],\n      value: 'foo',\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-combobox/prop-multiple.vue",
    "content": "<template>\n  <v-container fluid>\n    <v-row>\n      <v-col cols=\"12\">\n        <v-combobox\n          v-model=\"select\"\n          :items=\"items\"\n          label=\"Select a favorite activity or create a new one\"\n          multiple\n        ></v-combobox>\n      </v-col>\n      <v-col cols=\"12\">\n        <v-combobox\n          v-model=\"select\"\n          :items=\"items\"\n          label=\"I use chips\"\n          chips\n          multiple\n        ></v-combobox>\n      </v-col>\n      <v-col cols=\"12\">\n        <v-combobox\n          v-model=\"select\"\n          :items=\"items\"\n          label=\"I use a scoped slot\"\n          multiple\n        >\n          <template v-slot:selection=\"{ item, internalItem }\">\n            <v-chip\n              :text=\"item.title\"\n              :value=\"internalItem.value\"\n              size=\"small\"\n            >\n              <template v-slot:prepend>\n                <v-avatar class=\"bg-accent text-uppercase\" start>\n                  {{ item.slice(0, 1) }}\n                </v-avatar>\n              </template>\n              {{ item }}\n            </v-chip>\n          </template>\n        </v-combobox>\n      </v-col>\n      <v-col cols=\"12\">\n        <v-combobox\n          v-model=\"select\"\n          label=\"I'm readonly\"\n          chips\n          multiple\n          readonly\n        ></v-combobox>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const select = ref(['Vuetify', 'Programming'])\n\n  const items = [\n    'Programming',\n    'Design',\n    'Vue',\n    'Vuetify',\n  ]\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        select: ['Vuetify', 'Programming'],\n        items: [\n          'Programming',\n          'Design',\n          'Vue',\n          'Vuetify',\n        ],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-combobox/prop-placeholder.vue",
    "content": "<template>\n  <v-container>\n    <v-combobox\n      :items=\"fruits\"\n      label=\"Fruits\"\n      placeholder=\"Ex: Apple, Grape\"\n      multiple\n      persistent-placeholder\n    ></v-combobox>\n  </v-container>\n</template>\n\n<script setup>\n  const fruits = ['Apple', 'Grape', 'Banana']\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-combobox/slot-custom-chip.vue",
    "content": "<template>\n  <v-combobox\n    v-model=\"selected\"\n    :items=\"items\"\n    item-title=\"name\"\n    item-value=\"name\"\n    chips\n    closable-chips\n    multiple\n  >\n    <template v-slot:chip=\"{ props, item }\">\n      <v-chip v-bind=\"props\" label>\n        <template v-slot:prepend>\n          <div class=\"me-1\">{{ item.symbol }}</div>\n        </template>\n        <template v-slot:close>\n          <v-icon icon=\"$close\" size=\"14\"></v-icon>\n        </template>\n      </v-chip>\n    </template>\n  </v-combobox>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const items = [\n    { symbol: '🍎', name: 'Apple' },\n    { symbol: '🍌', name: 'Banana' },\n    { symbol: '🍇', name: 'Grapes' },\n    { symbol: '🍉', name: 'Watermelon' },\n    { symbol: '🍓', name: 'Strawberry' },\n    { symbol: '🥝', name: 'Kiwi' },\n  ]\n  const selected = ref(['Apple', 'Kiwi', 'Grapes']\n    .map(v => items.find(item => item.name === v)))\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        items: [\n          { symbol: '🍎', name: 'Apple' },\n          { symbol: '🍌', name: 'Banana' },\n          { symbol: '🍇', name: 'Grapes' },\n          { symbol: '🍉', name: 'Watermelon' },\n          { symbol: '🍓', name: 'Strawberry' },\n          { symbol: '🥝', name: 'Kiwi' },\n        ],\n        selected: [],\n      }\n    },\n    mounted () {\n      this.selected = ['Apple', 'Kiwi', 'Grapes']\n        .map(v => this.items.find(item => item.name === v))\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-combobox/slot-menu-header.vue",
    "content": "<template>\n  <v-container>\n    <v-combobox\n      v-model=\"model\"\n      v-model:menu=\"menu\"\n      :items=\"filteredItems\"\n      item-title=\"value\"\n      item-value=\"id\"\n      multiple\n    >\n      <template v-slot:menu-header>\n        <v-tabs\n          v-model=\"tab\"\n          class=\"mt-2\"\n          slider-color=\"primary\"\n          grow\n          @keydown.enter.stop\n        >\n          <v-tab value=\"fruits\">Fruits</v-tab>\n          <v-tab value=\"vegetables\">Vegetables</v-tab>\n        </v-tabs>\n      </template>\n    </v-combobox>\n  </v-container>\n</template>\n\n<script setup>\n  import { computed, shallowRef } from 'vue'\n\n  const fruits = [\n    { id: 1, value: 'Apple', category: 'fruits' },\n    { id: 2, value: 'Banana', category: 'fruits' },\n    { id: 3, value: 'Cherry', category: 'fruits' },\n    { id: 4, value: 'Mango', category: 'fruits' },\n    { id: 5, value: 'Orange', category: 'fruits' },\n    { id: 6, value: 'Peach', category: 'fruits' },\n    { id: 7, value: 'Pineapple', category: 'fruits' },\n    { id: 8, value: 'Strawberry', category: 'fruits' },\n  ]\n\n  const vegetables = [\n    { id: 9, value: 'Broccoli', category: 'vegetables' },\n    { id: 10, value: 'Carrot', category: 'vegetables' },\n    { id: 11, value: 'Celery', category: 'vegetables' },\n    { id: 12, value: 'Cucumber', category: 'vegetables' },\n    { id: 13, value: 'Lettuce', category: 'vegetables' },\n    { id: 14, value: 'Pepper', category: 'vegetables' },\n    { id: 15, value: 'Spinach', category: 'vegetables' },\n    { id: 16, value: 'Tomato', category: 'vegetables' },\n  ]\n\n  const items = [...fruits, ...vegetables]\n\n  const model = shallowRef([fruits[0], vegetables[1]])\n  const menu = shallowRef(false)\n  const tab = shallowRef('fruits')\n\n  const filteredItems = computed(() => {\n    return items.filter(item => item.category === tab.value)\n  })\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      fruits: [\n        { id: 1, value: 'Apple', category: 'fruits' },\n        { id: 2, value: 'Banana', category: 'fruits' },\n        { id: 3, value: 'Cherry', category: 'fruits' },\n        { id: 4, value: 'Mango', category: 'fruits' },\n        { id: 5, value: 'Orange', category: 'fruits' },\n        { id: 6, value: 'Peach', category: 'fruits' },\n        { id: 7, value: 'Pineapple', category: 'fruits' },\n        { id: 8, value: 'Strawberry', category: 'fruits' },\n      ],\n      vegetables: [\n        { id: 9, value: 'Broccoli', category: 'vegetables' },\n        { id: 10, value: 'Carrot', category: 'vegetables' },\n        { id: 11, value: 'Celery', category: 'vegetables' },\n        { id: 12, value: 'Cucumber', category: 'vegetables' },\n        { id: 13, value: 'Lettuce', category: 'vegetables' },\n        { id: 14, value: 'Pepper', category: 'vegetables' },\n        { id: 15, value: 'Spinach', category: 'vegetables' },\n        { id: 16, value: 'Tomato', category: 'vegetables' },\n      ],\n      model: [\n        { id: 1, value: 'Apple', category: 'fruits' },\n        { id: 10, value: 'Carrot', category: 'vegetables' },\n      ],\n      menu: false,\n      tab: 'fruits',\n    }),\n\n    computed: {\n      items () {\n        return [...this.fruits, ...this.vegetables]\n      },\n      filteredItems () {\n        return this.items.filter(item => item.category === this.tab)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-combobox/slot-no-data.vue",
    "content": "<template>\n  <v-container fluid>\n    <v-combobox\n      v-model=\"model\"\n      v-model:search=\"search\"\n      :hide-no-data=\"false\"\n      :items=\"items\"\n      hint=\"Maximum of 5 tags\"\n      label=\"Add some tags\"\n      chips\n      hide-selected\n      multiple\n      persistent-hint\n    >\n      <template v-slot:no-data>\n        <v-list-item>\n          <v-list-item-title>\n            No results matching \"<strong>{{ search }}</strong>\". Press <kbd>enter</kbd> to create a new one\n          </v-list-item-title>\n        </v-list-item>\n      </template>\n    </v-combobox>\n  </v-container>\n</template>\n\n<script setup>\n  import { nextTick, ref, watch } from 'vue'\n\n  const items = ['Gaming', 'Programming', 'Vue', 'Vuetify']\n\n  const model = ref(['Vuetify'])\n  const search = ref(null)\n\n  watch(model, val => {\n    if (val.length > 5) {\n      nextTick(() => model.value.pop())\n    }\n  })\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: ['Gaming', 'Programming', 'Vue', 'Vuetify'],\n      model: ['Vuetify'],\n      search: null,\n    }),\n\n    watch: {\n      model (val) {\n        if (val.length > 5) {\n          this.$nextTick(() => this.model.pop())\n        }\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-combobox/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div>\n      <v-combobox v-bind=\"props\"></v-combobox>\n    </div>\n\n    <template v-slot:configuration>\n      <v-checkbox v-model=\"clear\" label=\"Clearable\"></v-checkbox>\n\n      <v-checkbox v-model=\"chips\" label=\"Chips\"></v-checkbox>\n\n      <v-checkbox v-model=\"multiple\" label=\"Multiple\"></v-checkbox>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-combobox'\n  const model = ref('default')\n  const clear = ref(false)\n  const chips = ref(false)\n  const multiple = ref(false)\n  const options = ['outlined', 'underlined', 'solo', 'solo-filled', 'solo-inverted']\n  const props = computed(() => {\n    return {\n      clearable: clear.value || undefined,\n      chips: chips.value || undefined,\n      multiple: multiple.value || undefined,\n      label: 'Combobox',\n      items: ['California', 'Colorado', 'Florida', 'Georgia', 'Texas', 'Wyoming'],\n      variant: model.value === 'default' ? undefined : model.value,\n    }\n  })\n\n  const slots = computed(() => {\n    return ``\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-command-palette/prop-close-on-select.vue",
    "content": "<template>\n  <div class=\"text-center my-3\">\n    <v-btn text=\"Open Command Palette\" @click=\"dialog = true\"></v-btn>\n\n    <v-command-palette\n      v-model=\"dialog\"\n      :items=\"items\"\n      placeholder=\"Search commands...\"\n      @after-leave=\"onAfterLeave\"\n      @before-select=\"handleBeforeSelect\"\n      @click:item=\"handleClick\"\n    ></v-command-palette>\n\n    <v-alert\n      :text=\"`Last action: ${lastAction || 'none'}`\"\n      class=\"mt-3\"\n      type=\"info\"\n      variant=\"tonal\"\n    ></v-alert>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const dialog = ref(false)\n  const lastAction = ref('')\n\n  const rootItems = [\n    { title: 'Files', subtitle: 'Enter file commands', value: 'files' },\n    { title: 'Settings', subtitle: 'Open settings', value: 'settings' },\n  ]\n\n  const fileItems = [\n    { title: 'Back', subtitle: 'Return to root commands', value: 'back' },\n    { title: 'New File', subtitle: 'Create a new file', value: 'new-file' },\n    { title: 'Open File', subtitle: 'Open an existing file', value: 'open-file' },\n  ]\n\n  const items = ref(rootItems)\n\n  function handleBeforeSelect ({ item, preventDefault }) {\n    if (item.value === 'files') {\n      preventDefault()\n      items.value = fileItems\n    }\n\n    if (item.value === 'back') {\n      preventDefault()\n      items.value = rootItems\n    }\n  }\n\n  function handleClick (item) {\n    lastAction.value = item.title\n  }\n\n  function onAfterLeave () {\n    items.value = rootItems\n  }\n</script>\n\n<script>\n  const rootItems = [\n    { title: 'Files', subtitle: 'Enter file commands', value: 'files' },\n    { title: 'Settings', subtitle: 'Open settings', value: 'settings' },\n  ]\n\n  const fileItems = [\n    { title: 'Back', subtitle: 'Return to root commands', value: 'back' },\n    { title: 'New File', subtitle: 'Create a new file', value: 'new-file' },\n    { title: 'Open File', subtitle: 'Open an existing file', value: 'open-file' },\n  ]\n\n  export default {\n    data: () => ({\n      dialog: false,\n      lastAction: '',\n      rootItems,\n      fileItems,\n      items: rootItems,\n    }),\n    methods: {\n      handleBeforeSelect ({ item, preventDefault }) {\n        if (item.value === 'files') {\n          preventDefault()\n          this.items = this.fileItems\n        }\n\n        if (item.value === 'back') {\n          preventDefault()\n          this.items = this.rootItems\n        }\n      },\n      handleClick (item) {\n        this.lastAction = item.title\n      },\n      onAfterLeave () {\n        this.items = this.rootItems\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-command-palette/prop-hotkey.vue",
    "content": "<template>\n  <div>\n    <v-alert\n      class=\"mb-4\"\n      type=\"info\"\n      variant=\"tonal\"\n    >\n      <div class=\"d-flex align-center justify-space-between\">\n        <span>Press <v-hotkey keys=\"ctrl+shift+p\" inline></v-hotkey> to open the command palette</span>\n      </div>\n    </v-alert>\n\n    <v-command-palette\n      v-model=\"dialog\"\n      v-model:search=\"search\"\n      :items=\"items\"\n      hotkey=\"ctrl+shift+p\"\n      placeholder=\"Type a command or search...\"\n      @click:item=\"handleItemClick\"\n    ></v-command-palette>\n\n    <v-card v-if=\"lastAction\">\n      <v-card-title>Last Action</v-card-title>\n      <v-card-text>\n        <div class=\"d-flex flex-column ga-2\">\n          <div><strong>Command:</strong> {{ lastAction.title }}</div>\n          <div v-if=\"lastAction.hotkey\">\n            <strong>Hotkey:</strong> <v-hotkey :keys=\"lastAction.hotkey\" inline></v-hotkey>\n          </div>\n          <div><strong>Value:</strong> {{ lastAction.value }}</div>\n        </div>\n      </v-card-text>\n    </v-card>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const dialog = ref(false)\n  const search = ref('')\n  const lastAction = ref(null)\n\n  const items = [\n    {\n      title: 'Save File',\n      subtitle: 'Save the current file',\n      prependIcon: 'mdi-content-save',\n      value: 'save',\n      hotkey: 'meta+s',\n    },\n    {\n      title: 'Open File',\n      subtitle: 'Open a file from disk',\n      prependIcon: 'mdi-folder-open',\n      value: 'open',\n      hotkey: 'meta+o',\n    },\n    {\n      type: 'divider',\n    },\n    {\n      type: 'subheader',\n      title: 'Edit',\n    },\n    {\n      title: 'Find',\n      subtitle: 'Find in current file',\n      prependIcon: 'mdi-magnify',\n      value: 'find',\n      hotkey: 'meta+f',\n    },\n    {\n      title: 'Replace',\n      subtitle: 'Find and replace',\n      prependIcon: 'mdi-find-replace',\n      value: 'replace',\n      hotkey: 'meta+h',\n    },\n    {\n      title: 'Go to Line',\n      subtitle: 'Jump to specific line',\n      prependIcon: 'mdi-arrow-right-bold',\n      value: 'goto',\n      hotkey: 'ctrl+g',\n    },\n    {\n      type: 'divider',\n    },\n    {\n      type: 'subheader',\n      title: 'View',\n    },\n    {\n      title: 'Toggle Sidebar',\n      subtitle: 'Show or hide sidebar',\n      prependIcon: 'mdi-page-layout-sidebar-left',\n      value: 'sidebar',\n      hotkey: 'meta+b',\n    },\n    {\n      title: 'Zoom In',\n      subtitle: 'Increase font size',\n      prependIcon: 'mdi-magnify-plus-outline',\n      value: 'zoom-in',\n      hotkey: 'meta+plus',\n    },\n    {\n      title: 'Zoom Out',\n      subtitle: 'Decrease font size',\n      prependIcon: 'mdi-magnify-minus-outline',\n      value: 'zoom-out',\n      hotkey: 'meta+minus',\n    },\n  ]\n\n  function handleItemClick (item, event) {\n    lastAction.value = item\n    console.log('Executed command:', item.title)\n  }\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        dialog: false,\n        search: '',\n        lastAction: null,\n        items: [\n          {\n            title: 'Save File',\n            subtitle: 'Save the current file',\n            prependIcon: 'mdi-content-save',\n            value: 'save',\n            hotkey: 'meta+s',\n          },\n          {\n            title: 'Open File',\n            subtitle: 'Open a file from disk',\n            prependIcon: 'mdi-folder-open',\n            value: 'open',\n            hotkey: 'meta+o',\n          },\n          {\n            type: 'divider',\n          },\n          {\n            type: 'subheader',\n            title: 'Edit',\n          },\n          {\n            title: 'Find',\n            subtitle: 'Find in current file',\n            prependIcon: 'mdi-magnify',\n            value: 'find',\n            hotkey: 'meta+f',\n          },\n          {\n            title: 'Replace',\n            subtitle: 'Find and replace',\n            prependIcon: 'mdi-find-replace',\n            value: 'replace',\n            hotkey: 'meta+h',\n          },\n          {\n            title: 'Go to Line',\n            subtitle: 'Jump to specific line',\n            prependIcon: 'mdi-arrow-right-bold',\n            value: 'goto',\n            hotkey: 'ctrl+g',\n          },\n          {\n            type: 'divider',\n          },\n          {\n            type: 'subheader',\n            title: 'View',\n          },\n          {\n            title: 'Toggle Sidebar',\n            subtitle: 'Show or hide sidebar',\n            prependIcon: 'mdi-page-layout-sidebar-left',\n            value: 'sidebar',\n            hotkey: 'meta+b',\n          },\n          {\n            title: 'Zoom In',\n            subtitle: 'Increase font size',\n            prependIcon: 'mdi-magnify-plus-outline',\n            value: 'zoom-in',\n            hotkey: 'meta+plus',\n          },\n          {\n            title: 'Zoom Out',\n            subtitle: 'Decrease font size',\n            prependIcon: 'mdi-magnify-minus-outline',\n            value: 'zoom-out',\n            hotkey: 'meta+minus',\n          },\n        ],\n      }\n    },\n    methods: {\n      handleItemClick (item, event) {\n        this.lastAction = item\n        console.log('Executed command:', item.title)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-command-palette/prop-items.vue",
    "content": "<template>\n  <div class=\"text-center my-3\">\n    <v-btn text=\"Open Command Palette\" @click=\"dialog = true\"></v-btn>\n\n    <v-command-palette\n      v-model=\"dialog\"\n      v-model:search=\"search\"\n      :items=\"items\"\n      placeholder=\"Search commands...\"\n      @click:item=\"handleItemClick\"\n    ></v-command-palette>\n\n    <v-alert\n      v-if=\"lastAction\"\n      :text=\"`Action: ${lastAction}`\"\n      type=\"info\"\n      variant=\"tonal\"\n    ></v-alert>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const dialog = ref(false)\n  const search = ref('')\n  const lastAction = ref('')\n\n  const items = [\n    {\n      title: 'Create File',\n      subtitle: 'Create a new file in current directory',\n      prependIcon: 'mdi-file-plus',\n      value: 'create-file',\n    },\n    {\n      title: 'Create Folder',\n      subtitle: 'Create a new folder',\n      prependIcon: 'mdi-folder-plus',\n      value: 'create-folder',\n    },\n    {\n      title: 'Open Recent',\n      subtitle: 'Open recently accessed files',\n      prependIcon: 'mdi-history',\n      value: 'open-recent',\n    },\n    {\n      type: 'divider',\n    },\n    {\n      type: 'subheader',\n      title: 'Edit Actions',\n    },\n    {\n      title: 'Find in Files',\n      subtitle: 'Search across all project files',\n      prependIcon: 'mdi-magnify',\n      value: 'find-files',\n    },\n    {\n      title: 'Replace in Files',\n      subtitle: 'Find and replace across project',\n      prependIcon: 'mdi-find-replace',\n      value: 'replace-files',\n    },\n    {\n      type: 'divider',\n    },\n    {\n      type: 'subheader',\n      title: 'View',\n    },\n    {\n      title: 'Toggle Sidebar',\n      subtitle: 'Show or hide the sidebar',\n      prependIcon: 'mdi-page-layout-sidebar-left',\n      value: 'toggle-sidebar',\n    },\n    {\n      title: 'Toggle Terminal',\n      subtitle: 'Show or hide terminal panel',\n      prependIcon: 'mdi-console',\n      value: 'toggle-terminal',\n    },\n    {\n      type: 'divider',\n    },\n    {\n      type: 'subheader',\n      title: 'Settings',\n    },\n    {\n      title: 'Preferences',\n      subtitle: 'Open settings',\n      prependIcon: 'mdi-cog',\n      value: 'preferences',\n    },\n    {\n      title: 'Keyboard Shortcuts',\n      subtitle: 'View and edit shortcuts',\n      prependIcon: 'mdi-keyboard-outline',\n      value: 'shortcuts',\n    },\n  ]\n\n  function handleItemClick (item, event) {\n    lastAction.value = item.title\n    console.log('Item clicked:', item)\n  }\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        dialog: false,\n        search: '',\n        lastAction: '',\n        items: [\n          {\n            title: 'Create File',\n            subtitle: 'Create a new file in current directory',\n            prependIcon: 'mdi-file-plus',\n            value: 'create-file',\n          },\n          {\n            title: 'Create Folder',\n            subtitle: 'Create a new folder',\n            prependIcon: 'mdi-folder-plus',\n            value: 'create-folder',\n          },\n          {\n            title: 'Open Recent',\n            subtitle: 'Open recently accessed files',\n            prependIcon: 'mdi-history',\n            value: 'open-recent',\n          },\n          {\n            type: 'divider',\n          },\n          {\n            type: 'subheader',\n            title: 'Edit Actions',\n          },\n          {\n            title: 'Find in Files',\n            subtitle: 'Search across all project files',\n            prependIcon: 'mdi-magnify',\n            value: 'find-files',\n          },\n          {\n            title: 'Replace in Files',\n            subtitle: 'Find and replace across project',\n            prependIcon: 'mdi-find-replace',\n            value: 'replace-files',\n          },\n          {\n            type: 'divider',\n          },\n          {\n            type: 'subheader',\n            title: 'View',\n          },\n          {\n            title: 'Toggle Sidebar',\n            subtitle: 'Show or hide the sidebar',\n            prependIcon: 'mdi-page-layout-sidebar-left',\n            value: 'toggle-sidebar',\n          },\n          {\n            title: 'Toggle Terminal',\n            subtitle: 'Show or hide terminal panel',\n            prependIcon: 'mdi-console',\n            value: 'toggle-terminal',\n          },\n          {\n            type: 'divider',\n          },\n          {\n            type: 'subheader',\n            title: 'Settings',\n          },\n          {\n            title: 'Preferences',\n            subtitle: 'Open settings',\n            prependIcon: 'mdi-cog',\n            value: 'preferences',\n          },\n          {\n            title: 'Keyboard Shortcuts',\n            subtitle: 'View and edit shortcuts',\n            prependIcon: 'mdi-keyboard-outline',\n            value: 'shortcuts',\n          },\n        ],\n      }\n    },\n    methods: {\n      handleItemClick (item, event) {\n        this.lastAction = item.title\n        console.log('Item clicked:', item)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-command-palette/slot-item-append.vue",
    "content": "<template>\n  <div class=\"text-center my-3\">\n    <v-btn text=\"Open\" @click=\"model = true\"></v-btn>\n    <v-command-palette\n      v-model=\"model\"\n      :items=\"items\"\n      :search-props=\"{ autocomplete: 'off' }\"\n      hotkey=\"ctrl+/\"\n      max-width=\"500\"\n      placeholder=\"Remind me...\"\n    >\n      <template v-slot:input.append-inner>\n        <v-kbd class=\"opacity-70 align-self-center py-1\">Esc</v-kbd>\n      </template>\n\n      <template v-slot:item.append=\"{ item }\">\n        <span class=\"text-body-small opacity-70\">{{ item.hint }}</span>\n      </template>\n\n      <template v-slot:append>\n        <div class=\"d-flex pa-3 ga-1 text-body-small align-center border-t opacity-70\">\n          <v-kbd>\n            <v-icon\n              :icon=\"['M16.018 3.815L15.232 8h-4.966l.716-3.815l-1.964-.37L8.232 8H4v2h3.857l-.751 4H3v2h3.731l-.714 3.805l1.965.369L8.766 16h4.966l-.714 3.805l1.965.369l.783-4.174H20v-2h-3.859l.751-4H21V8h-3.733l.716-3.815zM14.106 14H9.141l.751-4h4.966z']\"\n              size=\"14\"\n            ></v-icon>\n          </v-kbd>\n          <div class=\"mr-3\">tags</div>\n          <v-kbd><v-icon icon=\"$arrowup\" size=\"14\"></v-icon></v-kbd>\n          <v-kbd><v-icon icon=\"$arrowdown\" size=\"14\"></v-icon></v-kbd>\n          <div class=\"mr-3\">navigate</div>\n          <v-kbd><v-icon icon=\"$enter\" size=\"14\"></v-icon></v-kbd>\n          <div class=\"mr-3\">open</div>\n          <v-kbd>esc</v-kbd>\n          <div class=\"mr-3\">close</div>\n        </div>\n      </template>\n    </v-command-palette>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n  import { useDate } from 'vuetify'\n\n  const model = ref(false)\n  const adapter = useDate()\n\n  function futureTime (minutes) {\n    const d = new Date()\n    d.setMinutes(d.getMinutes() + minutes)\n    return new Intl.DateTimeFormat(adapter.locale, { hour: 'numeric', minute: 'numeric' }).format(d)\n  }\n\n  function futureDay (days, hour = 9) {\n    const d = new Date()\n    d.setDate(d.getDate() + days)\n    d.setHours(hour)\n    d.setMinutes(0)\n    d.setMilliseconds(0)\n    return new Intl.DateTimeFormat(adapter.locale, { weekday: 'long', hour: 'numeric', minute: 'numeric' }).format(d)\n  }\n\n  const items = ref([\n    { title: 'In 15 minutes', hint: futureTime(15), value: '+15m' },\n    { title: 'In 30 minutes', hint: futureTime(30), value: '+30m' },\n    { title: 'In 1 hour', hint: futureTime(60), value: '+60m' },\n    { title: 'Tomorrow', hint: futureDay(1), value: '+1d' },\n    { title: 'Next week', hint: futureDay(7), value: '+7d' },\n  ])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      model: false,\n    }),\n    computed: {\n      items () {\n        return [\n          { title: 'In 15 minutes', hint: this.futureTime(15), value: '+15m' },\n          { title: 'In 30 minutes', hint: this.futureTime(30), value: '+30m' },\n          { title: 'In 1 hour', hint: this.futureTime(60), value: '+60m' },\n          { title: 'Tomorrow', hint: this.futureDay(1), value: '+1d' },\n          { title: 'Next week', hint: this.futureDay(7), value: '+7d' },\n        ]\n      },\n    },\n    methods: {\n      futureTime (minutes) {\n        const d = new Date()\n        d.setMinutes(d.getMinutes() + minutes)\n        return new Intl.DateTimeFormat(this.$vuetify.date.locale, { hour: 'numeric', minute: 'numeric' }).format(d)\n      },\n      futureDay (days, hour = 9) {\n        const d = new Date()\n        d.setDate(d.getDate() + days)\n        d.setHours(hour)\n        d.setMinutes(0)\n        d.setMilliseconds(0)\n        return new Intl.DateTimeFormat(this.$vuetify.date.locale, { weekday: 'long', hour: 'numeric', minute: 'numeric' }).format(d)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-command-palette/slot-item-prepend.vue",
    "content": "<template>\n  <div class=\"text-center my-3\">\n    <v-btn text=\"Open\" @click=\"model = !model\"></v-btn>\n\n    <v-command-palette\n      v-model=\"model\"\n      :filter-keys=\"['raw.name', 'raw.username']\"\n      :items=\"items\"\n      hotkey=\"alt+g\"\n      item-title=\"name\"\n      item-value=\"name\"\n      max-height=\"800\"\n      placeholder=\"Search by name\"\n    >\n      <template v-slot:prepend>\n        <div class=\"ma-2 text-title-small\">\n          What are you looking for?\n        </div>\n\n        <v-chip-group class=\"pl-2 mt-n1 mb-1\">\n          <v-chip\n            v-for=\"c in ['People', 'Files', 'Actions']\"\n            :key=\"c\"\n            :text=\"c\"\n            size=\"small\"\n            closable\n            label\n          >\n            <template v-slot:close>\n              <v-icon icon=\"$close\" size=\"14\"></v-icon>\n            </template>\n          </v-chip>\n        </v-chip-group>\n      </template>\n\n      <template v-slot:item.prepend=\"{ item }\">\n        <v-avatar :image=\"`https://avataaars.io/${item.avatar}`\" size=\"small\"></v-avatar>\n      </template>\n\n      <template v-slot:list.subheader=\"{ props: { title } }\">\n        <div class=\"d-flex align-center\">\n          <v-list-subheader>{{ title }}</v-list-subheader>\n          <v-btn\n            class=\"ml-auto my-n1\"\n            size=\"small\"\n            tabindex=\"-1\"\n            text=\"See all\"\n            variant=\"text\"\n          ></v-btn>\n        </div>\n      </template>\n\n      <template v-slot:item.title=\"{ item }\">\n        {{ item.name }}\n        <v-chip :text=\"item.username\" class=\"opacity-70 ml-1\" size=\"small\"></v-chip>\n      </template>\n    </v-command-palette>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const avatars = [\n    '?accessoriesType=Blank&avatarStyle=Circle&clotheColor=PastelGreen&clotheType=ShirtScoopNeck&eyeType=Wink&eyebrowType=UnibrowNatural&facialHairColor=Black&facialHairType=MoustacheMagnum&hairColor=Platinum&mouthType=Concerned&skinColor=Tanned&topType=Turban',\n    '?accessoriesType=Prescription02&avatarStyle=Circle&clotheColor=Black&clotheType=ShirtVNeck&eyeType=Surprised&eyebrowType=Angry&facialHairColor=Blonde&facialHairType=Blank&hairColor=Blonde&hatColor=PastelOrange&mouthType=Smile&skinColor=Black&topType=LongHairNotTooLong',\n    '?accessoriesType=Blank&avatarStyle=Circle&clotheColor=White&clotheType=GraphicShirt&eyeType=Dizzy&eyebrowType=RaisedExcitedNatural&facialHairColor=Brown&facialHairType=BeardLight&hairColor=Platinum&mouthType=Serious&skinColor=Tanned&topType=ShortHairShortCurly',\n    '?accessoriesType=Round&avatarStyle=Circle&clotheColor=PastelOrange&clotheType=Overall&eyeType=Close&eyebrowType=AngryNatural&facialHairColor=Blonde&facialHairType=Blank&graphicType=Pizza&hairColor=Black&hatColor=PastelBlue&mouthType=Serious&skinColor=Light&topType=LongHairBigHair',\n    '?accessoriesType=Sunglasses&avatarStyle=Circle&clotheColor=Gray02&clotheType=ShirtScoopNeck&eyeType=EyeRoll&eyebrowType=RaisedExcited&facialHairColor=Red&facialHairType=BeardMagestic&hairColor=Red&hatColor=White&mouthType=Twinkle&skinColor=DarkBrown&topType=LongHairBun',\n    '?accessoriesType=Kurt&avatarStyle=Circle&clotheColor=Gray01&clotheType=BlazerShirt&eyeType=Surprised&eyebrowType=Default&facialHairColor=Red&facialHairType=Blank&graphicType=Selena&hairColor=Red&hatColor=Blue02&mouthType=Twinkle&skinColor=Pale&topType=LongHairCurly',\n  ]\n\n  const people = [\n    { value: 1, username: '@james', name: 'James Brown', avatar: avatars[0] },\n    { value: 2, username: '@sophia', name: 'Sophia Williams', avatar: avatars[1] },\n    { value: 3, username: '@taylor', name: 'Arthur Taylor', avatar: avatars[2] },\n    { value: 4, username: '@emma', name: 'Emma Wright', avatar: avatars[3] },\n    { value: 5, username: '@matt', name: 'Matthew Johnson', avatar: avatars[4] },\n    { value: 6, username: '@laura', name: 'Laura Perez', avatar: avatars[5] },\n  ]\n\n  const model = ref(false)\n\n  const items = [\n    { type: 'divider' },\n    { type: 'subheader', title: 'Recently open', childrenCount: 2 },\n    ...people.slice(0, 2).map(x => ({ ...x, type: 'item' })),\n    { type: 'divider' },\n    { type: 'subheader', title: 'Other results', childrenCount: 4 },\n    ...people.slice(2).map(x => ({ ...x, type: 'item' })),\n  ]\n</script>\n\n<script>\n  const avatars = [\n    '?accessoriesType=Blank&avatarStyle=Circle&clotheColor=PastelGreen&clotheType=ShirtScoopNeck&eyeType=Wink&eyebrowType=UnibrowNatural&facialHairColor=Black&facialHairType=MoustacheMagnum&hairColor=Platinum&mouthType=Concerned&skinColor=Tanned&topType=Turban',\n    '?accessoriesType=Prescription02&avatarStyle=Circle&clotheColor=Black&clotheType=ShirtVNeck&eyeType=Surprised&eyebrowType=Angry&facialHairColor=Blonde&facialHairType=Blank&hairColor=Blonde&hatColor=PastelOrange&mouthType=Smile&skinColor=Black&topType=LongHairNotTooLong',\n    '?accessoriesType=Blank&avatarStyle=Circle&clotheColor=White&clotheType=GraphicShirt&eyeType=Dizzy&eyebrowType=RaisedExcitedNatural&facialHairColor=Brown&facialHairType=BeardLight&hairColor=Platinum&mouthType=Serious&skinColor=Tanned&topType=ShortHairShortCurly',\n    '?accessoriesType=Round&avatarStyle=Circle&clotheColor=PastelOrange&clotheType=Overall&eyeType=Close&eyebrowType=AngryNatural&facialHairColor=Blonde&facialHairType=Blank&graphicType=Pizza&hairColor=Black&hatColor=PastelBlue&mouthType=Serious&skinColor=Light&topType=LongHairBigHair',\n    '?accessoriesType=Sunglasses&avatarStyle=Circle&clotheColor=Gray02&clotheType=ShirtScoopNeck&eyeType=EyeRoll&eyebrowType=RaisedExcited&facialHairColor=Red&facialHairType=BeardMagestic&hairColor=Red&hatColor=White&mouthType=Twinkle&skinColor=DarkBrown&topType=LongHairBun',\n    '?accessoriesType=Kurt&avatarStyle=Circle&clotheColor=Gray01&clotheType=BlazerShirt&eyeType=Surprised&eyebrowType=Default&facialHairColor=Red&facialHairType=Blank&graphicType=Selena&hairColor=Red&hatColor=Blue02&mouthType=Twinkle&skinColor=Pale&topType=LongHairCurly',\n  ]\n\n  const people = [\n    { value: 1, username: '@james', name: 'James Brown', avatar: avatars[0] },\n    { value: 2, username: '@sophia', name: 'Sophia Williams', avatar: avatars[1] },\n    { value: 3, username: '@taylor', name: 'Arthur Taylor', avatar: avatars[2] },\n    { value: 4, username: '@emma', name: 'Emma Wright', avatar: avatars[3] },\n    { value: 5, username: '@matt', name: 'Matthew Johnson', avatar: avatars[4] },\n    { value: 6, username: '@laura', name: 'Laura Perez', avatar: avatars[5] },\n  ]\n\n  export default {\n    data: () => ({\n      model: false,\n      items: [\n        { type: 'divider' },\n        { type: 'subheader', title: 'Recently open', childrenCount: 2 },\n        ...people.slice(0, 2).map(x => ({ ...x, type: 'item' })),\n        { type: 'divider' },\n        { type: 'subheader', title: 'Other results', childrenCount: 4 },\n        ...people.slice(2).map(x => ({ ...x, type: 'item' })),\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-command-palette/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n    :script=\"script\"\n  >\n    <div class=\"text-center\">\n      <v-command-palette\n        v-model:search=\"search\"\n        v-bind=\"props\"\n        :items=\"items\"\n        @click:item=\"onItemClick\"\n      >\n        <template v-slot:activator=\"{ props: activatorProps }\">\n          <v-btn v-bind=\"activatorProps\">Open Command Palette</v-btn>\n        </template>\n      </v-command-palette>\n    </div>\n\n    <template v-slot:configuration>\n      <v-text-field\n        v-model=\"placeholder\"\n        label=\"Placeholder\"\n        hide-details\n      ></v-text-field>\n\n      <v-text-field\n        v-model=\"hotkey\"\n        hint=\"Try 'ctrl+shift+p' or 'meta+j'\"\n        label=\"Global Hotkey\"\n        persistent-hint\n      ></v-text-field>\n\n      <v-slider\n        v-model=\"offsetTop\"\n        :max=\"40\"\n        :min=\"0\"\n        :step=\"1\"\n        label=\"Offset Top\"\n        hide-details\n        thumb-label\n      >\n        <template v-slot:thumb-label>{{ offsetTop }}vh</template>\n      </v-slider>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-command-palette'\n  const model = ref('default')\n  const search = ref('')\n  const placeholder = ref('Search commands...')\n  const hotkey = ref('ctrl+shift+k')\n  const offsetTop = ref(15)\n  const options = []\n\n  const items = [\n    {\n      title: 'Find File',\n      subtitle: 'Open general search',\n      prependIcon: 'mdi-file-find',\n      value: 'find-file',\n    },\n    {\n      title: 'Open Project',\n      subtitle: 'Open an existing project',\n      prependIcon: 'mdi-folder-open',\n      value: 'open-project',\n    },\n    { type: 'divider' },\n    { type: 'subheader', title: 'Settings' },\n    {\n      title: 'Help',\n      subtitle: 'View documentation',\n      prependIcon: 'mdi-help-circle-outline',\n      value: 'help',\n    },\n  ]\n\n  const props = computed(() => ({\n    placeholder: placeholder.value,\n    hotkey: hotkey.value || undefined,\n    'offset-top': offsetTop.value !== 15 ? `${offsetTop.value}vh` : undefined,\n  }))\n\n  const code = computed(() => {\n    return `<v-command-palette\n  v-model:search=\"search\"\n  :items=\"items\"${propsToString(props.value)}  @click:item=\"onItemClick\"\n>\n  <template v-slot:activator=\"{ props: activatorProps }\">\n    <v-btn v-bind=\"activatorProps\">Open Command Palette</v-btn>\n  </template>\n</v-command-palette>`\n  })\n\n  function onItemClick (item) {\n    console.log('selected item:', item)\n  }\n\n  const script = computed(() => {\n    return `<script setup>\n  import { shallowRef } from 'vue'\n\n  const search = shallowRef('')\n  const items = ${JSON.stringify(items, null, 2)}\n\n  function onItemClick (item) {\n    console.log('selected item:', item)\n  }\n<` + '/script>'\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-confirm-edit/misc-date-picker.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"328\"\n    rounded=\"lg\"\n    border\n  >\n    <v-confirm-edit v-model=\"date\">\n      <template v-slot:default=\"{ model: proxyModel, actions }\">\n        <v-date-picker v-model=\"proxyModel.value\">\n          <template v-slot:actions>\n            <component :is=\"actions\"></component>\n          </template>\n        </v-date-picker>\n      </template>\n    </v-confirm-edit>\n  </v-card>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const date = shallowRef()\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-confirm-edit/misc-disable-actions.vue",
    "content": "<template>\n  <div>\n    <div class=\"d-flex justify-center\">\n      <v-btn-toggle\n        density=\"comfortable\"\n        rounded=\"lg\"\n        border\n        divided\n      >\n        <v-btn\n          :active=\"Array.isArray(disabled) && disabled?.includes('cancel')\"\n          text=\"Toggle cancel\"\n          @click=\"onClick('cancel')\"\n        ></v-btn>\n\n        <v-btn\n          :active=\"Array.isArray(disabled) && disabled?.includes('save')\"\n          text=\"Toggle save\"\n          @click=\"onClick('save')\"\n        ></v-btn>\n\n        <v-btn\n          :active=\"typeof disabled === 'boolean'\"\n          text=\"Toggle Boolean\"\n          @click=\"disabled = !disabled\"\n        ></v-btn>\n\n        <v-btn\n          :active=\"disabled === undefined\"\n          text=\"Default\"\n          @click=\"disabled = undefined\"\n        ></v-btn>\n      </v-btn-toggle>\n    </div>\n\n    <div class=\"d-flex justify-center align-center py-4 ga-2\">\n      <strong>Disabled:</strong>\n      <span\n        class=\"bg-surface-light rounded rounded-md pa-1\"\n        size=\"small\"\n        v-text=\"disabled === undefined ? 'undefined' : disabled\"\n      ></span>\n    </div>\n\n    <v-sheet\n      class=\"pa-4\"\n      color=\"surface-light\"\n      rounded=\"lg\"\n    >\n      <v-confirm-edit\n        v-slot=\"{ model: proxyModel, actions }\"\n        v-model=\"value\"\n        :disabled=\"disabled\"\n      >\n        <v-card class=\"mx-auto\" max-width=\"400\" rounded=\"lg\" title=\"Update Field\">\n          <template v-slot:text>\n            <v-text-field\n              v-model=\"proxyModel.value\"\n              label=\"Name\"\n              prepend-icon=\"$vuetify\"\n              variant=\"outlined\"\n            ></v-text-field>\n          </template>\n\n          <v-divider></v-divider>\n\n          <template v-slot:actions>\n            <v-spacer></v-spacer>\n\n            <component :is=\"actions\"></component>\n          </template>\n        </v-card>\n      </v-confirm-edit>\n    </v-sheet>\n  </div>\n</template>\n\n<script setup>\n  import { ref, shallowRef } from 'vue'\n\n  const disabled = ref([])\n  const value = shallowRef('My Beach Vacation')\n\n  function onClick (action) {\n    if (!Array.isArray(disabled.value)) {\n      disabled.value = []\n    }\n\n    if (disabled.value.includes(action)) {\n      disabled.value = disabled.value.filter(item => item !== action)\n    } else {\n      disabled.value.push(action)\n    }\n  }\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        disabled: [],\n        value: 'My Beach Vacation',\n      }\n    },\n\n    methods: {\n      onClick (action) {\n        if (!Array.isArray(this.disabled)) {\n          this.disabled = []\n        }\n\n        if (this.disabled.includes(action)) {\n          this.disabled = this.disabled.filter(item => item !== action)\n        } else {\n          this.disabled.push(action)\n        }\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-confirm-edit/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :options=\"options\"\n    :script=\"script\"\n    name=\"v-avatar\"\n  >\n    <div>\n      <v-confirm-edit v-model=\"value\" v-bind=\"props\">\n        <template v-slot:default=\"{ model: proxyModel, actions }\">\n          <v-card\n            class=\"mx-auto\"\n            max-width=\"320\"\n            title=\"Update Field\"\n          >\n            <template v-slot:text>\n              <v-text-field\n                v-model=\"proxyModel.value\"\n                messages=\"Modify my value\"\n              ></v-text-field>\n            </template>\n\n            <template v-slot:actions>\n              <v-spacer></v-spacer>\n\n              <component :is=\"actions\"></component>\n            </template>\n          </v-card>\n        </template>\n      </v-confirm-edit>\n    </div>\n\n    <template v-slot:configuration>\n      <v-text-field v-model=\"okText\" label=\"Ok text\"></v-text-field>\n      <v-text-field v-model=\"cancelText\" label=\"Cancel text\"></v-text-field>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const model = ref('default')\n  const options = []\n  const value = ref('Egg Plant')\n  const okText = ref('Ok')\n  const cancelText = ref('Cancel')\n\n  const props = computed(() => {\n    return {\n      'ok-text': okText.value === 'Ok' ? undefined : okText.value,\n      'cancel-text': cancelText.value === 'Cancel' ? undefined : cancelText.value,\n      'v-model': 'model',\n    }\n  })\n\n  const slots = computed(() => {\n    return `\n  <template v-slot:default=\"{ model: proxyModel, actions }\">\n    <v-card\n      class=\"mx-auto\"\n      max-width=\"320\"\n      title=\"Update Field\"\n    >\n      <template v-slot:text>\n        <v-text-field\n          v-model=\"proxyModel.value\"\n          messages=\"Modify my value\"\n        ></v-text-field>\n      </template>\n\n      <template v-slot:actions>\n        <v-spacer></v-spacer>\n\n        <component :is=\"actions\"></component>\n      </template>\n    </v-card>\n  </template>\n`\n  })\n\n  const script = computed(() => {\n    return `<script setup>\n  import { shallowRef } from 'vue'\n\n  const model = shallowRef('Egg plant')\n<` + '/script>'\n  })\n\n  const code = computed(() => {\n    return `<v-confirm-edit${propsToString(props.value)}>${slots.value}</v-confirm-edit>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-iterator/misc-filter.vue",
    "content": "<template>\n  <v-card>\n    <v-data-iterator\n      :items=\"games\"\n      :items-per-page=\"3\"\n      :search=\"search\"\n    >\n      <template v-slot:header>\n        <v-toolbar class=\"px-2\">\n          <v-text-field\n            v-model=\"search\"\n            density=\"comfortable\"\n            placeholder=\"Search\"\n            prepend-inner-icon=\"mdi-magnify\"\n            style=\"max-width: 300px;\"\n            variant=\"solo\"\n            clearable\n            hide-details\n          ></v-text-field>\n        </v-toolbar>\n      </template>\n\n      <template v-slot:default=\"{ items }\">\n        <v-container class=\"pa-2\" fluid>\n          <v-row density=\"comfortable\">\n            <v-col\n              v-for=\"item in items\"\n              :key=\"item.title\"\n              cols=\"auto\"\n              md=\"4\"\n            >\n              <v-card class=\"pb-3\" border flat>\n                <v-img :src=\"item.raw.img\"></v-img>\n\n                <v-list-item :subtitle=\"item.raw.subtitle\" class=\"mb-2\">\n                  <template v-slot:title>\n                    <strong class=\"d-block text-title-large py-2 text-truncate\">{{ item.raw.title }}</strong>\n                  </template>\n                </v-list-item>\n\n                <div class=\"d-flex justify-space-between px-4\">\n                  <div class=\"d-flex align-center text-body-small text-medium-emphasis me-1\">\n                    <v-icon icon=\"mdi-clock\" start></v-icon>\n\n                    <div class=\"text-truncate\">{{ item.raw.duration }}</div>\n                  </div>\n\n                  <v-btn\n                    class=\"text-none\"\n                    size=\"small\"\n                    text=\"Read\"\n                    variant=\"flat\"\n                    border\n                  >\n                  </v-btn>\n                </div>\n              </v-card>\n            </v-col>\n          </v-row>\n        </v-container>\n      </template>\n\n      <template v-slot:footer=\"{ page, pageCount, prevPage, nextPage }\">\n        <div class=\"d-flex align-center justify-center pa-4\">\n          <v-btn\n            :disabled=\"page === 1\"\n            density=\"comfortable\"\n            icon=\"mdi-arrow-left\"\n            variant=\"tonal\"\n            rounded\n            @click=\"prevPage\"\n          ></v-btn>\n\n          <div class=\"mx-2 text-body-small\">\n            Page {{ page }} of {{ pageCount }}\n          </div>\n\n          <v-btn\n            :disabled=\"page >= pageCount\"\n            density=\"comfortable\"\n            icon=\"mdi-arrow-right\"\n            variant=\"tonal\"\n            rounded\n            @click=\"nextPage\"\n          ></v-btn>\n        </div>\n      </template>\n    </v-data-iterator>\n  </v-card>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const search = shallowRef('')\n  const games = [\n    {\n      img: 'https://cdn.vuetifyjs.com/docs/images/graphics/games/4.png',\n      title: 'The Sci-Fi Shooter Experience',\n      subtitle: 'Dive into a futuristic world of intense battles and alien encounters.',\n      advanced: false,\n      duration: '8 minutes',\n    },\n    {\n      img: 'https://cdn.vuetifyjs.com/docs/images/graphics/games/2.png',\n      title: 'Epic Adventures in Open Worlds',\n      subtitle: 'Embark on a journey through vast, immersive landscapes and quests.',\n      advanced: true,\n      duration: '10 minutes',\n    },\n    {\n      img: 'https://cdn.vuetifyjs.com/docs/images/graphics/games/3.png',\n      title: 'Surviving the Space Station Horror',\n      subtitle: 'Navigate a haunted space station in this chilling survival horror game.',\n      advanced: false,\n      duration: '9 minutes',\n    },\n    {\n      img: 'https://cdn.vuetifyjs.com/docs/images/graphics/games/5.png',\n      title: 'Neon-Lit High-Speed Racing Thrills',\n      subtitle: 'Experience adrenaline-pumping races in a futuristic, neon-soaked city.',\n      advanced: true,\n      duration: '12 minutes',\n    },\n    {\n      img: 'https://cdn.vuetifyjs.com/docs/images/graphics/games/6.png',\n      title: 'Retro-Style Platformer Adventures',\n      subtitle: 'Jump and dash through pixelated worlds in this classic-style platformer.',\n      advanced: false,\n      duration: '11 minutes',\n    },\n    {\n      img: 'https://cdn.vuetifyjs.com/docs/images/graphics/games/7.png',\n      title: 'Medieval Strategic War Campaigns',\n      subtitle: 'Lead armies into epic battles and conquer kingdoms in this strategic war game.',\n      advanced: true,\n      duration: '10 minutes',\n    },\n    {\n      img: 'https://cdn.vuetifyjs.com/docs/images/graphics/games/1.png',\n      title: 'Underwater VR Exploration Adventure',\n      subtitle: 'Dive deep into the ocean and discover the mysteries of the underwater world.',\n      advanced: true,\n      duration: '11 minutes',\n    },\n    {\n      img: 'https://cdn.vuetifyjs.com/docs/images/graphics/games/8.png',\n      title: '1920s Mystery Detective Chronicles',\n      subtitle: 'Solve crimes and uncover secrets in the glamorous 1920s era.',\n      advanced: false,\n      duration: '9 minutes',\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      search: '',\n      games: [\n        {\n          img: 'https://cdn.vuetifyjs.com/docs/images/graphics/games/4.png',\n          title: 'The Sci-Fi Shooter Experience',\n          subtitle: 'Dive into a futuristic world of intense battles and alien encounters.',\n          advanced: false,\n          duration: '8 minutes',\n        },\n        {\n          img: 'https://cdn.vuetifyjs.com/docs/images/graphics/games/2.png',\n          title: 'Epic Adventures in Open Worlds',\n          subtitle: 'Embark on a journey through vast, immersive landscapes and quests.',\n          advanced: true,\n          duration: '10 minutes',\n        },\n        {\n          img: 'https://cdn.vuetifyjs.com/docs/images/graphics/games/3.png',\n          title: 'Surviving the Space Station Horror',\n          subtitle: 'Navigate a haunted space station in this chilling survival horror game.',\n          advanced: false,\n          duration: '9 minutes',\n        },\n        {\n          img: 'https://cdn.vuetifyjs.com/docs/images/graphics/games/5.png',\n          title: 'Neon-Lit High-Speed Racing Thrills',\n          subtitle: 'Experience adrenaline-pumping races in a futuristic, neon-soaked city.',\n          advanced: true,\n          duration: '12 minutes',\n        },\n        {\n          img: 'https://cdn.vuetifyjs.com/docs/images/graphics/games/6.png',\n          title: 'Retro-Style Platformer Adventures',\n          subtitle: 'Jump and dash through pixelated worlds in this classic-style platformer.',\n          advanced: false,\n          duration: '11 minutes',\n        },\n        {\n          img: 'https://cdn.vuetifyjs.com/docs/images/graphics/games/7.png',\n          title: 'Medieval Strategic War Campaigns',\n          subtitle: 'Lead armies into epic battles and conquer kingdoms in this strategic game.',\n          advanced: true,\n          duration: '10 minutes',\n        },\n        {\n          img: 'https://cdn.vuetifyjs.com/docs/images/graphics/games/1.png',\n          title: 'Underwater VR Exploration Adventure',\n          subtitle: 'Dive deep into the ocean and discover the mysteries of the underwater world.',\n          advanced: true,\n          duration: '11 minutes',\n        },\n        {\n          img: 'https://cdn.vuetifyjs.com/docs/images/graphics/games/8.png',\n          title: '1920s Mystery Detective Chronicles',\n          subtitle: 'Solve crimes and uncover secrets in the glamorous 1920s era.',\n          advanced: false,\n          duration: '9 minutes',\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-iterator/slot-default.vue",
    "content": "<template>\n  <v-data-iterator\n    :items=\"desserts\"\n    item-value=\"name\"\n  >\n    <template v-slot:default=\"{ items, isExpanded, toggleExpand }\">\n      <v-row>\n        <v-col\n          v-for=\"item in items\"\n          :key=\"item.raw.name\"\n          cols=\"12\"\n          md=\"6\"\n          sm=\"12\"\n        >\n          <v-card>\n            <v-card-title class=\"d-flex align-center\">\n              <v-icon\n                :color=\"item.raw.color\"\n                :icon=\"item.raw.icon\"\n                size=\"18\"\n                start\n              ></v-icon>\n\n              <h4 class=\"my-0 text-title-large font-weight-medium\">{{ item.raw.name }}</h4>\n            </v-card-title>\n\n            <v-card-text>\n              {{ item.raw.description }}\n            </v-card-text>\n\n            <div class=\"px-4\">\n              <v-switch\n                :label=\"`${isExpanded(item) ? 'Hide' : 'Show'} details`\"\n                :model-value=\"isExpanded(item)\"\n                density=\"compact\"\n                inset\n                @click=\"() => toggleExpand(item)\"\n              ></v-switch>\n            </div>\n\n            <v-divider></v-divider>\n\n            <v-expand-transition>\n              <div v-if=\"isExpanded(item)\">\n                <v-list :lines=\"false\" density=\"compact\">\n                  <v-list-item :title=\"`🔥 Calories: ${item.raw.calories}`\" active></v-list-item>\n                  <v-list-item :title=\"`🍔 Fat: ${item.raw.fat}`\"></v-list-item>\n                  <v-list-item :title=\"`🍞 Carbs: ${item.raw.carbs}`\"></v-list-item>\n                  <v-list-item :title=\"`🍗 Protein: ${item.raw.protein}`\"></v-list-item>\n                  <v-list-item :title=\"`🧂 Sodium: ${item.raw.sodium}`\"></v-list-item>\n                  <v-list-item :title=\"`🦴 Calcium: ${item.raw.calcium}`\"></v-list-item>\n                  <v-list-item :title=\"`🧲 Iron: ${item.raw.iron}`\"></v-list-item>\n                </v-list>\n              </div>\n            </v-expand-transition>\n          </v-card>\n        </v-col>\n      </v-row>\n    </template>\n  </v-data-iterator>\n</template>\n\n<script setup>\n  const desserts = [\n    {\n      name: 'Frozen Yogurt',\n      description: 'A tangy and creamy dessert made from yogurt and sometimes fruit, Frozen Yogurt is a lighter alternative to ice cream. Perfect for those who crave a sweet treat but want to keep it on the healthier side.',\n      icon: 'mdi-ice-cream',\n      color: '#6EC1E4',\n      calories: 159,\n      fat: 6,\n      carbs: 24,\n      protein: 4,\n      sodium: 87,\n      calcium: '14%',\n      iron: '1%',\n    },\n    {\n      name: 'Ice cream sandwich',\n      description: 'A classic treat featuring a layer of creamy ice cream sandwiched between two cookies or cake layers. Ideal for those hot summer days when you can\\'t decide between a cookie and ice cream.',\n      icon: 'mdi-cookie',\n      color: '#F4A261',\n      calories: 237,\n      fat: 9,\n      carbs: 37,\n      protein: 4.3,\n      sodium: 129,\n      calcium: '8%',\n      iron: '1%',\n    },\n    {\n      name: 'Eclair',\n      description: 'A small, individual cake topped with frosting and often adorned with sprinkles or other decorations. Great for parties or as a quick indulgence when you need a sugar fix.',\n      icon: 'mdi-cake-variant',\n      color: '#6D4C41',\n      calories: 262,\n      fat: 16,\n      carbs: 23,\n      protein: 6,\n      sodium: 337,\n      calcium: '6%',\n      iron: '7%',\n    },\n    {\n      name: 'Cupcake',\n      description: 'A small, individual cake topped with frosting and often adorned with sprinkles or other decorations. Great for parties or as a quick indulgence when you need a sugar fix.',\n      color: '#FFADAD',\n      icon: 'mdi-cupcake',\n      calories: 305,\n      fat: 3.7,\n      carbs: 67,\n      protein: 4.3,\n      sodium: 413,\n      calcium: '3%',\n      iron: '8%',\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      desserts: [\n        {\n          name: 'Frozen Yogurt',\n          description: 'A tangy and creamy dessert made from yogurt and sometimes fruit, Frozen Yogurt is a lighter alternative to ice cream. Perfect for those who crave a sweet treat but want to keep it on the healthier side.',\n          icon: 'mdi-ice-cream',\n          color: '#6EC1E4',\n          calories: 159,\n          fat: 6,\n          carbs: 24,\n          protein: 4,\n          sodium: 87,\n          calcium: '14%',\n          iron: '1%',\n        },\n        {\n          name: 'Ice cream sandwich',\n          description: 'A classic treat featuring a layer of creamy ice cream sandwiched between two cookies or cake layers. Ideal for those hot summer days when you can\\'t decide between a cookie and ice cream.',\n          icon: 'mdi-cookie',\n          color: '#F4A261',\n          calories: 237,\n          fat: 9,\n          carbs: 37,\n          protein: 4.3,\n          sodium: 129,\n          calcium: '8%',\n          iron: '1%',\n        },\n        {\n          name: 'Eclair',\n          description: 'A small, individual cake topped with frosting and often adorned with sprinkles or other decorations. Great for parties or as a quick indulgence when you need a sugar fix.',\n          icon: 'mdi-cake-variant',\n          color: '#6D4C41',\n          calories: 262,\n          fat: 16,\n          carbs: 23,\n          protein: 6,\n          sodium: 337,\n          calcium: '6%',\n          iron: '7%',\n        },\n        {\n          name: 'Cupcake',\n          description: 'A small, individual cake topped with frosting and often adorned with sprinkles or other decorations. Great for parties or as a quick indulgence when you need a sugar fix.',\n          color: '#FFADAD',\n          icon: 'mdi-cupcake',\n          calories: 305,\n          fat: 3.7,\n          carbs: 67,\n          protein: 4.3,\n          sodium: 413,\n          calcium: '3%',\n          iron: '8%',\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-iterator/slot-header-and-footer.vue",
    "content": "<template>\n  <v-data-iterator\n    :items=\"mice\"\n    :items-per-page=\"itemsPerPage\"\n  >\n    <template v-slot:header=\"{ page, pageCount, prevPage, nextPage }\">\n      <h1 class=\"text-headline-large font-weight-bold d-flex justify-space-between mt-0 mb-4 align-center\">\n        <div class=\"text-truncate\">\n          Most popular mice\n        </div>\n\n        <div class=\"d-flex align-center\">\n          <v-btn\n            class=\"me-8\"\n            variant=\"text\"\n            @click=\"onClickSeeAll\"\n          >\n            <span class=\"text-decoration-underline text-none\">See all</span>\n          </v-btn>\n\n          <div class=\"d-inline-flex\">\n            <v-btn\n              :disabled=\"page === 1\"\n              class=\"me-2\"\n              icon=\"mdi-arrow-left\"\n              size=\"small\"\n              variant=\"tonal\"\n              @click=\"prevPage\"\n            ></v-btn>\n\n            <v-btn\n              :disabled=\"page === pageCount\"\n              icon=\"mdi-arrow-right\"\n              size=\"small\"\n              variant=\"tonal\"\n              @click=\"nextPage\"\n            ></v-btn>\n          </div>\n        </div>\n      </h1>\n    </template>\n\n    <template v-slot:default=\"{ items }\">\n      <v-row>\n        <v-col\n          v-for=\"(item, i) in items\"\n          :key=\"i\"\n          cols=\"12\"\n          sm=\"6\"\n          xl=\"3\"\n        >\n          <v-sheet border>\n            <v-img\n              :gradient=\"`to top right, rgba(255, 255, 255, .1), rgba(${item.raw.color}, .15)`\"\n              :src=\"item.raw.src\"\n              height=\"150\"\n              cover\n            ></v-img>\n\n            <v-list-item\n              :title=\"item.raw.name\"\n              density=\"comfortable\"\n              lines=\"two\"\n              subtitle=\"Lorem ipsum dil orei namdie dkaf\"\n            >\n              <template v-slot:title>\n                <strong class=\"d-block text-title-large py-2 text-truncate\">\n                  {{ item.raw.name }}\n                </strong>\n              </template>\n            </v-list-item>\n\n            <v-table class=\"text-body-small\" density=\"compact\">\n              <tbody>\n                <tr align=\"right\">\n                  <th>DPI:</th>\n\n                  <td>{{ item.raw.dpi }}</td>\n                </tr>\n\n                <tr align=\"right\">\n                  <th>Buttons:</th>\n\n                  <td>{{ item.raw.buttons }}</td>\n                </tr>\n\n                <tr align=\"right\">\n                  <th>Weight:</th>\n\n                  <td>{{ item.raw.weight }}</td>\n                </tr>\n\n                <tr align=\"right\">\n                  <th>Wireless:</th>\n\n                  <td>{{ item.raw.wireless ? 'Yes' : 'No' }}</td>\n                </tr>\n\n                <tr align=\"right\">\n                  <th>Price:</th>\n\n                  <td>${{ item.raw.price }}</td>\n                </tr>\n              </tbody>\n            </v-table>\n          </v-sheet>\n        </v-col>\n      </v-row>\n    </template>\n\n    <template v-slot:footer=\"{ page, pageCount }\">\n      <v-footer\n        class=\"justify-space-between text-body-medium mt-4\"\n        color=\"surface-variant\"\n      >\n        Total mice: {{ mice.length }}\n\n        <div>\n          Page {{ page }} of {{ pageCount }}\n        </div>\n      </v-footer>\n    </template>\n  </v-data-iterator>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const itemsPerPage = shallowRef(4)\n  const mice = [\n    {\n      name: 'Logitech G Pro X',\n      color: '14, 151, 210',\n      dpi: 16000,\n      buttons: 8,\n      weight: '63g',\n      wireless: true,\n      price: 149.99,\n      description: 'Logitech G Pro X',\n      src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/3.png',\n    },\n    {\n      name: 'Razer DeathAdder V2',\n      color: '12, 146, 47',\n      dpi: 20000,\n      buttons: 8,\n      weight: '82g',\n      wireless: false,\n      price: 69.99,\n      description: 'Razer DeathAdder V2',\n      src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/2.png',\n    },\n    {\n      name: 'Corsair Dark Core RGB',\n      color: '107, 187, 226',\n      dpi: 18000,\n      buttons: 9,\n      weight: '133g',\n      wireless: true,\n      price: 89.99,\n      description: 'Corsair Dark Core RGB',\n      src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/1.png',\n    },\n    {\n      name: 'SteelSeries Rival 3',\n      color: '228, 196, 69',\n      dpi: 8500,\n      buttons: 6,\n      weight: '77g',\n      wireless: false,\n      price: 29.99,\n      description: 'SteelSeries Rival 3',\n      src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/4.png',\n    },\n    {\n      name: 'HyperX Pulsefire FPS Pro',\n      color: '156, 82, 251',\n      dpi: 16000,\n      buttons: 6,\n      weight: '95g',\n      wireless: false,\n      price: 44.99,\n      description: 'HyperX Pulsefire FPS Pro',\n      src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/6.png',\n    },\n    {\n      name: 'Zowie EC2',\n      color: '166, 39, 222',\n      dpi: 3200,\n      buttons: 5,\n      weight: '90g',\n      wireless: false,\n      price: 69.99,\n      description: 'Zowie EC2',\n      src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/7.png',\n    },\n    {\n      name: 'Roccat Kone AIMO',\n      color: '131, 9, 10',\n      dpi: 16000,\n      buttons: 10,\n      weight: '130g',\n      wireless: false,\n      price: 79.99,\n      description: 'Roccat Kone AIMO',\n      src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/8.png',\n    },\n    {\n      name: 'Logitech G903',\n      color: '232, 94, 102',\n      dpi: 12000,\n      buttons: 11,\n      weight: '110g',\n      wireless: true,\n      price: 129.99,\n      description: 'Logitech G903',\n      src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/9.png',\n    },\n    {\n      name: 'Cooler Master MM711',\n      color: '58, 192, 239',\n      dpi: 16000,\n      buttons: 6,\n      weight: '60g',\n      wireless: false,\n      price: 49.99,\n      description: 'Cooler Master MM711',\n      src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/5.png',\n    },\n    {\n      name: 'Glorious Model O',\n      color: '161, 252, 250',\n      dpi: 12000,\n      buttons: 6,\n      weight: '67g',\n      wireless: false,\n      price: 49.99,\n      description: 'Glorious Model O',\n      src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/15.png',\n    },\n    {\n      name: 'HP Omen Photon',\n      color: '201, 1, 2',\n      dpi: 16000,\n      buttons: 11,\n      weight: '128g',\n      wireless: true,\n      price: 99.99,\n      description: 'HP Omen Photon',\n      src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/10.png',\n    },\n    {\n      name: 'Asus ROG Chakram',\n      color: '10, 181, 19',\n      dpi: 16000,\n      buttons: 9,\n      weight: '121g',\n      wireless: true,\n      price: 159.99,\n      description: 'Asus ROG Chakram',\n      src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/11.png',\n    },\n    {\n      name: 'Razer Naga X',\n      color: '100, 101, 102',\n      dpi: 16000,\n      buttons: 16,\n      weight: '85g',\n      wireless: false,\n      price: 79.99,\n      description: 'Razer Naga X',\n      src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/12.png',\n    },\n    {\n      name: 'Mad Catz R.A.T. 8+',\n      color: '136, 241, 242',\n      dpi: 16000,\n      buttons: 11,\n      weight: '145g',\n      wireless: false,\n      price: 99.99,\n      description: 'Mad Catz R.A.T. 8+',\n      src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/13.png',\n    },\n    {\n      name: 'Alienware 610M',\n      color: '109, 110, 114',\n      dpi: 16000,\n      buttons: 7,\n      weight: '120g',\n      wireless: true,\n      price: 99.99,\n      description: 'Alienware 610M',\n      src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/14.png',\n    },\n  ]\n\n  function onClickSeeAll () {\n    itemsPerPage.value = itemsPerPage.value === 4 ? mice.length : 4\n  }\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        itemsPerPage: 4,\n        mice: [\n          {\n            name: 'Logitech G Pro X',\n            color: '14, 151, 210',\n            dpi: 16000,\n            buttons: 8,\n            weight: '63g',\n            wireless: true,\n            price: 149.99,\n            description: 'Logitech G Pro X',\n            src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/3.png',\n          },\n          {\n            name: 'Razer DeathAdder V2',\n            color: '12, 146, 47',\n            dpi: 20000,\n            buttons: 8,\n            weight: '82g',\n            wireless: false,\n            price: 69.99,\n            description: 'Razer DeathAdder V2',\n            src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/2.png',\n          },\n          {\n            name: 'Corsair Dark Core RGB',\n            color: '107, 187, 226',\n            dpi: 18000,\n            buttons: 9,\n            weight: '133g',\n            wireless: true,\n            price: 89.99,\n            description: 'Corsair Dark Core RGB',\n            src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/1.png',\n          },\n          {\n            name: 'SteelSeries Rival 3',\n            color: '228, 196, 69',\n            dpi: 8500,\n            buttons: 6,\n            weight: '77g',\n            wireless: false,\n            price: 29.99,\n            description: 'SteelSeries Rival 3',\n            src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/4.png',\n          },\n          {\n            name: 'HyperX Pulsefire FPS Pro',\n            color: '156, 82, 251',\n            dpi: 16000,\n            buttons: 6,\n            weight: '95g',\n            wireless: false,\n            price: 44.99,\n            description: 'HyperX Pulsefire FPS Pro',\n            src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/6.png',\n          },\n          {\n            name: 'Zowie EC2',\n            color: '166, 39, 222',\n            dpi: 3200,\n            buttons: 5,\n            weight: '90g',\n            wireless: false,\n            price: 69.99,\n            description: 'Zowie EC2',\n            src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/7.png',\n          },\n          {\n            name: 'Roccat Kone AIMO',\n            color: '131, 9, 10',\n            dpi: 16000,\n            buttons: 10,\n            weight: '130g',\n            wireless: false,\n            price: 79.99,\n            description: 'Roccat Kone AIMO',\n            src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/8.png',\n          },\n          {\n            name: 'Logitech G903',\n            color: '232, 94, 102',\n            dpi: 12000,\n            buttons: 11,\n            weight: '110g',\n            wireless: true,\n            price: 129.99,\n            description: 'Logitech G903',\n            src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/9.png',\n          },\n          {\n            name: 'Cooler Master MM711',\n            color: '58, 192, 239',\n            dpi: 16000,\n            buttons: 6,\n            weight: '60g',\n            wireless: false,\n            price: 49.99,\n            description: 'Cooler Master MM711',\n            src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/5.png',\n          },\n          {\n            name: 'Glorious Model O',\n            color: '161, 252, 250',\n            dpi: 12000,\n            buttons: 6,\n            weight: '67g',\n            wireless: false,\n            price: 49.99,\n            description: 'Glorious Model O',\n            src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/15.png',\n          },\n          {\n            name: 'HP Omen Photon',\n            color: '201, 1, 2',\n            dpi: 16000,\n            buttons: 11,\n            weight: '128g',\n            wireless: true,\n            price: 99.99,\n            description: 'HP Omen Photon',\n            src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/10.png',\n          },\n          {\n            name: 'Asus ROG Chakram',\n            color: '10, 181, 19',\n            dpi: 16000,\n            buttons: 9,\n            weight: '121g',\n            wireless: true,\n            price: 159.99,\n            description: 'Asus ROG Chakram',\n            src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/11.png',\n          },\n          {\n            name: 'Razer Naga X',\n            color: '100, 101, 102',\n            dpi: 16000,\n            buttons: 16,\n            weight: '85g',\n            wireless: false,\n            price: 79.99,\n            description: 'Razer Naga X',\n            src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/12.png',\n          },\n          {\n            name: 'Mad Catz R.A.T. 8+',\n            color: '136, 241, 242',\n            dpi: 16000,\n            buttons: 11,\n            weight: '145g',\n            wireless: false,\n            price: 99.99,\n            description: 'Mad Catz R.A.T. 8+',\n            src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/13.png',\n          },\n          {\n            name: 'Alienware 610M',\n            color: '109, 110, 114',\n            dpi: 16000,\n            buttons: 7,\n            weight: '120g',\n            wireless: true,\n            price: 99.99,\n            description: 'Alienware 610M',\n            src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/14.png',\n          },\n        ],\n      }\n    },\n    methods: {\n      onClickSeeAll () {\n        this.itemsPerPage = this.itemsPerPage === 4 ? this.mice.length : 4\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-iterator/slot-loader.vue",
    "content": "<template>\n  <v-data-iterator\n    :items=\"mice\"\n    :items-per-page=\"itemsPerPage\"\n    :loading=\"true\"\n  >\n    <template v-slot:default=\"{ items }\">\n      <v-row>\n        <v-col\n          v-for=\"(item, i) in items\"\n          :key=\"i\"\n          cols=\"12\"\n          sm=\"6\"\n          xl=\"3\"\n        >\n          <v-sheet border>\n            <v-img\n              :gradient=\"`to top right, rgba(255, 255, 255, .1), rgba(${item.raw.color}, .15)`\"\n              :src=\"item.raw.src\"\n              height=\"150\"\n              cover\n            ></v-img>\n\n            <v-list-item\n              :title=\"item.raw.name\"\n              density=\"comfortable\"\n              lines=\"two\"\n              subtitle=\"Lorem ipsum dil orei namdie dkaf\"\n            >\n              <template v-slot:title>\n                <strong class=\"text-title-large\">\n                  {{ item.raw.name }}\n                </strong>\n              </template>\n            </v-list-item>\n\n            <v-table class=\"text-body-small\" density=\"compact\">\n              <tbody>\n                <tr align=\"right\">\n                  <th>DPI:</th>\n\n                  <td>{{ item.raw.dpi }}</td>\n                </tr>\n\n                <tr align=\"right\">\n                  <th>Buttons:</th>\n\n                  <td>{{ item.raw.buttons }}</td>\n                </tr>\n\n                <tr align=\"right\">\n                  <th>Weight:</th>\n\n                  <td>{{ item.raw.weight }}</td>\n                </tr>\n\n                <tr align=\"right\">\n                  <th>Wireless:</th>\n\n                  <td>{{ item.raw.wireless ? 'Yes' : 'No' }}</td>\n                </tr>\n\n                <tr align=\"right\">\n                  <th>Price:</th>\n\n                  <td>${{ item.raw.price }}</td>\n                </tr>\n              </tbody>\n            </v-table>\n          </v-sheet>\n        </v-col>\n      </v-row>\n    </template>\n\n    <template v-slot:loader>\n      <v-row>\n        <v-col\n          v-for=\"(_, k) in [0, 1, 2, 3]\"\n          :key=\"k\"\n          cols=\"12\"\n          sm=\"6\"\n          xl=\"3\"\n        >\n          <v-skeleton-loader\n            class=\"border\"\n            type=\"image, article\"\n          ></v-skeleton-loader>\n        </v-col>\n      </v-row>\n    </template>\n\n  </v-data-iterator>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const itemsPerPage = shallowRef(4)\n  const mice = [\n    {\n      name: 'Logitech G Pro X',\n      color: '14, 151, 210',\n      dpi: 16000,\n      buttons: 8,\n      weight: '63g',\n      wireless: true,\n      price: 149.99,\n      description: 'Logitech G Pro X',\n      src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/1.png',\n    },\n    {\n      name: 'Razer DeathAdder V2',\n      color: '12, 146, 47',\n      dpi: 20000,\n      buttons: 8,\n      weight: '82g',\n      wireless: false,\n      price: 69.99,\n      description: 'Razer DeathAdder V2',\n      src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/2.png',\n    },\n    {\n      name: 'Corsair Dark Core RGB',\n      color: '107, 187, 226',\n      dpi: 18000,\n      buttons: 9,\n      weight: '133g',\n      wireless: true,\n      price: 89.99,\n      description: 'Corsair Dark Core RGB',\n      src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/3.png',\n    },\n    {\n      name: 'SteelSeries Rival 3',\n      color: '228, 196, 69',\n      dpi: 8500,\n      buttons: 6,\n      weight: '77g',\n      wireless: false,\n      price: 29.99,\n      description: 'SteelSeries Rival 3',\n      src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/4.png',\n    },\n    {\n      name: 'HyperX Pulsefire FPS Pro',\n      color: '156, 82, 251',\n      dpi: 16000,\n      buttons: 6,\n      weight: '95g',\n      wireless: false,\n      price: 44.99,\n      description: 'HyperX Pulsefire FPS Pro',\n      src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/5.png',\n    },\n    {\n      name: 'Zowie EC2',\n      color: '166, 39, 222',\n      dpi: 3200,\n      buttons: 5,\n      weight: '90g',\n      wireless: false,\n      price: 69.99,\n      description: 'Zowie EC2',\n      src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/6.png',\n    },\n    {\n      name: 'Roccat Kone AIMO',\n      color: '131, 9, 10',\n      dpi: 16000,\n      buttons: 10,\n      weight: '130g',\n      wireless: false,\n      price: 79.99,\n      description: 'Roccat Kone AIMO',\n      src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/7.png',\n    },\n    {\n      name: 'Logitech G903',\n      color: '232, 94, 102',\n      dpi: 12000,\n      buttons: 11,\n      weight: '110g',\n      wireless: true,\n      price: 129.99,\n      description: 'Logitech G903',\n      src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/8.png',\n    },\n    {\n      name: 'Cooler Master MM711',\n      color: '58, 192, 239',\n      dpi: 16000,\n      buttons: 6,\n      weight: '60g',\n      wireless: false,\n      price: 49.99,\n      description: 'Cooler Master MM711',\n      src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/9.png',\n    },\n    {\n      name: 'Glorious Model O',\n      color: '161, 252, 250',\n      dpi: 12000,\n      buttons: 6,\n      weight: '67g',\n      wireless: false,\n      price: 49.99,\n      description: 'Glorious Model O',\n      src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/10.png',\n    },\n    {\n      name: 'HP Omen Photon',\n      color: '201, 1, 2',\n      dpi: 16000,\n      buttons: 11,\n      weight: '128g',\n      wireless: true,\n      price: 99.99,\n      description: 'HP Omen Photon',\n      src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/11.png',\n    },\n    {\n      name: 'Asus ROG Chakram',\n      color: '10, 181, 19',\n      dpi: 16000,\n      buttons: 9,\n      weight: '121g',\n      wireless: true,\n      price: 159.99,\n      description: 'Asus ROG Chakram',\n      src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/12.png',\n    },\n    {\n      name: 'Razer Naga X',\n      color: '100, 101, 102',\n      dpi: 16000,\n      buttons: 16,\n      weight: '85g',\n      wireless: false,\n      price: 79.99,\n      description: 'Razer Naga X',\n      src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/13.png',\n    },\n    {\n      name: 'Mad Catz R.A.T. 8+',\n      color: '136, 241, 242',\n      dpi: 16000,\n      buttons: 11,\n      weight: '145g',\n      wireless: false,\n      price: 99.99,\n      description: 'Mad Catz R.A.T. 8+',\n      src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/14.png',\n    },\n    {\n      name: 'Alienware 610M',\n      color: '109, 110, 114',\n      dpi: 16000,\n      buttons: 7,\n      weight: '120g',\n      wireless: true,\n      price: 99.99,\n      description: 'Alienware 610M',\n      src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/15.png',\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        itemsPerPage: 4,\n        mice: [\n          {\n            name: 'Logitech G Pro X',\n            color: '14, 151, 210',\n            dpi: 16000,\n            buttons: 8,\n            weight: '63g',\n            wireless: true,\n            price: 149.99,\n            description: 'Logitech G Pro X',\n            src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/1.png',\n          },\n          {\n            name: 'Razer DeathAdder V2',\n            color: '12, 146, 47',\n            dpi: 20000,\n            buttons: 8,\n            weight: '82g',\n            wireless: false,\n            price: 69.99,\n            description: 'Razer DeathAdder V2',\n            src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/2.png',\n          },\n          {\n            name: 'Corsair Dark Core RGB',\n            color: '107, 187, 226',\n            dpi: 18000,\n            buttons: 9,\n            weight: '133g',\n            wireless: true,\n            price: 89.99,\n            description: 'Corsair Dark Core RGB',\n            src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/3.png',\n          },\n          {\n            name: 'SteelSeries Rival 3',\n            color: '228, 196, 69',\n            dpi: 8500,\n            buttons: 6,\n            weight: '77g',\n            wireless: false,\n            price: 29.99,\n            description: 'SteelSeries Rival 3',\n            src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/4.png',\n          },\n          {\n            name: 'HyperX Pulsefire FPS Pro',\n            color: '156, 82, 251',\n            dpi: 16000,\n            buttons: 6,\n            weight: '95g',\n            wireless: false,\n            price: 44.99,\n            description: 'HyperX Pulsefire FPS Pro',\n            src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/5.png',\n          },\n          {\n            name: 'Zowie EC2',\n            color: '166, 39, 222',\n            dpi: 3200,\n            buttons: 5,\n            weight: '90g',\n            wireless: false,\n            price: 69.99,\n            description: 'Zowie EC2',\n            src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/6.png',\n          },\n          {\n            name: 'Roccat Kone AIMO',\n            color: '131, 9, 10',\n            dpi: 16000,\n            buttons: 10,\n            weight: '130g',\n            wireless: false,\n            price: 79.99,\n            description: 'Roccat Kone AIMO',\n            src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/7.png',\n          },\n          {\n            name: 'Logitech G903',\n            color: '232, 94, 102',\n            dpi: 12000,\n            buttons: 11,\n            weight: '110g',\n            wireless: true,\n            price: 129.99,\n            description: 'Logitech G903',\n            src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/8.png',\n          },\n          {\n            name: 'Cooler Master MM711',\n            color: '58, 192, 239',\n            dpi: 16000,\n            buttons: 6,\n            weight: '60g',\n            wireless: false,\n            price: 49.99,\n            description: 'Cooler Master MM711',\n            src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/9.png',\n          },\n          {\n            name: 'Glorious Model O',\n            color: '161, 252, 250',\n            dpi: 12000,\n            buttons: 6,\n            weight: '67g',\n            wireless: false,\n            price: 49.99,\n            description: 'Glorious Model O',\n            src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/10.png',\n          },\n          {\n            name: 'HP Omen Photon',\n            color: '201, 1, 2',\n            dpi: 16000,\n            buttons: 11,\n            weight: '128g',\n            wireless: true,\n            price: 99.99,\n            description: 'HP Omen Photon',\n            src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/11.png',\n          },\n          {\n            name: 'Asus ROG Chakram',\n            color: '10, 181, 19',\n            dpi: 16000,\n            buttons: 9,\n            weight: '121g',\n            wireless: true,\n            price: 159.99,\n            description: 'Asus ROG Chakram',\n            src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/12.png',\n          },\n          {\n            name: 'Razer Naga X',\n            color: '100, 101, 102',\n            dpi: 16000,\n            buttons: 16,\n            weight: '85g',\n            wireless: false,\n            price: 79.99,\n            description: 'Razer Naga X',\n            src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/13.png',\n          },\n          {\n            name: 'Mad Catz R.A.T. 8+',\n            color: '136, 241, 242',\n            dpi: 16000,\n            buttons: 11,\n            weight: '145g',\n            wireless: false,\n            price: 99.99,\n            description: 'Mad Catz R.A.T. 8+',\n            src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/14.png',\n          },\n          {\n            name: 'Alienware 610M',\n            color: '109, 110, 114',\n            dpi: 16000,\n            buttons: 7,\n            weight: '120g',\n            wireless: true,\n            price: 99.99,\n            description: 'Alienware 610M',\n            src: 'https://cdn.vuetifyjs.com/docs/images/graphics/mice/15.png',\n          },\n        ],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-iterator/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n    :script=\"script\"\n  >\n    <div>\n      <v-data-iterator\n        v-bind=\"props\"\n        :items=\"cards\"\n        :page=\"page\"\n      >\n        <template v-slot:default=\"{ items }\">\n          <template\n            v-for=\"(item, i) in items\"\n            :key=\"i\"\n          >\n            <v-card v-bind=\"item.raw\"></v-card>\n\n            <br>\n          </template>\n        </template>\n\n        <template v-slot:footer=\"{ pageCount }\">\n          <v-pagination v-model=\"page\" :length=\"pageCount\"></v-pagination>\n        </template>\n      </v-data-iterator>\n    </div>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-data-iterator'\n  const model = ref('default')\n  const options = []\n\n  const page = ref(1)\n\n  const cards = Array.from({ length: 15 }, (k, v) => ({\n    title: `Item ${v + 1}`,\n    text: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!',\n  }))\n\n  const props = computed(() => {\n    return {\n      'items-per-page': 3,\n    }\n  })\n\n  const slots = computed(() => {\n    return `\n  <template v-slot:default=\"{ items }\">\n    <template\n      v-for=\"(item, i) in items\"\n      :key=\"i\"\n    >\n      <v-card v-bind=\"item.raw\"></v-card>\n\n      <br>\n    </template>\n  </template>\n  <template v-slot:footer=\"{ pageCount }\">\n    <v-pagination v-model=\"page\" :length=\"pageCount\"></v-pagination>\n  </template>\n`\n  })\n\n  const code = computed(() => {\n    return `<v-data-iterator :items=\"items\" :page=\"page\"${propsToString(props.value, ['items'])}>${slots.value}</v-data-iterator>`\n  })\n\n  const script = computed(() => {\n    return `<script setup>\n  import { ref } from 'vue'\n\n  const page = ref(1)\n  const items = Array.from({ length: 15 }, (k, v) => ({\n    title: 'Item ' + v + 1,\n    text: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!',\n  }))\n<` + '/script>'\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/headers-multiple.vue",
    "content": "<template>\n  <v-data-table\n    :headers=\"headers\"\n    :items=\"items\"\n    item-key=\"name\"\n    hide-default-footer\n  ></v-data-table>\n</template>\n\n<script setup>\n  const headers = [\n    { title: 'Pyramid', value: 'name' },\n    { title: 'Location', value: 'location' },\n    { title: 'Construction Date', value: 'constructionDate' },\n    {\n      title: 'Dimensions',\n      align: 'center',\n      children: [\n        { title: 'Height(m)', value: 'height' },\n        { title: 'Base(m)', value: 'base' },\n        { title: 'Volume(m³)', value: 'volume' },\n      ],\n    },\n  ]\n\n  const items = [\n    {\n      name: 'Great Pyramid of Giza',\n      location: 'Egypt',\n      height: '146.6',\n      base: '230.4',\n      volume: '2583285',\n      constructionDate: 'c. 2580–2560 BC',\n    },\n    {\n      name: 'Pyramid of Khafre',\n      location: 'Egypt',\n      height: '136.4',\n      base: '215.3',\n      volume: '1477485',\n      constructionDate: 'c. 2570 BC',\n    },\n    {\n      name: 'Red Pyramid',\n      location: 'Egypt',\n      height: '104',\n      base: '220',\n      volume: '1602895',\n      constructionDate: 'c. 2590 BC',\n    },\n    {\n      name: 'Bent Pyramid',\n      location: 'Egypt',\n      height: '101.1',\n      base: '188.6',\n      volume: '1200690',\n      constructionDate: 'c. 2600 BC',\n    },\n    {\n      name: 'Pyramid of the Sun',\n      location: 'Mexico',\n      height: '65',\n      base: '225',\n      volume: '1237097',\n      constructionDate: 'c. 200 CE',\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      headers: [\n        { title: 'Pyramid', value: 'name' },\n        { title: 'Location', value: 'location' },\n        { title: 'Construction Date', value: 'constructionDate' },\n        {\n          title: 'Dimensions',\n          align: 'center',\n          children: [\n            { title: 'Height(m)', value: 'height' },\n            { title: 'Base(m)', value: 'base' },\n            { title: 'Volume(m³)', value: 'volume' },\n          ],\n        },\n      ],\n      items: [\n        {\n          name: 'Great Pyramid of Giza',\n          location: 'Egypt',\n          height: '146.6',\n          base: '230.4',\n          volume: '2583285',\n          constructionDate: 'c. 2580–2560 BC',\n        },\n        {\n          name: 'Pyramid of Khafre',\n          location: 'Egypt',\n          height: '136.4',\n          base: '215.3',\n          volume: '1477485',\n          constructionDate: 'c. 2570 BC',\n        },\n        {\n          name: 'Red Pyramid',\n          location: 'Egypt',\n          height: '104',\n          base: '220',\n          volume: '1602895',\n          constructionDate: 'c. 2590 BC',\n        },\n        {\n          name: 'Bent Pyramid',\n          location: 'Egypt',\n          height: '101.1',\n          base: '188.6',\n          volume: '1200690',\n          constructionDate: 'c. 2600 BC',\n        },\n        {\n          name: 'Pyramid of the Sun',\n          location: 'Mexico',\n          height: '65',\n          base: '225',\n          volume: '1237097',\n          constructionDate: 'c. 200 CE',\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/misc-crud.vue",
    "content": "<template>\n  <v-sheet border rounded>\n    <v-data-table\n      :headers=\"headers\"\n      :hide-default-footer=\"books.length < 11\"\n      :items=\"books\"\n    >\n      <template v-slot:top>\n        <v-toolbar flat>\n          <v-toolbar-title>\n            <v-icon color=\"medium-emphasis\" icon=\"mdi-book-multiple\" size=\"x-small\" start></v-icon>\n\n            Popular books\n          </v-toolbar-title>\n\n          <v-btn\n            class=\"me-2\"\n            prepend-icon=\"mdi-plus\"\n            rounded=\"lg\"\n            text=\"Add a Book\"\n            border\n            @click=\"add\"\n          ></v-btn>\n        </v-toolbar>\n      </template>\n\n      <template v-slot:item.title=\"{ value }\">\n        <v-chip :text=\"value\" border=\"thin opacity-25\" prepend-icon=\"mdi-book\" label>\n          <template v-slot:prepend>\n            <v-icon color=\"medium-emphasis\"></v-icon>\n          </template>\n        </v-chip>\n      </template>\n\n      <template v-slot:item.actions=\"{ item }\">\n        <div class=\"d-flex ga-2 justify-end\">\n          <v-icon color=\"medium-emphasis\" icon=\"mdi-pencil\" size=\"small\" @click=\"edit(item.id)\"></v-icon>\n\n          <v-icon color=\"medium-emphasis\" icon=\"mdi-delete\" size=\"small\" @click=\"remove(item.id)\"></v-icon>\n        </div>\n      </template>\n\n      <template v-slot:no-data>\n        <v-btn\n          prepend-icon=\"mdi-backup-restore\"\n          rounded=\"lg\"\n          text=\"Reset data\"\n          variant=\"text\"\n          border\n          @click=\"reset\"\n        ></v-btn>\n      </template>\n    </v-data-table>\n  </v-sheet>\n\n  <v-dialog v-model=\"dialog\" max-width=\"500\">\n    <v-card\n      :subtitle=\"`${isEditing ? 'Update' : 'Create'} your favorite book`\"\n      :title=\"`${isEditing ? 'Edit' : 'Add'} a Book`\"\n    >\n      <template v-slot:text>\n        <v-row>\n          <v-col cols=\"12\">\n            <v-text-field v-model=\"formModel.title\" label=\"Title\"></v-text-field>\n          </v-col>\n\n          <v-col cols=\"12\" md=\"6\">\n            <v-text-field v-model=\"formModel.author\" label=\"Author\"></v-text-field>\n          </v-col>\n\n          <v-col cols=\"12\" md=\"6\">\n            <v-select v-model=\"formModel.genre\" :items=\"['Fiction', 'Dystopian', 'Non-Fiction', 'Sci-Fi']\" label=\"Genre\"></v-select>\n          </v-col>\n\n          <v-col cols=\"12\" md=\"6\">\n            <v-number-input v-model=\"formModel.year\" :max=\"currentYear\" :min=\"1\" label=\"Year\"></v-number-input>\n          </v-col>\n\n          <v-col cols=\"12\" md=\"6\">\n            <v-number-input v-model=\"formModel.pages\" :min=\"1\" label=\"Pages\"></v-number-input>\n          </v-col>\n        </v-row>\n      </template>\n\n      <v-divider></v-divider>\n\n      <v-card-actions class=\"bg-surface-light\">\n        <v-btn text=\"Cancel\" variant=\"plain\" @click=\"dialog = false\"></v-btn>\n\n        <v-spacer></v-spacer>\n\n        <v-btn text=\"Save\" @click=\"save\"></v-btn>\n      </v-card-actions>\n    </v-card>\n  </v-dialog>\n</template>\n\n<script setup>\n  import { onMounted, ref, shallowRef, toRef } from 'vue'\n\n  const currentYear = new Date().getFullYear()\n\n  function createNewRecord () {\n    return {\n      title: '',\n      author: '',\n      genre: '',\n      year: currentYear,\n      pages: 1,\n    }\n  }\n\n  const books = ref([])\n  const formModel = ref(createNewRecord())\n  const dialog = shallowRef(false)\n  const isEditing = toRef(() => !!formModel.value.id)\n\n  const headers = [\n    { title: 'Title', key: 'title', align: 'start' },\n    { title: 'Author', key: 'author' },\n    { title: 'Genre', key: 'genre' },\n    { title: 'Year', key: 'year', align: 'end' },\n    { title: 'Pages', key: 'pages', align: 'end' },\n    { title: 'Actions', key: 'actions', align: 'end', sortable: false },\n  ]\n\n  onMounted(() => {\n    reset()\n  })\n\n  function add () {\n    formModel.value = createNewRecord()\n    dialog.value = true\n  }\n\n  function edit (id) {\n    const found = books.value.find(book => book.id === id)\n\n    formModel.value = {\n      id: found.id,\n      title: found.title,\n      author: found.author,\n      genre: found.genre,\n      year: found.year,\n      pages: found.pages,\n    }\n\n    dialog.value = true\n  }\n\n  function remove (id) {\n    const index = books.value.findIndex(book => book.id === id)\n    books.value.splice(index, 1)\n  }\n\n  function save () {\n    if (isEditing.value) {\n      const index = books.value.findIndex(book => book.id === formModel.value.id)\n      books.value[index] = formModel.value\n    } else {\n      formModel.value.id = books.value.length + 1\n      books.value.push(formModel.value)\n    }\n\n    dialog.value = false\n  }\n\n  function reset () {\n    dialog.value = false\n    formModel.value = createNewRecord()\n    books.value = [\n      { id: 1, title: 'To Kill a Mockingbird', author: 'Harper Lee', genre: 'Fiction', year: 1960, pages: 281 },\n      { id: 2, title: '1984', author: 'George Orwell', genre: 'Dystopian', year: 1949, pages: 328 },\n      { id: 3, title: 'The Great Gatsby', author: 'F. Scott Fitzgerald', genre: 'Fiction', year: 1925, pages: 180 },\n      { id: 4, title: 'Sapiens', author: 'Yuval Noah Harari', genre: 'Non-Fiction', year: 2011, pages: 443 },\n      { id: 5, title: 'Dune', author: 'Frank Herbert', genre: 'Sci-Fi', year: 1965, pages: 412 },\n    ]\n  }\n</script>\n\n<script>\n  const currentYear = new Date().getFullYear()\n\n  function createNewRecord () {\n    return {\n      title: '',\n      author: '',\n      genre: '',\n      year: currentYear,\n      pages: 1,\n    }\n  }\n\n  export default {\n    data () {\n      return {\n        currentYear,\n        books: [],\n        formModel: createNewRecord(),\n        dialog: false,\n        headers: [\n          { title: 'Title', key: 'title', align: 'start' },\n          { title: 'Author', key: 'author' },\n          { title: 'Genre', key: 'genre' },\n          { title: 'Year', key: 'year', align: 'end' },\n          { title: 'Pages', key: 'pages', align: 'end' },\n          { title: 'Actions', key: 'actions', align: 'end', sortable: false },\n        ],\n      }\n    },\n    computed: {\n      isEditing () {\n        return !!this.formModel.id\n      },\n    },\n    mounted () {\n      this.reset()\n    },\n    methods: {\n      add () {\n        this.formModel = createNewRecord()\n        this.dialog = true\n      },\n      edit (id) {\n        const found = this.books.find(book => book.id === id)\n        this.formModel = { ...found }\n        this.dialog = true\n      },\n      remove (id) {\n        const index = this.books.findIndex(book => book.id === id)\n        this.books.splice(index, 1)\n      },\n      save () {\n        if (this.isEditing) {\n          const index = this.books.findIndex(book => book.id === this.formModel.id)\n          this.books[index] = { ...this.formModel }\n        } else {\n          this.formModel.id = this.books.length + 1\n          this.books.push({ ...this.formModel })\n        }\n        this.dialog = false\n      },\n      reset () {\n        this.dialog = false\n        this.formModel = createNewRecord()\n        this.books = [\n          { id: 1, title: 'To Kill a Mockingbird', author: 'Harper Lee', genre: 'Fiction', year: 1960, pages: 281 },\n          { id: 2, title: '1984', author: 'George Orwell', genre: 'Dystopian', year: 1949, pages: 328 },\n          { id: 3, title: 'The Great Gatsby', author: 'F. Scott Fitzgerald', genre: 'Fiction', year: 1925, pages: 180 },\n          { id: 4, title: 'Sapiens', author: 'Yuval Noah Harari', genre: 'Non-Fiction', year: 2011, pages: 443 },\n          { id: 5, title: 'Dune', author: 'Frank Herbert', genre: 'Sci-Fi', year: 1965, pages: 412 },\n        ]\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/misc-edit-dialog.vue",
    "content": "<template>\n  <div>\n    <v-data-table\n      :headers=\"headers\"\n      :items=\"desserts\"\n    >\n      <template v-slot:item.name=\"props\">\n        <v-edit-dialog\n          v-model:return-value=\"props.item.name\"\n          @cancel=\"cancel\"\n          @close=\"close\"\n          @open=\"open\"\n          @save=\"save\"\n        >\n          {{ props.item.name }}\n          <template v-slot:input>\n            <v-text-field\n              v-model=\"props.item.name\"\n              :rules=\"[max25chars]\"\n              label=\"Edit\"\n              counter\n              single-line\n            ></v-text-field>\n          </template>\n        </v-edit-dialog>\n      </template>\n      <template v-slot:item.iron=\"props\">\n        <v-edit-dialog\n          v-model:return-value=\"props.item.iron\"\n          large\n          persistent\n          @cancel=\"cancel\"\n          @close=\"close\"\n          @open=\"open\"\n          @save=\"save\"\n        >\n          <div>{{ props.item.iron }}</div>\n          <template v-slot:input>\n            <div class=\"mt-4 text-title-large\">\n              Update Iron\n            </div>\n            <v-text-field\n              v-model=\"props.item.iron\"\n              :rules=\"[max25chars]\"\n              label=\"Edit\"\n              autofocus\n              counter\n              single-line\n            ></v-text-field>\n          </template>\n        </v-edit-dialog>\n      </template>\n    </v-data-table>\n\n    <v-snackbar\n      v-model=\"snack\"\n      :color=\"snackColor\"\n      :timeout=\"3000\"\n    >\n      {{ snackText }}\n\n      <template v-slot:actions>\n        <v-btn @click=\"snack = false\">\n          Close\n        </v-btn>\n      </template>\n    </v-snackbar>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const snack = ref(false)\n  const snackColor = ref('')\n  const snackText = ref('')\n  const max25chars = ref(v => v.length <= 25 || 'Input too long!')\n  const headers = ref([\n    {\n      text: 'Dessert (100g serving)',\n      align: 'start',\n      sortable: false,\n      value: 'name',\n    },\n    { text: 'Calories', value: 'calories' },\n    { text: 'Fat (g)', value: 'fat' },\n    { text: 'Carbs (g)', value: 'carbs' },\n    { text: 'Protein (g)', value: 'protein' },\n    { text: 'Iron (%)', value: 'iron' },\n  ])\n  const desserts = ref([\n    {\n      name: 'Frozen Yogurt',\n      calories: 159,\n      fat: 6,\n      carbs: 24,\n      protein: 4,\n      iron: 1,\n    },\n    {\n      name: 'Ice cream sandwich',\n      calories: 237,\n      fat: 9,\n      carbs: 37,\n      protein: 4.3,\n      iron: 1,\n    },\n    {\n      name: 'Eclair',\n      calories: 262,\n      fat: 16,\n      carbs: 23,\n      protein: 6,\n      iron: 7,\n    },\n    {\n      name: 'Cupcake',\n      calories: 305,\n      fat: 3.7,\n      carbs: 67,\n      protein: 4.3,\n      iron: 8,\n    },\n    {\n      name: 'Gingerbread',\n      calories: 356,\n      fat: 16,\n      carbs: 49,\n      protein: 3.9,\n      iron: 16,\n    },\n    {\n      name: 'Jelly bean',\n      calories: 375,\n      fat: 0,\n      carbs: 94,\n      protein: 0,\n      iron: 0,\n    },\n    {\n      name: 'Lollipop',\n      calories: 392,\n      fat: 0.2,\n      carbs: 98,\n      protein: 0,\n      iron: 2,\n    },\n    {\n      name: 'Honeycomb',\n      calories: 408,\n      fat: 3.2,\n      carbs: 87,\n      protein: 6.5,\n      iron: 45,\n    },\n    {\n      name: 'Donut',\n      calories: 452,\n      fat: 25,\n      carbs: 51,\n      protein: 4.9,\n      iron: 22,\n    },\n    {\n      name: 'KitKat',\n      calories: 518,\n      fat: 26,\n      carbs: 65,\n      protein: 7,\n      iron: 6,\n    },\n  ])\n  function save () {\n    snack.value = true\n    snackColor.value = 'success'\n    snackText.value = 'Data saved'\n  }\n  function cancel () {\n    snack.value = true\n    snackColor.value = 'error'\n    snackText.value = 'Canceled'\n  }\n  function open () {\n    snack.value = true\n    snackColor.value = 'info'\n    snackText.value = 'Dialog opened'\n  }\n  function close () {\n    console.log('Dialog closed')\n  }\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        snack: false,\n        snackColor: '',\n        snackText: '',\n        max25chars: v => v.length <= 25 || 'Input too long!',\n        headers: [\n          {\n            text: 'Dessert (100g serving)',\n            align: 'start',\n            sortable: false,\n            value: 'name',\n          },\n          { text: 'Calories', value: 'calories' },\n          { text: 'Fat (g)', value: 'fat' },\n          { text: 'Carbs (g)', value: 'carbs' },\n          { text: 'Protein (g)', value: 'protein' },\n          { text: 'Iron (%)', value: 'iron' },\n        ],\n        desserts: [\n          {\n            name: 'Frozen Yogurt',\n            calories: 159,\n            fat: 6.0,\n            carbs: 24,\n            protein: 4.0,\n            iron: 1,\n          },\n          {\n            name: 'Ice cream sandwich',\n            calories: 237,\n            fat: 9.0,\n            carbs: 37,\n            protein: 4.3,\n            iron: 1,\n          },\n          {\n            name: 'Eclair',\n            calories: 262,\n            fat: 16.0,\n            carbs: 23,\n            protein: 6.0,\n            iron: 7,\n          },\n          {\n            name: 'Cupcake',\n            calories: 305,\n            fat: 3.7,\n            carbs: 67,\n            protein: 4.3,\n            iron: 8,\n          },\n          {\n            name: 'Gingerbread',\n            calories: 356,\n            fat: 16.0,\n            carbs: 49,\n            protein: 3.9,\n            iron: 16,\n          },\n          {\n            name: 'Jelly bean',\n            calories: 375,\n            fat: 0.0,\n            carbs: 94,\n            protein: 0.0,\n            iron: 0,\n          },\n          {\n            name: 'Lollipop',\n            calories: 392,\n            fat: 0.2,\n            carbs: 98,\n            protein: 0,\n            iron: 2,\n          },\n          {\n            name: 'Honeycomb',\n            calories: 408,\n            fat: 3.2,\n            carbs: 87,\n            protein: 6.5,\n            iron: 45,\n          },\n          {\n            name: 'Donut',\n            calories: 452,\n            fat: 25.0,\n            carbs: 51,\n            protein: 4.9,\n            iron: 22,\n          },\n          {\n            name: 'KitKat',\n            calories: 518,\n            fat: 26.0,\n            carbs: 65,\n            protein: 7,\n            iron: 6,\n          },\n        ],\n      }\n    },\n    methods: {\n      save () {\n        this.snack = true\n        this.snackColor = 'success'\n        this.snackText = 'Data saved'\n      },\n      cancel () {\n        this.snack = true\n        this.snackColor = 'error'\n        this.snackText = 'Canceled'\n      },\n      open () {\n        this.snack = true\n        this.snackColor = 'info'\n        this.snackText = 'Dialog opened'\n      },\n      close () {\n        console.log('Dialog closed')\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/misc-expand.vue",
    "content": "<template>\n  <v-data-table\n    :headers=\"headers\"\n    :items=\"movies\"\n    item-value=\"title\"\n    hide-default-footer\n    show-expand\n  >\n    <template v-slot:item.data-table-expand=\"{ internalItem, isExpanded, toggleExpand }\">\n      <v-btn\n        :append-icon=\"isExpanded(internalItem) ? 'mdi-chevron-up' : 'mdi-chevron-down'\"\n        :text=\"isExpanded(internalItem) ? 'Collapse' : 'More info'\"\n        class=\"text-none\"\n        color=\"medium-emphasis\"\n        size=\"small\"\n        variant=\"text\"\n        width=\"105\"\n        border\n        slim\n        @click=\"toggleExpand(internalItem)\"\n      ></v-btn>\n    </template>\n\n    <template v-slot:expanded-row=\"{ columns, item }\">\n      <tr>\n        <td :colspan=\"columns.length\" class=\"py-2\">\n          <v-sheet rounded=\"lg\" border>\n            <v-table density=\"compact\">\n              <tbody class=\"bg-surface-light\">\n                <tr>\n                  <th>Rating</th>\n                  <th>Synopsis</th>\n                  <th>Cast</th>\n                </tr>\n              </tbody>\n\n              <tbody>\n                <tr>\n                  <td class=\"py-2\">\n                    <v-rating\n                      :model-value=\"item.details.rating\"\n                      color=\"orange-darken-2\"\n                      density=\"comfortable\"\n                      size=\"small\"\n                      half-increments\n                      readonly\n                    ></v-rating>\n                  </td>\n                  <td class=\"py-2\">{{ item.details.synopsis }}</td>\n                  <td class=\"py-2\">{{ item.details.cast.join(', ') }}</td>\n                </tr>\n              </tbody>\n            </v-table>\n          </v-sheet>\n        </td>\n      </tr>\n    </template>\n  </v-data-table>\n</template>\n\n<script setup>\n  const headers = [\n    { width: 300, title: 'Title', key: 'title', align: 'start', sortable: true },\n    { width: 250, title: 'Director', key: 'director' },\n    { width: 150, title: 'Genre', key: 'genre' },\n    { width: 100, title: 'Year', key: 'year', align: 'end' },\n    { width: 140, title: 'Runtime(min)', key: 'runtime', align: 'end' },\n    { width: 1, key: 'data-table-expand', align: 'end' }, // optional, to keep it as short as possible\n  ]\n\n  const movies = [\n    {\n      title: 'The Shawshank Redemption',\n      director: 'Frank Darabont',\n      genre: 'Drama',\n      year: 1994,\n      runtime: 142,\n      details: {\n        synopsis: 'Two imprisoned men bond over years, finding solace and redemption through acts of decency.',\n        cast: ['Tim Robbins', 'Morgan Freeman'],\n        rating: 3.5,\n      },\n    },\n    {\n      title: 'Inception',\n      director: 'Christopher Nolan',\n      genre: 'Sci-Fi',\n      year: 2010,\n      runtime: 148,\n      details: {\n        synopsis: 'A thief with the ability to enter dreams is tasked with stealing a secret from the subconscious.',\n        cast: ['Leonardo DiCaprio', 'Joseph Gordon-Levitt'],\n        rating: 5,\n      },\n    },\n    {\n      title: 'The Godfather',\n      director: 'Francis Ford Coppola',\n      genre: 'Crime',\n      year: 1972,\n      runtime: 175,\n      details: {\n        synopsis: 'The aging patriarch of a crime dynasty transfers control to his reluctant son.',\n        cast: ['Marlon Brando', 'Al Pacino'],\n        rating: 4.5,\n      },\n    },\n    {\n      title: 'Pulp Fiction',\n      director: 'Quentin Tarantino',\n      genre: 'Crime',\n      year: 1994,\n      runtime: 154,\n      details: {\n        synopsis: 'Interwoven stories of criminals, violence, and redemption in Los Angeles.',\n        cast: ['John Travolta', 'Samuel L. Jackson'],\n        rating: 4.5,\n      },\n    },\n    {\n      title: 'The Dark Knight',\n      director: 'Christopher Nolan',\n      genre: 'Action',\n      year: 2008,\n      runtime: 152,\n      details: {\n        synopsis: 'When the menace known as the Joker wreaks havoc and chaos on the people of Gotham, Batman must accept one of the greatest psychological and physical tests of his ability to fight injustice.',\n        cast: ['Christian Bale', 'Heath Ledger'],\n        rating: 4,\n      },\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      headers: [\n        { width: 300, title: 'Title', key: 'title', align: 'start', sortable: true },\n        { width: 250, title: 'Director', key: 'director' },\n        { width: 150, title: 'Genre', key: 'genre' },\n        { width: 100, title: 'Year', key: 'year', align: 'end' },\n        { width: 140, title: 'Runtime(min)', key: 'runtime', align: 'end' },\n        { width: 1, key: 'data-table-expand', align: 'end' }, // optional, to keep it as short as possible\n      ],\n      movies: [\n        {\n          title: 'The Shawshank Redemption',\n          director: 'Frank Darabont',\n          genre: 'Drama',\n          year: 1994,\n          runtime: 142,\n          details: {\n            synopsis: 'Two imprisoned men bond over years, finding solace and redemption through acts of decency.',\n            cast: ['Tim Robbins', 'Morgan Freeman'],\n            rating: 3.5,\n          },\n        },\n        {\n          title: 'Inception',\n          director: 'Christopher Nolan',\n          genre: 'Sci-Fi',\n          year: 2010,\n          runtime: 148,\n          details: {\n            synopsis: 'A thief with the ability to enter dreams is tasked with stealing a secret from the subconscious.',\n            cast: ['Leonardo DiCaprio', 'Joseph Gordon-Levitt'],\n            rating: 5,\n          },\n        },\n        {\n          title: 'The Godfather',\n          director: 'Francis Ford Coppola',\n          genre: 'Crime',\n          year: 1972,\n          runtime: 175,\n          details: {\n            synopsis: 'The aging patriarch of a crime dynasty transfers control to his reluctant son.',\n            cast: ['Marlon Brando', 'Al Pacino'],\n            rating: 4.5,\n          },\n        },\n        {\n          title: 'Pulp Fiction',\n          director: 'Quentin Tarantino',\n          genre: 'Crime',\n          year: 1994,\n          runtime: 154,\n          details: {\n            synopsis: 'Interwoven stories of criminals, violence, and redemption in Los Angeles.',\n            cast: ['John Travolta', 'Samuel L. Jackson'],\n            rating: 4.5,\n          },\n        },\n        {\n          title: 'The Dark Knight',\n          director: 'Christopher Nolan',\n          genre: 'Action',\n          year: 2008,\n          runtime: 152,\n          details: {\n            synopsis: 'When the menace known as the Joker wreaks havoc and chaos on the people of Gotham, Batman must accept one of the greatest psychological and physical tests of his ability to fight injustice.',\n            cast: ['Christian Bale', 'Heath Ledger'],\n            rating: 4,\n          },\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/misc-external-paginate.vue",
    "content": "<template>\n  <v-data-table\n    v-model:page=\"page\"\n    :headers=\"headers\"\n    :items=\"desserts\"\n    :items-per-page=\"itemsPerPage\"\n  >\n    <template v-slot:top>\n      <v-number-input\n        v-model=\"itemsPerPage\"\n        :max=\"15\"\n        :min=\"-1\"\n        class=\"pa-2\"\n        label=\"Items per page\"\n        hide-details\n      ></v-number-input>\n    </template>\n\n    <template v-slot:bottom>\n      <div class=\"text-center pt-2\">\n        <v-pagination\n          v-model=\"page\"\n          :length=\"pageCount\"\n        ></v-pagination>\n      </div>\n    </template>\n  </v-data-table>\n</template>\n\n<script setup>\n  import { computed, ref } from 'vue'\n\n  const page = ref(1)\n  const itemsPerPage = ref(5)\n  const headers = ref([\n    {\n      align: 'start',\n      key: 'name',\n      sortable: false,\n      title: 'Dessert (100g serving)',\n    },\n    { title: 'Calories', key: 'calories' },\n    { title: 'Fat (g)', key: 'fat' },\n    { title: 'Carbs (g)', key: 'carbs' },\n    { title: 'Protein (g)', key: 'protein' },\n    { title: 'Iron (%)', key: 'iron' },\n  ])\n  const desserts = ref([\n    { name: 'Frozen Yogurt', calories: 159, fat: 6, carbs: 24, protein: 4, iron: 1 },\n    { name: 'Ice cream sandwich', calories: 237, fat: 9, carbs: 37, protein: 4.3, iron: 1 },\n    { name: 'Eclair', calories: 262, fat: 16, carbs: 23, protein: 6, iron: 7 },\n    { name: 'Cupcake', calories: 305, fat: 3.7, carbs: 67, protein: 4.3, iron: 8 },\n    { name: 'Gingerbread', calories: 356, fat: 16, carbs: 49, protein: 3.9, iron: 16 },\n    { name: 'Jelly bean', calories: 375, fat: 0, carbs: 94, protein: 0, iron: 0 },\n    { name: 'Lollipop', calories: 392, fat: 0.2, carbs: 98, protein: 0, iron: 2 },\n    { name: 'Honeycomb', calories: 408, fat: 3.2, carbs: 87, protein: 6.5, iron: 45 },\n    { name: 'Donut', calories: 452, fat: 25, carbs: 51, protein: 4.9, iron: 22 },\n    { name: 'KitKat', calories: 518, fat: 26, carbs: 65, protein: 7, iron: 6 },\n  ])\n  const pageCount = computed(() => {\n    return Math.ceil(desserts.value.length / itemsPerPage.value)\n  })\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        page: 1,\n        itemsPerPage: 5,\n        headers: [\n          {\n            align: 'start',\n            key: 'name',\n            sortable: false,\n            title: 'Dessert (100g serving)',\n          },\n          { title: 'Calories', key: 'calories' },\n          { title: 'Fat (g)', key: 'fat' },\n          { title: 'Carbs (g)', key: 'carbs' },\n          { title: 'Protein (g)', key: 'protein' },\n          { title: 'Iron (%)', key: 'iron' },\n        ],\n        desserts: [\n          { name: 'Frozen Yogurt', calories: 159, fat: 6, carbs: 24, protein: 4, iron: 1 },\n          { name: 'Ice cream sandwich', calories: 237, fat: 9, carbs: 37, protein: 4.3, iron: 1 },\n          { name: 'Eclair', calories: 262, fat: 16, carbs: 23, protein: 6, iron: 7 },\n          { name: 'Cupcake', calories: 305, fat: 3.7, carbs: 67, protein: 4.3, iron: 8 },\n          { name: 'Gingerbread', calories: 356, fat: 16, carbs: 49, protein: 3.9, iron: 16 },\n          { name: 'Jelly bean', calories: 375, fat: 0, carbs: 94, protein: 0, iron: 0 },\n          { name: 'Lollipop', calories: 392, fat: 0.2, carbs: 98, protein: 0, iron: 2 },\n          { name: 'Honeycomb', calories: 408, fat: 3.2, carbs: 87, protein: 6.5, iron: 45 },\n          { name: 'Donut', calories: 452, fat: 25, carbs: 51, protein: 4.9, iron: 22 },\n          { name: 'KitKat', calories: 518, fat: 26, carbs: 65, protein: 7, iron: 6 },\n        ],\n      }\n    },\n    computed: {\n      pageCount () {\n        return Math.ceil(this.desserts.length / this.itemsPerPage)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/misc-external-sort.vue",
    "content": "<template>\n  <div>\n    <v-data-table\n      v-model:sort-by=\"sortBy\"\n      :headers=\"headers\"\n      :items=\"desserts\"\n      class=\"elevation-1\"\n    ></v-data-table>\n    <div class=\"text-center pt-2\">\n      <v-btn\n        class=\"me-2\"\n        color=\"primary\"\n        @click=\"toggleOrder\"\n      >\n        Toggle sort order\n      </v-btn>\n      <v-btn\n        color=\"primary\"\n        @click=\"nextSort\"\n      >\n        Sort next column\n      </v-btn>\n    </div>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const sortBy = ref([{ key: 'fat', order: 'asc' }])\n  const headers = ref([\n    {\n      title: 'Dessert (100g serving)',\n      align: 'start',\n      key: 'name',\n    },\n    { title: 'Calories', key: 'calories' },\n    { title: 'Fat (g)', key: 'fat' },\n    { title: 'Carbs (g)', key: 'carbs' },\n    { title: 'Protein (g)', key: 'protein' },\n    { title: 'Iron (%)', key: 'iron' },\n  ])\n  const desserts = ref([\n    {\n      name: 'Frozen Yogurt',\n      calories: 159,\n      fat: 6,\n      carbs: 24,\n      protein: 4,\n      iron: 1,\n    },\n    {\n      name: 'Ice cream sandwich',\n      calories: 237,\n      fat: 9,\n      carbs: 37,\n      protein: 4.3,\n      iron: 1,\n    },\n    {\n      name: 'Eclair',\n      calories: 262,\n      fat: 16,\n      carbs: 23,\n      protein: 6,\n      iron: 7,\n    },\n    {\n      name: 'Cupcake',\n      calories: 305,\n      fat: 3.7,\n      carbs: 67,\n      protein: 4.3,\n      iron: 8,\n    },\n    {\n      name: 'Gingerbread',\n      calories: 356,\n      fat: 16,\n      carbs: 49,\n      protein: 3.9,\n      iron: 16,\n    },\n    {\n      name: 'Jelly bean',\n      calories: 375,\n      fat: 0,\n      carbs: 94,\n      protein: 0,\n      iron: 0,\n    },\n    {\n      name: 'Lollipop',\n      calories: 392,\n      fat: 0.2,\n      carbs: 98,\n      protein: 0,\n      iron: 2,\n    },\n    {\n      name: 'Honeycomb',\n      calories: 408,\n      fat: 3.2,\n      carbs: 87,\n      protein: 6.5,\n      iron: 45,\n    },\n    {\n      name: 'Donut',\n      calories: 452,\n      fat: 25,\n      carbs: 51,\n      protein: 4.9,\n      iron: 22,\n    },\n    {\n      name: 'KitKat',\n      calories: 518,\n      fat: 26,\n      carbs: 65,\n      protein: 7,\n      iron: 6,\n    },\n  ])\n  function toggleOrder () {\n    sortBy.value = [{ key: sortBy.value[0].key, order: sortBy.value[0].order === 'asc' ? 'desc' : 'asc' }]\n  }\n  function nextSort () {\n    let index = headers.value.findIndex(h => h.key === sortBy.value[0].key)\n    index = (index + 1) % headers.value.length\n    sortBy.value = [{ key: headers.value[index].key, order: 'asc' }]\n  }\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        sortBy: [{ key: 'fat', order: 'asc' }],\n        headers: [\n          {\n            title: 'Dessert (100g serving)',\n            align: 'start',\n            key: 'name',\n          },\n          { title: 'Calories', key: 'calories' },\n          { title: 'Fat (g)', key: 'fat' },\n          { title: 'Carbs (g)', key: 'carbs' },\n          { title: 'Protein (g)', key: 'protein' },\n          { title: 'Iron (%)', key: 'iron' },\n        ],\n        desserts: [\n          {\n            name: 'Frozen Yogurt',\n            calories: 159,\n            fat: 6.0,\n            carbs: 24,\n            protein: 4.0,\n            iron: 1,\n          },\n          {\n            name: 'Ice cream sandwich',\n            calories: 237,\n            fat: 9.0,\n            carbs: 37,\n            protein: 4.3,\n            iron: 1,\n          },\n          {\n            name: 'Eclair',\n            calories: 262,\n            fat: 16.0,\n            carbs: 23,\n            protein: 6.0,\n            iron: 7,\n          },\n          {\n            name: 'Cupcake',\n            calories: 305,\n            fat: 3.7,\n            carbs: 67,\n            protein: 4.3,\n            iron: 8,\n          },\n          {\n            name: 'Gingerbread',\n            calories: 356,\n            fat: 16.0,\n            carbs: 49,\n            protein: 3.9,\n            iron: 16,\n          },\n          {\n            name: 'Jelly bean',\n            calories: 375,\n            fat: 0.0,\n            carbs: 94,\n            protein: 0.0,\n            iron: 0,\n          },\n          {\n            name: 'Lollipop',\n            calories: 392,\n            fat: 0.2,\n            carbs: 98,\n            protein: 0,\n            iron: 2,\n          },\n          {\n            name: 'Honeycomb',\n            calories: 408,\n            fat: 3.2,\n            carbs: 87,\n            protein: 6.5,\n            iron: 45,\n          },\n          {\n            name: 'Donut',\n            calories: 452,\n            fat: 25.0,\n            carbs: 51,\n            protein: 4.9,\n            iron: 22,\n          },\n          {\n            name: 'KitKat',\n            calories: 518,\n            fat: 26.0,\n            carbs: 65,\n            protein: 7,\n            iron: 6,\n          },\n        ],\n      }\n    },\n    methods: {\n      toggleOrder () {\n        this.sortBy = [{ key: this.sortBy[0].key, order: this.sortBy[0].order === 'asc' ? 'desc' : 'asc' }]\n      },\n      nextSort () {\n        let index = this.headers.findIndex(h => h.key === this.sortBy[0].key)\n        index = (index + 1) % this.headers.length\n        this.sortBy = [{ key: this.headers[index].key, order: 'asc' }]\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/misc-select-all.vue",
    "content": "<template>\n  <v-data-table\n    v-model=\"selected\"\n    :items=\"items\"\n    item-value=\"name\"\n    tabindex=\"0\"\n    show-select\n    @keydown.ctrl.a.prevent=\"onKeydownA\"\n    @keydown.meta.a.prevent=\"onKeydownA\"\n  ></v-data-table>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const selected = ref([])\n\n  const items = [\n    { name: 'Alice Johnson', email: 'alice@example.com', age: 42 },\n    { name: 'Bob Smith', email: 'bob@example.com', age: 36 },\n    { name: 'Charlie Davis', email: 'charlie@example.com', age: 24 },\n    { name: 'Diana Prince', email: 'diana@example.com', age: 30 },\n  ]\n\n  function onKeydownA () {\n    selected.value = selected.value.length === 0 ? items.map(item => item.name) : []\n  }\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        items: [\n          { name: 'Alice Johnson', email: 'alice@example.com', age: 42 },\n          { name: 'Bob Smith', email: 'bob@example.com', age: 36 },\n          { name: 'Charlie Davis', email: 'charlie@example.com', age: 24 },\n          { name: 'Diana Prince', email: 'diana@example.com', age: 30 },\n        ],\n        selected: [],\n      }\n    },\n    methods: {\n      onKeydownA () {\n        this.selected = this.selected.value.length === 0 ? items.map(item => item.name) : []\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/misc-server-side-paginate-and-sort.vue",
    "content": "<template>\n  <v-data-table-server\n    v-model:items-per-page=\"itemsPerPage\"\n    :headers=\"headers\"\n    :items=\"serverItems\"\n    :items-length=\"totalItems\"\n    :loading=\"loading\"\n    :search=\"search\"\n    item-value=\"name\"\n    @update:options=\"loadItems\"\n  ></v-data-table-server>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const desserts = [\n    {\n      name: 'Frozen Yogurt',\n      calories: 159,\n      fat: 6,\n      carbs: 24,\n      protein: 4,\n      iron: '1',\n    },\n    {\n      name: 'Jelly bean',\n      calories: 375,\n      fat: 0,\n      carbs: 94,\n      protein: 0,\n      iron: '0',\n    },\n    {\n      name: 'KitKat',\n      calories: 518,\n      fat: 26,\n      carbs: 65,\n      protein: 7,\n      iron: '6',\n    },\n    {\n      name: 'Eclair',\n      calories: 262,\n      fat: 16,\n      carbs: 23,\n      protein: 6,\n      iron: '7',\n    },\n    {\n      name: 'Gingerbread',\n      calories: 356,\n      fat: 16,\n      carbs: 49,\n      protein: 3.9,\n      iron: '16',\n    },\n    {\n      name: 'Ice cream sandwich',\n      calories: 237,\n      fat: 9,\n      carbs: 37,\n      protein: 4.3,\n      iron: '1',\n    },\n    {\n      name: 'Lollipop',\n      calories: 392,\n      fat: 0.2,\n      carbs: 98,\n      protein: 0,\n      iron: '2',\n    },\n    {\n      name: 'Cupcake',\n      calories: 305,\n      fat: 3.7,\n      carbs: 67,\n      protein: 4.3,\n      iron: '8',\n    },\n    {\n      name: 'Honeycomb',\n      calories: 408,\n      fat: 3.2,\n      carbs: 87,\n      protein: 6.5,\n      iron: '45',\n    },\n    {\n      name: 'Donut',\n      calories: 452,\n      fat: 25,\n      carbs: 51,\n      protein: 4.9,\n      iron: '22',\n    },\n  ]\n  const FakeAPI = {\n    async fetch ({ page, itemsPerPage, sortBy }) {\n      return new Promise(resolve => {\n        setTimeout(() => {\n          const start = (page - 1) * itemsPerPage\n          const end = start + itemsPerPage\n          const items = desserts.slice()\n          if (sortBy.length) {\n            const sortKey = sortBy[0].key\n            const sortOrder = sortBy[0].order\n            items.sort((a, b) => {\n              const aValue = a[sortKey]\n              const bValue = b[sortKey]\n              return sortOrder === 'desc' ? bValue - aValue : aValue - bValue\n            })\n          }\n          const paginated = items.slice(start, end === -1 ? undefined : end)\n          resolve({ items: paginated, total: items.length })\n        }, 500)\n      })\n    },\n  }\n  const itemsPerPage = ref(5)\n  const headers = ref([\n    {\n      title: 'Dessert (100g serving)',\n      align: 'start',\n      sortable: false,\n      key: 'name',\n    },\n    { title: 'Calories', key: 'calories', align: 'end' },\n    { title: 'Fat (g)', key: 'fat', align: 'end' },\n    { title: 'Carbs (g)', key: 'carbs', align: 'end' },\n    { title: 'Protein (g)', key: 'protein', align: 'end' },\n    { title: 'Iron (%)', key: 'iron', align: 'end' },\n  ])\n  const search = ref('')\n  const serverItems = ref([])\n  const loading = ref(true)\n  const totalItems = ref(0)\n  function loadItems ({ page, itemsPerPage, sortBy }) {\n    loading.value = true\n    FakeAPI.fetch({ page, itemsPerPage, sortBy }).then(({ items, total }) => {\n      serverItems.value = items\n      totalItems.value = total\n      loading.value = false\n    })\n  }\n</script>\n\n<script>\n  const desserts = [\n    {\n      name: 'Frozen Yogurt',\n      calories: 159,\n      fat: 6.0,\n      carbs: 24,\n      protein: 4.0,\n      iron: '1',\n    },\n    {\n      name: 'Jelly bean',\n      calories: 375,\n      fat: 0.0,\n      carbs: 94,\n      protein: 0.0,\n      iron: '0',\n    },\n    {\n      name: 'KitKat',\n      calories: 518,\n      fat: 26.0,\n      carbs: 65,\n      protein: 7,\n      iron: '6',\n    },\n    {\n      name: 'Eclair',\n      calories: 262,\n      fat: 16.0,\n      carbs: 23,\n      protein: 6.0,\n      iron: '7',\n    },\n    {\n      name: 'Gingerbread',\n      calories: 356,\n      fat: 16.0,\n      carbs: 49,\n      protein: 3.9,\n      iron: '16',\n    },\n    {\n      name: 'Ice cream sandwich',\n      calories: 237,\n      fat: 9.0,\n      carbs: 37,\n      protein: 4.3,\n      iron: '1',\n    },\n    {\n      name: 'Lollipop',\n      calories: 392,\n      fat: 0.2,\n      carbs: 98,\n      protein: 0,\n      iron: '2',\n    },\n    {\n      name: 'Cupcake',\n      calories: 305,\n      fat: 3.7,\n      carbs: 67,\n      protein: 4.3,\n      iron: '8',\n    },\n    {\n      name: 'Honeycomb',\n      calories: 408,\n      fat: 3.2,\n      carbs: 87,\n      protein: 6.5,\n      iron: '45',\n    },\n    {\n      name: 'Donut',\n      calories: 452,\n      fat: 25.0,\n      carbs: 51,\n      protein: 4.9,\n      iron: '22',\n    },\n  ]\n\n  const FakeAPI = {\n    async fetch ({ page, itemsPerPage, sortBy }) {\n      return new Promise(resolve => {\n        setTimeout(() => {\n          const start = (page - 1) * itemsPerPage\n          const end = start + itemsPerPage\n          const items = desserts.slice()\n\n          if (sortBy.length) {\n            const sortKey = sortBy[0].key\n            const sortOrder = sortBy[0].order\n            items.sort((a, b) => {\n              const aValue = a[sortKey]\n              const bValue = b[sortKey]\n              return sortOrder === 'desc' ? bValue - aValue : aValue - bValue\n            })\n          }\n\n          const paginated = items.slice(start, end)\n\n          resolve({ items: paginated, total: items.length })\n        }, 500)\n      })\n    },\n  }\n\n  export default {\n    data: () => ({\n      itemsPerPage: 5,\n      headers: [\n        {\n          title: 'Dessert (100g serving)',\n          align: 'start',\n          sortable: false,\n          key: 'name',\n        },\n        { title: 'Calories', key: 'calories', align: 'end' },\n        { title: 'Fat (g)', key: 'fat', align: 'end' },\n        { title: 'Carbs (g)', key: 'carbs', align: 'end' },\n        { title: 'Protein (g)', key: 'protein', align: 'end' },\n        { title: 'Iron (%)', key: 'iron', align: 'end' },\n      ],\n      search: '',\n      serverItems: [],\n      loading: true,\n      totalItems: 0,\n    }),\n    methods: {\n      loadItems ({ page, itemsPerPage, sortBy }) {\n        this.loading = true\n        FakeAPI.fetch({ page, itemsPerPage, sortBy }).then(({ items, total }) => {\n          this.serverItems = items\n          this.totalItems = total\n          this.loading = false\n        })\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/prop-custom-filter.vue",
    "content": "<template>\n  <v-data-table\n    :custom-filter=\"filterOnlyCapsText\"\n    :headers=\"headers\"\n    :items=\"items\"\n    :search=\"search\"\n    item-value=\"name\"\n  >\n    <template v-slot:top>\n      <v-text-field\n        v-model=\"search\"\n        class=\"pa-2\"\n        label=\"Search (UPPER CASE ONLY)\"\n      ></v-text-field>\n    </template>\n  </v-data-table>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const search = ref('')\n  const headers = [\n    {\n      title: 'CPU Model',\n      align: 'start',\n      key: 'name',\n    },\n    {\n      title: 'Cores',\n      align: 'end',\n      key: 'cores',\n    },\n    {\n      title: 'Threads',\n      align: 'end',\n      key: 'threads',\n    },\n    {\n      title: 'Base Clock',\n      align: 'end',\n      key: 'baseClock',\n    },\n    {\n      title: 'Boost Clock',\n      align: 'end',\n      key: 'boostClock',\n    },\n    {\n      title: 'TDP (W)',\n      align: 'end',\n      key: 'tdp',\n    },\n  ]\n  const items = [\n    {\n      name: 'Intel Core i9-11900K',\n      cores: 8,\n      threads: 16,\n      baseClock: '3.5 GHz',\n      boostClock: '5.3 GHz',\n      tdp: '125W',\n    },\n    {\n      name: 'AMD Ryzen 9 5950X',\n      cores: 16,\n      threads: 32,\n      baseClock: '3.4 GHz',\n      boostClock: '4.9 GHz',\n      tdp: '105W',\n    },\n    {\n      name: 'Intel Core i7-10700K',\n      cores: 8,\n      threads: 16,\n      baseClock: '3.8 GHz',\n      boostClock: '5.1 GHz',\n      tdp: '125W',\n    },\n    {\n      name: 'AMD Ryzen 5 5600X',\n      cores: 6,\n      threads: 12,\n      baseClock: '3.7 GHz',\n      boostClock: '4.6 GHz',\n      tdp: '65W',\n    },\n    {\n      name: 'Intel Core i5-10600K',\n      cores: 6,\n      threads: 12,\n      baseClock: '4.1 GHz',\n      boostClock: '4.8 GHz',\n      tdp: '125W',\n    },\n    {\n      name: 'AMD Ryzen 7 5800X',\n      cores: 8,\n      threads: 16,\n      baseClock: '3.8 GHz',\n      boostClock: '4.7 GHz',\n      tdp: '105W',\n    },\n    {\n      name: 'Intel Core i3-10100',\n      cores: 4,\n      threads: 8,\n      baseClock: '3.6 GHz',\n      boostClock: '4.3 GHz',\n      tdp: '65W',\n    },\n    {\n      name: 'AMD Ryzen 3 3300X',\n      cores: 4,\n      threads: 8,\n      baseClock: '3.8 GHz',\n      boostClock: '4.3 GHz',\n      tdp: '65W',\n    },\n    {\n      name: 'Intel Pentium Gold G6400',\n      cores: 2,\n      threads: 4,\n      baseClock: '4.0 GHz',\n      tdp: '58W',\n    },\n    {\n      name: 'AMD Athlon 3000G',\n      cores: 2,\n      threads: 4,\n      baseClock: '3.5 GHz',\n      tdp: '35W',\n    },\n  ]\n\n  function filterOnlyCapsText (value, query, item) {\n    return value != null && query != null && typeof value === 'string' && value.toString().toLocaleUpperCase().indexOf(query) !== -1\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      search: '',\n      headers: [\n        {\n          title: 'CPU Model',\n          align: 'start',\n          key: 'name',\n        },\n        {\n          title: 'Cores',\n          align: 'end',\n          key: 'cores',\n        },\n        {\n          title: 'Threads',\n          align: 'end',\n          key: 'threads',\n        },\n        {\n          title: 'Base Clock',\n          align: 'end',\n          key: 'baseClock',\n        },\n        {\n          title: 'Boost Clock',\n          align: 'end',\n          key: 'boostClock',\n        },\n        {\n          title: 'TDP (W)',\n          align: 'end',\n          key: 'tdp',\n        },\n      ],\n      items: [\n        {\n          name: 'Intel Core i9-11900K',\n          cores: 8,\n          threads: 16,\n          baseClock: '3.5 GHz',\n          boostClock: '5.3 GHz',\n          tdp: '125W',\n        },\n        {\n          name: 'AMD Ryzen 9 5950X',\n          cores: 16,\n          threads: 32,\n          baseClock: '3.4 GHz',\n          boostClock: '4.9 GHz',\n          tdp: '105W',\n        },\n        {\n          name: 'Intel Core i7-10700K',\n          cores: 8,\n          threads: 16,\n          baseClock: '3.8 GHz',\n          boostClock: '5.1 GHz',\n          tdp: '125W',\n        },\n        {\n          name: 'AMD Ryzen 5 5600X',\n          cores: 6,\n          threads: 12,\n          baseClock: '3.7 GHz',\n          boostClock: '4.6 GHz',\n          tdp: '65W',\n        },\n        {\n          name: 'Intel Core i5-10600K',\n          cores: 6,\n          threads: 12,\n          baseClock: '4.1 GHz',\n          boostClock: '4.8 GHz',\n          tdp: '125W',\n        },\n        {\n          name: 'AMD Ryzen 7 5800X',\n          cores: 8,\n          threads: 16,\n          baseClock: '3.8 GHz',\n          boostClock: '4.7 GHz',\n          tdp: '105W',\n        },\n        {\n          name: 'Intel Core i3-10100',\n          cores: 4,\n          threads: 8,\n          baseClock: '3.6 GHz',\n          boostClock: '4.3 GHz',\n          tdp: '65W',\n        },\n        {\n          name: 'AMD Ryzen 3 3300X',\n          cores: 4,\n          threads: 8,\n          baseClock: '3.8 GHz',\n          boostClock: '4.3 GHz',\n          tdp: '65W',\n        },\n        {\n          name: 'Intel Pentium Gold G6400',\n          cores: 2,\n          threads: 4,\n          baseClock: '4.0 GHz',\n          tdp: '58W',\n        },\n        {\n          name: 'AMD Athlon 3000G',\n          cores: 2,\n          threads: 4,\n          baseClock: '3.5 GHz',\n          tdp: '35W',\n        },\n      ],\n    }),\n\n    methods: {\n      filterOnlyCapsText (value, query, item) {\n        return value != null &&\n          query != null &&\n          typeof value === 'string' &&\n          value.toString().toLocaleUpperCase().indexOf(query) !== -1\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/prop-dense.vue",
    "content": "<template>\n  <v-data-table\n    :headers=\"headers\"\n    :items=\"plants\"\n    density=\"compact\"\n    item-key=\"name\"\n  ></v-data-table>\n</template>\n\n<script setup>\n  const headers = [\n    { title: 'Plant', align: 'start', sortable: false, key: 'name' },\n    { title: 'Light', align: 'end', key: 'light' },\n    { title: 'Height', align: 'end', key: 'height' },\n    { title: 'Pet Friendly', align: 'end', key: 'petFriendly' },\n    { title: 'Price ($)', align: 'end', key: 'price' },\n  ]\n\n  const plants = [\n    {\n      name: 'Fern',\n      light: 'Low',\n      height: '20cm',\n      petFriendly: 'Yes',\n      price: 20,\n    },\n    {\n      name: 'Snake Plant',\n      light: 'Low',\n      height: '50cm',\n      petFriendly: 'No',\n      price: 35,\n    },\n    {\n      name: 'Monstera',\n      light: 'Medium',\n      height: '60cm',\n      petFriendly: 'No',\n      price: 50,\n    },\n    {\n      name: 'Pothos',\n      light: 'Low to medium',\n      height: '40cm',\n      petFriendly: 'Yes',\n      price: 25,\n    },\n    {\n      name: 'ZZ Plant',\n      light: 'Low to medium',\n      height: '90cm',\n      petFriendly: 'Yes',\n      price: 30,\n    },\n    {\n      name: 'Spider Plant',\n      light: 'Bright, indirect',\n      height: '30cm',\n      petFriendly: 'Yes',\n      price: 15,\n    },\n    {\n      name: 'Air Plant',\n      light: 'Bright, indirect',\n      height: '15cm',\n      petFriendly: 'Yes',\n      price: 10,\n    },\n    {\n      name: 'Peperomia',\n      light: 'Bright, indirect',\n      height: '25cm',\n      petFriendly: 'Yes',\n      price: 20,\n    },\n    {\n      name: 'Aloe Vera',\n      light: 'Bright, direct',\n      height: '30cm',\n      petFriendly: 'Yes',\n      price: 15,\n    },\n    {\n      name: 'Jade Plant',\n      light: 'Bright, direct',\n      height: '40cm',\n      petFriendly: 'Yes',\n      price: 25,\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      headers: [\n        { title: 'Plant', align: 'start', sortable: false, key: 'name' },\n        { title: 'Light', align: 'end', key: 'light' },\n        { title: 'Height', align: 'end', key: 'height' },\n        { title: 'Pet Friendly', align: 'end', key: 'petFriendly' },\n        { title: 'Price ($)', align: 'end', key: 'price' },\n      ],\n      plants: [\n        {\n          name: 'Fern',\n          light: 'Low',\n          height: '20cm',\n          petFriendly: 'Yes',\n          price: 20,\n        },\n        {\n          name: 'Snake Plant',\n          light: 'Low',\n          height: '50cm',\n          petFriendly: 'No',\n          price: 35,\n        },\n        {\n          name: 'Monstera',\n          light: 'Medium',\n          height: '60cm',\n          petFriendly: 'No',\n          price: 50,\n        },\n        {\n          name: 'Pothos',\n          light: 'Low to medium',\n          height: '40cm',\n          petFriendly: 'Yes',\n          price: 25,\n        },\n        {\n          name: 'ZZ Plant',\n          light: 'Low to medium',\n          height: '90cm',\n          petFriendly: 'Yes',\n          price: 30,\n        },\n        {\n          name: 'Spider Plant',\n          light: 'Bright, indirect',\n          height: '30cm',\n          petFriendly: 'Yes',\n          price: 15,\n        },\n        {\n          name: 'Air Plant',\n          light: 'Bright, indirect',\n          height: '15cm',\n          petFriendly: 'Yes',\n          price: 10,\n        },\n        {\n          name: 'Peperomia',\n          light: 'Bright, indirect',\n          height: '25cm',\n          petFriendly: 'Yes',\n          price: 20,\n        },\n        {\n          name: 'Aloe Vera',\n          light: 'Bright, direct',\n          height: '30cm',\n          petFriendly: 'Yes',\n          price: 15,\n        },\n        {\n          name: 'Jade Plant',\n          light: 'Bright, direct',\n          height: '40cm',\n          petFriendly: 'Yes',\n          price: 25,\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/prop-filter-keys.vue",
    "content": "<template>\n  <v-card flat>\n    <v-card-title class=\"d-flex align-center pe-2\">\n      <v-icon icon=\"mdi-video-input-component\"></v-icon> &nbsp;\n      Find a Graphics Card\n\n      <v-spacer></v-spacer>\n\n      <v-text-field\n        v-model=\"search\"\n        density=\"compact\"\n        label=\"Search\"\n        prepend-inner-icon=\"mdi-magnify\"\n        variant=\"solo-filled\"\n        flat\n        hide-details\n        single-line\n      ></v-text-field>\n    </v-card-title>\n\n    <v-divider></v-divider>\n    <v-data-table\n      v-model:search=\"search\"\n      :filter-keys=\"['name']\"\n      :items=\"items\"\n    >\n      <template v-slot:header.stock>\n        <div class=\"text-end\">Stock</div>\n      </template>\n\n      <template v-slot:item.image=\"{ item }\">\n        <v-card class=\"my-2\" elevation=\"1\" rounded>\n          <v-img\n            :src=\"`https://cdn.vuetifyjs.com/docs/images/graphics/gpus/${item.image}`\"\n            height=\"64\"\n            cover\n          ></v-img>\n        </v-card>\n      </template>\n\n      <template v-slot:item.rating=\"{ item }\">\n        <v-rating\n          :model-value=\"item.rating\"\n          color=\"orange-darken-2\"\n          density=\"compact\"\n          size=\"small\"\n          readonly\n        ></v-rating>\n      </template>\n\n      <template v-slot:item.stock=\"{ item }\">\n        <div class=\"text-end\">\n          <v-chip\n            :color=\"item.stock ? 'green' : 'red'\"\n            :text=\"item.stock ? 'In stock' : 'Out of stock'\"\n            class=\"text-uppercase\"\n            size=\"small\"\n            label\n          ></v-chip>\n        </div>\n      </template>\n    </v-data-table>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const search = ref('')\n  const items = [\n    {\n      name: 'Nebula GTX 3080',\n      image: '1.png',\n      price: 699.99,\n      rating: 5,\n      stock: true,\n    },\n    {\n      name: 'Galaxy RTX 3080',\n      image: '2.png',\n      price: 799.99,\n      rating: 4,\n      stock: false,\n    },\n    {\n      name: 'Orion RX 6800 XT',\n      image: '3.png',\n      price: 649.99,\n      rating: 3,\n      stock: true,\n    },\n    {\n      name: 'Vortex RTX 3090',\n      image: '4.png',\n      price: 1499.99,\n      rating: 4,\n      stock: true,\n    },\n    {\n      name: 'Cosmos GTX 1660 Super',\n      image: '5.png',\n      price: 299.99,\n      rating: 4,\n      stock: false,\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        search: '',\n        items: [\n          {\n            name: 'Nebula GTX 3080',\n            image: '1.png',\n            price: 699.99,\n            rating: 5,\n            stock: true,\n          },\n          {\n            name: 'Galaxy RTX 3080',\n            image: '2.png',\n            price: 799.99,\n            rating: 4,\n            stock: false,\n          },\n          {\n            name: 'Orion RX 6800 XT',\n            image: '3.png',\n            price: 649.99,\n            rating: 3,\n            stock: true,\n          },\n          {\n            name: 'Vortex RTX 3090',\n            image: '4.png',\n            price: 1499.99,\n            rating: 4,\n            stock: true,\n          },\n          {\n            name: 'Cosmos GTX 1660 Super',\n            image: '5.png',\n            price: 299.99,\n            rating: 4,\n            stock: false,\n          },\n        ],\n      }\n    },\n  }\n</script>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2143-110596&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/prop-footer-props.vue",
    "content": "<template>\n  <v-data-table\n    :footer-props=\"{\n      showFirstLastPage: true,\n      firstIcon: 'mdi-arrow-collapse-left',\n      lastIcon: 'mdi-arrow-collapse-right',\n      prevIcon: 'mdi-minus',\n      nextIcon: 'mdi-plus'\n    }\"\n    :headers=\"headers\"\n    :items=\"desserts\"\n    :items-per-page=\"5\"\n    item-key=\"name\"\n  ></v-data-table>\n</template>\n\n<script setup>\n  const headers = [\n    {\n      title: 'Dessert (100g serving)',\n      align: 'start',\n      value: 'name',\n    },\n    { title: 'Category', value: 'category' },\n  ]\n  const desserts = [\n    {\n      name: 'Frozen Yogurt',\n      category: 'Ice cream',\n    },\n    {\n      name: 'Ice cream sandwich',\n      category: 'Ice cream',\n    },\n    {\n      name: 'Eclair',\n      category: 'Cookie',\n    },\n    {\n      name: 'Cupcake',\n      category: 'Pastry',\n    },\n    {\n      name: 'Gingerbread',\n      category: 'Cookie',\n    },\n    {\n      name: 'Jelly bean',\n      category: 'Candy',\n    },\n    {\n      name: 'Lollipop',\n      category: 'Candy',\n    },\n    {\n      name: 'Honeycomb',\n      category: 'Toffee',\n    },\n    {\n      name: 'Donut',\n      category: 'Pastry',\n    },\n    {\n      name: 'KitKat',\n      category: 'Candy',\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      headers: [\n        {\n          title: 'Dessert (100g serving)',\n          align: 'start',\n          value: 'name',\n        },\n        { title: 'Category', value: 'category' },\n      ],\n      desserts: [\n        {\n          name: 'Frozen Yogurt',\n          category: 'Ice cream',\n        },\n        {\n          name: 'Ice cream sandwich',\n          category: 'Ice cream',\n        },\n        {\n          name: 'Eclair',\n          category: 'Cookie',\n        },\n        {\n          name: 'Cupcake',\n          category: 'Pastry',\n        },\n        {\n          name: 'Gingerbread',\n          category: 'Cookie',\n        },\n        {\n          name: 'Jelly bean',\n          category: 'Candy',\n        },\n        {\n          name: 'Lollipop',\n          category: 'Candy',\n        },\n        {\n          name: 'Honeycomb',\n          category: 'Toffee',\n        },\n        {\n          name: 'Donut',\n          category: 'Pastry',\n        },\n        {\n          name: 'KitKat',\n          category: 'Candy',\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/prop-grouping.vue",
    "content": "<template>\n  <v-data-table\n    :group-by=\"groupBy\"\n    :headers=\"headers\"\n    :items=\"desserts\"\n    :sort-by=\"sortBy\"\n    item-value=\"name\"\n  ></v-data-table>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const sortBy = ref([{ key: 'name', order: 'asc' }])\n  const groupBy = ref([{ key: 'category', order: 'asc' }, { key: 'status', order: 'asc' }])\n\n  const headers = [\n    { key: 'data-table-group', title: 'Category' },\n    {\n      title: 'Dessert (100g serving)',\n      align: 'start',\n      key: 'name',\n      groupable: false,\n    },\n    { title: 'Dairy', key: 'dairy', align: 'end' },\n  ]\n  const desserts = [\n    {\n      name: 'Frozen Yogurt',\n      category: 'Ice cream',\n      status: 'Available',\n      dairy: 'Yes',\n    },\n    {\n      name: 'Ice cream sandwich',\n      category: 'Ice cream',\n      status: 'Available',\n      dairy: 'Yes',\n    },\n    {\n      name: 'Eclair',\n      category: 'Cookie',\n      status: 'Out of stock',\n      dairy: 'Yes',\n    },\n    {\n      name: 'Cupcake',\n      category: 'Pastry',\n      status: 'Out of stock',\n      dairy: 'Yes',\n    },\n    {\n      name: 'Gingerbread',\n      category: 'Cookie',\n      status: 'Available',\n      dairy: 'No',\n    },\n    {\n      name: 'Jelly bean',\n      category: 'Candy',\n      status: 'Available',\n      dairy: 'No',\n    },\n    {\n      name: 'Lollipop',\n      category: 'Candy',\n      status: 'Out of stock',\n      dairy: 'No',\n    },\n    {\n      name: 'Honeycomb',\n      category: 'Toffee',\n      status: 'Out of stock',\n      dairy: 'No',\n    },\n    {\n      name: 'Donut',\n      category: 'Pastry',\n      dairy: 'Yes',\n      status: 'Available',\n    },\n    {\n      name: 'KitKat',\n      category: 'Candy',\n      dairy: 'Yes',\n      status: 'Available',\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      sortBy: [{ key: 'name', order: 'asc' }],\n      groupBy: [{ key: 'category', order: 'asc' }, { key: 'status', order: 'asc' }],\n      headers: [\n        {\n          title: 'Dessert (100g serving)',\n          align: 'start',\n          key: 'name',\n          groupable: false,\n        },\n        { title: 'Category', key: 'category', align: 'end' },\n        { title: 'Dairy', key: 'dairy', align: 'end' },\n      ],\n      desserts: [\n        {\n          name: 'Frozen Yogurt',\n          category: 'Ice cream',\n          status: 'Available',\n          dairy: 'Yes',\n        },\n        {\n          name: 'Ice cream sandwich',\n          category: 'Ice cream',\n          status: 'Available',\n          dairy: 'Yes',\n        },\n        {\n          name: 'Eclair',\n          category: 'Cookie',\n          status: 'Out of stock',\n          dairy: 'Yes',\n        },\n        {\n          name: 'Cupcake',\n          category: 'Pastry',\n          status: 'Out of stock',\n          dairy: 'Yes',\n        },\n        {\n          name: 'Gingerbread',\n          category: 'Cookie',\n          status: 'Available',\n          dairy: 'No',\n        },\n        {\n          name: 'Jelly bean',\n          category: 'Candy',\n          status: 'Available',\n          dairy: 'No',\n        },\n        {\n          name: 'Lollipop',\n          category: 'Candy',\n          status: 'Out of stock',\n          dairy: 'No',\n        },\n        {\n          name: 'Honeycomb',\n          category: 'Toffee',\n          status: 'Out of stock',\n          dairy: 'No',\n        },\n        {\n          name: 'Donut',\n          category: 'Pastry',\n          dairy: 'Yes',\n          status: 'Available',\n        },\n        {\n          name: 'KitKat',\n          category: 'Candy',\n          dairy: 'Yes',\n          status: 'Available',\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/prop-headers-sort-raw.vue",
    "content": "<template>\n  <v-data-table\n    :headers=\"headers\"\n    :items=\"items\"\n  ></v-data-table>\n</template>\n\n<script setup>\n  function sortRaw (a, b) {\n    if (a.location < b.location) return -1\n    if (a.location > b.location) return 1\n\n    const dateA = a.constructed.split('-').pop().trim()\n    const dateB = b.constructed.split('-').pop().trim()\n\n    return dateA.localeCompare(dateB, undefined, { numeric: true, sensitivity: 'base' })\n  }\n\n  const headers = [\n    { title: 'Name', key: 'name' },\n    { title: 'Location', key: 'location', sortRaw },\n    { title: 'Constructed', key: 'constructed' },\n    { title: 'Description', key: 'description' },\n  ]\n\n  const items = [\n    { name: 'Great Pyramid of Giza', location: 'Egypt', constructed: '2584-2561 BC', description: 'The oldest and largest of the three pyramids in the Giza pyramid complex.' },\n    { name: 'Hanging Gardens of Babylon', location: 'Iraq', constructed: '600 BC', description: 'An ascending series of tiered gardens, said to have been built in ancient Babylon.' },\n    { name: 'Statue of Zeus at Olympia', location: 'Greece', constructed: '435 BC', description: 'A giant seated figure of Zeus, made by the sculptor Phidias.' },\n    { name: 'Temple of Artemis at Ephesus', location: 'Turkey', constructed: '550 BC', description: 'A large temple dedicated to the goddess Artemis, one of the Seven Wonders of the Ancient World.' },\n    { name: 'Mausoleum at Halicarnassus', location: 'Turkey', constructed: '351 BC', description: 'A tomb built for Mausolus, a satrap of the Persian Empire.' },\n    { name: 'Colossus of Rhodes', location: 'Greece', constructed: '292-280 BC', description: 'A statue of the Greek sun-god Helios, erected in the city of Rhodes.' },\n    { name: 'Lighthouse of Alexandria', location: 'Egypt', constructed: '280 BC', description: 'A lighthouse built by the Ptolemaic Kingdom on the island of Pharos.' },\n    { name: 'Great Wall of China', location: 'China', constructed: '7th century BC - 1644 AD', description: 'A series of fortifications made of stone, brick, and other materials.' },\n    { name: 'Petra', location: 'Jordan', constructed: '312 BC', description: 'A historical city known for its rock-cut architecture and water conduit system.' },\n    { name: 'Taj Mahal', location: 'India', constructed: '1632-1653 AD', description: 'An ivory-white marble mausoleum on the south bank of the Yamuna river.' },\n    { name: 'Machu Picchu', location: 'Peru', constructed: '1450 AD', description: 'An Incan citadel set high in the Andes Mountains.' },\n    { name: 'Chichen Itza', location: 'Mexico', constructed: '600 AD', description: 'A large pre-Columbian archaeological site built by the Maya people.' },\n    { name: 'Roman Colosseum', location: 'Italy', constructed: '70-80 AD', description: 'An oval amphitheatre in the centre of the city of Rome.' },\n    { name: 'Stonehenge', location: 'United Kingdom', constructed: '3000 BC - 2000 BC', description: 'A prehistoric monument consisting of a ring of standing stones.' },\n    { name: 'Angkor Wat', location: 'Cambodia', constructed: '12th century AD', description: 'The largest religious monument in the world, originally constructed as a Hindu temple.' },\n    { name: 'Moai Statues of Easter Island', location: 'Chile', constructed: '1250-1500 AD', description: 'Monolithic human figures carved by the Rapa Nui people on Easter Island.' },\n    { name: 'Hagia Sophia', location: 'Turkey', constructed: '537 AD', description: 'A former Greek Orthodox Christian patriarchal basilica, later an Ottoman imperial mosque and now a museum.' },\n    { name: 'Alhambra', location: 'Spain', constructed: '13th century AD', description: 'A palace and fortress complex located in Granada.' },\n    { name: 'Forbidden City', location: 'China', constructed: '1406-1420 AD', description: 'A palace complex in central Beijing, serving as the home of emperors and their households.' },\n    { name: 'Christ the Redeemer', location: 'Brazil', constructed: '1922-1931 AD', description: 'An Art Deco statue of Jesus Christ in Rio de Janeiro.' },\n    { name: 'Acropolis of Athens', location: 'Greece', constructed: '5th century BC', description: 'An ancient citadel located on a rocky outcrop above the city of Athens.' },\n    { name: 'Terracotta Army', location: 'China', constructed: '246-206 BC', description: 'A collection of terracotta sculptures depicting the armies of Qin Shi Huang, the first Emperor of China.' },\n    { name: 'Parthenon', location: 'Greece', constructed: '447-438 BC', description: 'A former temple on the Athenian Acropolis, dedicated to the goddess Athena.' },\n    { name: 'Tower of London', location: 'United Kingdom', constructed: '1078 AD', description: 'A historic castle located on the north bank of the River Thames in central London.' },\n    { name: 'Neuschwanstein Castle', location: 'Germany', constructed: '1869-1886 AD', description: 'A 19th-century Romanesque Revival palace on a rugged hill above the village of Hohenschwangau.' },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      headers: [\n        { title: 'Name', key: 'name' },\n        {\n          title: 'Location',\n          key: 'location',\n          sortRaw (a, b) {\n            if (a.location < b.location) return -1\n            if (a.location > b.location) return 1\n\n            const dateA = a.constructed.split('-').pop().trim()\n            const dateB = b.constructed.split('-').pop().trim()\n\n            return dateA.localeCompare(dateB, undefined, { numeric: true, sensitivity: 'base' })\n          },\n        },\n        { title: 'Constructed', key: 'constructed' },\n        { title: 'Description', key: 'description' },\n      ],\n      items: [\n        { name: 'Great Pyramid of Giza', location: 'Egypt', constructed: '2584-2561 BC', description: 'The oldest and largest of the three pyramids in the Giza pyramid complex.' },\n        { name: 'Hanging Gardens of Babylon', location: 'Iraq', constructed: '600 BC', description: 'An ascending series of tiered gardens, said to have been built in ancient Babylon.' },\n        { name: 'Statue of Zeus at Olympia', location: 'Greece', constructed: '435 BC', description: 'A giant seated figure of Zeus, made by the sculptor Phidias.' },\n        { name: 'Temple of Artemis at Ephesus', location: 'Turkey', constructed: '550 BC', description: 'A large temple dedicated to the goddess Artemis, one of the Seven Wonders of the Ancient World.' },\n        { name: 'Mausoleum at Halicarnassus', location: 'Turkey', constructed: '351 BC', description: 'A tomb built for Mausolus, a satrap of the Persian Empire.' },\n        { name: 'Colossus of Rhodes', location: 'Greece', constructed: '292-280 BC', description: 'A statue of the Greek sun-god Helios, erected in the city of Rhodes.' },\n        { name: 'Lighthouse of Alexandria', location: 'Egypt', constructed: '280 BC', description: 'A lighthouse built by the Ptolemaic Kingdom on the island of Pharos.' },\n        { name: 'Great Wall of China', location: 'China', constructed: '7th century BC - 1644 AD', description: 'A series of fortifications made of stone, brick, and other materials.' },\n        { name: 'Petra', location: 'Jordan', constructed: '312 BC', description: 'A historical city known for its rock-cut architecture and water conduit system.' },\n        { name: 'Taj Mahal', location: 'India', constructed: '1632-1653 AD', description: 'An ivory-white marble mausoleum on the south bank of the Yamuna river.' },\n        { name: 'Machu Picchu', location: 'Peru', constructed: '1450 AD', description: 'An Incan citadel set high in the Andes Mountains.' },\n        { name: 'Chichen Itza', location: 'Mexico', constructed: '600 AD', description: 'A large pre-Columbian archaeological site built by the Maya people.' },\n        { name: 'Roman Colosseum', location: 'Italy', constructed: '70-80 AD', description: 'An oval amphitheatre in the centre of the city of Rome.' },\n        { name: 'Stonehenge', location: 'United Kingdom', constructed: '3000 BC - 2000 BC', description: 'A prehistoric monument consisting of a ring of standing stones.' },\n        { name: 'Angkor Wat', location: 'Cambodia', constructed: '12th century AD', description: 'The largest religious monument in the world, originally constructed as a Hindu temple.' },\n        { name: 'Moai Statues of Easter Island', location: 'Chile', constructed: '1250-1500 AD', description: 'Monolithic human figures carved by the Rapa Nui people on Easter Island.' },\n        { name: 'Hagia Sophia', location: 'Turkey', constructed: '537 AD', description: 'A former Greek Orthodox Christian patriarchal basilica, later an Ottoman imperial mosque and now a museum.' },\n        { name: 'Alhambra', location: 'Spain', constructed: '13th century AD', description: 'A palace and fortress complex located in Granada.' },\n        { name: 'Forbidden City', location: 'China', constructed: '1406-1420 AD', description: 'A palace complex in central Beijing, serving as the home of emperors and their households.' },\n        { name: 'Christ the Redeemer', location: 'Brazil', constructed: '1922-1931 AD', description: 'An Art Deco statue of Jesus Christ in Rio de Janeiro.' },\n        { name: 'Acropolis of Athens', location: 'Greece', constructed: '5th century BC', description: 'An ancient citadel located on a rocky outcrop above the city of Athens.' },\n        { name: 'Terracotta Army', location: 'China', constructed: '246-206 BC', description: 'A collection of terracotta sculptures depicting the armies of Qin Shi Huang, the first Emperor of China.' },\n        { name: 'Parthenon', location: 'Greece', constructed: '447-438 BC', description: 'A former temple on the Athenian Acropolis, dedicated to the goddess Athena.' },\n        { name: 'Tower of London', location: 'United Kingdom', constructed: '1078 AD', description: 'A historic castle located on the north bank of the River Thames in central London.' },\n        { name: 'Neuschwanstein Castle', location: 'Germany', constructed: '1869-1886 AD', description: 'A 19th-century Romanesque Revival palace on a rugged hill above the village of Hohenschwangau.' },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/prop-hide-header-footer.vue",
    "content": "<template>\n  <v-data-table\n    :headers=\"headers\"\n    :items=\"desserts\"\n    hide-default-footer\n    hide-default-header\n  ></v-data-table>\n</template>\n\n<script setup>\n  const headers = [\n    {\n      title: 'Dessert(100g serving)',\n      align: 'start',\n      key: 'name',\n    },\n    { title: 'Calories', align: 'end', key: 'calories' },\n    { title: 'Fat(g)', align: 'end', key: 'fat' },\n    { title: 'Carbs(g)', align: 'end', key: 'carbs' },\n    { title: 'Protein(g)', align: 'end', key: 'protein' },\n    { title: 'Iron(%)', align: 'end', key: 'iron' },\n  ]\n  const desserts = [\n    {\n      name: 'Frozen Yogurt',\n      calories: 159,\n      fat: 6,\n      carbs: 24,\n      protein: 4,\n      iron: '1%',\n    },\n    {\n      name: 'Ice cream sandwich',\n      calories: 237,\n      fat: 9,\n      carbs: 37,\n      protein: 4.3,\n      iron: '1%',\n    },\n    {\n      name: 'Eclair',\n      calories: 262,\n      fat: 16,\n      carbs: 23,\n      protein: 6,\n      iron: '7%',\n    },\n    {\n      name: 'Cupcake',\n      calories: 305,\n      fat: 3.7,\n      carbs: 67,\n      protein: 4.3,\n      iron: '8%',\n    },\n    {\n      name: 'Gingerbread',\n      calories: 356,\n      fat: 16,\n      carbs: 49,\n      protein: 3.9,\n      iron: '16%',\n    },\n    {\n      name: 'Jelly bean',\n      calories: 375,\n      fat: 0,\n      carbs: 94,\n      protein: 0,\n      iron: '0%',\n    },\n    {\n      name: 'Lollipop',\n      calories: 392,\n      fat: 0.2,\n      carbs: 98,\n      protein: 0,\n      iron: '2%',\n    },\n    {\n      name: 'Honeycomb',\n      calories: 408,\n      fat: 3.2,\n      carbs: 87,\n      protein: 6.5,\n      iron: '45%',\n    },\n    {\n      name: 'Donut',\n      calories: 452,\n      fat: 25,\n      carbs: 51,\n      protein: 4.9,\n      iron: '22%',\n    },\n    {\n      name: 'KitKat',\n      calories: 518,\n      fat: 26,\n      carbs: 65,\n      protein: 7,\n      iron: '6%',\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      headers: [\n        {\n          title: 'Dessert(100g serving)',\n          align: 'start',\n          key: 'name',\n        },\n        { title: 'Calories', align: 'end', key: 'calories' },\n        { title: 'Fat(g)', align: 'end', key: 'fat' },\n        { title: 'Carbs(g)', align: 'end', key: 'carbs' },\n        { title: 'Protein(g)', align: 'end', key: 'protein' },\n        { title: 'Iron(%)', align: 'end', key: 'iron' },\n      ],\n      desserts: [\n        {\n          name: 'Frozen Yogurt',\n          calories: 159,\n          fat: 6.0,\n          carbs: 24,\n          protein: 4.0,\n          iron: '1%',\n        },\n        {\n          name: 'Ice cream sandwich',\n          calories: 237,\n          fat: 9.0,\n          carbs: 37,\n          protein: 4.3,\n          iron: '1%',\n        },\n        {\n          name: 'Eclair',\n          calories: 262,\n          fat: 16.0,\n          carbs: 23,\n          protein: 6.0,\n          iron: '7%',\n        },\n        {\n          name: 'Cupcake',\n          calories: 305,\n          fat: 3.7,\n          carbs: 67,\n          protein: 4.3,\n          iron: '8%',\n        },\n        {\n          name: 'Gingerbread',\n          calories: 356,\n          fat: 16.0,\n          carbs: 49,\n          protein: 3.9,\n          iron: '16%',\n        },\n        {\n          name: 'Jelly bean',\n          calories: 375,\n          fat: 0.0,\n          carbs: 94,\n          protein: 0.0,\n          iron: '0%',\n        },\n        {\n          name: 'Lollipop',\n          calories: 392,\n          fat: 0.2,\n          carbs: 98,\n          protein: 0,\n          iron: '2%',\n        },\n        {\n          name: 'Honeycomb',\n          calories: 408,\n          fat: 3.2,\n          carbs: 87,\n          protein: 6.5,\n          iron: '45%',\n        },\n        {\n          name: 'Donut',\n          calories: 452,\n          fat: 25.0,\n          carbs: 51,\n          protein: 4.9,\n          iron: '22%',\n        },\n        {\n          name: 'KitKat',\n          calories: 518,\n          fat: 26.0,\n          carbs: 65,\n          protein: 7,\n          iron: '6%',\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/prop-item-selectable.vue",
    "content": "<template>\n  <v-data-table\n    :headers=\"headers\"\n    :items=\"desserts\"\n    item-selectable=\"selectable\"\n    item-value=\"name\"\n    items-per-page=\"5\"\n    show-select\n  ></v-data-table>\n</template>\n\n<script setup>\n  const headers = [\n    {\n      title: 'Dessert (100g serving)',\n      align: 'start',\n      key: 'name',\n    },\n    { title: 'Calories', align: 'end', key: 'calories' },\n    { title: 'Fat (g)', align: 'end', key: 'fat' },\n    { title: 'Carbs (g)', align: 'end', key: 'carbs' },\n    { title: 'Protein (g)', align: 'end', key: 'protein' },\n    { title: 'Iron (%)', align: 'end', key: 'iron' },\n  ]\n  const desserts = [\n    {\n      name: 'Frozen Yogurt',\n      calories: 159,\n      fat: 6,\n      carbs: 24,\n      protein: 4,\n      iron: 1,\n      selectable: false,\n    },\n    {\n      name: 'Ice cream sandwich',\n      calories: 237,\n      fat: 9,\n      carbs: 37,\n      protein: 4.3,\n      iron: 1,\n      selectable: true,\n    },\n    {\n      name: 'Eclair',\n      calories: 262,\n      fat: 16,\n      carbs: 23,\n      protein: 6,\n      iron: 7,\n      selectable: true,\n    },\n    {\n      name: 'Cupcake',\n      calories: 305,\n      fat: 3.7,\n      carbs: 67,\n      protein: 4.3,\n      iron: 8,\n      selectable: false,\n    },\n    {\n      name: 'Gingerbread',\n      calories: 356,\n      fat: 16,\n      carbs: 49,\n      protein: 3.9,\n      iron: 16,\n      selectable: true,\n    },\n    {\n      name: 'Jelly bean',\n      calories: 375,\n      fat: 0,\n      carbs: 94,\n      protein: 0,\n      iron: 0,\n      selectable: true,\n    },\n    {\n      name: 'Lollipop',\n      calories: 392,\n      fat: 0.2,\n      carbs: 98,\n      protein: 0,\n      iron: 2,\n      selectable: true,\n    },\n    {\n      name: 'Honeycomb',\n      calories: 408,\n      fat: 3.2,\n      carbs: 87,\n      protein: 6.5,\n      iron: 45,\n      selectable: false,\n    },\n    {\n      name: 'Donut',\n      calories: 452,\n      fat: 25,\n      carbs: 51,\n      protein: 4.9,\n      iron: 22,\n      selectable: true,\n    },\n    {\n      name: 'KitKat',\n      calories: 518,\n      fat: 26,\n      carbs: 65,\n      protein: 7,\n      iron: 6,\n      selectable: true,\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        headers: [\n          {\n            title: 'Dessert (100g serving)',\n            align: 'start',\n            key: 'name',\n          },\n          { title: 'Calories', align: 'end', key: 'calories' },\n          { title: 'Fat (g)', align: 'end', key: 'fat' },\n          { title: 'Carbs (g)', align: 'end', key: 'carbs' },\n          { title: 'Protein (g)', align: 'end', key: 'protein' },\n          { title: 'Iron (%)', align: 'end', key: 'iron' },\n        ],\n        desserts: [\n          {\n            name: 'Frozen Yogurt',\n            calories: 159,\n            fat: 6.0,\n            carbs: 24,\n            protein: 4.0,\n            iron: 1,\n            selectable: false,\n          },\n          {\n            name: 'Ice cream sandwich',\n            calories: 237,\n            fat: 9.0,\n            carbs: 37,\n            protein: 4.3,\n            iron: 1,\n            selectable: true,\n          },\n          {\n            name: 'Eclair',\n            calories: 262,\n            fat: 16.0,\n            carbs: 23,\n            protein: 6.0,\n            iron: 7,\n            selectable: true,\n          },\n          {\n            name: 'Cupcake',\n            calories: 305,\n            fat: 3.7,\n            carbs: 67,\n            protein: 4.3,\n            iron: 8,\n            selectable: false,\n          },\n          {\n            name: 'Gingerbread',\n            calories: 356,\n            fat: 16.0,\n            carbs: 49,\n            protein: 3.9,\n            iron: 16,\n            selectable: true,\n          },\n          {\n            name: 'Jelly bean',\n            calories: 375,\n            fat: 0.0,\n            carbs: 94,\n            protein: 0.0,\n            iron: 0,\n            selectable: true,\n          },\n          {\n            name: 'Lollipop',\n            calories: 392,\n            fat: 0.2,\n            carbs: 98,\n            protein: 0,\n            iron: 2,\n            selectable: true,\n          },\n          {\n            name: 'Honeycomb',\n            calories: 408,\n            fat: 3.2,\n            carbs: 87,\n            protein: 6.5,\n            iron: 45,\n            selectable: false,\n          },\n          {\n            name: 'Donut',\n            calories: 452,\n            fat: 25.0,\n            carbs: 51,\n            protein: 4.9,\n            iron: 22,\n            selectable: true,\n          },\n          {\n            name: 'KitKat',\n            calories: 518,\n            fat: 26.0,\n            carbs: 65,\n            protein: 7,\n            iron: 6,\n            selectable: true,\n          },\n        ],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/prop-item-value.vue",
    "content": "<template>\n  <v-data-table\n    :headers=\"headers\"\n    :item-value=\"item => `${item.name}-${item.version}`\"\n    :items=\"desserts\"\n    items-per-page=\"5\"\n    show-select\n  ></v-data-table>\n</template>\n\n<script setup>\n  const headers = [\n    {\n      title: 'Operating System',\n      align: 'start',\n      key: 'name',\n    },\n    { title: 'Version', align: 'end', key: 'version' },\n  ]\n  const desserts = [\n    {\n      name: 'Windows',\n      version: '3.11',\n    },\n    {\n      name: 'Windows',\n      version: '95',\n    },\n    {\n      name: 'Windows',\n      version: '98',\n    },\n    {\n      name: 'Windows',\n      version: '2000',\n    },\n    {\n      name: 'Windows',\n      version: 'XP',\n    },\n    {\n      name: 'Windows',\n      version: 'Vista',\n    },\n    {\n      name: 'Windows',\n      version: '7',\n    },\n    {\n      name: 'Windows',\n      version: '8',\n    },\n    {\n      name: 'Windows',\n      version: '10',\n    },\n    {\n      name: 'Windows',\n      version: '11',\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        headers: [\n          {\n            title: 'Operating System',\n            align: 'start',\n            key: 'name',\n          },\n          { title: 'Version', align: 'end', key: 'version' },\n        ],\n        desserts: [\n          {\n            name: 'Windows',\n            version: '3.11',\n          },\n          {\n            name: 'Windows',\n            version: '95',\n          },\n          {\n            name: 'Windows',\n            version: '98',\n          },\n          {\n            name: 'Windows',\n            version: '2000',\n          },\n          {\n            name: 'Windows',\n            version: 'XP',\n          },\n          {\n            name: 'Windows',\n            version: 'Vista',\n          },\n          {\n            name: 'Windows',\n            version: '7',\n          },\n          {\n            name: 'Windows',\n            version: '8',\n          },\n          {\n            name: 'Windows',\n            version: '10',\n          },\n          {\n            name: 'Windows',\n            version: '11',\n          },\n        ],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/prop-loading.vue",
    "content": "<template>\n  <v-data-table-server\n    :items-length=\"0\"\n    item-key=\"name\"\n    loading-text=\"Loading... Please wait\"\n    loading\n  ></v-data-table-server>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/prop-multi-sort.vue",
    "content": "<template>\n  <div>\n    <v-alert class=\"mb-2\" density=\"compact\" variant=\"outlined\">\n      <strong>Hint:</strong> Hold  <v-kbd>Alt</v-kbd> to prepend new columns to <v-code>sort-by</v-code> array\n    </v-alert>\n    <v-data-table\n      :headers=\"headers\"\n      :items=\"desserts\"\n      :multi-sort=\"{ mode: 'append', modifier: 'alt' }\"\n      :sort-by=\"[{ key: 'calories', order: 'asc' }, { key: 'fat', order: 'desc' }]\"\n    ></v-data-table>\n  </div>\n</template>\n\n<script setup>\n  const headers = [\n    {\n      title: 'Dessert (100g serving)',\n      align: 'start',\n      sortable: false,\n      key: 'name',\n    },\n    { title: 'Calories', key: 'calories' },\n    { title: 'Fat (g)', key: 'fat' },\n    { title: 'Carbs (g)', key: 'carbs' },\n    { title: 'Protein (g)', key: 'protein' },\n    { title: 'Iron (%)', key: 'iron' },\n  ]\n  const desserts = [\n    { name: 'Frozen Yogurt', calories: 200, fat: 6, carbs: 24, protein: 4, iron: 1 },\n    { name: 'Ice cream sandwich', calories: 200, fat: 9, carbs: 37, protein: 4.3, iron: 1 },\n    { name: 'Eclair', calories: 300, fat: 16, carbs: 23, protein: 6, iron: 7 },\n    { name: 'Cupcake', calories: 300, fat: 3.7, carbs: 67, protein: 4.3, iron: 8 },\n    { name: 'Gingerbread', calories: 400, fat: 16, carbs: 49, protein: 3.9, iron: 16 },\n    { name: 'Jelly bean', calories: 400, fat: 0, carbs: 94, protein: 0, iron: 0 },\n    { name: 'Lollipop', calories: 400, fat: 0.2, carbs: 98, protein: 0, iron: 2 },\n    { name: 'Honeycomb', calories: 400, fat: 3.2, carbs: 87, protein: 6.5, iron: 45 },\n    { name: 'Donut', calories: 500, fat: 25, carbs: 51, protein: 4.9, iron: 22 },\n    { name: 'KitKat', calories: 500, fat: 26, carbs: 65, protein: 7, iron: 6 },\n  ]\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        headers: [\n          {\n            title: 'Dessert (100g serving)',\n            align: 'start',\n            sortable: false,\n            key: 'name',\n          },\n          { title: 'Calories', key: 'calories' },\n          { title: 'Fat (g)', key: 'fat' },\n          { title: 'Carbs (g)', key: 'carbs' },\n          { title: 'Protein (g)', key: 'protein' },\n          { title: 'Iron (%)', key: 'iron' },\n        ],\n        desserts: [\n          { name: 'Frozen Yogurt', calories: 200, fat: 6.0, carbs: 24, protein: 4.0, iron: 1 },\n          { name: 'Ice cream sandwich', calories: 200, fat: 9.0, carbs: 37, protein: 4.3, iron: 1 },\n          { name: 'Eclair', calories: 300, fat: 16.0, carbs: 23, protein: 6.0, iron: 7 },\n          { name: 'Cupcake', calories: 300, fat: 3.7, carbs: 67, protein: 4.3, iron: 8 },\n          { name: 'Gingerbread', calories: 400, fat: 16.0, carbs: 49, protein: 3.9, iron: 16 },\n          { name: 'Jelly bean', calories: 400, fat: 0.0, carbs: 94, protein: 0.0, iron: 0 },\n          { name: 'Lollipop', calories: 400, fat: 0.2, carbs: 98, protein: 0, iron: 2 },\n          { name: 'Honeycomb', calories: 400, fat: 3.2, carbs: 87, protein: 6.5, iron: 45 },\n          { name: 'Donut', calories: 500, fat: 25.0, carbs: 51, protein: 4.9, iron: 22 },\n          { name: 'KitKat', calories: 500, fat: 26.0, carbs: 65, protein: 7, iron: 6 },\n        ],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/prop-return-object.vue",
    "content": "<template>\n  <v-data-table\n    v-model=\"selected\"\n    :headers=\"headers\"\n    :items=\"desserts\"\n    item-value=\"name\"\n    items-per-page=\"5\"\n    return-object\n    show-select\n  ></v-data-table>\n\n  <pre>{{ selected }}</pre>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const selected = ref([])\n\n  const headers = ref([\n    {\n      title: 'Dessert (100g serving)',\n      align: 'start',\n      key: 'name',\n    },\n    { title: 'Calories', align: 'end', key: 'calories' },\n    { title: 'Fat (g)', align: 'end', key: 'fat' },\n    { title: 'Carbs (g)', align: 'end', key: 'carbs' },\n    { title: 'Protein (g)', align: 'end', key: 'protein' },\n    { title: 'Iron (%)', align: 'end', key: 'iron' },\n  ])\n  const desserts = ref([\n    {\n      name: 'Frozen Yogurt',\n      calories: 159,\n      fat: 6,\n      carbs: 24,\n      protein: 4,\n      iron: 1,\n    },\n    {\n      name: 'Ice cream sandwich',\n      calories: 237,\n      fat: 9,\n      carbs: 37,\n      protein: 4.3,\n      iron: 1,\n    },\n    {\n      name: 'Eclair',\n      calories: 262,\n      fat: 16,\n      carbs: 23,\n      protein: 6,\n      iron: 7,\n    },\n    {\n      name: 'Cupcake',\n      calories: 305,\n      fat: 3.7,\n      carbs: 67,\n      protein: 4.3,\n      iron: 8,\n    },\n    {\n      name: 'Gingerbread',\n      calories: 356,\n      fat: 16,\n      carbs: 49,\n      protein: 3.9,\n      iron: 16,\n    },\n    {\n      name: 'Jelly bean',\n      calories: 375,\n      fat: 0,\n      carbs: 94,\n      protein: 0,\n      iron: 0,\n    },\n    {\n      name: 'Lollipop',\n      calories: 392,\n      fat: 0.2,\n      carbs: 98,\n      protein: 0,\n      iron: 2,\n    },\n    {\n      name: 'Honeycomb',\n      calories: 408,\n      fat: 3.2,\n      carbs: 87,\n      protein: 6.5,\n      iron: 45,\n    },\n    {\n      name: 'Donut',\n      calories: 452,\n      fat: 25,\n      carbs: 51,\n      protein: 4.9,\n      iron: 22,\n    },\n    {\n      name: 'KitKat',\n      calories: 518,\n      fat: 26,\n      carbs: 65,\n      protein: 7,\n      iron: 6,\n    },\n  ])\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        selected: [],\n        headers: [\n          {\n            title: 'Dessert (100g serving)',\n            align: 'start',\n            key: 'name',\n          },\n          { title: 'Calories', align: 'end', key: 'calories' },\n          { title: 'Fat (g)', align: 'end', key: 'fat' },\n          { title: 'Carbs (g)', align: 'end', key: 'carbs' },\n          { title: 'Protein (g)', align: 'end', key: 'protein' },\n          { title: 'Iron (%)', align: 'end', key: 'iron' },\n        ],\n        desserts: [\n          {\n            name: 'Frozen Yogurt',\n            calories: 159,\n            fat: 6.0,\n            carbs: 24,\n            protein: 4.0,\n            iron: 1,\n          },\n          {\n            name: 'Ice cream sandwich',\n            calories: 237,\n            fat: 9.0,\n            carbs: 37,\n            protein: 4.3,\n            iron: 1,\n          },\n          {\n            name: 'Eclair',\n            calories: 262,\n            fat: 16.0,\n            carbs: 23,\n            protein: 6.0,\n            iron: 7,\n          },\n          {\n            name: 'Cupcake',\n            calories: 305,\n            fat: 3.7,\n            carbs: 67,\n            protein: 4.3,\n            iron: 8,\n          },\n          {\n            name: 'Gingerbread',\n            calories: 356,\n            fat: 16.0,\n            carbs: 49,\n            protein: 3.9,\n            iron: 16,\n          },\n          {\n            name: 'Jelly bean',\n            calories: 375,\n            fat: 0.0,\n            carbs: 94,\n            protein: 0.0,\n            iron: 0,\n          },\n          {\n            name: 'Lollipop',\n            calories: 392,\n            fat: 0.2,\n            carbs: 98,\n            protein: 0,\n            iron: 2,\n          },\n          {\n            name: 'Honeycomb',\n            calories: 408,\n            fat: 3.2,\n            carbs: 87,\n            protein: 6.5,\n            iron: 45,\n          },\n          {\n            name: 'Donut',\n            calories: 452,\n            fat: 25.0,\n            carbs: 51,\n            protein: 4.9,\n            iron: 22,\n          },\n          {\n            name: 'KitKat',\n            calories: 518,\n            fat: 26.0,\n            carbs: 65,\n            protein: 7,\n            iron: 6,\n          },\n        ],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/prop-row-selection.vue",
    "content": "<template>\n  <v-data-table\n    v-model=\"selected\"\n    :items=\"items\"\n    item-value=\"name\"\n    show-select\n  ></v-data-table>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const selected = ref([])\n  const items = [\n    {\n      name: '🍎 Apple',\n      location: 'Washington',\n      height: '0.1',\n      base: '0.07',\n      volume: '0.0001',\n    },\n    {\n      name: '🍌 Banana',\n      location: 'Ecuador',\n      height: '0.2',\n      base: '0.05',\n      volume: '0.0002',\n    },\n    {\n      name: '🍇 Grapes',\n      location: 'Italy',\n      height: '0.02',\n      base: '0.02',\n      volume: '0.00001',\n    },\n    {\n      name: '🍉 Watermelon',\n      location: 'China',\n      height: '0.4',\n      base: '0.3',\n      volume: '0.03',\n    },\n    {\n      name: '🍍 Pineapple',\n      location: 'Thailand',\n      height: '0.3',\n      base: '0.2',\n      volume: '0.005',\n    },\n    {\n      name: '🍒 Cherries',\n      location: 'Turkey',\n      height: '0.02',\n      base: '0.02',\n      volume: '0.00001',\n    },\n    {\n      name: '🥭 Mango',\n      location: 'India',\n      height: '0.15',\n      base: '0.1',\n      volume: '0.0005',\n    },\n    {\n      name: '🍓 Strawberry',\n      location: 'USA',\n      height: '0.03',\n      base: '0.03',\n      volume: '0.00002',\n    },\n    {\n      name: '🍑 Peach',\n      location: 'China',\n      height: '0.09',\n      base: '0.08',\n      volume: '0.0004',\n    },\n    {\n      name: '🥝 Kiwi',\n      location: 'New Zealand',\n      height: '0.05',\n      base: '0.05',\n      volume: '0.0001',\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        selected: [],\n        items: [\n          {\n            name: '🍎 Apple',\n            location: 'Washington',\n            height: '0.1',\n            base: '0.07',\n            volume: '0.0001',\n          },\n          {\n            name: '🍌 Banana',\n            location: 'Ecuador',\n            height: '0.2',\n            base: '0.05',\n            volume: '0.0002',\n          },\n          {\n            name: '🍇 Grapes',\n            location: 'Italy',\n            height: '0.02',\n            base: '0.02',\n            volume: '0.00001',\n          },\n          {\n            name: '🍉 Watermelon',\n            location: 'China',\n            height: '0.4',\n            base: '0.3',\n            volume: '0.03',\n          },\n          {\n            name: '🍍 Pineapple',\n            location: 'Thailand',\n            height: '0.3',\n            base: '0.2',\n            volume: '0.005',\n          },\n          {\n            name: '🍒 Cherries',\n            location: 'Turkey',\n            height: '0.02',\n            base: '0.02',\n            volume: '0.00001',\n          },\n          {\n            name: '🥭 Mango',\n            location: 'India',\n            height: '0.15',\n            base: '0.1',\n            volume: '0.0005',\n          },\n          {\n            name: '🍓 Strawberry',\n            location: 'USA',\n            height: '0.03',\n            base: '0.03',\n            volume: '0.00002',\n          },\n          {\n            name: '🍑 Peach',\n            location: 'China',\n            height: '0.09',\n            base: '0.08',\n            volume: '0.0004',\n          },\n          {\n            name: '🥝 Kiwi',\n            location: 'New Zealand',\n            height: '0.05',\n            base: '0.05',\n            volume: '0.0001',\n          },\n        ],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/prop-search.vue",
    "content": "<template>\n  <v-card\n    title=\"Nutrition\"\n    flat\n  >\n    <template v-slot:text>\n      <v-text-field\n        v-model=\"search\"\n        label=\"Search\"\n        prepend-inner-icon=\"mdi-magnify\"\n        variant=\"outlined\"\n        hide-details\n        single-line\n      ></v-text-field>\n    </template>\n\n    <v-data-table\n      :headers=\"headers\"\n      :items=\"desserts\"\n      :search=\"search\"\n    ></v-data-table>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const search = ref('')\n  const headers = [\n    {\n      align: 'start',\n      key: 'name',\n      sortable: false,\n      title: 'Dessert (100g serving)',\n    },\n    { key: 'calories', title: 'Calories' },\n    { key: 'fat', title: 'Fat (g)' },\n    { key: 'carbs', title: 'Carbs (g)' },\n    { key: 'protein', title: 'Protein (g)' },\n    { key: 'iron', title: 'Iron (%)' },\n  ]\n  const desserts = [\n    {\n      name: 'Frozen Yogurt',\n      calories: 159,\n      fat: 6,\n      carbs: 24,\n      protein: 4,\n      iron: 1,\n    },\n    {\n      name: 'Ice cream sandwich',\n      calories: 237,\n      fat: 9,\n      carbs: 37,\n      protein: 4.3,\n      iron: 1,\n    },\n    {\n      name: 'Eclair',\n      calories: 262,\n      fat: 16,\n      carbs: 23,\n      protein: 6,\n      iron: 7,\n    },\n    {\n      name: 'Cupcake',\n      calories: 305,\n      fat: 3.7,\n      carbs: 67,\n      protein: 4.3,\n      iron: 8,\n    },\n    {\n      name: 'Gingerbread',\n      calories: 356,\n      fat: 16,\n      carbs: 49,\n      protein: 3.9,\n      iron: 16,\n    },\n    {\n      name: 'Jelly bean',\n      calories: 375,\n      fat: 0,\n      carbs: 94,\n      protein: 0,\n      iron: 0,\n    },\n    {\n      name: 'Lollipop',\n      calories: 392,\n      fat: 0.2,\n      carbs: 98,\n      protein: 0,\n      iron: 2,\n    },\n    {\n      name: 'Honeycomb',\n      calories: 408,\n      fat: 3.2,\n      carbs: 87,\n      protein: 6.5,\n      iron: 45,\n    },\n    {\n      name: 'Donut',\n      calories: 452,\n      fat: 25,\n      carbs: 51,\n      protein: 4.9,\n      iron: 22,\n    },\n    {\n      name: 'KitKat',\n      calories: 518,\n      fat: 26,\n      carbs: 65,\n      protein: 7,\n      iron: 6,\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        search: '',\n        headers: [\n          {\n            align: 'start',\n            key: 'name',\n            sortable: false,\n            title: 'Dessert (100g serving)',\n          },\n          { key: 'calories', title: 'Calories' },\n          { key: 'fat', title: 'Fat (g)' },\n          { key: 'carbs', title: 'Carbs (g)' },\n          { key: 'protein', title: 'Protein (g)' },\n          { key: 'iron', title: 'Iron (%)' },\n        ],\n        desserts: [\n          {\n            name: 'Frozen Yogurt',\n            calories: 159,\n            fat: 6.0,\n            carbs: 24,\n            protein: 4.0,\n            iron: 1,\n          },\n          {\n            name: 'Ice cream sandwich',\n            calories: 237,\n            fat: 9.0,\n            carbs: 37,\n            protein: 4.3,\n            iron: 1,\n          },\n          {\n            name: 'Eclair',\n            calories: 262,\n            fat: 16.0,\n            carbs: 23,\n            protein: 6.0,\n            iron: 7,\n          },\n          {\n            name: 'Cupcake',\n            calories: 305,\n            fat: 3.7,\n            carbs: 67,\n            protein: 4.3,\n            iron: 8,\n          },\n          {\n            name: 'Gingerbread',\n            calories: 356,\n            fat: 16.0,\n            carbs: 49,\n            protein: 3.9,\n            iron: 16,\n          },\n          {\n            name: 'Jelly bean',\n            calories: 375,\n            fat: 0.0,\n            carbs: 94,\n            protein: 0.0,\n            iron: 0,\n          },\n          {\n            name: 'Lollipop',\n            calories: 392,\n            fat: 0.2,\n            carbs: 98,\n            protein: 0,\n            iron: 2,\n          },\n          {\n            name: 'Honeycomb',\n            calories: 408,\n            fat: 3.2,\n            carbs: 87,\n            protein: 6.5,\n            iron: 45,\n          },\n          {\n            name: 'Donut',\n            calories: 452,\n            fat: 25.0,\n            carbs: 51,\n            protein: 4.9,\n            iron: 22,\n          },\n          {\n            name: 'KitKat',\n            calories: 518,\n            fat: 26.0,\n            carbs: 65,\n            protein: 7,\n            iron: 6,\n          },\n        ],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/prop-select-strategy.vue",
    "content": "<template>\n  <v-data-table\n    :headers=\"headers\"\n    :items=\"desserts\"\n    item-value=\"name\"\n    select-strategy=\"single\"\n    show-select\n  ></v-data-table>\n</template>\n\n<script setup>\n  const headers = [\n    {\n      title: 'Dessert (100g serving)',\n      align: 'start',\n      key: 'name',\n    },\n    { title: 'Calories', align: 'end', key: 'calories' },\n    { title: 'Fat (g)', align: 'end', key: 'fat' },\n    { title: 'Carbs (g)', align: 'end', key: 'carbs' },\n    { title: 'Protein (g)', align: 'end', key: 'protein' },\n    { title: 'Iron (%)', align: 'end', key: 'iron' },\n  ]\n  const desserts = [\n    {\n      name: 'Frozen Yogurt',\n      calories: 159,\n      fat: 6,\n      carbs: 24,\n      protein: 4,\n      iron: 1,\n    },\n    {\n      name: 'Ice cream sandwich',\n      calories: 237,\n      fat: 9,\n      carbs: 37,\n      protein: 4.3,\n      iron: 1,\n    },\n    {\n      name: 'Eclair',\n      calories: 262,\n      fat: 16,\n      carbs: 23,\n      protein: 6,\n      iron: 7,\n    },\n    {\n      name: 'Cupcake',\n      calories: 305,\n      fat: 3.7,\n      carbs: 67,\n      protein: 4.3,\n      iron: 8,\n    },\n    {\n      name: 'Gingerbread',\n      calories: 356,\n      fat: 16,\n      carbs: 49,\n      protein: 3.9,\n      iron: 16,\n    },\n    {\n      name: 'Jelly bean',\n      calories: 375,\n      fat: 0,\n      carbs: 94,\n      protein: 0,\n      iron: 0,\n    },\n    {\n      name: 'Lollipop',\n      calories: 392,\n      fat: 0.2,\n      carbs: 98,\n      protein: 0,\n      iron: 2,\n    },\n    {\n      name: 'Honeycomb',\n      calories: 408,\n      fat: 3.2,\n      carbs: 87,\n      protein: 6.5,\n      iron: 45,\n    },\n    {\n      name: 'Donut',\n      calories: 452,\n      fat: 25,\n      carbs: 51,\n      protein: 4.9,\n      iron: 22,\n    },\n    {\n      name: 'KitKat',\n      calories: 518,\n      fat: 26,\n      carbs: 65,\n      protein: 7,\n      iron: 6,\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        headers: [\n          {\n            title: 'Dessert (100g serving)',\n            align: 'start',\n            key: 'name',\n          },\n          { title: 'Calories', align: 'end', key: 'calories' },\n          { title: 'Fat (g)', align: 'end', key: 'fat' },\n          { title: 'Carbs (g)', align: 'end', key: 'carbs' },\n          { title: 'Protein (g)', align: 'end', key: 'protein' },\n          { title: 'Iron (%)', align: 'end', key: 'iron' },\n        ],\n        desserts: [\n          {\n            name: 'Frozen Yogurt',\n            calories: 159,\n            fat: 6.0,\n            carbs: 24,\n            protein: 4.0,\n            iron: 1,\n          },\n          {\n            name: 'Ice cream sandwich',\n            calories: 237,\n            fat: 9.0,\n            carbs: 37,\n            protein: 4.3,\n            iron: 1,\n          },\n          {\n            name: 'Eclair',\n            calories: 262,\n            fat: 16.0,\n            carbs: 23,\n            protein: 6.0,\n            iron: 7,\n          },\n          {\n            name: 'Cupcake',\n            calories: 305,\n            fat: 3.7,\n            carbs: 67,\n            protein: 4.3,\n            iron: 8,\n          },\n          {\n            name: 'Gingerbread',\n            calories: 356,\n            fat: 16.0,\n            carbs: 49,\n            protein: 3.9,\n            iron: 16,\n          },\n          {\n            name: 'Jelly bean',\n            calories: 375,\n            fat: 0.0,\n            carbs: 94,\n            protein: 0.0,\n            iron: 0,\n          },\n          {\n            name: 'Lollipop',\n            calories: 392,\n            fat: 0.2,\n            carbs: 98,\n            protein: 0,\n            iron: 2,\n          },\n          {\n            name: 'Honeycomb',\n            calories: 408,\n            fat: 3.2,\n            carbs: 87,\n            protein: 6.5,\n            iron: 45,\n          },\n          {\n            name: 'Donut',\n            calories: 452,\n            fat: 25.0,\n            carbs: 51,\n            protein: 4.9,\n            iron: 22,\n          },\n          {\n            name: 'KitKat',\n            calories: 518,\n            fat: 26.0,\n            carbs: 65,\n            protein: 7,\n            iron: 6,\n          },\n        ],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/prop-sort-by.vue",
    "content": "<template>\n  <v-data-table\n    v-model:sort-by=\"sortBy\"\n    :headers=\"headers\"\n    :items=\"desserts\"\n  ></v-data-table>\n\n  <pre>{{ sortBy }}</pre>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const sortBy = ref([{ key: 'calories', order: 'asc' }])\n\n  const headers = [\n    {\n      title: 'Dessert (100g serving)',\n      align: 'start',\n      sortable: false,\n      key: 'name',\n    },\n    { title: 'Calories', key: 'calories' },\n    { title: 'Fat (g)', key: 'fat' },\n    { title: 'Carbs (g)', key: 'carbs' },\n    { title: 'Protein (g)', key: 'protein' },\n    { title: 'Iron (%)', key: 'iron' },\n  ]\n  const desserts = [\n    {\n      name: 'Frozen Yogurt',\n      calories: 200,\n      fat: 6,\n      carbs: 24,\n      protein: 4,\n      iron: '1%',\n    },\n    {\n      name: 'Ice cream sandwich',\n      calories: 200,\n      fat: 9,\n      carbs: 37,\n      protein: 4.3,\n      iron: '1%',\n    },\n    {\n      name: 'Eclair',\n      calories: 300,\n      fat: 16,\n      carbs: 23,\n      protein: 6,\n      iron: '7%',\n    },\n    {\n      name: 'Cupcake',\n      calories: 300,\n      fat: 3.7,\n      carbs: 67,\n      protein: 4.3,\n      iron: '8%',\n    },\n    {\n      name: 'Gingerbread',\n      calories: 400,\n      fat: 16,\n      carbs: 49,\n      protein: 3.9,\n      iron: '16%',\n    },\n    {\n      name: 'Jelly bean',\n      calories: 400,\n      fat: 0,\n      carbs: 94,\n      protein: 0,\n      iron: '0%',\n    },\n    {\n      name: 'Lollipop',\n      calories: 400,\n      fat: 0.2,\n      carbs: 98,\n      protein: 0,\n      iron: '2%',\n    },\n    {\n      name: 'Honeycomb',\n      calories: 400,\n      fat: 3.2,\n      carbs: 87,\n      protein: 6.5,\n      iron: '45%',\n    },\n    {\n      name: 'Donut',\n      calories: 500,\n      fat: 25,\n      carbs: 51,\n      protein: 4.9,\n      iron: '22%',\n    },\n    {\n      name: 'KitKat',\n      calories: 500,\n      fat: 26,\n      carbs: 65,\n      protein: 7,\n      iron: '6%',\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        sortBy: [{ key: 'calories', order: 'asc' }],\n        headers: [\n          {\n            title: 'Dessert (100g serving)',\n            align: 'start',\n            sortable: false,\n            key: 'name',\n          },\n          { title: 'Calories', key: 'calories' },\n          { title: 'Fat (g)', key: 'fat' },\n          { title: 'Carbs (g)', key: 'carbs' },\n          { title: 'Protein (g)', key: 'protein' },\n          { title: 'Iron (%)', key: 'iron' },\n        ],\n        desserts: [\n          {\n            name: 'Frozen Yogurt',\n            calories: 200,\n            fat: 6.0,\n            carbs: 24,\n            protein: 4.0,\n            iron: '1%',\n          },\n          {\n            name: 'Ice cream sandwich',\n            calories: 200,\n            fat: 9.0,\n            carbs: 37,\n            protein: 4.3,\n            iron: '1%',\n          },\n          {\n            name: 'Eclair',\n            calories: 300,\n            fat: 16.0,\n            carbs: 23,\n            protein: 6.0,\n            iron: '7%',\n          },\n          {\n            name: 'Cupcake',\n            calories: 300,\n            fat: 3.7,\n            carbs: 67,\n            protein: 4.3,\n            iron: '8%',\n          },\n          {\n            name: 'Gingerbread',\n            calories: 400,\n            fat: 16.0,\n            carbs: 49,\n            protein: 3.9,\n            iron: '16%',\n          },\n          {\n            name: 'Jelly bean',\n            calories: 400,\n            fat: 0.0,\n            carbs: 94,\n            protein: 0.0,\n            iron: '0%',\n          },\n          {\n            name: 'Lollipop',\n            calories: 400,\n            fat: 0.2,\n            carbs: 98,\n            protein: 0,\n            iron: '2%',\n          },\n          {\n            name: 'Honeycomb',\n            calories: 400,\n            fat: 3.2,\n            carbs: 87,\n            protein: 6.5,\n            iron: '45%',\n          },\n          {\n            name: 'Donut',\n            calories: 500,\n            fat: 25.0,\n            carbs: 51,\n            protein: 4.9,\n            iron: '22%',\n          },\n          {\n            name: 'KitKat',\n            calories: 500,\n            fat: 26.0,\n            carbs: 65,\n            protein: 7,\n            iron: '6%',\n          },\n        ],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/prop-sort-icon.vue",
    "content": "<template>\n  <v-data-table\n    :headers=\"headers\"\n    :items=\"desserts\"\n    :sort-by=\"[{ key: 'calories', order: 'asc' }, { key: 'fat', order: 'desc' }]\"\n    sort-asc-icon=\"mdi-sort-ascending\"\n    sort-desc-icon=\"mdi-sort-descending\"\n    sort-icon=\"mdi-swap-vertical\"\n  ></v-data-table>\n</template>\n\n<script setup>\n  const headers = [\n    {\n      title: 'Dessert (100g serving)',\n      align: 'start',\n      sortable: false,\n      key: 'name',\n    },\n    { title: 'Calories', key: 'calories' },\n    { title: 'Fat (g)', key: 'fat' },\n    { title: 'Carbs (g)', key: 'carbs' },\n    { title: 'Protein (g)', key: 'protein' },\n  ]\n  const desserts = [\n    { name: 'Frozen Yogurt', calories: 159, fat: 6, carbs: 24, protein: 4 },\n    { name: 'Ice cream sandwich', calories: 237, fat: 9, carbs: 37, protein: 4.3 },\n    { name: 'Eclair', calories: 262, fat: 16, carbs: 23, protein: 6 },\n    { name: 'Cupcake', calories: 305, fat: 3.7, carbs: 67, protein: 4.3 },\n  ]\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        headers: [\n          {\n            title: 'Dessert (100g serving)',\n            align: 'start',\n            sortable: false,\n            key: 'name',\n          },\n          { title: 'Calories', key: 'calories' },\n          { title: 'Fat (g)', key: 'fat' },\n          { title: 'Carbs (g)', key: 'carbs' },\n          { title: 'Protein (g)', key: 'protein' },\n        ],\n        desserts: [\n          { name: 'Frozen Yogurt', calories: 159, fat: 6, carbs: 24, protein: 4 },\n          { name: 'Ice cream sandwich', calories: 237, fat: 9, carbs: 37, protein: 4.3 },\n          { name: 'Eclair', calories: 262, fat: 16, carbs: 23, protein: 6 },\n          { name: 'Cupcake', calories: 305, fat: 3.7, carbs: 67, protein: 4.3 },\n        ],\n      }\n    },\n  }\n</script>\n\n<style scoped>\n  ::v-deep(.v-table__wrapper)  > table > thead > tr > th:not(.v-data-table__th--sorted):not(:hover) .v-data-table-header__sort-icon {\n    opacity: .3; /* $data-table-header-sort-icon-default-opacity */\n  }\n  ::v-deep(.v-data-table-header__sort-icon) {\n    margin-inline: .5rem 0; /* $data-table-header-sort-icon-margin-inline */\n  }\n</style>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/server-search.vue",
    "content": "<template>\n  <v-data-table-server\n    v-model:items-per-page=\"itemsPerPage\"\n    :headers=\"headers\"\n    :items=\"serverItems\"\n    :items-length=\"totalItems\"\n    :loading=\"loading\"\n    :search=\"search\"\n    item-value=\"name\"\n    @update:options=\"loadItems\"\n  >\n    <template v-slot:tfoot>\n      <tr>\n        <td>\n          <v-text-field v-model=\"name\" class=\"ma-2\" density=\"compact\" placeholder=\"Search name...\" hide-details></v-text-field>\n        </td>\n        <td>\n          <v-text-field\n            v-model=\"calories\"\n            class=\"ma-2\"\n            density=\"compact\"\n            placeholder=\"Minimum calories\"\n            type=\"number\"\n            hide-details\n          ></v-text-field>\n        </td>\n      </tr>\n    </template>\n  </v-data-table-server>\n</template>\n\n<script setup>\n  import { ref, watch } from 'vue'\n\n  const desserts = [\n    {\n      name: 'Frozen Yogurt',\n      calories: 159,\n      fat: 6,\n      carbs: 24,\n      protein: 4,\n      iron: '1',\n    },\n    {\n      name: 'Jelly bean',\n      calories: 375,\n      fat: 0,\n      carbs: 94,\n      protein: 0,\n      iron: '0',\n    },\n    {\n      name: 'KitKat',\n      calories: 518,\n      fat: 26,\n      carbs: 65,\n      protein: 7,\n      iron: '6',\n    },\n    {\n      name: 'Eclair',\n      calories: 262,\n      fat: 16,\n      carbs: 23,\n      protein: 6,\n      iron: '7',\n    },\n    {\n      name: 'Gingerbread',\n      calories: 356,\n      fat: 16,\n      carbs: 49,\n      protein: 3.9,\n      iron: '16',\n    },\n    {\n      name: 'Ice cream sandwich',\n      calories: 237,\n      fat: 9,\n      carbs: 37,\n      protein: 4.3,\n      iron: '1',\n    },\n    {\n      name: 'Lollipop',\n      calories: 392,\n      fat: 0.2,\n      carbs: 98,\n      protein: 0,\n      iron: '2',\n    },\n    {\n      name: 'Cupcake',\n      calories: 305,\n      fat: 3.7,\n      carbs: 67,\n      protein: 4.3,\n      iron: '8',\n    },\n    {\n      name: 'Honeycomb',\n      calories: 408,\n      fat: 3.2,\n      carbs: 87,\n      protein: 6.5,\n      iron: '45',\n    },\n    {\n      name: 'Donut',\n      calories: 452,\n      fat: 25,\n      carbs: 51,\n      protein: 4.9,\n      iron: '22',\n    },\n  ]\n  const FakeAPI = {\n    async fetch ({ page, itemsPerPage, sortBy, search }) {\n      return new Promise(resolve => {\n        setTimeout(() => {\n          const start = (page - 1) * itemsPerPage\n          const end = start + itemsPerPage\n          const items = desserts.slice().filter(item => {\n            if (search.name && !item.name.toLowerCase().includes(search.name.toLowerCase())) {\n              return false\n            }\n            // eslint-disable-next-line sonarjs/prefer-single-boolean-return\n            if (search.calories && !(item.calories >= Number(search.calories))) {\n              return false\n            }\n            return true\n          })\n          if (sortBy.length) {\n            const sortKey = sortBy[0].key\n            const sortOrder = sortBy[0].order\n            items.sort((a, b) => {\n              const aValue = a[sortKey]\n              const bValue = b[sortKey]\n              return sortOrder === 'desc' ? bValue - aValue : aValue - bValue\n            })\n          }\n          const paginated = items.slice(start, end === -1 ? undefined : end)\n          resolve({ items: paginated, total: items.length })\n        }, 500)\n      })\n    },\n  }\n  const itemsPerPage = ref(5)\n  const headers = ref([\n    {\n      title: 'Dessert (100g serving)',\n      align: 'start',\n      sortable: false,\n      key: 'name',\n    },\n    { title: 'Calories', key: 'calories', align: 'end' },\n    { title: 'Fat (g)', key: 'fat', align: 'end' },\n    { title: 'Carbs (g)', key: 'carbs', align: 'end' },\n    { title: 'Protein (g)', key: 'protein', align: 'end' },\n    { title: 'Iron (%)', key: 'iron', align: 'end' },\n  ])\n  const serverItems = ref([])\n  const loading = ref(true)\n  const totalItems = ref(0)\n  const name = ref('')\n  const calories = ref('')\n  const search = ref('')\n  function loadItems ({ page, itemsPerPage, sortBy }) {\n    loading.value = true\n    FakeAPI.fetch({ page, itemsPerPage, sortBy, search: { name: name.value, calories: calories.value } }).then(({ items, total }) => {\n      serverItems.value = items\n      totalItems.value = total\n      loading.value = false\n    })\n  }\n  watch(name, () => {\n    search.value = String(Date.now())\n  })\n  watch(calories, () => {\n    search.value = String(Date.now())\n  })\n</script>\n\n<script>\n  const desserts = [\n    {\n      name: 'Frozen Yogurt',\n      calories: 159,\n      fat: 6.0,\n      carbs: 24,\n      protein: 4.0,\n      iron: '1',\n    },\n    {\n      name: 'Jelly bean',\n      calories: 375,\n      fat: 0.0,\n      carbs: 94,\n      protein: 0.0,\n      iron: '0',\n    },\n    {\n      name: 'KitKat',\n      calories: 518,\n      fat: 26.0,\n      carbs: 65,\n      protein: 7,\n      iron: '6',\n    },\n    {\n      name: 'Eclair',\n      calories: 262,\n      fat: 16.0,\n      carbs: 23,\n      protein: 6.0,\n      iron: '7',\n    },\n    {\n      name: 'Gingerbread',\n      calories: 356,\n      fat: 16.0,\n      carbs: 49,\n      protein: 3.9,\n      iron: '16',\n    },\n    {\n      name: 'Ice cream sandwich',\n      calories: 237,\n      fat: 9.0,\n      carbs: 37,\n      protein: 4.3,\n      iron: '1',\n    },\n    {\n      name: 'Lollipop',\n      calories: 392,\n      fat: 0.2,\n      carbs: 98,\n      protein: 0,\n      iron: '2',\n    },\n    {\n      name: 'Cupcake',\n      calories: 305,\n      fat: 3.7,\n      carbs: 67,\n      protein: 4.3,\n      iron: '8',\n    },\n    {\n      name: 'Honeycomb',\n      calories: 408,\n      fat: 3.2,\n      carbs: 87,\n      protein: 6.5,\n      iron: '45',\n    },\n    {\n      name: 'Donut',\n      calories: 452,\n      fat: 25.0,\n      carbs: 51,\n      protein: 4.9,\n      iron: '22',\n    },\n  ]\n\n  const FakeAPI = {\n    async fetch ({ page, itemsPerPage, sortBy, search }) {\n      return new Promise(resolve => {\n        setTimeout(() => {\n          const start = (page - 1) * itemsPerPage\n          const end = start + itemsPerPage\n          const items = desserts.slice().filter(item => {\n            if (search.name && !item.name.toLowerCase().includes(search.name.toLowerCase())) {\n              return false\n            }\n\n            // eslint-disable-next-line sonarjs/prefer-single-boolean-return\n            if (search.calories && !(item.calories >= Number(search.calories))) {\n              return false\n            }\n\n            return true\n          })\n\n          if (sortBy.length) {\n            const sortKey = sortBy[0].key\n            const sortOrder = sortBy[0].order\n            items.sort((a, b) => {\n              const aValue = a[sortKey]\n              const bValue = b[sortKey]\n              return sortOrder === 'desc' ? bValue - aValue : aValue - bValue\n            })\n          }\n\n          const paginated = items.slice(start, end)\n\n          resolve({ items: paginated, total: items.length })\n        }, 500)\n      })\n    },\n  }\n\n  export default {\n    data: () => ({\n      itemsPerPage: 5,\n      headers: [\n        {\n          title: 'Dessert (100g serving)',\n          align: 'start',\n          sortable: false,\n          key: 'name',\n        },\n        { title: 'Calories', key: 'calories', align: 'end' },\n        { title: 'Fat (g)', key: 'fat', align: 'end' },\n        { title: 'Carbs (g)', key: 'carbs', align: 'end' },\n        { title: 'Protein (g)', key: 'protein', align: 'end' },\n        { title: 'Iron (%)', key: 'iron', align: 'end' },\n      ],\n      serverItems: [],\n      loading: true,\n      totalItems: 0,\n      name: '',\n      calories: '',\n      search: '',\n    }),\n    watch: {\n      name () {\n        this.search = String(Date.now())\n      },\n      calories () {\n        this.search = String(Date.now())\n      },\n    },\n    methods: {\n      loadItems ({ page, itemsPerPage, sortBy }) {\n        this.loading = true\n        FakeAPI.fetch({ page, itemsPerPage, sortBy, search: { name: this.name, calories: this.calories } }).then(({ items, total }) => {\n          this.serverItems = items\n          this.totalItems = total\n          this.loading = false\n        })\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/server.vue",
    "content": "<template>\n  <v-data-table-server\n    v-model:items-per-page=\"itemsPerPage\"\n    :headers=\"headers\"\n    :items=\"serverItems\"\n    :items-length=\"totalItems\"\n    :loading=\"loading\"\n    item-value=\"name\"\n    @update:options=\"loadItems\"\n  ></v-data-table-server>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const cars = [\n    {\n      name: 'Ford Mustang',\n      horsepower: 450,\n      fuel: 'Gasoline',\n      origin: 'USA',\n      price: 55000,\n    },\n    {\n      name: 'Tesla Model S',\n      horsepower: 670,\n      fuel: 'Electric',\n      origin: 'USA',\n      price: 79999,\n    },\n    {\n      name: 'BMW M3',\n      horsepower: 503,\n      fuel: 'Gasoline',\n      origin: 'Germany',\n      price: 70000,\n    },\n    {\n      name: 'Audi RS6',\n      horsepower: 591,\n      fuel: 'Gasoline',\n      origin: 'Germany',\n      price: 109000,\n    },\n    {\n      name: 'Chevrolet Camaro',\n      horsepower: 650,\n      fuel: 'Gasoline',\n      origin: 'USA',\n      price: 62000,\n    },\n    {\n      name: 'Porsche 911',\n      horsepower: 379,\n      fuel: 'Gasoline',\n      origin: 'Germany',\n      price: 101000,\n    },\n    {\n      name: 'Jaguar F-Type',\n      horsepower: 575,\n      fuel: 'Gasoline',\n      origin: 'UK',\n      price: 61000,\n    },\n    {\n      name: 'Mazda MX-5',\n      horsepower: 181,\n      fuel: 'Gasoline',\n      origin: 'Japan',\n      price: 26000,\n    },\n    {\n      name: 'Nissan GT-R',\n      horsepower: 565,\n      fuel: 'Gasoline',\n      origin: 'Japan',\n      price: 113540,\n    },\n    {\n      name: 'Mercedes-AMG GT',\n      horsepower: 523,\n      fuel: 'Gasoline',\n      origin: 'Germany',\n      price: 115900,\n    },\n  ]\n\n  const FakeAPI = {\n    async fetch ({ page, itemsPerPage, sortBy }) {\n      return new Promise(resolve => {\n        setTimeout(() => {\n          const start = (page - 1) * itemsPerPage\n          const end = start + itemsPerPage\n          const items = cars.slice()\n          if (sortBy.length) {\n            const sortKey = sortBy[0].key\n            const sortOrder = sortBy[0].order\n            items.sort((a, b) => {\n              const aValue = a[sortKey]\n              const bValue = b[sortKey]\n              return sortOrder === 'desc' ? bValue - aValue : aValue - bValue\n            })\n          }\n          const paginated = items.slice(start, end)\n          resolve({ items: paginated, total: items.length })\n        }, 500)\n      })\n    },\n  }\n  const itemsPerPage = ref(5)\n  const headers = ref([\n    { title: 'Car Model', key: 'name', align: 'start' },\n    { title: 'Horsepower', key: 'horsepower', align: 'end' },\n    { title: 'Fuel Type', key: 'fuel', align: 'start' },\n    { title: 'Origin', key: 'origin', align: 'start' },\n    { title: 'Price ($)', key: 'price', align: 'end' },\n  ])\n  const serverItems = ref([])\n  const loading = ref(true)\n  const totalItems = ref(0)\n  function loadItems ({ page, itemsPerPage, sortBy }) {\n    loading.value = true\n    FakeAPI.fetch({ page, itemsPerPage, sortBy }).then(({ items, total }) => {\n      serverItems.value = items\n      totalItems.value = total\n      loading.value = false\n    })\n  }\n</script>\n\n<script>\n  const desserts = [\n    {\n      name: 'Frozen Yogurt',\n      calories: 159,\n      fat: 6.0,\n      carbs: 24,\n      protein: 4.0,\n      iron: '1',\n    },\n    {\n      name: 'Jelly bean',\n      calories: 375,\n      fat: 0.0,\n      carbs: 94,\n      protein: 0.0,\n      iron: '0',\n    },\n    {\n      name: 'KitKat',\n      calories: 518,\n      fat: 26.0,\n      carbs: 65,\n      protein: 7,\n      iron: '6',\n    },\n    {\n      name: 'Eclair',\n      calories: 262,\n      fat: 16.0,\n      carbs: 23,\n      protein: 6.0,\n      iron: '7',\n    },\n    {\n      name: 'Gingerbread',\n      calories: 356,\n      fat: 16.0,\n      carbs: 49,\n      protein: 3.9,\n      iron: '16',\n    },\n    {\n      name: 'Ice cream sandwich',\n      calories: 237,\n      fat: 9.0,\n      carbs: 37,\n      protein: 4.3,\n      iron: '1',\n    },\n    {\n      name: 'Lollipop',\n      calories: 392,\n      fat: 0.2,\n      carbs: 98,\n      protein: 0,\n      iron: '2',\n    },\n    {\n      name: 'Cupcake',\n      calories: 305,\n      fat: 3.7,\n      carbs: 67,\n      protein: 4.3,\n      iron: '8',\n    },\n    {\n      name: 'Honeycomb',\n      calories: 408,\n      fat: 3.2,\n      carbs: 87,\n      protein: 6.5,\n      iron: '45',\n    },\n    {\n      name: 'Donut',\n      calories: 452,\n      fat: 25.0,\n      carbs: 51,\n      protein: 4.9,\n      iron: '22',\n    },\n  ]\n\n  const FakeAPI = {\n    async fetch ({ page, itemsPerPage, sortBy }) {\n      return new Promise(resolve => {\n        setTimeout(() => {\n          const start = (page - 1) * itemsPerPage\n          const end = start + itemsPerPage\n          const items = desserts.slice()\n\n          if (sortBy.length) {\n            const sortKey = sortBy[0].key\n            const sortOrder = sortBy[0].order\n            items.sort((a, b) => {\n              const aValue = a[sortKey]\n              const bValue = b[sortKey]\n              return sortOrder === 'desc' ? bValue - aValue : aValue - bValue\n            })\n          }\n\n          const paginated = items.slice(start, end)\n\n          resolve({ items: paginated, total: items.length })\n        }, 500)\n      })\n    },\n  }\n\n  export default {\n    data: () => ({\n      itemsPerPage: 5,\n      headers: [\n        {\n          title: 'Dessert (100g serving)',\n          align: 'start',\n          sortable: false,\n          key: 'name',\n        },\n        { title: 'Calories', key: 'calories', align: 'end' },\n        { title: 'Fat (g)', key: 'fat', align: 'end' },\n        { title: 'Carbs (g)', key: 'carbs', align: 'end' },\n        { title: 'Protein (g)', key: 'protein', align: 'end' },\n        { title: 'Iron (%)', key: 'iron', align: 'end' },\n      ],\n      serverItems: [],\n      loading: true,\n      totalItems: 0,\n    }),\n    methods: {\n      loadItems ({ page, itemsPerPage, sortBy }) {\n        this.loading = true\n        FakeAPI.fetch({ page, itemsPerPage, sortBy }).then(({ items, total }) => {\n          this.serverItems = items\n          this.totalItems = total\n          this.loading = false\n        })\n      },\n    },\n  }\n</script>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2139-110365&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/slot-group-header.vue",
    "content": "<template>\n  <v-data-table\n    :group-by=\"groupBy\"\n    :headers=\"headers\"\n    :items=\"tools\"\n    :items-per-page=\"-1\"\n    item-value=\"name\"\n    hide-default-footer\n  >\n    <template v-slot:group-header=\"{ item, columns, toggleGroup, isGroupOpen }\">\n      <tr>\n        <td\n          :colspan=\"columns.length\"\n          class=\"cursor-pointer\"\n          v-ripple\n          @click=\"toggleGroup(item)\"\n        >\n          <div class=\"d-flex align-center\">\n            <v-btn\n              :icon=\"isGroupOpen(item) ? '$expand' : '$next'\"\n              color=\"medium-emphasis\"\n              density=\"comfortable\"\n              size=\"small\"\n              variant=\"outlined\"\n            ></v-btn>\n\n            <span class=\"ms-4\">Tool Type: {{ item.value }}</span>\n          </div>\n        </td>\n      </tr>\n    </template>\n  </v-data-table>\n</template>\n\n<script setup>\n  const groupBy = [{ key: 'type', order: 'asc' }]\n\n  const headers = [\n    {\n      title: 'Tool Name',\n      align: 'start',\n      sortable: false,\n      key: 'name',\n    },\n    { title: 'Weight(kg)', key: 'weight' },\n    { title: 'Length(cm)', key: 'length' },\n    { title: 'Price($)', key: 'price' },\n  ]\n\n  const tools = [\n    { name: 'Hammer', weight: 0.5, length: 30, price: 10, type: 'hand' },\n    { name: 'Screwdriver', weight: 0.2, length: 20, price: 5, type: 'hand' },\n    { name: 'Drill', weight: 1.5, length: 25, price: 50, type: 'power' },\n    { name: 'Saw', weight: 0.7, length: 50, price: 15, type: 'hand' },\n    { name: 'Tape Measure', weight: 0.3, length: 10, price: 8, type: 'measuring' },\n    { name: 'Level', weight: 0.4, length: 60, price: 12, type: 'measuring' },\n    { name: 'Wrench', weight: 0.6, length: 25, price: 10, type: 'hand' },\n    { name: 'Pliers', weight: 0.3, length: 15, price: 7, type: 'hand' },\n    { name: 'Sander', weight: 2.0, length: 30, price: 60, type: 'power' },\n    { name: 'Multimeter', weight: 0.5, length: 15, price: 30, type: 'measuring' },\n  ]\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        groupBy: [\n          {\n            key: 'type',\n            order: 'asc',\n          },\n        ],\n        headers: [\n          {\n            title: 'Tool Name',\n            align: 'start',\n            sortable: false,\n            key: 'name',\n          },\n          { title: 'Weight (kg)', key: 'weight' },\n          { title: 'Length (cm)', key: 'length' },\n          { title: 'Price ($)', key: 'price' },\n        ],\n        tools: [\n          { name: 'Hammer', weight: 0.5, length: 30, price: 10, type: 'hand' },\n          { name: 'Screwdriver', weight: 0.2, length: 20, price: 5, type: 'hand' },\n          { name: 'Drill', weight: 1.5, length: 25, price: 50, type: 'power' },\n          { name: 'Saw', weight: 0.7, length: 50, price: 15, type: 'hand' },\n          { name: 'Tape Measure', weight: 0.3, length: 10, price: 8, type: 'measuring' },\n          { name: 'Level', weight: 0.4, length: 60, price: 12, type: 'measuring' },\n          { name: 'Wrench', weight: 0.6, length: 25, price: 10, type: 'hand' },\n          { name: 'Pliers', weight: 0.3, length: 15, price: 7, type: 'hand' },\n          { name: 'Sander', weight: 2.0, length: 30, price: 60, type: 'power' },\n          { name: 'Multimeter', weight: 0.5, length: 15, price: 30, type: 'measuring' },\n        ],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/slot-group-summary.vue",
    "content": "<template>\n  <v-data-table\n    :group-by=\"groupBy\"\n    :headers=\"headers\"\n    :items=\"tools\"\n    :items-per-page=\"-1\"\n    item-value=\"name\"\n    hide-default-footer\n  >\n    <template v-slot:group-summary=\"{ item, columns }\">\n      <tr class=\"font-weight-bold text-red\">\n        <td v-for=\"c in columns\" :key=\"c.key\" :class=\"['v-data-table__td', c.align ? `v-data-table-column--align-${c.align}` : '']\">\n          <span v-if=\"c.key === 'name'\">Totals</span>\n          <span v-if=\"c.key === 'weight'\">{{ item.items.reduce((sum, n) => sum + n.raw.weight, 0) }}</span>\n          <span v-if=\"c.key === 'length'\">{{ item.items.reduce((sum, n) => sum + n.raw.length, 0) }}</span>\n          <span v-if=\"c.key === 'price'\">{{ item.items.reduce((sum, n) => sum + n.raw.price, 0) }}</span>\n        </td>\n      </tr>\n    </template>\n  </v-data-table>\n</template>\n\n<script setup>\n  const groupBy = [{ key: 'type', order: 'asc' }]\n\n  const headers = [\n    { title: 'Tool Name', sortable: false, key: 'name' },\n    { title: 'Weight(kg)', key: 'weight', align: 'end' },\n    { title: 'Length(cm)', key: 'length', align: 'end' },\n    { title: 'Price($)', key: 'price', align: 'end' },\n  ]\n\n  const tools = [\n    { name: 'Hammer', weight: 0.5, length: 30, price: 10, type: 'hand' },\n    { name: 'Screwdriver', weight: 0.2, length: 20, price: 5, type: 'hand' },\n    { name: 'Drill', weight: 1.5, length: 25, price: 50, type: 'power' },\n    { name: 'Saw', weight: 0.7, length: 50, price: 15, type: 'hand' },\n    { name: 'Tape Measure', weight: 0.3, length: 10, price: 8, type: 'measuring' },\n    { name: 'Level', weight: 0.4, length: 60, price: 12, type: 'measuring' },\n    { name: 'Wrench', weight: 0.6, length: 25, price: 10, type: 'hand' },\n    { name: 'Pliers', weight: 0.3, length: 15, price: 7, type: 'hand' },\n    { name: 'Sander', weight: 2.0, length: 30, price: 60, type: 'power' },\n    { name: 'Multimeter', weight: 0.5, length: 15, price: 30, type: 'measuring' },\n  ]\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        groupBy: [{ key: 'type', order: 'asc' }],\n        headers: [\n          { title: 'Tool Name', sortable: false, key: 'name' },\n          { title: 'Weight(kg)', key: 'weight', align: 'end' },\n          { title: 'Length(cm)', key: 'length', align: 'end' },\n          { title: 'Price($)', key: 'price', align: 'end' },\n        ],\n        tools: [\n          { name: 'Hammer', weight: 0.5, length: 30, price: 10, type: 'hand' },\n          { name: 'Screwdriver', weight: 0.2, length: 20, price: 5, type: 'hand' },\n          { name: 'Drill', weight: 1.5, length: 25, price: 50, type: 'power' },\n          { name: 'Saw', weight: 0.7, length: 50, price: 15, type: 'hand' },\n          { name: 'Tape Measure', weight: 0.3, length: 10, price: 8, type: 'measuring' },\n          { name: 'Level', weight: 0.4, length: 60, price: 12, type: 'measuring' },\n          { name: 'Wrench', weight: 0.6, length: 25, price: 10, type: 'hand' },\n          { name: 'Pliers', weight: 0.3, length: 15, price: 7, type: 'hand' },\n          { name: 'Sander', weight: 2.0, length: 30, price: 60, type: 'power' },\n          { name: 'Multimeter', weight: 0.5, length: 15, price: 30, type: 'measuring' },\n        ],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/slot-header.vue",
    "content": "<template>\n  <v-data-table :items=\"items\">\n    <template v-slot:header.id=\"{ column }\">\n      {{ column.title.toUpperCase() }}\n    </template>\n  </v-data-table>\n</template>\n\n<script setup>\n  const items = [\n    {\n      id: 1,\n      name: 'T-Shirt',\n      size: 'M',\n      color: 'Red',\n      price: 19.99,\n      quantity: 10,\n    },\n    {\n      id: 2,\n      name: 'Jeans',\n      size: '32',\n      color: 'Blue',\n      price: 49.99,\n      quantity: 5,\n    },\n    {\n      id: 3,\n      name: 'Sweater',\n      size: 'L',\n      color: 'Green',\n      price: 29.99,\n      quantity: 7,\n    },\n    {\n      id: 4,\n      name: 'Jacket',\n      size: 'XL',\n      color: 'Black',\n      price: 89.99,\n      quantity: 3,\n    },\n    {\n      id: 5,\n      name: 'Socks',\n      size: 'One Size',\n      color: 'White',\n      price: 9.99,\n      quantity: 20,\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        {\n          id: 1,\n          name: 'T-Shirt',\n          size: 'M',\n          color: 'Red',\n          price: 19.99,\n          quantity: 10,\n        },\n        {\n          id: 2,\n          name: 'Jeans',\n          size: '32',\n          color: 'Blue',\n          price: 49.99,\n          quantity: 5,\n        },\n        {\n          id: 3,\n          name: 'Sweater',\n          size: 'L',\n          color: 'Green',\n          price: 29.99,\n          quantity: 7,\n        },\n        {\n          id: 4,\n          name: 'Jacket',\n          size: 'XL',\n          color: 'Black',\n          price: 89.99,\n          quantity: 3,\n        },\n        {\n          id: 5,\n          name: 'Socks',\n          size: 'One Size',\n          color: 'White',\n          price: 9.99,\n          quantity: 20,\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/slot-headers.vue",
    "content": "<template>\n  <v-data-table\n    :headers=\"headers\"\n    :items=\"desserts\"\n    item-value=\"name\"\n    items-per-page=\"5\"\n    hover\n  >\n    <template v-slot:top>\n      <v-expand-transition>\n        <div v-if=\"headers.length < 6\">\n          <v-btn\n            class=\"mb-2\"\n            rounded=\"lg\"\n            size=\"small\"\n            text=\"Reset\"\n            variant=\"text\"\n            block\n            border\n            @click=\"onClickReset\"\n          ></v-btn>\n\n          <v-divider></v-divider>\n        </div>\n      </v-expand-transition>\n    </template>\n\n    <template v-slot:headers=\"{ columns, isSorted, getSortIcon, toggleSort }\">\n      <tr>\n        <template v-for=\"column in columns\" :key=\"column.key\">\n          <th>\n            <div class=\"d-flex align-center\">\n              <span\n                class=\"me-2 cursor-pointer\"\n                @click=\"toggleSort(column)\"\n                v-text=\"column.title\"\n              ></span>\n\n              <v-icon\n                v-if=\"isSorted(column)\"\n                :icon=\"getSortIcon(column)\"\n                color=\"medium-emphasis\"\n              ></v-icon>\n\n              <v-icon\n                v-if=\"column.removable\"\n                color=\"medium-emphasis\"\n                icon=\"$close\"\n                @click=\"remove(column.key)\"\n              ></v-icon>\n            </div>\n          </th>\n        </template>\n      </tr>\n    </template>\n  </v-data-table>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  function DEFAULT_HEADERS () {\n    return [\n      {\n        title: 'Dessert',\n        align: 'start',\n        key: 'name',\n        sortable: false,\n        removable: false,\n      },\n      { title: 'Calories', key: 'calories', removable: true },\n      { title: 'Fat(g)', key: 'fat', removable: true },\n      { title: 'Carbs(g)', key: 'carbs', removable: true },\n      { title: 'Protein(g)', key: 'protein', removable: true },\n      { title: 'Iron(%)', key: 'iron', removable: true },\n    ]\n  }\n\n  const headers = ref(DEFAULT_HEADERS())\n\n  const desserts = [\n    {\n      name: 'Frozen Yogurt',\n      calories: 159,\n      fat: 6,\n      carbs: 24,\n      protein: 4,\n      iron: 1,\n    },\n    {\n      name: 'Ice cream sandwich',\n      calories: 237,\n      fat: 9,\n      carbs: 37,\n      protein: 4.3,\n      iron: 1,\n    },\n    {\n      name: 'Eclair',\n      calories: 262,\n      fat: 16,\n      carbs: 23,\n      protein: 6,\n      iron: 7,\n    },\n    {\n      name: 'Cupcake',\n      calories: 305,\n      fat: 3.7,\n      carbs: 67,\n      protein: 4.3,\n      iron: 8,\n    },\n    {\n      name: 'Gingerbread',\n      calories: 356,\n      fat: 16,\n      carbs: 49,\n      protein: 3.9,\n      iron: 16,\n    },\n    {\n      name: 'Jelly bean',\n      calories: 375,\n      fat: 0,\n      carbs: 94,\n      protein: 0,\n      iron: 0,\n    },\n    {\n      name: 'Lollipop',\n      calories: 392,\n      fat: 0.2,\n      carbs: 98,\n      protein: 0,\n      iron: 2,\n    },\n    {\n      name: 'Honeycomb',\n      calories: 408,\n      fat: 3.2,\n      carbs: 87,\n      protein: 6.5,\n      iron: 45,\n    },\n    {\n      name: 'Donut',\n      calories: 452,\n      fat: 25,\n      carbs: 51,\n      protein: 4.9,\n      iron: 22,\n    },\n    {\n      name: 'KitKat',\n      calories: 518,\n      fat: 26,\n      carbs: 65,\n      protein: 7,\n      iron: 6,\n    },\n  ]\n\n  function onClickReset () {\n    headers.value = DEFAULT_HEADERS()\n  }\n\n  function remove (key) {\n    headers.value = headers.value.filter(header => header.key !== key)\n  }\n</script>\n\n<script>\n  function DEFAULT_HEADERS () {\n    return [\n      {\n        title: 'Dessert',\n        align: 'start',\n        key: 'name',\n        sortable: false,\n        removable: false,\n      },\n      { title: 'Calories', key: 'calories', removable: true },\n      { title: 'Fat(g)', key: 'fat', removable: true },\n      { title: 'Carbs(g)', key: 'carbs', removable: true },\n      { title: 'Protein(g)', key: 'protein', removable: true },\n      { title: 'Iron(%)', key: 'iron', removable: true },\n    ]\n  }\n\n  export default {\n    data: () => ({\n      headers: DEFAULT_HEADERS(),\n      desserts: [\n        {\n          name: 'Frozen Yogurt',\n          calories: 159,\n          fat: 6.0,\n          carbs: 24,\n          protein: 4.0,\n          iron: 1,\n        },\n        {\n          name: 'Ice cream sandwich',\n          calories: 237,\n          fat: 9.0,\n          carbs: 37,\n          protein: 4.3,\n          iron: 1,\n        },\n        {\n          name: 'Eclair',\n          calories: 262,\n          fat: 16.0,\n          carbs: 23,\n          protein: 6.0,\n          iron: 7,\n        },\n        {\n          name: 'Cupcake',\n          calories: 305,\n          fat: 3.7,\n          carbs: 67,\n          protein: 4.3,\n          iron: 8,\n        },\n        {\n          name: 'Gingerbread',\n          calories: 356,\n          fat: 16.0,\n          carbs: 49,\n          protein: 3.9,\n          iron: 16,\n        },\n        {\n          name: 'Jelly bean',\n          calories: 375,\n          fat: 0.0,\n          carbs: 94,\n          protein: 0.0,\n          iron: 0,\n        },\n        {\n          name: 'Lollipop',\n          calories: 392,\n          fat: 0.2,\n          carbs: 98,\n          protein: 0,\n          iron: 2,\n        },\n        {\n          name: 'Honeycomb',\n          calories: 408,\n          fat: 3.2,\n          carbs: 87,\n          protein: 6.5,\n          iron: 45,\n        },\n        {\n          name: 'Donut',\n          calories: 452,\n          fat: 25.0,\n          carbs: 51,\n          protein: 4.9,\n          iron: 22,\n        },\n        {\n          name: 'KitKat',\n          calories: 518,\n          fat: 26.0,\n          carbs: 65,\n          protein: 7,\n          iron: 6,\n        },\n      ],\n    }),\n    methods: {\n      onClickReset () {\n        this.headers = DEFAULT_HEADERS()\n      },\n      remove (key) {\n        this.headers = this.headers.filter(header => header.key !== key)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/slot-item-data-table-select.vue",
    "content": "<template>\n  <v-data-table\n    :items=\"desserts\"\n    item-value=\"name\"\n    show-select\n  >\n    <template v-slot:header.data-table-select=\"{ allSelected, selectAll, someSelected }\">\n      <v-checkbox-btn\n        :indeterminate=\"someSelected && !allSelected\"\n        :model-value=\"allSelected\"\n        color=\"primary\"\n        @update:model-value=\"selectAll(!allSelected)\"\n      ></v-checkbox-btn>\n    </template>\n\n    <template v-slot:item.data-table-select=\"{ internalItem, isSelected, toggleSelect }\">\n      <v-checkbox-btn\n        :model-value=\"isSelected(internalItem)\"\n        color=\"primary\"\n        @update:model-value=\"toggleSelect(internalItem)\"\n      ></v-checkbox-btn>\n    </template>\n  </v-data-table>\n</template>\n\n<script setup>\n  const desserts = [\n    {\n      name: 'Frozen Yogurt',\n      calories: 159,\n      fat: 6,\n      carbs: 24,\n      protein: 4,\n      iron: 1,\n    },\n    {\n      name: 'Ice cream sandwich',\n      calories: 237,\n      fat: 9,\n      carbs: 37,\n      protein: 4.3,\n      iron: 1,\n    },\n    {\n      name: 'Eclair',\n      calories: 262,\n      fat: 16,\n      carbs: 23,\n      protein: 6,\n      iron: 7,\n    },\n    {\n      name: 'Cupcake',\n      calories: 305,\n      fat: 3.7,\n      carbs: 67,\n      protein: 4.3,\n      iron: 8,\n    },\n    {\n      name: 'Gingerbread',\n      calories: 356,\n      fat: 16,\n      carbs: 49,\n      protein: 3.9,\n      iron: 16,\n    },\n    {\n      name: 'Jelly bean',\n      calories: 375,\n      fat: 0,\n      carbs: 94,\n      protein: 0,\n      iron: 0,\n    },\n    {\n      name: 'Lollipop',\n      calories: 392,\n      fat: 0.2,\n      carbs: 98,\n      protein: 0,\n      iron: 2,\n    },\n    {\n      name: 'Honeycomb',\n      calories: 408,\n      fat: 3.2,\n      carbs: 87,\n      protein: 6.5,\n      iron: 45,\n    },\n    {\n      name: 'Donut',\n      calories: 452,\n      fat: 25,\n      carbs: 51,\n      protein: 4.9,\n      iron: 22,\n    },\n    {\n      name: 'KitKat',\n      calories: 518,\n      fat: 26,\n      carbs: 65,\n      protein: 7,\n      iron: 6,\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        desserts: [\n          {\n            name: 'Frozen Yogurt',\n            calories: 159,\n            fat: 6.0,\n            carbs: 24,\n            protein: 4.0,\n            iron: 1,\n          },\n          {\n            name: 'Ice cream sandwich',\n            calories: 237,\n            fat: 9.0,\n            carbs: 37,\n            protein: 4.3,\n            iron: 1,\n          },\n          {\n            name: 'Eclair',\n            calories: 262,\n            fat: 16.0,\n            carbs: 23,\n            protein: 6.0,\n            iron: 7,\n          },\n          {\n            name: 'Cupcake',\n            calories: 305,\n            fat: 3.7,\n            carbs: 67,\n            protein: 4.3,\n            iron: 8,\n          },\n          {\n            name: 'Gingerbread',\n            calories: 356,\n            fat: 16.0,\n            carbs: 49,\n            protein: 3.9,\n            iron: 16,\n          },\n          {\n            name: 'Jelly bean',\n            calories: 375,\n            fat: 0.0,\n            carbs: 94,\n            protein: 0.0,\n            iron: 0,\n          },\n          {\n            name: 'Lollipop',\n            calories: 392,\n            fat: 0.2,\n            carbs: 98,\n            protein: 0,\n            iron: 2,\n          },\n          {\n            name: 'Honeycomb',\n            calories: 408,\n            fat: 3.2,\n            carbs: 87,\n            protein: 6.5,\n            iron: 45,\n          },\n          {\n            name: 'Donut',\n            calories: 452,\n            fat: 25.0,\n            carbs: 51,\n            protein: 4.9,\n            iron: 22,\n          },\n          {\n            name: 'KitKat',\n            calories: 518,\n            fat: 26.0,\n            carbs: 65,\n            protein: 7,\n            iron: 6,\n          },\n        ],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/slot-item-key.vue",
    "content": "<template>\n  <v-data-table\n    :headers=\"headers\"\n    :items=\"vegetables\"\n  >\n    <template v-slot:item.calories=\"{ value }\">\n      <v-chip\n        :border=\"`${getColor(value)} thin opacity-25`\"\n        :color=\"getColor(value)\"\n        :text=\"value\"\n        size=\"x-small\"\n      ></v-chip>\n    </template>\n  </v-data-table>\n</template>\n\n<script setup>\n  const headers = [\n    { title: 'Vegetable', key: 'name' },\n    { title: 'Calories', key: 'calories' },\n    { title: 'Fat(g)', key: 'fat' },\n    { title: 'Carbs(g)', key: 'carbs' },\n    { title: 'Protein(g)', key: 'protein' },\n    { title: 'Iron(%)', key: 'iron' },\n  ]\n  const vegetables = [\n    {\n      name: 'Spinach',\n      calories: 23,\n      fat: 0.4,\n      carbs: 3.6,\n      protein: 2.9,\n      iron: '15%',\n    },\n    {\n      name: 'Kael',\n      calories: 49,\n      fat: 0.9,\n      carbs: 8.8,\n      protein: 4.3,\n      iron: '16%',\n    },\n    {\n      name: 'Broccoli',\n      calories: 34,\n      fat: 0.4,\n      carbs: 6.6,\n      protein: 2.8,\n      iron: '6%',\n    },\n    {\n      name: 'Brussels Sprouts',\n      calories: 43,\n      fat: 0.3,\n      carbs: 8.9,\n      protein: 3.4,\n      iron: '9%',\n    },\n    {\n      name: 'Avocado',\n      calories: 160,\n      fat: 15,\n      carbs: 9,\n      protein: 2,\n      iron: '3%',\n    },\n    {\n      name: 'Sweet Potato',\n      calories: 86,\n      fat: 0.1,\n      carbs: 20.1,\n      protein: 1.6,\n      iron: '3%',\n    },\n    {\n      name: 'Corn',\n      calories: 96,\n      fat: 1.5,\n      carbs: 21,\n      protein: 3.4,\n      iron: '2%',\n    },\n    {\n      name: 'Potato',\n      calories: 77,\n      fat: 0.1,\n      carbs: 17.5,\n      protein: 2,\n      iron: '8%',\n    },\n    {\n      name: 'Butternut Squash',\n      calories: 45,\n      fat: 0.1,\n      carbs: 11.7,\n      protein: 1,\n      iron: '4%',\n    },\n    {\n      name: 'Beetroot',\n      calories: 43,\n      fat: 0.2,\n      carbs: 10,\n      protein: 1.6,\n      iron: '6%',\n    },\n    {\n      name: 'Parsnip',\n      calories: 75,\n      fat: 0.3,\n      carbs: 18,\n      protein: 1.2,\n      iron: '4%',\n    },\n    {\n      name: 'Yam',\n      calories: 118,\n      fat: 0.2,\n      carbs: 27.9,\n      protein: 1.5,\n      iron: '4%',\n    },\n    {\n      name: 'Acorn Squash',\n      calories: 40,\n      fat: 0.1,\n      carbs: 10,\n      protein: 1,\n      iron: '5%',\n    },\n    {\n      name: 'Artichoke',\n      calories: 47,\n      fat: 0.2,\n      carbs: 10.5,\n      protein: 3.3,\n      iron: '7%',\n    },\n    {\n      name: 'Peas',\n      calories: 81,\n      fat: 0.4,\n      carbs: 14.5,\n      protein: 5.4,\n      iron: '25%',\n    },\n    {\n      name: 'Green Beans',\n      calories: 31,\n      fat: 0.1,\n      carbs: 6.9,\n      protein: 1.8,\n      iron: '8%',\n    },\n    {\n      name: 'Red Bell Pepper',\n      calories: 26,\n      fat: 0.2,\n      carbs: 6.0,\n      protein: 1.0,\n      iron: '3%',\n    },\n    {\n      name: 'Cauliflower',\n      calories: 25,\n      fat: 0.1,\n      carbs: 5.0,\n      protein: 1.9,\n      iron: '4%',\n    },\n    {\n      name: 'Zucchini',\n      calories: 17,\n      fat: 0.3,\n      carbs: 3.1,\n      protein: 1.2,\n      iron: '3%',\n    },\n    {\n      name: 'Asparagus',\n      calories: 20,\n      fat: 0.1,\n      carbs: 3.9,\n      protein: 2.2,\n      iron: '16%',\n    },\n    {\n      name: 'Eggplant',\n      calories: 25,\n      fat: 0.2,\n      carbs: 6,\n      protein: 1,\n      iron: '1%',\n    },\n    {\n      name: 'Pumpkin',\n      calories: 26,\n      fat: 0.1,\n      carbs: 6.5,\n      protein: 1,\n      iron: '4%',\n    },\n    {\n      name: 'Celery',\n      calories: 16,\n      fat: 0.2,\n      carbs: 3,\n      protein: 0.7,\n      iron: '1%',\n    },\n    {\n      name: 'Cucumber',\n      calories: 15,\n      fat: 0.1,\n      carbs: 3.6,\n      protein: 0.7,\n      iron: '2%',\n    },\n    {\n      name: 'Leek',\n      calories: 61,\n      fat: 0.3,\n      carbs: 14.2,\n      protein: 1.5,\n      iron: '12%',\n    },\n    {\n      name: 'Fennel',\n      calories: 31,\n      fat: 0.2,\n      carbs: 7,\n      protein: 1.2,\n      iron: '6%',\n    },\n    {\n      name: 'Green Peas',\n      calories: 81,\n      fat: 0.4,\n      carbs: 14.5,\n      protein: 5.4,\n      iron: '25%',\n    },\n    {\n      name: 'Okra',\n      calories: 33,\n      fat: 0.2,\n      carbs: 7.5,\n      protein: 1.9,\n      iron: '3%',\n    },\n    {\n      name: 'Chard',\n      calories: 19,\n      fat: 0.2,\n      carbs: 3.7,\n      protein: 1.8,\n      iron: '22%',\n    },\n    {\n      name: 'Collard Greens',\n      calories: 32,\n      fat: 0.6,\n      carbs: 5.4,\n      protein: 3,\n      iron: '2%',\n    },\n  ]\n\n  function getColor (calories) {\n    if (calories > 100) return 'error'\n    else if (calories > 50) return 'warning'\n    else return 'success'\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      headers: [\n        { title: 'Vegetable', key: 'name' },\n        { title: 'Calories', key: 'calories' },\n        { title: 'Fat(g)', key: 'fat' },\n        { title: 'Carbs(g)', key: 'carbs' },\n        { title: 'Protein(g)', key: 'protein' },\n        { title: 'Iron(%)', key: 'iron' },\n      ],\n      vegetables: [\n        {\n          name: 'Spinach',\n          calories: 23,\n          fat: 0.4,\n          carbs: 3.6,\n          protein: 2.9,\n          iron: '15%',\n        },\n        {\n          name: 'Kael',\n          calories: 49,\n          fat: 0.9,\n          carbs: 8.8,\n          protein: 4.3,\n          iron: '16%',\n        },\n        {\n          name: 'Broccoli',\n          calories: 34,\n          fat: 0.4,\n          carbs: 6.6,\n          protein: 2.8,\n          iron: '6%',\n        },\n        {\n          name: 'Brussels Sprouts',\n          calories: 43,\n          fat: 0.3,\n          carbs: 8.9,\n          protein: 3.4,\n          iron: '9%',\n        },\n        {\n          name: 'Avocado',\n          calories: 160,\n          fat: 15,\n          carbs: 9,\n          protein: 2,\n          iron: '3%',\n        },\n        {\n          name: 'Sweet Potato',\n          calories: 86,\n          fat: 0.1,\n          carbs: 20.1,\n          protein: 1.6,\n          iron: '3%',\n        },\n        {\n          name: 'Corn',\n          calories: 96,\n          fat: 1.5,\n          carbs: 21,\n          protein: 3.4,\n          iron: '2%',\n        },\n        {\n          name: 'Potato',\n          calories: 77,\n          fat: 0.1,\n          carbs: 17.5,\n          protein: 2,\n          iron: '8%',\n        },\n        {\n          name: 'Butternut Squash',\n          calories: 45,\n          fat: 0.1,\n          carbs: 11.7,\n          protein: 1,\n          iron: '4%',\n        },\n        {\n          name: 'Beetroot',\n          calories: 43,\n          fat: 0.2,\n          carbs: 10,\n          protein: 1.6,\n          iron: '6%',\n        },\n        {\n          name: 'Parsnip',\n          calories: 75,\n          fat: 0.3,\n          carbs: 18,\n          protein: 1.2,\n          iron: '4%',\n        },\n        {\n          name: 'Yam',\n          calories: 118,\n          fat: 0.2,\n          carbs: 27.9,\n          protein: 1.5,\n          iron: '4%',\n        },\n        {\n          name: 'Acorn Squash',\n          calories: 40,\n          fat: 0.1,\n          carbs: 10,\n          protein: 1,\n          iron: '5%',\n        },\n        {\n          name: 'Artichoke',\n          calories: 47,\n          fat: 0.2,\n          carbs: 10.5,\n          protein: 3.3,\n          iron: '7%',\n        },\n        {\n          name: 'Peas',\n          calories: 81,\n          fat: 0.4,\n          carbs: 14.5,\n          protein: 5.4,\n          iron: '25%',\n        },\n        {\n          name: 'Green Beans',\n          calories: 31,\n          fat: 0.1,\n          carbs: 6.9,\n          protein: 1.8,\n          iron: '8%',\n        },\n        {\n          name: 'Red Bell Pepper',\n          calories: 26,\n          fat: 0.2,\n          carbs: 6.0,\n          protein: 1.0,\n          iron: '3%',\n        },\n        {\n          name: 'Cauliflower',\n          calories: 25,\n          fat: 0.1,\n          carbs: 5.0,\n          protein: 1.9,\n          iron: '4%',\n        },\n        {\n          name: 'Zucchini',\n          calories: 17,\n          fat: 0.3,\n          carbs: 3.1,\n          protein: 1.2,\n          iron: '3%',\n        },\n        {\n          name: 'Asparagus',\n          calories: 20,\n          fat: 0.1,\n          carbs: 3.9,\n          protein: 2.2,\n          iron: '16%',\n        },\n        {\n          name: 'Eggplant',\n          calories: 25,\n          fat: 0.2,\n          carbs: 6,\n          protein: 1,\n          iron: '1%',\n        },\n        {\n          name: 'Pumpkin',\n          calories: 26,\n          fat: 0.1,\n          carbs: 6.5,\n          protein: 1,\n          iron: '4%',\n        },\n        {\n          name: 'Celery',\n          calories: 16,\n          fat: 0.2,\n          carbs: 3,\n          protein: 0.7,\n          iron: '1%',\n        },\n        {\n          name: 'Cucumber',\n          calories: 15,\n          fat: 0.1,\n          carbs: 3.6,\n          protein: 0.7,\n          iron: '2%',\n        },\n        {\n          name: 'Leek',\n          calories: 61,\n          fat: 0.3,\n          carbs: 14.2,\n          protein: 1.5,\n          iron: '12%',\n        },\n        {\n          name: 'Fennel',\n          calories: 31,\n          fat: 0.2,\n          carbs: 7,\n          protein: 1.2,\n          iron: '6%',\n        },\n        {\n          name: 'Green Peas',\n          calories: 81,\n          fat: 0.4,\n          carbs: 14.5,\n          protein: 5.4,\n          iron: '25%',\n        },\n        {\n          name: 'Okra',\n          calories: 33,\n          fat: 0.2,\n          carbs: 7.5,\n          protein: 1.9,\n          iron: '3%',\n        },\n        {\n          name: 'Chard',\n          calories: 19,\n          fat: 0.2,\n          carbs: 3.7,\n          protein: 1.8,\n          iron: '22%',\n        },\n        {\n          name: 'Collard Greens',\n          calories: 32,\n          fat: 0.6,\n          carbs: 5.4,\n          protein: 3,\n          iron: '2%',\n        },\n      ],\n    }),\n\n    methods: {\n      getColor (calories) {\n        if (calories > 100) return 'error'\n        else if (calories > 50) return 'warning'\n        else return 'success'\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/slot-item.vue",
    "content": "<template>\n  <v-data-table\n    :headers=\"headers\"\n    :items=\"employees\"\n    class=\"text-body-small\"\n    density=\"compact\"\n    item-value=\"name\"\n    hide-default-footer\n    hover\n  >\n    <template v-slot:item=\"{ item }\">\n      <tr class=\"text-no-wrap\">\n        <td>{{ item.id }}</td>\n        <td>{{ item.name }}</td>\n        <td>{{ item.department }}</td>\n        <td>{{ item.role }}</td>\n        <td\n          :class=\"{\n            'text-end': true,\n            'bg-success': item.salary > 80000,\n            'bg-warning': item.salary > 70000 && item.salary <= 80000,\n            'bg-error': item.salary <= 70000\n          }\"\n          v-text=\"`$${item.salary.toLocaleString()}`\"\n        ></td>\n        <td>{{ item.hireDate }}</td>\n        <td class=\"text-end\">{{ item.hoursPerWeek }}</td>\n        <td>{{ item.location }}</td>\n        <td>{{ item.status }}</td>\n        <td class=\"text-end\">\n          <v-chip\n            :text=\"item.score.toFixed(2)\"\n            append-icon=\"mdi-open-in-new\"\n            size=\"x-small\"\n            @click=\"\"\n          ></v-chip>\n        </td>\n      </tr>\n    </template>\n  </v-data-table>\n</template>\n\n<script setup>\n  const headers = [\n    { title: 'ID', key: 'id', align: 'start' },\n    { title: 'Name', key: 'name' },\n    { title: 'Dept', key: 'department' },\n    { title: 'Role', key: 'role' },\n    { title: 'Salary($)', key: 'salary', align: 'end' },\n    { title: 'HireDate', key: 'hireDate' },\n    { title: 'Hours/Wk', key: 'hoursPerWeek', align: 'end' },\n    { title: 'Location', key: 'location' },\n    { title: 'Status', key: 'status' },\n    { title: 'Score', key: 'score', align: 'end' },\n  ]\n  const employees = [\n    {\n      id: 'E001',\n      name: 'Alice Johnson',\n      department: 'Engineering',\n      role: 'Software Dev',\n      salary: 95000,\n      hireDate: '2020-03-15',\n      hoursPerWeek: 40,\n      location: 'New York',\n      status: 'Full-Time',\n      score: 4.5,\n    },\n    {\n      id: 'E002',\n      name: 'Bob Carter',\n      department: 'Sales',\n      role: 'Account Manager',\n      salary: 72000,\n      hireDate: '2019-11-01',\n      hoursPerWeek: 35,\n      location: 'Chicago',\n      status: 'Full-Time',\n      score: 4.2,\n    },\n    {\n      id: 'E003',\n      name: 'Clara Diaz',\n      department: 'HR',\n      role: 'Recruiter',\n      salary: 65000,\n      hireDate: '2021-06-10',\n      hoursPerWeek: 32,\n      location: 'Remote',\n      status: 'Part-Time',\n      score: 4.0,\n    },\n    {\n      id: 'E004',\n      name: 'David Lee',\n      department: 'Engineering',\n      role: 'DevOps Engineer',\n      salary: 105000,\n      hireDate: '2018-09-22',\n      hoursPerWeek: 40,\n      location: 'San Francisco',\n      status: 'Full-Time',\n      score: 4.7,\n    },\n    {\n      id: 'E005',\n      name: 'Ella Smith',\n      department: 'Marketing',\n      role: 'Social Media Mgr',\n      salary: 80000,\n      hireDate: '2020-01-05',\n      hoursPerWeek: 38,\n      location: 'Los Angeles',\n      status: 'Full-Time',\n      score: 4.3,\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      headers: [\n        { title: 'ID', key: 'id', align: 'start' },\n        { title: 'Name', key: 'name' },\n        { title: 'Dept', key: 'department' },\n        { title: 'Role', key: 'role' },\n        { title: 'Salary($)', key: 'salary', align: 'end' },\n        { title: 'HireDate', key: 'hireDate' },\n        { title: 'Hours/Wk', key: 'hoursPerWeek', align: 'end' },\n        { title: 'Location', key: 'location' },\n        { title: 'Status', key: 'status' },\n        { title: 'Score', key: 'score', align: 'end' },\n      ],\n      employees: [\n        {\n          id: 'E001',\n          name: 'Alice Johnson',\n          department: 'Engineering',\n          role: 'Software Dev',\n          salary: 95000,\n          hireDate: '2020-03-15',\n          hoursPerWeek: 40,\n          location: 'New York',\n          status: 'Full-Time',\n          score: 4.5,\n        },\n        {\n          id: 'E002',\n          name: 'Bob Carter',\n          department: 'Sales',\n          role: 'Account Manager',\n          salary: 72000,\n          hireDate: '2019-11-01',\n          hoursPerWeek: 35,\n          location: 'Chicago',\n          status: 'Full-Time',\n          score: 4.2,\n        },\n        {\n          id: 'E003',\n          name: 'Clara Diaz',\n          department: 'HR',\n          role: 'Recruiter',\n          salary: 65000,\n          hireDate: '2021-06-10',\n          hoursPerWeek: 32,\n          location: 'Remote',\n          status: 'Part-Time',\n          score: 4.0,\n        },\n        {\n          id: 'E004',\n          name: 'David Lee',\n          department: 'Engineering',\n          role: 'DevOps Engineer',\n          salary: 105000,\n          hireDate: '2018-09-22',\n          hoursPerWeek: 40,\n          location: 'San Francisco',\n          status: 'Full-Time',\n          score: 4.7,\n        },\n        {\n          id: 'E005',\n          name: 'Ella Smith',\n          department: 'Marketing',\n          role: 'Social Media Mgr',\n          salary: 80000,\n          hireDate: '2020-01-05',\n          hoursPerWeek: 38,\n          location: 'Los Angeles',\n          status: 'Full-Time',\n          score: 4.3,\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/slot-loading.vue",
    "content": "<template>\n  <div class=\"text-center mt-2 mb-4\">\n    <v-btn\n      :disabled=\"loading\"\n      prepend-icon=\"mdi-refresh\"\n      rounded=\"lg\"\n      text=\"Refresh\"\n      variant=\"text\"\n      border\n      @click=\"onClick\"\n    ></v-btn>\n  </div>\n\n  <v-sheet border rounded>\n    <v-data-table :items=\"items\" :loading=\"loading\">\n      <template v-slot:loading>\n        <v-skeleton-loader type=\"table-row@10\"></v-skeleton-loader>\n      </template>\n\n      <template v-slot:item.horsepower=\"{ value }\">\n        <div class=\"text-medium-emphasis\">\n          <span>{{ value }}</span>\n\n          <v-icon icon=\"mdi-horse-variant-fast\" end></v-icon>\n        </div>\n      </template>\n\n      <template v-slot:item.torque=\"{ value }\">\n        <div class=\"text-medium-emphasis\">\n          <span>{{ value }}</span>\n\n          <v-icon icon=\"mdi-tire\" end></v-icon>\n        </div>\n      </template>\n    </v-data-table>\n  </v-sheet>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const loading = shallowRef(false)\n\n  const items = [\n    { name: 'Chevrolet Camaro', year: 1967, engine: 'V8', horsepower: 375, torque: 415 },\n    { name: 'Ford Mustang', year: 1965, engine: 'V8', horsepower: 271, torque: 312 },\n    { name: 'Dodge Charger', year: 1968, engine: 'V8', horsepower: 425, torque: 490 },\n    { name: 'Pontiac GTO', year: 1964, engine: 'V8', horsepower: 350, torque: 445 },\n    { name: 'Plymouth Barracuda', year: 1964, engine: 'V8', horsepower: 330, torque: 425 },\n    { name: 'Chevrolet Chevelle SS', year: 1970, engine: 'V8', horsepower: 450, torque: 500 },\n    { name: 'Oldsmobile 442', year: 1971, engine: 'V8', horsepower: 340, torque: 440 },\n    { name: 'Dodge Challenger', year: 1970, engine: 'V8', horsepower: 425, torque: 490 },\n    { name: 'AMC Javelin', year: 1968, engine: 'V8', horsepower: 315, torque: 425 },\n    { name: 'Mercury Cougar', year: 1967, engine: 'V8', horsepower: 335, torque: 427 },\n  ]\n\n  function onClick () {\n    loading.value = true\n    setTimeout(() => {\n      loading.value = false\n    }, 2000)\n  }\n</script>\n\n<script>\n  import { shallowRef } from 'vue'\n\n  export default {\n    data () {\n      return {\n        loading: false,\n        items: [\n          { name: 'Chevrolet Camaro', year: 1967, engine: 'V8', horsepower: 375, torque: 415 },\n          { name: 'Ford Mustang', year: 1965, engine: 'V8', horsepower: 271, torque: 312 },\n          { name: 'Dodge Charger', year: 1968, engine: 'V8', horsepower: 425, torque: 490 },\n          { name: 'Pontiac GTO', year: 1964, engine: 'V8', horsepower: 350, torque: 445 },\n          { name: 'Plymouth Barracuda', year: 1964, engine: 'V8', horsepower: 330, torque: 425 },\n          { name: 'Chevrolet Chevelle SS', year: 1970, engine: 'V8', horsepower: 450, torque: 500 },\n          { name: 'Oldsmobile 442', year: 1971, engine: 'V8', horsepower: 340, torque: 440 },\n          { name: 'Dodge Challenger', year: 1970, engine: 'V8', horsepower: 425, torque: 490 },\n          { name: 'AMC Javelin', year: 1968, engine: 'V8', horsepower: 315, torque: 425 },\n          { name: 'Mercury Cougar', year: 1967, engine: 'V8', horsepower: 335, torque: 427 },\n        ],\n      }\n    },\n    methods: {\n      onClick () {\n        this.loading = true\n        setTimeout(() => {\n          this.loading = false\n        }, 2000)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/slot-main.vue",
    "content": "<template>\n  <div>\n    <v-select\n      v-model=\"enabled\"\n      :items=\"slots\"\n      label=\"Slot\"\n      clearable\n    ></v-select>\n    <v-data-table\n      :headers=\"headerArray\"\n      :hide-default-header=\"hideHeaders\"\n      :items=\"itemsArray\"\n      :loading=\"isLoading\"\n      :search=\"search\"\n      :show-select=\"showSelect\"\n      class=\"elevation-1\"\n      item-key=\"name\"\n      hide-default-footer\n    >\n      <template\n        v-if=\"isEnabled('top')\"\n        v-slot:top\n      >\n        <div>This is content above the actual table</div>\n      </template>\n\n      <template\n        v-if=\"isEnabled('header.data-table-select')\"\n        v-slot:header.data-table-select=\"{ on, props }\"\n      >\n        <v-checkbox-btn\n          color=\"purple\"\n          v-bind=\"props\"\n          v-on=\"on\"\n        ></v-checkbox-btn>\n      </template>\n\n      <template\n        v-if=\"isEnabled('header')\"\n        v-slot:header=\"{ props: { headers } }\"\n      >\n        <thead>\n          <tr>\n            <th :colspan=\"headers.length\">\n              This is a header\n            </th>\n          </tr>\n        </thead>\n      </template>\n\n      <template\n        v-if=\"isEnabled('progress')\"\n        v-slot:progress\n      >\n        <v-progress-linear\n          :height=\"10\"\n          color=\"purple\"\n          indeterminate\n        ></v-progress-linear>\n      </template>\n\n      <template\n        v-if=\"isEnabled('item.data-table-select')\"\n        v-slot:item.data-table-select=\"{ isSelected, select }\"\n      >\n        <v-checkbox-btn\n          :value=\"isSelected\"\n          color=\"green\"\n          @input=\"select($event)\"\n        ></v-checkbox-btn>\n      </template>\n\n      <template\n        v-if=\"isEnabled('item.<name>')\"\n        v-slot:item.name=\"{ value }\"\n      >\n        {{ value.toUpperCase() }}\n      </template>\n\n      <template\n        v-if=\"isEnabled('body.prepend')\"\n        v-slot:body.prepend=\"{ headers }\"\n      >\n        <tr>\n          <td :colspan=\"headers.length\">\n            This is a prepended row\n          </td>\n        </tr>\n      </template>\n\n      <template\n        v-if=\"isEnabled('body')\"\n        v-slot:body=\"{ items }\"\n      >\n        <tbody>\n          <tr\n            v-for=\"item in items\"\n            :key=\"item.name\"\n          >\n            <td>{{ item.name }}</td>\n            <td>CONTENT</td>\n            <td>CONTENT</td>\n            <td>CONTENT</td>\n            <td>CONTENT</td>\n            <td>CONTENT</td>\n          </tr>\n        </tbody>\n      </template>\n\n      <template\n        v-if=\"isEnabled('no-data')\"\n        v-slot:no-data\n      >\n        NO DATA HERE!\n      </template>\n\n      <template\n        v-if=\"isEnabled('no-results')\"\n        v-slot:no-results\n      >\n        NO RESULTS HERE!\n      </template>\n\n      <template\n        v-if=\"isEnabled('body.append')\"\n        v-slot:body.append=\"{ headers }\"\n      >\n        <tr>\n          <td :colspan=\"headers.length\">\n            This is an appended row\n          </td>\n        </tr>\n      </template>\n\n      <template\n        v-if=\"isEnabled('footer')\"\n        v-slot:footer\n      >\n        <div>\n          This is a footer\n        </div>\n      </template>\n    </v-data-table>\n  </div>\n</template>\n\n<script>\n  const desserts = [\n    { name: 'Frozen Yogurt', calories: 159, fat: 6.0, carbs: 24, protein: 4.0, iron: 1 },\n    { name: 'Ice cream sandwich', calories: 237, fat: 9.0, carbs: 37, protein: 4.3, iron: 1 },\n    { name: 'Eclair', calories: 262, fat: 16.0, carbs: 23, protein: 6.0, iron: 7 },\n    { name: 'Cupcake', calories: 305, fat: 3.7, carbs: 67, protein: 4.3, iron: 8 },\n    { name: 'Gingerbread', calories: 356, fat: 16.0, carbs: 49, protein: 3.9, iron: 16 },\n    { name: 'Jelly bean', calories: 375, fat: 0.0, carbs: 94, protein: 0.0, iron: 0 },\n    { name: 'Lollipop', calories: 392, fat: 0.2, carbs: 98, protein: 0, iron: 2 },\n    { name: 'Honeycomb', calories: 408, fat: 3.2, carbs: 87, protein: 6.5, iron: 45 },\n    { name: 'Donut', calories: 452, fat: 25.0, carbs: 51, protein: 4.9, iron: 22 },\n    { name: 'KitKat', calories: 518, fat: 26.0, carbs: 65, protein: 7, iron: 6 },\n  ]\n\n  export default {\n    data () {\n      return {\n        enabled: null,\n        itemsArray: desserts,\n        search: null,\n        slots: [\n          'body',\n          'body.append',\n          'body.prepend',\n          'footer',\n          'header.data-table-select',\n          'header',\n          'progress',\n          'item.data-table-select',\n          'item.<name>',\n          'no-data',\n          'no-results',\n          'top',\n        ],\n        headerArray: [\n          { text: 'Dessert (100g serving)', align: 'start', sortable: false, value: 'name' },\n          { text: 'Calories', value: 'calories' },\n          { text: 'Fat (g)', value: 'fat' },\n          { text: 'Carbs (g)', value: 'carbs' },\n          { text: 'Protein (g)', value: 'protein' },\n          { text: 'Iron (%)', value: 'iron' },\n        ],\n      }\n    },\n\n    computed: {\n      showSelect () {\n        return this.isEnabled('header.data-table-select') || this.isEnabled('item.data-table-select')\n      },\n      hideHeaders () {\n        return !this.showSelect\n      },\n      isLoading () {\n        return this.isEnabled('progress')\n      },\n    },\n\n    watch: {\n      enabled (slot) {\n        if (slot === 'no-data') {\n          this.items = []\n        } else if (slot === 'no-results') {\n          this.search = '...'\n        } else {\n          this.search = null\n          this.itemsArray = desserts\n        }\n      },\n    },\n\n    methods: {\n      isEnabled (slot) {\n        return this.enabled === slot\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/slot-simple-checkbox.vue",
    "content": "<template>\n  <v-data-table :items=\"consoles\" hide-default-footer>\n    <template v-slot:item.exclusive=\"{ item }\">\n      <v-checkbox-btn\n        v-model=\"item.exclusive\"\n        :ripple=\"false\"\n      ></v-checkbox-btn>\n    </template>\n  </v-data-table>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const consoles = ref([\n    {\n      name: 'PlayStation 5',\n      manufacturer: 'Sony',\n      year: 2020,\n      sales: '10M',\n      exclusive: true,\n    },\n    {\n      name: 'Xbox Series X',\n      manufacturer: 'Microsoft',\n      year: 2020,\n      sales: '6.5M',\n      exclusive: false,\n    },\n    {\n      name: 'Nintendo Switch',\n      manufacturer: 'Nintendo',\n      year: 2017,\n      sales: '89M',\n      exclusive: true,\n    },\n    {\n      name: 'PlayStation 4',\n      manufacturer: 'Sony',\n      year: 2013,\n      sales: '116M',\n      exclusive: true,\n    },\n    {\n      name: 'Xbox One',\n      manufacturer: 'Microsoft',\n      year: 2013,\n      sales: '50M',\n      exclusive: false,\n    },\n    {\n      name: 'Nintendo Wii',\n      manufacturer: 'Nintendo',\n      year: 2006,\n      sales: '101M',\n      exclusive: true,\n    },\n  ])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      consoles: [\n        {\n          name: 'PlayStation 5',\n          manufacturer: 'Sony',\n          year: 2020,\n          sales: '10M',\n          exclusive: true,\n        },\n        {\n          name: 'Xbox Series X',\n          manufacturer: 'Microsoft',\n          year: 2020,\n          sales: '6.5M',\n          exclusive: false,\n        },\n        {\n          name: 'Nintendo Switch',\n          manufacturer: 'Nintendo',\n          year: 2017,\n          sales: '89M',\n          exclusive: true,\n        },\n        {\n          name: 'PlayStation 4',\n          manufacturer: 'Sony',\n          year: 2013,\n          sales: '116M',\n          exclusive: true,\n        },\n        {\n          name: 'Xbox One',\n          manufacturer: 'Microsoft',\n          year: 2013,\n          sales: '50M',\n          exclusive: false,\n        },\n        {\n          name: 'Nintendo Wii',\n          manufacturer: 'Nintendo',\n          year: 2006,\n          sales: '101M',\n          exclusive: true,\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n    :script=\"script\"\n  >\n    <div>\n      <v-data-table\n        v-bind=\"props\"\n        :items=\"items\"\n      ></v-data-table>\n    </div>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-data-table'\n  const model = ref('default')\n  const options = ['Hide header', 'Hide footer', 'Hide both']\n\n  const items = [\n    {\n      name: 'African Elephant',\n      species: 'Loxodonta africana',\n      diet: 'Herbivore',\n      habitat: 'Savanna, Forests',\n    },\n    {\n      name: 'Lion',\n      species: 'Panthera leo',\n      diet: 'Carnivore',\n      habitat: 'Savanna, Grassland',\n    },\n    {\n      name: 'Giraffe',\n      species: 'Giraffa camelopardalis',\n      diet: 'Herbivore',\n      habitat: 'Savanna, Grassland',\n    },\n    {\n      name: 'Zebra',\n      species: 'Equus quagga',\n      diet: 'Herbivore',\n      habitat: 'Savanna, Grassland',\n    },\n    {\n      name: 'Hippopotamus',\n      species: 'Hippopotamus amphibius',\n      diet: 'Herbivore',\n      habitat: 'Riverbanks, Lakes',\n    },\n    {\n      name: 'Meerkat',\n      species: 'Suricata suricatta',\n      diet: 'Omnivore',\n      habitat: 'Desert, Savanna',\n    },\n    {\n      name: 'Hyena',\n      species: 'Crocuta crocuta',\n      diet: 'Carnivore',\n      habitat: 'Savanna, Grassland',\n    },\n    {\n      name: 'Zebra',\n      species: 'Equus quagga',\n      diet: 'Herbivore',\n      habitat: 'Savanna, Grassland',\n    },\n    {\n      name: 'Ostrich',\n      species: 'Struthio camelus',\n      diet: 'Omnivore',\n      habitat: 'Savanna, Grassland',\n    },\n    {\n      name: 'Cheetah',\n      species: 'Acinonyx jubatus',\n      diet: 'Carnivore',\n      habitat: 'Savanna, Grassland',\n    },\n  ]\n\n  const props = computed(() => {\n    return {\n      items: 'items',\n      'hide-default-header': ['Hide both', 'Hide header'].includes(model.value) || undefined,\n      'hide-default-footer': ['Hide both', 'Hide footer'].includes(model.value) || undefined,\n    }\n  })\n\n  // eslint doesn't like the script tag inside the template\n  const script = computed(() => {\n    return `<script setup>\n  const items = [\n    {\n      name: 'African Elephant',\n      species: 'Loxodonta africana',\n      diet: 'Herbivore',\n      habitat: 'Savanna, Forests',\n    },\n    // ... more items\n  ]\n<` + '/script>'\n  })\n\n  const code = computed(() => {\n    return `<v-data-table${propsToString(props.value, ['items'])}></v-data-table>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/virtual-custom.vue",
    "content": "<template>\n  <v-container>\n    <v-chip-group v-model=\"selectedSize\" class=\"mb-4\" mandatory row>\n      <v-chip\n        v-for=\"size in sizes\"\n        :key=\"size\"\n        :value=\"size\"\n        color=\"primary\"\n        variant=\"outlined\"\n      >\n        {{ size }} items\n      </v-chip>\n    </v-chip-group>\n\n    <v-data-table-virtual\n      :headers=\"headers\"\n      :items=\"items\"\n      height=\"400\"\n      item-key=\"id\"\n      fixed-header\n    >\n      <template v-slot:item=\"{ columns, internalItem, props, itemRef }\">\n        <tr v-bind=\"props\" :ref=\"itemRef\">\n          <td v-for=\"column in columns\" :key=\"column.key\">\n            {{ internalItem.raw[column.key] }}\n          </td>\n        </tr>\n      </template>\n    </v-data-table-virtual>\n  </v-container>\n</template>\n\n<script setup>\n  import { computed, ref } from 'vue'\n\n  const sizes = [100, 400, 800]\n  const selectedSize = ref(100)\n\n  const headers = [\n    { title: 'ID', value: 'id', sortable: true },\n    { title: 'Title', value: 'title', sortable: true },\n    { title: 'Name', value: 'name', sortable: true },\n    { title: 'Email', value: 'email', sortable: true },\n    { title: 'Role', value: 'role', sortable: true },\n  ]\n\n  const baseItems = [\n    { title: 'Mr.', name: 'James Smith', email: 'james.smith@gmail.com', role: 'Owner' },\n    { title: 'Ms.', name: 'Mary Johnson', email: 'mary.johnson@yahoo.com', role: 'Manager' },\n    { title: 'Dr.', name: 'Robert Williams', email: 'robert.williams@outlook.com', role: 'Board Member' },\n    { title: 'Mrs.', name: 'Patricia Brown', email: 'patricia.brown@hotmail.com', role: 'Developer' },\n    { title: 'Mr.', name: 'John Davis', email: 'john.davis@gmail.com', role: 'Designer' },\n    { title: 'Ms.', name: 'Jennifer Garcia', email: 'jennifer.garcia@yahoo.com', role: 'Manager' },\n    { title: 'Mr.', name: 'Michael Miller', email: 'michael.miller@outlook.com', role: 'Owner' },\n    { title: 'Mrs.', name: 'Linda Martinez', email: 'linda.martinez@hotmail.com', role: 'Developer' },\n    { title: 'Dr.', name: 'William Rodriguez', email: 'william.rodriguez@gmail.com', role: 'Board Member' },\n    { title: 'Ms.', name: 'Elizabeth Hernandez', email: 'elizabeth.hernandez@yahoo.com', role: 'Designer' },\n    { title: 'Mr.', name: 'David Lopez', email: 'david.lopez@outlook.com', role: 'Manager' },\n    { title: 'Mrs.', name: 'Barbara Gonzalez', email: 'barbara.gonzalez@hotmail.com', role: 'Owner' },\n  ]\n\n  const items = computed(() => {\n    return Array.from({ length: selectedSize.value }).map((_, i) => {\n      const base = baseItems[i % baseItems.length]\n      return { id: i + 1, ...base }\n    })\n  })\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        sizes: [100, 400, 800],\n        selectedSize: 100,\n        headers: [\n          { title: 'ID', value: 'id', sortable: true },\n          { title: 'Title', value: 'title', sortable: true },\n          { title: 'Name', value: 'name', sortable: true },\n          { title: 'Email', value: 'email', sortable: true },\n          { title: 'Role', value: 'role', sortable: true },\n        ],\n        baseItems: [\n          { title: 'Mr.', name: 'James Smith', email: 'james.smith@gmail.com', role: 'Owner' },\n          { title: 'Ms.', name: 'Mary Johnson', email: 'mary.johnson@yahoo.com', role: 'Manager' },\n          { title: 'Dr.', name: 'Robert Williams', email: 'robert.williams@outlook.com', role: 'Board Member' },\n          { title: 'Mrs.', name: 'Patricia Brown', email: 'patricia.brown@hotmail.com', role: 'Developer' },\n          { title: 'Mr.', name: 'John Davis', email: 'john.davis@gmail.com', role: 'Designer' },\n          { title: 'Ms.', name: 'Jennifer Garcia', email: 'jennifer.garcia@yahoo.com', role: 'Manager' },\n          { title: 'Mr.', name: 'Michael Miller', email: 'michael.miller@outlook.com', role: 'Owner' },\n          { title: 'Mrs.', name: 'Linda Martinez', email: 'linda.martinez@hotmail.com', role: 'Developer' },\n          { title: 'Dr.', name: 'William Rodriguez', email: 'william.rodriguez@gmail.com', role: 'Board Member' },\n          { title: 'Ms.', name: 'Elizabeth Hernandez', email: 'elizabeth.hernandez@yahoo.com', role: 'Designer' },\n          { title: 'Mr.', name: 'David Lopez', email: 'david.lopez@outlook.com', role: 'Manager' },\n          { title: 'Mrs.', name: 'Barbara Gonzalez', email: 'barbara.gonzalez@hotmail.com', role: 'Owner' },\n        ],\n      }\n    },\n\n    computed: {\n      items () {\n        return Array.from({ length: this.selectedSize }).map((_, i) => {\n          const base = this.baseItems[i % this.baseItems.length]\n          return { id: i + 1, ...base }\n        })\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/virtual.vue",
    "content": "<template>\n  <v-data-table-virtual\n    :headers=\"headers\"\n    :items=\"virtualBoats\"\n    height=\"400\"\n    item-value=\"name\"\n    fixed-header\n  ></v-data-table-virtual>\n</template>\n\n<script setup>\n  import { computed } from 'vue'\n\n  const headers = [\n    { title: 'Boat Type', align: 'start', key: 'name' },\n    { title: 'Speed(knots)', align: 'end', key: 'speed' },\n    { title: 'Length(m)', align: 'end', key: 'length' },\n    { title: 'Price($)', align: 'end', key: 'price', value: item => formatPrice(item.price) },\n    { title: 'Year', align: 'end', key: 'year' },\n  ]\n\n  const boats = [\n    {\n      name: 'Speedster',\n      speed: 35,\n      length: 22,\n      price: 300000,\n      year: 2021,\n    },\n    {\n      name: 'OceanMaster',\n      speed: 25,\n      length: 35,\n      price: 500000,\n      year: 2020,\n    },\n    {\n      name: 'Voyager',\n      speed: 20,\n      length: 45,\n      price: 700000,\n      year: 2019,\n    },\n    {\n      name: 'WaveRunner',\n      speed: 40,\n      length: 19,\n      price: 250000,\n      year: 2022,\n    },\n    {\n      name: 'SeaBreeze',\n      speed: 28,\n      length: 31,\n      price: 450000,\n      year: 2018,\n    },\n    {\n      name: 'HarborGuard',\n      speed: 18,\n      length: 50,\n      price: 800000,\n      year: 2017,\n    },\n    {\n      name: 'SlickFin',\n      speed: 33,\n      length: 24,\n      price: 350000,\n      year: 2021,\n    },\n    {\n      name: 'StormBreaker',\n      speed: 22,\n      length: 38,\n      price: 600000,\n      year: 2020,\n    },\n    {\n      name: 'WindSail',\n      speed: 15,\n      length: 55,\n      price: 900000,\n      year: 2019,\n    },\n    {\n      name: 'FastTide',\n      speed: 37,\n      length: 20,\n      price: 280000,\n      year: 2022,\n    },\n  ]\n\n  const virtualBoats = computed(() => {\n    return [...Array(10000).keys()].map(i => {\n      const boat = { ...boats[i % 10] }\n      boat.name = `${boat.name} #${i}`\n      return boat\n    })\n  })\n\n  function formatPrice (value) {\n    return `$${value.toFixed(0).replace(/\\d(?=(\\d{3})+$)/g, '$&,')}`\n  }\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        headers: [\n          { title: 'Boat Type', align: 'start', key: 'name' },\n          { title: 'Speed(knots)', align: 'end', key: 'speed' },\n          { title: 'Length(m)', align: 'end', key: 'length' },\n          { title: 'Price($)', align: 'end', key: 'price', value: item => this.formatPrice(item.price) },\n          { title: 'Year', align: 'end', key: 'year' },\n        ],\n        boats: [\n          {\n            name: 'Speedster',\n            speed: 35,\n            length: 22,\n            price: 300000,\n            year: 2021,\n          },\n          {\n            name: 'OceanMaster',\n            speed: 25,\n            length: 35,\n            price: 500000,\n            year: 2020,\n          },\n          {\n            name: 'Voyager',\n            speed: 20,\n            length: 45,\n            price: 700000,\n            year: 2019,\n          },\n          {\n            name: 'WaveRunner',\n            speed: 40,\n            length: 19,\n            price: 250000,\n            year: 2022,\n          },\n          {\n            name: 'SeaBreeze',\n            speed: 28,\n            length: 31,\n            price: 450000,\n            year: 2018,\n          },\n          {\n            name: 'HarborGuard',\n            speed: 18,\n            length: 50,\n            price: 800000,\n            year: 2017,\n          },\n          {\n            name: 'SlickFin',\n            speed: 33,\n            length: 24,\n            price: 350000,\n            year: 2021,\n          },\n          {\n            name: 'StormBreaker',\n            speed: 22,\n            length: 38,\n            price: 600000,\n            year: 2020,\n          },\n          {\n            name: 'WindSail',\n            speed: 15,\n            length: 55,\n            price: 900000,\n            year: 2019,\n          },\n          {\n            name: 'FastTide',\n            speed: 37,\n            length: 20,\n            price: 280000,\n            year: 2022,\n          },\n        ],\n      }\n    },\n\n    computed: {\n      virtualBoats () {\n        return [...Array(10000).keys()].map(i => {\n          const boat = { ...this.boats[i % this.boats.length] }\n          boat.name = `${boat.name} #${i}`\n          return boat\n        })\n      },\n    },\n\n    methods: {\n      formatPrice (value) {\n        return `$${value.toFixed(0).replace(/\\d(?=(\\d{3})+$)/g, '$&,')}`\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-data-table/virtualized.vue",
    "content": "<template>\n  <v-data-table\n    :headers=\"headers\"\n    :items=\"items\"\n    :items-per-page=\"-1\"\n    height=\"500\"\n    hide-default-footer\n    virtual-rows\n  ></v-data-table>\n</template>\n\n<script setup>\n  import { computed } from 'vue'\n\n  const desserts = [\n    {\n      name: 'Frozen Yogurt',\n      calories: 159,\n      fat: 6,\n      carbs: 24,\n      protein: 4,\n      iron: 1,\n    },\n    {\n      name: 'Ice cream sandwich',\n      calories: 237,\n      fat: 9,\n      carbs: 37,\n      protein: 4.3,\n      iron: 1,\n    },\n    {\n      name: 'Eclair',\n      calories: 262,\n      fat: 16,\n      carbs: 23,\n      protein: 6,\n      iron: 7,\n    },\n    {\n      name: 'Cupcake',\n      calories: 305,\n      fat: 3.7,\n      carbs: 67,\n      protein: 4.3,\n      iron: 8,\n    },\n    {\n      name: 'Gingerbread',\n      calories: 356,\n      fat: 16,\n      carbs: 49,\n      protein: 3.9,\n      iron: 16,\n    },\n    {\n      name: 'Jelly bean',\n      calories: 375,\n      fat: 0,\n      carbs: 94,\n      protein: 0,\n      iron: 0,\n    },\n    {\n      name: 'Lollipop',\n      calories: 392,\n      fat: 0.2,\n      carbs: 98,\n      protein: 0,\n      iron: 2,\n    },\n    {\n      name: 'Honeycomb',\n      calories: 408,\n      fat: 3.2,\n      carbs: 87,\n      protein: 6.5,\n      iron: 45,\n    },\n    {\n      name: 'Donut',\n      calories: 452,\n      fat: 25,\n      carbs: 51,\n      protein: 4.9,\n      iron: 22,\n    },\n    {\n      name: 'KitKat',\n      calories: 518,\n      fat: 26,\n      carbs: 65,\n      protein: 7,\n      iron: 6,\n    },\n  ]\n  const headers = [\n    {\n      title: 'Dessert (100g serving)',\n      align: 'start',\n      sortable: false,\n      key: 'name',\n    },\n    { title: 'Calories', key: 'calories' },\n    { title: 'Fat (g)', key: 'fat' },\n    { title: 'Carbs (g)', key: 'carbs' },\n    { title: 'Protein (g)', key: 'protein' },\n    { title: 'Iron (%)', key: 'iron' },\n  ]\n\n  const items = computed(() => {\n    return [...new Array(100)].reduce(items => {\n      items.push(...desserts)\n      return items\n    }, [])\n  })\n</script>\n\n<script>\n  const desserts = [\n    {\n      name: 'Frozen Yogurt',\n      calories: 159,\n      fat: 6.0,\n      carbs: 24,\n      protein: 4.0,\n      iron: 1,\n    },\n    {\n      name: 'Ice cream sandwich',\n      calories: 237,\n      fat: 9.0,\n      carbs: 37,\n      protein: 4.3,\n      iron: 1,\n    },\n    {\n      name: 'Eclair',\n      calories: 262,\n      fat: 16.0,\n      carbs: 23,\n      protein: 6.0,\n      iron: 7,\n    },\n    {\n      name: 'Cupcake',\n      calories: 305,\n      fat: 3.7,\n      carbs: 67,\n      protein: 4.3,\n      iron: 8,\n    },\n    {\n      name: 'Gingerbread',\n      calories: 356,\n      fat: 16.0,\n      carbs: 49,\n      protein: 3.9,\n      iron: 16,\n    },\n    {\n      name: 'Jelly bean',\n      calories: 375,\n      fat: 0.0,\n      carbs: 94,\n      protein: 0.0,\n      iron: 0,\n    },\n    {\n      name: 'Lollipop',\n      calories: 392,\n      fat: 0.2,\n      carbs: 98,\n      protein: 0,\n      iron: 2,\n    },\n    {\n      name: 'Honeycomb',\n      calories: 408,\n      fat: 3.2,\n      carbs: 87,\n      protein: 6.5,\n      iron: 45,\n    },\n    {\n      name: 'Donut',\n      calories: 452,\n      fat: 25.0,\n      carbs: 51,\n      protein: 4.9,\n      iron: 22,\n    },\n    {\n      name: 'KitKat',\n      calories: 518,\n      fat: 26.0,\n      carbs: 65,\n      protein: 7,\n      iron: 6,\n    },\n  ]\n\n  export default {\n    data: () => ({\n      headers: [\n        {\n          title: 'Dessert (100g serving)',\n          align: 'start',\n          sortable: false,\n          key: 'name',\n        },\n        { title: 'Calories', key: 'calories' },\n        { title: 'Fat (g)', key: 'fat' },\n        { title: 'Carbs (g)', key: 'carbs' },\n        { title: 'Protein (g)', key: 'protein' },\n        { title: 'Iron (%)', key: 'iron' },\n      ],\n    }),\n    computed: {\n      items () {\n        return [...new Array(100)].reduce(items => {\n          items.push(...desserts)\n          return items\n        }, [])\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-input/misc-passenger.vue",
    "content": "<template>\n  <v-card class=\"mx-auto\" max-width=\"420\">\n    <v-layout>\n      <v-system-bar color=\"#4603c0\">\n        <v-icon icon=\"mdi-square\"></v-icon>\n\n        <v-icon icon=\"mdi-circle\"></v-icon>\n\n        <v-icon icon=\"mdi-triangle\"></v-icon>\n      </v-system-bar>\n\n      <v-app-bar color=\"#6200ee\" title=\"Passenger information\" flat>\n        <template v-slot:prepend>\n          <v-btn icon=\"mdi-arrow-left\"></v-btn>\n        </template>\n      </v-app-bar>\n\n      <v-main>\n        <v-container class=\"pt-8\">\n          <v-text-field\n            label=\"Name\"\n            model-value=\"John Leider\"\n            variant=\"outlined\"\n          ></v-text-field>\n\n          <v-date-input\n            label=\"Date of birth\"\n            prepend-icon=\"\"\n            variant=\"outlined\"\n            persistent-placeholder\n          ></v-date-input>\n\n          <v-text-field label=\"Address\" variant=\"outlined\"></v-text-field>\n          <v-text-field label=\"City\" variant=\"outlined\"></v-text-field>\n\n          <div class=\"d-flex ga-2\">\n            <v-text-field label=\"State\" variant=\"outlined\"></v-text-field>\n\n            <v-text-field label=\"Zip code\" variant=\"outlined\"></v-text-field>\n          </div>\n        </v-container>\n      </v-main>\n    </v-layout>\n\n    <template v-slot:actions>\n      <v-btn color=\"#4603c0\" disabled>Prev</v-btn>\n\n      <v-spacer></v-spacer>\n\n      <v-btn color=\"#4603c0\">Next</v-btn>\n    </template>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-input/prop-input-format.vue",
    "content": "<template>\n  <div class=\"d-flex justify-center\">\n    <v-date-input\n      v-model=\"model\"\n      input-format=\"yyyy-mm-dd\"\n      max-width=\"368\"\n      prefix=\"ISO Date:\"\n    ></v-date-input>\n  </div>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n  import { useDate } from 'vuetify'\n\n  const adapter = useDate()\n  const model = shallowRef(adapter.parseISO('2025-02-25'))\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-input/prop-model.vue",
    "content": "<template>\n  <div class=\"d-flex justify-center\">\n    <v-date-input\n      v-model=\"model\"\n      label=\"Select a date\"\n      max-width=\"368\"\n    ></v-date-input>\n  </div>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const model = shallowRef(null)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      model: null,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-input/prop-multiple-range.vue",
    "content": "<template>\n  <div class=\"d-flex justify-center\">\n    <v-date-input\n      v-model=\"model\"\n      label=\"Select range\"\n      max-width=\"368\"\n      multiple=\"range\"\n    ></v-date-input>\n  </div>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const model = shallowRef(null)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      model: null,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-input/prop-multiple.vue",
    "content": "<template>\n  <div class=\"d-flex justify-center\">\n    <v-date-input\n      v-model=\"model\"\n      label=\"Select day(s)\"\n      max-width=\"368\"\n      multiple\n    ></v-date-input>\n  </div>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const model = shallowRef(null)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      model: null,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-input/prop-prepend-icon.vue",
    "content": "<template>\n  <v-row density=\"comfortable\">\n    <v-col cols=\"12\" md=\"6\">\n      <v-date-input\n        label=\"Select a date\"\n        prepend-icon=\"\"\n        prepend-inner-icon=\"$calendar\"\n        variant=\"solo\"\n      ></v-date-input>\n    </v-col>\n\n    <v-col cols=\"12\" md=\"6\">\n      <v-date-input\n        label=\"Select a date\"\n        prepend-icon=\"\"\n        variant=\"solo\"\n      ></v-date-input>\n    </v-col>\n  </v-row>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-input/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div>\n      <v-date-input v-bind=\"props\"></v-date-input>\n    </div>\n\n    <template v-slot:configuration>\n      <v-checkbox v-model=\"clear\" label=\"Clearable\"></v-checkbox>\n\n      <v-checkbox v-model=\"disabled\" label=\"Disabled\"></v-checkbox>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-date-input'\n  const model = ref('default')\n  const options = ['outlined', 'underlined', 'solo', 'solo-filled', 'solo-inverted']\n  const clear = ref(false)\n  const counter = ref(false)\n  const disabled = ref(false)\n  const props = computed(() => {\n    return {\n      clearable: clear.value || undefined,\n      counter: counter.value || undefined,\n      disabled: disabled.value || undefined,\n      label: 'Date input',\n      variant: model.value === 'default' ? undefined : model.value,\n    }\n  })\n\n  const slots = computed(() => {\n    return ``\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-picker/event-button-events.vue",
    "content": "<template>\n  <v-row>\n    <v-col\n      class=\"my-2 px-1\"\n      cols=\"12\"\n      sm=\"6\"\n    >\n      <v-date-picker\n        v-model=\"date\"\n        @contextmenu:year=\"contextMenu\"\n        @dblclick:date=\"dblClick\"\n        @mouseenter:month=\"mouseEnter\"\n        @mouseleave:month=\"mouseLeave\"\n      ></v-date-picker>\n    </v-col>\n\n    <v-col\n      class=\"my-2 px-1\"\n      cols=\"12\"\n      sm=\"6\"\n    >\n      <div class=\"text-body-large mb-2\">\n        <v-icon size=\"small\">\n          {{ done[0] ? '$checkboxOn' : '$checkboxOff' }}\n        </v-icon>\n        Double click on any date\n      </div>\n\n      <div class=\"text-body-large\">\n        <v-icon size=\"small\">\n          {{ done[1] ? '$checkboxOn' : '$checkboxOff' }}\n        </v-icon>\n        Move mouse cursor over any month button\n      </div>\n\n      <div class=\"text-title-large mb-2\">\n        Mouse pointer is located on: {{ mouseMonth || '-' }}\n      </div>\n\n      <div class=\"text-body-large\">\n        <v-icon size=\"small\">\n          {{ done[2] ? '$checkboxOn' : '$checkboxOff' }}\n        </v-icon>\n        Right click on any year\n      </div>\n    </v-col>\n  </v-row>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const date = ref((new Date(Date.now() - (new Date()).getTimezoneOffset() * 60000)).toISOString().substr(0, 10))\n  const done = ref([false, false, false])\n  const mouseMonth = ref(null)\n\n  function contextMenu (year, event) {\n    done.value[2] = true\n    event.preventDefault()\n    alert(`You have activated context menu for year ${year}`)\n  }\n  function dblClick (date) {\n    done.value[0] = true\n    alert(`You have just double clicked the following date: ${date}`)\n  }\n  function mouseEnter (month) {\n    done.value[1] = true\n    mouseMonth.value = month\n  }\n  function mouseLeave () {\n    mouseMonth.value = null\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      date: (new Date(Date.now() - (new Date()).getTimezoneOffset() * 60000)).toISOString().substr(0, 10),\n      done: [false, false, false],\n      mouseMonth: null,\n    }),\n\n    methods: {\n      contextMenu (year, event) {\n        this.done[2] = true\n\n        event.preventDefault()\n\n        alert(`You have activated context menu for year ${year}`)\n      },\n      dblClick (date) {\n        this.done[0] = true\n\n        alert(`You have just double clicked the following date: ${date}`)\n      },\n      mouseEnter (month) {\n        this.done[1] = true\n        this.mouseMonth = month\n      },\n      mouseLeave () {\n        this.mouseMonth = null\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-picker/guide-locale.vue",
    "content": "<template>\n  <div class=\"d-flex justify-center\">\n    <v-locale-provider locale=\"sv\">\n      <v-date-picker></v-date-picker>\n    </v-locale-provider>\n  </div>\n</template>\n\n<playground-resources lang=\"json\">\n{\n  \"imports\": {\n    \"vuetify/locale\": \"https://cdn.jsdelivr.net/npm/vuetify/lib/locale/index.js/+esm\",\n    \"@date-io/date-fns\": \"https://cdn.jsdelivr.net/npm/@date-io/date-fns@2.17.0/build/index.esm.js/+esm\",\n    \"date-fns/locale/en-US\": \"https://cdn.jsdelivr.net/npm/date-fns@2.30.0/esm/locale/en-US/index.js/+esm\",\n    \"date-fns/locale/sv\": \"https://cdn.jsdelivr.net/npm/date-fns@2.30.0/esm/locale/sv/index.js/+esm\"\n  }\n}\n</playground-resources>\n\n<playground-setup>\nimport { createVuetify } from 'vuetify'\nimport { sv } from 'vuetify/locale'\nimport DateFnsAdapter from '@date-io/date-fns'\nimport enUS from 'date-fns/locale/en-US'\nimport svSE from 'date-fns/locale/sv'\n\nexport const vuetify = createVuetify({\n  locale: {\n    messages: { sv },\n  },\n  date: {\n    adapter: DateFnsAdapter,\n    locale: {\n      en: enUS,\n      sv: svSE,\n    },\n  },\n})\n</playground-setup>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-picker/misc-birthday.vue",
    "content": "<template>\n  <div>\n    <div class=\"mb-6\">Active picker: <code>{{ activePicker || 'null' }}</code></div>\n    <v-menu\n      ref=\"menu\"\n      v-model=\"menuActive\"\n      :close-on-content-click=\"false\"\n      min-width=\"auto\"\n      transition=\"scale-transition\"\n    >\n      <template v-slot:activator=\"{ props }\">\n        <v-text-field\n          v-model=\"date\"\n          label=\"Birthday date\"\n          prepend-icon=\"mdi-calendar\"\n          readonly\n          v-bind=\"props\"\n        ></v-text-field>\n      </template>\n      <v-date-picker\n        v-model=\"date\"\n        v-model:active-picker=\"activePicker\"\n        :max=\"(new Date(Date.now() - (new Date()).getTimezoneOffset() * 60000)).toISOString().substr(0, 10)\"\n        min=\"1950-01-01\"\n        @change=\"save\"\n      ></v-date-picker>\n    </v-menu>\n  </div>\n</template>\n\n<script setup>\n  import { ref, watch } from 'vue'\n\n  const menu = ref()\n\n  const activePicker = ref(null)\n  const date = ref(null)\n  const menuActive = ref(false)\n\n  watch(menuActive, val => {\n    val && setTimeout(() => (activePicker.value = 'YEAR'))\n  })\n\n  function save (date) {\n    menu.value.save(date)\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      activePicker: null,\n      date: null,\n      menuActive: false,\n    }),\n    watch: {\n      menuActive (val) {\n        val && setTimeout(() => (this.activePicker = 'YEAR'))\n      },\n    },\n    methods: {\n      save (date) {\n        this.$refs.menu.save(date)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-picker/misc-dialog-and-menu.vue",
    "content": "<template>\n  <v-row>\n    <v-col\n      cols=\"12\"\n      md=\"4\"\n      sm=\"6\"\n    >\n      <v-menu\n        ref=\"menu\"\n        v-model=\"menuActive\"\n        v-model:return-value=\"date\"\n        :close-on-content-click=\"false\"\n        min-width=\"auto\"\n        transition=\"scale-transition\"\n      >\n        <template v-slot:activator=\"{ props }\">\n          <v-text-field\n            v-model=\"date\"\n            label=\"Picker in menu\"\n            prepend-icon=\"mdi-calendar\"\n            readonly\n            v-bind=\"props\"\n          ></v-text-field>\n        </template>\n        <v-date-picker\n          v-model=\"date\"\n          no-title\n          scrollable\n        >\n          <v-spacer></v-spacer>\n          <v-btn\n            color=\"primary\"\n            variant=\"text\"\n            @click=\"menu = false\"\n          >\n            Cancel\n          </v-btn>\n          <v-btn\n            color=\"primary\"\n            variant=\"text\"\n            @click=\"menu.save(date)\"\n          >\n            OK\n          </v-btn>\n        </v-date-picker>\n      </v-menu>\n    </v-col>\n    <v-spacer></v-spacer>\n    <v-col\n      cols=\"12\"\n      md=\"4\"\n      sm=\"6\"\n    >\n      <v-dialog\n        ref=\"dialog\"\n        v-model=\"modal\"\n        width=\"290px\"\n        persistent\n      >\n        <template v-slot:activator=\"{ props }\">\n          <v-text-field\n            v-model=\"date\"\n            label=\"Picker in dialog\"\n            prepend-icon=\"mdi-calendar\"\n            readonly\n            v-bind=\"props\"\n          ></v-text-field>\n        </template>\n        <v-date-picker\n          v-model=\"date\"\n          scrollable\n        >\n          <v-spacer></v-spacer>\n          <v-btn\n            color=\"primary\"\n            variant=\"text\"\n            @click=\"modal = false\"\n          >\n            Cancel\n          </v-btn>\n          <v-btn\n            color=\"primary\"\n            variant=\"text\"\n            @click=\"dialog.save(date)\"\n          >\n            OK\n          </v-btn>\n        </v-date-picker>\n      </v-dialog>\n    </v-col>\n    <v-col\n      cols=\"12\"\n      md=\"4\"\n      sm=\"6\"\n    >\n      <v-menu\n        v-model=\"menu2\"\n        :close-on-content-click=\"false\"\n        min-width=\"auto\"\n        transition=\"scale-transition\"\n      >\n        <template v-slot:activator=\"{ props }\">\n          <v-text-field\n            v-model=\"date\"\n            label=\"Picker without buttons\"\n            prepend-icon=\"mdi-calendar\"\n            readonly\n            v-bind=\"props\"\n          ></v-text-field>\n        </template>\n        <v-date-picker\n          v-model=\"date\"\n          @change=\"menu2 = false\"\n        ></v-date-picker>\n      </v-menu>\n    </v-col>\n    <v-spacer></v-spacer>\n  </v-row>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const menu = ref()\n\n  const date = ref((new Date(Date.now() - (new Date()).getTimezoneOffset() * 60000)).toISOString().substr(0, 10))\n  const menuActive = ref(false)\n  const modal = ref(false)\n  const menu2 = ref(false)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      date: (new Date(Date.now() - (new Date()).getTimezoneOffset() * 60000)).toISOString().substr(0, 10),\n      menuActive: false,\n      modal: false,\n      menu2: false,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-picker/misc-formatting-external-libraries.vue",
    "content": "<template>\n  <v-container>\n    <v-row>\n      <v-col\n        cols=\"12\"\n        lg=\"6\"\n      >\n        <v-menu\n          v-model=\"menu1\"\n          :close-on-content-click=\"false\"\n          max-width=\"290\"\n        >\n          <template v-slot:activator=\"{ props }\">\n            <v-text-field\n              :model-value=\"computedDateFormattedMomentjs\"\n              label=\"Formatted with Moment.js\"\n              clearable\n              readonly\n              v-bind=\"props\"\n              @click:clear=\"date = null\"\n            ></v-text-field>\n          </template>\n          <v-date-picker\n            v-model=\"date\"\n            @change=\"menu1 = false\"\n          ></v-date-picker>\n        </v-menu>\n      </v-col>\n\n      <v-col\n        cols=\"12\"\n        lg=\"6\"\n      >\n        <v-menu\n          v-model=\"menu2\"\n          :close-on-content-click=\"false\"\n          max-width=\"290\"\n        >\n          <template v-slot:activator=\"{ props }\">\n            <v-text-field\n              :model-value=\"computedDateFormattedDatefns\"\n              label=\"Formatted with datefns\"\n              clearable\n              readonly\n              v-bind=\"props\"\n              @click:clear=\"date = null\"\n            ></v-text-field>\n          </template>\n          <v-date-picker\n            v-model=\"date\"\n            @change=\"menu2 = false\"\n          ></v-date-picker>\n        </v-menu>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { computed, ref } from 'vue'\n  import moment from 'moment'\n  import { format, parseISO } from 'date-fns'\n\n  const date = ref(format(parseISO(new Date().toISOString()), 'yyyy-MM-dd'))\n  const menu1 = ref(false)\n  const menu2 = ref(false)\n\n  const computedDateFormattedMomentjs = computed(() => {\n    return date.value ? moment(date.value).format('dddd, MMMM Do YYYY') : ''\n  })\n  const computedDateFormattedDatefns = computed(() => {\n    return date.value ? format(parseISO(date.value), 'EEEE, MMMM do yyyy') : ''\n  })\n</script>\n\n<script>\n  import moment from 'moment'\n  import { format, parseISO } from 'date-fns'\n\n  export default {\n    data: () => ({\n      // https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#string-arguments\n      date: format(parseISO(new Date().toISOString()), 'yyyy-MM-dd'),\n      menu1: false,\n      menu2: false,\n    }),\n\n    computed: {\n      computedDateFormattedMomentjs () {\n        return this.date ? moment(this.date).format('dddd, MMMM Do YYYY') : ''\n      },\n      computedDateFormattedDatefns () {\n        return this.date ? format(parseISO(this.date), 'EEEE, MMMM do yyyy') : ''\n      },\n    },\n  }\n</script>\n\n<playground-resources lang=\"json\">\n  {\n    \"imports\": {\n      \"moment\": \"https://cdn.jsdelivr.net/npm/moment@2.29.4/moment.min.js\",\n      \"date-fns\": \"https://cdn.jsdelivr.net/npm/date-fns@2.30.0/esm/index.js/+esm\"\n    }\n  }\n</playground-resources>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-picker/misc-formatting.vue",
    "content": "<template>\n  <v-container>\n    <v-row>\n      <v-col\n        cols=\"12\"\n        lg=\"6\"\n      >\n        <v-menu\n          ref=\"menu1\"\n          v-model=\"menu1Active\"\n          :close-on-content-click=\"false\"\n          max-width=\"290px\"\n          min-width=\"auto\"\n          transition=\"scale-transition\"\n        >\n          <template v-slot:activator=\"{ props }\">\n            <v-text-field\n              v-model=\"dateFormatted\"\n              hint=\"MM/DD/YYYY format\"\n              label=\"Date\"\n              prepend-icon=\"mdi-calendar\"\n              persistent-hint\n              v-bind=\"props\"\n              @blur=\"date = parseDate(dateFormatted)\"\n            ></v-text-field>\n          </template>\n          <v-date-picker\n            v-model=\"date\"\n            no-title\n            @input=\"menu1 = false\"\n          ></v-date-picker>\n        </v-menu>\n        <p>Date in ISO format: <strong>{{ date }}</strong></p>\n      </v-col>\n\n      <v-col\n        cols=\"12\"\n        lg=\"6\"\n      >\n        <v-menu\n          v-model=\"menu2\"\n          :close-on-content-click=\"false\"\n          max-width=\"290px\"\n          min-width=\"auto\"\n          transition=\"scale-transition\"\n        >\n          <template v-slot:activator=\"{ props }\">\n            <v-text-field\n              v-model=\"computedDateFormatted\"\n              hint=\"MM/DD/YYYY format\"\n              label=\"Date (read only text field)\"\n              prepend-icon=\"mdi-calendar\"\n              persistent-hint\n              readonly\n              v-bind=\"props\"\n            ></v-text-field>\n          </template>\n          <v-date-picker\n            v-model=\"date\"\n            no-title\n            @input=\"menu2 = false\"\n          ></v-date-picker>\n        </v-menu>\n        <p>Date in ISO format: <strong>{{ date }}</strong></p>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { computed, ref, watch } from 'vue'\n\n  const menu1 = ref()\n\n  const date = ref((new Date(Date.now() - (new Date()).getTimezoneOffset() * 60000)).toISOString().substr(0, 10))\n  const dateFormatted = ref(formatDate((new Date(Date.now() - (new Date()).getTimezoneOffset() * 60000)).toISOString().substr(0, 10)))\n  const menu1Active = ref(false)\n  const menu2 = ref(false)\n\n  const computedDateFormatted = computed(() => {\n    return formatDate(date.value)\n  })\n\n  watch(date, val => {\n    dateFormatted.value = formatDate(val)\n  })\n\n  function formatDate (date) {\n    if (!date) return null\n    const [year, month, day] = date.split('-')\n    return `${month}/${day}/${year}`\n  }\n  function parseDate (date) {\n    if (!date) return null\n    const [month, day, year] = date.split('/')\n    return `${year}-${month.padStart(2, '0')}-${day.padStart(2, '0')}`\n  }\n</script>\n\n<script>\n  export default {\n    data: vm => ({\n      date: (new Date(Date.now() - (new Date()).getTimezoneOffset() * 60000)).toISOString().substr(0, 10),\n      dateFormatted: vm.formatDate((new Date(Date.now() - (new Date()).getTimezoneOffset() * 60000)).toISOString().substr(0, 10)),\n      menu1: false,\n      menu2: false,\n    }),\n\n    computed: {\n      computedDateFormatted () {\n        return this.formatDate(this.date)\n      },\n    },\n\n    watch: {\n      date (val) {\n        this.dateFormatted = this.formatDate(this.date)\n      },\n    },\n\n    methods: {\n      formatDate (date) {\n        if (!date) return null\n\n        const [year, month, day] = date.split('-')\n        return `${month}/${day}/${year}`\n      },\n      parseDate (date) {\n        if (!date) return null\n\n        const [month, day, year] = date.split('/')\n        return `${year}-${month.padStart(2, '0')}-${day.padStart(2, '0')}`\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-picker/misc-internationalization.vue",
    "content": "<template>\n  <v-row class=\"justify-space-around\">\n    <v-date-picker\n      v-model=\"picker\"\n      :first-day-of-week=\"0\"\n      locale=\"zh-cn\"\n    ></v-date-picker>\n    <v-date-picker\n      v-model=\"picker\"\n      :first-day-of-week=\"1\"\n      locale=\"sv-se\"\n    ></v-date-picker>\n  </v-row>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const picker = ref((new Date(Date.now() - (new Date()).getTimezoneOffset() * 60000)).toISOString().substr(0, 10))\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        picker: (new Date(Date.now() - (new Date()).getTimezoneOffset() * 60000)).toISOString().substr(0, 10),\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-picker/misc-orientation.vue",
    "content": "<template>\n  <v-row class=\"align-center\">\n    <v-checkbox\n      v-model=\"landscape\"\n      label=\"Landscape\"\n    ></v-checkbox>\n    <v-date-picker\n      v-model=\"picker\"\n      :landscape=\"landscape\"\n    ></v-date-picker>\n  </v-row>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const picker = ref(new Date().toISOString().substr(0, 7))\n  const landscape = ref(false)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        picker: new Date().toISOString().substr(0, 7),\n        landscape: false,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-picker/prop-allowed-dates.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"justify-space-around\">\n      <v-date-picker\n        v-model=\"date\"\n        :allowed-dates=\"allowedDates\"\n        max=\"2018-03-20\"\n        min=\"2016-06-15\"\n      ></v-date-picker>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { useDate } from 'vuetify'\n  import { ref } from 'vue'\n\n  const date = ref(new Date('2018-03-02'))\n  const adapter = useDate()\n\n  function allowedDates (val) {\n    return parseInt(adapter.toISO(val).split('-')[2], 10) % 2 === 0\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      date: new Date('2018-03-02'),\n    }),\n\n    methods: {\n      allowedDates: val => {\n        return parseInt(this.$vuetify.date.toISO(val).split('-')[2], 10) % 2 === 0\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-picker/prop-colors.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"justify-space-around\">\n      <v-date-picker\n        color=\"primary\"\n      ></v-date-picker>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-picker/prop-elevation.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"justify-space-around\">\n      <v-date-picker elevation=\"5\"></v-date-picker>\n    </v-row>\n  </v-container>\n</template>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2270-66230&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-picker/prop-events.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"justify-space-between\">\n      <div>\n        <div class=\"subheading mb-5 font-weight-medium\">\n          Defined by array\n        </div>\n        <v-date-picker\n          v-model=\"date1\"\n          :events=\"arrayEvents\"\n          event-color=\"green lighten-1\"\n        ></v-date-picker>\n      </div>\n      <div>\n        <div class=\"subheading mb-5 font-weight-medium\">\n          Defined by function\n        </div>\n        <v-date-picker\n          v-model=\"date2\"\n          :event-color=\"date => date[9] % 2 ? 'red' : 'yellow'\"\n          :events=\"functionEvents\"\n        ></v-date-picker>\n      </div>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { onMounted, ref } from 'vue'\n\n  const arrayEvents = ref(null)\n  const date1 = ref((new Date(Date.now() - (new Date()).getTimezoneOffset() * 60000)))\n  const date2 = ref((new Date(Date.now() - (new Date()).getTimezoneOffset() * 60000)))\n\n  function functionEvents (date) {\n    const [, , day] = date.split('-')\n    if ([12, 17, 28].includes(parseInt(day, 10))) return true\n    if ([1, 19, 22].includes(parseInt(day, 10))) return ['red', '#00f']\n    return false\n  }\n  onMounted(() => {\n    arrayEvents.value = [...Array(6)].map(() => {\n      const day = Math.floor(Math.random() * 30)\n      const d = new Date()\n      d.setDate(day)\n      return d.toISOString().substr(0, 10)\n    })\n  })\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      arrayEvents: null,\n      date1: (new Date(Date.now() - (new Date()).getTimezoneOffset() * 60000)),\n      date2: (new Date(Date.now() - (new Date()).getTimezoneOffset() * 60000)),\n    }),\n\n    mounted () {\n      this.arrayEvents = [...Array(6)].map(() => {\n        const day = Math.floor(Math.random() * 30)\n        const d = new Date()\n        d.setDate(day)\n        return d.toISOString().substr(0, 10)\n      })\n    },\n\n    methods: {\n      functionEvents (date) {\n        const [,, day] = date.split('-')\n        if ([12, 17, 28].includes(parseInt(day, 10))) return true\n        if ([1, 19, 22].includes(parseInt(day, 10))) return ['red', '#00f']\n        return false\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-picker/prop-icons.vue",
    "content": "<template>\n  <v-row class=\"justify-center\">\n    <v-date-picker\n      v-model=\"picker\"\n      next-icon=\"mdi-skip-next\"\n      prev-icon=\"mdi-skip-previous\"\n      year-icon=\"mdi-calendar-blank\"\n    ></v-date-picker>\n  </v-row>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const picker = ref((new Date(Date.now() - (new Date()).getTimezoneOffset() * 60000)).toISOString().substr(0, 10))\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        picker: (new Date(Date.now() - (new Date()).getTimezoneOffset() * 60000)).toISOString().substr(0, 10),\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-picker/prop-landscape.vue",
    "content": "<template>\n  <v-layout>\n    <v-container>\n      <v-fab\n        icon=\"mdi-refresh\"\n        location=\"top end\"\n        app\n        v-tooltip=\"'Clear selection'\"\n        @click=\"value = null\"\n      ></v-fab>\n\n      <div class=\"d-flex flex-wrap justify-space-around ga-6\">\n        <v-date-picker\n          v-model=\"value\"\n          color=\"primary\"\n          landscape\n        ></v-date-picker>\n\n        <v-date-picker\n          v-model=\"value\"\n          color=\"purple\"\n          header-date-format=\"monthAndDate\"\n          landscape-header-width=\"250\"\n          landscape\n        ></v-date-picker>\n      </div>\n    </v-container>\n  </v-layout>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const value = shallowRef('2025-11-01')\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-picker/prop-multiple.vue",
    "content": "<template>\n  <v-row>\n    <v-col\n      cols=\"12\"\n      sm=\"6\"\n    >\n      <v-date-picker\n        v-model=\"dates\"\n        multiple\n      ></v-date-picker>\n    </v-col>\n    <v-col\n      cols=\"12\"\n      sm=\"6\"\n    >\n      <v-menu\n        ref=\"menu\"\n        v-model=\"menuActive\"\n        v-model:return-value=\"dates\"\n        :close-on-content-click=\"false\"\n        min-width=\"auto\"\n        transition=\"scale-transition\"\n      >\n        <template v-slot:activator=\"{ props }\">\n          <v-combobox\n            v-model=\"dates\"\n            label=\"Multiple picker in menu\"\n            prepend-icon=\"mdi-calendar\"\n            chips\n            multiple\n            readonly\n            v-bind=\"props\"\n          ></v-combobox>\n        </template>\n        <v-date-picker\n          v-model=\"dates\"\n          multiple\n          no-title\n          scrollable\n        >\n          <v-spacer></v-spacer>\n          <v-btn\n            color=\"primary\"\n            variant=\"text\"\n            @click=\"menu = false\"\n          >\n            Cancel\n          </v-btn>\n          <v-btn\n            color=\"primary\"\n            variant=\"text\"\n            @click=\"menu.save(dates)\"\n          >\n            OK\n          </v-btn>\n        </v-date-picker>\n      </v-menu>\n    </v-col>\n  </v-row>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const menu = ref()\n\n  const dates = ref(['2018-09-15', '2018-09-20'])\n  const menuActive = ref(false)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      dates: ['2018-09-15', '2018-09-20'],\n      menuActive: false,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-picker/prop-range.vue",
    "content": "<template>\n  <v-row>\n    <v-col\n      cols=\"12\"\n      sm=\"6\"\n    >\n      <v-date-picker\n        v-model=\"dates\"\n        range\n      ></v-date-picker>\n    </v-col>\n    <v-col\n      cols=\"12\"\n      sm=\"6\"\n    >\n      <v-text-field\n        v-model=\"dateRangeText\"\n        label=\"Date range\"\n        prepend-icon=\"mdi-calendar\"\n        readonly\n      ></v-text-field>\n      model: {{ dates }}\n    </v-col>\n  </v-row>\n</template>\n\n<script setup>\n  import { computed, ref } from 'vue'\n\n  const dates = ref(['2019-09-10', '2019-09-20'])\n  const dateRangeText = computed(() => {\n    return dates.value.join(' ~ ')\n  })\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      dates: ['2019-09-10', '2019-09-20'],\n    }),\n    computed: {\n      dateRangeText () {\n        return this.dates.join(' ~ ')\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-picker/prop-readonly.vue",
    "content": "<template>\n  <v-row class=\"justify-center\">\n    <v-date-picker\n      v-model=\"date\"\n      readonly\n    ></v-date-picker>\n  </v-row>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const date = ref((new Date(Date.now() - (new Date()).getTimezoneOffset() * 60000)).toISOString().substr(0, 10))\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        date: (new Date(Date.now() - (new Date()).getTimezoneOffset() * 60000)).toISOString().substr(0, 10),\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-picker/prop-show-adjacent-months.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"justify-space-around\">\n      <v-date-picker show-adjacent-months></v-date-picker>\n    </v-row>\n  </v-container>\n</template>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2270-68245&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-picker/prop-show-current.vue",
    "content": "<template>\n  <v-row class=\"justify-space-around\">\n    <v-date-picker\n      v-model=\"date1\"\n      :show-current=\"false\"\n    ></v-date-picker>\n    <v-date-picker\n      v-model=\"date2\"\n      show-current=\"2013-07-13\"\n    ></v-date-picker>\n  </v-row>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const date1 = ref((new Date(Date.now() - (new Date()).getTimezoneOffset() * 60000)).toISOString().substr(0, 10))\n  const date2 = ref('2013-07-29')\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        date1: (new Date(Date.now() - (new Date()).getTimezoneOffset() * 60000)).toISOString().substr(0, 10),\n        date2: '2013-07-29',\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-picker/prop-width.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"justify-center\">\n      <v-date-picker\n        :weekday-format=\"$vuetify.display.width > 550 ? 'long' : 'short'\"\n        width=\"700\"\n      ></v-date-picker>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-picker/slots-controls.vue",
    "content": "<template>\n  <v-container class=\"d-flex align-start ga-12 justify-center flex-wrap\">\n    <v-date-picker\n      :max=\"new Date()\"\n      class=\"weekdays-primary\"\n      elevation=\"5\"\n      weekday-format=\"short\"\n      hide-header\n    >\n      <template v-slot:controls=\"{ disabled, nextMonth, prevMonth, monthYearText }\">\n        <v-btn :disabled=\"disabled.includes('prev-month')\" color=\"primary\" icon=\"$prev\" @click=\"prevMonth \"></v-btn>\n        <v-spacer></v-spacer>\n        <div class=\"text-center\">\n          <div class=\"text-body-small my-n1 text-primary\">{{ monthYearText.split(' ')[1] }}</div>\n          <div class=\"text-body-large\">{{ monthYearText.split(' ')[0] }}</div>\n        </div>\n        <v-spacer></v-spacer>\n        <v-btn :disabled=\"disabled.includes('next-month')\" color=\"primary\" icon=\"$next\" @click=\"nextMonth\"></v-btn>\n      </template>\n    </v-date-picker>\n    <v-date-picker :max=\"new Date()\" elevation=\"5\" min=\"2000-09-15\" hide-header>\n      <template v-slot:controls=\"{ monthText, yearText, openMonths, openYears }\">\n        <v-sheet class=\"w-100 d-flex align-center rounded-lg pa-1 ga-1\" color=\"rgba(var(--v-theme-on-surface), .2)\">\n          <v-btn :text=\"monthText\" append-icon=\"$dropdown\" class=\"bg-surface px-2\" @click=\"openMonths\"></v-btn>\n          <v-btn :text=\"yearText\" append-icon=\"$dropdown\" class=\"bg-surface px-2\" @click=\"openYears\"></v-btn>\n          <v-spacer></v-spacer>\n          <v-btn class=\"bg-surface px-2\" prepend-icon=\"$plus\" text=\"Add event\"></v-btn>\n        </v-sheet>\n      </template>\n    </v-date-picker>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-picker/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <v-date-picker\n      v-bind=\"props\"\n      v-model=\"date\"\n      class=\"mx-auto\"\n    ></v-date-picker>\n\n    <template v-slot:configuration>\n      <!-- <v-checkbox v-model=\"hideActions\" label=\"Hide actions\"></v-checkbox> -->\n      <v-checkbox v-model=\"adjacent\" label=\"Show adjacent months\"></v-checkbox>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-date-picker'\n  const model = ref('default')\n  const date = ref()\n  const options = ['modal']\n  // const hideActions = ref(false)\n  const adjacent = ref(false)\n\n  const controlVariant = toRef(() => model.value !== 'default' ? model.value : undefined)\n\n  const props = computed(() => {\n    return {\n      'control-variant': controlVariant.value,\n      // 'hide-actions': hideActions.value || undefined,\n      'show-adjacent-months': adjacent.value || undefined,\n    }\n  })\n\n  const slots = computed(() => {\n    return ''\n  })\n\n  const code = computed(() => {\n    return `<v-date-picker${propsToString(props.value)}>${slots.value}</v-date-picker>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-picker-month/misc-dialog-and-menu.vue",
    "content": "<template>\n  <v-row>\n    <v-col\n      cols=\"11\"\n      sm=\"5\"\n    >\n      <v-menu\n        ref=\"menu\"\n        v-model=\"menuActive\"\n        v-model:return-value=\"date\"\n        :close-on-content-click=\"false\"\n        max-width=\"290px\"\n        min-width=\"auto\"\n        transition=\"scale-transition\"\n      >\n        <template v-slot:activator=\"{ props }\">\n          <v-text-field\n            v-model=\"date\"\n            label=\"Picker in menu\"\n            prepend-icon=\"mdi-calendar\"\n            readonly\n            v-bind=\"props\"\n          ></v-text-field>\n        </template>\n        <v-date-picker\n          v-model=\"date\"\n          type=\"month\"\n          no-title\n          scrollable\n        >\n          <v-spacer></v-spacer>\n          <v-btn\n            color=\"primary\"\n            variant=\"text\"\n            @click=\"menu = false\"\n          >\n            Cancel\n          </v-btn>\n          <v-btn\n            color=\"primary\"\n            variant=\"text\"\n            @click=\"menu.save(date)\"\n          >\n            OK\n          </v-btn>\n        </v-date-picker>\n      </v-menu>\n    </v-col>\n    <v-spacer></v-spacer>\n    <v-col\n      cols=\"11\"\n      sm=\"5\"\n    >\n      <v-dialog\n        ref=\"dialog\"\n        v-model=\"modal\"\n        v-model:return-value=\"date\"\n        width=\"290px\"\n        persistent\n      >\n        <template v-slot:activator=\"{ props }\">\n          <v-text-field\n            v-model=\"date\"\n            label=\"Picker in dialog\"\n            prepend-icon=\"mdi-calendar\"\n            readonly\n            v-bind=\"props\"\n          ></v-text-field>\n        </template>\n        <v-date-picker\n          v-model=\"date\"\n          type=\"month\"\n          scrollable\n        >\n          <v-spacer></v-spacer>\n          <v-btn\n            color=\"primary\"\n            variant=\"text\"\n            @click=\"modal = false\"\n          >\n            Cancel\n          </v-btn>\n          <v-btn\n            color=\"primary\"\n            variant=\"text\"\n            @click=\"dialog.save(date)\"\n          >\n            OK\n          </v-btn>\n        </v-date-picker>\n      </v-dialog>\n    </v-col>\n  </v-row>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const menu = ref()\n  const dialog = ref()\n\n  const date = ref(new Date().toISOString().substr(0, 7))\n  const menuActive = ref(false)\n  const modal = ref(false)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      date: new Date().toISOString().substr(0, 7),\n      menuActive: false,\n      modal: false,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-picker-month/misc-internationalization.vue",
    "content": "<template>\n  <v-row class=\"justify-space-around\">\n    <v-date-picker\n      v-model=\"picker\"\n      locale=\"th\"\n      type=\"month\"\n    ></v-date-picker>\n    <v-date-picker\n      v-model=\"picker\"\n      locale=\"sv-se\"\n      type=\"month\"\n    ></v-date-picker>\n  </v-row>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const picker = ref(new Date().toISOString().substr(0, 7))\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        picker: new Date().toISOString().substr(0, 7),\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-picker-month/misc-orientation.vue",
    "content": "<template>\n  <v-row class=\"align-center\">\n    <v-checkbox\n      v-model=\"landscape\"\n      label=\"Landscape\"\n    ></v-checkbox>\n    <v-date-picker\n      v-model=\"picker\"\n      :landscape=\"landscape\"\n      type=\"month\"\n    ></v-date-picker>\n  </v-row>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const picker = ref(new Date().toISOString().substr(0, 7))\n  const landscape = ref(false)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        picker: new Date().toISOString().substr(0, 7),\n        landscape: false,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-picker-month/prop-allowed-months.vue",
    "content": "<template>\n  <v-row class=\"justify-center\">\n    <v-date-picker\n      v-model=\"date\"\n      :allowed-dates=\"allowedMonths\"\n      class=\"mt-4\"\n      max=\"2019-10\"\n      min=\"2017-06\"\n      type=\"month\"\n    ></v-date-picker>\n  </v-row>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const date = ref('2017-12')\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        date: '2017-12',\n      }\n    },\n\n    methods: {\n      allowedMonths: val => parseInt(val.split('-')[1], 10) % 2 === 0,\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-picker-month/prop-colors.vue",
    "content": "<template>\n  <v-row class=\"justify-space-around\">\n    <v-date-picker\n      v-model=\"picker\"\n      color=\"green-lighten-1\"\n      type=\"month\"\n    ></v-date-picker>\n    <v-date-picker\n      v-model=\"picker2\"\n      color=\"green-lighten-1\"\n      header-color=\"primary\"\n      type=\"month\"\n    ></v-date-picker>\n  </v-row>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const picker = ref(new Date().toISOString().substr(0, 7))\n  const picker2 = ref(new Date().toISOString().substr(0, 7))\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        picker: new Date().toISOString().substr(0, 7),\n        picker2: new Date().toISOString().substr(0, 7),\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-picker-month/prop-icons.vue",
    "content": "<template>\n  <v-row class=\"justify-center\">\n    <v-date-picker\n      v-model=\"picker\"\n      next-icon=\"mdi-skip-next\"\n      prev-icon=\"mdi-skip-previous\"\n      type=\"month\"\n      year-icon=\"mdi-calendar-blank\"\n    ></v-date-picker>\n  </v-row>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const picker = ref(new Date().toISOString().substr(0, 7))\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        picker: new Date().toISOString().substr(0, 7),\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-picker-month/prop-multiple.vue",
    "content": "<template>\n  <v-row class=\"justify-center\">\n    <v-date-picker\n      v-model=\"months\"\n      type=\"month\"\n      multiple\n    ></v-date-picker>\n  </v-row>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const months = ref(['2018-09', '2018-10'])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      months: ['2018-09', '2018-10'],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-picker-month/prop-readonly.vue",
    "content": "<template>\n  <v-row class=\"justify-center\">\n    <v-date-picker\n      v-model=\"date\"\n      type=\"month\"\n      readonly\n    ></v-date-picker>\n  </v-row>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const date = ref(new Date().toISOString().substr(0, 7))\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        date: new Date().toISOString().substr(0, 7),\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-picker-month/prop-show-current.vue",
    "content": "<template>\n  <v-row class=\"justify-space-around\">\n    <v-date-picker\n      v-model=\"month1\"\n      :show-current=\"false\"\n      type=\"month\"\n    ></v-date-picker>\n    <v-date-picker\n      v-model=\"month2\"\n      show-current=\"2013-07\"\n      type=\"month\"\n    ></v-date-picker>\n  </v-row>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const month1 = ref(new Date().toISOString().substr(0, 7))\n  const month2 = ref('2013-09')\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        month1: new Date().toISOString().substr(0, 7),\n        month2: '2013-09',\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-picker-month/prop-width.vue",
    "content": "<template>\n  <v-row class=\"justify-space-around\">\n    <v-date-picker\n      v-model=\"date\"\n      class=\"mt-4\"\n      type=\"month\"\n      width=\"290\"\n    ></v-date-picker>\n    <v-date-picker\n      v-model=\"date\"\n      class=\"mt-4\"\n      type=\"month\"\n      full-width\n    ></v-date-picker>\n  </v-row>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const date = ref(new Date().toISOString().substr(0, 7))\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      date: new Date().toISOString().substr(0, 7),\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-date-picker-month/usage.vue",
    "content": "<template>\n  <v-row class=\"justify-center\">\n    <v-date-picker\n      v-model=\"picker\"\n      type=\"month\"\n    ></v-date-picker>\n  </v-row>\n</template>\n\n<script>\n  export default {\n    data () {\n      return {\n        picker: (new Date(Date.now() - (new Date()).getTimezoneOffset() * 60000)).toISOString().substr(0, 10),\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-defaults-provider/prop-defaults.vue",
    "content": "<template>\n  <div>\n    <v-card class=\"ma-10\" subtitle=\"Subtitle\" title=\"Title\"></v-card>\n    <v-defaults-provider :defaults=\"defaults\">\n      <v-card class=\"ma-10\" subtitle=\"Subtitle\" title=\"Title\"></v-card>\n    </v-defaults-provider>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const defaults = ref({\n    global: {\n      elevation: 3,\n    },\n    VCard: {\n      color: 'secondary',\n    },\n  })\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      defaults: {\n        global: {\n          elevation: 3,\n        },\n        VCard: {\n          color: 'secondary',\n        },\n      },\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-defaults-provider/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div class=\"text-center\">\n      <v-defaults-provider\n        :defaults=\"{\n          VBtn: !button ? {} : {\n            color: 'primary',\n            size: 'large',\n            variant: 'tonal',\n          },\n        }\"\n      >\n        <v-btn>Button</v-btn>\n      </v-defaults-provider>\n    </div>\n\n    <template v-slot:configuration>\n      <v-checkbox v-model=\"button\" label=\"Use v-btn defaults\"></v-checkbox>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-defaults-provider'\n  const model = ref('default')\n  const button = ref(false)\n  const options = []\n  const props = computed(() => {\n    return {\n      defaults: button.value ? {\n        VBtn: {\n          color: 'primary',\n          size: 'large',\n          variant: 'tonal',\n        },\n      } : undefined,\n    }\n  })\n\n  const slots = computed(() => {\n    return `\n  <v-btn>Button</v-btn>\n`\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-dialog/misc-data-table.vue",
    "content": "<template>\n  <v-data-table :headers=\"headers\" :items=\"items\">\n    <template v-slot:item.progress=\"{ item }\">\n      <v-progress-linear\n        :color=\"color(item.progress)\"\n        :model-value=\"item.progress\"\n        height=\"25\"\n      >\n        <template v-slot:default=\"{ value }\">\n          <strong>{{ value }}%</strong>\n        </template>\n      </v-progress-linear>\n    </template>\n\n    <template v-slot:item.actions=\"{ item }\">\n      <v-btn\n        variant=\"text\"\n        icon\n        @click=\"edit(item)\"\n        @mouseenter=\"register($event)\"\n      >\n        <v-icon>mdi-pencil</v-icon>\n      </v-btn>\n\n      <v-btn variant=\"text\" icon @click=\"remove(item.id)\">\n        <v-icon>mdi-delete</v-icon>\n      </v-btn>\n    </template>\n  </v-data-table>\n\n  <v-dialog v-model=\"dialog\" :activator=\"activator\" max-width=\"500\">\n    <v-confirm-edit\n      ref=\"confirm\"\n      v-model=\"model\"\n      ok-text=\"save\"\n      @cancel=\"dialog = false\"\n      @save=\"save\"\n    >\n      <template v-slot:default=\"{ model: proxyModel, actions }\">\n        <v-card title=\"Modify Data\">\n          <v-card-text>\n            <v-text-field\n              v-model=\"proxyModel.value.name\"\n              label=\"Modify name\"\n            ></v-text-field>\n\n            <v-number-input\n              v-model=\"proxyModel.value.progress\"\n              label=\"Modify progress\"\n              max=\"100\"\n              min=\"0\"\n            ></v-number-input>\n          </v-card-text>\n\n          <template v-slot:actions>\n            <v-spacer></v-spacer>\n            <component :is=\"actions\"></component>\n          </template>\n        </v-card>\n      </template>\n    </v-confirm-edit>\n  </v-dialog>\n</template>\n\n<script setup>\n  import { computed, ref } from 'vue'\n\n  // v-dialog\n  const dialog = ref(false)\n  const activator = ref(null)\n\n  // v-confirm-edit\n  const confirm = ref(null)\n\n  const model = ref({\n    name: '',\n    progress: 0,\n  })\n\n  const selected = ref()\n\n  const headers = [\n    { title: 'ID', value: 'id' },\n    { title: 'Name', value: 'name' },\n    { title: 'Progress', value: 'progress' },\n    { title: 'Actions', value: 'actions' },\n  ]\n\n  const items = ref([\n    { id: 1, name: 'Tumwater', progress: 50 },\n    { id: 2, name: 'Siena', progress: 73 },\n    { id: 3, name: 'Cold Harbor', progress: 100 },\n    { id: 4, name: 'Cairns', progress: 92 },\n    { id: 5, name: 'Allentown', progress: 40 },\n  ])\n\n  // Adjust progress bar color based on progress\n  const color = computed(() => progress => {\n    if (progress === 100) return 'green-lighten-2'\n    if (progress >= 90) return 'green-lighten-4'\n    if (progress >= 70) return 'light-green-lighten-2'\n    if (progress >= 50) return 'light-green-lighten-4'\n    return 'blue-grey'\n  })\n\n  // Register current, hovered row to activator\n  // Preferrably called before edit()\n  function register (event) {\n    activator.value = event.currentTarget\n  }\n\n  // Select & load data to be edited\n  function edit (item) {\n    selected.value = item.id\n    model.value = { name: item.name, progress: item.progress }\n  }\n\n  // Update item data\n  function save () {\n    dialog.value = false\n\n    items.value = items.value.map(item =>\n      item.id === selected.value\n        ? { ...item, name: model.value.name, progress: model.value.progress }\n        : item\n    )\n  }\n\n  function remove (id) {\n    items.value = items.value.filter(item => item.id !== id)\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-dialog/misc-form.vue",
    "content": "<template>\n  <div class=\"pa-4 text-center\">\n    <v-dialog\n      v-model=\"dialog\"\n      max-width=\"600\"\n    >\n      <template v-slot:activator=\"{ props: activatorProps }\">\n        <v-btn\n          class=\"text-none font-weight-regular\"\n          prepend-icon=\"mdi-account\"\n          text=\"Edit Profile\"\n          variant=\"tonal\"\n          v-bind=\"activatorProps\"\n        ></v-btn>\n      </template>\n\n      <v-card\n        prepend-icon=\"mdi-account\"\n        title=\"User Profile\"\n      >\n        <v-card-text>\n          <v-row density=\"comfortable\">\n            <v-col\n              cols=\"12\"\n              md=\"4\"\n              sm=\"6\"\n            >\n              <v-text-field\n                label=\"First name*\"\n                required\n              ></v-text-field>\n            </v-col>\n\n            <v-col\n              cols=\"12\"\n              md=\"4\"\n              sm=\"6\"\n            >\n              <v-text-field\n                hint=\"example of helper text only on focus\"\n                label=\"Middle name\"\n              ></v-text-field>\n            </v-col>\n\n            <v-col\n              cols=\"12\"\n              md=\"4\"\n              sm=\"6\"\n            >\n              <v-text-field\n                hint=\"example of persistent helper text\"\n                label=\"Last name*\"\n                persistent-hint\n                required\n              ></v-text-field>\n            </v-col>\n\n            <v-col\n              cols=\"12\"\n              md=\"4\"\n              sm=\"6\"\n            >\n              <v-text-field\n                label=\"Email*\"\n                required\n              ></v-text-field>\n            </v-col>\n\n            <v-col\n              cols=\"12\"\n              md=\"4\"\n              sm=\"6\"\n            >\n              <v-text-field\n                label=\"Password*\"\n                type=\"password\"\n                required\n              ></v-text-field>\n            </v-col>\n\n            <v-col\n              cols=\"12\"\n              md=\"4\"\n              sm=\"6\"\n            >\n              <v-text-field\n                label=\"Confirm Password*\"\n                type=\"password\"\n                required\n              ></v-text-field>\n            </v-col>\n\n            <v-col\n              cols=\"12\"\n              sm=\"6\"\n            >\n              <v-select\n                :items=\"['0-17', '18-29', '30-54', '54+']\"\n                label=\"Age*\"\n                required\n              ></v-select>\n            </v-col>\n\n            <v-col\n              cols=\"12\"\n              sm=\"6\"\n            >\n              <v-autocomplete\n                :items=\"['Skiing', 'Ice hockey', 'Soccer', 'Basketball', 'Hockey', 'Reading', 'Writing', 'Coding', 'Basejump']\"\n                label=\"Interests\"\n                auto-select-first\n                multiple\n              ></v-autocomplete>\n            </v-col>\n          </v-row>\n\n          <small class=\"text-body-small text-medium-emphasis\">*indicates required field</small>\n        </v-card-text>\n\n        <v-divider></v-divider>\n\n        <v-card-actions>\n          <v-spacer></v-spacer>\n\n          <v-btn\n            text=\"Close\"\n            variant=\"plain\"\n            @click=\"dialog = false\"\n          ></v-btn>\n\n          <v-btn\n            color=\"primary\"\n            text=\"Save\"\n            variant=\"tonal\"\n            @click=\"dialog = false\"\n          ></v-btn>\n        </v-card-actions>\n      </v-card>\n    </v-dialog>\n  </div>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const dialog = shallowRef(false)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      dialog: false,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-dialog/misc-invite-dialog.vue",
    "content": "<template>\n  <div class=\"pa-4 text-center\">\n    <v-btn-group\n      color=\"#b2d7ef\"\n      density=\"comfortable\"\n      rounded=\"pill\"\n      divided\n    >\n      <v-btn\n        class=\"pe-2\"\n        prepend-icon=\"mdi-account-multiple-outline\"\n        variant=\"flat\"\n      >\n        <div class=\"text-none font-weight-regular\">\n          Share\n        </div>\n\n        <v-dialog activator=\"parent\" max-width=\"500\">\n          <template v-slot:default=\"{ isActive }\">\n            <v-card rounded=\"lg\">\n              <v-card-title class=\"d-flex justify-space-between align-center\">\n                <div class=\"text-headline-small text-medium-emphasis ps-2\">\n                  Invite John to connect\n                </div>\n\n                <v-btn\n                  icon=\"mdi-close\"\n                  variant=\"text\"\n                  @click=\"isActive.value = false\"\n                ></v-btn>\n              </v-card-title>\n\n              <v-divider class=\"mb-4\"></v-divider>\n\n              <v-card-text>\n                <div class=\"text-medium-emphasis mb-4\">\n                  Invite collaborators to your network and grow your connections.\n                </div>\n\n                <div class=\"mb-2\">Message (optional)</div>\n\n                <v-textarea\n                  :counter=\"300\"\n                  class=\"mb-2\"\n                  rows=\"2\"\n                  variant=\"outlined\"\n                  persistent-counter\n                ></v-textarea>\n\n                <div class=\"text-label-medium mb-2\">💎 PREMIUM</div>\n\n                <div class=\"text-medium-emphasis mb-1\">\n                  Share with unlimited people and get more insights about your network. Try Premium Free for 30 days.\n                </div>\n\n                <v-btn\n                  class=\"text-none font-weight-bold ms-n4\"\n                  color=\"primary\"\n                  text=\"Retry Premium Free\"\n                  variant=\"text\"\n                ></v-btn>\n              </v-card-text>\n\n              <v-divider class=\"mt-2\"></v-divider>\n\n              <v-card-actions class=\"my-2 d-flex justify-end\">\n                <v-btn\n                  class=\"text-none\"\n                  rounded=\"xl\"\n                  text=\"Cancel\"\n                  @click=\"isActive.value = false\"\n                ></v-btn>\n\n                <v-btn\n                  class=\"text-none\"\n                  color=\"primary\"\n                  rounded=\"xl\"\n                  text=\"Send\"\n                  variant=\"flat\"\n                  @click=\"isActive.value = false\"\n                ></v-btn>\n              </v-card-actions>\n            </v-card>\n          </template>\n        </v-dialog>\n      </v-btn>\n\n      <v-btn\n        size=\"small\"\n        icon\n      >\n        <v-icon icon=\"mdi-menu-down\"></v-icon>\n\n        <v-menu\n          activator=\"parent\"\n          location=\"bottom end\"\n          transition=\"fade-transition\"\n        >\n          <v-list\n            density=\"compact\"\n            min-width=\"250\"\n            rounded=\"lg\"\n            slim\n          >\n            <v-list-item\n              prepend-icon=\"mdi-link\"\n              title=\"Copy link\"\n              link\n            ></v-list-item>\n\n            <v-divider class=\"my-2\"></v-divider>\n\n            <v-list-item min-height=\"24\">\n              <template v-slot:subtitle>\n                <div class=\"text-body-small\">\n                  Shared with John + 1 more\n                </div>\n              </template>\n            </v-list-item>\n          </v-list>\n        </v-menu>\n      </v-btn>\n    </v-btn-group>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-dialog/misc-loader.vue",
    "content": "<template>\n  <div class=\"pa-4 text-center\">\n    <v-btn\n      :disabled=\"dialog\"\n      color=\"primary\"\n      icon=\"mdi-refresh\"\n      text=\"Start loading\"\n      @click=\"dialog = true\"\n    ></v-btn>\n\n    <v-dialog\n      v-model=\"dialog\"\n      max-width=\"320\"\n      persistent\n    >\n      <v-list\n        class=\"py-2\"\n        color=\"primary\"\n        elevation=\"4\"\n        rounded=\"lg\"\n      >\n        <v-list-item\n          prepend-icon=\"$vuetify-outline\"\n          title=\"Refreshing Application...\"\n        >\n          <template v-slot:prepend>\n            <div class=\"pe-4\">\n              <v-icon color=\"primary\" size=\"x-large\"></v-icon>\n            </div>\n          </template>\n\n          <template v-slot:append>\n            <v-progress-circular\n              color=\"primary\"\n              indeterminate=\"disable-shrink\"\n              size=\"16\"\n              width=\"2\"\n            ></v-progress-circular>\n          </template>\n        </v-list-item>\n      </v-list>\n    </v-dialog>\n  </div>\n</template>\n\n<script setup>\n  import { shallowRef, watch } from 'vue'\n\n  const dialog = shallowRef(false)\n  watch(dialog, val => {\n    if (!val) return\n    setTimeout(() => (dialog.value = false), 4000)\n  })\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        dialog: false,\n      }\n    },\n\n    watch: {\n      dialog (val) {\n        if (!val) return\n\n        setTimeout(() => (this.dialog = false), 4000)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-dialog/misc-nesting.vue",
    "content": "<template>\n  <div class=\"pa-4 text-center\">\n    <v-btn\n      text=\"Open Dialog 1\"\n      @click=\"dialog = true\"\n    ></v-btn>\n\n    <v-dialog\n      v-model=\"dialog\"\n      max-width=\"480\"\n    >\n      <v-card title=\"Dialog 1\">\n        <template v-slot:text>\n          <v-btn\n            class=\"my-2\"\n            text=\"Open Dialog 2\"\n            @click=\"dialog2 = true\"\n          ></v-btn>\n        </template>\n\n        <v-card-actions>\n          <v-spacer></v-spacer>\n\n          <v-btn\n            text=\"Close\"\n            variant=\"text\"\n            @click=\"dialog = false\"\n          ></v-btn>\n        </v-card-actions>\n      </v-card>\n    </v-dialog>\n\n    <v-dialog\n      v-model=\"dialog2\"\n      max-width=\"240\"\n    >\n      <v-card title=\"Dialog 2\">\n        <template v-slot:text>\n          <v-btn\n            class=\"my-2\"\n            text=\"Open Dialog 3\"\n            @click=\"dialog3 = !dialog3\"\n          ></v-btn>\n        </template>\n\n        <v-card-actions>\n          <v-spacer></v-spacer>\n\n          <v-btn\n            text=\"Close\"\n            variant=\"text\"\n            @click=\"dialog2 = false\"\n          ></v-btn>\n        </v-card-actions>\n      </v-card>\n    </v-dialog>\n\n    <v-dialog\n      v-model=\"dialog3\"\n      width=\"auto\"\n    >\n      <v-card title=\"Dialog 3\">\n        <v-card-actions>\n          <v-spacer></v-spacer>\n\n          <v-btn\n            text=\"Close\"\n            variant=\"text\"\n            @click=\"dialog3 = false\"\n          ></v-btn>\n        </v-card-actions>\n      </v-card>\n    </v-dialog>\n  </div>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const dialog = shallowRef(false)\n  const dialog2 = shallowRef(false)\n  const dialog3 = shallowRef(false)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        dialog: false,\n        dialog2: false,\n        dialog3: false,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-dialog/misc-overflowed.vue",
    "content": "<template>\n  <div class=\"pa-4 text-center\">\n    <v-dialog max-width=\"800\">\n      <template v-slot:activator=\"{ props: activatorProps }\">\n        <v-btn\n          v-bind=\"activatorProps\"\n          text=\"Open Dialog\"\n        ></v-btn>\n      </template>\n\n      <template v-slot:default=\"{ isActive }\">\n        <v-card title=\"Use Google's location service?\">\n          <template v-slot:text>\n            Lorem ipsum dolor sit amet, semper quis, sapien id natoque elit. Nostra urna at, magna at neque sed sed ante imperdiet, dolor mauris cursus velit, velit non, sem nec. Volutpat sem ridiculus placerat leo, augue in, duis erat proin condimentum in a eget, sed fermentum sed vestibulum varius ac, vestibulum volutpat orci ut elit eget tortor. Ultrices nascetur nulla gravida ante arcu. Pharetra rhoncus morbi ipsum, nunc tempor debitis, ipsum pellentesque, vitae id quam ut mauris dui tempor, aptent non. Quisque turpis. Phasellus quis lectus luctus orci eget rhoncus. Amet donec vestibulum mattis commodo, nulla aliquet, nibh praesent, elementum nulla. Sit lacus pharetra tempus magna neque pellentesque, nulla vel erat.\n\n            <br>\n\n            Justo ex quisque nulla accusamus venenatis, sed quis. Nibh phasellus gravida metus in, fusce aenean ut erat commodo eros. Ut turpis, dui integer, nonummy pede placeat nec in sit leo. Faucibus porttitor illo taciti odio, amet viverra scelerisque quis quis et tortor, curabitur morbi a. Enim tempor at, rutrum elit condimentum, amet rutrum vitae tempor torquent nunc. Praesent vestibulum integer maxime felis. Neque aenean quia vitae nostra, tempus elit enim id dui, at egestas pulvinar. Integer libero vestibulum, quis blandit scelerisque mattis fermentum nulla, tortor donec vestibulum dolor amet eget, elit nullam. Aliquam leo phasellus aliquam curabitur metus a, nulla justo mattis duis interdum vel, mollis vitae et id, vestibulum erat ridiculus sit pulvinar justo sed. Vehicula convallis, et nulla wisi, amet vestibulum risus, quam ac egestas.\n\n            <br>\n\n            Et vitae, nulla gravida erat scelerisque nullam nunc pellentesque, a dictumst cras augue, purus imperdiet non. Varius montes cursus varius vel tortor, nec leo a qui, magni cras, velit vel consectetuer lobortis vel. Nibh erat et wisi felis leo porttitor, sapien nibh sapien pede mi, sed eget porttitor, repellendus arcu ac quis. Luctus vulputate aut est sem magna, placerat accumsan nunc vestibulum ipsum ac auctor, maecenas lorem in ut nec mauris tortor, doloribus varius sem tortor vestibulum mollis, eleifend tortor felis tempus lacus eu eu. Eleifend vel eu, nullam maecenas mauris nec nunc euismod, tortor porta ridiculus potenti, massa tristique nam magna, et wisi placerat et erat ante. Eget pede erat in facilisis, fermentum venenatis sodales. Ac tortor sociis et non animi tristique, rhoncus malesuada, ut arcu volutpat scelerisque sollicitudin, elit curabitur dui pede purus dolor, integer aenean risus taciti nulla eleifend accumsan. At pulvinar diam parturient, interdum mi velit aliquet et a. Arcu at ac placerat eget justo semper, purus sociis curabitur mi ipsum consequat ut, mollis vestibulum, est ante ornare lacus sem. Neque magna mauris, commodo quisque, praesent semper suscipit lobortis nam. Justo malesuada cursus ac nunc litora nunc. Tellus ac, in lobortis nunc, montes lectus purus fermentum.\n\n            <br>\n\n            Ac sit wisi. Sodales aliquam, sed vestibulum nullam arcu sit risus arcu, id luctus vitae lorem nibh, integer nec nullam class cursus mi, purus arcu lectus. Vel ante suscipit volutpat potenti mattis sed, wisi eu placerat aliquam erat, lectus morbi lobortis at assumenda. Consequat neque purus ipsum voluptas odio, netus vestibulum ut nec, suspendisse pellentesque nec enim in. Wisi dictum sed semper a, ipsum erat tellus habitasse est, erat sem ornare, vitae quisque ultricies. Dui sed blandit. Tempor et faucibus justo sed luctus, nec vitae vitae. Nunc nibh pede, ipsum vestibulum aenean leo ante ultricies, nam cras quis sed penatibus amet. In mauris a. Integer metus mauris tortor, et rutrum vestibulum ultricies, ut phasellus in ullamcorper ut mollit, eu justo. Cursus pretium venenatis.\n            Cras pellentesque vel sodales accumsan aenean. Feugiat metus sit nec in aliquet amet, porttitor pretium vulputate massa. Consequat ipsum luctus quisque adipiscing libero. Wisi sollicitudin. Eget vitae ac lobortis, lorem natoque vestibulum et, aliquet faucibus at morbi nibh, vel condimentum. Massa unde orci sed id sed, odio donec congue nec praesent amet. Hymenaeos velit lacus, quis vivamus libero tempus duis, eu nisi eu, ipsum at accumsan pede justo morbi donec, massa et libero sit risus neque tortor. Ut sed sed etiam hendrerit dapibus, quis metus suspendisse nibh.\n\n            <br>\n\n            Fringilla tempor felis augue magna. Cum arcu a, id vitae. Pellentesque pharetra in cras sociis adipiscing est. Nibh nec mattis at maecenas, nisl orci aliquam nulla justo egestas venenatis, elementum duis vel porta eros, massa vitae, eligendi imperdiet amet. Nec neque luctus suscipit, justo sem praesent, ut nisl quisque, volutpat torquent wisi tellus aliquam reprehenderit, curabitur cras at quis massa porttitor mauris. Eros sed ultrices. Amet dignissim justo urna feugiat mauris litora, etiam accumsan, lobortis a orci suspendisse. Semper ac mauris, varius bibendum pretium, orci urna nunc ullamcorper auctor, saepe sem integer quam, at feugiat egestas duis. Urna ligula ante. Leo elementum nonummy. Sagittis mauris est in ipsum, nulla amet non justo, proin id potenti platea posuere sit ut, nunc sit erat bibendum. Nibh id auctor, ab nulla vivamus ultrices, posuere morbi nunc tellus gravida vivamus.\n\n            <br>\n\n            Mauris nec, facilisi quam fermentum, ut mauris integer, orci tellus tempus diam ut in pellentesque. Wisi faucibus tempor et odio leo diam, eleifend quis integer curabitur sit scelerisque ac, mauris consequat luctus quam penatibus fringilla dis, vitae lacus in, est eu ac tempus. Consectetuer amet ipsum amet dui, sed blandit id sed. Tellus integer, dignissim id pede sodales quis, felis dolorem id mauris orci, orci tempus ut. Nullam hymenaeos. Curabitur in a, tortor ut praesent placerat tincidunt interdum, ac dignissim metus nonummy hendrerit wisi, etiam ut.\n\n            <br>\n\n            Semper praesent integer fusce, tortor suspendisse, augue ligula orci ante asperiores ullamcorper. In sit per mi sed sed, mi vestibulum mus nam, morbi mauris neque vitae aliquam proin senectus. Ac amet arcu mollis ante congue elementum, inceptos eget optio quam pellentesque quis lobortis, sollicitudin sed vestibulum sollicitudin, lectus parturient nullam, leo orci ligula ultrices. At tincidunt enim, suspendisse est sit sem ac. Amet tellus molestie est purus magna augue, non etiam et in wisi id. Non commodo, metus lorem facilisi lobortis ac velit, montes neque sed risus consectetuer fringilla dolor. Quam justo et integer aliquam, cursus nulla enim orci, nam cursus adipiscing, integer torquent non, fringilla per maecenas. Libero ipsum sed tellus purus et. Duis molestie placerat erat donec ut. Dolor enim erat massa faucibus ultrices in, ante ultricies orci lacus, libero consectetuer mauris magna feugiat neque dapibus, donec pretium et. Aptent dui, aliquam et et amet nostra ligula.\n\n            <br>\n\n            Augue curabitur duis dui volutpat, tempus sed ut pede donec. Interdum luctus, lectus nulla aenean elit, id sit magna, vulputate ultrices pellentesque vel id fermentum morbi. Tortor et. Adipiscing augue lorem cum non lacus, rutrum sodales laoreet duis tortor, modi placerat facilisis et malesuada eros ipsum, vehicula tempus. Ac vivamus amet non aliquam venenatis lectus, sociosqu adipiscing consequat nec arcu odio. Blandit orci nec nec, posuere in pretium, enim ut, consectetuer nullam urna, risus vel. Nullam odio vehicula massa sed, etiam sociis mauris, lacus ullamcorper, libero imperdiet non sodales placerat justo vehicula. Nec morbi imperdiet. Fermentum sem libero iaculis bibendum et eros, eget maecenas non nunc, ad pellentesque. Ut nec diam elementum interdum. Elementum vitae tellus lacus vitae, ipsum phasellus, corporis vehicula in ac sed massa vivamus, rutrum elit, ultricies metus volutpat.\n\n            <br>\n\n            Semper wisi et, sollicitudin nunc vestibulum, cursus accumsan nunc pede tempus mi ipsum, ligula sed. Non condimentum ac dolor sit. Mollis eu aliquam, vel mattis mollis massa ut dolor ante, tempus lacinia arcu. Urna vestibulum lorem, nulla fermentum, iaculis ut congue ac vivamus. Nam libero orci, pulvinar nulla, enim pellentesque consectetuer leo, feugiat rhoncus rhoncus vel. Magna sociosqu donec, dictum cursus ullamcorper viverra. Ultricies quis orci lorem, suspendisse ut vestibulum integer, purus sed lorem pulvinar habitasse turpis.\n          </template>\n\n          <v-card-actions>\n            <v-spacer></v-spacer>\n\n            <v-btn\n              text=\"Disagree\"\n              variant=\"text\"\n              @click=\"isActive.value = false\"\n            ></v-btn>\n\n            <v-btn\n              color=\"surface-variant\"\n              text=\"Agree\"\n              variant=\"flat\"\n              @click=\"isActive.value = false\"\n            ></v-btn>\n          </v-card-actions>\n        </v-card>\n      </template>\n    </v-dialog>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-dialog/misc-without-activator.vue",
    "content": "<template>\n  <v-row class=\"justify-center\">\n    <v-btn\n      color=\"primary\"\n      @click.stop=\"dialog = true\"\n    >\n      Open Dialog\n    </v-btn>\n\n    <v-dialog\n      v-model=\"dialog\"\n      max-width=\"290\"\n    >\n      <v-card>\n        <v-card-title class=\"text-headline-small\">\n          Use Google's location service?\n        </v-card-title>\n\n        <v-card-text>\n          Let Google help apps determine location. This means sending anonymous location data to Google, even when no apps are running.\n        </v-card-text>\n\n        <v-card-actions>\n          <v-spacer></v-spacer>\n\n          <v-btn\n            color=\"green-darken-1\"\n            variant=\"text\"\n            @click=\"dialog = false\"\n          >\n            Disagree\n          </v-btn>\n\n          <v-btn\n            color=\"green-darken-1\"\n            variant=\"text\"\n            @click=\"dialog = false\"\n          >\n            Agree\n          </v-btn>\n        </v-card-actions>\n      </v-card>\n    </v-dialog>\n  </v-row>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const dialog = ref(false)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        dialog: false,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-dialog/prop-activator.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"text-center\">\n      <v-col cols=\"12\" md=\"6\">\n        <v-dialog max-width=\"340\">\n          <template v-slot:activator=\"{ props: activatorProps }\">\n            <v-btn\n              v-bind=\"activatorProps\"\n              prepend-icon=\"mdi-package\"\n              width=\"204\"\n            >\n              Slot Activator\n            </v-btn>\n          </template>\n\n          <template v-slot:default=\"{ isActive }\">\n            <v-card\n              prepend-icon=\"mdi-package\"\n              text=\"When using the activator slot, you must bind the slot props to the activator element.\"\n              title=\"Slot Activator\"\n            >\n              <template v-slot:actions>\n                <v-btn\n                  class=\"ml-auto\"\n                  text=\"Close\"\n                  @click=\"isActive.value = false\"\n                ></v-btn>\n              </template>\n            </v-card>\n          </template>\n        </v-dialog>\n      </v-col>\n\n      <v-col cols=\"12\" md=\"6\">\n        <v-btn\n          prepend-icon=\"mdi-picture-in-picture-bottom-right\"\n          width=\"204\"\n        >\n          Parent Activator\n\n          <v-dialog activator=\"parent\" max-width=\"340\">\n            <template v-slot:default=\"{ isActive }\">\n              <v-card\n                prepend-icon=\"mdi-picture-in-picture-bottom-right\"\n                text=\"When using the parent as the activator, the dialog will bind its listeners to the parent element.\"\n                title=\"Parent Activator\"\n              >\n                <template v-slot:actions>\n                  <v-btn\n                    class=\"ml-auto\"\n                    text=\"Close\"\n                    @click=\"isActive.value = false\"\n                  ></v-btn>\n                </template>\n              </v-card>\n            </template>\n          </v-dialog>\n        </v-btn>\n      </v-col>\n\n      <v-col cols=\"12\" md=\"6\">\n        <v-btn\n          ref=\"btn\"\n          prepend-icon=\"mdi-variable\"\n          width=\"204\"\n        >\n          Ref Activator\n        </v-btn>\n\n        <v-dialog :activator=\"btn\" max-width=\"340\">\n          <template v-slot:default=\"{ isActive }\">\n            <v-card\n              prepend-icon=\"mdi-variable\"\n              text=\"When using a ref, the dialog will bind its listeners to the ref element. This works for any element and custom components.\"\n              title=\"Ref Activator\"\n            >\n              <template v-slot:actions>\n                <v-btn\n                  class=\"ml-auto\"\n                  text=\"Close\"\n                  @click=\"isActive.value = false\"\n                ></v-btn>\n              </template>\n            </v-card>\n          </template>\n        </v-dialog>\n      </v-col>\n\n      <v-col cols=\"12\" md=\"6\">\n        <v-btn\n          id=\"activator-target\"\n          prepend-icon=\"mdi-bullseye-arrow\"\n          width=\"204\"\n        >\n          Target Activator\n        </v-btn>\n\n        <v-dialog activator=\"#activator-target\" max-width=\"340\">\n          <template v-slot:default=\"{ isActive }\">\n            <v-card\n              prepend-icon=\"mdi-bullseye-arrow\"\n              text=\"Pass any valid querySelector to the activator prop to bind the dialog to the target element.\"\n              title=\"Target Activator\"\n            >\n              <template v-slot:actions>\n                <v-btn\n                  class=\"ml-auto\"\n                  text=\"Close\"\n                  @click=\"isActive.value = false\"\n                ></v-btn>\n              </template>\n            </v-card>\n          </template>\n        </v-dialog>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const btn = ref(null)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        btn: null,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-dialog/prop-fullscreen.vue",
    "content": "<template>\n  <div class=\"text-center pa-4\">\n    <v-dialog\n      v-model=\"dialog\"\n      transition=\"dialog-bottom-transition\"\n      fullscreen\n    >\n      <template v-slot:activator=\"{ props: activatorProps }\">\n        <v-btn\n          prepend-icon=\"mdi-cog\"\n          size=\"small\"\n          text=\"Settings\"\n          v-bind=\"activatorProps\"\n        ></v-btn>\n      </template>\n\n      <v-card>\n        <v-toolbar>\n          <v-btn\n            icon=\"mdi-close\"\n            @click=\"dialog = false\"\n          ></v-btn>\n\n          <v-toolbar-title>Settings</v-toolbar-title>\n\n          <v-toolbar-items>\n            <v-btn\n              text=\"Save\"\n              variant=\"text\"\n              @click=\"dialog = false\"\n            ></v-btn>\n          </v-toolbar-items>\n        </v-toolbar>\n\n        <v-list lines=\"two\">\n          <v-list-subheader>User Controls</v-list-subheader>\n\n          <v-list-item\n            subtitle=\"Set the content filtering level to restrict apps that can be downloaded\"\n            title=\"Content filtering\"\n            link\n          ></v-list-item>\n\n          <v-list-item\n            subtitle=\"Require password for purchase or use password to restrict purchase\"\n            title=\"Password\"\n            link\n          ></v-list-item>\n\n          <v-divider></v-divider>\n\n          <v-list-subheader>General</v-list-subheader>\n\n          <v-list-item\n            subtitle=\"Notify me about updates to apps or games that I downloaded\"\n            title=\"Notifications\"\n            @click=\"notifications = !notifications\"\n          >\n            <template v-slot:prepend>\n              <v-list-item-action start>\n                <v-checkbox-btn v-model=\"notifications\" color=\"primary\"></v-checkbox-btn>\n              </v-list-item-action>\n            </template>\n          </v-list-item>\n\n          <v-list-item\n            subtitle=\"Auto-update apps at any time. Data charges may apply\"\n            title=\"Sound\"\n            @click=\"sound = !sound\"\n          >\n            <template v-slot:prepend>\n              <v-list-item-action start>\n                <v-checkbox-btn v-model=\"sound\" color=\"primary\"></v-checkbox-btn>\n              </v-list-item-action>\n            </template>\n          </v-list-item>\n\n          <v-list-item\n            subtitle=\"Automatically add home screen widgets\"\n            title=\"Auto-add widgets\"\n            @click=\"widgets = !widgets\"\n          >\n            <template v-slot:prepend>\n              <v-list-item-action start>\n                <v-checkbox-btn v-model=\"widgets\" color=\"primary\"></v-checkbox-btn>\n              </v-list-item-action>\n            </template>\n          </v-list-item>\n        </v-list>\n      </v-card>\n    </v-dialog>\n  </div>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const dialog = shallowRef(false)\n  const notifications = shallowRef(false)\n  const sound = shallowRef(true)\n  const widgets = shallowRef(false)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        dialog: false,\n        notifications: false,\n        sound: true,\n        widgets: false,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-dialog/prop-model.vue",
    "content": "<template>\n  <div class=\"text-center pa-4\">\n    <v-btn @click=\"dialog = true\">\n      Open Dialog\n    </v-btn>\n\n    <v-dialog\n      v-model=\"dialog\"\n      width=\"auto\"\n    >\n      <v-card\n        max-width=\"400\"\n        prepend-icon=\"mdi-update\"\n        text=\"Your application will relaunch automatically after the update is complete.\"\n        title=\"Update in progress\"\n      >\n        <template v-slot:actions>\n          <v-btn\n            class=\"ms-auto\"\n            text=\"Ok\"\n            @click=\"dialog = false\"\n          ></v-btn>\n        </template>\n      </v-card>\n    </v-dialog>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const dialog = ref(false)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        dialog: false,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-dialog/prop-persistent.vue",
    "content": "<template>\n  <div class=\"text-center pa-4\">\n    <v-dialog\n      v-model=\"dialog\"\n      max-width=\"400\"\n      persistent\n    >\n      <template v-slot:activator=\"{ props: activatorProps }\">\n        <v-btn v-bind=\"activatorProps\">\n          Open Dialog\n        </v-btn>\n      </template>\n\n      <v-card\n        prepend-icon=\"mdi-map-marker\"\n        text=\"Let Google help apps determine location. This means sending anonymous location data to Google, even when no apps are running.\"\n        title=\"Use Google's location service?\"\n      >\n        <template v-slot:actions>\n          <v-spacer></v-spacer>\n\n          <v-btn @click=\"dialog = false\">\n            Disagree\n          </v-btn>\n\n          <v-btn @click=\"dialog = false\">\n            Agree\n          </v-btn>\n        </template>\n      </v-card>\n    </v-dialog>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const dialog = ref(false)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        dialog: false,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-dialog/prop-scrollable.vue",
    "content": "<template>\n  <div class=\"pa-4 text-center\">\n    <v-dialog\n      width=\"auto\"\n      scrollable\n    >\n      <template v-slot:activator=\"{ props: activatorProps }\">\n        <v-btn\n          color=\"brown\"\n          prepend-icon=\"mdi-earth\"\n          text=\"Select Country\"\n          variant=\"outlined\"\n          v-bind=\"activatorProps\"\n        ></v-btn>\n      </template>\n\n      <template v-slot:default=\"{ isActive }\">\n        <v-card\n          prepend-icon=\"mdi-earth\"\n          title=\"Select Country\"\n        >\n          <v-divider class=\"mt-3\"></v-divider>\n\n          <v-card-text class=\"px-4\" style=\"height: 300px;\">\n            <v-radio-group\n              v-model=\"dialog\"\n              messages=\"Select a Country from the radio group\"\n            >\n              <v-radio\n                label=\"Bahamas, The\"\n                value=\"bahamas\"\n              ></v-radio>\n\n              <v-radio\n                label=\"Bahrain\"\n                value=\"bahrain\"\n              ></v-radio>\n\n              <v-radio\n                label=\"Bangladesh\"\n                value=\"bangladesh\"\n              ></v-radio>\n\n              <v-radio\n                label=\"Barbados\"\n                value=\"barbados\"\n              ></v-radio>\n\n              <v-radio\n                label=\"Belarus\"\n                value=\"belarus\"\n              ></v-radio>\n\n              <v-radio\n                label=\"Belgium\"\n                value=\"belgium\"\n              ></v-radio>\n\n              <v-radio\n                label=\"Belize\"\n                value=\"belize\"\n              ></v-radio>\n\n              <v-radio\n                label=\"Benin\"\n                value=\"benin\"\n              ></v-radio>\n\n              <v-radio\n                label=\"Bhutan\"\n                value=\"bhutan\"\n              ></v-radio>\n\n              <v-radio\n                label=\"Bolivia\"\n                value=\"bolivia\"\n              ></v-radio>\n\n              <v-radio\n                label=\"Bosnia and Herzegovina\"\n                value=\"bosnia\"\n              ></v-radio>\n\n              <v-radio\n                label=\"Botswana\"\n                value=\"botswana\"\n              ></v-radio>\n\n              <v-radio\n                label=\"Brazil\"\n                value=\"brazil\"\n              ></v-radio>\n\n              <v-radio\n                label=\"Brunei\"\n                value=\"brunei\"\n              ></v-radio>\n\n              <v-radio\n                label=\"Bulgaria\"\n                value=\"bulgaria\"\n              ></v-radio>\n\n              <v-radio\n                label=\"Burkina Faso\"\n                value=\"burkina\"\n              ></v-radio>\n\n              <v-radio\n                label=\"Burma\"\n                value=\"burma\"\n              ></v-radio>\n\n              <v-radio\n                label=\"Burundi\"\n                value=\"burundi\"\n              ></v-radio>\n            </v-radio-group>\n          </v-card-text>\n\n          <v-divider></v-divider>\n\n          <v-card-actions>\n            <v-btn\n              text=\"Close\"\n              @click=\"isActive.value = false\"\n            ></v-btn>\n\n            <v-spacer></v-spacer>\n\n            <v-btn\n              color=\"surface-variant\"\n              text=\"Save\"\n              variant=\"flat\"\n              @click=\"isActive.value = false\"\n            ></v-btn>\n          </v-card-actions>\n        </v-card>\n      </template>\n    </v-dialog>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const dialog = ref('')\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        dialog: '',\n      }\n    },\n  }\n</script>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=1632-103562&t=tWnPBMI0RfGlNRgq-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-dialog/prop-transitions.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"justify-space-around\">\n      <v-col cols=\"12\" md=\"6\">\n        <v-dialog\n          transition=\"dialog-bottom-transition\"\n          width=\"auto\"\n        >\n          <template v-slot:activator=\"{ props: activatorProps }\">\n            <v-btn\n              v-bind=\"activatorProps\"\n              text=\"Transition from Bottom\"\n              block\n            ></v-btn>\n          </template>\n\n          <template v-slot:default=\"{ isActive }\">\n            <v-card>\n              <v-toolbar title=\"Opening from the Bottom\"></v-toolbar>\n\n              <v-card-text class=\"text-display-large pa-12\">\n                Hello world!\n              </v-card-text>\n\n              <v-card-actions class=\"justify-end\">\n                <v-btn\n                  text=\"Close\"\n                  @click=\"isActive.value = false\"\n                ></v-btn>\n              </v-card-actions>\n            </v-card>\n          </template>\n        </v-dialog>\n      </v-col>\n\n      <v-col cols=\"12\" md=\"6\">\n        <v-dialog\n          transition=\"dialog-top-transition\"\n          width=\"auto\"\n        >\n          <template v-slot:activator=\"{ props: activatorProps }\">\n            <v-btn\n              v-bind=\"activatorProps\"\n              text=\"Transition from Top\"\n              block\n            ></v-btn>\n          </template>\n          <template v-slot:default=\"{ isActive }\">\n            <v-card>\n              <v-toolbar title=\"Opening from the Top\"></v-toolbar>\n\n              <v-card-text class=\"text-display-large pa-12\">\n                Hello world!\n              </v-card-text>\n\n              <v-card-actions class=\"justify-end\">\n                <v-btn\n                  text=\"Close\"\n                  @click=\"isActive.value = false\"\n                ></v-btn>\n              </v-card-actions>\n            </v-card>\n          </template>\n        </v-dialog>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-dialog/slot-default.vue",
    "content": "<template>\n  <div class=\"text-center pa-4\">\n    <v-btn @click=\"dialog = true\">\n      Open Dialog\n    </v-btn>\n\n    <v-dialog\n      v-model=\"dialog\"\n      width=\"auto\"\n    >\n      <v-card\n        max-width=\"400\"\n        prepend-icon=\"mdi-update\"\n        text=\"Your application will relaunch automatically after the update is complete.\"\n        title=\"Update in progress\"\n      >\n        <template v-slot:actions>\n          <v-btn\n            class=\"ms-auto\"\n            text=\"Ok\"\n            @click=\"dialog = false\"\n          ></v-btn>\n        </template>\n      </v-card>\n    </v-dialog>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const dialog = ref(false)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        dialog: false,\n      }\n    },\n  }\n</script>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=1632-103314&t=tWnPBMI0RfGlNRgq-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-dialog/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div class=\"text-center\">\n      <v-dialog\n        v-model=\"dialog\"\n        v-bind=\"props\"\n      >\n        <template v-slot:activator=\"{ props: activatorProps }\">\n          <v-btn v-bind=\"activatorProps\">\n            Open Dialog\n          </v-btn>\n        </template>\n\n        <template v-slot:default=\"{ isActive }\">\n          <v-card title=\"Dialog\">\n            <v-card-text>\n              Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n            </v-card-text>\n\n            <v-card-actions>\n              <v-spacer></v-spacer>\n\n              <v-btn\n                text=\"Close Dialog\"\n                @click=\"isActive.value = false\"\n              ></v-btn>\n            </v-card-actions>\n          </v-card>\n        </template>\n      </v-dialog>\n    </div>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-dialog'\n  const model = ref('default')\n  const dialog = ref(false)\n  const options = []\n\n  const props = computed(() => {\n    return {\n      'max-width': '500',\n    }\n  })\n\n  const slots = computed(() => {\n    return `\n  <template v-slot:activator=\"{ props: activatorProps }\">\n    <v-btn\n      v-bind=\"activatorProps\"\n      color=\"surface-variant\"\n      text=\"Open Dialog\"\n      variant=\"flat\"\n    ></v-btn>\n  </template>\n\n  <template v-slot:default=\"{ isActive }\">\n    <v-card title=\"Dialog\">\n      <v-card-text>\n        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n      </v-card-text>\n\n      <v-card-actions>\n        <v-spacer></v-spacer>\n\n        <v-btn\n          text=\"Close Dialog\"\n          @click=\"isActive.value = false\"\n        ></v-btn>\n      </v-card-actions>\n    </v-card>\n  </template>\n`\n  })\n\n  const code = computed(() => {\n    return `<v-dialog${propsToString(props.value)}>${slots.value}</v-dialog>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-divider/misc-portrait-view.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"500\"\n  >\n    <v-card-item class=\"bg-cyan-darken-1\">\n      <v-card-title>\n        <span class=\"text-headline-small\">Sarah Mcbeal</span>\n      </v-card-title>\n\n      <template v-slot:append>\n        <v-defaults-provider\n          :defaults=\"{\n            VBtn: {\n              variant: 'text',\n              density: 'comfortable',\n            }\n          }\"\n        >\n          <v-btn icon=\"mdi-chevron-left\"></v-btn>\n\n          <v-btn icon=\"mdi-pencil\"></v-btn>\n\n          <v-btn icon=\"mdi-dots-vertical\"></v-btn>\n        </v-defaults-provider>\n      </template>\n    </v-card-item>\n\n    <v-list>\n      <v-list-item\n        append-icon=\"mdi-message-text\"\n        prepend-icon=\"mdi-phone\"\n        title=\"(650) 555-1234\"\n      ></v-list-item>\n\n      <v-divider inset></v-divider>\n\n      <v-list-item\n        append-icon=\"mdi-message-text\"\n        prepend-icon=\"mdi-phone\"\n        title=\"(323) 555-6789\"\n      ></v-list-item>\n\n      <v-divider inset></v-divider>\n\n      <v-list-item\n        prepend-icon=\"mdi-email\"\n        title=\"mcbeal@example.com\"\n      ></v-list-item>\n\n      <v-divider inset></v-divider>\n\n      <v-list-item\n        prepend-icon=\"mdi-map-marker\"\n        title=\"Orlando, FL 79938\"\n      ></v-list-item>\n    </v-list>\n\n    <v-img\n      height=\"200\"\n      src=\"https://picsum.photos/700?image=996\"\n      cover\n    ></v-img>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-divider/misc-subheaders.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"400\"\n  >\n    <v-toolbar\n      color=\"orange-lighten-1\"\n      dark\n    >\n      <v-app-bar-nav-icon></v-app-bar-nav-icon>\n\n      <v-toolbar-title>Message Board</v-toolbar-title>\n\n      <v-btn icon>\n        <v-icon>mdi-magnify</v-icon>\n      </v-btn>\n    </v-toolbar>\n\n    <v-list lines=\"two\">\n      <template v-for=\"(item, index) in items\">\n        <v-list-subheader\n          v-if=\"item.header\"\n          :key=\"item.header\"\n          inset\n        >\n          {{ item.header }}\n        </v-list-subheader>\n\n        <v-divider\n          v-else-if=\"item.divider\"\n          :key=\"index\"\n          inset\n        ></v-divider>\n\n        <v-list-item\n          v-else\n          :key=\"item.title\"\n          :prepend-avatar=\"item.avatar\"\n          ripple\n        >\n          <template v-slot:title>\n            <div v-html=\"item.title\"></div>\n          </template>\n\n          <template v-slot:subtitle>\n            <div v-html=\"item.subtitle\"></div>\n          </template>\n        </v-list-item>\n      </template>\n    </v-list>\n  </v-card>\n</template>\n\n<script setup>\n  const items = [\n    {\n      header: 'Today',\n    },\n    { divider: true },\n    {\n      avatar: 'https://picsum.photos/250/300?image=660',\n      title: 'Meeting @ Noon',\n      subtitle: `<span class=\"font-weight-bold\">Spike Lee</span> &mdash; I'll be in your neighborhood`,\n    },\n    {\n      avatar: 'https://picsum.photos/250/300?image=821',\n      title: 'Summer BBQ <span class=\"text-grey-lighten-1\"></span>',\n      subtitle: '<span class=\"font-weight-bold\">to Operations support</span> &mdash; Wish I could come.',\n    },\n    {\n      avatar: 'https://picsum.photos/250/300?image=783',\n      title: 'Yes yes',\n      subtitle: '<span class=\"font-weight-bold\">Bella</span> &mdash; Do you have Paris recommendations',\n    },\n    {\n      header: 'Yesterday',\n    },\n    { divider: true },\n    {\n      avatar: 'https://picsum.photos/250/300?image=1006',\n      title: 'Dinner tonight?',\n      subtitle: '<span class=\"font-weight-bold\">LaToya</span> &mdash; Do you want to hang out?',\n    },\n    {\n      avatar: 'https://picsum.photos/250/300?image=146',\n      title: 'So long',\n      subtitle: '<span class=\"font-weight-bold\">Nancy</span> &mdash; Do you see what time it is?',\n    },\n    {\n      header: 'Last Week',\n    },\n    { divider: true },\n    {\n      avatar: 'https://picsum.photos/250/300?image=1008',\n      title: 'Breakfast?',\n      subtitle: '<span class=\"font-weight-bold\">LaToya</span> &mdash; Do you want to hang out?',\n    },\n    {\n      avatar: 'https://picsum.photos/250/300?image=839',\n      title: 'Winter Porridge <span class=\"text-grey-lighten-1\"></span>',\n      subtitle: '<span class=\"font-weight-bold\">cc: Daniel</span> &mdash; Tell me more...',\n    },\n    {\n      avatar: 'https://picsum.photos/250/300?image=145',\n      title: 'Oui oui',\n      subtitle: '<span class=\"font-weight-bold\">Nancy</span> &mdash; Do you see what time it is?',\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        {\n          header: 'Today',\n        },\n        { divider: true },\n        {\n          avatar: 'https://picsum.photos/250/300?image=660',\n          title: 'Meeting @ Noon',\n          subtitle: `<span class=\"font-weight-bold\">Spike Lee</span> &mdash; I'll be in your neighborhood`,\n        },\n        {\n          avatar: 'https://picsum.photos/250/300?image=821',\n          title: 'Summer BBQ <span class=\"text-grey-lighten-1\"></span>',\n          subtitle: '<span class=\"font-weight-bold\">to Operations support</span> &mdash; Wish I could come.',\n        },\n        {\n          avatar: 'https://picsum.photos/250/300?image=783',\n          title: 'Yes yes',\n          subtitle: '<span class=\"font-weight-bold\">Bella</span> &mdash; Do you have Paris recommendations',\n        },\n        {\n          header: 'Yesterday',\n        },\n        { divider: true },\n        {\n          avatar: 'https://picsum.photos/250/300?image=1006',\n          title: 'Dinner tonight?',\n          subtitle: '<span class=\"font-weight-bold\">LaToya</span> &mdash; Do you want to hang out?',\n        },\n        {\n          avatar: 'https://picsum.photos/250/300?image=146',\n          title: 'So long',\n          subtitle: '<span class=\"font-weight-bold\">Nancy</span> &mdash; Do you see what time it is?',\n        },\n        {\n          header: 'Last Week',\n        },\n        { divider: true },\n        {\n          avatar: 'https://picsum.photos/250/300?image=1008',\n          title: 'Breakfast?',\n          subtitle: '<span class=\"font-weight-bold\">LaToya</span> &mdash; Do you want to hang out?',\n        },\n        {\n          avatar: 'https://picsum.photos/250/300?image=839',\n          title: 'Winter Porridge <span class=\"text-grey-lighten-1\"></span>',\n          subtitle: '<span class=\"font-weight-bold\">cc: Daniel</span> &mdash; Tell me more...',\n        },\n        {\n          avatar: 'https://picsum.photos/250/300?image=145',\n          title: 'Oui oui',\n          subtitle: '<span class=\"font-weight-bold\">Nancy</span> &mdash; Do you see what time it is?',\n        },\n      ],\n    }),\n  }\n</script>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=1632-105006&t=tWnPBMI0RfGlNRgq-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-divider/prop-gradient.vue",
    "content": "<template>\n  <v-container class=\"d-flex\">\n    <div class=\"d-flex flex-column gr-4 py-8 flex-grow-1\">\n      <v-divider color=\"red\" opacity=\".7\" thickness=\"3\" gradient></v-divider>\n      <v-divider opacity=\".7\" thickness=\"3\" gradient>OR</v-divider>\n      <v-divider\n        color=\"primary\"\n        opacity=\".7\"\n        thickness=\"12\"\n        variant=\"double\"\n        gradient\n      >\n        AND\n      </v-divider>\n    </div>\n    <div class=\"d-flex gc-8 px-8\">\n      <v-divider color=\"red\" opacity=\".7\" thickness=\"3\" gradient vertical></v-divider>\n      <v-divider opacity=\".7\" thickness=\"3\" gradient vertical>OR</v-divider>\n      <v-divider\n        color=\"primary\"\n        opacity=\".7\"\n        thickness=\"12\"\n        variant=\"double\"\n        gradient\n        vertical\n      >\n        AND\n      </v-divider>\n    </div>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-divider/prop-inset.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"425\"\n  >\n    <v-list lines=\"two\">\n      <v-list-subheader>Today</v-list-subheader>\n\n      <v-list-item\n        prepend-avatar=\"https://cdn.vuetifyjs.com/images/lists/1.jpg\"\n        title=\"Brunch this weekend?\"\n      >\n        <template v-slot:subtitle>\n          <span class=\"font-weight-bold\">Ali Connors</span> &mdash; I'll be in your neighborhood doing errands this weekend. Do you want to hang out?\n        </template>\n      </v-list-item>\n\n      <v-divider inset></v-divider>\n\n      <v-list-item\n        prepend-avatar=\"https://cdn.vuetifyjs.com/images/lists/2.jpg\"\n      >\n        <template v-slot:title>\n          Summer BBQ <span class=\"text-grey-lighten-1\">4</span>\n        </template>\n\n        <template v-slot:subtitle>\n          <span class=\"font-weight-bold\">to Alex, Scott, Jennifer</span> &mdash; Wish I could come, but I'm out of town this weekend.\n        </template>\n      </v-list-item>\n\n      <v-divider inset></v-divider>\n\n      <v-list-item\n        prepend-avatar=\"https://cdn.vuetifyjs.com/images/lists/3.jpg\"\n        title=\"Oui oui\"\n      >\n        <template v-slot:subtitle>\n          <span class=\"font-weight-bold\">Sandra Adams</span> &mdash; Do you have Paris recommendations? Have you ever been?\n        </template>\n      </v-list-item>\n    </v-list>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-divider/prop-vertical.vue",
    "content": "<template>\n  <div class=\"text-body-medium mb-1\">dividers with <v-code>vertical</v-code></div>\n  <v-toolbar color=\"purple\">\n    <template v-slot:prepend>\n      <div class=\"text-headline-small px-3\">Title</div>\n    </template>\n\n    <v-divider class=\"mx-3\" vertical></v-divider>\n    <v-toolbar-title>My Home</v-toolbar-title>\n\n    <v-toolbar-items>\n      <v-btn variant=\"text\">News</v-btn>\n      <v-divider vertical></v-divider>\n      <v-btn variant=\"text\">Blog</v-btn>\n      <v-divider vertical></v-divider>\n      <v-btn variant=\"text\">Music</v-btn>\n    </v-toolbar-items>\n    <v-divider vertical></v-divider>\n    <v-app-bar-nav-icon class=\"ms-2\"></v-app-bar-nav-icon>\n  </v-toolbar>\n\n  <div class=\"text-body-medium mt-3 mb-1\">dividers with <v-code>vertical</v-code> and <v-code>inset</v-code></div>\n  <v-toolbar color=\"teal\">\n    <template v-slot:prepend>\n      <div class=\"text-headline-small px-3\">Title</div>\n    </template>\n\n    <v-divider class=\"mx-3\" inset vertical></v-divider>\n    <v-toolbar-title>My Home</v-toolbar-title>\n\n    <v-toolbar-items>\n      <v-btn variant=\"text\">News</v-btn>\n      <v-divider inset vertical></v-divider>\n      <v-btn variant=\"text\">Blog</v-btn>\n      <v-divider inset vertical></v-divider>\n      <v-btn variant=\"text\">Music</v-btn>\n    </v-toolbar-items>\n    <v-divider inset vertical></v-divider>\n    <v-app-bar-nav-icon class=\"ms-2\"></v-app-bar-nav-icon>\n  </v-toolbar>\n</template>\n\n<style scoped>\n.v-toolbar .v-divider {\n  --v-border-opacity: .7\n}\n</style>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2418-7463&t=tWnPBMI0RfGlNRgq-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-divider/slot-default.vue",
    "content": "<template>\n  <v-container class=\"d-flex flex-column gr-4\">\n    <v-divider content-offset=\"2rem\" opacity=\".7\" thickness=\"5\" variant=\"dotted\" gradient>CHAPTER 1.4</v-divider>\n    <v-divider :content-offset=\"[40, -1.5]\" opacity=\".7\" thickness=\"2\" variant=\"dashed\">∞</v-divider>\n    <v-divider :content-offset=\"[12, 2.5]\" opacity=\".7\">* * *</v-divider>\n    <v-divider color=\"primary\" content-offset=\"-16\" opacity=\"1\" style=\"color: inherit\" thickness=\"1\">\n      <v-avatar class=\"border border-primary border-opacity-100\" icon=\"mdi-chevron-down\" size=\"36\"></v-avatar>\n    </v-divider>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-divider/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div class=\"d-flex align-center justify-center\" style=\"height: 200px;\">\n      <v-divider v-bind=\"props\"></v-divider>\n    </div>\n\n    <template v-slot:configuration>\n      <v-slider v-model=\"thickness\" label=\"Thickness\" max=\"20\" min=\"1\"></v-slider>\n\n      <v-select v-model=\"opacity\" :items=\"opacities\" label=\"Opacity\"></v-select>\n\n      <v-select v-model=\"color\" :items=\"colors\" label=\"Color\"></v-select>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-divider'\n  const model = ref('default')\n  const color = ref()\n  const opacity = ref('default')\n  const thickness = ref(1)\n  const colors = [\n    'success',\n    'info',\n    'warning',\n    'error',\n  ]\n  const opacities = [100, 75, 50, 25, 'default', 0]\n  const options = ['inset', 'vertical']\n  const props = computed(() => {\n    let classes\n\n    if (opacity.value != null && opacity.value !== 'default') {\n      classes = `border-opacity-${opacity.value}`\n    }\n    return {\n      thickness: thickness.value !== 1 ? thickness.value : undefined,\n      class: classes || undefined,\n      color: color.value || undefined,\n      inset: model.value === 'inset' || undefined,\n      vertical: model.value === 'vertical' || undefined,\n    }\n  })\n\n  const slots = computed(() => {\n    return ``\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-empty-state/misc-astro-cat.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"360\"\n    variant=\"flat\"\n    border\n  >\n    <v-layout>\n      <v-system-bar class=\"ga-1\" color=\"surface-light\">\n        <v-icon icon=\"mdi-square\" size=\"x-small\"></v-icon>\n\n        <v-icon icon=\"mdi-circle\" size=\"x-small\"></v-icon>\n\n        <v-icon icon=\"mdi-triangle\" size=\"x-small\"></v-icon>\n      </v-system-bar>\n\n      <v-app-bar title=\"My Library\">\n        <template v-slot:prepend>\n          <v-app-bar-nav-icon></v-app-bar-nav-icon>\n        </template>\n\n        <template v-slot:extension>\n          <v-tabs v-model=\"tabs\" color=\"#4c00d5\" grow>\n            <v-tab text=\"My Movies\"></v-tab>\n\n            <v-tab text=\"My Tv Shows\"></v-tab>\n          </v-tabs>\n        </template>\n      </v-app-bar>\n\n      <v-main>\n        <div class=\"pt-4 pb-16\">\n          <v-window v-model=\"tabs\">\n            <v-window-item :value=\"0\" class=\"pa-2\">\n              <v-card>\n                <v-empty-state\n                  class=\"pa-0\"\n                  image=\"https://vuetifyjs.b-cdn.net/docs/images/components/v-empty-state/astro-cat.svg\"\n                  size=\"200\"\n                >\n                  <template v-slot:media>\n                    <v-sheet class=\"py-4 mb-4\" color=\"#fdefff\">\n                      <v-img></v-img>\n                    </v-sheet>\n                  </template>\n\n                  <template v-slot:title>\n                    <div class=\"text-title-large text-high-emphasis\">Get Started</div>\n                  </template>\n\n                  <template v-slot:text>\n                    <div class=\"text-body-medium font-weight-medium text-medium-emphasis\">\n                      Find a great movie, then relax and enjoy with the Movies & TV app.\n                    </div>\n                  </template>\n\n                  <template v-slot:actions>\n                    <v-spacer></v-spacer>\n\n                    <v-btn color=\"#4c00d5\" text=\"Shop Movies\"></v-btn>\n\n                    <v-spacer></v-spacer>\n                  </template>\n                </v-empty-state>\n              </v-card>\n            </v-window-item>\n\n            <v-window-item :value=\"1\" class=\"pa-2\">\n              <v-card>\n                <v-empty-state\n                  class=\"pa-0\"\n                  image=\"https://vuetifyjs.b-cdn.net/docs/images/components/v-empty-state/astro-dog.svg\"\n                  size=\"200\"\n                >\n                  <template v-slot:media>\n                    <v-sheet class=\"py-4 mb-4\" color=\"#fdefff\">\n                      <v-img></v-img>\n                    </v-sheet>\n                  </template>\n\n                  <template v-slot:title>\n                    <div class=\"text-title-large text-high-emphasis\">Get Started</div>\n                  </template>\n\n                  <template v-slot:text>\n                    <div class=\"text-body-medium font-weight-medium text-medium-emphasis\">\n                      Watch your favorite TV Shows with the Movies & TV app.\n                    </div>\n                  </template>\n\n                  <template v-slot:actions>\n                    <v-spacer></v-spacer>\n\n                    <v-btn color=\"#4c00d5\" text=\"Shop TV Shows\"></v-btn>\n\n                    <v-spacer></v-spacer>\n                  </template>\n                </v-empty-state>\n              </v-card>\n            </v-window-item>\n          </v-window>\n        </div>\n      </v-main>\n    </v-layout>\n  </v-card>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const tabs = shallowRef(0)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      tabs: 0,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-empty-state/misc-astro-dog.vue",
    "content": "<template>\n  <v-card class=\"mx-auto\" max-width=\"360\">\n    <v-layout>\n      <v-system-bar class=\"ga-1\" color=\"#4c00d5\">\n        <v-icon icon=\"mdi-square\" size=\"x-small\"></v-icon>\n\n        <v-icon icon=\"mdi-circle\" size=\"x-small\"></v-icon>\n\n        <v-icon icon=\"mdi-triangle\" size=\"x-small\"></v-icon>\n      </v-system-bar>\n\n      <v-app-bar color=\"#6200ee\" title=\"Drafts\">\n        <template v-slot:prepend>\n          <v-app-bar-nav-icon></v-app-bar-nav-icon>\n        </template>\n\n        <template v-slot:append>\n          <v-btn icon=\"mdi-magnify\"></v-btn>\n\n          <v-btn icon=\"mdi-dots-vertical\"></v-btn>\n        </template>\n      </v-app-bar>\n\n      <v-main>\n        <v-empty-state\n          image=\"https://vuetifyjs.b-cdn.net/docs/images/components/v-empty-state/astro-dog.svg\"\n          size=\"200\"\n          text-width=\"250\"\n        >\n          <template v-slot:media>\n            <v-img class=\"mb-8\"></v-img>\n          </template>\n\n          <template v-slot:title>\n            <div class=\"text-title-large text-high-emphasis\">Empty in drafts</div>\n          </template>\n\n          <template v-slot:text>\n            <div class=\"text-body-large\">Save a draft message and it will show up here</div>\n          </template>\n        </v-empty-state>\n      </v-main>\n\n      <v-layout-item\n        class=\"text-end\"\n        position=\"bottom\"\n        size=\"80\"\n        model-value\n      >\n        <v-btn\n          class=\"ma-4\"\n          color=\"#4c00d5\"\n          elevation=\"3\"\n          icon=\"mdi-plus\"\n        ></v-btn>\n      </v-layout-item>\n    </v-layout>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-empty-state/prop-actions.vue",
    "content": "<template>\n  <v-empty-state\n    action-text=\"Retry Request\"\n    image=\"https://cdn.vuetifyjs.com/docs/images/components/v-empty-state/connection.svg\"\n    text=\"There might be a problem with your connection or our servers. Please check your internet connection or try again later. We appreciate your patience.\"\n    title=\"Something Went Wrong\"\n    @click:action=\"onClickAction\"\n  ></v-empty-state>\n</template>\n\n<script setup>\n  function onClickAction () {\n    alert('You clicked the action button')\n  }\n</script>\n\n<script>\n  export default {\n    methods: {\n      onClickAction () {\n        alert('You clicked the action button')\n      },\n    },\n  }\n</script>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2261-15913&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-empty-state/prop-content.vue",
    "content": "<template>\n  <v-empty-state\n    headline=\"No Messages Yet\"\n    text=\"You haven't received any messages yet. When you do, they'll appear here.\"\n    title=\"Check back later.\"\n    @click:action=\"onClickAction\"\n  ></v-empty-state>\n</template>\n\n<script setup>\n  function onClickAction () {\n    alert('You clicked the action button')\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-empty-state/prop-media.vue",
    "content": "<template>\n  <v-empty-state\n    icon=\"mdi-magnify\"\n    text=\"Try adjusting your search terms or filters. Sometimes less specific terms or broader queries can help you find what you're looking for.\"\n    title=\"We couldn't find a match.\"\n  ></v-empty-state>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-empty-state/slot-actions.vue",
    "content": "<template>\n  <v-empty-state image=\"https://cdn.vuetifyjs.com/docs/images/components/v-empty-state/teamwork.png\">\n    <template v-slot:title>\n      <div class=\"text-title-small mt-8\">\n        Manage your inventory transfers\n      </div>\n    </template>\n\n    <template v-slot:text>\n      <div class=\"text-body-small\">\n        Track and receive your incoming inventory from suppliers\n      </div>\n    </template>\n\n    <template v-slot:actions>\n      <v-btn\n        class=\"text-none\"\n        color=\"white\"\n        elevation=\"1\"\n        rounded=\"lg\"\n        size=\"small\"\n        text=\"Learn more\"\n        width=\"96\"\n      ></v-btn>\n\n      <v-btn\n        class=\"text-none\"\n        elevation=\"1\"\n        rounded=\"lg\"\n        size=\"small\"\n        text=\"Add transfer\"\n        width=\"96\"\n      ></v-btn>\n    </template>\n  </v-empty-state>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-empty-state/slot-default.vue",
    "content": "<template>\n  <v-empty-state\n    headline=\"Welcome,\"\n    icon=\"$vuetify\"\n    title=\"What would you like to do today?\"\n  >\n    <v-container>\n      <v-row>\n        <v-col cols=\"12\" md=\"6\">\n          <v-card\n            href=\"https://vuetifyjs.com/introduction/why-vuetify/#feature-guides\"\n            prepend-icon=\"$vuetify\"\n            target=\"_blank\"\n            text=\"Start with our dedicated feature guides\"\n            title=\"Learn Vuetify\"\n          ></v-card>\n        </v-col>\n\n        <v-col cols=\"12\" md=\"6\">\n          <v-card\n            href=\"https://play.vuetifyjs.com\"\n            prepend-icon=\"$vuetify-play\"\n            target=\"_blank\"\n            text=\"Test Vuetify out in our playground\"\n            title=\"Create a Playground\"\n          ></v-card>\n        </v-col>\n\n        <v-col cols=\"12\" md=\"6\">\n          <v-card\n            href=\"https://bin.vuetifyjs.com\"\n            prepend-icon=\"mdi-delete\"\n            target=\"_blank\"\n            text=\"Create a new bin to store your code\"\n            title=\"Create a Bin\"\n          ></v-card>\n        </v-col>\n\n        <v-col cols=\"12\" md=\"6\">\n          <v-card\n            href=\"https://issues.vuetifyjs.com\"\n            prepend-icon=\"$warning\"\n            target=\"_blank\"\n            text=\"File a bug report for Vuetify\"\n            title=\"Report a Bug\"\n          ></v-card>\n        </v-col>\n      </v-row>\n    </v-container>\n  </v-empty-state>\n</template>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2261-15951&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-empty-state/slot-title.vue",
    "content": "<template>\n  <v-empty-state icon=\"$success\">\n    <template v-slot:media>\n      <v-icon color=\"surface-variant\"></v-icon>\n    </template>\n\n    <template v-slot:headline>\n      <div class=\"text-headline-large\">\n        All Done For Now!\n      </div>\n    </template>\n\n    <template v-slot:title>\n      <div class=\"text-title-large\">\n        You're all caught up.\n      </div>\n    </template>\n\n    <template v-slot:text>\n      <div class=\"text-medium-emphasis text-body-small\">\n        Great job on completing all your tasks! This might be a good time to relax or consider planning your next set of goals. If you think of something new, just hit the button below to add a new task.\n      </div>\n    </template>\n  </v-empty-state>\n</template>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2261-33467&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-empty-state/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <v-empty-state\n      v-bind=\"props\"\n    ></v-empty-state>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-empty-state'\n  const model = ref('default')\n  const options = []\n\n  const props = computed(() => {\n    return {\n      headline: 'Whoops, 404',\n      title: 'Page not found',\n      text: 'The page you were looking for does not exist',\n      image: 'https://vuetifyjs.b-cdn.net/docs/images/logos/v.png',\n    }\n  })\n\n  const slots = computed(() => {\n    return ''\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-expansion-panels/misc-advanced.vue",
    "content": "<template>\n  <v-expansion-panels>\n    <v-expansion-panel>\n      <v-expansion-panel-title>\n        <template v-slot:default=\"{ expanded }\">\n          <v-row density=\"comfortable\">\n            <v-col class=\"d-flex justify-start\" cols=\"4\">\n              Trip name\n            </v-col>\n            <v-col\n              class=\"text-grey\"\n              cols=\"8\"\n            >\n              <v-fade-transition leave-absolute>\n                <span\n                  v-if=\"expanded\"\n                  key=\"0\"\n                >\n                  Enter a name for the trip\n                </span>\n                <span\n                  v-else\n                  key=\"1\"\n                >\n                  {{ trip.name }}\n                </span>\n              </v-fade-transition>\n            </v-col>\n          </v-row>\n        </template>\n      </v-expansion-panel-title>\n      <v-expansion-panel-text>\n        <v-text-field\n          v-model=\"trip.name\"\n          placeholder=\"Caribbean Cruise\"\n          hide-details\n        ></v-text-field>\n      </v-expansion-panel-text>\n    </v-expansion-panel>\n\n    <v-expansion-panel>\n      <v-expansion-panel-title v-slot=\"{ expanded }\">\n        <v-row density=\"comfortable\">\n          <v-col class=\"d-flex justify-start\" cols=\"4\">\n            Location\n          </v-col>\n          <v-col\n            class=\"text--secondary\"\n            cols=\"8\"\n          >\n            <v-fade-transition leave-absolute>\n              <span\n                v-if=\"expanded\"\n                key=\"0\"\n              >\n                Select trip destination\n              </span>\n              <span\n                v-else\n                key=\"1\"\n              >\n                {{ trip.location }}\n              </span>\n            </v-fade-transition>\n          </v-col>\n        </v-row>\n      </v-expansion-panel-title>\n      <v-expansion-panel-text>\n        <v-row density=\"comfortable\">\n          <v-spacer></v-spacer>\n          <v-col cols=\"5\">\n            <v-select\n              v-model=\"trip.location\"\n              :items=\"locations\"\n              variant=\"solo\"\n              chips\n              flat\n            ></v-select>\n          </v-col>\n\n          <v-divider\n            class=\"mx-4\"\n            vertical\n          ></v-divider>\n\n          <v-col cols=\"3\">\n            Select your destination of choice\n            <br>\n            <a href=\"#\">Learn more</a>\n          </v-col>\n        </v-row>\n\n        <v-card-actions>\n          <v-spacer></v-spacer>\n          <v-btn\n            color=\"secondary\"\n            variant=\"text\"\n          >\n            Cancel\n          </v-btn>\n          <v-btn\n            color=\"primary\"\n            variant=\"text\"\n          >\n            Save\n          </v-btn>\n        </v-card-actions>\n      </v-expansion-panel-text>\n    </v-expansion-panel>\n\n    <v-expansion-panel>\n      <v-expansion-panel-title v-slot=\"{ expanded }\">\n        <v-row density=\"comfortable\">\n          <v-col class=\"d-flex justify-start\" cols=\"4\">\n            Start and end dates\n          </v-col>\n          <v-col\n            class=\"text--secondary\"\n            cols=\"8\"\n          >\n            <v-fade-transition leave-absolute>\n              <span v-if=\"expanded\">When do you want to travel?</span>\n              <v-row\n                v-else\n                density=\"compact\"\n                style=\"width: 100%\"\n              >\n                <v-col class=\"d-flex justify-start\" cols=\"6\">\n                  Start date: {{ trip.start || 'Not set' }}\n                </v-col>\n                <v-col class=\"d-flex justify-start\" cols=\"6\">\n                  End date: {{ trip.end || 'Not set' }}\n                </v-col>\n              </v-row>\n            </v-fade-transition>\n          </v-col>\n        </v-row>\n      </v-expansion-panel-title>\n      <v-expansion-panel-text>\n        <v-row\n          class=\"justify-space-around\"\n          density=\"compact\"\n        >\n          <v-col cols=\"3\">\n            <v-text-field\n              v-model=\"trip.start\"\n              label=\"Start date\"\n              type=\"date\"\n            ></v-text-field>\n          </v-col>\n\n          <v-col cols=\"3\">\n            <v-text-field\n              v-model=\"trip.end\"\n              label=\"End date\"\n              type=\"date\"\n            ></v-text-field>\n          </v-col>\n        </v-row>\n      </v-expansion-panel-text>\n    </v-expansion-panel>\n  </v-expansion-panels>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const locations = ['Australia', 'Barbados', 'Chile', 'Denmark', 'Ecuador', 'France']\n\n  const trip = ref({\n    name: '',\n    location: null,\n    start: null,\n    end: null,\n  })\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      trip: {\n        name: '',\n        location: null,\n        start: null,\n        end: null,\n      },\n      locations: ['Australia', 'Barbados', 'Chile', 'Denmark', 'Ecuador', 'France'],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-expansion-panels/misc-custom-icons.vue",
    "content": "<template>\n  <div>\n    <v-expansion-panels class=\"mb-6\">\n      <v-expansion-panel\n        v-for=\"i in 3\"\n        :key=\"i\"\n      >\n        <v-expansion-panel-title expand-icon=\"mdi-menu-down\">\n          Item\n        </v-expansion-panel-title>\n        <v-expansion-panel-text>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</v-expansion-panel-text>\n      </v-expansion-panel>\n    </v-expansion-panels>\n\n    <v-expansion-panels>\n      <v-expansion-panel>\n        <v-expansion-panel-title collapse-icon=\"mdi-minus\" expand-icon=\"mdi-plus\">\n          Item\n        </v-expansion-panel-title>\n        <v-expansion-panel-text>\n          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n        </v-expansion-panel-text>\n      </v-expansion-panel>\n\n      <v-expansion-panel>\n        <v-expansion-panel-title>\n          Item\n          <template v-slot:actions=\"{ expanded }\">\n            <v-icon :color=\"!expanded ? 'teal' : ''\" :icon=\"expanded ? 'mdi-pencil' : 'mdi-check'\"></v-icon>\n          </template>\n        </v-expansion-panel-title>\n        <v-expansion-panel-text>\n          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n        </v-expansion-panel-text>\n      </v-expansion-panel>\n\n      <v-expansion-panel>\n        <v-expansion-panel-title disable-icon-rotate>\n          Item\n          <template v-slot:actions>\n            <v-icon color=\"error\" icon=\"mdi-alert-circle\">\n            </v-icon>\n          </template>\n        </v-expansion-panel-title>\n        <v-expansion-panel-text>\n          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n        </v-expansion-panel-text>\n      </v-expansion-panel>\n    </v-expansion-panels>\n  </div>\n</template>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2790-117689&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-expansion-panels/prop-disabled.vue",
    "content": "<template>\n  <div>\n    <div class=\"d-flex\">\n      <v-checkbox\n        v-model=\"disabled\"\n        label=\"Disabled\"\n      ></v-checkbox>\n    </div>\n\n    <v-expansion-panels\n      v-model=\"panel\"\n      :disabled=\"disabled\"\n      multiple\n    >\n      <v-expansion-panel>\n        <v-expansion-panel-title>Panel 1</v-expansion-panel-title>\n        <v-expansion-panel-text>\n          Some content\n        </v-expansion-panel-text>\n      </v-expansion-panel>\n\n      <v-expansion-panel>\n        <v-expansion-panel-title>Panel 2</v-expansion-panel-title>\n        <v-expansion-panel-text>\n          Some content\n        </v-expansion-panel-text>\n      </v-expansion-panel>\n\n      <v-expansion-panel>\n        <v-expansion-panel-title>Panel 3</v-expansion-panel-title>\n        <v-expansion-panel-text>\n          Some content\n        </v-expansion-panel-text>\n      </v-expansion-panel>\n    </v-expansion-panels>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const panel = ref([0, 1])\n  const disabled = ref(false)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      panel: [0, 1],\n      disabled: false,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-expansion-panels/prop-model.vue",
    "content": "<template>\n  <div>\n    <div class=\"text-center d-flex pb-4\">\n      <v-btn class=\"ma-2\" @click=\"all\">\n        All\n      </v-btn>\n      <v-btn class=\"ma-2\" @click=\"none\">\n        None\n      </v-btn>\n    </div>\n\n    <div class=\"pb-4\">v-model {{ panel }}</div>\n\n    <v-expansion-panels\n      v-model=\"panel\"\n      multiple\n    >\n      <v-expansion-panel\n        text=\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\"\n        title=\"Foo\"\n        value=\"foo\"\n      ></v-expansion-panel>\n\n      <v-expansion-panel\n        text=\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\"\n        title=\"Bar\"\n        value=\"bar\"\n      ></v-expansion-panel>\n\n      <v-expansion-panel\n        text=\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\"\n        title=\"Baz\"\n        value=\"baz\"\n      ></v-expansion-panel>\n    </v-expansion-panels>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const panel = ref([])\n  function all () {\n    panel.value = ['foo', 'bar', 'baz']\n  }\n  function none () {\n    panel.value = []\n  }\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        panel: [],\n      }\n    },\n    methods: {\n      all () {\n        this.panel = ['foo', 'bar', 'baz']\n      },\n      none () {\n        this.panel = []\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-expansion-panels/prop-readonly.vue",
    "content": "<template>\n  <div>\n    <div class=\"d-flex\">\n      <v-checkbox\n        v-model=\"readonly\"\n        label=\"Readonly\"\n      ></v-checkbox>\n    </div>\n\n    <v-expansion-panels\n      v-model=\"panel\"\n      :readonly=\"readonly\"\n      multiple\n    >\n      <v-expansion-panel>\n        <v-expansion-panel-title>Panel 1</v-expansion-panel-title>\n        <v-expansion-panel-text>\n          Some content\n        </v-expansion-panel-text>\n      </v-expansion-panel>\n\n      <v-expansion-panel>\n        <v-expansion-panel-title>Panel 2</v-expansion-panel-title>\n        <v-expansion-panel-text>\n          Some content\n        </v-expansion-panel-text>\n      </v-expansion-panel>\n\n      <v-expansion-panel>\n        <v-expansion-panel-title>Panel 3</v-expansion-panel-title>\n        <v-expansion-panel-text>\n          Some content\n        </v-expansion-panel-text>\n      </v-expansion-panel>\n    </v-expansion-panels>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const panel = ref([0, 1])\n  const readonly = ref(false)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      panel: [0, 1],\n      readonly: false,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-expansion-panels/prop-variant.vue",
    "content": "<template>\n  <div>\n    <div class=\"text-title-small mb-2\">Default</div>\n    <v-expansion-panels>\n      <v-expansion-panel\n        v-for=\"i in 3\"\n        :key=\"i\"\n        text=\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\"\n        title=\"Item\"\n      ></v-expansion-panel>\n    </v-expansion-panels>\n\n    <div class=\"text-title-small mt-4 mb-2\">Accordion</div>\n\n    <v-expansion-panels variant=\"accordion\">\n      <v-expansion-panel\n        v-for=\"i in 3\"\n        :key=\"i\"\n        text=\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\"\n        title=\"Item\"\n      ></v-expansion-panel>\n    </v-expansion-panels>\n\n    <div class=\"text-title-small mt-4 mb-2\">Inset</div>\n\n    <v-expansion-panels class=\"my-4\" variant=\"inset\">\n      <v-expansion-panel\n        v-for=\"i in 3\"\n        :key=\"i\"\n        text=\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\"\n        title=\"Item\"\n      ></v-expansion-panel>\n    </v-expansion-panels>\n\n    <div class=\"text-title-small mt-4 mb-2\">Popout</div>\n\n    <v-expansion-panels class=\"my-4\" variant=\"popout\">\n      <v-expansion-panel\n        v-for=\"i in 3\"\n        :key=\"i\"\n        text=\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\"\n        title=\"Item\"\n      ></v-expansion-panel>\n    </v-expansion-panels>\n  </div>\n</template>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2791-123125&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-expansion-panels/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div>\n      <v-expansion-panels v-bind=\"props\">\n        <v-expansion-panel\n          text=\"Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima\"\n          title=\"Title\"\n        >\n        </v-expansion-panel>\n      </v-expansion-panels>\n    </div>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-expansion-panels'\n  const model = ref('default')\n  const options = []\n  const props = computed(() => {\n    return {}\n  })\n\n  const slots = computed(() => {\n    return `\n  <v-expansion-panel\n    title=\"Title\"\n    text=\"Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima\"\n  >\n  </v-expansion-panel>\n`\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-fab/misc-display-animation.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"360\"\n  >\n    <v-layout>\n      <v-app-bar absolute extended>\n        <v-app-bar-nav-icon></v-app-bar-nav-icon>\n\n        <template v-slot:extension>\n          <v-fab\n            :active=\"!hidden\"\n            class=\"ms-4\"\n            icon=\"mdi-plus\"\n            location=\"bottom start\"\n            size=\"small\"\n            absolute\n            offset\n          ></v-fab>\n        </template>\n      </v-app-bar>\n\n      <v-main>\n        <v-sheet class=\"pa-4 text-center\" color=\"surface-light\" height=\"300\">\n          <v-btn\n            :text=\"hidden ? 'Show' : 'Hide'\"\n            color=\"surface-variant\"\n            width=\"80\"\n            @click=\"hidden = !hidden\"\n          >\n          </v-btn>\n        </v-sheet>\n\n        <v-sheet height=\"125\">\n          <v-fab\n            :active=\"!hidden\"\n            class=\"me-4\"\n            icon=\"mdi-plus\"\n            location=\"top end\"\n            absolute\n            offset\n          ></v-fab>\n        </v-sheet>\n      </v-main>\n    </v-layout>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const hidden = ref(false)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      hidden: false,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-fab/misc-lateral-screens.vue",
    "content": "<template>\n  <v-card>\n    <v-layout>\n      <v-app-bar\n        color=\"indigo\"\n        absolute\n        flat\n      >\n        <v-app-bar-nav-icon></v-app-bar-nav-icon>\n\n        <v-app-bar-title>Page title</v-app-bar-title>\n\n        <v-btn icon=\"mdi-magnify\"></v-btn>\n\n        <v-btn icon=\"mdi-dots-vertical\">\n          <v-icon></v-icon>\n        </v-btn>\n\n        <template v-slot:extension>\n          <v-tabs\n            v-model=\"tabs\"\n            align-tabs=\"title\"\n            slider-color=\"pink\"\n          >\n            <v-tab text=\"Item One\" value=\"one\"></v-tab>\n\n            <v-tab text=\"Item Two\" value=\"two\"></v-tab>\n\n            <v-tab text=\"Item Three\" value=\"three\"></v-tab>\n          </v-tabs>\n        </template>\n      </v-app-bar>\n\n      <v-main>\n        <v-sheet height=\"150\"></v-sheet>\n      </v-main>\n\n      <v-fab\n        :key=\"activeFab.icon\"\n        :color=\"activeFab.color\"\n        :icon=\"activeFab.icon\"\n        class=\"ms-4 mb-4\"\n        location=\"bottom start\"\n        size=\"64\"\n        absolute\n        app\n        appear\n      ></v-fab>\n    </v-layout>\n  </v-card>\n</template>\n\n<script setup>\n  import { computed, ref } from 'vue'\n\n  const tabs = ref(null)\n  const activeFab = computed(() => {\n    switch (tabs.value) {\n      case 'one': return { color: 'success', icon: 'mdi-share-variant' }\n      case 'two': return { color: 'red', icon: 'mdi-pencil' }\n      case 'three': return { color: 'green', icon: 'mdi-chevron-up' }\n      default: return {}\n    }\n  })\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      tabs: null,\n    }),\n\n    computed: {\n      activeFab () {\n        switch (this.tabs) {\n          case 'one': return { color: 'success', icon: 'mdi-share-variant' }\n          case 'two': return { color: 'red', icon: 'mdi-pencil' }\n          case 'three': return { color: 'green', icon: 'mdi-chevron-up' }\n          default: return {}\n        }\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-fab/misc-small.vue",
    "content": "<template>\n  <v-card class=\"mx-auto\" max-width=\"365\">\n    <v-toolbar\n      color=\"light-blue\"\n      extended\n      light\n    >\n      <v-app-bar-nav-icon color=\"grey-darken-4\"></v-app-bar-nav-icon>\n\n      <v-toolbar-title>My files</v-toolbar-title>\n\n      <v-btn color=\"grey-darken-4\" icon=\"mdi-magnify\"></v-btn>\n\n      <v-btn color=\"grey-darken-4\" icon=\"mdi-view-module\"></v-btn>\n\n      <template v-slot:extension>\n        <v-fab\n          class=\"ms-4\"\n          color=\"cyan-accent-2\"\n          icon=\"mdi-plus\"\n          location=\"bottom left\"\n          size=\"40\"\n          absolute\n          offset\n          @click=\"dialog = !dialog\"\n        ></v-fab>\n      </template>\n    </v-toolbar>\n\n    <v-list lines=\"two\">\n      <v-list-subheader title=\"Folders\" inset></v-list-subheader>\n\n      <v-list-item\n        v-for=\"item in items\"\n        :key=\"item.title\"\n        link\n      >\n        <template v-slot:prepend>\n          <v-avatar :class=\"[item.iconClass]\" :icon=\"item.icon\"></v-avatar>\n        </template>\n\n        <v-list-item-title>{{ item.title }}</v-list-item-title>\n\n        <v-list-item-subtitle>{{ item.subtitle }}</v-list-item-subtitle>\n\n        <template v-slot:append>\n          <v-list-item-action>\n            <v-btn color=\"grey-lighten-1\" icon=\"mdi-information\" variant=\"text\"></v-btn>\n          </v-list-item-action>\n        </template>\n      </v-list-item>\n\n      <v-divider inset></v-divider>\n\n      <v-list-subheader title=\"Files\" inset></v-list-subheader>\n\n      <v-list-item\n        v-for=\"item in items2\"\n        :key=\"item.title\"\n        link\n      >\n        <template v-slot:prepend>\n          <v-avatar :class=\"[item.iconClass]\" :icon=\"item.icon\"></v-avatar>\n        </template>\n\n        <v-list-item-title>{{ item.title }}</v-list-item-title>\n\n        <v-list-item-subtitle>{{ item.subtitle }}</v-list-item-subtitle>\n\n        <template v-slot:append>\n          <v-list-item-action>\n            <v-btn color=\"grey-lighten-1\" icon=\"mdi-information\" variant=\"text\"></v-btn>\n          </v-list-item-action>\n        </template>\n      </v-list-item>\n    </v-list>\n\n    <v-dialog\n      v-model=\"dialog\"\n      max-width=\"500\"\n    >\n      <v-card>\n        <v-card-text>\n          <v-text-field label=\"File name\"></v-text-field>\n\n          <small class=\"text-grey\">* This doesn't actually save.</small>\n        </v-card-text>\n\n        <v-card-actions>\n          <v-spacer></v-spacer>\n\n          <v-btn\n            color=\"primary\"\n            variant=\"text\"\n            @click=\"dialog = false\"\n          >\n            Submit\n          </v-btn>\n        </v-card-actions>\n      </v-card>\n    </v-dialog>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const dialog = ref(false)\n  const items = ref([\n    { icon: 'mdi-folder', iconClass: 'bg-grey text-white', title: 'Photos', subtitle: 'Jan 9, 2014' },\n    { icon: 'mdi-folder', iconClass: 'bg-grey text-white', title: 'Recipes', subtitle: 'Jan 17, 2014' },\n    { icon: 'mdi-folder', iconClass: 'bg-grey text-white', title: 'Work', subtitle: 'Jan 28, 2014' },\n  ])\n  const items2 = ref([\n    { icon: 'mdi-clipboard-text', iconClass: 'bg-blue text-white', title: 'Vacation itinerary', subtitle: 'Jan 20, 2014' },\n    { icon: 'mdi-gesture-tap-button', iconClass: 'bg-amber text-white', title: 'Kitchen remodel', subtitle: 'Jan 10, 2014' },\n  ])\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-fab/misc-speed-dial.vue",
    "content": "<template>\n  <v-app>\n    <v-card class=\"pa-6 mb-6\" variant=\"flat\">\n      <v-row density=\"comfortable\">\n        <v-col cols=\"12\" sm=\"3\">\n          <h5 class=\"my-0\">FAB position</h5>\n\n          <v-radio-group v-model=\"fabPosition\" density=\"compact\" hide-details>\n            <v-radio label=\"App (fixed)\" value=\"fixed\"></v-radio>\n            <v-radio label=\"Absolute\" value=\"absolute\"></v-radio>\n            <v-radio label=\"None\" value=\"\"></v-radio>\n          </v-radio-group>\n        </v-col>\n\n        <v-col cols=\"12\" sm=\"3\">\n          <h5 class=\"my-0\">FAB location</h5>\n\n          <v-radio-group v-model=\"fabLocation\" :disabled=\"!fabPosition\" density=\"compact\" hide-details>\n            <div class=\"d-flex\">\n              <v-radio value=\"top left\"></v-radio>\n              <v-radio value=\"top center\"></v-radio>\n              <v-radio value=\"top right\"></v-radio>\n            </div>\n\n            <div class=\"d-flex\">\n              <v-radio value=\"left center\"></v-radio>\n              <v-radio :disabled=\"fabPosition !== 'absolute'\" value=\"center center\"></v-radio>\n              <v-radio value=\"right center\"></v-radio>\n            </div>\n\n            <div class=\"d-flex\">\n              <v-radio value=\"left bottom\"></v-radio>\n              <v-radio value=\"bottom center\"></v-radio>\n              <v-radio value=\"right bottom\"></v-radio>\n            </div>\n          </v-radio-group>\n\n          <code>({{ fabLocation }})</code>\n        </v-col>\n\n        <v-col cols=\"12\" sm=\"3\">\n          <h5 class=\"my-0\">Menu location</h5>\n\n          <v-radio-group v-model=\"menuLocation\" density=\"compact\" hide-details>\n            <div class=\"d-flex\">\n              <v-radio disabled></v-radio>\n              <v-radio value=\"top left\"></v-radio>\n              <v-radio value=\"top center\"></v-radio>\n              <v-radio value=\"top right\"></v-radio>\n              <v-radio disabled></v-radio>\n            </div>\n\n            <div class=\"d-flex\">\n              <v-radio value=\"left top\"></v-radio>\n              <v-radio disabled></v-radio>\n              <v-radio disabled></v-radio>\n              <v-radio disabled></v-radio>\n              <v-radio value=\"right top\"></v-radio>\n            </div>\n\n            <div class=\"d-flex\">\n              <v-radio value=\"left center\"></v-radio>\n              <v-radio disabled></v-radio>\n              <v-radio value=\"center\"></v-radio>\n              <v-radio disabled></v-radio>\n              <v-radio value=\"right center\"></v-radio>\n            </div>\n\n            <div class=\"d-flex\">\n              <v-radio value=\"left bottom\"></v-radio>\n              <v-radio disabled></v-radio>\n              <v-radio disabled></v-radio>\n              <v-radio disabled></v-radio>\n              <v-radio value=\"right bottom\"></v-radio>\n            </div>\n\n            <div class=\"d-flex\">\n              <v-radio disabled></v-radio>\n              <v-radio value=\"bottom left\"></v-radio>\n              <v-radio value=\"bottom center\"></v-radio>\n              <v-radio value=\"bottom right\"></v-radio>\n              <v-radio disabled></v-radio>\n            </div>\n          </v-radio-group>\n\n          <code>({{ menuLocation }})</code>\n        </v-col>\n\n        <v-col cols=\"12\" sm=\"3\">\n          <h5 class=\"my-0\">Transition</h5>\n\n          <v-radio-group v-model=\"transition\" density=\"compact\" hide-details>\n            <v-radio label=\"Fade\" value=\"fade-transition\"></v-radio>\n            <v-radio label=\"Slide y\" value=\"slide-y-transition\"></v-radio>\n            <v-radio label=\"Slide y reverse\" value=\"slide-y-reverse-transition\"></v-radio>\n            <v-radio label=\"Slide x\" value=\"slide-x-transition\"></v-radio>\n            <v-radio label=\"Slide x reverse\" value=\"slide-x-reverse-transition\"></v-radio>\n            <v-radio label=\"Scale\" value=\"scale-transition\"></v-radio>\n          </v-radio-group>\n        </v-col>\n      </v-row>\n    </v-card>\n\n    <v-card :class=\"fabPosition === 'absolute' ? 'demo-panel-relative' : 'demo-panel-static'\" border flat>\n      <v-fab\n        :key=\"fabPosition\"\n        :absolute=\"fabPosition === 'absolute'\"\n        :app=\"fabPosition === 'fixed'\"\n        :color=\"open ? '' : 'primary'\"\n        :location=\"fabLocation\"\n        size=\"large\"\n        icon\n      >\n        <v-icon>{{ open ? 'mdi-close' : 'mdi-crown' }}</v-icon>\n        <v-speed-dial v-model=\"open\" :location=\"menuLocation\" :transition=\"transition\" activator=\"parent\">\n          <v-btn key=\"1\" color=\"success\" icon>\n            <v-icon size=\"24\">$success</v-icon>\n          </v-btn>\n\n          <v-btn key=\"2\" color=\"info\" icon>\n            <v-icon size=\"24\">$info</v-icon>\n          </v-btn>\n\n          <v-btn key=\"3\" color=\"warning\" icon>\n            <v-icon size=\"24\">$warning</v-icon>\n          </v-btn>\n\n          <v-btn key=\"4\" color=\"error\" icon>\n            <v-icon size=\"24\">$error</v-icon>\n          </v-btn>\n        </v-speed-dial>\n      </v-fab>\n    </v-card>\n  </v-app>\n</template>\n\n<script setup>\n  import { shallowRef, watch } from 'vue'\n\n  const open = shallowRef(false)\n  const fabPosition = shallowRef('absolute')\n  const menuLocation = shallowRef('left center')\n  const fabLocation = shallowRef('right bottom')\n  const transition = shallowRef('slide-y-reverse-transition')\n\n  watch(menuLocation, reopen)\n  watch(transition, reopen)\n  watch(fabLocation, () => open.value = false)\n  watch(fabPosition, () => open.value = false)\n\n  function reopen () {\n    open.value = false\n    setTimeout(() => open.value = true, 400)\n  }\n</script>\n\n<style scoped>\n/* This is for documentation purposes and will not be needed in your application */\n::v-deep(.v-application__wrap) {\n  min-height: 0 !important;\n}\n\n.demo-panel-static,\n.demo-panel-relative {\n  margin: 0 80px 50px;\n  padding: 24px;\n  min-height: 300px;\n}\n.demo-panel-static {\n  position: static;\n}\n.demo-panel-relative {\n  position: relative;\n}\n\n.v-selection-control--disabled,\n.v-input--disabled .v-selection-control {\n  opacity: .1;\n}\n\n.v-radio {\n  flex-grow: 0 !important;\n}\n\nh5 {\n  margin-bottom: 12px;\n}\n\ncode {\n  display: block;\n  font-size: .8rem;\n  margin-top: 12px;\n}\n\n::v-deep(.v-label) {\n  margin-left: 8px;\n}\n</style>\n"
  },
  {
    "path": "packages/docs/src/examples/v-fab/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div class=\"text-center\">\n      <v-fab v-bind=\"props\"></v-fab>\n    </div>\n\n    <template v-slot:configuration>\n      <v-select\n        v-model=\"color\"\n        :items=\"items\"\n        label=\"Color\"\n        clearable\n      ></v-select>\n      <v-checkbox v-model=\"extended\" label=\"Extended\"></v-checkbox>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const variants = ['outlined', 'tonal', 'flat', 'text', 'plain']\n  const name = 'v-fab'\n  const model = shallowRef('default')\n  const options = [...variants]\n  const extended = shallowRef(false)\n  const color = shallowRef()\n  const items = ['primary', 'success', 'surface-variant']\n\n  const props = computed(() => {\n    return {\n      color: color.value || undefined,\n      extended: extended.value || undefined,\n      icon: !extended.value ? '$vuetify' : undefined,\n      'prepend-icon': extended.value ? '$vuetify' : undefined,\n      text: extended.value ? 'Extended' : undefined,\n      variant: variants.includes(model.value) ? model.value : undefined,\n    }\n  })\n\n  const slots = computed(() => {\n    return ''\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-file-input/misc-complex-selection.vue",
    "content": "<template>\n  <div class=\"py-3\">\n    <v-file-input\n      v-model=\"files\"\n      :show-size=\"1000\"\n      color=\"deep-purple-accent-4\"\n      label=\"File input\"\n      placeholder=\"Select your files\"\n      prepend-icon=\"mdi-paperclip\"\n      variant=\"outlined\"\n      counter\n      multiple\n    >\n      <template v-slot:selection=\"{ fileNames }\">\n        <template v-for=\"(fileName, index) in fileNames\" :key=\"fileName\">\n          <v-chip\n            v-if=\"index < 2\"\n            class=\"me-2\"\n            color=\"primary\"\n            size=\"small\"\n            label\n          >\n            {{ fileName }}\n          </v-chip>\n\n          <span\n            v-else-if=\"index === 2\"\n            class=\"text-label-medium text-medium-emphasis mx-2\"\n          >\n            +{{ files.length - 2 }} File(s)\n          </span>\n        </template>\n      </template>\n    </v-file-input>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const files = ref([])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      files: [],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-file-input/prop-accept.vue",
    "content": "<template>\n  <v-file-input\n    accept=\"image/*\"\n    label=\"File input\"\n  ></v-file-input>\n</template>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2796-135158&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-file-input/prop-chips.vue",
    "content": "<template>\n  <div>\n    <v-file-input\n      label=\"File input w/ chips\"\n      chips\n      multiple\n    ></v-file-input>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-file-input/prop-counter.vue",
    "content": "<template>\n  <v-file-input\n    label=\"File input\"\n    counter\n    multiple\n    show-size\n  ></v-file-input>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-file-input/prop-dense.vue",
    "content": "<template>\n  <v-file-input\n    density=\"compact\"\n    label=\"File input\"\n  ></v-file-input>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-file-input/prop-multiple.vue",
    "content": "<template>\n  <v-file-input\n    label=\"File input\"\n    multiple\n  ></v-file-input>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-file-input/prop-prepend-icon.vue",
    "content": "<template>\n  <v-file-input\n    label=\"File input\"\n    prepend-icon=\"mdi-camera\"\n    variant=\"filled\"\n  ></v-file-input>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-file-input/prop-show-size.vue",
    "content": "<template>\n  <v-file-input\n    label=\"File input\"\n    show-size\n  ></v-file-input>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-file-input/prop-validation.vue",
    "content": "<template>\n  <v-file-input\n    :rules=\"rules\"\n    accept=\"image/png, image/jpeg, image/bmp\"\n    label=\"Photos\"\n    placeholder=\"Upload your photos\"\n    prepend-icon=\"mdi-camera\"\n    multiple\n  ></v-file-input>\n</template>\n\n<script setup>\n  const maxSize = 5000000 // 5 MB\n  const errorMessage = 'Total image size should be less than 5 MB!'\n\n  const rules = [\n    value => {\n      // Multiple files\n      if (value && Array.isArray(value)) {\n        const totalSize = value.reduce((acc, current) => acc + current.size, 0)\n        return totalSize < maxSize || errorMessage\n      }\n\n      // Single file (if multiple is undefined or set to false)\n      return !value || value.size < maxSize || errorMessage\n    },\n  ]\n</script>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2796-135813&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-file-input/slot-selection.vue",
    "content": "<template>\n  <v-file-input\n    v-model=\"files\"\n    label=\"File input\"\n    placeholder=\"Upload your documents\"\n    prepend-icon=\"mdi-paperclip\"\n    multiple\n  >\n    <template v-slot:selection=\"{ fileNames }\">\n      <template v-for=\"fileName in fileNames\" :key=\"fileName\">\n        <v-chip\n          class=\"me-2\"\n          color=\"primary\"\n          size=\"small\"\n          label\n        >\n          {{ fileName }}\n        </v-chip>\n      </template>\n    </template>\n  </v-file-input>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const files = ref([])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      files: [],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-file-input/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div>\n      <v-file-input v-bind=\"props\"></v-file-input>\n    </div>\n\n    <template v-slot:configuration>\n      <v-checkbox v-model=\"clear\" label=\"Clearable\"></v-checkbox>\n\n      <v-checkbox v-model=\"disabled\" label=\"Disabled\"></v-checkbox>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-file-input'\n  const model = ref('default')\n  const options = ['outlined', 'underlined', 'solo', 'solo-filled', 'solo-inverted']\n  const clear = ref(false)\n  const counter = ref(false)\n  const disabled = ref(false)\n  const props = computed(() => {\n    return {\n      clearable: clear.value || undefined,\n      counter: counter.value || undefined,\n      disabled: disabled.value || undefined,\n      label: 'File input',\n      variant: model.value === 'default' ? undefined : model.value,\n    }\n  })\n\n  const slots = computed(() => {\n    return ``\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-file-upload/misc-list.vue",
    "content": "<template>\n  <v-file-upload v-model=\"model\" clearable multiple show-size>\n    <template v-slot:default>\n      <v-file-upload-dropzone density=\"comfortable\"></v-file-upload-dropzone>\n\n      <v-file-upload-list class=\"upload-list\">\n        <template v-slot:default=\"{ files, onClickRemove }\">\n          <v-file-upload-item\n            v-for=\"(file, index) in files\"\n            :key=\"file\"\n            :file=\"file\"\n            clearable\n            show-size\n            @click:remove=\"onClickRemove(index)\"\n          >\n            <template v-slot:prepend>\n              <VAvatar rounded=\"circle\"></VAvatar>\n              <v-progress-linear\n                v-if=\"uploads.has(file)\"\n                :buffer-value=\"uploads.get(file).buffer\"\n                :color=\"uploads.get(file).progress >= 100 ? 'success' : 'primary'\"\n                :model-value=\"uploads.get(file).progress\"\n                location=\"bottom\"\n                absolute\n              ></v-progress-linear>\n            </template>\n          </v-file-upload-item>\n        </template>\n      </v-file-upload-list>\n    </template>\n  </v-file-upload>\n</template>\n\n<script setup>\n  import { onMounted, ref, shallowReactive, watch } from 'vue'\n\n  function createImageFile (name, colors) {\n    const canvas = document.createElement('canvas')\n    canvas.width = 64\n    canvas.height = 64\n    const ctx = canvas.getContext('2d')\n    const gradient = ctx.createLinearGradient(0, 0, 64, 64)\n    gradient.addColorStop(0, colors[0])\n    gradient.addColorStop(1, colors[1])\n    ctx.fillStyle = gradient\n    ctx.fillRect(0, 0, 64, 64)\n    return new Promise(resolve => {\n      canvas.toBlob(blob => {\n        resolve(new File([blob], name, { type: 'image/png' }))\n      })\n    })\n  }\n\n  const model = ref([])\n  const uploads = shallowReactive(new Map())\n  const queue = []\n  let activeCount = 0\n  const maxConcurrent = 2\n\n  function enqueueFiles (files) {\n    for (const file of files) {\n      if (uploads.has(file)) continue\n      uploads.set(file, { progress: 0, buffer: 0 })\n      queue.push(file)\n    }\n    drainQueue()\n  }\n\n  function drainQueue () {\n    while (activeCount < maxConcurrent && queue.length) {\n      const file = queue.shift()\n      if (!uploads.has(file)) continue\n      activeCount++\n      simulateOne(file, () => {\n        activeCount--\n        drainQueue()\n      })\n    }\n  }\n\n  function simulateOne (file, onComplete) {\n    const speed = 200 + Math.random() * 300\n    let progress = 0\n\n    const interval = setInterval(() => {\n      if (!uploads.has(file)) {\n        clearInterval(interval)\n        onComplete()\n        return\n      }\n      const increment = 2 + Math.random() * 5\n      progress = Math.min(progress + increment, 100)\n      const buffer = Math.min(progress + 10 + Math.random() * 15, 100)\n      uploads.set(file, { progress, buffer })\n\n      if (progress >= 100) {\n        clearInterval(interval)\n        onComplete()\n      }\n    }, speed)\n  }\n\n  watch(model, (val, oldVal) => {\n    const oldSet = new Set(oldVal)\n    const newFiles = val.filter(f => !oldSet.has(f))\n\n    // clean up removed files\n    for (const file of oldSet) {\n      if (!val.includes(file)) {\n        uploads.delete(file)\n      }\n    }\n\n    if (newFiles.length) {\n      enqueueFiles(newFiles)\n    }\n  })\n\n  onMounted(async () => {\n    model.value = await Promise.all([\n      createImageFile('sunset.png', ['#e91e63', '#4caf50']),\n      createImageFile('aurora.png', ['#ff9800', '#9c27b0']),\n      createImageFile('horizon.png', ['#2196f3', '#ff5722']),\n      createImageFile('tropical.png', ['#00bcd4', '#ffc107']),\n      createImageFile('neon.png', ['#673ab7', '#00e676']),\n      createImageFile('twilight.png', ['#f44336', '#3f51b5']),\n    ])\n  })\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      model: [],\n      uploads: new Map(),\n      queue: [],\n      activeCount: 0,\n      maxConcurrent: 2,\n    }),\n    watch: {\n      model (val, oldVal) {\n        const oldSet = new Set(oldVal)\n        const newFiles = val.filter(f => !oldSet.has(f))\n\n        for (const file of oldSet) {\n          if (!val.includes(file)) {\n            this.uploads.delete(file)\n          }\n        }\n\n        if (newFiles.length) {\n          this.enqueueFiles(newFiles)\n        }\n      },\n    },\n    async mounted () {\n      this.model = await Promise.all([\n        this.createImageFile('sunset.png', ['#e91e63', '#4caf50']),\n        this.createImageFile('aurora.png', ['#ff9800', '#9c27b0']),\n        this.createImageFile('horizon.png', ['#2196f3', '#ff5722']),\n        this.createImageFile('tropical.png', ['#00bcd4', '#ffc107']),\n        this.createImageFile('neon.png', ['#673ab7', '#00e676']),\n        this.createImageFile('twilight.png', ['#f44336', '#3f51b5']),\n      ])\n    },\n    methods: {\n      createImageFile (name, colors) {\n        const canvas = document.createElement('canvas')\n        canvas.width = 64\n        canvas.height = 64\n        const ctx = canvas.getContext('2d')\n        const gradient = ctx.createLinearGradient(0, 0, 64, 64)\n        gradient.addColorStop(0, colors[0])\n        gradient.addColorStop(1, colors[1])\n        ctx.fillStyle = gradient\n        ctx.fillRect(0, 0, 64, 64)\n        return new Promise(resolve => {\n          canvas.toBlob(blob => {\n            resolve(new File([blob], name, { type: 'image/png' }))\n          })\n        })\n      },\n      enqueueFiles (files) {\n        for (const file of files) {\n          if (this.uploads.has(file)) continue\n          this.uploads.set(file, { progress: 0, buffer: 0 })\n          this.queue.push(file)\n        }\n        this.drainQueue()\n      },\n      drainQueue () {\n        while (this.activeCount < this.maxConcurrent && this.queue.length) {\n          const file = this.queue.shift()\n          if (!this.uploads.has(file)) continue\n          this.activeCount++\n          this.simulateOne(file, () => {\n            this.activeCount--\n            this.drainQueue()\n          })\n        }\n      },\n      simulateOne (file, onComplete) {\n        const speed = 200 + Math.random() * 300\n        let progress = 0\n\n        const interval = setInterval(() => {\n          if (!this.uploads.has(file)) {\n            clearInterval(interval)\n            onComplete()\n            return\n          }\n          const increment = 2 + Math.random() * 5\n          progress = Math.min(progress + increment, 100)\n          const buffer = Math.min(progress + 10 + Math.random() * 15, 100)\n          this.uploads.set(file, { progress, buffer })\n\n          if (progress >= 100) {\n            clearInterval(interval)\n            onComplete()\n          }\n        }, speed)\n      },\n    },\n  }\n</script>\n\n<style scoped>\n.upload-list {\n  display: grid;\n  grid-template-columns: 1fr 1fr;\n  gap: 1rem;\n  margin-bottom: 0;\n\n  > * {\n    margin: 0;\n  }\n}\n</style>\n"
  },
  {
    "path": "packages/docs/src/examples/v-file-upload/prop-content.vue",
    "content": "<template>\n  <v-file-upload\n    browse-text=\"Local Filesystem\"\n    divider-text=\"or choose locally\"\n    icon=\"mdi-upload\"\n    title=\"Drag and Drop Here\"\n  ></v-file-upload>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-file-upload/prop-inset-file-list.vue",
    "content": "<template>\n  <v-file-upload\n    v-model=\"model\"\n    clearable\n    inset-file-list\n    multiple\n    show-size\n  ></v-file-upload>\n</template>\n\n<script setup>\n  import { onMounted, ref } from 'vue'\n\n  function createImageFile (name, colors) {\n    const canvas = document.createElement('canvas')\n    canvas.width = 64\n    canvas.height = 64\n    const ctx = canvas.getContext('2d')\n    const gradient = ctx.createLinearGradient(0, 0, 64, 64)\n    gradient.addColorStop(0, colors[0])\n    gradient.addColorStop(1, colors[1])\n    ctx.fillStyle = gradient\n    ctx.fillRect(0, 0, 64, 64)\n    return new Promise(resolve => {\n      canvas.toBlob(blob => {\n        resolve(new File([blob], name, { type: 'image/png' }))\n      })\n    })\n  }\n\n  const model = ref([])\n\n  onMounted(async () => {\n    model.value = await Promise.all([\n      createImageFile('sunset.png', ['#e91e63', '#4caf50']),\n      createImageFile('aurora.png', ['#ff9800', '#9c27b0']),\n      createImageFile('horizon.png', ['#2196f3', '#ff5722']),\n    ])\n  })\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      model: [],\n    }),\n    async mounted () {\n      this.model = await Promise.all([\n        this.createImageFile('sunset.png', ['#e91e63', '#4caf50']),\n        this.createImageFile('aurora.png', ['#ff9800', '#9c27b0']),\n        this.createImageFile('horizon.png', ['#2196f3', '#ff5722']),\n      ])\n    },\n    methods: {\n      createImageFile (name, colors) {\n        const canvas = document.createElement('canvas')\n        canvas.width = 64\n        canvas.height = 64\n        const ctx = canvas.getContext('2d')\n        const gradient = ctx.createLinearGradient(0, 0, 64, 64)\n        gradient.addColorStop(0, colors[0])\n        gradient.addColorStop(1, colors[1])\n        ctx.fillStyle = gradient\n        ctx.fillRect(0, 0, 64, 64)\n        return new Promise(resolve => {\n          canvas.toBlob(blob => {\n            resolve(new File([blob], name, { type: 'image/png' }))\n          })\n        })\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-file-upload/prop-scrim.vue",
    "content": "<template>\n  <v-file-upload\n    density=\"comfortable\"\n    scrim=\"primary\"\n  ></v-file-upload>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-file-upload/slot-item.vue",
    "content": "<template>\n  <v-file-upload\n    v-model=\"model\"\n    density=\"comfortable\"\n    clearable\n    multiple\n    show-size\n  >\n    <template v-slot:item=\"{ props: itemProps }\">\n      <v-file-upload-item v-bind=\"itemProps\" lines=\"two\">\n        <template v-slot:prepend>\n          <v-avatar\n            rounded=\"lg\"\n            size=\"32\"\n            style=\"transform: rotate(45deg)\"\n          ></v-avatar>\n        </template>\n\n        <template v-slot:clear=\"{ props: clearProps }\">\n          <v-btn color=\"error\" icon=\"mdi-trash-can\" v-bind=\"clearProps\"></v-btn>\n        </template>\n      </v-file-upload-item>\n    </template>\n  </v-file-upload>\n</template>\n\n<script setup>\n  import { onMounted, ref } from 'vue'\n\n  function createImageFile (name, colors) {\n    const canvas = document.createElement('canvas')\n    canvas.width = 64\n    canvas.height = 64\n    const ctx = canvas.getContext('2d')\n    const gradient = ctx.createLinearGradient(0, 0, 64, 64)\n    gradient.addColorStop(0, colors[0])\n    gradient.addColorStop(1, colors[1])\n    ctx.fillStyle = gradient\n    ctx.fillRect(0, 0, 64, 64)\n    return new Promise(resolve => {\n      canvas.toBlob(blob => {\n        resolve(new File([blob], name, { type: 'image/png' }))\n      })\n    })\n  }\n\n  const model = ref([])\n\n  onMounted(async () => {\n    model.value = await Promise.all([\n      createImageFile('sunset.png', ['#ff9800', '#9c27b0']),\n      createImageFile('aurora.png', ['#4caf50', '#e91e63']),\n      createImageFile('horizon.png', ['#2196f3', '#ff5722']),\n    ])\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-file-upload/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div>\n      <v-file-upload v-bind=\"props\"></v-file-upload>\n    </div>\n\n    <template v-slot:configuration>\n      <v-text-field v-model=\"title\" label=\"Title\"></v-text-field>\n\n      <v-checkbox v-model=\"disabled\" label=\"Disabled\"></v-checkbox>\n\n      <v-checkbox v-model=\"clear\" label=\"Clearable\"></v-checkbox>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-file-upload'\n  const model = ref('default')\n  const options = ['comfortable', 'compact']\n  const clear = ref(false)\n  const counter = ref(false)\n  const disabled = ref(false)\n  const title = ref()\n  const props = computed(() => {\n    return {\n      clearable: clear.value || undefined,\n      counter: counter.value || undefined,\n      disabled: disabled.value || undefined,\n      density: model.value,\n      title: title.value || undefined,\n      variant: model.value === 'default' ? undefined : model.value,\n    }\n  })\n\n  const slots = computed(() => {\n    return ``\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-footer/misc-company-footer.vue",
    "content": "<template>\n  <v-footer class=\"d-flex align-center justify-center ga-2 flex-wrap flex-grow-1 py-3\" color=\"surface-light\">\n    <v-btn\n      v-for=\"link in links\"\n      :key=\"link\"\n      :text=\"link\"\n      variant=\"text\"\n      rounded\n    ></v-btn>\n\n    <div class=\"flex-1-0-100 text-center mt-2\">\n      {{ new Date().getFullYear() }} — <strong>Vuetify</strong>\n    </div>\n  </v-footer>\n</template>\n\n<script setup>\n  const links = [\n    'Home',\n    'About Us',\n    'Team',\n    'Services',\n    'Blog',\n    'Contact Us',\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      links: [\n        'Home',\n        'About Us',\n        'Team',\n        'Services',\n        'Blog',\n        'Contact Us',\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-footer/misc-indigo-footer.vue",
    "content": "<template>\n  <v-footer class=\"text-center d-flex flex-column ga-2 py-4\" color=\"indigo-lighten-1\">\n    <div class=\"d-flex ga-3\">\n      <v-btn\n        v-for=\"icon in icons\"\n        :key=\"icon\"\n        :icon=\"icon\"\n        density=\"comfortable\"\n        variant=\"text\"\n      ></v-btn>\n    </div>\n\n    <v-divider class=\"my-2\" thickness=\"2\" width=\"50\"></v-divider>\n\n    <div class=\"text-body-small font-weight-regular opacity-60\">\n      Phasellus feugiat arcu sapien, et iaculis ipsum elementum sit amet. Mauris cursus commodo interdum. Praesent ut risus eget metus luctus accumsan id ultrices nunc. Sed at orci sed massa consectetur dignissim a sit amet dui. Duis commodo vitae velit et faucibus. Morbi vehicula lacinia malesuada. Nulla placerat augue vel ipsum ultrices, cursus iaculis dui sollicitudin. Vestibulum eu ipsum vel diam elementum tempor vel ut orci. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.\n    </div>\n\n    <v-divider></v-divider>\n\n    <div>\n      {{ new Date().getFullYear() }} — <strong>Vuetify</strong>\n    </div>\n  </v-footer>\n</template>\n\n<script setup>\n  const icons = [\n    'mdi-facebook',\n    'mdi-twitter',\n    'mdi-linkedin',\n    'mdi-instagram',\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      icons: [\n        'mdi-facebook',\n        'mdi-twitter',\n        'mdi-linkedin',\n        'mdi-instagram',\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-footer/misc-teal-footer.vue",
    "content": "<template>\n  <v-footer class=\"d-flex flex-column\" color=\"teal\" rounded=\"lg\">\n    <div class=\"d-flex w-100 align-center px-4 py-2\">\n      <strong>Get connected with us on social networks!</strong>\n\n      <div class=\"d-flex ga-2 ms-auto\">\n        <v-btn\n          v-for=\"icon in icons\"\n          :key=\"icon\"\n          :icon=\"icon\"\n          size=\"small\"\n          variant=\"plain\"\n        ></v-btn>\n      </div>\n    </div>\n\n    <div class=\"px-4 py-2 bg-surface-variant text-center w-100 rounded-lg\">\n      {{ new Date().getFullYear() }} — <strong>Vuetify</strong>\n    </div>\n  </v-footer>\n</template>\n\n<script setup>\n  const icons = [\n    'mdi-facebook',\n    'mdi-twitter',\n    'mdi-linkedin',\n    'mdi-instagram',\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      icons: [\n        'mdi-facebook',\n        'mdi-twitter',\n        'mdi-linkedin',\n        'mdi-instagram',\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-footer/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div>\n      <v-footer v-bind=\"props\">\n        {{ new Date().getFullYear() }} — <strong>Vuetify, LLC</strong>\n      </v-footer>\n    </div>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-footer'\n  const model = ref('default')\n  const options = ['bordered']\n  const props = computed(() => {\n    return {\n      border: model.value === 'bordered' || undefined,\n    }\n  })\n\n  const slots = computed(() => {\n    return ``\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-form/misc-exposed.vue",
    "content": "<template>\n  <v-sheet class=\"mx-auto\" width=\"300\">\n\n    <v-form ref=\"form\">\n      <v-text-field\n        v-model=\"name\"\n        :counter=\"10\"\n        :rules=\"nameRules\"\n        label=\"Name\"\n        required\n      ></v-text-field>\n\n      <v-select\n        v-model=\"select\"\n        :items=\"items\"\n        :rules=\"[v => !!v || 'Item is required']\"\n        label=\"Item\"\n        required\n      ></v-select>\n\n      <v-checkbox\n        v-model=\"checkbox\"\n        :rules=\"[v => !!v || 'You must agree to continue!']\"\n        label=\"Do you agree?\"\n        indent-details\n        required\n      ></v-checkbox>\n\n      <div class=\"d-flex flex-column\">\n        <v-btn\n          class=\"mt-4\"\n          color=\"success\"\n          block\n          @click=\"validate\"\n        >\n          Validate\n        </v-btn>\n\n        <v-btn\n          class=\"mt-4\"\n          color=\"error\"\n          block\n          @click=\"reset\"\n        >\n          Reset Form\n        </v-btn>\n\n        <v-btn\n          class=\"mt-4\"\n          color=\"warning\"\n          block\n          @click=\"resetValidation\"\n        >\n          Reset Validation\n        </v-btn>\n      </div>\n    </v-form>\n  </v-sheet>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const form = ref()\n\n  const items = [\n    'Item 1',\n    'Item 2',\n    'Item 3',\n    'Item 4',\n  ]\n\n  const name = ref('')\n  const nameRules = ref([\n    v => !!v || 'Name is required',\n    v => (v && v.length <= 10) || 'Name must be 10 characters or less',\n  ])\n  const select = ref(null)\n  const checkbox = ref(false)\n\n  async function validate () {\n    const { valid } = await form.value.validate()\n\n    if (valid) alert('Form is valid')\n  }\n  function reset () {\n    form.value.reset()\n  }\n  function resetValidation () {\n    form.value.resetValidation()\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      name: '',\n      nameRules: [\n        v => !!v || 'Name is required',\n        v => (v && v.length <= 10) || 'Name must be 10 characters or less',\n      ],\n      select: null,\n      items: [\n        'Item 1',\n        'Item 2',\n        'Item 3',\n        'Item 4',\n      ],\n      checkbox: false,\n    }),\n\n    methods: {\n      async validate () {\n        const { valid } = await this.$refs.form.validate()\n\n        if (valid) alert('Form is valid')\n      },\n      reset () {\n        this.$refs.form.reset()\n      },\n      resetValidation () {\n        this.$refs.form.resetValidation()\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-form/misc-vee-validate.vue",
    "content": "<template>\n  <form @submit.prevent=\"submit\">\n    <v-text-field\n      v-model=\"name.value.value\"\n      :counter=\"10\"\n      :error-messages=\"name.errorMessage.value\"\n      label=\"Name\"\n    ></v-text-field>\n\n    <v-text-field\n      v-model=\"phone.value.value\"\n      :counter=\"7\"\n      :error-messages=\"phone.errorMessage.value\"\n      label=\"Phone Number\"\n    ></v-text-field>\n\n    <v-text-field\n      v-model=\"email.value.value\"\n      :error-messages=\"email.errorMessage.value\"\n      label=\"E-mail\"\n    ></v-text-field>\n\n    <v-select\n      v-model=\"select.value.value\"\n      :error-messages=\"select.errorMessage.value\"\n      :items=\"items\"\n      label=\"Select\"\n    ></v-select>\n\n    <v-checkbox\n      v-model=\"checkbox.value.value\"\n      :error-messages=\"checkbox.errorMessage.value\"\n      label=\"Option\"\n      type=\"checkbox\"\n      value=\"1\"\n      indent-details\n    ></v-checkbox>\n\n    <v-btn\n      class=\"me-4\"\n      type=\"submit\"\n    >\n      submit\n    </v-btn>\n\n    <v-btn @click=\"handleReset\">\n      clear\n    </v-btn>\n  </form>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n  import { useField, useForm } from 'vee-validate'\n\n  const { handleSubmit, handleReset } = useForm({\n    validationSchema: {\n      name (value) {\n        if (value?.length >= 2) return true\n\n        return 'Name needs to be at least 2 characters.'\n      },\n      phone (value) {\n        if (/^[0-9-]{7,}$/.test(value)) return true\n\n        return 'Phone number needs to be at least 7 digits.'\n      },\n      email (value) {\n        if (/^[a-z.-]+@[a-z.-]+\\.[a-z]+$/i.test(value)) return true\n\n        return 'Must be a valid e-mail.'\n      },\n      select (value) {\n        if (value) return true\n\n        return 'Select an item.'\n      },\n      checkbox (value) {\n        if (value === '1') return true\n\n        return 'Must be checked.'\n      },\n    },\n  })\n  const name = useField('name')\n  const phone = useField('phone')\n  const email = useField('email')\n  const select = useField('select')\n  const checkbox = useField('checkbox')\n\n  const items = ref([\n    'Item 1',\n    'Item 2',\n    'Item 3',\n    'Item 4',\n  ])\n\n  const submit = handleSubmit(values => {\n    alert(JSON.stringify(values, null, 2))\n  })\n</script>\n\n<playground-resources lang=\"json\">\n  {\n    \"imports\": {\n      \"vee-validate\": \"https://cdn.jsdelivr.net/npm/vee-validate@4.8.4/dist/vee-validate.esm.js\",\n      \"@vue/devtools-api\": \"https://cdn.jsdelivr.net/npm/@vue/devtools-api@6.5.0/lib/esm/index.js\"\n    }\n  }\n</playground-resources>\n"
  },
  {
    "path": "packages/docs/src/examples/v-form/misc-vuelidate.vue",
    "content": "<template>\n  <form>\n    <v-text-field\n      v-model=\"state.name\"\n      :counter=\"10\"\n      :error-messages=\"v$.name.$errors.map(e => e.$message)\"\n      label=\"Name\"\n      required\n      @blur=\"v$.name.$touch\"\n      @input=\"v$.name.$touch\"\n    ></v-text-field>\n\n    <v-text-field\n      v-model=\"state.email\"\n      :error-messages=\"v$.email.$errors.map(e => e.$message)\"\n      label=\"E-mail\"\n      required\n      @blur=\"v$.email.$touch\"\n      @input=\"v$.email.$touch\"\n    ></v-text-field>\n\n    <v-select\n      v-model=\"state.select\"\n      :error-messages=\"v$.select.$errors.map(e => e.$message)\"\n      :items=\"items\"\n      label=\"Item\"\n      required\n      @blur=\"v$.select.$touch\"\n      @change=\"v$.select.$touch\"\n    ></v-select>\n\n    <v-checkbox\n      v-model=\"state.checkbox\"\n      :error-messages=\"v$.checkbox.$errors.map(e => e.$message)\"\n      label=\"Do you agree?\"\n      indent-details\n      required\n      @blur=\"v$.checkbox.$touch\"\n      @change=\"v$.checkbox.$touch\"\n    ></v-checkbox>\n\n    <v-btn\n      class=\"me-4\"\n      @click=\"v$.$validate\"\n    >\n      submit\n    </v-btn>\n    <v-btn @click=\"clear\">\n      clear\n    </v-btn>\n  </form>\n</template>\n\n<script setup>\n  import { reactive } from 'vue'\n  import { useVuelidate } from '@vuelidate/core'\n  import { email, required } from '@vuelidate/validators'\n\n  const initialState = {\n    name: '',\n    email: '',\n    select: null,\n    checkbox: null,\n  }\n\n  const state = reactive({\n    ...initialState,\n  })\n\n  const items = [\n    'Item 1',\n    'Item 2',\n    'Item 3',\n    'Item 4',\n  ]\n\n  const rules = {\n    name: { required },\n    email: { required, email },\n    select: { required },\n    items: { required },\n    checkbox: { required },\n  }\n\n  const v$ = useVuelidate(rules, state)\n\n  function clear () {\n    v$.value.$reset()\n\n    for (const [key, value] of Object.entries(initialState)) {\n      state[key] = value\n    }\n  }\n</script>\n\n<playground-resources lang=\"json\">\n  {\n    \"imports\": {\n      \"vue-demi\": \"https://cdn.jsdelivr.net/npm/vue-demi/lib/index.mjs\",\n      \"@vuelidate/core\": \"https://cdn.jsdelivr.net/npm/@vuelidate/core/dist/index.esm.js\",\n      \"@vuelidate/validators\": \"https://cdn.jsdelivr.net/npm/@vuelidate/validators/dist/index.esm.js\"\n    }\n  }\n</playground-resources>\n"
  },
  {
    "path": "packages/docs/src/examples/v-form/prop-disabled.vue",
    "content": "<template>\n  <v-sheet class=\"mx-auto\" width=\"300\">\n    <v-checkbox v-model=\"isEnabled\" label=\"Form is enabled\"></v-checkbox>\n    <v-form :disabled=\"!isEnabled\">\n      <v-text-field v-model=\"firstName\" label=\"First name\"></v-text-field>\n      <v-text-field v-model=\"lastName\" label=\"Last name\"></v-text-field>\n      <v-checkbox v-model=\"isAdmin\" label=\"User is admin\"></v-checkbox>\n      <v-select\n        v-model=\"role\"\n        :disabled=\"isAdmin || undefined\"\n        :items=\"['VIEWER', 'EDITOR']\"\n        hint=\"I'm enabled only if the user is not an admin\"\n        persistent-hint\n      ></v-select>\n    </v-form>\n  </v-sheet>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const isEnabled = ref(true)\n  const firstName = ref('')\n  const lastName = ref('')\n  const isAdmin = ref(false)\n  const role = ref()\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      isEnabled: true,\n      firstName: '',\n      lastName: '',\n      isAdmin: false,\n      role: null,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-form/prop-fast-fail.vue",
    "content": "<template>\n  <v-sheet class=\"mx-auto\" width=\"300\">\n    <v-form fast-fail @submit.prevent>\n      <v-text-field\n        v-model=\"firstName\"\n        :rules=\"firstNameRules\"\n        label=\"First name\"\n      ></v-text-field>\n\n      <v-text-field\n        v-model=\"lastName\"\n        :rules=\"lastNameRules\"\n        label=\"Last name\"\n      ></v-text-field>\n\n      <v-btn class=\"mt-2\" type=\"submit\" block>Submit</v-btn>\n    </v-form>\n  </v-sheet>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const firstName = ref('')\n  const firstNameRules = [\n    value => {\n      if (value?.length >= 3) return true\n      return 'First name must be at least 3 characters.'\n    },\n  ]\n\n  const lastName = ref('123')\n  const lastNameRules = [\n    value => {\n      if (/[^0-9]/.test(value)) return true\n      return 'Last name can not contain digits.'\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      firstName: '',\n      firstNameRules: [\n        value => {\n          if (value?.length >= 3) return true\n\n          return 'First name must be at least 3 characters.'\n        },\n      ],\n      lastName: '123',\n      lastNameRules: [\n        value => {\n          if (/[^0-9]/.test(value)) return true\n\n          return 'Last name can not contain digits.'\n        },\n      ],\n    }),\n  }\n</script>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2801-143726&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-form/rules-async.vue",
    "content": "<template>\n  <v-sheet class=\"mx-auto\" max-width=\"300\">\n    <v-form validate-on=\"submit lazy\" @submit.prevent=\"submit\">\n      <v-text-field\n        v-model=\"userName\"\n        :rules=\"rules\"\n        label=\"User name\"\n      ></v-text-field>\n\n      <v-btn\n        :loading=\"loading\"\n        class=\"mt-2\"\n        text=\"Submit\"\n        type=\"submit\"\n        block\n      ></v-btn>\n    </v-form>\n  </v-sheet>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const rules = [value => checkApi(value)]\n\n  const loading = ref(false)\n  const userName = ref('')\n\n  async function submit (event) {\n    loading.value = true\n    const results = await event\n    loading.value = false\n    alert(JSON.stringify(results, null, 2))\n  }\n\n  let timeout = -1\n  async function checkApi (userName) {\n    return new Promise(resolve => {\n      clearTimeout(timeout)\n\n      timeout = setTimeout(() => {\n        if (!userName) return resolve('Please enter a user name.')\n        if (userName === 'johnleider') return resolve('User name already taken. Please try another one.')\n        return resolve(true)\n      }, 1000)\n    })\n  }\n</script>\n\n<script>\n  export default {\n    data: vm => ({\n      loading: false,\n      rules: [value => vm.checkApi(value)],\n      timeout: null,\n      userName: '',\n    }),\n\n    methods: {\n      async submit (event) {\n        this.loading = true\n\n        const results = await event\n\n        this.loading = false\n\n        alert(JSON.stringify(results, null, 2))\n      },\n      async checkApi (userName) {\n        return new Promise(resolve => {\n          clearTimeout(this.timeout)\n\n          this.timeout = setTimeout(() => {\n            if (!userName) return resolve('Please enter a user name.')\n            if (userName === 'johnleider') return resolve('User name already taken. Please try another one.')\n\n            return resolve(true)\n          }, 1000)\n        })\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-form/rules-required.vue",
    "content": "<template>\n  <v-sheet class=\"mx-auto\" width=\"300\">\n    <v-form @submit.prevent>\n      <v-text-field\n        v-model=\"firstName\"\n        :rules=\"rules\"\n        label=\"First name\"\n      ></v-text-field>\n      <v-btn class=\"mt-2\" type=\"submit\" block>Submit</v-btn>\n    </v-form>\n  </v-sheet>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const firstName = ref('')\n\n  const rules = [\n    value => {\n      if (value) return true\n      return 'You must enter a first name.'\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      firstName: '',\n      rules: [\n        value => {\n          if (value) return true\n\n          return 'You must enter a first name.'\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-form/usage.vue",
    "content": "<template>\n  <v-form v-model=\"valid\">\n    <v-container>\n      <v-row>\n        <v-col\n          cols=\"12\"\n          md=\"4\"\n        >\n          <v-text-field\n            v-model=\"firstname\"\n            :counter=\"10\"\n            :rules=\"nameRules\"\n            label=\"First name\"\n            required\n          ></v-text-field>\n        </v-col>\n\n        <v-col\n          cols=\"12\"\n          md=\"4\"\n        >\n          <v-text-field\n            v-model=\"lastname\"\n            :counter=\"10\"\n            :rules=\"nameRules\"\n            label=\"Last name\"\n            required\n          ></v-text-field>\n        </v-col>\n\n        <v-col\n          cols=\"12\"\n          md=\"4\"\n        >\n          <v-text-field\n            v-model=\"email\"\n            :rules=\"emailRules\"\n            label=\"E-mail\"\n            required\n          ></v-text-field>\n        </v-col>\n      </v-row>\n    </v-container>\n  </v-form>\n</template>\n\n<script>\n  export default {\n    data: () => ({\n      valid: false,\n      firstname: '',\n      lastname: '',\n      nameRules: [\n        value => {\n          if (value) return true\n\n          return 'Name is required.'\n        },\n        value => {\n          if (value?.length <= 10) return true\n\n          return 'Name must be less than 10 characters.'\n        },\n      ],\n      email: '',\n      emailRules: [\n        value => {\n          if (value) return true\n\n          return 'E-mail is required.'\n        },\n        value => {\n          if (/.+@.+\\..+/.test(value)) return true\n\n          return 'E-mail must be valid.'\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-hotkey/prop-display-mode.vue",
    "content": "<template>\n  <v-container class=\"pa-0\" fluid>\n    <v-row density=\"comfortable\">\n      <v-col cols=\"12\" md=\"6\">\n        <v-card\n          height=\"232\"\n          subtitle=\"Uses SVG icons - compact and modern\"\n          title=\"Icon Mode (Default)\"\n        >\n          <template v-slot:text>\n            <div class=\"d-flex flex-column ga-2\">\n              <div class=\"d-flex align-center justify-space-between\">\n                Ctrl + K:\n                <v-hotkey display-mode=\"icon\" keys=\"ctrl+k\"></v-hotkey>\n              </div>\n\n              <div class=\"d-flex align-center justify-space-between\">\n                Meta + Shift + P:\n                <v-hotkey display-mode=\"icon\" keys=\"meta+shift+p\"></v-hotkey>\n              </div>\n\n              <div class=\"d-flex align-center justify-space-between\">\n                Alt + Arrow:\n                <v-hotkey display-mode=\"icon\" keys=\"alt+arrowup\"></v-hotkey>\n              </div>\n\n              <div class=\"d-flex align-center justify-space-between\">\n                Enter:\n                <v-hotkey display-mode=\"icon\" keys=\"enter\"></v-hotkey>\n              </div>\n            </div>\n          </template>\n        </v-card>\n      </v-col>\n\n      <v-col cols=\"12\" md=\"6\">\n        <v-card\n          height=\"232\"\n          subtitle=\"Uses Unicode symbols - Mac-style appearance\"\n          title=\"Symbol Mode\"\n        >\n          <template v-slot:text>\n            <div class=\"d-flex flex-column ga-2\">\n              <div class=\"d-flex align-center justify-space-between\">\n                Ctrl + K:\n                <v-hotkey display-mode=\"symbol\" keys=\"ctrl+k\"></v-hotkey>\n              </div>\n\n              <div class=\"d-flex align-center justify-space-between\">\n                Meta + Shift + P:\n                <v-hotkey display-mode=\"symbol\" keys=\"meta+shift+p\"></v-hotkey>\n              </div>\n\n              <div class=\"d-flex align-center justify-space-between\">\n                Alt + Arrow:\n                <v-hotkey display-mode=\"symbol\" keys=\"alt+arrowup\"></v-hotkey>\n              </div>\n\n              <div class=\"d-flex align-center justify-space-between\">\n                Enter:\n                <v-hotkey display-mode=\"symbol\" keys=\"enter\"></v-hotkey>\n              </div>\n            </div>\n          </template>\n        </v-card>\n      </v-col>\n\n      <v-col cols=\"12\">\n        <v-card\n          subtitle=\"Uses full text labels - most accessible\"\n          title=\"Text Mode\"\n        >\n          <template v-slot:text>\n            <div class=\"d-flex flex-column ga-2\">\n              <div class=\"d-flex align-center justify-space-between\">\n                Ctrl + K:\n                <v-hotkey display-mode=\"text\" keys=\"ctrl+k\"></v-hotkey>\n              </div>\n\n              <div class=\"d-flex align-center justify-space-between\">\n                Meta + Shift + P:\n                <v-hotkey display-mode=\"text\" keys=\"meta+shift+p\"></v-hotkey>\n              </div>\n\n              <div class=\"d-flex align-center justify-space-between\">\n                Alt + Arrow:\n                <v-hotkey display-mode=\"text\" keys=\"alt+arrowup\"></v-hotkey>\n              </div>\n\n              <div class=\"d-flex align-center justify-space-between\">\n                Enter:\n                <v-hotkey display-mode=\"text\" keys=\"enter\"></v-hotkey>\n              </div>\n            </div>\n          </template>\n        </v-card>\n      </v-col>\n    </v-row>\n\n    <v-row density=\"comfortable\">\n      <v-col cols=\"12\">\n        <v-card title=\"Interactive Comparison\">\n          <template v-slot:text>\n            <div class=\"mb-4 text-center\">\n              <div class=\"mb-2\">\n                <v-btn-toggle v-model=\"displayMode\" density=\"compact\" border divided mandatory>\n                  <v-btn value=\"icon\">Icon</v-btn>\n                  <v-btn value=\"symbol\">Symbol</v-btn>\n                  <v-btn value=\"text\">Text</v-btn>\n                </v-btn-toggle>\n              </div>\n              <div>\n                <v-btn-toggle v-model=\"platform\" density=\"compact\" border divided mandatory>\n                  <v-btn value=\"pc\">PC Platform</v-btn>\n                  <v-btn value=\"mac\">Mac Platform</v-btn>\n                </v-btn-toggle>\n              </div>\n            </div>\n\n            <div class=\"d-flex flex-wrap ga-4 align-center justify-center\">\n              <v-hotkey\n                :display-mode=\"displayMode\"\n                :platform=\"platform\"\n                keys=\"ctrl+shift+k\"\n              ></v-hotkey>\n              <v-hotkey\n                :display-mode=\"displayMode\"\n                :platform=\"platform\"\n                keys=\"meta+alt+p\"\n              ></v-hotkey>\n              <v-hotkey\n                :display-mode=\"displayMode\"\n                :platform=\"platform\"\n                keys=\"shift+enter\"\n              ></v-hotkey>\n              <v-hotkey\n                :display-mode=\"displayMode\"\n                :platform=\"platform\"\n                keys=\"ctrl+k-p\"\n              ></v-hotkey>\n            </div>\n          </template>\n        </v-card>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const displayMode = ref('icon')\n  const platform = ref('mac')\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        displayMode: 'icon',\n        platform: 'mac',\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-hotkey/prop-inline.vue",
    "content": "<template>\n  <v-container class=\"pa-0\" fluid>\n    <v-row density=\"comfortable\">\n      <v-col cols=\"12\">\n        <v-card>\n          <template v-slot:text>\n            <div class=\"mb-4 text-center\">\n              <div class=\"mb-2\">\n                <v-btn-toggle v-model=\"displayMode\" density=\"compact\" border divided mandatory>\n                  <v-btn value=\"icon\">Icon</v-btn>\n                  <v-btn value=\"symbol\">Symbol</v-btn>\n                  <v-btn value=\"text\">Text</v-btn>\n                </v-btn-toggle>\n              </div>\n              <div>\n                <v-btn-toggle v-model=\"platform\" density=\"compact\" border divided mandatory>\n                  <v-btn value=\"pc\">PC Platform</v-btn>\n                  <v-btn value=\"mac\">Mac Platform</v-btn>\n                </v-btn-toggle>\n              </div>\n            </div>\n\n            <div class=\"d-flex flex-column ga-4\">\n              <div>\n                <h4 class=\"text-body-large mt-0 mb-2\">Standard Display (Block-level)</h4>\n                <div class=\"pa-3 border rounded\">\n                  <p class=\"mb-2\">\n                    Save your work with <v-hotkey :display-mode=\"displayMode\" :platform=\"platform\" keys=\"cmd+s\"></v-hotkey>\n                    or create a new file using <v-hotkey :display-mode=\"displayMode\" :platform=\"platform\" keys=\"cmd+n\"></v-hotkey>.\n                  </p>\n                  <p class=\"mb-0\">\n                    Access the command palette with <v-hotkey :display-mode=\"displayMode\" :platform=\"platform\" keys=\"cmd+shift+p\"></v-hotkey>\n                    to quickly navigate your project.\n                  </p>\n                </div>\n              </div>\n\n              <div>\n                <h4 class=\"text-body-large mt-0 mb-2\">Inline Display (Text-integrated)</h4>\n                <div class=\"pa-4 border rounded\" style=\"line-height: 1.7;\">\n                  <h4 class=\"text-title-large mt-0 mb-3\">Getting Started with Code Editor</h4>\n\n                  <p class=\"mb-3\">\n                    Welcome to your new development environment! Here are the essential keyboard shortcuts\n                    to boost your productivity. Press\n                    <v-hotkey :display-mode=\"displayMode\" :platform=\"platform\" keys=\"cmd+shift+p\" inline></v-hotkey>\n                    to open the command palette, or use\n                    <v-hotkey :display-mode=\"displayMode\" :platform=\"platform\" keys=\"cmd+p\" inline></v-hotkey>\n                    to quickly open any file in your project.\n                  </p>\n\n                  <p class=\"mb-3\">\n                    <strong>File Operations:</strong> Save your current file with\n                    <v-hotkey :display-mode=\"displayMode\" :platform=\"platform\" keys=\"cmd+s\" inline></v-hotkey>\n                    or create a new file by pressing\n                    <v-hotkey :display-mode=\"displayMode\" :platform=\"platform\" keys=\"cmd+n\" inline></v-hotkey>.\n                    Need to close a file? Use\n                    <v-hotkey :display-mode=\"displayMode\" :platform=\"platform\" keys=\"cmd+w\" inline></v-hotkey>\n                    to close the current tab.\n                  </p>\n\n                  <p class=\"mb-3\">\n                    <strong>Navigation:</strong> Jump to a specific line with\n                    <v-hotkey :display-mode=\"displayMode\" :platform=\"platform\" keys=\"cmd+g\" inline></v-hotkey>,\n                    find text using\n                    <v-hotkey :display-mode=\"displayMode\" :platform=\"platform\" keys=\"cmd+f\" inline></v-hotkey>,\n                    or search across your entire project with\n                    <v-hotkey :display-mode=\"displayMode\" :platform=\"platform\" keys=\"cmd+shift+f\" inline></v-hotkey>.\n                  </p>\n\n                  <p class=\"mb-0\">\n                    <strong>Advanced:</strong> For power users, try the sequence\n                    <v-hotkey :display-mode=\"displayMode\" :platform=\"platform\" keys=\"cmd+k-p\" inline></v-hotkey>\n                    to access advanced search options, or use\n                    <v-hotkey :display-mode=\"displayMode\" :platform=\"platform\" keys=\"cmd+k-s\" inline></v-hotkey>\n                    to open settings.\n                  </p>\n                </div>\n              </div>\n            </div>\n          </template>\n        </v-card>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const displayMode = ref('icon')\n  const platform = ref('mac')\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        displayMode: 'icon',\n        platform: 'mac',\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-hotkey/prop-key-map.vue",
    "content": "<template>\n  <v-container class=\"pa-0\" fluid>\n    <v-alert\n      class=\"mb-2\"\n      type=\"info\"\n      variant=\"tonal\"\n    >\n      <div>\n        <strong>Custom Key Mapping:</strong> Override default key representations for localization, branding, or special keys.\n      </div>\n    </v-alert>\n\n    <v-row density=\"comfortable\">\n      <v-col cols=\"12\" md=\"6\">\n        <v-card subtitle=\"Standard Vuetify key representations\" title=\"Default Key Mapping\">\n          <template v-slot:text>\n            <div class=\"d-flex flex-column ga-2\">\n              <div class=\"d-flex align-center justify-space-between\">\n                ctrl+s:\n                <v-hotkey keys=\"ctrl+s\"></v-hotkey>\n              </div>\n\n              <div class=\"d-flex align-center justify-space-between\">\n                meta+z:\n                <v-hotkey keys=\"meta+z\"></v-hotkey>\n              </div>\n\n              <div class=\"d-flex align-center justify-space-between\">\n                alt+f4:\n                <v-hotkey keys=\"alt+f4\"></v-hotkey>\n              </div>\n\n              <div class=\"d-flex align-center justify-space-between\">\n                shift+enter:\n                <v-hotkey keys=\"shift+enter\"></v-hotkey>\n              </div>\n            </div>\n          </template>\n        </v-card>\n      </v-col>\n\n      <v-col cols=\"12\" md=\"6\">\n        <v-card subtitle=\"Customized key representations\" title=\"Custom Key Mapping\">\n          <template v-slot:text>\n            <div class=\"d-flex flex-column ga-2\">\n              <div class=\"d-flex align-center justify-space-between\">\n                ctrl+s:\n                <v-hotkey :key-map=\"customKeyMap\" keys=\"ctrl+s\"></v-hotkey>\n              </div>\n\n              <div class=\"d-flex align-center justify-space-between\">\n                meta+z:\n                <v-hotkey :key-map=\"customKeyMap\" keys=\"meta+z\"></v-hotkey>\n              </div>\n\n              <div class=\"d-flex align-center justify-space-between\">\n                alt+f4:\n                <v-hotkey :key-map=\"customKeyMap\" keys=\"alt+f4\"></v-hotkey>\n              </div>\n\n              <div class=\"d-flex align-center justify-space-between\">\n                shift+enter:\n                <v-hotkey :key-map=\"customKeyMap\" keys=\"shift+enter\"></v-hotkey>\n              </div>\n            </div>\n          </template>\n        </v-card>\n      </v-col>\n    </v-row>\n\n    <v-row density=\"comfortable\">\n      <v-col cols=\"12\">\n        <v-card title=\"Platform Comparison with Custom Mapping\">\n          <template v-slot:text>\n            <div class=\"mb-4 text-center\">\n              <div class=\"mb-2\">\n                <v-btn-toggle v-model=\"displayMode\" density=\"compact\" border divided mandatory>\n                  <v-btn value=\"icon\">Icon</v-btn>\n                  <v-btn value=\"symbol\">Symbol</v-btn>\n                  <v-btn value=\"text\">Text</v-btn>\n                </v-btn-toggle>\n              </div>\n              <div>\n                <v-btn-toggle v-model=\"platform\" density=\"compact\" border divided mandatory>\n                  <v-btn value=\"pc\">PC Platform</v-btn>\n                  <v-btn value=\"mac\">Mac Platform</v-btn>\n                </v-btn-toggle>\n              </div>\n            </div>\n\n            <v-table>\n              <thead>\n                <tr>\n                  <th>Key</th>\n                  <th>Default Mapping</th>\n                  <th>Custom Mapping</th>\n                  <th>Difference</th>\n                </tr>\n              </thead>\n\n              <tbody>\n                <tr>\n                  <td><code>ctrl+s</code></td>\n                  <td>\n                    <v-hotkey\n                      :display-mode=\"displayMode\"\n                      :platform=\"platform\"\n                      keys=\"ctrl+s\"\n                    ></v-hotkey>\n                  </td>\n                  <td>\n                    <v-hotkey\n                      :display-mode=\"displayMode\"\n                      :key-map=\"customKeyMap\"\n                      :platform=\"platform\"\n                      keys=\"ctrl+s\"\n                    ></v-hotkey>\n                  </td>\n                  <td>Uses \"Control\" instead of \"Ctrl\" in Text mode</td>\n                </tr>\n                <tr>\n                  <td><code>alt+f</code></td>\n                  <td>\n                    <v-hotkey\n                      :display-mode=\"displayMode\"\n                      :platform=\"platform\"\n                      keys=\"alt+f\"\n                    ></v-hotkey>\n                  </td>\n                  <td>\n                    <v-hotkey\n                      :display-mode=\"displayMode\"\n                      :key-map=\"customKeyMap\"\n                      :platform=\"platform\"\n                      keys=\"alt+f\"\n                    ></v-hotkey>\n                  </td>\n                  <td>Different symbols: ⎇ vs ⌥/Alt in Symbol mode</td>\n                </tr>\n                <tr>\n                  <td><code>enter</code></td>\n                  <td>\n                    <v-hotkey\n                      :display-mode=\"displayMode\"\n                      :platform=\"platform\"\n                      keys=\"enter\"\n                    ></v-hotkey>\n                  </td>\n                  <td>\n                    <v-hotkey\n                      :display-mode=\"displayMode\"\n                      :key-map=\"customKeyMap\"\n                      :platform=\"platform\"\n                      keys=\"enter\"\n                    ></v-hotkey>\n                  </td>\n                  <td>Uses \"Return\" and ⏎ symbol in Text mode and Symbol mode respectively</td>\n                </tr>\n              </tbody>\n            </v-table>\n          </template>\n        </v-card>\n      </v-col>\n    </v-row>\n\n    <v-row density=\"comfortable\">\n      <v-col cols=\"12\">\n        <v-card title=\"Code Example\">\n          <template v-slot:text>\n            <pre class=\"text-mono\">\n// Import the default hotkeyMap and extend it\nimport { hotkeyMap } from 'vuetify/labs/VHotkey'\n\nconst customKeyMap = {\n  ...hotkeyMap,\n  ctrl: {\n    mac: { symbol: '⌃', icon: '$ctrl', text: 'Control' },\n    default: { symbol: '⌃', icon: '$ctrl', text: 'Control' },\n  },\n  alt: {\n    mac: { symbol: '⌥', icon: '$alt', text: 'Option' },\n    default: { symbol: '⎇', icon: '$alt', text: 'Alt' },\n  },\n  enter: {\n    default: { symbol: '⏎', icon: '$enter', text: 'Return' },\n  },\n}\n            </pre>\n          </template>\n        </v-card>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const platform = ref('mac')\n  const displayMode = ref('icon')\n\n  const customKeyMap = {\n    // Include common keys that we're not customizing\n    shift: {\n      mac: { symbol: '⇧', icon: '$shift', text: '$vuetify.hotkey.shift' },\n      default: { text: 'Shift' },\n    },\n    meta: {\n      mac: { symbol: '⌘', icon: '$command', text: '$vuetify.hotkey.command' },\n      default: { text: 'Ctrl' },\n    },\n    cmd: {\n      mac: { symbol: '⌘', icon: '$command', text: '$vuetify.hotkey.command' },\n      default: { text: 'Ctrl' },\n    },\n\n    // Custom key overrides\n    ctrl: {\n      mac: { symbol: '⌃', icon: '$ctrl', text: 'Control' },\n      default: { symbol: '⌃', icon: '$ctrl', text: 'Control' },\n    },\n    alt: {\n      mac: { symbol: '⌥', icon: '$alt', text: 'Option' },\n      default: { symbol: '⎇', icon: '$alt', text: 'Alt' },\n    },\n    enter: {\n      default: { symbol: '⏎', icon: '$enter', text: 'Return' },\n    },\n\n    // Include other keys for completeness\n    arrowup: {\n      default: { symbol: '↑', icon: '$arrowup', text: '$vuetify.hotkey.upArrow' },\n    },\n    arrowdown: {\n      default: { symbol: '↓', icon: '$arrowdown', text: '$vuetify.hotkey.downArrow' },\n    },\n    arrowleft: {\n      default: { symbol: '←', icon: '$arrowleft', text: '$vuetify.hotkey.leftArrow' },\n    },\n    arrowright: {\n      default: { symbol: '→', icon: '$arrowright', text: '$vuetify.hotkey.rightArrow' },\n    },\n    backspace: {\n      default: { symbol: '⌫', icon: '$backspace', text: '$vuetify.hotkey.backspace' },\n    },\n    escape: {\n      default: { text: '$vuetify.hotkey.escape' },\n    },\n    space: {\n      mac: { symbol: '␣', icon: '$space', text: '$vuetify.hotkey.space' },\n      default: { text: '$vuetify.hotkey.space' },\n    },\n    '-': {\n      default: { symbol: '-', icon: '$minus', text: '-' },\n    },\n    minus: {\n      default: { symbol: '-', icon: '$minus', text: '-' },\n    },\n    hyphen: {\n      default: { symbol: '-', icon: '$minus', text: '-' },\n    },\n  }\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        platform: 'mac',\n        displayMode: 'icon',\n        customKeyMap: {\n          // Include common keys that we're not customizing\n          shift: {\n            mac: { symbol: '⇧', icon: '$shift', text: '$vuetify.hotkey.shift' },\n            default: { text: 'Shift' },\n          },\n          meta: {\n            mac: { symbol: '⌘', icon: '$command', text: '$vuetify.hotkey.command' },\n            default: { text: 'Ctrl' },\n          },\n          cmd: {\n            mac: { symbol: '⌘', icon: '$command', text: '$vuetify.hotkey.command' },\n            default: { text: 'Ctrl' },\n          },\n\n          // Custom key overrides\n          ctrl: {\n            mac: { symbol: '⌃', icon: '$ctrl', text: 'Control' },\n            default: { symbol: '⌃', icon: '$ctrl', text: 'Control' },\n          },\n          alt: {\n            mac: { symbol: '⌥', icon: '$alt', text: 'Option' },\n            default: { symbol: '⎇', icon: '$alt', text: 'Alt' },\n          },\n          enter: {\n            default: { symbol: '⏎', icon: '$enter', text: 'Return' },\n          },\n\n          // Include other keys for completeness\n          arrowup: {\n            default: { symbol: '↑', icon: '$arrowup', text: '$vuetify.hotkey.upArrow' },\n          },\n          arrowdown: {\n            default: { symbol: '↓', icon: '$arrowdown', text: '$vuetify.hotkey.downArrow' },\n          },\n          arrowleft: {\n            default: { symbol: '←', icon: '$arrowleft', text: '$vuetify.hotkey.leftArrow' },\n          },\n          arrowright: {\n            default: { symbol: '→', icon: '$arrowright', text: '$vuetify.hotkey.rightArrow' },\n          },\n          backspace: {\n            default: { symbol: '⌫', icon: '$backspace', text: '$vuetify.hotkey.backspace' },\n          },\n          escape: {\n            default: { text: '$vuetify.hotkey.escape' },\n          },\n          space: {\n            mac: { symbol: '␣', icon: '$space', text: '$vuetify.hotkey.space' },\n            default: { text: '$vuetify.hotkey.space' },\n          },\n          '-': {\n            default: { symbol: '-', icon: '$minus', text: '-' },\n          },\n          minus: {\n            default: { symbol: '-', icon: '$minus', text: '-' },\n          },\n          hyphen: {\n            default: { symbol: '-', icon: '$minus', text: '-' },\n          },\n        },\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-hotkey/prop-keys.vue",
    "content": "<template>\n  <v-container class=\"pa-0\" fluid>\n    <v-row density=\"comfortable\">\n      <v-col cols=\"12\" md=\"6\">\n        <v-card height=\"200\" title=\"Single Keys\">\n          <template v-slot:text>\n            <div class=\"d-flex flex-column ga-2\">\n              <div class=\"d-flex align-center justify-space-between\">\n                Letter key:\n                <v-hotkey keys=\"k\"></v-hotkey>\n              </div>\n\n              <div class=\"d-flex align-center justify-space-between\">\n                Enter key:\n                <v-hotkey keys=\"enter\"></v-hotkey>\n              </div>\n\n              <div class=\"d-flex align-center justify-space-between\">\n                Escape key:\n                <v-hotkey keys=\"escape\"></v-hotkey>\n              </div>\n\n              <div class=\"d-flex align-center justify-space-between\">\n                Arrow key:\n                <v-hotkey keys=\"arrowup\"></v-hotkey>\n              </div>\n            </div>\n          </template>\n        </v-card>\n      </v-col>\n\n      <v-col cols=\"12\" md=\"6\">\n        <v-card height=\"200\" title=\"Key Combinations\">\n          <template v-slot:text>\n            <div class=\"d-flex flex-column ga-2\">\n              <div class=\"d-flex align-center justify-space-between\">\n                Ctrl + K:\n                <v-hotkey keys=\"ctrl+k\"></v-hotkey>\n              </div>\n\n              <div class=\"d-flex align-center justify-space-between\">\n                Meta + Shift + P:\n                <v-hotkey keys=\"meta+shift+p\"></v-hotkey>\n              </div>\n\n              <div class=\"d-flex align-center justify-space-between\">\n                Alt + Arrow:\n                <v-hotkey keys=\"alt+arrowup\"></v-hotkey>\n              </div>\n\n              <div class=\"d-flex align-center justify-space-between\">\n                Ctrl + Shift + Enter:\n                <v-hotkey keys=\"ctrl+shift+enter\"></v-hotkey>\n              </div>\n            </div>\n          </template>\n        </v-card>\n      </v-col>\n    </v-row>\n\n    <v-row density=\"comfortable\">\n      <v-col cols=\"12\" md=\"6\">\n        <v-card height=\"132\" title=\"Sequential Actions\">\n          <template v-slot:text>\n            <div class=\"d-flex flex-column ga-2\">\n              <div class=\"d-flex align-center justify-space-between\">\n                Ctrl+K then P:\n                <v-hotkey keys=\"ctrl+k-p\"></v-hotkey>\n              </div>\n\n              <div class=\"d-flex align-center justify-space-between\">\n                Ctrl+X then Ctrl+C:\n                <v-hotkey keys=\"ctrl+x-ctrl+c\"></v-hotkey>\n              </div>\n            </div>\n          </template>\n        </v-card>\n      </v-col>\n\n      <v-col cols=\"12\" md=\"6\">\n        <v-card height=\"132\" title=\"Multiple Options\">\n          <template v-slot:text>\n            <div class=\"d-flex flex-column ga-2\">\n              <div class=\"d-flex align-center justify-space-between\">\n                Ctrl+K or Meta+P:\n                <v-hotkey keys=\"ctrl+k meta+p\"></v-hotkey>\n              </div>\n\n              <div class=\"d-flex align-center justify-space-between\">\n                Multiple options:\n                <v-hotkey keys=\"ctrl+s meta+s ctrl+shift+s\"></v-hotkey>\n              </div>\n            </div>\n          </template>\n        </v-card>\n      </v-col>\n    </v-row>\n\n    <v-row density=\"comfortable\">\n      <v-col cols=\"12\">\n        <v-card title=\"Platform-Aware Key Combinations\">\n          <template v-slot:text>\n            <div class=\"mb-4 text-center\">\n              <v-btn-toggle v-model=\"platform\" density=\"compact\" border divided mandatory>\n                <v-btn value=\"pc\">PC Platform</v-btn>\n                <v-btn value=\"mac\">Mac Platform</v-btn>\n              </v-btn-toggle>\n            </div>\n\n            <div class=\"d-flex flex-wrap ga-4 align-center justify-center\">\n              <div class=\"text-center\">\n                <div class=\"text-body-small mb-1\">meta+shift+p</div>\n                <v-hotkey\n                  :platform=\"platform\"\n                  keys=\"meta+shift+p\"\n                ></v-hotkey>\n              </div>\n\n              <div class=\"text-center\">\n                <div class=\"text-body-small mb-1\">ctrl+k meta+p</div>\n                <v-hotkey\n                  :platform=\"platform\"\n                  keys=\"ctrl+k meta+p\"\n                ></v-hotkey>\n              </div>\n\n              <div class=\"text-center\">\n                <div class=\"text-body-small mb-1\">alt+arrowup</div>\n                <v-hotkey\n                  :platform=\"platform\"\n                  keys=\"alt+arrowup\"\n                ></v-hotkey>\n              </div>\n\n              <div class=\"text-center\">\n                <div class=\"text-body-small mb-1\">ctrl+k-meta+p</div>\n                <v-hotkey\n                  :platform=\"platform\"\n                  keys=\"ctrl+k-meta+p\"\n                ></v-hotkey>\n              </div>\n            </div>\n          </template>\n        </v-card>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const platform = ref('mac')\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        platform: 'mac',\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-hotkey/prop-platform-aware.vue",
    "content": "<template>\n  <v-container class=\"pa-0\" fluid>\n    <v-alert\n      class=\"mb-2\"\n      type=\"info\"\n      variant=\"tonal\"\n    >\n      <div class=\"d-flex align-center\">\n        <div>\n          <strong>Platform Detection:</strong> Currently detected as {{ isMac ? 'Mac' : 'PC' }}\n        </div>\n      </div>\n    </v-alert>\n\n    <v-row density=\"comfortable\">\n      <v-col cols=\"12\" md=\"6\">\n        <v-card subtitle=\"These keys automatically adapt to your platform\" title=\"Cross-Platform Keys\">\n          <template v-slot:text>\n            <div class=\"d-flex flex-column ga-2\">\n              <div class=\"d-flex align-center justify-space-between\">\n                meta+k:\n                <v-hotkey keys=\"meta+k\"></v-hotkey>\n              </div>\n\n              <div class=\"d-flex align-center justify-space-between\">\n                alt+shift+f:\n                <v-hotkey keys=\"alt+shift+f\"></v-hotkey>\n              </div>\n\n              <div class=\"d-flex align-center justify-space-between\">\n                meta+alt+shift+k:\n                <v-hotkey keys=\"meta+alt+shift+k\"></v-hotkey>\n              </div>\n            </div>\n          </template>\n        </v-card>\n      </v-col>\n\n      <v-col cols=\"12\" md=\"6\">\n        <v-card subtitle=\"Explicit platform targeting\" title=\"Platform-Specific Keys\">\n          <template v-slot:text>\n            <div class=\"d-flex flex-column ga-2\">\n              <div class=\"d-flex align-center justify-space-between\">\n                ctrl+c:\n                <v-hotkey keys=\"ctrl+c\"></v-hotkey>\n              </div>\n\n              <div class=\"d-flex align-center justify-space-between\">\n                cmd+v:\n                <v-hotkey keys=\"cmd+v\"></v-hotkey>\n              </div>\n\n              <div class=\"d-flex align-center justify-space-between\">\n                ctrl+x meta+c:\n                <v-hotkey keys=\"ctrl+x meta+c\"></v-hotkey>\n              </div>\n            </div>\n          </template>\n        </v-card>\n      </v-col>\n    </v-row>\n\n    <v-row density=\"comfortable\">\n      <v-col cols=\"12\">\n        <v-card title=\"Display Mode & Platform Comparison\">\n          <template v-slot:text>\n            <div class=\"mb-4 text-center\">\n              <div class=\"mb-2\">\n                <v-btn-toggle v-model=\"displayMode\" density=\"compact\" border divided mandatory>\n                  <v-btn value=\"icon\">Icon</v-btn>\n                  <v-btn value=\"symbol\">Symbol</v-btn>\n                  <v-btn value=\"text\">Text</v-btn>\n                </v-btn-toggle>\n              </div>\n              <div>\n                <v-btn-toggle v-model=\"platform\" density=\"compact\" border divided mandatory>\n                  <v-btn value=\"pc\">PC Platform</v-btn>\n                  <v-btn value=\"mac\">Mac Platform</v-btn>\n                </v-btn-toggle>\n              </div>\n            </div>\n\n            <v-table>\n              <thead>\n                <tr>\n                  <th>Key Combination</th>\n                  <th>Display</th>\n                  <th>Platform Behavior</th>\n                </tr>\n              </thead>\n\n              <tbody>\n                <tr>\n                  <td><code>meta+k</code></td>\n                  <td>\n                    <v-hotkey\n                      :display-mode=\"displayMode\"\n                      :platform=\"platform\"\n                      keys=\"meta+k\"\n                    ></v-hotkey>\n                  </td>\n                  <td>{{ effectivePlatform === 'mac' ? 'Command on Mac' : 'Ctrl on PC' }}</td>\n                </tr>\n                <tr>\n                  <td><code>alt+f</code></td>\n                  <td>\n                    <v-hotkey\n                      :display-mode=\"displayMode\"\n                      :platform=\"platform\"\n                      keys=\"alt+f\"\n                    ></v-hotkey>\n                  </td>\n                  <td>{{ effectivePlatform === 'mac' ? 'Option on Mac' : 'Alt on PC' }}</td>\n                </tr>\n                <tr>\n                  <td><code>ctrl+shift+p</code></td>\n                  <td>\n                    <v-hotkey\n                      :display-mode=\"displayMode\"\n                      :platform=\"platform\"\n                      keys=\"ctrl+shift+p\"\n                    ></v-hotkey>\n                  </td>\n                  <td>Always Ctrl (explicit)</td>\n                </tr>\n                <tr>\n                  <td><code>cmd+shift+p</code></td>\n                  <td>\n                    <v-hotkey\n                      :display-mode=\"displayMode\"\n                      :platform=\"platform\"\n                      keys=\"cmd+shift+p\"\n                    ></v-hotkey>\n                  </td>\n                  <td>{{ effectivePlatform === 'mac' ? 'Command on Mac' : 'Ctrl on PC' }}</td>\n                </tr>\n              </tbody>\n            </v-table>\n          </template>\n        </v-card>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { computed, ref } from 'vue'\n\n  const displayMode = ref('icon')\n  const platform = ref('mac')\n\n  const isMac = computed(() => {\n    return typeof navigator !== 'undefined' && /macintosh/i.test(navigator.userAgent)\n  })\n\n  const effectivePlatform = computed(() => {\n    return platform.value\n  })\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        displayMode: 'icon',\n        platform: 'mac',\n      }\n    },\n\n    computed: {\n      isMac () {\n        return typeof navigator !== 'undefined' && /macintosh/i.test(navigator.userAgent)\n      },\n\n      effectivePlatform () {\n        return this.platform\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-hotkey/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div class=\"text-center\">\n      <v-hotkey v-bind=\"props\">\n        {{ keys }}\n      </v-hotkey>\n    </div>\n\n    <template v-slot:configuration>\n      <v-select\n        v-model=\"keyExample\"\n        :items=\"keyExamples\"\n        class=\"mb-4\"\n        item-title=\"label\"\n        item-value=\"value\"\n        label=\"Key combination\"\n      ></v-select>\n\n      <v-select\n        v-model=\"platformOverride\"\n        :items=\"platformOptions\"\n        hint=\"Choose how keyboard shortcuts are displayed\"\n        item-title=\"label\"\n        item-value=\"value\"\n        label=\"Platform behavior\"\n        persistent-hint\n      ></v-select>\n\n      <v-select\n        v-model=\"variant\"\n        :items=\"variants\"\n        item-title=\"label\"\n        item-value=\"value\"\n        label=\"Variant\"\n      ></v-select>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const displayModes = ['icon', 'symbol', 'text']\n  const name = 'v-hotkey'\n  const model = ref('default')\n  const options = [...displayModes]\n  const keyExample = ref('cmd+k')\n  const platformOverride = ref('mac')\n  const variant = ref('elevated')\n\n  const keyExamples = [\n    { label: 'Basic shortcut (Cmd+K)', value: 'cmd+k' },\n    { label: 'Multiple keys (Ctrl+Shift+P)', value: 'ctrl+shift+p' },\n    { label: 'Meta key (Meta+S)', value: 'meta+s' },\n    { label: 'Sequential (Ctrl+K-P)', value: 'ctrl+k-p' },\n    { label: 'Arrow key (Alt+Up)', value: 'alt+arrowup' },\n    { label: 'Function key (F1)', value: 'f1' },\n    { label: 'Special key (Enter)', value: 'enter' },\n    { label: 'Multiple options (Ctrl+S or Meta+S)', value: 'ctrl+s meta+s' },\n  ]\n\n  const platformOptions = [\n    { label: 'Mac', value: 'mac' },\n    { label: 'PC', value: 'pc' },\n    { label: 'Auto', value: 'auto' },\n  ]\n\n  const variants = [\n    { label: 'Elevated', value: 'elevated' },\n    { label: 'Plain', value: 'plain' },\n    { label: 'Contained', value: 'contained' },\n    { label: 'Flat', value: 'flat' },\n    { label: 'Tonal', value: 'tonal' },\n    { label: 'Outlined', value: 'outlined' },\n    { label: 'Text', value: 'text' },\n  ]\n\n  const props = computed(() => {\n    const baseProps = {\n      keys: keyExample.value,\n      'display-mode': displayModes.includes(model.value) ? model.value : undefined,\n      variant: variant.value,\n    }\n\n    // Set platform prop directly - 'auto' is now the default value\n    baseProps.platform = platformOverride.value\n\n    return baseProps\n  })\n\n  const keys = computed(() => keyExample.value)\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)} />`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-hover/misc-hover-list.vue",
    "content": "<template>\n  <v-container class=\"pa-4 text-center\">\n    <v-row class=\"fill-height align-center justify-center\">\n      <template v-for=\"(item, i) in items\" :key=\"i\">\n        <v-col\n          cols=\"12\"\n          md=\"4\"\n        >\n          <v-hover v-slot=\"{ isHovering, props }\">\n            <v-card\n              :class=\"{ 'on-hover': isHovering }\"\n              :elevation=\"isHovering ? 12 : 2\"\n              v-bind=\"props\"\n            >\n              <v-img\n                :src=\"item.img\"\n                height=\"225px\"\n                cover\n              >\n                <v-card-title class=\"text-title-large text-white d-flex flex-column\">\n                  <p class=\"mt-4\">\n                    {{ item.title }}\n                  </p>\n\n                  <div>\n                    <p class=\"ma-0 text-body-large font-weight-bold\">\n                      {{ item.text }}\n                    </p>\n                    <p class=\"text-body-small font-weight-medium\">\n                      {{ item.subtext }}\n                    </p>\n                  </div>\n                </v-card-title>\n                <div class=\"align-self-center\">\n                  <v-btn\n                    v-for=\"(icon, index) in icons\"\n                    :key=\"index\"\n                    :class=\"{ 'show-btns': isHovering }\"\n                    :color=\"transparent\"\n                    :icon=\"icon\"\n                    variant=\"text\"\n                  ></v-btn>\n                </div>\n              </v-img>\n            </v-card>\n          </v-hover>\n        </v-col>\n      </template>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  const icons = ['mdi-rewind', 'mdi-play', 'mdi-fast-forward']\n  const items = [\n    {\n      title: 'New Releases',\n      text: `It's New Release Friday`,\n      subtext: 'Newly released songs.',\n      img: 'https://cdn.vuetifyjs.com/docs/images/cards/hands.jpg',\n    },\n    {\n      title: 'Rock',\n      text: 'Greatest Rock Hits',\n      subtext: 'Lose yourself in rock tunes.',\n      img: 'https://cdn.vuetifyjs.com/docs/images/cards/singer.jpg',\n    },\n    {\n      title: 'Mellow Moods',\n      text: 'Ambient Bass',\n      subtext: 'Chill beats to mellow you out.',\n      img: 'https://cdn.vuetifyjs.com/docs/images/cards/concert.jpg',\n    },\n  ]\n  const transparent = 'rgba(255, 255, 255, 0)'\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      icons: ['mdi-rewind', 'mdi-play', 'mdi-fast-forward'],\n      items: [\n        {\n          title: 'New Releases',\n          text: `It's New Release Friday`,\n          subtext: 'Newly released songs.',\n          img: 'https://cdn.vuetifyjs.com/docs/images/cards/hands.jpg',\n        },\n        {\n          title: 'Rock',\n          text: 'Greatest Rock Hits',\n          subtext: 'Lose yourself in rock tunes.',\n          img: 'https://cdn.vuetifyjs.com/docs/images/cards/singer.jpg',\n        },\n        {\n          title: 'Mellow Moods',\n          text: 'Ambient Bass',\n          subtext: 'Chill beats to mellow you out.',\n          img: 'https://cdn.vuetifyjs.com/docs/images/cards/concert.jpg',\n        },\n      ],\n      transparent: 'rgba(255, 255, 255, 0)',\n    }),\n  }\n</script>\n\n<style scoped>\n  .v-card {\n    transition: opacity .4s ease-in-out;\n  }\n\n  .v-card:not(.on-hover) {\n    opacity: 0.6;\n  }\n\n  .show-btns {\n    color: rgba(255, 255, 255, 1) !important;\n  }\n</style>\n"
  },
  {
    "path": "packages/docs/src/examples/v-hover/misc-transition.vue",
    "content": "<template>\n  <div>\n    <v-hover v-slot=\"{ isHovering, props }\">\n      <v-card\n        class=\"mx-auto\"\n        color=\"grey-lighten-4\"\n        max-width=\"600\"\n        v-bind=\"props\"\n      >\n        <v-img\n          :aspect-ratio=\"16/9\"\n          src=\"https://cdn.vuetifyjs.com/images/cards/kitchen.png\"\n          cover\n        >\n          <v-expand-transition>\n            <div\n              v-if=\"isHovering\"\n              class=\"d-flex bg-orange-darken-2 v-card--reveal text-display-large\"\n              style=\"height: 100%;\"\n            >\n              $14.99\n            </div>\n          </v-expand-transition>\n        </v-img>\n\n        <v-card-text class=\"pt-6\">\n          <div class=\"font-weight-light text-grey text-title-large mb-2\">\n            For the perfect meal\n          </div>\n\n          <h3 class=\"text-headline-large font-weight-light text-orange mt-0 mb-2\">\n            QW cooking utensils\n          </h3>\n\n          <div class=\"font-weight-light text-title-large mb-2\">\n            Our Vintage kitchen utensils delight any chef.<br>\n            Made of bamboo by hand\n          </div>\n        </v-card-text>\n      </v-card>\n    </v-hover>\n  </div>\n</template>\n\n<style>\n  .v-card--reveal {\n    align-items: center;\n    bottom: 0;\n    justify-content: center;\n    opacity: .9;\n    position: absolute;\n    width: 100%;\n  }\n</style>\n"
  },
  {
    "path": "packages/docs/src/examples/v-hover/prop-disabled.vue",
    "content": "<template>\n  <v-row class=\"align-center justify-center\">\n    <v-col cols=\"12\">\n      <v-hover\n        v-slot=\"{ isHovering, props }\"\n        disabled\n      >\n        <v-card\n          :elevation=\"isHovering ? 12 : 2\"\n          class=\"mx-auto\"\n          height=\"350\"\n          max-width=\"350\"\n          v-bind=\"props\"\n        >\n          <v-card-text class=\"my-4 text-center text-title-large\">\n            Hover over me!\n          </v-card-text>\n        </v-card>\n      </v-hover>\n    </v-col>\n  </v-row>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-hover/prop-open-and-close-delay.vue",
    "content": "<template>\n  <v-row>\n    <v-col\n      cols=\"12\"\n      sm=\"6\"\n    >\n      <v-hover\n        v-slot=\"{ isHovering, props }\"\n        open-delay=\"200\"\n      >\n        <v-card\n          :class=\"{ 'on-hover': isHovering }\"\n          :elevation=\"isHovering ? 4 : 1\"\n          class=\"mx-auto\"\n          height=\"350\"\n          max-width=\"350\"\n          v-bind=\"props\"\n        >\n          <v-card-text class=\"font-weight-medium mt-12 text-center text-body-large\">\n            Open Delay (Mouse enter)\n          </v-card-text>\n        </v-card>\n      </v-hover>\n    </v-col>\n\n    <v-col\n      cols=\"12\"\n      sm=\"6\"\n    >\n      <v-hover\n        v-slot=\"{ isHovering, props }\"\n        close-delay=\"200\"\n      >\n        <v-card\n          :class=\"{ 'on-hover': isHovering }\"\n          :elevation=\"isHovering ? 4 : 1\"\n          class=\"mx-auto\"\n          height=\"350\"\n          max-width=\"350\"\n          v-bind=\"props\"\n        >\n          <v-card-text class=\"font-weight-medium mt-12 text-center text-body-large\">\n            Close Delay (Mouse leave)\n          </v-card-text>\n        </v-card>\n      </v-hover>\n    </v-col>\n  </v-row>\n</template>\n\n<style lang=\"sass\" scoped>\n.v-card.on-hover.v-theme--dark\n  background-color: rgba(#FFF, 0.8)\n  >.v-card__text\n    color: #000\n</style>\n"
  },
  {
    "path": "packages/docs/src/examples/v-hover/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div>\n      <v-hover v-bind=\"props\">\n        <template v-slot:default=\"{ isHovering, props: hoverProps }\">\n          <v-card\n            v-bind=\"hoverProps\"\n            :color=\"isHovering ? 'primary' : undefined\"\n            text=\"Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!\"\n            title=\"Hover over me\"\n          ></v-card>\n        </template>\n      </v-hover>\n    </div>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-hover'\n  const model = ref('default')\n  const options = []\n  const props = computed(() => {\n    return {}\n  })\n\n  const slots = computed(() => {\n    return `\n  <template v-slot:default=\"{ isHovering, props }\">\n    <v-card\n      v-bind=\"props\"\n      :color=\"isHovering ? 'primary' : undefined\"\n      title=\"Hover over me\"\n      text=\"...\"\n    ></v-card>\n  </template>\n`\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-icon/event-click.vue",
    "content": "<template>\n  <v-card>\n    <v-toolbar\n      color=\"pink\"\n      dark\n      dense\n      flat\n    >\n      <v-toolbar-title class=\"text-body-medium\">\n        Upcoming Changes\n      </v-toolbar-title>\n    </v-toolbar>\n    <v-card-text>\n      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n    </v-card-text>\n\n    <v-card-actions>\n      <v-spacer></v-spacer>\n      <v-icon\n        size=\"large\"\n        @click=\"next\"\n      >\n        mdi-chevron-right\n      </v-icon>\n    </v-card-actions>\n  </v-card>\n</template>\n\n<script setup>\n  function next () {\n    alert('You clicked next!')\n  }\n</script>\n\n<script>\n  export default {\n    methods: {\n      next () {\n        alert('You clicked next!')\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-icon/misc-buttons.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <div>\n      <v-btn\n        class=\"ma-2\"\n        color=\"primary\"\n      >\n        Accept\n        <v-icon\n          icon=\"mdi-checkbox-marked-circle\"\n          end\n        ></v-icon>\n      </v-btn>\n\n      <v-btn\n        class=\"ma-2\"\n        color=\"red\"\n      >\n        Decline\n        <v-icon\n          icon=\"mdi-cancel\"\n          end\n        ></v-icon>\n      </v-btn>\n\n      <v-btn\n        class=\"ma-2\"\n      >\n        <v-icon\n          icon=\"mdi-minus-circle\"\n          start\n        ></v-icon>\n        Cancel\n      </v-btn>\n    </div>\n\n    <div>\n      <v-btn\n        class=\"ma-2\"\n        color=\"orange-darken-2\"\n      >\n        <v-icon\n          icon=\"mdi-arrow-left\"\n          start\n        ></v-icon>\n        Back\n      </v-btn>\n\n      <v-btn\n        class=\"ma-2\"\n        color=\"purple\"\n        icon=\"mdi-wrench\"\n      ></v-btn>\n\n      <v-btn\n        class=\"ma-2\"\n        color=\"indigo\"\n        icon=\"mdi-cloud-upload\"\n      ></v-btn>\n    </div>\n\n    <div>\n      <v-btn\n        class=\"ma-2\"\n        color=\"blue-lighten-2\"\n        icon=\"mdi-thumb-up\"\n        variant=\"text\"\n      ></v-btn>\n\n      <v-btn\n        class=\"ma-2\"\n        color=\"red-lighten-2\"\n        icon=\"mdi-thumb-down\"\n        variant=\"text\"\n      ></v-btn>\n    </div>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-icon/misc-font-awesome.vue",
    "content": "<template>\n  <div class=\"d-flex justify-space-around\">\n    <v-icon icon=\"fa:fas fa-lock\"></v-icon>\n\n    <v-icon icon=\"fa:fas fa-search\"></v-icon>\n\n    <v-icon icon=\"fa:fas fa-list\"></v-icon>\n\n    <v-icon icon=\"fa:fas fa-edit\"></v-icon>\n\n    <v-icon icon=\"fa:fas fa-tachometer-alt\"></v-icon>\n\n    <v-icon icon=\"fa:fas fa-circle-notch fa-spin\"></v-icon>\n  </div>\n</template>\n\n<playground-resources lang=\"json\">\n  {\n    \"css\": [\"https://use.fontawesome.com/releases/v5.1.0/css/all.css\"]\n  }\n</playground-resources>\n"
  },
  {
    "path": "packages/docs/src/examples/v-icon/misc-md.vue",
    "content": "<template>\n  <div class=\"d-flex justify-space-around\">\n    <v-icon icon=\"md:home\"></v-icon>\n    <v-icon icon=\"md:event\"></v-icon>\n    <v-icon icon=\"md:info\"></v-icon>\n    <v-icon icon=\"md:folder_open\"></v-icon>\n    <v-icon icon=\"md:widgets\"></v-icon>\n    <v-icon icon=\"md:gavel\"></v-icon>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-icon/misc-mdi-svg.vue",
    "content": "<template>\n  <div class=\"d-flex justify-space-around\">\n    <v-icon :icon=\"`mdiSvg:${mdiAccount}`\"></v-icon>\n    <v-icon :icon=\"`mdiSvg:${mdiPencil}`\"></v-icon>\n    <v-icon :icon=\"`mdiSvg:${mdiShareVariant}`\"></v-icon>\n    <v-icon :icon=\"`mdiSvg:${mdiDelete}`\"></v-icon>\n  </div>\n</template>\n\n<script setup>\n  import { mdiAccount, mdiDelete, mdiPencil, mdiShareVariant } from '@mdi/js'\n</script>\n\n<script>\n  import {\n    mdiAccount,\n    mdiDelete,\n    mdiPencil,\n    mdiShareVariant,\n  } from '@mdi/js'\n\n  export default {\n    data: () => ({\n      mdiAccount,\n      mdiPencil,\n      mdiShareVariant,\n      mdiDelete,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-icon/prop-color.vue",
    "content": "<template>\n  <v-row class=\"py-4 justify-space-around\">\n    <v-icon\n      color=\"green-darken-2\"\n      icon=\"mdi-domain\"\n      size=\"large\"\n    ></v-icon>\n\n    <v-icon\n      color=\"blue-darken-2\"\n      icon=\"mdi-message-text\"\n      size=\"large\"\n    ></v-icon>\n\n    <v-icon\n      color=\"purple-darken-2\"\n      icon=\"mdi-dialpad\"\n      size=\"large\"\n    ></v-icon>\n\n    <v-icon\n      color=\"teal-darken-2\"\n      icon=\"mdi-email\"\n      size=\"large\"\n    ></v-icon>\n\n    <v-icon\n      color=\"blue-grey-darken-2\"\n      icon=\"mdi-call-split\"\n      size=\"large\"\n    ></v-icon>\n\n    <v-icon\n      color=\"orange-darken-2\"\n      icon=\"mdi-arrow-up-bold-box-outline\"\n      size=\"large\"\n    ></v-icon>\n  </v-row>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-icon/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div class=\"text-center\">\n      <v-icon v-bind=\"props\"></v-icon>\n    </div>\n\n    <template v-slot:configuration>\n      <v-select v-model=\"size\" :items=\"sizes\" label=\"Size\"></v-select>\n\n      <v-select v-model=\"color\" :items=\"colors\" label=\"Color\"></v-select>\n\n      <v-select v-model=\"icon\" :items=\"icons\" label=\"Icon\" clearable></v-select>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-icon'\n  const model = ref('default')\n  const icon = ref()\n  const size = ref()\n  const color = ref()\n  const options = []\n  const props = computed(() => {\n    return {\n      color: color.value || undefined,\n      icon: icon.value || '$vuetify',\n      size: ['', 'medium'].includes(size.value) ? undefined : size.value,\n    }\n  })\n  const colors = [\n    'success',\n    'info',\n    'warning',\n    'error',\n  ]\n  const icons = [\n    'mdi-plus',\n    'mdi-check-circle',\n    'mdi-information',\n    'mdi-alert',\n    'mdi-alert-circle',\n    'mdi-wifi',\n    'mdi-access-point',\n    'mdi-antenna',\n  ]\n  const sizes = [\n    'x-small',\n    'small',\n    'medium',\n    'large',\n    'x-large',\n  ]\n\n  const slots = computed(() => {\n    return ``\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-icon-btn/misc-dialog.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-btn>\n      Open Dialog\n\n      <v-dialog v-model=\"dialog\" activator=\"parent\" max-width=\"500\" persistent>\n        <v-card subtitle=\"Click the X to close\" title=\"Dialog\">\n          <template v-slot:append>\n            <v-icon-btn icon=\"$close\" @click=\"dialog = false\"></v-icon-btn>\n          </template>\n        </v-card>\n      </v-dialog>\n    </v-btn>\n  </div>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const dialog = shallowRef(false)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        dialog: false,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-icon-btn/misc-markdown-editor.vue",
    "content": "<template>\n  <v-container class=\"pa-md-12\">\n    <v-card\n      class=\"mx-auto\"\n      color=\"blue-grey-darken-2\"\n      max-width=\"640\"\n      rounded=\"lg\"\n      variant=\"tonal\"\n    >\n      <v-toolbar\n        density=\"compact\"\n        rounded=\"t-lg\"\n        title=\"Editor\"\n        border\n      >\n        <template v-slot:append>\n          <div class=\"d-flex align-center pa-1\">\n            <div ref=\"desktopTarget\"></div>\n\n            <v-icon-btn\n              v-if=\"display.mobile.value\"\n              icon=\"mdi-dots-vertical\"\n              rounded=\"lg\"\n              size=\"32\"\n            >\n              <v-icon></v-icon>\n\n              <v-menu activator=\"parent\" width=\"200\">\n                <v-card rounded=\"lg\">\n                  <div ref=\"mobileTarget\"></div>\n                </v-card>\n              </v-menu>\n            </v-icon-btn>\n          </div>\n        </template>\n      </v-toolbar>\n\n      <div class=\"px-4 pb-4\">\n        <v-textarea\n          ref=\"textarea\"\n          v-model=\"model\"\n          variant=\"plain\"\n          auto-grow\n          hide-details\n        ></v-textarea>\n\n        <input\n          ref=\"images\"\n          class=\"d-none\"\n          type=\"file\"\n          multiple\n        >\n      </div>\n    </v-card>\n\n    <Teleport v-if=\"teleportTarget\" :to=\"teleportTarget\">\n      <div class=\"d-flex ga-2 pa-2 flex-wrap justify-space-between\">\n        <template v-for=\"(item, i) in actions\" :key=\"i\">\n          <v-icon-btn\n            v-if=\"!item.divider\"\n            v-bind=\"item\"\n            rounded=\"lg\"\n            size=\"32\"\n          ></v-icon-btn>\n\n          <v-divider v-else-if=\"!display.mobile.value\" class=\"mx-1\" vertical></v-divider>\n        </template>\n      </div>\n    </Teleport>\n  </v-container>\n</template>\n\n<script setup>\n  import { computed, nextTick, ref, shallowRef } from 'vue'\n  import { useDisplay } from 'vuetify'\n\n  const display = useDisplay()\n\n  const images = ref()\n  const textarea = ref()\n  const mobileTarget = ref()\n  const desktopTarget = ref()\n  const model = shallowRef('')\n  const teleportTarget = computed(() => display.mobile.value ? mobileTarget.value : desktopTarget.value)\n\n  function onClickHeading () {\n    if (!model.value) {\n      model.value = '# '\n    } else if (model.value === '# ') {\n      model.value = ''\n    } else {\n      model.value += ' # '\n    }\n\n    textarea.value.focus()\n  }\n\n  async function onClickBold () {\n    textarea.value.focus()\n\n    if (!model.value) {\n      model.value = '**'\n      await nextTick()\n      textarea.value.setSelectionRange(1, 1)\n    } else if (model.value === '**') {\n      model.value = ''\n    } else {\n      const start = model.value.length\n      model.value += ' **'\n      await nextTick()\n      textarea.value.setSelectionRange(start + 2, start + 2)\n    }\n  }\n\n  async function onClickItalic () {\n    textarea.value.focus()\n\n    if (!model.value) {\n      model.value = '__'\n      await nextTick()\n      textarea.value.setSelectionRange(1, 1)\n    } else if (model.value === '__') {\n      model.value = ''\n    } else {\n      const start = model.value.length\n      model.value += ' __'\n      await nextTick()\n      textarea.value.setSelectionRange(start + 2, start + 2)\n    }\n  }\n\n  function onClickListNumbered () {\n    if (!model.value) {\n      model.value = '1. '\n    } else if (model.value === '1. ') {\n      model.value = ''\n    } else {\n      model.value += ' 1. '\n    }\n\n    textarea.value.focus()\n  }\n\n  function onClickListUnordered () {\n    if (!model.value) {\n      model.value = '- '\n    } else if (model.value === '- ') {\n      model.value = ''\n    } else {\n      model.value += ' - '\n    }\n\n    textarea.value.focus()\n  }\n\n  function onClickListTask () {\n    if (!model.value) {\n      model.value = '- [] '\n    } else {\n      model.value += '\\n\\n- [] '\n    }\n\n    textarea.value.focus()\n  }\n\n  function onClickAttachFiles () {\n    images.value.click()\n  }\n\n  async function onClickDetails () {\n    textarea.value.focus()\n\n    if (!model.value.startsWith('<details>')) {\n      model.value = `<details>\\n<summary>Details</summary>\\n\\n\\n\\n</details>`\n      await nextTick()\n      textarea.value.setSelectionRange(38, 38)\n    } else {\n      model.value = ''\n    }\n  }\n\n  const actions = [\n    { icon: 'mdi-format-header-1', onClick: onClickHeading },\n    { icon: 'mdi-format-bold', onClick: onClickBold },\n    { icon: 'mdi-format-italic', onClick: onClickItalic },\n    { divider: true },\n    { icon: 'mdi-format-list-numbered', onClick: onClickListNumbered },\n    { icon: 'mdi-format-list-bulleted', onClick: onClickListUnordered },\n    { icon: 'mdi-format-list-checks', onClick: onClickListTask },\n    { divider: true },\n    { icon: 'mdi-paperclip', onClick: onClickAttachFiles },\n    { divider: true },\n    { icon: 'mdi-format-vertical-align-bottom', onClick: onClickDetails },\n  ]\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-icon-btn/misc-table-actions.vue",
    "content": "<template>\n  <v-container>\n    <v-sheet border>\n      <v-data-table :headers=\"headers\" :items=\"plants\" hide-default-footer>\n        <template v-slot:item.color=\"{ item }\">\n          <v-chip\n            :text=\"item.color\"\n            color=\"medium-emphasis\"\n            size=\"small\"\n            border\n          >\n            <template v-slot:prepend>\n              <v-avatar\n                :color=\"item.color.toLowerCase()\"\n                border=\"thin opacity-25\"\n                size=\"16\"\n                start\n              ></v-avatar>\n            </template>\n          </v-chip>\n        </template>\n\n        <template v-slot:item.actions=\"{ item, index }\">\n          <div class=\"d-flex ga-2 justify-end\">\n            <v-icon-btn\n              icon=\"mdi-pencil\"\n              size=\"24\"\n              variant=\"plain\"\n              @click=\"onClickEdit(item)\"\n            >\n              <v-icon size=\"16\"></v-icon>\n            </v-icon-btn>\n\n            <v-icon-btn\n              icon=\"mdi-delete-outline\"\n              size=\"24\"\n              variant=\"plain\"\n              @click=\"onClickDelete(index)\"\n            >\n              <v-icon size=\"16\"></v-icon>\n            </v-icon-btn>\n          </div>\n        </template>\n\n        <template v-slot:no-data>\n          <v-btn\n            prepend-icon=\"mdi-backup-restore\"\n            rounded=\"lg\"\n            text=\"Reset data\"\n            variant=\"text\"\n            border\n            @click=\"onClickReset\"\n          ></v-btn>\n        </template>\n      </v-data-table>\n    </v-sheet>\n\n    <v-dialog\n      v-model=\"dialog\"\n      max-width=\"450\"\n      @after-leave=\"onAfterLeave\"\n    >\n      <v-card density=\"compact\" title=\"Edit\">\n        <v-divider></v-divider>\n\n        <v-card-text>\n          <v-text-field\n            v-model=\"record.title\"\n            density=\"compact\"\n            label=\"Title\"\n            variant=\"outlined\"\n            rounded\n          ></v-text-field>\n\n          <v-text-field\n            v-model=\"record.color\"\n            density=\"compact\"\n            label=\"Color\"\n            variant=\"outlined\"\n            rounded\n          ></v-text-field>\n        </v-card-text>\n\n        <v-divider></v-divider>\n\n        <v-card-actions class=\"bg-surface-light\">\n          <v-spacer></v-spacer>\n\n          <v-icon-btn\n            :loading=\"isSaving\"\n            color=\"primary\"\n            icon=\"mdi-content-save\"\n            variant=\"flat\"\n            @click=\"onClickSave\"\n          ></v-icon-btn>\n        </v-card-actions>\n      </v-card>\n    </v-dialog>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref, shallowRef } from 'vue'\n\n  const DEFAULT_RECORD = () => ({ title: '', color: '' })\n  const DEFAULT_RECORDS = () => ([\n    { id: 1, title: '🌹 Rose', color: 'Red' },\n    { id: 2, title: '🌷 Tulip', color: 'Yellow' },\n    { id: 3, title: '🌻 Sunflower', color: 'Yellow' },\n    { id: 4, title: '🌼 Daisy', color: 'White' },\n    { id: 5, title: '🥀 Orchid', color: 'Purple' },\n  ])\n\n  const isSaving = shallowRef(false)\n  const dialog = shallowRef(false)\n  const record = shallowRef(DEFAULT_RECORD())\n\n  const headers = [\n    { title: 'Title', align: 'start', key: 'title' },\n    { title: 'Color', align: 'end', key: 'color' },\n    { title: 'Actions', align: 'end', key: 'actions' },\n  ]\n\n  const plants = ref(DEFAULT_RECORDS())\n\n  function onAfterLeave () {\n    record.value = DEFAULT_RECORD()\n  }\n\n  function onClickDelete (index) {\n    plants.value.splice(index, 1)\n  }\n\n  function onClickEdit (item) {\n    dialog.value = true\n    record.value = { ...item }\n  }\n\n  function onClickReset () {\n    plants.value = DEFAULT_RECORDS()\n  }\n\n  async function onClickSave () {\n    isSaving.value = true\n\n    await new Promise(resolve => setTimeout(resolve, 1000))\n\n    const index = plants.value.findIndex(plant => plant.id === record.value.id)\n\n    plants.value[index] = { ...record.value }\n\n    dialog.value = false\n    isSaving.value = false\n  }\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        isSaving: false,\n        dialog: false,\n        record: { title: '', color: '' },\n        plants: [\n          { id: 1, title: '🌹 Rose', color: 'Red' },\n          { id: 2, title: '🌷 Tulip', color: 'Yellow' },\n          { id: 3, title: '🌻 Sunflower', color: 'Yellow' },\n          { id: 4, title: '🌼 Daisy', color: 'White' },\n          { id: 5, title: '🥀 Orchid', color: 'Purple' },\n        ],\n        headers: [\n          { title: 'Title', align: 'start', key: 'title' },\n          { title: 'Color', align: 'end', key: 'color' },\n          { title: 'Actions', align: 'end', key: 'actions' },\n        ],\n      }\n    },\n    methods: {\n      defaultRecord () {\n        return { title: '', color: '' }\n      },\n      defaultRecords () {\n        return [\n          { id: 1, title: '🌹 Rose', color: 'Red' },\n          { id: 2, title: '🌷 Tulip', color: 'Yellow' },\n          { id: 3, title: '🌻 Sunflower', color: 'Yellow' },\n          { id: 4, title: '🌼 Daisy', color: 'White' },\n          { id: 5, title: '🥀 Orchid', color: 'Purple' },\n        ]\n      },\n      onAfterLeave () {\n        this.record = this.defaultRecord()\n      },\n      onClickDelete (index) {\n        this.plants.splice(index, 1)\n      },\n      onClickEdit (item) {\n        this.dialog = true\n        this.record = { ...item }\n      },\n      onClickReset () {\n        this.plants = this.defaultRecords()\n      },\n      async onClickSave () {\n        this.isSaving = true\n        await new Promise(resolve => setTimeout(resolve, 1000))\n\n        const index = this.plants.findIndex(plant => plant.id === this.record.id)\n        this.plants[index] = { ...this.record }\n\n        this.dialog = false\n        this.isSaving = false\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-icon-btn/misc-video-controls.vue",
    "content": "<template>\n  <v-container class=\"pa-md-12 text-center\">\n    <v-sheet\n      class=\"d-inline-flex ga-1 pa-4 align-center justify-center mx-auto\"\n      color=\"surface-light\"\n      rounded=\"pill\"\n    >\n      <v-sheet\n        :rounded=\"!mic ? 'lg' : 'xl'\"\n        class=\"overflow-visible d-flex align-center\"\n        color=\"surface\"\n        height=\"48\"\n        width=\"88\"\n        flat\n      >\n        <v-icon-btn\n          v-model:active=\"micOptions\"\n          :active-variant=\"!mic ? 'flat' : 'text'\"\n          :base-variant=\"!mic ? 'flat' : 'text'\"\n          :color=\"!mic ? 'error' : ''\"\n          :rotate=\"micOptions ? 180 : 0\"\n          :rounded=\"!mic ? 'lg' : 'circle'\"\n          icon=\"mdi-chevron-up\"\n          size=\"48\"\n          hide-overlay\n        ></v-icon-btn>\n\n        <v-icon-btn\n          v-model:active=\"mic\"\n          :rounded=\"!mic ? 'lg' : 'circle'\"\n          active-color=\"\"\n          active-icon=\"mdi-microphone\"\n          active-variant=\"tonal\"\n          base-variant=\"flat\"\n          class=\"ms-n2\"\n          color=\"#f9dedc\"\n          icon=\"mdi-microphone-off\"\n          size=\"48\"\n          v-ripple\n        ></v-icon-btn>\n      </v-sheet>\n\n      <v-sheet\n        :rounded=\"!video ? 'lg' : 'xl'\"\n        class=\"overflow-visible d-flex align-center\"\n        color=\"surface\"\n        height=\"48\"\n        width=\"88\"\n        flat\n      >\n        <v-icon-btn\n          v-model:active=\"videoOptions\"\n          :active-variant=\"!video ? 'flat' : 'text'\"\n          :base-variant=\"!video ? 'flat' : 'text'\"\n          :color=\"!video ? 'error' : ''\"\n          :rotate=\"videoOptions ? 180 : 0\"\n          :rounded=\"!video ? 'lg' : 'circle'\"\n          icon=\"mdi-chevron-up\"\n          size=\"48\"\n          hide-overlay\n        ></v-icon-btn>\n\n        <v-icon-btn\n          v-model:active=\"video\"\n          :rounded=\"!video ? 'lg' : 'circle'\"\n          active-color=\"\"\n          active-icon=\"mdi-video-outline\"\n          active-variant=\"tonal\"\n          base-variant=\"flat\"\n          class=\"ms-n2\"\n          color=\"#f9dedc\"\n          icon=\"mdi-video-off\"\n          size=\"48\"\n        ></v-icon-btn>\n      </v-sheet>\n\n      <v-icon-btn\n        v-model:active=\"caption\"\n        :class=\"!caption ? 'mx-1' : undefined\"\n        :rounded=\"!caption ? 'circle' : 'lg'\"\n        :width=\"caption ? 56 : 48\"\n        active-color=\"#9bbbef\"\n        active-icon=\"mdi-closed-caption\"\n        active-variant=\"flat\"\n        height=\"48\"\n        icon=\"mdi-closed-caption-outline\"\n      ></v-icon-btn>\n\n      <v-icon-btn\n        v-model:active=\"emoji\"\n        :class=\"!emoji ? 'mx-1' : undefined\"\n        :rounded=\"!emoji ? 'circle' : 'lg'\"\n        :width=\"emoji ? 56 : 48\"\n        active-color=\"#9bbbef\"\n        active-icon=\"mdi-emoticon\"\n        height=\"48\"\n        icon=\"mdi-emoticon-outline\"\n      ></v-icon-btn>\n\n      <v-icon-btn\n        v-model:active=\"share\"\n        :class=\"!share ? 'mx-1' : undefined\"\n        :rounded=\"!share ? 'circle' : 'lg'\"\n        :width=\"share ? 56 : 48\"\n        active-color=\"#9bbbef\"\n        active-icon=\"mdi-arrow-up-bold-box\"\n        height=\"48\"\n        icon=\"mdi-arrow-up-bold-box-outline\"\n        @click=\"onClick\"\n      ></v-icon-btn>\n\n      <v-icon-btn\n        v-model:active=\"raised\"\n        :class=\"!raised ? 'mx-1' : undefined\"\n        :rounded=\"!raised ? 'circle' : 'lg'\"\n        :width=\"raised ? 56 : 48\"\n        active-color=\"#9bbbef\"\n        active-icon=\"mdi-hand-back-right\"\n        height=\"48\"\n        icon=\"mdi-hand-back-right-outline\"\n      ></v-icon-btn>\n\n      <v-icon-btn\n        height=\"48\"\n        icon=\"mdi-dots-vertical\"\n        rounded=\"xl\"\n        variant=\"tonal\"\n      >\n        <v-icon></v-icon>\n\n        <v-menu activator=\"parent\" location=\"top end\" offset=\"4\">\n          <v-list rounded=\"lg\" slim>\n            <v-list-item\n              prepend-icon=\"mdi-radiobox-marked\"\n              title=\"Manage recording\"\n              link\n            ></v-list-item>\n\n            <v-divider class=\"my-2\"></v-divider>\n\n            <v-list-item\n              prepend-icon=\"mdi-view-grid-outline\"\n              title=\"Change layout\"\n              link\n            ></v-list-item>\n\n            <v-list-item\n              prepend-icon=\"mdi-fullscreen\"\n              title=\"Full screen\"\n              link\n            ></v-list-item>\n\n            <v-list-item\n              prepend-icon=\"mdi-share-variant-outline\"\n              title=\"Share screen\"\n              link\n            ></v-list-item>\n\n            <v-divider class=\"my-2\"></v-divider>\n\n            <v-list-item\n              prepend-icon=\"mdi-cog-outline\"\n              title=\"Settings\"\n              link\n            ></v-list-item>\n          </v-list>\n        </v-menu>\n      </v-icon-btn>\n\n      <v-icon-btn\n        v-model:active=\"hangup\"\n        active-variant=\"outlined\"\n        base-variant=\"flat\"\n        color=\"error\"\n        height=\"48\"\n        icon=\"mdi-phone-hangup-outline\"\n        rounded=\"xl\"\n        width=\"72\"\n      ></v-icon-btn>\n    </v-sheet>\n  </v-container>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const caption = shallowRef(false)\n  const emoji = shallowRef(false)\n  const hangup = shallowRef(false)\n  const mic = shallowRef(true)\n  const micOptions = shallowRef(false)\n  const raised = shallowRef(false)\n  const share = shallowRef(false)\n  const video = shallowRef(true)\n  const videoOptions = shallowRef(false)\n\n  function onClick () {\n    console.log('Sharing your screen')\n  }\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        caption: false,\n        emoji: false,\n        raised: false,\n        share: false,\n        mic: true,\n        micOptions: false,\n        video: true,\n        videoOptions: false,\n      }\n    },\n    methods: {\n      onClick () {\n        console.log('Sharing your screen')\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-icon-btn/prop-active.vue",
    "content": "<template>\n  <v-toolbar class=\"px-3 mx-auto\" rounded=\"pill\" title=\"Toolbar\">\n    <template v-slot:append>\n      <v-icon-btn :active=\"menu\" active-color=\"surface-variant\" icon=\"mdi-dots-vertical\">\n        <v-icon></v-icon>\n\n        <v-menu v-model=\"menu\" activator=\"parent\" location=\"bottom end\" offset=\"4\">\n          <v-list\n            bg-color=\"surface-light\"\n            class=\"d-flex flex-column ga-1 pa-1\"\n            density=\"compact\"\n            rounded=\"lg\"\n            variant=\"text\"\n            slim\n          >\n            <v-list-item\n              prepend-icon=\"mdi-account-circle-outline\"\n              rounded=\"lg\"\n              title=\"Account\"\n              link\n            ></v-list-item>\n\n            <v-list-item\n              prepend-icon=\"mdi-cog-outline\"\n              rounded=\"lg\"\n              title=\"Settings\"\n              link\n            ></v-list-item>\n\n            <v-list-item\n              prepend-icon=\"mdi-logout-variant\"\n              rounded=\"lg\"\n              title=\"Logout\"\n              link\n            ></v-list-item>\n          </v-list>\n        </v-menu>\n      </v-icon-btn>\n    </template>\n  </v-toolbar>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const menu = shallowRef(false)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        menu: false,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-icon-btn/prop-opacity.vue",
    "content": "<template>\n  <v-text-field\n    class=\"mx-auto\"\n    hide-details=\"auto\"\n    label=\"Search\"\n    max-width=\"200\"\n    variant=\"outlined\"\n  >\n    <template v-slot:append-inner>\n      <v-icon-btn\n        :opacity=\"dialog ? 1 : 0.32\"\n        icon=\"mdi-magnify\"\n        @click.stop\n        @mousedown.stop\n      >\n        <v-icon></v-icon>\n\n        <v-dialog v-model=\"dialog\" activator=\"parent\" width=\"400\">\n          <v-card title=\"Find in page\">\n            <v-card-text>\n              <v-text-field hide-details=\"auto\" label=\"Search\"></v-text-field>\n            </v-card-text>\n\n            <template v-slot:actions>\n              <v-btn text=\"Cancel\" variant=\"plain\" @click=\"dialog = false\"></v-btn>\n\n              <v-btn text=\"Search\" @click=\"dialog = false\"></v-btn>\n            </template>\n          </v-card>\n        </v-dialog>\n      </v-icon-btn>\n    </template>\n  </v-text-field>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const dialog = shallowRef(false)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        dialog: false,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-icon-btn/prop-rotate.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-menu>\n      <template v-slot:activator=\"{ props: activatorProps, isActive }\">\n        <v-btn v-bind=\"activatorProps\" text=\"Toggle\">\n          <template v-slot:append>\n            <v-icon-btn\n              :rotate=\"isActive ? 180 : 0\"\n              icon=\"$dropdown\"\n              size=\"16\"\n              variant=\"plain\"\n              hide-overlay\n            ></v-icon-btn>\n          </template>\n        </v-btn>\n      </template>\n\n      <v-list>\n        <v-list-item title=\"Item 1\" link></v-list-item>\n        <v-list-item title=\"Item 2\" link></v-list-item>\n        <v-list-item title=\"Item 3\" link></v-list-item>\n      </v-list>\n    </v-menu>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-icon-btn/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div class=\"text-center\">\n      <v-icon-btn v-bind=\"props\" v-ripple=\"ripple\"></v-icon-btn>\n    </div>\n\n    <template v-slot:configuration>\n      <v-select\n        v-model=\"color\"\n        :items=\"['primary', 'secondary', 'accent', 'error', 'warning', 'info', 'success']\"\n        label=\"Color\"\n        clearable\n      ></v-select>\n\n      <v-select\n        v-model=\"size\"\n        :items=\"['x-small', 'small', 'default', 'large', 'x-large']\"\n        label=\"Size\"\n        clearable\n      ></v-select>\n\n      <v-select\n        v-model=\"icon\"\n        :items=\"['$vuetify', 'mdi-lightning-bolt', 'mdi-account-outline', 'mdi-cog-outline', 'mdi-heart-outline']\"\n        :list-props=\"{ slim: true }\"\n        label=\"Icon\"\n      >\n        <template v-slot:item=\"{ props: itemProps, item }\">\n          <v-list-item v-bind=\"itemProps\" :prepend-icon=\"item.title\"></v-list-item>\n        </template>\n      </v-select>\n\n      <v-checkbox-btn v-model=\"loading\" label=\"Loading\"></v-checkbox-btn>\n\n      <v-checkbox-btn v-model=\"hideOverlay\" label=\"Hide overlay\"></v-checkbox-btn>\n\n      <v-checkbox-btn v-model=\"ripple\" label=\"Ripple\"></v-checkbox-btn>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const variants = ['outlined', 'tonal', 'flat', 'text', 'plain']\n  const name = 'v-icon-btn'\n  const model = shallowRef('default')\n  const color = shallowRef()\n  const hideOverlay = shallowRef(false)\n  const icon = shallowRef('$vuetify')\n  const ripple = shallowRef(false)\n  const loading = shallowRef(false)\n  const size = shallowRef('default')\n  const options = [...variants]\n  const props = computed(() => {\n    return {\n      color: color.value || undefined,\n      'hide-overlay': hideOverlay.value || undefined,\n      icon: icon.value || undefined,\n      loading: loading.value || undefined,\n      size: size.value !== 'default' ? size.value : undefined,\n      variant: model.value !== 'default' ? model.value : undefined,\n      'v-ripple': ripple.value || undefined,\n    }\n  })\n\n  const slots = computed(() => {\n    return ``\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-img/complex-grid.vue",
    "content": "<template>\n  <v-row>\n    <template v-for=\"(image,imgIdx) in imageLayout\" :key=\"imgIdx\">\n      <v-col :cols=\"image.cols\">\n        <v-img\n          :src=\"`https://picsum.photos/500/300?image=${image.cols * 20}`\"\n          height=\"100%\"\n          cover\n        ></v-img>\n      </v-col>\n\n      <v-col v-if=\"image.children\" class=\"d-flex flex-column\" cols=\"6\">\n        <v-row>\n          <v-col v-for=\"(children,childIdx) in image.children\" :key=\"childIdx\" :cols=\"children.cols\">\n            <v-img\n              :src=\"`https://picsum.photos/500/300?image=${children.cols + childIdx}`\"\n              height=\"100%\"\n              cover\n            ></v-img>\n          </v-col>\n        </v-row>\n      </v-col>\n    </template>\n  </v-row>\n</template>\n\n<script setup>\n  const imageLayout = [\n    { cols: 4 },\n    {\n      cols: 8,\n      children: [{ cols: 12 }, { cols: 12 }],\n    },\n    { cols: 6 },\n    { cols: 3 },\n    { cols: 9 },\n    { cols: 4 },\n    { cols: 8 },\n  ]\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-img/misc-grid.vue",
    "content": "<template>\n  <v-row>\n    <v-col\n      v-for=\"n in 9\"\n      :key=\"n\"\n      class=\"d-flex child-flex\"\n      cols=\"4\"\n    >\n      <v-img\n        :lazy-src=\"`https://picsum.photos/10/6?image=${n * 5 + 10}`\"\n        :src=\"`https://picsum.photos/500/300?image=${n * 5 + 10}`\"\n        aspect-ratio=\"1\"\n        class=\"bg-grey-lighten-2\"\n        cover\n      >\n        <template v-slot:placeholder>\n          <v-row class=\"fill-height align-center justify-center\">\n            <v-progress-circular\n              color=\"grey-lighten-5\"\n              indeterminate\n            ></v-progress-circular>\n          </v-row>\n        </template>\n      </v-img>\n    </v-col>\n  </v-row>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-img/prop-contain.vue",
    "content": "<template>\n  <v-container fluid>\n    <v-row class=\"justify-space-around\">\n      <v-col cols=\"5\">\n        <div class=\"text-title-large mb-1\">\n          Default (cover)\n        </div>\n        <div class=\"subheading\">\n          Matching\n        </div>\n        <v-img\n          aspect-ratio=\"1.7\"\n          src=\"https://picsum.photos/510/300?random\"\n        ></v-img>\n        <div class=\"subheading pt-4\">\n          Too high\n        </div>\n        <v-img\n          aspect-ratio=\"2\"\n          src=\"https://picsum.photos/510/300?random\"\n        ></v-img>\n        <div class=\"subheading pt-4\">\n          Too low\n        </div>\n        <v-img\n          aspect-ratio=\"1.4\"\n          src=\"https://picsum.photos/510/300?random\"\n        ></v-img>\n      </v-col>\n\n      <v-col cols=\"5\">\n        <div class=\"text-title-large mb-1\">\n          Contain\n        </div>\n        <div class=\"subheading\">\n          Matching\n        </div>\n        <v-img\n          aspect-ratio=\"1.7\"\n          src=\"https://picsum.photos/510/300?random\"\n        ></v-img>\n        <div class=\"subheading pt-4\">\n          Too high\n        </div>\n        <v-img\n          aspect-ratio=\"2\"\n          src=\"https://picsum.photos/510/300?random\"\n        ></v-img>\n        <div class=\"subheading pt-4\">\n          Too low\n        </div>\n        <v-img\n          aspect-ratio=\"1.4\"\n          src=\"https://picsum.photos/510/300?random\"\n        ></v-img>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-img/prop-cover.vue",
    "content": "<template>\n  <div class=\"d-flex justify-space-around align-center\">\n    <div class=\"ma-4\">\n      <div class=\"text-title-small\">Default</div>\n      <v-img\n        :aspect-ratio=\"1\"\n        class=\"bg-surface elevation-3\"\n        src=\"https://cdn.vuetifyjs.com/images/parallax/material.jpg\"\n        width=\"300\"\n      ></v-img>\n    </div>\n\n    <div class=\"ma-4\">\n      <div class=\"text-title-small\">Cover</div>\n      <v-img\n        :aspect-ratio=\"1\"\n        class=\"bg-surface elevation-3\"\n        src=\"https://cdn.vuetifyjs.com/images/parallax/material.jpg\"\n        width=\"300\"\n        cover\n      ></v-img>\n    </div>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-img/prop-gradient.vue",
    "content": "<template>\n  <v-row>\n    <v-col\n      cols=\"6\"\n      sm=\"4\"\n    >\n      <v-img\n        gradient=\"to top right, rgba(100,115,201,.33), rgba(25,32,72,.7)\"\n        src=\"https://cdn.vuetifyjs.com/images/parallax/material2.jpg\"\n      ></v-img>\n    </v-col>\n\n    <v-col\n      cols=\"6\"\n      sm=\"4\"\n    >\n      <v-img src=\"https://cdn.vuetifyjs.com/images/parallax/material2.jpg\">\n        <div class=\"fill-height bottom-gradient\"></div>\n      </v-img>\n    </v-col>\n\n    <v-col\n      cols=\"6\"\n      sm=\"4\"\n    >\n      <v-img src=\"https://cdn.vuetifyjs.com/images/parallax/material2.jpg\">\n        <div class=\"fill-height repeating-gradient\"></div>\n      </v-img>\n    </v-col>\n  </v-row>\n</template>\n\n<style scoped>\n  .bottom-gradient {\n    background-image: linear-gradient(to top, rgba(0, 0, 0, 0.4) 0%, transparent 72px);\n  }\n\n  .repeating-gradient {\n    background-image: repeating-linear-gradient(-45deg,\n                        rgba(255,0,0,.25),\n                        rgba(255,0,0,.25) 5px,\n                        rgba(0,0,255,.25) 5px,\n                        rgba(0,0,255,.25) 10px\n                      );\n  }\n</style>\n"
  },
  {
    "path": "packages/docs/src/examples/v-img/prop-image-class.vue",
    "content": "<template>\n  <v-row>\n    <v-col cols=\"12\" sm=\"6\">\n      <v-img\n        class=\"border-dotted\"\n        height=\"300\"\n        image-class=\"transition-400 hover:scale-110 hover:rotate-2\"\n        src=\"https://picsum.photos/400/600?image=136\"\n      ></v-img>\n    </v-col>\n\n    <v-col cols=\"12\" sm=\"6\">\n      <v-img\n        class=\"border-dotted\"\n        color=\"yellow\"\n        height=\"300\"\n        image-class=\"transition-400 hover:scale-90 rounded-pill elevation-2\"\n        rounded=\"pill\"\n        src=\"https://picsum.photos/400/400?image=128\"\n        cover\n      ></v-img>\n    </v-col>\n  </v-row>\n</template>\n\n<style scoped>\n  /* expected to be generated by UnoCSS */\n  ::v-deep(.transition-400) { transition: all .4s cubic-bezier(0.4, 0, 0.2, 1); }\n  ::v-deep(.hover\\:scale-90:hover) { scale: 90%; }\n  ::v-deep(.hover\\:scale-110:hover) { scale: 110%; }\n  ::v-deep(.hover\\:rotate-2:hover) { transform: rotate(2deg); }\n</style>\n"
  },
  {
    "path": "packages/docs/src/examples/v-img/prop-max-height.vue",
    "content": "<template>\n  <v-container\n    class=\"fill-height\"\n    style=\"min-height: 434px\"\n    fluid\n  >\n    <v-fade-transition mode=\"out-in\">\n      <v-row>\n        <v-col cols=\"6\">\n          <v-card>\n            <v-img\n              class=\"bg-grey-lighten-2\"\n              height=\"125\"\n              src=\"https://picsum.photos/350/165?random\"\n            ></v-img>\n            <v-card-title class=\"text-title-medium py-3\">\n              height\n            </v-card-title>\n          </v-card>\n        </v-col>\n\n        <v-col cols=\"6\">\n          <v-card>\n            <v-img\n              class=\"bg-grey-lighten-2\"\n              height=\"125\"\n              src=\"https://picsum.photos/350/165?random\"\n              cover\n            ></v-img>\n            <v-card-title class=\"text-title-medium py-3\">\n              height with cover\n            </v-card-title>\n          </v-card>\n        </v-col>\n\n        <v-col cols=\"6\">\n          <v-card>\n            <v-img\n              class=\"bg-grey-lighten-2\"\n              max-height=\"125\"\n              src=\"https://picsum.photos/350/165?random\"\n            ></v-img>\n            <v-card-title class=\"text-title-medium py-3\">\n              max-height\n            </v-card-title>\n          </v-card>\n        </v-col>\n\n        <v-col cols=\"6\">\n          <v-card>\n            <v-img\n              class=\"bg-grey-lighten-2\"\n              max-height=\"125\"\n              src=\"https://picsum.photos/350/165?random\"\n              cover\n            ></v-img>\n            <v-card-title class=\"text-title-medium py-3\">\n              max-height with cover\n            </v-card-title>\n          </v-card>\n        </v-col>\n      </v-row>\n    </v-fade-transition>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-img/prop-rounded.vue",
    "content": "<template>\n  <v-row class=\"align-stretch\">\n    <v-col cols=\"12\" sm=\"6\">\n      <v-img\n        color=\"red\"\n        height=\"180\"\n        rounded=\"xl\"\n        src=\"https://picsum.photos/300/180?image=503\"\n      ></v-img>\n      <h4 class=\"my-0 text-center\">height</h4>\n    </v-col>\n    <v-col cols=\"12\" sm=\"6\">\n      <v-img\n        color=\"red\"\n        height=\"180\"\n        rounded=\"xl\"\n        src=\"https://picsum.photos/300/180?image=503\"\n        cover\n      ></v-img>\n      <h4 class=\"my-0 text-center\">height with cover</h4>\n    </v-col>\n    <v-col cols=\"12\" sm=\"6\">\n      <v-img\n        class=\"mx-auto\"\n        rounded=\"xl\"\n        src=\"https://picsum.photos/300/180?image=503\"\n        width=\"fit-content\"\n      ></v-img>\n      <h4 class=\"my-0 text-center\">width=\"fit-content\"</h4>\n    </v-col>\n  </v-row>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-img/slot-error.vue",
    "content": "<template>\n  <v-img\n    class=\"mx-auto\"\n    height=\"300\"\n    max-width=\"500\"\n    src=\"https://bad.src/not/valid\"\n  >\n    <template v-slot:error>\n      <v-img\n        class=\"mx-auto\"\n        height=\"300\"\n        max-width=\"500\"\n        src=\"https://picsum.photos/500/300?image=232\"\n      ></v-img>\n    </template>\n  </v-img>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-img/slot-placeholder.vue",
    "content": "<template>\n  <v-img\n    class=\"mx-auto\"\n    height=\"300\"\n    lazy-src=\"https://picsum.photos/id/11/100/60\"\n    max-width=\"500\"\n    src=\"https://bad.src/not/valid\"\n  >\n    <template v-slot:placeholder>\n      <div class=\"d-flex align-center justify-center fill-height\">\n        <v-progress-circular\n          color=\"grey-lighten-4\"\n          indeterminate\n        ></v-progress-circular>\n      </div>\n    </template>\n  </v-img>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-img/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div>\n      <v-img\n        v-bind=\"props\"\n        :aspect-ratio=\"aspectRatio.value\"\n        class=\"mx-auto\"\n      ></v-img>\n    </div>\n\n    <template v-slot:configuration>\n\n      <v-select\n        v-model=\"aspectRatio\"\n        :items=\"aspectRatios\"\n        label=\"Aspect ratio\"\n        return-object\n      ></v-select>\n\n      <v-slider\n        v-model=\"width\"\n        label=\"Width\"\n        max=\"400\"\n        min=\"100\"\n      ></v-slider>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-img'\n  const model = ref('default')\n  const width = ref(300)\n  const aspectRatio = ref({ title: '16/9', value: 16 / 9 })\n  const aspectRatios = [\n    { title: '16/9', value: 16 / 9 },\n    { title: '4/3', value: 4 / 3 },\n    { title: '1/1', value: 1 },\n  ]\n  const options = []\n\n  const props = computed(() => {\n    return {\n      width: width.value,\n      'aspect-ratio': aspectRatio.value.title,\n      cover: true,\n      src: 'https://cdn.vuetifyjs.com/images/parallax/material.jpg',\n    }\n  })\n\n  const slots = computed(() => {\n    return ''\n  })\n\n  const code = computed(() => {\n    return `<v-img${propsToString(props.value)}>${slots.value}</v-img>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-infinite-scroll/misc-reset.vue",
    "content": "<template>\n  <v-container>\n    <div class=\"d-flex ga-3 mb-2\">\n      <v-chip>Server items: {{ serverItems.length }}</v-chip>\n      <v-chip>Loaded items: {{ items.length }}</v-chip>\n      <v-spacer></v-spacer>\n      <v-checkbox v-model=\"showEmptyText\" hide-details=\"\" label=\"show empty text\"></v-checkbox>\n    </div>\n    <v-infinite-scroll\n      ref=\"scroll\"\n      :empty-text=\"showEmptyText ? 'No more records' : ''\"\n      height=\"300\"\n      side=\"both\"\n      @load=\"load\"\n    >\n      <template v-for=\"(item, index) in items\" :key=\"index\">\n        <div :class=\"['px-2', index % 2 === 0 ? 'bg-grey-lighten-2' : '']\">\n          Item number {{ item }}\n        </div>\n      </template>\n    </v-infinite-scroll>\n\n    <div class=\"d-flex ga-3 mt-2\">\n      <v-btn @click=\"prependFewMore(); reset('start')\">prepend items + reset('start')</v-btn>\n      <v-btn @click=\"appendFewMore(); reset('end')\">append items + reset('end')</v-btn>\n      <v-btn @click=\"reset()\">just reset()</v-btn>\n    </div>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref, useTemplateRef } from 'vue'\n\n  const infiniteScrollRef = useTemplateRef('scroll')\n\n  const items = ref([])\n  const showEmptyText = ref(false)\n\n  let firstId = 0\n  let lastId = 0\n  const serverItems = ref(Array.from({ length: 30 }, () => ++lastId))\n\n  function prependFewMore () {\n    serverItems.value = [...serverItems.value, ...Array.from({ length: 6 }, () => --firstId)]\n  }\n\n  function appendFewMore () {\n    serverItems.value = [...serverItems.value, ...Array.from({ length: 6 }, () => ++lastId)]\n  }\n\n  function reset (side) {\n    infiniteScrollRef.value?.reset(side)\n  }\n\n  async function load ({ side, done }) {\n    await new Promise(resolve => setTimeout(resolve, 500))\n\n    let page = []\n    if (side === 'start') {\n      page = loadPreviousPage()\n      if (page.length) {\n        items.value = [...page, ...items.value]\n      }\n    }\n    if (side === 'end') {\n      page = loadNextPage()\n      if (page.length) {\n        items.value = [...items.value, ...page]\n      }\n    }\n    done(page.length === 10 ? 'ok' : 'empty')\n  }\n\n  function loadPreviousPage () {\n    const cursor = items.value.at(0) ?? 0\n    return serverItems.value.filter(x => x < cursor).reverse().slice(0, 10)\n  }\n\n  function loadNextPage () {\n    const cursor = items.value.at(-1) ?? 0\n    return serverItems.value.filter(x => x > cursor).slice(0, 10)\n  }\n</script>\n\n<script>\n  let firstId = 0\n  let lastId = 0\n  export default {\n    data: () => {\n      return {\n        items: [],\n        showEmptyText: false,\n        serverItems: Array.from({ length: 30 }, () => ++lastId),\n      }\n    },\n    methods: {\n      prependFewMore () {\n        this.serverItems = [...this.serverItems, ...Array.from({ length: 6 }, () => --firstId)]\n      },\n      appendFewMore () {\n        this.serverItems = [...this.serverItems, ...Array.from({ length: 6 }, () => ++lastId)]\n      },\n      reset (side) {\n        this.$refs.scroll.reset(side)\n      },\n      async load ({ side, done }) {\n        await new Promise(resolve => setTimeout(resolve, 500))\n\n        let page = []\n        if (side === 'start') {\n          page = this.loadPreviousPage()\n          if (page.length) {\n            this.items = [...page, ...this.items]\n          }\n        }\n        if (side === 'end') {\n          page = this.loadNextPage()\n          if (page.length) {\n            this.items = [...this.items, ...page]\n          }\n        }\n        done(page.length === 10 ? 'ok' : 'empty')\n      },\n\n      loadPreviousPage () {\n        const cursor = this.items.at(0) ?? 0\n        return this.serverItems.filter(x => x < cursor).reverse().slice(0, 10)\n      },\n\n      loadNextPage () {\n        const cursor = this.items.at(-1) ?? 0\n        return this.serverItems.filter(x => x > cursor).slice(0, 10)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-infinite-scroll/misc-virtual.vue",
    "content": "<template>\n  <v-infinite-scroll\n    ref=\"infinite\"\n    height=\"500\"\n    side=\"both\"\n    @load=\"load\"\n  >\n    <div>\n      <template v-for=\"card in cards\" :key=\"card\">\n        <v-sheet\n          :color=\"card % 2 === 0 ? 'primary' : card % 4 === 0 ? 'secondary' : 'warning'\"\n          :height=\"size\"\n          class=\"d-flex align-center justify-center\"\n        >\n          <div>{{ card }}</div>\n        </v-sheet>\n      </template>\n    </div>\n  </v-infinite-scroll>\n</template>\n\n<script setup>\n  import { nextTick, ref } from 'vue'\n\n  const infinite = ref()\n\n  const size = ref(300)\n  const virtualLength = ref(12)\n  const cards = ref([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])\n\n  function createRange (length, start) {\n    return Array.from({ length }).map((_, i) => i + start)\n  }\n  function load ({ side, done }) {\n    const halfVirtualLength = virtualLength.value / 2\n    if (side === 'start') {\n      const arr = createRange(halfVirtualLength, cards.value[0] - halfVirtualLength)\n      cards.value = [...arr, ...cards.value.slice(0, halfVirtualLength)]\n      nextTick(() => {\n        infinite.value.$el.scrollTop = infinite.value.$el.scrollHeight - (halfVirtualLength * size.value) - infinite.value.$el.scrollTop\n      })\n    } else {\n      const arr = createRange(halfVirtualLength, cards.value.at(-1) + 1)\n      cards.value = [...cards.value.slice(halfVirtualLength), ...arr]\n    }\n    done('ok')\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      size: 300,\n      virtualLength: 12,\n      cards: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],\n    }),\n\n    methods: {\n      createRange (length, start) {\n        return Array.from({ length }).map((_, i) => i + start)\n      },\n      load ({ side, done }) {\n        const halfVirtualLength = this.virtualLength / 2\n        if (side === 'start') {\n          const arr = this.createRange(halfVirtualLength, this.cards[0] - halfVirtualLength)\n          this.cards = [...arr, ...this.cards.slice(0, halfVirtualLength)]\n          this.$nextTick(() => {\n            this.$refs.infinite.$el.scrollTop = this.$refs.infinite.$el.scrollHeight - (halfVirtualLength * this.size) - this.$refs.infinite.$el.scrollTop\n          })\n        } else {\n          const arr = this.createRange(halfVirtualLength, this.cards.at(-1) + 1)\n          this.cards = [...this.cards.slice(halfVirtualLength), ...arr]\n        }\n\n        done('ok')\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-infinite-scroll/prop-color.vue",
    "content": "<template>\n  <v-infinite-scroll\n    color=\"secondary\"\n    height=\"400\"\n    mode=\"manual\"\n    @load=\"load\"\n  >\n    <template v-for=\"(item, index) in items\" :key=\"item\">\n      <div :class=\"['pa-2', index % 2 === 0 ? 'bg-grey-lighten-2' : '']\">\n        Item #{{ item }}\n      </div>\n    </template>\n  </v-infinite-scroll>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const items = ref(Array.from({ length: 50 }, (k, v) => v + 1))\n\n  function load ({ done }) {\n    setTimeout(() => {\n      items.value.push(...Array.from({ length: 10 }, (k, v) => v + items.value.at(-1) + 1))\n      done('ok')\n    }, 1000)\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: Array.from({ length: 50 }, (k, v) => v + 1),\n    }),\n\n    methods: {\n      load ({ done }) {\n        setTimeout(() => {\n          this.items.push(...Array.from({ length: 10 }, (k, v) => v + this.items.at(-1) + 1))\n\n          done('ok')\n        }, 1000)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-infinite-scroll/prop-direction.vue",
    "content": "<template>\n  <v-infinite-scroll\n    direction=\"horizontal\"\n    @load=\"load\"\n  >\n    <template v-for=\"(item, index) in items\" :key=\"item\">\n      <div :class=\"['pa-2', index % 2 === 0 ? 'bg-grey-lighten-2' : '']\">\n        Item #{{ item }}\n      </div>\n    </template>\n  </v-infinite-scroll>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const items = ref(Array.from({ length: 50 }, (k, v) => v + 1))\n\n  function load ({ done }) {\n    setTimeout(() => {\n      items.value.push(...Array.from({ length: 10 }, (k, v) => v + items.value.at(-1) + 1))\n      done('ok')\n    }, 1000)\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: Array.from({ length: 50 }, (k, v) => v + 1),\n    }),\n\n    methods: {\n      load ({ done }) {\n        setTimeout(() => {\n          this.items.push(...Array.from({ length: 10 }, (k, v) => v + this.items.at(-1) + 1))\n\n          done('ok')\n        }, 1000)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-infinite-scroll/prop-mode.vue",
    "content": "<template>\n  <v-infinite-scroll\n    height=\"300\"\n    mode=\"manual\"\n    @load=\"load\"\n  >\n    <template v-for=\"(item, index) in items\" :key=\"item\">\n      <div :class=\"['px-2', index % 2 === 0 ? 'bg-grey-lighten-2' : '']\">\n        Item number {{ item }}\n      </div>\n    </template>\n  </v-infinite-scroll>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const items = ref(Array.from({ length: 50 }, (k, v) => v + 1))\n  function load ({ done }) {\n    setTimeout(() => {\n      items.value.push(...Array.from({ length: 10 }, (k, v) => v + items.value.at(-1) + 1))\n      done('ok')\n    }, 1000)\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: Array.from({ length: 50 }, (k, v) => v + 1),\n    }),\n\n    methods: {\n      load ({ done }) {\n        setTimeout(() => {\n          this.items.push(...Array.from({ length: 10 }, (k, v) => v + this.items.at(-1) + 1))\n\n          done('ok')\n        }, 1000)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-infinite-scroll/prop-side-both.vue",
    "content": "<template>\n  <v-infinite-scroll\n    height=\"300\"\n    side=\"both\"\n    @load=\"load\"\n  >\n    <template v-for=\"(item, index) in items\" :key=\"item\">\n      <div :class=\"['px-2', index % 2 === 0 ? 'bg-grey-lighten-2' : '']\">\n        Item number {{ item }}\n      </div>\n    </template>\n  </v-infinite-scroll>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const items = ref(Array.from({ length: 50 }, (k, v) => v + 1))\n  function load ({ side, done }) {\n    setTimeout(() => {\n      if (side === 'start') {\n        const arr = Array.from({ length: 10 }, (k, v) => items.value[0] - (10 - v))\n        items.value = [...arr, ...items.value]\n      } else if (side === 'end') {\n        const arr = Array.from({ length: 10 }, (k, v) => items.value.at(-1) + 1 + v)\n        items.value = [...items.value, ...arr]\n      }\n      done('ok')\n    }, 1000)\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: Array.from({ length: 50 }, (k, v) => v + 1),\n    }),\n\n    methods: {\n      load ({ side, done }) {\n        setTimeout(() => {\n          if (side === 'start') {\n            const arr = Array.from({ length: 10 }, (k, v) => this.items[0] - (10 - v))\n            this.items = [...arr, ...this.items]\n          } else if (side === 'end') {\n            const arr = Array.from({ length: 10 }, (k, v) => this.items.at(-1) + 1 + v)\n            this.items = [...this.items, ...arr]\n          }\n\n          done('ok')\n        }, 1000)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-infinite-scroll/prop-side-start.vue",
    "content": "<template>\n  <v-infinite-scroll\n    height=\"300\"\n    side=\"start\"\n    @load=\"load\"\n  >\n    <template v-for=\"(item, index) in items\" :key=\"item\">\n      <div :class=\"['px-2', index % 2 === 0 ? 'bg-grey-lighten-2' : '']\">\n        Item number {{ item }}\n      </div>\n    </template>\n  </v-infinite-scroll>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const items = ref(Array.from({ length: 50 }, (k, v) => v + 1))\n  function load ({ done }) {\n    setTimeout(() => {\n      items.value.unshift(...Array.from({ length: 10 }, (k, v) => items.value[0] - (10 - v)))\n      done('ok')\n    }, 1000)\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: Array.from({ length: 50 }, (k, v) => v + 1),\n    }),\n\n    methods: {\n      load ({ done }) {\n        setTimeout(() => {\n          this.items.unshift(...Array.from({ length: 10 }, (k, v) => this.items[0] - (10 - v)))\n\n          done('ok')\n        }, 1000)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-infinite-scroll/slot-empty.vue",
    "content": "<template>\n  <v-infinite-scroll\n    height=\"400\"\n    @load=\"load\"\n  >\n    <template v-for=\"(item, index) in items\" :key=\"item\">\n      <div :class=\"['pa-2', index % 2 === 0 ? 'bg-grey-lighten-2' : '']\">\n        Item #{{ item }}\n      </div>\n    </template>\n    <template v-slot:empty>\n      <v-alert type=\"warning\">No more items!</v-alert>\n    </template>\n  </v-infinite-scroll>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const items = ref(Array.from({ length: 50 }, (k, v) => v + 1))\n  function load ({ done }) {\n    setTimeout(() => {\n      done('empty')\n    }, 1000)\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: Array.from({ length: 50 }, (k, v) => v + 1),\n    }),\n\n    methods: {\n      load ({ done }) {\n        setTimeout(() => {\n          done('empty')\n        }, 1000)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-infinite-scroll/slot-error.vue",
    "content": "<template>\n  <v-infinite-scroll\n    height=\"400\"\n    @load=\"load\"\n  >\n    <template v-for=\"(item, index) in items\" :key=\"item\">\n      <div :class=\"['pa-2', index % 2 === 0 ? 'bg-grey-lighten-2' : '']\">\n        Item #{{ item }}\n      </div>\n    </template>\n    <template v-slot:error=\"{ props }\">\n      <v-alert type=\"error\">\n        <div class=\"d-flex justify-space-between align-center\">\n          Something went wrong...\n          <v-btn\n            color=\"white\"\n            size=\"small\"\n            variant=\"outlined\"\n            v-bind=\"props\"\n          >\n            Retry\n          </v-btn>\n        </div>\n      </v-alert>\n    </template>\n  </v-infinite-scroll>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const items = ref(Array.from({ length: 50 }, (k, v) => v + 1))\n  function load ({ done }) {\n    setTimeout(() => {\n      done('error')\n    }, 2000)\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: Array.from({ length: 50 }, (k, v) => v + 1),\n    }),\n\n    methods: {\n      load ({ done }) {\n        setTimeout(() => {\n          done('error')\n        }, 2000)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-infinite-scroll/slot-load-more.vue",
    "content": "<template>\n  <v-infinite-scroll\n    height=\"400\"\n    mode=\"manual\"\n    @load=\"load\"\n  >\n    <template v-for=\"(item, index) in items\" :key=\"item\">\n      <div :class=\"['pa-2', index % 2 === 0 ? 'bg-grey-lighten-2' : '']\">\n        Item #{{ item }}\n      </div>\n    </template>\n    <template v-slot:load-more=\"{ props }\">\n      <v-btn\n        icon=\"mdi-refresh\"\n        size=\"small\"\n        variant=\"text\"\n        v-bind=\"props\"\n      ></v-btn>\n    </template>\n  </v-infinite-scroll>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const items = ref(Array.from({ length: 50 }, (k, v) => v + 1))\n  function load ({ done }) {\n    setTimeout(() => {\n      items.value.push(...Array.from({ length: 10 }, (k, v) => v + items.value.at(-1) + 1))\n      done('ok')\n    }, 1000)\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: Array.from({ length: 50 }, (k, v) => v + 1),\n    }),\n\n    methods: {\n      load ({ done }) {\n        setTimeout(() => {\n          this.items.push(...Array.from({ length: 10 }, (k, v) => v + this.items.at(-1) + 1))\n\n          done('ok')\n        }, 1000)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-infinite-scroll/slot-loading.vue",
    "content": "<template>\n  <v-infinite-scroll\n    height=\"400\"\n    @load=\"load\"\n  >\n    <template v-for=\"(item, index) in items\" :key=\"item\">\n      <div :class=\"['pa-2', index % 2 === 0 ? 'bg-grey-lighten-2' : '']\">\n        Item #{{ item }}\n      </div>\n    </template>\n    <template v-slot:loading>\n      This is taking a very long time...\n    </template>\n  </v-infinite-scroll>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const items = ref(Array.from({ length: 50 }, (k, v) => v + 1))\n  function load ({ done }) {\n    setTimeout(() => {\n      items.value.push(...Array.from({ length: 10 }, (k, v) => v + items.value.at(-1) + 1))\n      done('ok')\n    }, 4000)\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: Array.from({ length: 50 }, (k, v) => v + 1),\n    }),\n\n    methods: {\n      load ({ done }) {\n        setTimeout(() => {\n          this.items.push(...Array.from({ length: 10 }, (k, v) => v + this.items.at(-1) + 1))\n\n          done('ok')\n        }, 4000)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-infinite-scroll/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n    :script=\"script\"\n  >\n    <div>\n      <v-infinite-scroll\n        v-bind=\"props\"\n        @load=\"load\"\n      >\n        <template v-for=\"(item, index) in items\" :key=\"item\">\n          <div :class=\"['pa-2', index % 2 === 0 ? 'bg-grey-lighten-2' : '']\">\n            Item number {{ item }}\n          </div>\n        </template>\n      </v-infinite-scroll>\n    </div>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-infinite-scroll'\n  const model = ref('default')\n  const options = []\n  const items = ref(Array.from({ length: 30 }, (k, v) => v + 1))\n\n  function api () {\n    return new Promise(resolve => {\n      setTimeout(() => {\n        resolve(Array.from({ length: 10 }, (k, v) => v + items.value.at(-1) + 1))\n      }, 1000)\n    })\n  }\n\n  async function load ({ done }) {\n    // Perform API call\n    const res = await api()\n\n    items.value.push(...res)\n\n    done('ok')\n  }\n\n  const props = computed(() => {\n    return {\n      height: 300,\n      items: 'items',\n      onLoad: 'load',\n    }\n  })\n\n  const slots = computed(() => {\n    return `\n  <template v-for=\"(item, index) in items\" :key=\"item\">\n    <div :class=\"['pa-2', index % 2 === 0 ? 'bg-grey-lighten-2' : '']\">\n      Item number #{{ item }}\n    </div>\n  </template>\n`\n  })\n\n  const code = computed(() => {\n    return `<v-infinite-scroll>${slots.value}</v-infinite-scroll>`\n  })\n\n  const script = computed(() => {\n    return `<script setup>\n  import { ref } from 'vue'\n\n  const items = ref(Array.from({ length: 30 }, (k, v) => v + 1))\n\n  async function api () {\n    return new Promise(resolve => {\n      setTimeout(() => {\n        resolve(Array.from({ length: 10 }, (k, v) => v + items.value.at(-1) + 1))\n      }, 1000)\n    })\n  }\n  async function load ({ done }) {\n    // Perform API call\n    const res = await api()\n\n    items.value.push(...res)\n\n    done('ok')\n  }\n<` + '/script>'\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-input/event-slot-clicks.vue",
    "content": "<template>\n  <v-container\n    id=\"input-usage\"\n    fluid\n  >\n    <v-row>\n      <v-col cols=\"12\">\n        <v-input\n          :messages=\"['Messages']\"\n          append-icon=\"mdi-close\"\n          prepend-icon=\"mdi-phone\"\n          @click:append=\"appendIconCallback\"\n          @click:prepend=\"prependIconCallback\"\n        >\n          Default Slot\n        </v-input>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  function appendIconCallback () {\n    alert('click:append')\n  }\n  function prependIconCallback () {\n    alert('click:prepend')\n  }\n</script>\n\n<script>\n  export default {\n    methods: {\n      appendIconCallback () {\n        alert('click:append')\n      },\n      prependIconCallback () {\n        alert('click:prepend')\n      },\n    },\n  }\n</script>\n\n<style>\n  #input-usage .v-input__prepend-outer,\n  #input-usage .v-input__append-outer,\n  #input-usage .v-input__slot,\n  #input-usage .v-messages {\n    border: 1px dashed rgba(0,0,0, .4);\n  }\n</style>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2801-143731&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-input/prop-error-count.vue",
    "content": "<template>\n  <v-input\n    :error-messages=\"['Fatal error', 'Another error']\"\n    max-errors=\"2\"\n    disabled\n    error\n  >\n    Input\n  </v-input>\n</template>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2801-143985&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-input/prop-error.vue",
    "content": "<template>\n  <v-input\n    :error-messages=\"['Fatal error']\"\n    disabled\n    error\n  >\n    Input\n  </v-input>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-input/prop-hide-details.vue",
    "content": "<template>\n  <div>\n    <v-text-field\n      :rules=\"rules\"\n      hide-details=\"auto\"\n      label=\"Main input\"\n    ></v-text-field>\n    <v-text-field label=\"Another input\"></v-text-field>\n  </div>\n</template>\n\n<script setup>\n  const rules = [\n    value => !!value || 'Required.',\n    value => (value && value.length >= 3) || 'Min 3 characters',\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      rules: [\n        value => !!value || 'Required.',\n        value => (value && value.length >= 3) || 'Min 3 characters',\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-input/prop-hint.vue",
    "content": "<template>\n  <v-switch\n    v-model=\"showMessages\"\n    label=\"Show messages\"\n    hide-details\n  ></v-switch>\n  <v-input\n    :messages=\"messages\"\n    hint=\"I am hint\"\n    persistent-hint\n  >\n    Input\n  </v-input>\n</template>\n\n<script setup>\n  import { computed, ref } from 'vue'\n\n  const showMessages = ref(false)\n  const messages = computed(() => {\n    return showMessages.value ? ['Message'] : undefined\n  })\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      showMessages: false,\n    }),\n\n    computed: {\n      messages () {\n        return this.showMessages ? ['Message'] : undefined\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-input/prop-loading.vue",
    "content": "<template>\n  <v-text-field\n    color=\"success\"\n    disabled\n    loading\n  ></v-text-field>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-input/prop-rules.vue",
    "content": "<template>\n  <v-text-field :rules=\"rules\"></v-text-field>\n</template>\n\n<script setup>\n  const rules = [\n    value => !!value || 'Required.',\n    value => (value || '').length <= 20 || 'Max 20 characters',\n    value => {\n      const pattern = /^(([^<>()[\\]\\\\.,;:\\s@\"]+(\\.[^<>()[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$/\n      return pattern.test(value) || 'Invalid e-mail.'\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      rules: [\n        value => !!value || 'Required.',\n        value => (value || '').length <= 20 || 'Max 20 characters',\n        value => {\n          const pattern = /^(([^<>()[\\]\\\\.,;:\\s@\"]+(\\.[^<>()[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$/\n          return pattern.test(value) || 'Invalid e-mail.'\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-input/slot-append-and-prepend.vue",
    "content": "<template>\n  <v-text-field>\n    <template v-slot:append>\n      <v-icon color=\"red\">\n        mdi-plus\n      </v-icon>\n    </template>\n    <template v-slot:prepend>\n      <v-icon color=\"green\">\n        mdi-minus\n      </v-icon>\n    </template>\n  </v-text-field>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-input/usage.vue",
    "content": "<template>\n  <v-container\n    id=\"input-usage\"\n    fluid\n  >\n    <v-row>\n      <v-col cols=\"12\">\n        <v-input\n          :messages=\"['Messages']\"\n          append-icon=\"mdi-close\"\n          prepend-icon=\"mdi-phone\"\n        >\n          Default Slot\n        </v-input>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-intersect/prop-options.vue",
    "content": "<template>\n  <div>\n    <div class=\"d-flex align-center text-center justify-center\">\n      <v-avatar\n        :color=\"intersecting ? 'green-lighten-1' : 'red-darken-2'\"\n        class=\"me-3 swing-transition\"\n        size=\"32\"\n        variant=\"flat\"\n      ></v-avatar>\n    </div>\n\n    <v-sheet\n      class=\"overflow-y-auto\"\n      max-height=\"400\"\n    >\n      <v-sheet\n        class=\"d-flex align-center text-center pa-2\"\n        height=\"200vh\"\n      >\n        <v-card\n          class=\"mx-auto\"\n          max-width=\"336\"\n          v-intersect=\"{\n            handler: onIntersect,\n            options: {\n              threshold: [0, 0.5, 1.0]\n            }\n          }\"\n        >\n          <v-card-title>Card title</v-card-title>\n\n          <v-card-text>\n            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do\n            eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim\n            ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut\n            aliquip ex ea commodo consequat. Duis aute irure dolor in\n            reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla\n            pariatur. Excepteur sint occaecat cupidatat non proident, sunt in\n            culpa qui officia deserunt mollit anim id est laborum.\n          </v-card-text>\n        </v-card>\n      </v-sheet>\n    </v-sheet>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const intersecting = ref(false)\n  function onIntersect (isIntersecting, entries, observer) {\n    intersecting.value = entries[0].intersectionRatio >= 0.5\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      isIntersecting: false,\n    }),\n\n    methods: {\n      onIntersect (isIntersecting, entries, observer) {\n        // More information about these options\n        // is located here: https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API\n        this.isIntersecting = entries[0].intersectionRatio >= 0.5\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-intersect/usage.vue",
    "content": "<template>\n  <div>\n    <div class=\"d-flex align-center text-center justify-center\">\n      <v-avatar\n        :color=\"isIntersecting ? 'green-lighten-1' : 'red-darken-2'\"\n        class=\"me-3 swing-transition\"\n        size=\"32\"\n        variant=\"flat\"\n      ></v-avatar>\n    </div>\n\n    <v-sheet\n      class=\"overflow-y-auto\"\n      max-height=\"400\"\n    >\n      <v-sheet\n        class=\"d-flex align-center text-center pa-2\"\n        height=\"200vh\"\n      >\n        <v-card\n          class=\"mx-auto\"\n          max-width=\"336\"\n          v-intersect=\"onIntersect\"\n        >\n          <v-card-title>Card title</v-card-title>\n\n          <v-card-text>\n            Phasellus magna. Quisque rutrum. Nunc egestas, augue at pellentesque laoreet, felis eros vehicula leo, at malesuada velit leo quis pede. Aliquam lobortis. Quisque libero metus, condimentum nec, tempor a, commodo mollis, magna.\n\n            In turpis. In dui magna, posuere eget, vestibulum et, tempor auctor, justo. In turpis. Pellentesque dapibus hendrerit tortor. Ut varius tincidunt libero.\n          </v-card-text>\n        </v-card>\n      </v-sheet>\n    </v-sheet>\n  </div>\n</template>\n\n<script>\n  export default {\n    data: () => ({\n      isIntersecting: false,\n    }),\n\n    methods: {\n      onIntersect (isIntersecting, entries, observer) {\n        // More information about these options\n        // is located here: https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API\n        this.isIntersecting = isIntersecting\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-item-group/misc-selection.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"400\"\n  >\n    <v-container class=\"pa-1\">\n      <v-item-group\n        v-model=\"selection\"\n        multiple\n      >\n        <v-row>\n          <v-col\n            v-for=\"(item, i) in items\"\n            :key=\"i\"\n            cols=\"12\"\n            md=\"6\"\n          >\n            <v-item v-slot=\"{ isSelected, toggle }\">\n              <v-img\n                :src=\"`https://cdn.vuetifyjs.com/images/${item.src}`\"\n                class=\"text-right pa-2\"\n                height=\"150\"\n                cover\n                @click=\"toggle\"\n              >\n                <v-btn :icon=\"isSelected ? 'mdi-heart' : 'mdi-heart-outline'\"></v-btn>\n              </v-img>\n            </v-item>\n          </v-col>\n        </v-row>\n      </v-item-group>\n    </v-container>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const items = [\n    {\n      src: 'backgrounds/bg.jpg',\n    },\n    {\n      src: 'backgrounds/md.jpg',\n    },\n    {\n      src: 'backgrounds/bg-2.jpg',\n    },\n    {\n      src: 'backgrounds/md2.jpg',\n    },\n  ]\n\n  const selection = ref([])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        {\n          src: 'backgrounds/bg.jpg',\n        },\n        {\n          src: 'backgrounds/md.jpg',\n        },\n        {\n          src: 'backgrounds/bg-2.jpg',\n        },\n        {\n          src: 'backgrounds/md2.jpg',\n        },\n      ],\n      selection: [],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-item-group/prop-mandatory.vue",
    "content": "<template>\n  <v-item-group mandatory>\n    <v-container>\n      <v-row>\n        <v-col\n          v-for=\"n in 3\"\n          :key=\"n\"\n          cols=\"12\"\n          md=\"4\"\n        >\n          <v-item v-slot=\"{ isSelected, toggle }\">\n            <v-card\n              :color=\"isSelected ? 'primary' : ''\"\n              class=\"d-flex align-center\"\n              height=\"200\"\n              dark\n              @click=\"toggle\"\n            >\n              <v-scroll-y-transition>\n                <div\n                  class=\"text-display-medium flex-grow-1 text-center\"\n                >\n                  {{ isSelected ? 'Selected' : 'Click Me!' }}\n                </div>\n              </v-scroll-y-transition>\n            </v-card>\n          </v-item>\n        </v-col>\n      </v-row>\n    </v-container>\n  </v-item-group>\n</template>\n\n<script></script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-item-group/prop-multiple.vue",
    "content": "<template>\n  <v-item-group multiple>\n    <v-container>\n      <v-row>\n        <v-col\n          v-for=\"n in 3\"\n          :key=\"n\"\n          cols=\"12\"\n          md=\"4\"\n        >\n          <v-item v-slot=\"{ isSelected, toggle }\">\n            <v-card\n              :color=\"isSelected ? 'primary' : ''\"\n              class=\"d-flex align-center\"\n              height=\"200\"\n              dark\n              @click=\"toggle\"\n            >\n              <v-scroll-y-transition>\n                <div\n                  class=\"text-display-medium flex-grow-1 text-center\"\n                >\n                  {{ isSelected ? 'Selected' : 'Click Me!' }}\n                </div>\n              </v-scroll-y-transition>\n            </v-card>\n          </v-item>\n        </v-col>\n      </v-row>\n    </v-container>\n  </v-item-group>\n</template>\n\n<script></script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-item-group/prop-selected-class.vue",
    "content": "<template>\n  <v-item-group selected-class=\"bg-primary\">\n    <v-container>\n      <v-row>\n        <v-col\n          v-for=\"n in 3\"\n          :key=\"n\"\n          cols=\"12\"\n          md=\"4\"\n        >\n          <v-item v-slot=\"{ isSelected, selectedClass, toggle }\">\n            <v-card\n              :class=\"['d-flex align-center', selectedClass]\"\n              height=\"200\"\n              dark\n              @click=\"toggle\"\n            >\n              <div\n                class=\"text-display-medium flex-grow-1 text-center\"\n              >\n                {{ isSelected ? 'Selected' : 'Click Me!' }}\n              </div>\n            </v-card>\n          </v-item>\n        </v-col>\n      </v-row>\n    </v-container>\n  </v-item-group>\n</template>\n\n<script></script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-item-group/usage.vue",
    "content": "<template>\n  <v-item-group>\n    <v-container>\n      <v-row>\n        <v-col\n          v-for=\"n in 3\"\n          :key=\"n\"\n          cols=\"12\"\n          md=\"4\"\n        >\n          <v-item v-slot=\"{ isSelected, toggle }\">\n            <v-card\n              :color=\"isSelected ? 'primary' : ''\"\n              class=\"d-flex align-center\"\n              height=\"200\"\n              dark\n              @click=\"toggle\"\n            >\n              <v-scroll-y-transition>\n                <div\n                  v-if=\"isSelected\"\n                  class=\"text-display-large flex-grow-1 text-center\"\n                >\n                  Selected\n                </div>\n              </v-scroll-y-transition>\n            </v-card>\n          </v-item>\n        </v-col>\n      </v-row>\n    </v-container>\n  </v-item-group>\n</template>\n\n<script></script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-lazy/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n    :script=\"script\"\n  >\n    <v-sheet\n      ref=\"sheetRef\"\n      :max-height=\"300\"\n      class=\"overflow-y-auto ma-4\"\n      elevation=\"2\"\n    >\n      <div class=\"pa-6 text-center position-sticky\">\n        Scroll down\n      </div>\n\n      <v-responsive min-height=\"50vh\"></v-responsive>\n\n      <div class=\"text-center text-body-medium mb-12\">\n        The card will appear below:\n      </div>\n\n      <v-lazy\n        v-model=\"isActive\"\n        :options=\"{ threshold: .5 }\"\n        min-height=\"200\"\n        transition=\"fade-transition\"\n      >\n        <v-card\n          class=\"mx-auto\"\n          color=\"primary\"\n          max-width=\"336\"\n          text=\"This card was rendered later\"\n          title=\"Lazy card\"\n        >\n          <v-card-actions class=\"justify-center\">\n            <v-btn @click=\"reset\">Reset Demo</v-btn>\n          </v-card-actions>\n        </v-card>\n      </v-lazy>\n    </v-sheet>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const goTo = useGoTo()\n\n  const name = 'v-lazy'\n  const model = shallowRef('default')\n  const isActive = shallowRef(false)\n  const sheetRef = ref()\n  const options = []\n\n  async function reset () {\n    await goTo(0, { container: sheetRef.value.$el })\n\n    isActive.value = false\n  }\n\n  const props = computed(() => {\n    return {\n      'v-model': 'isActive',\n      'min-height': 200,\n      options: { threshold: 0.5 },\n      transition: 'fade-transition',\n    }\n  })\n\n  const slots = computed(() => {\n    return `\n  <v-card\n    class=\"mx-auto\"\n    color=\"primary\"\n    max-width=\"336\"\n    text=\"This card was rendered later\"\n    title=\"Lazy card\"\n  >\n    <v-card-actions class=\"justify-center\">\n      <v-btn @click=\"reset\">Reset Demo</v-btn>\n    </v-card-actions>\n  </v-card>\n`\n  })\n\n  const script = computed(() => {\n    return `<script setup>\n  import { ref, shallowRef } from 'vue'\n  import { useGoTo } from 'vuetify'\n\n  const goTo = useGoTo()\n\n  const isActive = shallowRef(false)\n  const sheetRef = ref()\n\n  async function reset () {\n    await goTo(0, { container: sheetRef.value.$el })\n\n    isActive.value = false\n  }\n<` + '/script>'\n  })\n\n  const code = computed(() => {\n    return `<v-sheet\n  ref=\"sheetRef\"\n  class=\"overflow-y-auto ma-4\"\n  :max-height=\"300\"\n  elevation=\"2\"\n>\n  <div class=\"pa-6 text-center position-sticky\">Scroll down</div>\n  <v-responsive min-height=\"100vh\"></v-responsive>\n\n  <div class=\"text-center text-body-medium mb-12\">\n    The card will appear below:\n  </div>\n\n  <${name}${propsToString(props.value)}>${slots.value}</${name}>\n</v-sheet>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-list/misc-action-stack.vue",
    "content": "<template>\n  <v-card class=\"mx-auto\" max-width=\"500\">\n    <v-toolbar color=\"pink\">\n      <v-btn icon=\"mdi-menu\"></v-btn>\n\n      <v-toolbar-title>Inbox</v-toolbar-title>\n\n      <v-btn icon=\"mdi-magnify\"></v-btn>\n\n      <v-btn icon=\"mdi-checkbox-marked-circle\"></v-btn>\n    </v-toolbar>\n\n    <v-list v-model:selected=\"selected\" select-strategy=\"leaf\">\n      <v-list-item\n        v-for=\"item in items\"\n        :key=\"item.id\"\n        :value=\"item.id\"\n        active-class=\"text-pink\"\n        class=\"py-3\"\n      >\n        <v-list-item-title>{{ item.title }}</v-list-item-title>\n\n        <v-list-item-subtitle class=\"mb-1 text-high-emphasis opacity-100\">{{ item.headline }}</v-list-item-subtitle>\n\n        <v-list-item-subtitle class=\"text-high-emphasis\">{{ item.subtitle }}</v-list-item-subtitle>\n\n        <template v-slot:append=\"{ isSelected }\">\n          <v-list-item-action class=\"flex-column align-end\">\n            <small class=\"mb-4 text-high-emphasis opacity-60\">{{ item.action }}</small>\n\n            <v-spacer></v-spacer>\n\n            <v-icon v-if=\"isSelected\" color=\"yellow-darken-3\">mdi-star</v-icon>\n\n            <v-icon v-else class=\"opacity-30\">mdi-star-outline</v-icon>\n          </v-list-item-action>\n        </template>\n      </v-list-item>\n    </v-list>\n  </v-card>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const items = [\n    { id: 1, action: '15 min', headline: 'Brunch this weekend?', subtitle: `I'll be in your neighborhood doing errands this weekend. Do you want to hang out?`, title: 'Ali Connors' },\n    { id: 2, action: '2 hr', headline: 'Summer BBQ', subtitle: `Wish I could come, but I'm out of town this weekend.`, title: 'me, Scrott, Jennifer' },\n    { id: 3, action: '6 hr', headline: 'Oui oui', subtitle: 'Do you have Paris recommendations? Have you ever been?', title: 'Sandra Adams' },\n    { id: 4, action: '12 hr', headline: 'Birthday gift', subtitle: 'Have any ideas about what we should get Heidi for her birthday?', title: 'Trevor Hansen' },\n    { id: 5, action: '18hr', headline: 'Recipe to try', subtitle: 'We should eat this: Grate, Squash, Corn, and tomatillo Tacos.', title: 'Britta Holt' },\n  ]\n\n  const selected = shallowRef([2])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        { id: 1, action: '15 min', headline: 'Brunch this weekend?', subtitle: `I'll be in your neighborhood doing errands this weekend. Do you want to hang out?`, title: 'Ali Connors' },\n        { id: 2, action: '2 hr', headline: 'Summer BBQ', subtitle: `Wish I could come, but I'm out of town this weekend.`, title: 'me, Scrott, Jennifer' },\n        { id: 3, action: '6 hr', headline: 'Oui oui', subtitle: 'Do you have Paris recommendations? Have you ever been?', title: 'Sandra Adams' },\n        { id: 4, action: '12 hr', headline: 'Birthday gift', subtitle: 'Have any ideas about what we should get Heidi for her birthday?', title: 'Trevor Hansen' },\n        { id: 5, action: '18hr', headline: 'Recipe to try', subtitle: 'We should eat this: Grate, Squash, Corn, and tomatillo Tacos.', title: 'Britta Holt' },\n      ],\n      selected: [2],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-list/misc-actions.vue",
    "content": "<template>\n  <v-card class=\"mx-auto\" max-width=\"400\">\n    <v-toolbar color=\"purple\">\n      <v-btn icon=\"mdi-menu\"></v-btn>\n      <v-toolbar-title>Settings</v-toolbar-title>\n      <v-btn icon=\"mdi-magnify\"></v-btn>\n    </v-toolbar>\n\n    <v-list lines=\"three\">\n      <v-list-subheader>User Controls</v-list-subheader>\n      <v-list-item\n        v-for=\"item in userControls\"\n        :key=\"item.value\"\n        :subtitle=\"item.subtitle\"\n        :title=\"item.title\"\n      ></v-list-item>\n    </v-list>\n\n    <v-divider></v-divider>\n\n    <v-list\n      v-model:selected=\"settingsSelection\"\n      lines=\"three\"\n      select-strategy=\"leaf\"\n    >\n      <v-list-subheader>General</v-list-subheader>\n      <v-list-item\n        v-for=\"item in settingsItems\"\n        :key=\"item.value\"\n        :subtitle=\"item.subtitle\"\n        :title=\"item.title\"\n        :value=\"item.value\"\n      >\n        <template v-slot:prepend=\"{ isSelected, select }\">\n          <v-list-item-action start>\n            <v-checkbox-btn :model-value=\"isSelected\" @update:model-value=\"select\"></v-checkbox-btn>\n          </v-list-item-action>\n        </template>\n      </v-list-item>\n    </v-list>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const userControls = [\n    { title: 'Content filtering', subtitle: 'Set the content filtering level to restrict appts that can be downloaded' },\n    { title: 'Password', subtitle: 'Require password for purchase or use password to restrict purchase' },\n  ]\n\n  const settingsItems = [\n    { value: 'notifications', title: 'Notifications', subtitle: 'Notify me about updates to apps or games that I downloaded' },\n    { value: 'sound', title: 'Sound', subtitle: 'Auto-update apps at any time. Data charges may apply' },\n    { value: 'widgets', title: 'Auto-add widgets', subtitle: 'Automatically add home screen widgets when downloads complete' },\n  ]\n\n  const settingsSelection = ref([])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      userControls: [\n        { title: 'Content filtering', subtitle: 'Set the content filtering level to restrict appts that can be downloaded' },\n        { title: 'Password', subtitle: 'Require password for purchase or use password to restrict purchase' },\n      ],\n\n      settingsItems: [\n        { value: 'notifications', title: 'Notifications', subtitle: 'Notify me about updates to apps or games that I downloaded' },\n        { value: 'sound', title: 'Sound', subtitle: 'Auto-update apps at any time. Data charges may apply' },\n        { value: 'widgets', title: 'Auto-add widgets', subtitle: 'Automatically add home screen widgets when downloads complete' },\n      ],\n\n      settingsSelection: [],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-list/misc-card-list.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"375\"\n  >\n    <v-img\n      class=\"text-white\"\n      height=\"300px\"\n      src=\"https://cdn.vuetifyjs.com/images/lists/ali.png\"\n      cover\n    >\n      <div class=\"d-flex flex-column h-100\">\n        <v-card-title class=\"d-flex ga-2 px-2\">\n          <v-btn icon=\"mdi-chevron-left\" variant=\"text\"></v-btn>\n          <v-spacer></v-spacer>\n          <v-btn icon=\"mdi-pencil\" variant=\"text\"></v-btn>\n          <v-btn icon=\"mdi-dots-vertical\" variant=\"text\"></v-btn>\n        </v-card-title>\n\n        <v-spacer></v-spacer>\n\n        <v-card-title class=\"pb-6 text-center\">\n          <div class=\"text-headline-large\">Ali Conners</div>\n        </v-card-title>\n      </div>\n    </v-img>\n\n    <v-list lines=\"two\">\n      <v-list-item>\n        <template v-slot:prepend>\n          <v-avatar>\n            <v-icon color=\"indigo\" icon=\"mdi-phone\"></v-icon>\n          </v-avatar>\n        </template>\n\n        <v-list-item-title>(650) 555-1234</v-list-item-title>\n        <v-list-item-subtitle>Mobile</v-list-item-subtitle>\n\n        <template v-slot:append>\n          <v-avatar>\n            <v-icon icon=\"mdi-message-text\"></v-icon>\n          </v-avatar>\n        </template>\n      </v-list-item>\n\n      <v-list-item>\n        <template v-slot:prepend>\n          <v-avatar></v-avatar>\n        </template>\n\n        <v-list-item-title>(323) 555-6789</v-list-item-title>\n        <v-list-item-subtitle>Work</v-list-item-subtitle>\n\n        <template v-slot:append>\n          <v-avatar>\n            <v-icon icon=\"mdi-message-text\"></v-icon>\n          </v-avatar>\n        </template>\n      </v-list-item>\n\n      <v-divider inset></v-divider>\n\n      <v-list-item>\n        <template v-slot:prepend>\n          <v-avatar>\n            <v-icon color=\"indigo\" icon=\"mdi-email\"></v-icon>\n          </v-avatar>\n        </template>\n\n        <v-list-item-title>aliconnors@example.com</v-list-item-title>\n        <v-list-item-subtitle>Personal</v-list-item-subtitle>\n      </v-list-item>\n\n      <v-list-item>\n        <template v-slot:prepend>\n          <v-avatar></v-avatar>\n        </template>\n\n        <v-list-item-title>ali_connors@example.com</v-list-item-title>\n        <v-list-item-subtitle>Work</v-list-item-subtitle>\n      </v-list-item>\n\n      <v-divider inset></v-divider>\n\n      <v-list-item>\n        <template v-slot:prepend>\n          <v-avatar>\n            <v-icon color=\"indigo\" icon=\"mdi-map-marker\"></v-icon>\n          </v-avatar>\n        </template>\n\n        <v-list-item-title>1400 Main Street</v-list-item-title>\n        <v-list-item-subtitle>Orlando, FL 79938</v-list-item-subtitle>\n      </v-list-item>\n    </v-list>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-list/misc-simple-avatar-list.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"500\"\n  >\n    <v-toolbar\n      color=\"indigo\"\n      dark\n    >\n      <v-app-bar-nav-icon></v-app-bar-nav-icon>\n\n      <v-toolbar-title>Inbox</v-toolbar-title>\n\n      <v-btn icon>\n        <v-icon>mdi-magnify</v-icon>\n      </v-btn>\n\n      <v-btn icon>\n        <v-icon>mdi-dots-vertical</v-icon>\n      </v-btn>\n    </v-toolbar>\n    <v-list>\n      <v-list-item\n        v-for=\"item in items\"\n        :key=\"item.title\"\n      >\n        <template v-slot:prepend>\n          <v-avatar>\n            <v-icon\n              v-if=\"item.icon\"\n              color=\"pink\"\n            >\n              mdi-star\n            </v-icon>\n          </v-avatar>\n        </template>\n\n        <v-list-item-title>{{ item.title }}</v-list-item-title>\n\n        <template v-slot:append>\n          <v-avatar>\n            <v-img :src=\"item.avatar\"></v-img>\n          </v-avatar>\n        </template>\n      </v-list-item>\n    </v-list>\n  </v-card>\n</template>\n\n<script setup>\n  const items = [\n    { icon: true, title: 'Jason Oner', avatar: 'https://cdn.vuetifyjs.com/images/lists/1.jpg' },\n    { title: 'Travis Howard', avatar: 'https://cdn.vuetifyjs.com/images/lists/2.jpg' },\n    { title: 'Ali Connors', avatar: 'https://cdn.vuetifyjs.com/images/lists/3.jpg' },\n    { title: 'Cindy Baker', avatar: 'https://cdn.vuetifyjs.com/images/lists/4.jpg' },\n  ]\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        items: [\n          { icon: true, title: 'Jason Oner', avatar: 'https://cdn.vuetifyjs.com/images/lists/1.jpg' },\n          { title: 'Travis Howard', avatar: 'https://cdn.vuetifyjs.com/images/lists/2.jpg' },\n          { title: 'Ali Connors', avatar: 'https://cdn.vuetifyjs.com/images/lists/3.jpg' },\n          { title: 'Cindy Baker', avatar: 'https://cdn.vuetifyjs.com/images/lists/4.jpg' },\n        ],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-list/misc-single-line-list.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"500\"\n  >\n    <v-toolbar color=\"deep-purple-accent-4\">\n      <v-app-bar-nav-icon></v-app-bar-nav-icon>\n\n      <v-toolbar-title>New Chat</v-toolbar-title>\n\n      <v-btn icon>\n        <v-icon>mdi-magnify</v-icon>\n      </v-btn>\n    </v-toolbar>\n\n    <v-list>\n      <v-list-subheader>Recent chat</v-list-subheader>\n\n      <v-list-item\n        v-for=\"chat in recent\"\n        :key=\"chat.title\"\n      >\n        <template v-slot:prepend>\n          <v-avatar>\n            <v-img :src=\"chat.avatar\"></v-img>\n          </v-avatar>\n        </template>\n\n        <v-list-item-title>{{ chat.title }}</v-list-item-title>\n\n        <template v-slot:append>\n          <v-avatar>\n            <v-icon :color=\"chat.active ? 'deep-purple accent-4' : 'grey'\">\n              mdi-message-outline\n            </v-icon>\n          </v-avatar>\n        </template>\n      </v-list-item>\n    </v-list>\n\n    <v-divider></v-divider>\n\n    <v-list>\n      <v-list-subheader>Previous chats</v-list-subheader>\n\n      <v-list-item\n        v-for=\"chat in previous\"\n        :key=\"chat.title\"\n      >\n        <template v-slot:prepend>\n          <v-avatar>\n            <v-img :src=\"chat.avatar\"></v-img>\n          </v-avatar>\n        </template>\n\n        <v-list-item-title v-text=\"chat.title\"></v-list-item-title>\n      </v-list-item>\n    </v-list>\n  </v-card>\n</template>\n\n<script setup>\n  const recent = [\n    {\n      active: true,\n      avatar: 'https://cdn.vuetifyjs.com/images/lists/1.jpg',\n      title: 'Jason Oner',\n    },\n    {\n      active: true,\n      avatar: 'https://cdn.vuetifyjs.com/images/lists/2.jpg',\n      title: 'Mike Carlson',\n    },\n    {\n      avatar: 'https://cdn.vuetifyjs.com/images/lists/3.jpg',\n      title: 'Cindy Baker',\n    },\n    {\n      avatar: 'https://cdn.vuetifyjs.com/images/lists/4.jpg',\n      title: 'Ali Connors',\n    },\n  ]\n  const previous = [{\n    title: 'Travis Howard',\n    avatar: 'https://cdn.vuetifyjs.com/images/lists/5.jpg',\n  }]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      recent: [\n        {\n          active: true,\n          avatar: 'https://cdn.vuetifyjs.com/images/lists/1.jpg',\n          title: 'Jason Oner',\n        },\n        {\n          active: true,\n          avatar: 'https://cdn.vuetifyjs.com/images/lists/2.jpg',\n          title: 'Mike Carlson',\n        },\n        {\n          avatar: 'https://cdn.vuetifyjs.com/images/lists/3.jpg',\n          title: 'Cindy Baker',\n        },\n        {\n          avatar: 'https://cdn.vuetifyjs.com/images/lists/4.jpg',\n          title: 'Ali Connors',\n        },\n      ],\n      previous: [{\n        title: 'Travis Howard',\n        avatar: 'https://cdn.vuetifyjs.com/images/lists/5.jpg',\n      }],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-list/misc-subheadings-and-dividers.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"475\"\n  >\n    <v-toolbar\n      color=\"teal\"\n      dark\n    >\n      <v-app-bar-nav-icon></v-app-bar-nav-icon>\n\n      <v-toolbar-title>Settings</v-toolbar-title>\n    </v-toolbar>\n\n    <v-list lines=\"two\">\n      <v-list-subheader>General</v-list-subheader>\n\n      <v-list-item>\n        <v-list-item-title>Profile photo</v-list-item-title>\n        <v-list-item-subtitle>Change your Google+ profile photo</v-list-item-subtitle>\n      </v-list-item>\n\n      <v-list-item>\n        <v-list-item-title>Show your status</v-list-item-title>\n        <v-list-item-subtitle>Your status is visible to everyone</v-list-item-subtitle>\n      </v-list-item>\n    </v-list>\n\n    <v-divider></v-divider>\n\n    <v-list v-model=\"settings\" lines=\"two\" select-strategy=\"leaf\">\n      <v-list-subheader>Hangout notifications</v-list-subheader>\n\n      <v-list-item>\n        <template v-slot:default=\"{ active, }\">\n          <v-list-item-action>\n            <v-checkbox\n              :model-value=\"active\"\n              color=\"primary\"\n            ></v-checkbox>\n          </v-list-item-action>\n\n          <v-list-item-header>\n            <v-list-item-title>Notifications</v-list-item-title>\n            <v-list-item-subtitle>Allow notifications</v-list-item-subtitle>\n          </v-list-item-header>\n        </template>\n      </v-list-item>\n\n      <v-list-item>\n        <template v-slot:default=\"{ active }\">\n          <v-list-item-action>\n            <v-checkbox\n              :model-value=\"active\"\n              color=\"primary\"\n            ></v-checkbox>\n          </v-list-item-action>\n\n          <v-list-item-header>\n            <v-list-item-title>Sound</v-list-item-title>\n            <v-list-item-subtitle>Hangouts message</v-list-item-subtitle>\n          </v-list-item-header>\n        </template>\n      </v-list-item>\n\n      <v-list-item>\n        <template v-slot:default=\"{ active }\">\n          <v-list-item-action>\n            <v-checkbox\n              :model-value=\"active\"\n              color=\"primary\"\n            ></v-checkbox>\n          </v-list-item-action>\n\n          <v-list-item-header>\n            <v-list-item-title>Video sounds</v-list-item-title>\n            <v-list-item-subtitle>Hangouts video call</v-list-item-subtitle>\n          </v-list-item-header>\n        </template>\n      </v-list-item>\n\n      <v-list-item>\n        <template v-slot:default=\"{ active }\">\n          <v-list-item-action>\n            <v-checkbox\n              :model-value=\"active\"\n              color=\"primary\"\n            ></v-checkbox>\n          </v-list-item-action>\n\n          <v-list-item-header>\n            <v-list-item-title>Invites</v-list-item-title>\n            <v-list-item-subtitle>Notify when receiving invites</v-list-item-subtitle>\n          </v-list-item-header>\n        </template>\n      </v-list-item>\n    </v-list>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const settings = ref([])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      settings: [],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-list/prop-density.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"300\"\n  >\n    <v-list density=\"compact\">\n      <v-list-subheader>REPORTS</v-list-subheader>\n\n      <v-list-item\n        v-for=\"(item, i) in items\"\n        :key=\"i\"\n        :value=\"item\"\n        color=\"primary\"\n      >\n        <template v-slot:prepend>\n          <v-icon :icon=\"item.icon\"></v-icon>\n        </template>\n\n        <v-list-item-title v-text=\"item.text\"></v-list-item-title>\n      </v-list-item>\n    </v-list>\n  </v-card>\n</template>\n\n<script setup>\n  const items = [\n    { text: 'Real-Time', icon: 'mdi-clock' },\n    { text: 'Audience', icon: 'mdi-account' },\n    { text: 'Conversions', icon: 'mdi-flag' },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        { text: 'Real-Time', icon: 'mdi-clock' },\n        { text: 'Audience', icon: 'mdi-account' },\n        { text: 'Conversions', icon: 'mdi-flag' },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-list/prop-disabled.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"300\"\n  >\n    <v-list disabled>\n      <v-list-subheader>REPORTS</v-list-subheader>\n\n      <v-list-item\n        v-for=\"(item, i) in items\"\n        :key=\"i\"\n      >\n        <template v-slot:prepend>\n          <v-icon :icon=\"item.icon\"></v-icon>\n        </template>\n\n        <v-list-item-title v-text=\"item.text\"></v-list-item-title>\n      </v-list-item>\n    </v-list>\n  </v-card>\n</template>\n\n<script setup>\n  const items = [\n    { text: 'Real-Time', icon: 'mdi-clock' },\n    { text: 'Audience', icon: 'mdi-account' },\n    { text: 'Conversions', icon: 'mdi-flag' },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        { text: 'Real-Time', icon: 'mdi-clock' },\n        { text: 'Audience', icon: 'mdi-account' },\n        { text: 'Conversions', icon: 'mdi-flag' },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-list/prop-items-custom.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"300\"\n  >\n    <v-list\n      :items=\"items\"\n      item-title=\"name\"\n      item-value=\"id\"\n    ></v-list>\n  </v-card>\n</template>\n\n<script setup>\n  const items = [\n    {\n      name: 'Item #1',\n      id: 1,\n    },\n    {\n      name: 'Item #2',\n      id: 2,\n    },\n    {\n      name: 'Item #3',\n      id: 3,\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        {\n          name: 'Item #1',\n          id: 1,\n        },\n        {\n          name: 'Item #2',\n          id: 2,\n        },\n        {\n          name: 'Item #3',\n          id: 3,\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-list/prop-items-prop.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"300\"\n  >\n    <v-list :items=\"items\"></v-list>\n  </v-card>\n</template>\n\n<script setup>\n  const items = [\n    {\n      title: 'Item #1',\n      value: 1,\n      props: {\n        prependIcon: 'mdi-home',\n      },\n    },\n    {\n      title: 'Item #2',\n      value: 2,\n      props: {\n        appendIcon: 'mdi-close',\n      },\n    },\n    {\n      title: 'Item #3',\n      value: 3,\n      props: {\n        color: 'primary',\n      },\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        {\n          title: 'Item #1',\n          value: 1,\n          props: {\n            prependIcon: 'mdi-home',\n          },\n        },\n        {\n          title: 'Item #2',\n          value: 2,\n          props: {\n            appendIcon: 'mdi-close',\n          },\n        },\n        {\n          title: 'Item #3',\n          value: 3,\n          props: {\n            color: 'primary',\n          },\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-list/prop-items-type.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"300\"\n  >\n    <v-list :items=\"items\"></v-list>\n  </v-card>\n</template>\n\n<script setup>\n  const items = [\n    { type: 'subheader', title: 'Group #1' },\n    {\n      title: 'Item #1',\n      value: 1,\n    },\n    {\n      title: 'Item #2',\n      value: 2,\n    },\n    {\n      title: 'Item #3',\n      value: 3,\n    },\n    { type: 'divider' },\n    { type: 'subheader', title: 'Group #2' },\n    {\n      title: 'Item #4',\n      value: 4,\n    },\n    {\n      title: 'Item #5',\n      value: 5,\n    },\n    {\n      title: 'Item #6',\n      value: 6,\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        { type: 'subheader', title: 'Group #1' },\n        {\n          title: 'Item #1',\n          value: 1,\n        },\n        {\n          title: 'Item #2',\n          value: 2,\n        },\n        {\n          title: 'Item #3',\n          value: 3,\n        },\n        { type: 'divider' },\n        { type: 'subheader', title: 'Group #2' },\n        {\n          title: 'Item #4',\n          value: 4,\n        },\n        {\n          title: 'Item #5',\n          value: 5,\n        },\n        {\n          title: 'Item #6',\n          value: 6,\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-list/prop-items.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"300\"\n  >\n    <v-list :items=\"items\"></v-list>\n  </v-card>\n</template>\n\n<script setup>\n  const items = [\n    {\n      title: 'Item #1',\n      value: 1,\n    },\n    {\n      title: 'Item #2',\n      value: 2,\n    },\n    {\n      title: 'Item #3',\n      value: 3,\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        {\n          title: 'Item #1',\n          value: 1,\n        },\n        {\n          title: 'Item #2',\n          value: 2,\n        },\n        {\n          title: 'Item #3',\n          value: 3,\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-list/prop-nav.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    width=\"256\"\n  >\n    <v-layout>\n      <v-navigation-drawer absolute permanent>\n        <v-list>\n          <v-list-item\n            prepend-avatar=\"https://cdn.vuetifyjs.com/images/john.png\"\n            subtitle=\"john@google.com\"\n            title=\"John Leider\"\n          >\n            <template v-slot:append>\n              <v-btn\n                icon=\"mdi-menu-down\"\n                size=\"small\"\n                variant=\"text\"\n              ></v-btn>\n            </template>\n          </v-list-item>\n        </v-list>\n\n        <v-divider></v-divider>\n\n        <v-list\n          :lines=\"false\"\n          density=\"compact\"\n          nav\n        >\n          <v-list-item\n            v-for=\"(item, i) in items\"\n            :key=\"i\"\n            :value=\"item\"\n            color=\"primary\"\n          >\n            <template v-slot:prepend>\n              <v-icon :icon=\"item.icon\"></v-icon>\n            </template>\n\n            <v-list-item-title v-text=\"item.text\"></v-list-item-title>\n          </v-list-item>\n        </v-list>\n      </v-navigation-drawer>\n\n      <v-main style=\"height: 354px;\"></v-main>\n    </v-layout>\n  </v-card>\n</template>\n\n<script setup>\n  const items = [\n    { text: 'My Files', icon: 'mdi-folder' },\n    { text: 'Shared with me', icon: 'mdi-account-multiple' },\n    { text: 'Starred', icon: 'mdi-star' },\n    { text: 'Recent', icon: 'mdi-history' },\n    { text: 'Offline', icon: 'mdi-check-circle' },\n    { text: 'Uploads', icon: 'mdi-upload' },\n    { text: 'Backups', icon: 'mdi-cloud-upload' },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        { text: 'My Files', icon: 'mdi-folder' },\n        { text: 'Shared with me', icon: 'mdi-account-multiple' },\n        { text: 'Starred', icon: 'mdi-star' },\n        { text: 'Recent', icon: 'mdi-history' },\n        { text: 'Offline', icon: 'mdi-check-circle' },\n        { text: 'Uploads', icon: 'mdi-upload' },\n        { text: 'Backups', icon: 'mdi-cloud-upload' },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-list/prop-rounded.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto pa-2\"\n    max-width=\"300\"\n  >\n    <v-list>\n      <v-list-subheader>REPORTS</v-list-subheader>\n\n      <v-list-item\n        v-for=\"(item, i) in items\"\n        :key=\"i\"\n        :value=\"item\"\n        color=\"primary\"\n        rounded=\"xl\"\n      >\n        <template v-slot:prepend>\n          <v-icon :icon=\"item.icon\"></v-icon>\n        </template>\n\n        <v-list-item-title v-text=\"item.text\"></v-list-item-title>\n      </v-list-item>\n    </v-list>\n  </v-card>\n</template>\n\n<script setup>\n  const items = [\n    { text: 'Real-Time', icon: 'mdi-clock' },\n    { text: 'Audience', icon: 'mdi-account' },\n    { text: 'Conversions', icon: 'mdi-flag' },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        { text: 'Real-Time', icon: 'mdi-clock' },\n        { text: 'Audience', icon: 'mdi-account' },\n        { text: 'Conversions', icon: 'mdi-flag' },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-list/prop-shaped.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto pa-2\"\n    max-width=\"300\"\n  >\n    <v-list>\n      <v-list-subheader>REPORTS</v-list-subheader>\n\n      <v-list-item\n        v-for=\"(item, i) in items\"\n        :key=\"i\"\n        :value=\"item\"\n        color=\"primary\"\n        rounded=\"shaped\"\n      >\n        <template v-slot:prepend>\n          <v-icon :icon=\"item.icon\"></v-icon>\n        </template>\n\n        <v-list-item-title v-text=\"item.text\"></v-list-item-title>\n      </v-list-item>\n    </v-list>\n  </v-card>\n</template>\n\n<script setup>\n  const items = [\n    { text: 'Real-Time', icon: 'mdi-clock' },\n    { text: 'Audience', icon: 'mdi-account' },\n    { text: 'Conversions', icon: 'mdi-flag' },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        { text: 'Real-Time', icon: 'mdi-clock' },\n        { text: 'Audience', icon: 'mdi-account' },\n        { text: 'Conversions', icon: 'mdi-flag' },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-list/prop-sub-group.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    width=\"300\"\n  >\n    <v-list v-model:opened=\"open\">\n      <v-list-item prepend-icon=\"mdi-home\" title=\"Home\"></v-list-item>\n\n      <v-list-group value=\"Users\">\n        <template v-slot:activator=\"{ props }\">\n          <v-list-item\n            v-bind=\"props\"\n            prepend-icon=\"mdi-account-circle\"\n            title=\"Users\"\n          ></v-list-item>\n        </template>\n\n        <v-list-group value=\"Admin\">\n          <template v-slot:activator=\"{ props }\">\n            <v-list-item\n              v-bind=\"props\"\n              title=\"Admin\"\n            ></v-list-item>\n          </template>\n\n          <v-list-item\n            v-for=\"([title, icon], i) in admins\"\n            :key=\"i\"\n            :prepend-icon=\"icon\"\n            :title=\"title\"\n            :value=\"title\"\n          ></v-list-item>\n        </v-list-group>\n\n        <v-list-group value=\"Actions\">\n          <template v-slot:activator=\"{ props }\">\n            <v-list-item\n              v-bind=\"props\"\n              title=\"Actions\"\n            ></v-list-item>\n          </template>\n\n          <v-list-item\n            v-for=\"([title, icon], i) in cruds\"\n            :key=\"i\"\n            :prepend-icon=\"icon\"\n            :title=\"title\"\n            :value=\"title\"\n          ></v-list-item>\n        </v-list-group>\n      </v-list-group>\n    </v-list>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const open = ref(['Users'])\n\n  const admins = [\n    ['Management', 'mdi-account-multiple-outline'],\n    ['Settings', 'mdi-cog-outline'],\n  ]\n  const cruds = [\n    ['Create', 'mdi-plus-outline'],\n    ['Read', 'mdi-file-outline'],\n    ['Update', 'mdi-update'],\n    ['Delete', 'mdi-delete'],\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      open: ['Users'],\n      admins: [\n        ['Management', 'mdi-account-multiple-outline'],\n        ['Settings', 'mdi-cog-outline'],\n      ],\n      cruds: [\n        ['Create', 'mdi-plus-outline'],\n        ['Read', 'mdi-file-outline'],\n        ['Update', 'mdi-update'],\n        ['Delete', 'mdi-delete'],\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-list/prop-three-line.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"450\"\n  >\n    <v-toolbar color=\"cyan-lighten-1\">\n      <v-btn icon=\"mdi-menu\" variant=\"text\"></v-btn>\n\n      <v-toolbar-title>Inbox</v-toolbar-title>\n\n      <v-btn icon=\"mdi-magnify\" variant=\"text\"></v-btn>\n    </v-toolbar>\n\n    <v-list\n      :items=\"items\"\n      lines=\"three\"\n      item-props\n    >\n      <template v-slot:subtitle=\"{ subtitle }\">\n        <div v-html=\"subtitle\"></div>\n      </template>\n    </v-list>\n  </v-card>\n</template>\n\n<script setup>\n  const items = [\n    { type: 'subheader', title: 'Today' },\n    {\n      prependAvatar: 'https://cdn.vuetifyjs.com/images/lists/1.jpg',\n      title: 'Brunch this weekend?',\n      subtitle: `<span class=\"text-primary\">Ali Connors</span> &mdash; I'll be in your neighborhood doing errands this weekend. Do you want to hang out?`,\n    },\n    { type: 'divider', inset: true },\n    {\n      prependAvatar: 'https://cdn.vuetifyjs.com/images/lists/2.jpg',\n      title: 'Summer BBQ',\n      subtitle: `<span class=\"text-primary\">to Alex, Scott, Jennifer</span> &mdash; Wish I could come, but I'm out of town this weekend.`,\n    },\n    { type: 'divider', inset: true },\n    {\n      prependAvatar: 'https://cdn.vuetifyjs.com/images/lists/3.jpg',\n      title: 'Oui oui',\n      subtitle: '<span class=\"text-primary\">Sandra Adams</span> &mdash; Do you have Paris recommendations? Have you ever been?',\n    },\n    { type: 'divider', inset: true },\n    {\n      prependAvatar: 'https://cdn.vuetifyjs.com/images/lists/4.jpg',\n      title: 'Birthday gift',\n      subtitle: '<span class=\"text-primary\">Trevor Hansen</span> &mdash; Have any ideas about what we should get Heidi for her birthday?',\n    },\n    { type: 'divider', inset: true },\n    {\n      prependAvatar: 'https://cdn.vuetifyjs.com/images/lists/5.jpg',\n      title: 'Recipe to try',\n      subtitle: '<span class=\"text-primary\">Britta Holt</span> &mdash; We should eat this: Grate, Squash, Corn, and tomatillo Tacos.',\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        { type: 'subheader', title: 'Today' },\n        {\n          prependAvatar: 'https://cdn.vuetifyjs.com/images/lists/1.jpg',\n          title: 'Brunch this weekend?',\n          subtitle: `<span class=\"text-primary\">Ali Connors</span> &mdash; I'll be in your neighborhood doing errands this weekend. Do you want to hang out?`,\n        },\n        { type: 'divider', inset: true },\n        {\n          prependAvatar: 'https://cdn.vuetifyjs.com/images/lists/2.jpg',\n          title: 'Summer BBQ',\n          subtitle: `<span class=\"text-primary\">to Alex, Scott, Jennifer</span> &mdash; Wish I could come, but I'm out of town this weekend.`,\n        },\n        { type: 'divider', inset: true },\n        {\n          prependAvatar: 'https://cdn.vuetifyjs.com/images/lists/3.jpg',\n          title: 'Oui oui',\n          subtitle: '<span class=\"text-primary\">Sandra Adams</span> &mdash; Do you have Paris recommendations? Have you ever been?',\n        },\n        { type: 'divider', inset: true },\n        {\n          prependAvatar: 'https://cdn.vuetifyjs.com/images/lists/4.jpg',\n          title: 'Birthday gift',\n          subtitle: '<span class=\"text-primary\">Trevor Hansen</span> &mdash; Have any ideas about what we should get Heidi for her birthday?',\n        },\n        { type: 'divider', inset: true },\n        {\n          prependAvatar: 'https://cdn.vuetifyjs.com/images/lists/5.jpg',\n          title: 'Recipe to try',\n          subtitle: '<span class=\"text-primary\">Britta Holt</span> &mdash; We should eat this: Grate, Squash, Corn, and tomatillo Tacos.',\n        },\n      ],\n    }),\n  }\n</script>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=1632-112421&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-list/prop-two-line-and-subheader.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"600\"\n  >\n    <v-toolbar color=\"secondary\">\n      <v-btn icon=\"mdi-menu\" variant=\"text\"></v-btn>\n\n      <v-toolbar-title>My files</v-toolbar-title>\n\n      <v-btn icon=\"mdi-magnify\" variant=\"text\"></v-btn>\n\n      <v-btn icon=\"mdi-view-module\" variant=\"text\"></v-btn>\n    </v-toolbar>\n\n    <v-list lines=\"two\">\n      <v-list-subheader inset>Folders</v-list-subheader>\n\n      <v-list-item\n        v-for=\"folder in folders\"\n        :key=\"folder.title\"\n        :subtitle=\"folder.subtitle\"\n        :title=\"folder.title\"\n      >\n        <template v-slot:prepend>\n          <v-avatar color=\"grey-lighten-1\">\n            <v-icon color=\"white\">mdi-folder</v-icon>\n          </v-avatar>\n        </template>\n\n        <template v-slot:append>\n          <v-btn\n            color=\"grey-lighten-1\"\n            icon=\"mdi-information\"\n            variant=\"text\"\n          ></v-btn>\n        </template>\n      </v-list-item>\n\n      <v-divider inset></v-divider>\n\n      <v-list-subheader inset>Files</v-list-subheader>\n\n      <v-list-item\n        v-for=\"file in files\"\n        :key=\"file.title\"\n        :subtitle=\"file.subtitle\"\n        :title=\"file.title\"\n      >\n        <template v-slot:prepend>\n          <v-avatar :color=\"file.color\">\n            <v-icon color=\"white\">{{ file.icon }}</v-icon>\n          </v-avatar>\n        </template>\n\n        <template v-slot:append>\n          <v-btn\n            color=\"grey-lighten-1\"\n            icon=\"mdi-information\"\n            variant=\"text\"\n          ></v-btn>\n        </template>\n      </v-list-item>\n    </v-list>\n  </v-card>\n</template>\n\n<script setup>\n  const files = [\n    {\n      color: 'blue',\n      icon: 'mdi-clipboard-text',\n      subtitle: 'Jan 20, 2014',\n      title: 'Vacation itinerary',\n    },\n    {\n      color: 'amber',\n      icon: 'mdi-gesture-tap-button',\n      subtitle: 'Jan 10, 2014',\n      title: 'Kitchen remodel',\n    },\n  ]\n  const folders = [\n    {\n      subtitle: 'Jan 9, 2014',\n      title: 'Photos',\n    },\n    {\n      subtitle: 'Jan 17, 2014',\n      title: 'Recipes',\n    },\n    {\n      subtitle: 'Jan 28, 2014',\n      title: 'Work',\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      files: [\n        {\n          color: 'blue',\n          icon: 'mdi-clipboard-text',\n          subtitle: 'Jan 20, 2014',\n          title: 'Vacation itinerary',\n        },\n        {\n          color: 'amber',\n          icon: 'mdi-gesture-tap-button',\n          subtitle: 'Jan 10, 2014',\n          title: 'Kitchen remodel',\n        },\n      ],\n      folders: [\n        {\n          subtitle: 'Jan 9, 2014',\n          title: 'Photos',\n        },\n        {\n          subtitle: 'Jan 17, 2014',\n          title: 'Recipes',\n        },\n        {\n          subtitle: 'Jan 28, 2014',\n          title: 'Work',\n        },\n      ],\n    }),\n  }\n</script>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=1632-113203&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-list/prop-variant.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"300\"\n  >\n    <v-list>\n      <v-list-subheader>Plain Variant</v-list-subheader>\n\n      <v-list-item\n        v-for=\"(item, i) in items\"\n        :key=\"i\"\n        :value=\"item\"\n        color=\"primary\"\n        variant=\"plain\"\n      >\n        <template v-slot:prepend>\n          <v-icon :icon=\"item.icon\"></v-icon>\n        </template>\n\n        <v-list-item-title v-text=\"item.text\"></v-list-item-title>\n      </v-list-item>\n    </v-list>\n\n    <v-list>\n      <v-list-subheader>Tonal Variant</v-list-subheader>\n\n      <v-list-item\n        v-for=\"(item, i) in items\"\n        :key=\"i\"\n        :value=\"item\"\n        color=\"primary\"\n        variant=\"tonal\"\n      >\n        <template v-slot:prepend>\n          <v-icon :icon=\"item.icon\"></v-icon>\n        </template>\n\n        <v-list-item-title v-text=\"item.text\"></v-list-item-title>\n      </v-list-item>\n    </v-list>\n  </v-card>\n</template>\n\n<script setup>\n  const items = [\n    { text: 'Real-Time', icon: 'mdi-clock' },\n    { text: 'Audience', icon: 'mdi-account' },\n    { text: 'Conversions', icon: 'mdi-flag' },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        { text: 'Real-Time', icon: 'mdi-clock' },\n        { text: 'Audience', icon: 'mdi-account' },\n        { text: 'Conversions', icon: 'mdi-flag' },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-list/slot-expansion-lists.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"500\"\n  >\n    <v-toolbar\n      color=\"teal\"\n      dark\n    >\n      <v-app-bar-nav-icon></v-app-bar-nav-icon>\n\n      <v-toolbar-title>Topics</v-toolbar-title>\n\n      <v-btn icon>\n        <v-icon>mdi-dots-vertical</v-icon>\n      </v-btn>\n    </v-toolbar>\n\n    <v-list>\n      <v-list-group\n        v-for=\"item in items\"\n        :key=\"item.title\"\n        v-model=\"item.active\"\n        :prepend-icon=\"item.action\"\n      >\n        <template v-slot:activator>\n          <v-list-item-header>\n            <v-list-item-title v-text=\"item.title\"></v-list-item-title>\n          </v-list-item-header>\n        </template>\n\n        <v-list-item\n          v-for=\"child in item.items\"\n          :key=\"child.title\"\n        >\n          <v-list-item-header>\n            <v-list-item-title v-text=\"child.title\"></v-list-item-title>\n          </v-list-item-header>\n        </v-list-item>\n      </v-list-group>\n    </v-list>\n  </v-card>\n</template>\n\n<script setup>\n  const items = [\n    {\n      action: 'mdi-ticket',\n      items: [{ title: 'List Item' }],\n      title: 'Attractions',\n    },\n    {\n      action: 'mdi-silverware-fork-knife',\n      active: true,\n      items: [\n        { title: 'Breakfast & brunch' },\n        { title: 'New American' },\n        { title: 'Sushi' },\n      ],\n      title: 'Dining',\n    },\n    {\n      action: 'mdi-school',\n      items: [{ title: 'List Item' }],\n      title: 'Education',\n    },\n    {\n      action: 'mdi-human-male-female-child',\n      items: [{ title: 'List Item' }],\n      title: 'Family',\n    },\n    {\n      action: 'mdi-bottle-tonic-plus',\n      items: [{ title: 'List Item' }],\n      title: 'Health',\n    },\n    {\n      action: 'mdi-briefcase',\n      items: [{ title: 'List Item' }],\n      title: 'Office',\n    },\n    {\n      action: 'mdi-tag',\n      items: [{ title: 'List Item' }],\n      title: 'Promotions',\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        {\n          action: 'mdi-ticket',\n          items: [{ title: 'List Item' }],\n          title: 'Attractions',\n        },\n        {\n          action: 'mdi-silverware-fork-knife',\n          active: true,\n          items: [\n            { title: 'Breakfast & brunch' },\n            { title: 'New American' },\n            { title: 'Sushi' },\n          ],\n          title: 'Dining',\n        },\n        {\n          action: 'mdi-school',\n          items: [{ title: 'List Item' }],\n          title: 'Education',\n        },\n        {\n          action: 'mdi-human-male-female-child',\n          items: [{ title: 'List Item' }],\n          title: 'Family',\n        },\n        {\n          action: 'mdi-bottle-tonic-plus',\n          items: [{ title: 'List Item' }],\n          title: 'Health',\n        },\n        {\n          action: 'mdi-briefcase',\n          items: [{ title: 'List Item' }],\n          title: 'Office',\n        },\n        {\n          action: 'mdi-tag',\n          items: [{ title: 'List Item' }],\n          title: 'Promotions',\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-list/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div>\n      <v-list v-bind=\"props\">\n        <v-list-item\n          v-for=\"n in 3\"\n          :key=\"n\"\n          :prepend-avatar=\"avatar ? 'https://randomuser.me/api/portraits/women/8.jpg' : undefined\"\n          :title=\"'Item ' + n\"\n          subtitle=\"Lorem ipsum dolor sit amet consectetur adipisicing elit\"\n        ></v-list-item>\n      </v-list>\n    </div>\n\n    <template v-slot:configuration>\n      <v-checkbox v-model=\"avatar\" label=\"Show avatars\"></v-checkbox>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-list'\n  const model = ref('default')\n  const options = ['two-lines', 'three-lines']\n  const avatar = ref(false)\n\n  const lines = computed(() => {\n    return {\n      default: 'one',\n      'two-lines': 'two',\n      'three-lines': 'three',\n    }[model.value]\n  })\n\n  const props = computed(() => {\n    return {\n      lines: lines.value,\n    }\n  })\n  const itemProps = computed(() => {\n    return {\n      'v-for': 'n in 3',\n      ':key': 'n',\n      ':title': `'Item ' + n`,\n      subtitle: 'Lorem ipsum dolor sit amet consectetur adipisicing elit',\n      ':prepend-avatar': avatar.value ? 'https://randomuser.me/api/portraits/women/8.jpg' : undefined,\n    }\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>\n  <v-list-item${propsToString(itemProps.value, [], 2)}></v-list-item>\n</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-mask-input/credit-card-form.vue",
    "content": "<template>\n  <div>\n    <v-row>\n      <v-col cols=\"12\">\n        <v-mask-input\n          v-model=\"cardNumber\"\n          :rules=\"[\n            v => !!v || 'Card number is required',\n            v => v.replace(/\\s/g, '').length === 16 || 'Card number must be 16 digits'\n          ]\"\n          hint=\"Enter 16-digit card number\"\n          mask=\"#### #### #### ####\"\n          placeholder=\"XXXX XXXX XXXX XXXX\"\n          prepend-inner-icon=\"mdi-credit-card-outline\"\n          persistent-hint\n        ></v-mask-input>\n      </v-col>\n\n      <v-col cols=\"6\">\n        <v-mask-input\n          v-model=\"expiryDate\"\n          :rules=\"[\n            v => !!v || 'Expiry date is required',\n            v => validateExpiryDate(v) || 'Invalid expiry date'\n          ]\"\n          hint=\"Enter expiry date\"\n          mask=\"##/##\"\n          placeholder=\"MM/YY\"\n          prepend-inner-icon=\"mdi-calendar-blank\"\n          persistent-hint\n          return-masked-value\n        ></v-mask-input>\n      </v-col>\n\n      <v-col cols=\"6\">\n        <v-mask-input\n          v-model=\"cvv\"\n          :rules=\"[\n            v => !!v || 'CVV is required',\n            v => v.length === 3 || 'CVV must be 3 digits'\n          ]\"\n          hint=\"3-digit security code\"\n          mask=\"###\"\n          placeholder=\"CVC\"\n          prepend-inner-icon=\"mdi-lock-outline\"\n          persistent-hint\n        ></v-mask-input>\n      </v-col>\n    </v-row>\n  </div>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const cardNumber = shallowRef(null)\n  const expiryDate = shallowRef(null)\n  const cvv = shallowRef(null)\n\n  const validateExpiryDate = date => {\n    if (!date || date.length !== 5) return false\n\n    const [month, year] = date.split('/')\n    const currentDate = new Date()\n    const currentYear = currentDate.getFullYear() % 100\n    const currentMonth = currentDate.getMonth() + 1\n\n    const monthNum = parseInt(month)\n    const yearNum = parseInt(year)\n\n    return monthNum >= 1 && monthNum <= 12 &&\n      yearNum >= currentYear &&\n      !(yearNum === currentYear && monthNum < currentMonth)\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      cardNumber: null,\n      expiryDate: null,\n      cvv: null,\n    }),\n    methods: {\n      validateExpiryDate (date) {\n        if (!date || date.length !== 5) return false\n\n        const [month, year] = date.split('/')\n        const currentDate = new Date()\n        const currentYear = currentDate.getFullYear() % 100\n        const currentMonth = currentDate.getMonth() + 1\n\n        const monthNum = parseInt(month)\n        const yearNum = parseInt(year)\n\n        return monthNum >= 1 && monthNum <= 12 &&\n          yearNum >= currentYear &&\n          !(yearNum === currentYear && monthNum < currentMonth)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-mask-input/custom-mask.vue",
    "content": "<template>\n  <div>\n    <v-mask-input\n      v-model=\"model\"\n      label=\"Product Code\"\n      mask=\"AAA-###\"\n      placeholder=\"ABC-123\"\n    ></v-mask-input>\n  </div>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const model = shallowRef(null)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      model: null,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-mask-input/custom-token.vue",
    "content": "<template>\n  <div>\n    <v-mask-input\n      v-model=\"model\"\n      :mask=\"{\n        mask: 'LLL-NNN',\n        tokens: {\n          'L': {\n            pattern: /[A-Z]/,\n            convert: v => v.toUpperCase()\n          },\n          'N': {\n            pattern: /[0-9]/,\n            convert: v => v\n          }\n        }\n      }\"\n      label=\"License Plate\"\n      persistent-hint\n    ></v-mask-input>\n  </div>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const model = shallowRef(null)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      model: null,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-mask-input/ip-address.vue",
    "content": "<template>\n  <div>\n    <v-mask-input\n      v-model=\"model\"\n      :rules=\"[\n        v => !!v || 'IP address is required',\n        v => validateIP(v) || 'Invalid IP address'\n      ]\"\n      hint=\"Enter a valid IP address\"\n      label=\"IP Address\"\n      mask=\"###.###.###.###\"\n      placeholder=\"192.168.001.001\"\n      persistent-hint\n      return-masked-value\n    ></v-mask-input>\n  </div>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const model = shallowRef(null)\n\n  const validateIP = ip => {\n    if (!ip) return false\n    const parts = ip.split('.')\n    return parts.length === 4 && parts.every(part => {\n      const num = parseInt(part)\n      return num >= 0 && num <= 255\n    })\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      model: null,\n    }),\n    methods: {\n      validateIP (ip) {\n        if (!ip) return false\n        const parts = ip.split('.')\n        return parts.length === 4 && parts.every(part => {\n          const num = parseInt(part)\n          return num >= 0 && num <= 255\n        })\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-mask-input/phone.vue",
    "content": "<template>\n  <div>\n    <v-mask-input\n      v-model=\"model\"\n      mask=\"phone\"\n      placeholder=\"(###) ### - ####\"\n    ></v-mask-input>\n  </div>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const model = shallowRef(null)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      model: null,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-mask-input/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div>\n      <v-mask-input v-bind=\"props\"></v-mask-input>\n    </div>\n\n    <template v-slot:configuration>\n      <v-checkbox v-model=\"clear\" label=\"Clearable\"></v-checkbox>\n\n      <v-checkbox v-model=\"disabled\" label=\"Disabled\"></v-checkbox>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-mask-input'\n  const model = ref('default')\n  const options = ['outlined', 'underlined', 'solo', 'solo-filled', 'solo-inverted']\n  const clear = ref(false)\n  const counter = ref(false)\n  const disabled = ref(false)\n  const props = computed(() => {\n    return {\n      clearable: clear.value || undefined,\n      counter: counter.value || undefined,\n      disabled: disabled.value || undefined,\n      mask: 'credit-card',\n      label: 'Mask input',\n      variant: model.value === 'default' ? undefined : model.value,\n    }\n  })\n\n  const slots = computed(() => {\n    return ``\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-menu/misc-popover.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-menu\n      v-model=\"menu\"\n      :close-on-content-click=\"false\"\n      location=\"end\"\n    >\n      <template v-slot:activator=\"{ props }\">\n        <v-btn\n          color=\"indigo\"\n          v-bind=\"props\"\n        >\n          Menu as Popover\n        </v-btn>\n      </template>\n\n      <v-card min-width=\"300\">\n        <v-list>\n          <v-list-item\n            prepend-avatar=\"https://cdn.vuetifyjs.com/images/john.jpg\"\n            subtitle=\"Founder of Vuetify\"\n            title=\"John Leider\"\n          >\n            <template v-slot:append>\n              <v-btn\n                :class=\"fav ? 'text-red' : ''\"\n                icon=\"mdi-heart\"\n                variant=\"text\"\n                @click=\"fav = !fav\"\n              ></v-btn>\n            </template>\n          </v-list-item>\n        </v-list>\n\n        <v-divider></v-divider>\n\n        <v-list>\n          <v-list-item>\n            <v-switch\n              v-model=\"message\"\n              color=\"purple\"\n              label=\"Enable messages\"\n              hide-details\n            ></v-switch>\n          </v-list-item>\n\n          <v-list-item>\n            <v-switch\n              v-model=\"hints\"\n              color=\"purple\"\n              label=\"Enable hints\"\n              hide-details\n            ></v-switch>\n          </v-list-item>\n        </v-list>\n\n        <v-card-actions>\n          <v-spacer></v-spacer>\n\n          <v-btn\n            variant=\"text\"\n            @click=\"menu = false\"\n          >\n            Cancel\n          </v-btn>\n          <v-btn\n            color=\"primary\"\n            variant=\"text\"\n            @click=\"menu = false\"\n          >\n            Save\n          </v-btn>\n        </v-card-actions>\n      </v-card>\n    </v-menu>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const fav = ref(true)\n  const menu = ref(false)\n  const message = ref(false)\n  const hints = ref(true)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      fav: true,\n      menu: false,\n      message: false,\n      hints: true,\n    }),\n  }\n</script>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=1632-127381&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-menu/misc-transition.vue",
    "content": "<template>\n  <div class=\"d-flex justify-space-around\">\n    <v-menu\n      transition=\"scale-transition\"\n    >\n      <template v-slot:activator=\"{ props }\">\n        <v-btn\n          color=\"primary\"\n          v-bind=\"props\"\n        >\n          Scale Transition\n        </v-btn>\n      </template>\n\n      <v-list>\n        <v-list-item\n          v-for=\"(item, i) in items\"\n          :key=\"i\"\n          :value=\"i\"\n        >\n          <v-list-item-title>{{ item.title }}</v-list-item-title>\n        </v-list-item>\n      </v-list>\n    </v-menu>\n\n    <v-menu\n      transition=\"slide-x-transition\"\n    >\n      <template v-slot:activator=\"{ props }\">\n        <v-btn\n          color=\"primary\"\n          v-bind=\"props\"\n        >\n          Slide X Transition\n        </v-btn>\n      </template>\n\n      <v-list>\n        <v-list-item\n          v-for=\"(item, i) in items\"\n          :key=\"i\"\n          :value=\"i\"\n        >\n          <v-list-item-title>{{ item.title }}</v-list-item-title>\n        </v-list-item>\n      </v-list>\n    </v-menu>\n\n    <v-menu\n      transition=\"slide-y-transition\"\n    >\n      <template v-slot:activator=\"{ props }\">\n        <v-btn\n          color=\"primary\"\n          v-bind=\"props\"\n        >\n          Slide Y Transition\n        </v-btn>\n      </template>\n      <v-list>\n        <v-list-item\n          v-for=\"(item, i) in items\"\n          :key=\"i\"\n          :value=\"i\"\n        >\n          <v-list-item-title>{{ item.title }}</v-list-item-title>\n        </v-list-item>\n      </v-list>\n    </v-menu>\n  </div>\n</template>\n\n<script setup>\n  const items = [\n    { title: 'Click Me' },\n    { title: 'Click Me' },\n    { title: 'Click Me' },\n    { title: 'Click Me 2' },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        { title: 'Click Me' },\n        { title: 'Click Me' },\n        { title: 'Click Me' },\n        { title: 'Click Me 2' },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-menu/misc-use-in-components.vue",
    "content": "<template>\n  <v-row>\n    <v-col\n      cols=\"12\"\n      offset-sm=\"3\"\n      sm=\"6\"\n    >\n      <v-card height=\"200px\">\n        <v-card-title class=\"bg-blue d-flex align-center\">\n          <span class=\"text-headline-small\">Menu</span>\n\n          <v-spacer></v-spacer>\n\n          <v-menu>\n            <template v-slot:activator=\"{ props }\">\n              <v-btn icon=\"mdi-dots-vertical\" variant=\"text\" v-bind=\"props\"></v-btn>\n            </template>\n\n            <v-list>\n              <v-list-item\n                v-for=\"(item, i) in items\"\n                :key=\"i\"\n                :value=\"i\"\n              >\n                <v-list-item-title>{{ item.title }}</v-list-item-title>\n              </v-list-item>\n            </v-list>\n          </v-menu>\n        </v-card-title>\n\n        <v-card-text>Lorem Ipsum</v-card-text>\n      </v-card>\n    </v-col>\n  </v-row>\n</template>\n\n<script setup>\n  const items = [\n    { title: 'Click Me' },\n    { title: 'Click Me' },\n    { title: 'Click Me' },\n    { title: 'Click Me 2' },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        { title: 'Click Me' },\n        { title: 'Click Me' },\n        { title: 'Click Me' },\n        { title: 'Click Me 2' },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-menu/prop-absolute-without-activator.vue",
    "content": "<template>\n  <div>\n    <v-row class=\"flex justify-center\">\n      <v-card\n        :ripple=\"false\"\n        class=\"portrait\"\n        height=\"300px\"\n        img=\"https://cdn.vuetifyjs.com/images/cards/girl.jpg\"\n        @contextmenu=\"show\"\n      ></v-card>\n    </v-row>\n\n    <v-menu\n      v-model=\"showMenu\"\n      :target=\"[x, y]\"\n      absolute\n    >\n      <v-list>\n        <v-list-item\n          v-for=\"(item, index) in items\"\n          :key=\"index\"\n        >\n          <v-list-item-title>{{ item.title }}</v-list-item-title>\n        </v-list-item>\n      </v-list>\n    </v-menu>\n  </div>\n</template>\n\n<script setup>\n  import { nextTick, ref } from 'vue'\n\n  const items = [\n    { title: 'Click Me' },\n    { title: 'Click Me' },\n    { title: 'Click Me' },\n    { title: 'Click Me 2' },\n  ]\n\n  const showMenu = ref(false)\n  const x = ref(0)\n  const y = ref(0)\n\n  function show (e) {\n    e.preventDefault()\n    showMenu.value = false\n    x.value = e.clientX\n    y.value = e.clientY\n    nextTick(() => {\n      showMenu.value = true\n    })\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      showMenu: false,\n      x: 0,\n      y: 0,\n      items: [\n        { title: 'Click Me' },\n        { title: 'Click Me' },\n        { title: 'Click Me' },\n        { title: 'Click Me 2' },\n      ],\n    }),\n\n    methods: {\n      show (e) {\n        e.preventDefault()\n        this.showMenu = false\n        this.x = e.clientX\n        this.y = e.clientY\n        this.$nextTick(() => {\n          this.showMenu = true\n        })\n      },\n    },\n  }\n</script>\n\n<style scoped>\n.portrait.v-card {\n  margin: 0 auto;\n  max-width: 600px;\n  width: 100%;\n}\n</style>\n"
  },
  {
    "path": "packages/docs/src/examples/v-menu/prop-absolute.vue",
    "content": "<template>\n  <div class=\"d-flex justify-center\">\n    <v-menu\n      v-model=\"showMenu\"\n      style=\"max-width: 600px\"\n    >\n      <template v-slot:activator=\"{ props }\">\n        <v-card\n          class=\"portrait\"\n          height=\"300\"\n          image=\"https://cdn.vuetifyjs.com/images/cards/girl.jpg\"\n          width=\"600\"\n          v-bind=\"props\"\n        ></v-card>\n      </template>\n\n      <v-list>\n        <v-list-item\n          v-for=\"(item, index) in items\"\n          :key=\"index\"\n          :value=\"index\"\n        >\n          <v-list-item-title>{{ item.title }}</v-list-item-title>\n        </v-list-item>\n      </v-list>\n    </v-menu>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const showMenu = ref(false)\n\n  const items = [\n    { title: 'Click Me' },\n    { title: 'Click Me' },\n    { title: 'Click Me' },\n    { title: 'Click Me 2' },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      showMenu: false,\n      items: [\n        { title: 'Click Me' },\n        { title: 'Click Me' },\n        { title: 'Click Me' },\n        { title: 'Click Me 2' },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-menu/prop-close-on-click.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-switch\n      v-model=\"closeOnClick\"\n      color=\"primary\"\n      label=\"Close on click\"\n    ></v-switch>\n    <v-menu :persistent=\"!closeOnClick\">\n      <template v-slot:activator=\"{ props }\">\n        <v-btn\n          color=\"primary\"\n          v-bind=\"props\"\n        >\n          Dropdown\n        </v-btn>\n      </template>\n\n      <v-list>\n        <v-list-item\n          v-for=\"(item, index) in items\"\n          :key=\"index\"\n          :value=\"index\"\n        >\n          <v-list-item-title>{{ item.title }}</v-list-item-title>\n        </v-list-item>\n      </v-list>\n    </v-menu>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const items = [\n    { title: 'Click Me' },\n    { title: 'Click Me' },\n    { title: 'Click Me' },\n    { title: 'Click Me 2' },\n  ]\n\n  const closeOnClick = ref(true)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        { title: 'Click Me' },\n        { title: 'Click Me' },\n        { title: 'Click Me' },\n        { title: 'Click Me 2' },\n      ],\n      closeOnClick: true,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-menu/prop-close-on-content-click.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-switch\n      v-model=\"closeOnContentClick\"\n      label=\"Close on content click\"\n    ></v-switch>\n    <v-menu\n      :close-on-content-click=\"closeOnContentClick\"\n      location=\"top\"\n    >\n      <template v-slot:activator=\"{ props }\">\n        <v-btn\n          color=\"primary\"\n          v-bind=\"props\"\n        >\n          Dropdown\n        </v-btn>\n      </template>\n\n      <v-list>\n        <v-list-item\n          v-for=\"(item, index) in items\"\n          :key=\"index\"\n          :value=\"index\"\n        >\n          <v-list-item-title>{{ item.title }}</v-list-item-title>\n        </v-list-item>\n      </v-list>\n    </v-menu>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const items = [\n    { title: 'Click Me' },\n    { title: 'Click Me' },\n    { title: 'Click Me' },\n    { title: 'Click Me 2' },\n  ]\n\n  const closeOnContentClick = ref(true)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        { title: 'Click Me' },\n        { title: 'Click Me' },\n        { title: 'Click Me' },\n        { title: 'Click Me 2' },\n      ],\n      closeOnContentClick: true,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-menu/prop-disabled.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-menu disabled>\n      <template v-slot:activator=\"{ props }\">\n        <v-btn\n          color=\"primary\"\n          v-bind=\"props\"\n        >\n          Dropdown\n        </v-btn>\n      </template>\n\n      <v-list>\n        <v-list-item\n          v-for=\"(item, index) in items\"\n          :key=\"index\"\n          :value=\"index\"\n        >\n          <v-list-item-title>{{ item.title }}</v-list-item-title>\n        </v-list-item>\n      </v-list>\n    </v-menu>\n  </div>\n</template>\n\n<script setup>\n  const items = [\n    { title: 'Click Me' },\n    { title: 'Click Me' },\n    { title: 'Click Me' },\n    { title: 'Click Me 2' },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        { title: 'Click Me' },\n        { title: 'Click Me' },\n        { title: 'Click Me' },\n        { title: 'Click Me 2' },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-menu/prop-location.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-select\n      v-model=\"location\"\n      :items=\"locations\"\n      label=\"Location\"\n    ></v-select>\n    <v-menu :location=\"location\">\n      <template v-slot:activator=\"{ props }\">\n        <v-btn\n          color=\"primary\"\n          v-bind=\"props\"\n        >\n          Dropdown\n        </v-btn>\n      </template>\n\n      <v-list>\n        <v-list-item\n          v-for=\"(item, index) in items\"\n          :key=\"index\"\n          :value=\"index\"\n        >\n          <v-list-item-title>{{ item.title }}</v-list-item-title>\n        </v-list-item>\n      </v-list>\n    </v-menu>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const location = ref('end')\n\n  const items = [\n    { title: 'Click Me' },\n    { title: 'Click Me' },\n    { title: 'Click Me' },\n    { title: 'Click Me 2' },\n  ]\n  const locations = [\n    'top',\n    'bottom',\n    'start',\n    'end',\n    'center',\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        { title: 'Click Me' },\n        { title: 'Click Me' },\n        { title: 'Click Me' },\n        { title: 'Click Me 2' },\n      ],\n      locations: [\n        'top',\n        'bottom',\n        'start',\n        'end',\n        'center',\n      ],\n      location: 'end',\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-menu/prop-open-on-hover.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-menu\n      open-on-hover\n    >\n      <template v-slot:activator=\"{ props }\">\n        <v-btn\n          color=\"primary\"\n          v-bind=\"props\"\n        >\n          Dropdown\n        </v-btn>\n      </template>\n\n      <v-list>\n        <v-list-item\n          v-for=\"(item, index) in items\"\n          :key=\"index\"\n          :value=\"index\"\n        >\n          <v-list-item-title>{{ item.title }}</v-list-item-title>\n        </v-list-item>\n      </v-list>\n    </v-menu>\n  </div>\n</template>\n\n<script setup>\n  const items = [\n    { title: 'Click Me' },\n    { title: 'Click Me' },\n    { title: 'Click Me' },\n    { title: 'Click Me 2' },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        { title: 'Click Me' },\n        { title: 'Click Me' },\n        { title: 'Click Me' },\n        { title: 'Click Me 2' },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-menu/prop-positioningmenu.vue",
    "content": "<template>\n  <v-container max-width=\"300\">\n    <div\n      v-for=\"n in 10\"\n      :key=\"n\"\n      class=\"py-2 border-b d-flex align-center ga-2\"\n    >\n      Some Text Here\n      <v-spacer></v-spacer>\n      <v-icon-btn\n        icon=\"mdi-dots-vertical\"\n        size=\"small\"\n        variant=\"outlined\"\n        @click=\"show\"\n      ></v-icon-btn>\n    </div>\n\n    <v-menu\n      v-model=\"showMenu\"\n      :offset=\"[-8,-12]\"\n      :target=\"menuTarget\"\n      location=\"bottom end\"\n      scroll-strategy=\"close\"\n    >\n      <v-list\n        :items=\"menuItems\"\n        class=\"py-0\"\n        density=\"compact\"\n        item-value=\"code\"\n        item-props\n        slim\n      >\n        <template v-slot:prepend>\n          <v-icon class=\"mr-n2\" size=\"small\"></v-icon>\n        </template>\n      </v-list>\n    </v-menu>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const showMenu = ref(false)\n  const menuTarget = ref(null)\n\n  const menuItems = [\n    { title: 'Create', prependIcon: 'mdi-plus-circle', code: 'add' },\n    { type: 'divider' },\n    { title: 'Modify', prependIcon: 'mdi-pencil', code: 'edit' },\n    { type: 'divider' },\n    { title: 'Remove', prependIcon: 'mdi-trash-can', code: 'delete' },\n  ]\n\n  async function show (evt) {\n    if (showMenu.value) {\n      showMenu.value = false\n      await new Promise(resolve => setTimeout(resolve, 100))\n    }\n    menuTarget.value = evt.target.closest('.v-icon-btn')\n    showMenu.value = true\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-menu/prop-rounded.vue",
    "content": "<template>\n  <v-row class=\"justify-space-around\">\n    <v-menu\n      v-for=\"([text, rounded], index) in btns\"\n      :key=\"text\"\n      :rounded=\"rounded\"\n      offset-y\n    >\n      <template v-slot:activator=\"{ props }\">\n        <v-btn\n          :color=\"colors[index]\"\n          class=\"text-white ma-5\"\n          v-bind=\"props\"\n        >\n          {{ text }} Radius\n        </v-btn>\n      </template>\n\n      <v-list :rounded=\"rounded\">\n        <v-list-item\n          v-for=\"item in items\"\n          :key=\"item\"\n          link\n        >\n          <v-list-item-title v-text=\"item\"></v-list-item-title>\n        </v-list-item>\n      </v-list>\n    </v-menu>\n  </v-row>\n</template>\n\n<script setup>\n  const btns = [\n    ['Removed', '0'],\n    ['Large', 'lg'],\n    ['Custom', 'b-xl'],\n  ]\n  const colors = ['deep-purple accent-4', 'error', 'teal darken-1']\n  const items = Array.from({ length: 4 }, (_, i) => `Item ${i}`)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      btns: [\n        ['Removed', '0'],\n        ['Large', 'lg'],\n        ['Custom', 'b-xl'],\n      ],\n      colors: ['deep-purple accent-4', 'error', 'teal darken-1'],\n      items: [...Array(4)].map((_, i) => `Item ${i}`),\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-menu/prop-submenu.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-btn color=\"primary\">\n      Open menu\n\n      <v-menu activator=\"parent\">\n        <v-list>\n          <v-list-item v-for=\"i in 5\" :key=\"i\" link>\n            <v-list-item-title>Item {{ i }}</v-list-item-title>\n            <template v-slot:append>\n              <v-icon icon=\"mdi-menu-right\" size=\"x-small\"></v-icon>\n            </template>\n\n            <v-menu :open-on-focus=\"false\" activator=\"parent\" open-on-hover submenu>\n              <v-list>\n                <v-list-item v-for=\"j in 5\" :key=\"j\" link>\n                  <v-list-item-title>Item {{ i }} - {{ j }}</v-list-item-title>\n                  <template v-slot:append>\n                    <v-icon icon=\"mdi-menu-right\" size=\"x-small\"></v-icon>\n                  </template>\n\n                  <v-menu :open-on-focus=\"false\" activator=\"parent\" open-on-hover submenu>\n                    <v-list>\n                      <v-list-item v-for=\"k in 5\" :key=\"k\" link>\n                        <v-list-item-title>Item {{ i }} - {{ j }} - {{ k }}</v-list-item-title>\n                      </v-list-item>\n                    </v-list>\n                  </v-menu>\n                </v-list-item>\n              </v-list>\n            </v-menu>\n          </v-list-item>\n        </v-list>\n      </v-menu>\n    </v-btn>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-menu/slot-activator-and-tooltip.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-menu>\n      <template v-slot:activator=\"{ props: menu }\">\n        <v-tooltip location=\"top\">\n          <template v-slot:activator=\"{ props: tooltip }\">\n            <v-btn\n              color=\"primary\"\n              v-bind=\"mergeProps(menu, tooltip)\"\n            >\n              Dropdown w/ Tooltip\n            </v-btn>\n          </template>\n          <span>I'm A Tooltip</span>\n        </v-tooltip>\n      </template>\n      <v-list>\n        <v-list-item\n          v-for=\"(item, index) in items\"\n          :key=\"index\"\n          :value=\"index\"\n        >\n          <v-list-item-title>{{ item.title }}</v-list-item-title>\n        </v-list-item>\n      </v-list>\n    </v-menu>\n  </div>\n</template>\n\n<script setup>\n  import { mergeProps } from 'vue'\n\n  const items = [\n    { title: 'Click Me 1' },\n    { title: 'Click Me 2' },\n    { title: 'Click Me 3' },\n    { title: 'Click Me 4' },\n  ]\n</script>\n\n<script>\n  import { mergeProps } from 'vue'\n\n  export default {\n    data: () => ({\n      items: [\n        { title: 'Click Me1' },\n        { title: 'Click Me2' },\n        { title: 'Click Me3' },\n        { title: 'Click Me4' },\n      ],\n    }),\n    methods: {\n      mergeProps,\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-menu/usage.vue",
    "content": "<template>\n  <div class=\"d-flex justify-space-around\">\n    <v-menu>\n      <template v-slot:activator=\"{ props }\">\n        <v-btn\n          color=\"primary\"\n          v-bind=\"props\"\n        >\n          Activator slot\n        </v-btn>\n      </template>\n      <v-list>\n        <v-list-item\n          v-for=\"(item, index) in items\"\n          :key=\"index\"\n          :value=\"index\"\n        >\n          <v-list-item-title>{{ item.title }}</v-list-item-title>\n        </v-list-item>\n      </v-list>\n    </v-menu>\n\n    <v-btn\n      color=\"primary\"\n    >\n      Parent activator\n\n      <v-menu activator=\"parent\">\n        <v-list>\n          <v-list-item\n            v-for=\"(item, index) in items\"\n            :key=\"index\"\n            :value=\"index\"\n          >\n            <v-list-item-title>{{ item.title }}</v-list-item-title>\n          </v-list-item>\n        </v-list>\n      </v-menu>\n    </v-btn>\n\n    <v-btn\n      id=\"menu-activator\"\n      color=\"primary\"\n    >\n      Sibling activator\n    </v-btn>\n\n    <v-menu activator=\"#menu-activator\">\n      <v-list>\n        <v-list-item\n          v-for=\"(item, index) in items\"\n          :key=\"index\"\n          :value=\"index\"\n        >\n          <v-list-item-title>{{ item.title }}</v-list-item-title>\n        </v-list-item>\n      </v-list>\n    </v-menu>\n  </div>\n</template>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        { title: 'Click Me' },\n        { title: 'Click Me' },\n        { title: 'Click Me' },\n        { title: 'Click Me 2' },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-mutate/option-modifiers.vue",
    "content": "<template>\n  <div>\n    <div>\n      <div class=\"text-center\">\n        <v-btn @click=\"content = !content\">\n          Change Content\n        </v-btn>\n      </div>\n\n      <v-container>\n        <v-row>\n          <v-col\n            cols=\"12\"\n            md=\"6\"\n          >\n            <v-card>\n              <v-card-title>Card 1</v-card-title>\n\n              <div class=\"text-title-large text-center pb-3\">\n                Times Mutated: {{ card1 }}\n              </div>\n\n              <v-card-text v-mutate=\"() => onMutate('card1')\">\n                <p\n                  v-for=\"n in +content + 2\"\n                  :key=\"n\"\n                  :class=\"n === +content + 2 && 'mb-0'\"\n                >\n                  Suspendisse enim turpis, dictum sed, iaculis a, condimentum nec, nisi. Fusce fermentum odio nec arcu. Aenean ut eros et nisl sagittis vestibulum. Nunc interdum lacus sit amet orci. Phasellus nec sem in justo pellentesque facilisis.\n                </p>\n              </v-card-text>\n            </v-card>\n          </v-col>\n\n          <v-col\n            cols=\"12\"\n            md=\"6\"\n          >\n            <v-card>\n              <v-card-title>Card 2 (w/ once modifier)</v-card-title>\n\n              <div class=\"text-title-large text-center pb-3\">\n                Times Mutated: {{ card2 }}\n              </div>\n\n              <v-card-text v-mutate.once=\"() => onMutate('card2')\">\n                <p\n                  v-for=\"n in +content + 2\"\n                  :key=\"n\"\n                  :class=\"n === +content + 2 && 'mb-0'\"\n                >\n                  Suspendisse enim turpis, dictum sed, iaculis a, condimentum nec, nisi. Fusce fermentum odio nec arcu. Aenean ut eros et nisl sagittis vestibulum. Nunc interdum lacus sit amet orci. Phasellus nec sem in justo pellentesque facilisis.\n                </p>\n              </v-card-text>\n            </v-card>\n          </v-col>\n        </v-row>\n      </v-container>\n    </div>\n  </div>\n</template>\n\n<script>\n  export default {\n    data: () => ({\n      content: false,\n      card1: 0,\n      card2: 0,\n    }),\n\n    methods: {\n      onMutate (card) {\n        this[card]++\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-mutate/usage.vue",
    "content": "<template>\n  <div>\n    <v-text-field\n      v-model=\"content\"\n      label=\"Content\"\n    ></v-text-field>\n    <v-sheet v-mutate=\"onMutate\">\n      {{ content }}\n    </v-sheet>\n    Total mutations: {{ mutations }}\n  </div>\n</template>\n\n<script>\n  export default {\n    data: () => ({\n      mutations: 0,\n      content: 'Hello, world!',\n    }),\n\n    methods: {\n      onMutate () {\n        this.mutations++\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-navigation-drawer/misc-colored.vue",
    "content": "<template>\n  <v-card>\n    <v-layout>\n      <v-navigation-drawer\n        class=\"bg-deep-purple\"\n        theme=\"dark\"\n        permanent\n      >\n        <v-list color=\"transparent\">\n          <v-list-item prepend-icon=\"mdi-view-dashboard\" title=\"Dashboard\"></v-list-item>\n          <v-list-item prepend-icon=\"mdi-account-box\" title=\"Account\"></v-list-item>\n          <v-list-item prepend-icon=\"mdi-gavel\" title=\"Admin\"></v-list-item>\n        </v-list>\n\n        <template v-slot:append>\n          <div class=\"pa-2\">\n            <v-btn block>\n              Logout\n            </v-btn>\n          </div>\n        </template>\n      </v-navigation-drawer>\n      <v-main style=\"height: 400px\"></v-main>\n    </v-layout>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-navigation-drawer/misc-combined.vue",
    "content": "<template>\n  <v-card>\n    <v-layout>\n      <v-navigation-drawer theme=\"dark\" permanent rail>\n        <v-list>\n          <v-list-item\n            prepend-avatar=\"https://randomuser.me/api/portraits/women/75.jpg\"\n          ></v-list-item>\n        </v-list>\n\n        <v-divider></v-divider>\n\n        <v-list density=\"compact\" nav>\n          <v-list-item\n            prepend-icon=\"mdi-view-dashboard\"\n            value=\"dashboard\"\n          ></v-list-item>\n\n          <v-list-item prepend-icon=\"mdi-forum\" value=\"messages\"></v-list-item>\n        </v-list>\n      </v-navigation-drawer>\n\n      <v-navigation-drawer permanent>\n        <v-list>\n          <v-list-item title=\"Home\" value=\"home\"></v-list-item>\n\n          <v-list-item title=\"Contacts\" value=\"contacts\"></v-list-item>\n\n          <v-list-item title=\"Settings\" value=\"settings\"></v-list-item>\n        </v-list>\n      </v-navigation-drawer>\n\n      <v-main style=\"height: 300px\"></v-main>\n    </v-layout>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-navigation-drawer/prop-bottom-drawer.vue",
    "content": "<template>\n  <v-card>\n    <v-layout>\n      <v-app-bar color=\"primary\">\n        <v-app-bar-nav-icon variant=\"text\" @click.stop=\"drawer = !drawer\"></v-app-bar-nav-icon>\n\n        <v-toolbar-title>My files</v-toolbar-title>\n\n        <template v-if=\"$vuetify.display.mdAndUp\">\n          <v-btn icon=\"mdi-magnify\" variant=\"text\"></v-btn>\n\n          <v-btn icon=\"mdi-filter\" variant=\"text\"></v-btn>\n        </template>\n\n        <v-btn icon=\"mdi-dots-vertical\" variant=\"text\"></v-btn>\n      </v-app-bar>\n\n      <v-navigation-drawer\n        v-model=\"drawer\"\n        :location=\"$vuetify.display.mobile ? 'bottom' : undefined\"\n        temporary\n      >\n        <v-list\n          :items=\"items\"\n        ></v-list>\n      </v-navigation-drawer>\n\n      <v-main style=\"height: 500px;\">\n        <v-card-text>\n          The navigation drawer will appear from the bottom on smaller size screens.\n        </v-card-text>\n      </v-main>\n    </v-layout>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref, watch } from 'vue'\n\n  const items = [\n    {\n      title: 'Foo',\n      value: 'foo',\n    },\n    {\n      title: 'Bar',\n      value: 'bar',\n    },\n    {\n      title: 'Fizz',\n      value: 'fizz',\n    },\n    {\n      title: 'Buzz',\n      value: 'buzz',\n    },\n  ]\n\n  const drawer = ref(false)\n  const group = ref(null)\n\n  watch(group, () => {\n    drawer.value = false\n  })\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      drawer: false,\n      group: null,\n      items: [\n        {\n          title: 'Foo',\n          value: 'foo',\n        },\n        {\n          title: 'Bar',\n          value: 'bar',\n        },\n        {\n          title: 'Fizz',\n          value: 'fizz',\n        },\n        {\n          title: 'Buzz',\n          value: 'buzz',\n        },\n      ],\n    }),\n\n    watch: {\n      group () {\n        this.drawer = false\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-navigation-drawer/prop-expand-on-hover.vue",
    "content": "<template>\n  <v-card>\n    <v-layout>\n      <v-navigation-drawer\n        expand-on-hover\n        permanent\n        rail\n      >\n        <v-list>\n          <v-list-item\n            prepend-avatar=\"https://randomuser.me/api/portraits/women/85.jpg\"\n            subtitle=\"sandra_a88@gmailcom\"\n            title=\"Sandra Adams\"\n          ></v-list-item>\n        </v-list>\n\n        <v-divider></v-divider>\n\n        <v-list density=\"compact\" nav>\n          <v-list-item prepend-icon=\"mdi-folder\" title=\"My Files\" value=\"myfiles\"></v-list-item>\n          <v-list-item prepend-icon=\"mdi-account-multiple\" title=\"Shared with me\" value=\"shared\"></v-list-item>\n          <v-list-item prepend-icon=\"mdi-star\" title=\"Starred\" value=\"starred\"></v-list-item>\n        </v-list>\n      </v-navigation-drawer>\n\n      <v-main style=\"height: 250px\"></v-main>\n    </v-layout>\n  </v-card>\n</template>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=1905-99231&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-navigation-drawer/prop-images.vue",
    "content": "<template>\n  <v-card>\n    <v-layout>\n      <v-navigation-drawer\n        image=\"https://cdn.vuetifyjs.com/images/backgrounds/bg-2.jpg\"\n        theme=\"dark\"\n        permanent\n      >\n        <v-list nav>\n          <v-list-item prepend-icon=\"mdi-email\" title=\"Inbox\" value=\"inbox\"></v-list-item>\n          <v-list-item prepend-icon=\"mdi-account-supervisor-circle\" title=\"Supervisors\" value=\"supervisors\"></v-list-item>\n          <v-list-item prepend-icon=\"mdi-clock-start\" title=\"Clock-in\" value=\"clockin\"></v-list-item>\n        </v-list>\n      </v-navigation-drawer>\n      <v-main style=\"height: 250px\"></v-main>\n    </v-layout>\n  </v-card>\n</template>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=1905-100779&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-navigation-drawer/prop-permanent-and-floating.vue",
    "content": "<template>\n  <v-card>\n    <v-layout>\n      <v-navigation-drawer\n        floating\n        permanent\n      >\n        <v-list\n          density=\"compact\"\n          nav\n        >\n          <v-list-item prepend-icon=\"mdi-view-dashboard\" title=\"Home\" value=\"home\"></v-list-item>\n          <v-list-item prepend-icon=\"mdi-forum\" title=\"About\" value=\"about\"></v-list-item>\n        </v-list>\n      </v-navigation-drawer>\n      <v-main style=\"height: 250px\"></v-main>\n    </v-layout>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-navigation-drawer/prop-rail-variant.vue",
    "content": "<template>\n  <v-card>\n    <v-layout>\n      <v-navigation-drawer\n        v-model=\"drawer\"\n        :rail=\"rail\"\n        permanent\n        @click=\"rail = false\"\n      >\n        <v-list>\n          <v-list-item\n            prepend-avatar=\"https://randomuser.me/api/portraits/men/85.jpg\"\n            title=\"John Leider\"\n          >\n            <template v-slot:append>\n              <v-btn\n                icon=\"mdi-chevron-left\"\n                variant=\"text\"\n                @click.stop=\"rail = !rail\"\n              ></v-btn>\n            </template>\n          </v-list-item>\n        </v-list>\n\n        <v-divider></v-divider>\n\n        <v-list density=\"compact\" nav>\n          <v-list-item\n            prepend-icon=\"mdi-home-city\"\n            title=\"Home\"\n            value=\"home\"\n          ></v-list-item>\n          <v-list-item\n            prepend-icon=\"mdi-account\"\n            title=\"My Account\"\n            value=\"account\"\n          ></v-list-item>\n          <v-list-item\n            prepend-icon=\"mdi-account-group-outline\"\n            title=\"Users\"\n            value=\"users\"\n          ></v-list-item>\n        </v-list>\n      </v-navigation-drawer>\n      <v-main style=\"height: 250px\"></v-main>\n    </v-layout>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const drawer = ref(true)\n  const rail = ref(true)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        drawer: true,\n        rail: true,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-navigation-drawer/prop-right.vue",
    "content": "<template>\n  <v-card>\n    <v-layout>\n      <v-navigation-drawer\n        location=\"right\"\n        permanent\n      >\n        <template v-slot:prepend>\n          <v-list-item\n            lines=\"two\"\n            prepend-avatar=\"https://randomuser.me/api/portraits/women/81.jpg\"\n            subtitle=\"Logged in\"\n            title=\"Jane Smith\"\n          ></v-list-item>\n        </template>\n\n        <v-divider></v-divider>\n\n        <v-list density=\"compact\" nav>\n          <v-list-item prepend-icon=\"mdi-home-city\" title=\"Home\" value=\"home\"></v-list-item>\n          <v-list-item prepend-icon=\"mdi-account\" title=\"My Account\" value=\"account\"></v-list-item>\n          <v-list-item prepend-icon=\"mdi-account-group-outline\" title=\"Users\" value=\"users\"></v-list-item>\n        </v-list>\n      </v-navigation-drawer>\n      <v-main style=\"height: 250px\"></v-main>\n    </v-layout>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-navigation-drawer/prop-temporary.vue",
    "content": "<template>\n  <v-card>\n    <v-layout>\n      <v-navigation-drawer\n        v-model=\"drawer\"\n        temporary\n      >\n        <v-list-item\n          prepend-avatar=\"https://randomuser.me/api/portraits/men/78.jpg\"\n          title=\"John Leider\"\n        ></v-list-item>\n\n        <v-divider></v-divider>\n\n        <v-list density=\"compact\" nav>\n          <v-list-item prepend-icon=\"mdi-view-dashboard\" title=\"Home\" value=\"home\"></v-list-item>\n          <v-list-item prepend-icon=\"mdi-forum\" title=\"About\" value=\"about\"></v-list-item>\n        </v-list>\n      </v-navigation-drawer>\n      <v-main style=\"height: 250px\">\n        <div class=\"d-flex justify-center align-center h-100\">\n          <v-btn\n            color=\"primary\"\n            @click.stop=\"drawer = !drawer\"\n          >\n            Toggle\n          </v-btn>\n        </div>\n      </v-main>\n    </v-layout>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const drawer = ref(null)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        drawer: null,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-navigation-drawer/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n    :script=\"script\"\n  >\n    <div>\n      <v-navigation-drawer\n        v-model=\"open\"\n        :temporary=\"!permanent\"\n        v-bind=\"props\"\n      >\n        <v-list-item subtitle=\"Vuetify\" title=\"My Application\"></v-list-item>\n        <v-divider></v-divider>\n        <v-list-item title=\"List Item 1\" link></v-list-item>\n        <v-list-item title=\"List Item 2\" link></v-list-item>\n        <v-list-item title=\"List Item 3\" link></v-list-item>\n      </v-navigation-drawer>\n      <v-container class=\"d-flex align-center justify-center\">\n        <v-switch v-if=\"!permanent\" v-model=\"open\" color=\"success\"></v-switch>\n      </v-container>\n    </div>\n\n    <template v-slot:configuration>\n      <v-select v-model=\"color\" :items=\"colors\" label=\"Color\" clearable></v-select>\n      <v-slider v-model=\"width\" label=\"Width\" max=\"400\" min=\"100\" step=\"5\"></v-slider>\n      <v-checkbox v-model=\"permanent\" label=\"Permanent\"></v-checkbox>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-navigation-drawer'\n\n  const colors = ['primary', 'purple-darken-2', 'surface-variant']\n\n  const model = ref('default')\n  const color = shallowRef()\n  const width = shallowRef(256)\n  const permanent = shallowRef(true)\n  const open = shallowRef(true)\n  const options = []\n\n  const props = computed(() => {\n    return {\n      permanent: permanent.value || undefined,\n      location: location.value || undefined,\n      color: color.value || undefined,\n      width: width.value === 256 ? undefined : width.value || undefined,\n    }\n  })\n\n  const modelValueTemplateCode = computed(() => {\n    return !permanent.value\n      ? ` v-model=\"open\"`\n      : ''\n  })\n\n  const modelValueToggle = computed(() => {\n    return !permanent.value\n      ? `\\n<v-main class=\"d-flex align-center justify-center\">\n  <v-switch v-model=\"open\" color=\"success\"></v-switch>\n</v-main>`\n      : ''\n  })\n\n  const script = toRef(() => {\n    return !permanent.value\n      ? `<script setup>\n  import { shallowRef } from 'vue'\n\n  const open = shallowRef(true)\n<\\\\/script>`.replace('\\\\/', '/')\n      : ''\n  })\n\n  const slots = computed(() => {\n    return `\n  <v-list-item title=\"My Application\" subtitle=\"Vuetify\"></v-list-item>\n  <v-divider></v-divider>\n  <v-list-item link title=\"List Item 1\"></v-list-item>\n  <v-list-item link title=\"List Item 2\"></v-list-item>\n  <v-list-item link title=\"List Item 3\"></v-list-item>\n`\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}${modelValueTemplateCode.value}>${slots.value}</${name}>\n${modelValueToggle.value}`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-number-input/prop-control-variant.vue",
    "content": "<template>\n  <v-container>\n    <v-row>\n      <v-col cols=\"12\" md=\"4\" sm=\"4\">\n        <h5 class=\"my-0\">Default</h5>\n\n        <v-number-input control-variant=\"default\"></v-number-input>\n      </v-col>\n\n      <v-col cols=\"12\" md=\"4\" sm=\"4\">\n        <h5 class=\"my-0\">Stacked</h5>\n\n        <v-number-input control-variant=\"stacked\"></v-number-input>\n      </v-col>\n\n      <v-col cols=\"12\" md=\"4\" sm=\"4\">\n        <h5 class=\"my-0\">Split</h5>\n\n        <v-number-input control-variant=\"split\"></v-number-input>\n      </v-col>\n\n      <v-col cols=\"12\" md=\"4\" sm=\"4\">\n        <h5 class=\"my-0\">Hidden</h5>\n\n        <v-number-input control-variant=\"hidden\"></v-number-input>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2723-39726&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-number-input/prop-hide-input.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"justify-center\">\n      <v-col cols=\"auto\">\n        <v-number-input variant=\"outlined\" hide-details hide-input></v-number-input>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-number-input/prop-inset.vue",
    "content": "<template>\n  <v-container>\n    <v-row>\n      <v-col cols=\"12\" sm=\"6\">\n        <h5 class=\"my-0\">Default</h5>\n\n        <v-number-input\n          control-variant=\"default\"\n          inset\n        ></v-number-input>\n      </v-col>\n\n      <v-col cols=\"12\" sm=\"6\">\n        <h5 class=\"my-0\">Stacked</h5>\n\n        <v-number-input\n          control-variant=\"stacked\"\n          inset\n        ></v-number-input>\n      </v-col>\n\n      <v-col cols=\"12\" sm=\"6\">\n        <h5 class=\"my-0\">Split</h5>\n\n        <v-number-input\n          control-variant=\"split\"\n          inset\n        ></v-number-input>\n      </v-col>\n\n      <v-col cols=\"12\" sm=\"6\">\n        <h5 class=\"my-0\">Hide-input</h5>\n\n        <v-number-input\n          hide-input\n          inset\n        ></v-number-input>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-number-input/prop-min-max.vue",
    "content": "<template>\n  <v-container>\n    <v-row>\n      <v-col>\n        <h5 class=\"my-0\">min:10/max:20</h5>\n\n        <v-number-input\n          :max=\"20\"\n          :min=\"10\"\n          :model-value=\"15\"\n        ></v-number-input>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-number-input/prop-precision.vue",
    "content": "<template>\n  <v-container>\n    <v-row>\n      <v-col>\n        <h5 class=\"my-0\">(default precision=\"0\")</h5>\n        <v-number-input v-model=\"example1\" :precision=\"0\" hide-details=\"auto\"></v-number-input>\n        <code class=\"d-block pt-3\">value: {{ example1 }}</code>\n      </v-col>\n    </v-row>\n    <v-row>\n      <v-col>\n        <h5 class=\"my-0\">(precision=\"2\")</h5>\n        <v-number-input v-model=\"example2\" :precision=\"2\" hide-details=\"auto\"></v-number-input>\n        <code class=\"d-block pt-3\">value: {{ example2 }}</code>\n      </v-col>\n      <v-col>\n        <h5 class=\"my-0\">(precision=\"5\")</h5>\n        <v-number-input v-model=\"example3\" :precision=\"5\" hide-details=\"auto\"></v-number-input>\n        <code class=\"d-block pt-3\">value: {{ example3 }}</code>\n      </v-col>\n      <v-col>\n        <h5 class=\"my-0\">(precision unrestricted)</h5>\n        <v-number-input v-model=\"example4\" :precision=\"null\" hide-details=\"auto\"></v-number-input>\n        <code class=\"d-block pt-3\">value: {{ example4 }}</code>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const example1 = ref(4.052)\n  const example2 = ref(123)\n  const example3 = ref(25.5)\n  const example4 = ref(0.052)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      example1: 4.052,\n      example2: 123,\n      example3: 25.5,\n      example4: 0.052,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-number-input/prop-reverse.vue",
    "content": "<template>\n  <v-container>\n    <v-row>\n      <v-col cols=\"12\" md=\"4\" sm=\"4\">\n        <h5 class=\"my-0\">Default</h5>\n\n        <v-number-input\n          control-variant=\"default\"\n          reverse\n        ></v-number-input>\n      </v-col>\n\n      <v-col cols=\"12\" md=\"4\" sm=\"4\">\n        <h5 class=\"my-0\">Stacked</h5>\n\n        <v-number-input\n          control-variant=\"stacked\"\n          reverse\n        ></v-number-input>\n      </v-col>\n\n      <v-col cols=\"12\" md=\"4\" sm=\"4\">\n        <h5 class=\"my-0\">Split</h5>\n\n        <v-number-input\n          control-variant=\"split\"\n        ></v-number-input>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2723-39727&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-number-input/prop-step.vue",
    "content": "<template>\n  <v-container>\n    <v-row>\n      <v-col>\n        <h5 class=\"my-0\">step 2; min:10; max:20</h5>\n\n        <v-number-input\n          :max=\"20\"\n          :min=\"10\"\n          :model-value=\"15\"\n          :step=\"2\"\n        ></v-number-input>\n      </v-col>\n      <v-col>\n        <h5 class=\"my-0\">step {{ step }}, rounding on blur</h5>\n        <v-number-input\n          v-model=\"roundedValue\"\n          :step=\"step\"\n        ></v-number-input>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { computed, shallowRef } from 'vue'\n\n  const step = 50\n  const value = shallowRef(100)\n  const roundedValue = computed({\n    get: () => value.value,\n    set: v => value.value = Math.round(v / step) * step,\n  })\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      value: 100,\n      step: 50,\n    }),\n    computed: {\n      roundedValue: {\n        get () { return this.value },\n        set (v) { this.value = Math.round(v / this.step) * this.step },\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-number-input/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div class=\"text-center\">\n      <v-number-input v-bind=\"props\"></v-number-input>\n    </div>\n\n    <template v-slot:configuration>\n      <v-select\n        v-model=\"controlVariant\"\n        :items=\"controlVariantOptions\"\n        label=\"Control Variant\"\n      ></v-select>\n      <v-checkbox v-model=\"reverse\" label=\"Reverse\"></v-checkbox>\n      <v-checkbox v-model=\"inset\" label=\"Inset\"></v-checkbox>\n      <v-checkbox v-model=\"hideInput\" label=\"HideInput\"></v-checkbox>\n      <v-text-field v-model=\"label\" label=\"Label\" clearable></v-text-field>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = ref('v-number-input')\n  const model = ref('default')\n  const options = ['outlined', 'filled', 'solo', 'solo-inverted', 'solo-filled']\n  const controlVariantOptions = ['default', 'stacked', 'split']\n  const reverse = ref(false)\n  const controlVariant = ref('default')\n  const disabled = ref(false)\n  const loading = ref(false)\n  const inset = ref(false)\n  const hideInput = ref(false)\n  const label = ref('')\n\n  const props = computed(() => {\n    return {\n      reverse: reverse.value,\n      controlVariant: controlVariant.value,\n      disabled: disabled.value || undefined,\n      label: label.value,\n      loading: loading.value || undefined,\n      hideInput: hideInput.value,\n      inset: inset.value,\n      variant: model.value !== 'default' ? model.value : undefined,\n    }\n  })\n\n  const slots = computed(() => {\n    return ``\n  })\n\n  const code = computed(() => {\n    return `<v-number-input${propsToString(props.value)}>${slots.value}</v-number-input>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-otp-input/misc-card.vue",
    "content": "<template>\n  <v-card\n    class=\"py-8 px-6 text-center mx-auto ma-4\"\n    elevation=\"4\"\n    max-width=\"400\"\n    width=\"100%\"\n  >\n    <h3 class=\"text-title-large mt-0 mb-4\">Verify Your Account</h3>\n\n    <div class=\"text-body-medium\">\n      We sent a verification code to john..@gmail.com <br>\n\n      Please check your email and paste the code below.\n    </div>\n\n    <v-sheet color=\"surface\">\n      <v-otp-input\n        v-model=\"otp\"\n        type=\"password\"\n        variant=\"solo\"\n      ></v-otp-input>\n    </v-sheet>\n\n    <v-btn\n      class=\"my-4\"\n      color=\"purple\"\n      height=\"40\"\n      text=\"Verify\"\n      variant=\"flat\"\n      width=\"70%\"\n    ></v-btn>\n\n    <div class=\"text-body-small\">\n      Didn't receive the code? <a href=\"#\" @click.prevent=\"otp = ''\">Resend</a>\n    </div>\n  </v-card>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const otp = shallowRef('')\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      otp: '',\n    }),\n  }\n</script>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2062-10241&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-otp-input/misc-divider.vue",
    "content": "<template>\n  <v-sheet\n    class=\"py-8 px-6 mx-auto ma-4 text-center\"\n    elevation=\"2\"\n    max-width=\"500\"\n    rounded=\"lg\"\n    width=\"100%\"\n  >\n    <h3 class=\"text-headline-small my-0\">Verification Code</h3>\n\n    <div class=\"text-title-small font-weight-light mb-3\">Please enter the verification code sent to your mobile</div>\n\n    <v-otp-input\n      v-model=\"otp\"\n      class=\"mb-8\"\n      divider=\"•\"\n      length=\"4\"\n      variant=\"outlined\"\n    ></v-otp-input>\n\n    <div class=\"text-body-small\">\n      <v-btn\n        color=\"primary\"\n        size=\"x-small\"\n        text=\"Send New Code\"\n        variant=\"text\"\n        @click=\"otp = ''\"\n      ></v-btn>\n    </div>\n  </v-sheet>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const otp = shallowRef('')\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      otp: '',\n    }),\n  }\n</script>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2063-78953&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-otp-input/misc-mobile.vue",
    "content": "<template>\n  <v-sheet\n    class=\"pt-8 pb-12 px-6 ma-4 mx-auto\"\n    max-width=\"350\"\n    width=\"100%\"\n    border\n  >\n    <h3 class=\"text-title-large mt-0 mb-1\">Mobile phone verification</h3>\n\n    <div class=\"text-body-medium font-weight-light\">\n      Enter the code we just sent to your mobile phone <span class=\"font-weight-black text-primary\">+1 408 555 1212</span>\n    </div>\n\n    <v-otp-input\n      v-model=\"otp\"\n      class=\"mt-3 ms-n2\"\n      length=\"4\"\n      placeholder=\"0\"\n      variant=\"underlined\"\n    ></v-otp-input>\n\n    <v-divider class=\"mt-3 mb-6\"></v-divider>\n\n    <div class=\"mb-3 text-body-medium\">\n      Need another <strong>code</strong>?\n    </div>\n\n    <v-btn\n      color=\"primary\"\n      size=\"small\"\n      text=\"Re-send Email\"\n      variant=\"tonal\"\n      @click=\"otp = ''\"\n    ></v-btn>\n  </v-sheet>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const otp = shallowRef('')\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      otp: '',\n    }),\n  }\n</script>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2063-36830&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-otp-input/misc-verify.vue",
    "content": "<template>\n  <v-card\n    class=\"py-12 px-8 text-center mx-auto ma-4\"\n    max-width=\"420\"\n    width=\"100%\"\n  >\n    <h3 class=\"text-title-large mt-0 mb-2\">\n      Please enter the one time password to verify your account\n    </h3>\n\n    <div>A code has been sent to *****2489</div>\n\n    <v-otp-input\n      v-model=\"otp\"\n      :disabled=\"validating\"\n      color=\"primary\"\n      variant=\"plain\"\n    ></v-otp-input>\n\n    <v-btn\n      :loading=\"validating\"\n      class=\"mt-6 text-none bg-surface-variant\"\n      height=\"40\"\n      text=\"Validate\"\n      variant=\"plain\"\n      width=\"135\"\n      border\n      rounded\n      @click=\"onClick\"\n    ></v-btn>\n  </v-card>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const otp = shallowRef('2401')\n  const validating = shallowRef(false)\n\n  function onClick () {\n    validating.value = true\n\n    setTimeout(() => {\n      validating.value = false\n    }, 2000)\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      otp: '',\n      validating: false,\n    }),\n\n    methods: {\n      onClick () {\n        this.validating = true\n\n        setTimeout(() => {\n          this.validating = false\n        }, 2000)\n      },\n    },\n  }\n</script>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2063-78016&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-otp-input/prop-error.vue",
    "content": "<template>\n  <v-otp-input\n    model-value=\"221\"\n    error\n  ></v-otp-input>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-otp-input/prop-focus-all.vue",
    "content": "<template>\n  <v-otp-input\n    model-value=\"425\"\n    focus-all\n    focused\n  ></v-otp-input>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-otp-input/prop-length.vue",
    "content": "<template>\n  <v-otp-input\n    length=\"7\"\n    model-value=\"3214214\"\n  ></v-otp-input>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-otp-input/prop-loader.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-otp-input\n      v-model=\"otp\"\n      :loading=\"loading\"\n      length=\"5\"\n      variant=\"underlined\"\n    ></v-otp-input>\n\n    <v-btn\n      :disabled=\"otp.length < 5 || loading\"\n      class=\"my-5\"\n      color=\"surface-variant\"\n      text=\"Submit\"\n      variant=\"tonal\"\n      @click=\"onClick\"\n    ></v-btn>\n  </div>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const loading = shallowRef(false)\n  const otp = shallowRef('31')\n\n  function onClick () {\n    loading.value = true\n\n    setTimeout(() => {\n      loading.value = false\n    }, 2000)\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      loading: false,\n      otp: '',\n    }),\n\n    methods: {\n      onClick () {\n        this.loading = true\n\n        setTimeout(() => {\n          this.loading = false\n        }, 2000)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-otp-input/prop-masked.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <h5 class=\"my-2\">(accepting only digits)</h5>\n    <v-otp-input\n      v-model=\"otp\"\n      type=\"number\"\n      masked\n    ></v-otp-input>\n\n    <div class=\"mt-2\">Value: <v-code>{{ otp }}</v-code></div>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const otp = ref('3216')\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      otp: '3216',\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-otp-input/prop-variant.vue",
    "content": "<template>\n  <v-otp-input\n    model-value=\"8011\"\n    variant=\"filled\"\n  ></v-otp-input>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-otp-input/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div class=\"text-center\">\n      <v-otp-input v-bind=\"props\"></v-otp-input>\n    </div>\n\n    <template v-slot:configuration>\n      <v-text-field v-model=\"placeholder\" label=\"Placeholder\" maxlength=\"1\" clearable></v-text-field>\n      <v-checkbox v-model=\"focus\" label=\"Focus all\"></v-checkbox>\n      <v-checkbox v-model=\"disabled\" label=\"Disabled\"></v-checkbox>\n      <v-checkbox v-model=\"loading\" label=\"Loading\"></v-checkbox>\n      <v-slider v-model=\"length\" label=\"Length\" max=\"8\" min=\"4\" step=\"1\"></v-slider>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-stepper'\n  const model = ref('default')\n  const options = ['solo', 'solo-filled', 'underlined']\n  const focus = ref(false)\n  const length = ref(6)\n  const placeholder = ref('')\n  const disabled = ref(false)\n  const loading = ref(false)\n\n  const props = computed(() => {\n    return {\n      disabled: disabled.value || undefined,\n      'focus-all': focus.value || undefined,\n      length: length.value === 6 ? undefined : length.value,\n      loading: loading.value || undefined,\n      placeholder: placeholder.value || undefined,\n      variant: model.value !== 'default' ? model.value : undefined,\n    }\n  })\n\n  const slots = computed(() => {\n    return ``\n  })\n\n  const code = computed(() => {\n    return `<v-otp-input${propsToString(props.value)}>${slots.value}</v-otp-input>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-overflow-btn/prop-counter.vue",
    "content": "<template>\n  <v-container id=\"dropdown-example-3\">\n    <v-overflow-btn\n      :items=\"dropdownEdit\"\n      class=\"my-2\"\n      item-value=\"text\"\n      label=\"Overflow Btn w/ counter\"\n      counter\n    ></v-overflow-btn>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const dropdownEdit = ref([\n    { text: '100%' },\n    { text: '75%' },\n    { text: '50%' },\n    { text: '25%' },\n    { text: '0%' },\n  ])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      dropdownEdit: [\n        { text: '100%' },\n        { text: '75%' },\n        { text: '50%' },\n        { text: '25%' },\n        { text: '0%' },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-overflow-btn/prop-dense.vue",
    "content": "<template>\n  <v-container>\n    <v-overflow-btn\n      :items=\"items\"\n      class=\"my-2\"\n      label=\"Overflow Btn - Dense\"\n      dense\n    ></v-overflow-btn>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const items = ref(['Arial', 'Calibri', 'Courier', 'Verdana'])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: ['Arial', 'Calibri', 'Courier', 'Verdana'],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-overflow-btn/prop-disabled.vue",
    "content": "<template>\n  <v-container id=\"dropdown-example-1\">\n    <v-overflow-btn\n      :items=\"dropdownFont\"\n      class=\"my-2\"\n      label=\"Overflow Btn w/ disabled\"\n      target=\"#dropdown-example-1\"\n      disabled\n    ></v-overflow-btn>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const dropdownFont = ref(['Arial', 'Calibri', 'Courier', 'Verdana'])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      dropdownFont: ['Arial', 'Calibri', 'Courier', 'Verdana'],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-overflow-btn/prop-editable.vue",
    "content": "<template>\n  <v-container id=\"dropdown-example-3\">\n    <v-overflow-btn\n      :items=\"dropdownEdit\"\n      class=\"my-2\"\n      item-value=\"text\"\n      label=\"Overflow Btn w/ editable\"\n      editable\n    ></v-overflow-btn>\n  </v-container>\n</template>\n\n<script setup>\n  const dropdownEdit = [\n    { text: '100%' },\n    { text: '75%' },\n    { text: '50%' },\n    { text: '25%' },\n    { text: '0%' },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      dropdownEdit: [\n        { text: '100%' },\n        { text: '75%' },\n        { text: '50%' },\n        { text: '25%' },\n        { text: '0%' },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-overflow-btn/prop-filled.vue",
    "content": "<template>\n  <v-container id=\"dropdown-example-1\">\n    <v-overflow-btn\n      :items=\"dropdownFont\"\n      class=\"my-2\"\n      label=\"Overflow Btn - filled\"\n      target=\"#dropdown-example-1\"\n      filled\n    ></v-overflow-btn>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const dropdownFont = ref(['Arial', 'Calibri', 'Courier', 'Verdana'])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      dropdownFont: ['Arial', 'Calibri', 'Courier', 'Verdana'],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-overflow-btn/prop-hint.vue",
    "content": "<template>\n  <v-container id=\"dropdown-example-1\">\n    <v-overflow-btn\n      :items=\"dropdownFont\"\n      class=\"my-2\"\n      hint=\"Select font\"\n      label=\"Overflow Btn w/ hint\"\n      menu-props=\"top\"\n      target=\"#dropdown-example-1\"\n    ></v-overflow-btn>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const dropdownFont = ref(['Arial', 'Calibri', 'Courier', 'Verdana'])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      dropdownFont: ['Arial', 'Calibri', 'Courier', 'Verdana'],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-overflow-btn/prop-loading.vue",
    "content": "<template>\n  <v-container id=\"dropdown-example-1\">\n    <v-overflow-btn\n      :items=\"dropdownFont\"\n      class=\"my-2\"\n      label=\"Overflow Btn w/ loading\"\n      target=\"#dropdown-example-1\"\n      loading\n    ></v-overflow-btn>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const dropdownFont = ref(['Arial', 'Calibri', 'Courier', 'Verdana'])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      dropdownFont: ['Arial', 'Calibri', 'Courier', 'Verdana'],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-overflow-btn/prop-menu-props.vue",
    "content": "<template>\n  <v-container id=\"dropdown-example-1\">\n    <v-overflow-btn\n      :items=\"dropdownFont\"\n      class=\"my-2\"\n      label=\"Overflow Btn w/ menu-props\"\n      menu-props=\"top\"\n      target=\"#dropdown-example-1\"\n    ></v-overflow-btn>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const dropdownFont = ref(['Arial', 'Calibri', 'Courier', 'Verdana'])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      dropdownFont: ['Arial', 'Calibri', 'Courier', 'Verdana'],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-overflow-btn/prop-readonly.vue",
    "content": "<template>\n  <v-container id=\"dropdown-example-1\">\n    <v-overflow-btn\n      :items=\"dropdownFont\"\n      class=\"my-2\"\n      label=\"Overflow Btn w/ readonly\"\n      target=\"#dropdown-example-1\"\n      readonly\n    ></v-overflow-btn>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const dropdownFont = ref(['Arial', 'Calibri', 'Courier', 'Verdana'])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      dropdownFont: ['Arial', 'Calibri', 'Courier', 'Verdana'],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-overflow-btn/prop-segmented.vue",
    "content": "<template>\n  <v-container id=\"dropdown-example-2\">\n    <v-overflow-btn\n      :items=\"dropdownIcon\"\n      class=\"my-2\"\n      label=\"Overflow Btn w/ segmented\"\n      target=\"#dropdown-example-2\"\n      segmented\n    ></v-overflow-btn>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const dropdownIcon = ref([\n    { text: 'list', callback: () => console.log('list') },\n    { text: 'favorite', callback: () => console.log('favorite') },\n    { text: 'delete', callback: () => console.log('delete') },\n  ])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      dropdownIcon: [\n        { text: 'list', callback: () => console.log('list') },\n        { text: 'favorite', callback: () => console.log('favorite') },\n        { text: 'delete', callback: () => console.log('delete') },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-overflow-btn/usage.vue",
    "content": "<template>\n  <v-container id=\"dropdown-playground\">\n    <v-overflow-btn\n      :items=\"dropdownFont\"\n      hint=\"I'm a hint\"\n      label=\"Overflow Btn\"\n      target=\"#dropdown-playground\"\n      v-bind=\"$attrs\"\n    ></v-overflow-btn>\n  </v-container>\n</template>\n\n<script>\n  export default {\n    name: 'Usage',\n\n    inheritAttrs: false,\n\n    data: () => ({\n      dropdownFont: [\n        { text: 'Arial', callback: () => {} },\n        { text: 'Calibri', callback: () => {} },\n        { text: 'Courier', callback: () => {} },\n        { text: 'Verdana', callback: () => {} },\n      ],\n      defaults: {\n        dense: false,\n        disabled: false,\n        editable: false,\n        filled: false,\n        loading: false,\n        overflow: false,\n        'persistent-hint': false,\n        readonly: false,\n        reverse: false,\n        segmented: false,\n      },\n      options: {\n        booleans: [\n          'dense',\n          'disabled',\n          'filled',\n          'loading',\n          'persistent-hint',\n          'readonly',\n          'reverse',\n        ],\n      },\n      tabs: ['editable', 'overflow', 'segmented'],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-overlay/connected-playground.vue",
    "content": "<template>\n  <div>\n    <v-row>\n      <v-col class=\"d-flex flex-column align-center\" cols=\"12\">\n        <code>{{ code }}</code>\n\n        <v-tooltip\n          :location=\"location\"\n          :origin=\"origin\"\n          no-click-animation\n        >\n          <template v-slot:activator=\"{ props }\">\n            <v-btn v-bind=\"props\" class=\"my-12\" text=\"Hover Me\"></v-btn>\n          </template>\n\n          <div>Overlay content</div>\n        </v-tooltip>\n      </v-col>\n\n      <v-col>\n        <v-radio-group v-model=\"locationSide\" label=\"Location side\">\n          <v-radio label=\"top\" value=\"top\"></v-radio>\n          <v-radio label=\"end\" value=\"end\"></v-radio>\n          <v-radio label=\"bottom\" value=\"bottom\"></v-radio>\n          <v-radio label=\"start\" value=\"start\"></v-radio>\n        </v-radio-group>\n      </v-col>\n\n      <v-col>\n        <v-radio-group v-model=\"locationAlign\" label=\"Location alignment\">\n          <v-radio :disabled=\"locationSide === 'top' || locationSide === 'bottom'\" label=\"top\" value=\"top\"></v-radio>\n          <v-radio :disabled=\"!(locationSide === 'top' || locationSide === 'bottom')\" label=\"start\" value=\"start\"></v-radio>\n          <v-radio label=\"center\" value=\"center\"></v-radio>\n          <v-radio :disabled=\"!(locationSide === 'top' || locationSide === 'bottom')\" label=\"end\" value=\"end\"></v-radio>\n          <v-radio :disabled=\"locationSide === 'top' || locationSide === 'bottom'\" label=\"bottom\" value=\"bottom\"></v-radio>\n        </v-radio-group>\n      </v-col>\n\n      <v-col>\n        <v-radio-group v-model=\"originSide\" label=\"Origin side\">\n          <v-radio label=\"auto\" value=\"auto\"></v-radio>\n          <v-radio label=\"overlap\" value=\"overlap\"></v-radio>\n          <v-radio label=\"top\" value=\"top\"></v-radio>\n          <v-radio label=\"end\" value=\"end\"></v-radio>\n          <v-radio label=\"bottom\" value=\"bottom\"></v-radio>\n          <v-radio label=\"start\" value=\"start\"></v-radio>\n        </v-radio-group>\n      </v-col>\n\n      <v-col>\n        <v-radio-group v-model=\"originAlign\" label=\"Origin alignment\">\n          <v-radio :disabled=\"originDisabled || originSide === 'top' || originSide === 'bottom'\" label=\"top\" value=\"top\"></v-radio>\n          <v-radio :disabled=\"originDisabled || !(originSide === 'top' || originSide === 'bottom')\" label=\"start\" value=\"start\"></v-radio>\n          <v-radio :disabled=\"originDisabled\" label=\"center\" value=\"center\"></v-radio>\n          <v-radio :disabled=\"originDisabled || !(originSide === 'top' || originSide === 'bottom')\" label=\"end\" value=\"end\"></v-radio>\n          <v-radio :disabled=\"originDisabled || originSide === 'top' || originSide === 'bottom'\" label=\"bottom\" value=\"bottom\"></v-radio>\n        </v-radio-group>\n      </v-col>\n    </v-row>\n  </div>\n</template>\n\n<script setup>\n  import { computed, ref, watch } from 'vue'\n\n  const locationSide = ref('top')\n  const locationAlign = ref('center')\n  const originSide = ref('auto')\n  const originAlign = ref('')\n\n  const location = computed(() => {\n    return `${locationSide.value} ${locationAlign.value}`\n  })\n  const origin = computed(() => {\n    return originDisabled.value ? originSide.value : `${originSide.value} ${originAlign.value}`\n  })\n  const code = computed(() => {\n    return `<v-tooltip location=\"${location.value}\" origin=\"${origin.value}\" />`\n  })\n  const originDisabled = computed(() => {\n    return ['auto', 'overlap'].includes(originSide.value)\n  })\n\n  watch(locationSide, val => {\n    if (['top', 'bottom'].includes(val)) {\n      locationAlign.value = {\n        top: 'start',\n        bottom: 'end',\n      }[locationAlign.value] || locationAlign.value\n    } else {\n      locationAlign.value = {\n        start: 'top',\n        end: 'bottom',\n      }[locationAlign.value] || locationAlign.value\n    }\n  })\n  watch(originDisabled, val => {\n    if (!val && !originAlign.value) {\n      originAlign.value = 'center'\n    }\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-overlay/misc-advanced.vue",
    "content": "<template>\n  <div>\n    <v-hover v-slot=\"{ isHovering, props }\">\n      <v-card\n        class=\"mx-auto\"\n        max-width=\"344\"\n        v-bind=\"props\"\n      >\n        <v-img src=\"https://cdn.vuetifyjs.com/images/cards/forest-art.jpg\"></v-img>\n\n        <v-card-text>\n          <h2 class=\"text-title-large text-primary my-0\">\n            Magento Forests\n          </h2>\n          Travel to the best outdoor experience on planet Earth. A vacation you will never forget!\n        </v-card-text>\n\n        <v-card-title>\n          <v-rating\n            :model-value=\"4\"\n            class=\"me-2\"\n            color=\"orange\"\n            density=\"compact\"\n            hover\n          ></v-rating>\n          <span class=\"text-primary text-title-small\">64 Reviews</span>\n        </v-card-title>\n\n        <v-overlay\n          :model-value=\"!!isHovering\"\n          class=\"align-center justify-center\"\n          scrim=\"#036358\"\n          contained\n        >\n          <v-btn variant=\"flat\">See more info</v-btn>\n        </v-overlay>\n      </v-card>\n    </v-hover>\n  </div>\n</template>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=1646-137446&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-overlay/misc-loader.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-btn\n      append-icon=\"mdi-open-in-new\"\n      color=\"deep-purple-accent-4\"\n      @click=\"overlay = !overlay\"\n    >\n      Launch Application\n    </v-btn>\n\n    <v-overlay\n      :model-value=\"overlay\"\n      class=\"align-center justify-center\"\n    >\n      <v-progress-circular\n        color=\"primary\"\n        size=\"64\"\n        indeterminate\n      ></v-progress-circular>\n    </v-overlay>\n  </div>\n</template>\n\n<script setup>\n  import { ref, watch } from 'vue'\n\n  const overlay = ref(false)\n  watch(overlay, val => {\n    val && setTimeout(() => {\n      overlay.value = false\n    }, 3000)\n  })\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      overlay: false,\n    }),\n\n    watch: {\n      overlay (val) {\n        val && setTimeout(() => {\n          this.overlay = false\n        }, 3000)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-overlay/prop-contained.vue",
    "content": "<template>\n  <v-row class=\"ma-4 align-center justify-center\">\n    <v-card\n      height=\"300\"\n      width=\"250\"\n    >\n      <v-row class=\"justify-center\">\n        <v-btn\n          class=\"mt-12\"\n          color=\"success\"\n          @click=\"overlay = !overlay\"\n        >\n          Show Overlay\n        </v-btn>\n\n        <v-overlay\n          v-model=\"overlay\"\n          class=\"align-center justify-center\"\n          contained\n        >\n          <v-btn\n            color=\"success\"\n            @click=\"overlay = false\"\n          >\n            Hide Overlay\n          </v-btn>\n        </v-overlay>\n      </v-row>\n    </v-card>\n  </v-row>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const overlay = ref(false)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      overlay: false,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-overlay/scroll-block.vue",
    "content": "<template>\n  <div class=\"d-flex justify-center\">\n    <v-btn>\n      block\n\n      <v-overlay\n        activator=\"parent\"\n        location-strategy=\"connected\"\n        scroll-strategy=\"block\"\n      >\n        <v-card class=\"pa-2\">\n          Hello!\n        </v-card>\n      </v-overlay>\n    </v-btn>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-overlay/scroll-close.vue",
    "content": "<template>\n  <div class=\"d-flex justify-center\">\n    <v-btn>\n      Close\n\n      <v-overlay\n        activator=\"parent\"\n        location-strategy=\"connected\"\n        scroll-strategy=\"close\"\n      >\n        <v-card class=\"pa-2\">\n          Hello!\n        </v-card>\n      </v-overlay>\n    </v-btn>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-overlay/scroll-none.vue",
    "content": "<template>\n  <div class=\"d-flex justify-center\">\n    <v-btn>\n      None\n\n      <v-overlay\n        activator=\"parent\"\n        location-strategy=\"connected\"\n        scroll-strategy=\"none\"\n      >\n        <v-card class=\"pa-2\">\n          Hello!\n        </v-card>\n      </v-overlay>\n    </v-btn>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-overlay/scroll-reposition.vue",
    "content": "<template>\n  <div class=\"d-flex justify-center\">\n    <v-btn>\n      Reposition\n\n      <v-overlay\n        activator=\"parent\"\n        location-strategy=\"connected\"\n        scroll-strategy=\"reposition\"\n      >\n        <v-card class=\"pa-2\">\n          Hello!\n        </v-card>\n      </v-overlay>\n    </v-btn>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-overlay/usage.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-btn\n      color=\"error\"\n      @click=\"overlay = !overlay\"\n    >\n      Show Overlay\n    </v-btn>\n\n    <v-overlay v-model=\"overlay\"></v-overlay>\n  </div>\n</template>\n\n<script>\n  export default {\n    data: () => ({\n      overlay: false,\n    }),\n\n    watch: {\n      overlay (val) {\n        val && setTimeout(() => {\n          this.overlay = false\n        }, 2000)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-pagination/prop-disabled.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-pagination\n      :length=\"3\"\n      disabled\n    ></v-pagination>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-pagination/prop-icons.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-pagination\n      v-model=\"page\"\n      :length=\"4\"\n      next-icon=\"mdi-menu-right\"\n      prev-icon=\"mdi-menu-left\"\n    ></v-pagination>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const page = ref(1)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        page: 1,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-pagination/prop-length.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-container>\n      <v-row class=\"justify-center\">\n        <v-col cols=\"8\">\n          <v-container class=\"max-width\">\n            <v-pagination\n              v-model=\"page\"\n              :length=\"15\"\n              class=\"my-4\"\n            ></v-pagination>\n          </v-container>\n        </v-col>\n      </v-row>\n    </v-container>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const page = ref(1)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        page: 1,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-pagination/prop-rounded.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-pagination\n      v-model=\"page\"\n      :length=\"4\"\n      rounded=\"circle\"\n    ></v-pagination>\n\n    <v-pagination\n      v-model=\"page\"\n      :length=\"4\"\n      rounded=\"0\"\n    ></v-pagination>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const page = ref(1)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        page: 1,\n      }\n    },\n  }\n</script>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=1906-101481&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-pagination/prop-total-visible.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-pagination\n      v-model=\"page\"\n      :length=\"15\"\n      :total-visible=\"7\"\n    ></v-pagination>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const page = ref(1)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        page: 1,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-pagination/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div>\n      <v-pagination\n        v-bind=\"props\"\n      ></v-pagination>\n    </div>\n\n    <template v-slot:configuration>\n      <v-slider v-model=\"length\" label=\"Length\" max=\"20\" min=\"1\"></v-slider>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-pagination'\n  const model = ref('default')\n  const length = ref(4)\n  const options = []\n\n  const props = computed(() => {\n    return {\n      length: length.value,\n    }\n  })\n\n  const slots = computed(() => {\n    return ''\n  })\n\n  const code = computed(() => {\n    return `<v-pagination${propsToString(props.value)}>${slots.value}</v-pagination>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-parallax/misc-content.vue",
    "content": "<template>\n  <v-parallax\n    src=\"https://cdn.vuetifyjs.com/images/backgrounds/vbanner.jpg\"\n  >\n    <div class=\"d-flex flex-column fill-height justify-center align-center text-white\">\n      <h1 class=\"text-headline-large font-weight-thin mt-0 mb-4\">\n        Vuetify\n      </h1>\n      <h4 class=\"subheading my-0\">\n        Build your application today!\n      </h4>\n    </div>\n  </v-parallax>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-parallax/misc-custom-height.vue",
    "content": "<template>\n  <v-parallax\n    height=\"300\"\n    src=\"https://cdn.vuetifyjs.com/images/parallax/material2.jpg\"\n  ></v-parallax>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-parallax/misc-welcome.vue",
    "content": "<template>\n  <v-parallax src=\"https://cdn.vuetifyjs.com/images/backgrounds/vbanner.jpg\">\n    <v-container class=\"fill-height\">\n      <v-row class=\"flex-column-reverse flex-md-row align-center justify-center\">\n        <v-col cols=\"12\" md=\"6\">\n          <h1 class=\"text-display-large mt-0 mb-8\">John Doe</h1>\n          <h3 class=\"text-display-medium mt-0 mb-8 font-weight-thin\">Web Developer</h3>\n          <v-btn class=\"elevation-2 rounded-xl mb-4\" color=\"primary\">\n            Contact Me\n          </v-btn>\n        </v-col>\n        <v-col class=\"text-center\" cols=\"12\" md=\"6\">\n          <v-avatar :size=\"300\" class=\"elevation-4 mx-auto mb-8\">\n            <v-img src=\"https://randomuser.me/api/portraits/men/78.jpg\"></v-img>\n          </v-avatar>\n        </v-col>\n      </v-row>\n    </v-container>\n  </v-parallax>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-parallax/usage.vue",
    "content": "<template>\n  <v-parallax src=\"https://cdn.vuetifyjs.com/images/parallax/material.jpg\"></v-parallax>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-pie/misc-custom-legend.vue",
    "content": "<template>\n  <div class=\"d-flex my-6 justify-center\">\n    <v-card class=\"pa-6\" elevation=\"2\" rounded=\"xl\">\n      <v-card-title class=\"d-flex align-center justify-space-between\">\n        <div class=\"text-truncate mr-6\">Expenses</div>\n        <v-select\n          v-model=\"selectedGroup\"\n          :items=\"['Transactions', 'Other']\"\n          density=\"compact\"\n          max-width=\"200\"\n          variant=\"solo-filled\"\n          flat\n          hide-details\n          single-line\n        ></v-select>\n      </v-card-title>\n\n      <v-pie\n        :key=\"selectedGroup\"\n        :items=\"currentItems\"\n        :legend=\"{ position: $vuetify.display.mdAndUp ? 'right' : 'bottom' }\"\n        :tooltip=\"{ subtitleFormat: '[value]%' }\"\n        class=\"pa-3 mt-3 justify-center\"\n        gap=\"2\"\n        inner-cut=\"70\"\n        item-key=\"id\"\n        rounded=\"2\"\n        size=\"300\"\n        animation\n        hide-slice\n        reveal\n      >\n        <template v-slot:center>\n          <div class=\"text-center\">\n            <div class=\"text-display-medium\">130</div>\n            <div class=\"opacity-70 mt-1 mb-n1\">Total</div>\n          </div>\n        </template>\n\n        <template v-slot:legend=\"{ items, toggle, isActive }\">\n          <v-list class=\"py-0 mb-n5 mb-md-0 bg-transparent\" density=\"compact\" width=\"300\">\n            <v-list-item\n              v-for=\"item in items\"\n              :key=\"item.key\"\n              :class=\"['my-1', { 'opacity-40': !isActive(item) }]\"\n              :title=\"item.title\"\n              rounded=\"lg\"\n              link\n              @click=\"toggle(item)\"\n            >\n              <template v-slot:prepend>\n                <v-avatar :color=\"item.color\" :size=\"16\"></v-avatar>\n              </template>\n              <template v-slot:append>\n                <div class=\"font-weight-bold\">{{ item.value }}%</div>\n              </template>\n            </v-list-item>\n          </v-list>\n        </template>\n      </v-pie>\n    </v-card>\n  </div>\n\n  <div class=\"h-0\">\n    <svg height=\"0\" version=\"1.1\" width=\"0\" xmlns=\"http://www.w3.org/2000/svg\">\n      <defs>\n        <pattern\n          id=\"pattern-0\"\n          height=\"20\"\n          patternTransform=\"rotate(145) scale(.2)\"\n          patternUnits=\"userSpaceOnUse\"\n          width=\"20\"\n        >\n          <path d=\"M0 10h20zm0 20h20zm0 20h20zm0 20h20z\" fill=\"none\" stroke=\"rgb(var(--v-theme-surface))\" stroke-width=\"3\" />\n        </pattern>\n      </defs>\n    </svg>\n  </div>\n</template>\n\n<script setup>\n  import { shallowRef, toRef } from 'vue'\n\n  const selectedGroup = shallowRef('Transactions')\n  const currentItems = toRef(() => selectedGroup.value === 'Transactions'\n    ? [\n      { id: 1, title: 'House & Bills', value: 40, color: 'rgba(var(--v-theme-on-surface), .2)', pattern: 'url(#pattern-0)' },\n      { id: 2, title: 'Transportation', value: 25, color: 'rgba(255, 151, 215, .4)' },\n      { id: 3, title: 'Entertainment', value: 20, color: 'rgba(255, 151, 215, .6)' },\n      { id: 4, title: 'Food', value: 10, color: 'rgba(255, 151, 215, .8)' },\n      { id: 5, title: 'Other', value: 5, color: 'rgba(255, 151, 215, 1)' },\n    ]\n    : [\n      { id: 1, title: 'OSS Donations', value: 37, color: '#767119' },\n      { id: 2, title: 'Travel', value: 22, color: '#9e850d' },\n      { id: 3, title: 'Investment', value: 20, color: '#cb9700' },\n      { id: 4, title: 'Books', value: 11, color: '#ffa600' },\n    ])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      selectedGroup: 'Transactions',\n    }),\n    computed: {\n      currentItems () {\n        return this.selectedGroup === 'Transactions'\n          ? [\n            { id: 1, title: 'House & Bills', value: 40, color: 'rgba(var(--v-theme-on-surface), .2)', pattern: 'url(#pattern-0)' },\n            { id: 2, title: 'Transportation', value: 25, color: 'rgba(255, 151, 215, .4)' },\n            { id: 3, title: 'Entertainment', value: 20, color: 'rgba(255, 151, 215, .6)' },\n            { id: 4, title: 'Food', value: 10, color: 'rgba(255, 151, 215, .8)' },\n            { id: 5, title: 'Other', value: 5, color: 'rgba(255, 151, 215, 1)' },\n          ]\n          : [\n            { id: 1, title: 'OSS Donations', value: 37, color: '#767119' },\n            { id: 2, title: 'Travel', value: 22, color: '#9e850d' },\n            { id: 3, title: 'Investment', value: 20, color: '#cb9700' },\n            { id: 4, title: 'Books', value: 11, color: '#ffa600' },\n          ]\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-pie/misc-patterns.vue",
    "content": "<template>\n  <v-container class=\"d-flex justify-center\">\n    <div class=\"h-0\">\n      <svg height=\"0\" version=\"1.1\" width=\"0\" xmlns=\"http://www.w3.org/2000/svg\">\n        <!-- source: https://pattern.monster -->\n        <defs>\n          <pattern\n            id=\"pattern-1\"\n            height=\"20\"\n            patternTransform=\"scale(.5)\"\n            patternUnits=\"userSpaceOnUse\"\n            width=\"40\"\n          >\n            <path\n              d=\"M40 0 20-10V0l20 10zm0 10L20 0v10l20 10zm0 10L20 10v10l20 10zM0 20l20-10v10L0 30zm0-10L20 0v10L0 20zM0 0l20-10V0L0 10z\"\n              fill=\"none\"\n              stroke=\"rgb(var(--v-theme-surface))\"\n            />\n          </pattern>\n          <pattern\n            id=\"pattern-2\"\n            height=\"8\"\n            patternTransform=\"scale(.5)\"\n            patternUnits=\"userSpaceOnUse\"\n            width=\"70\"\n          >\n            <path\n              d=\"M-.02 22c8.373 0 11.938-4.695 16.32-9.662C20.785 7.258 25.728 2 35 2s14.215 5.258 18.7 10.338C58.082 17.305 61.647 22 70.02 22M-.02 14.002C8.353 14 11.918 9.306 16.3 4.339 20.785-.742 25.728-6 35-6S49.215-.742 53.7 4.339c4.382 4.967 7.947 9.661 16.32 9.664M70 6.004c-8.373-.001-11.918-4.698-16.3-9.665C49.215-8.742 44.272-14 35-14S20.785-8.742 16.3-3.661C11.918 1.306 8.353 6-.02 6.002\"\n              fill=\"none\"\n              stroke=\"rgb(var(--v-theme-surface))\"\n            />\n          </pattern>\n          <pattern\n            id=\"pattern-3\"\n            height=\"10\"\n            patternTransform=\"scale(.5)\"\n            patternUnits=\"userSpaceOnUse\"\n            width=\"10\"\n          >\n            <path\n              d=\"M5 0v10ZM0 5h10Z\"\n              fill=\"none\"\n              stroke=\"rgb(var(--v-theme-surface))\"\n            />\n          </pattern>\n        </defs>\n      </svg>\n    </div>\n\n    <div class=\"d-flex mt-6 justify-center\">\n      <v-pie\n        :items=\"items\"\n        :legend=\"{ position: $vuetify.display.smAndUp ? 'left' : 'bottom' }\"\n        :tooltip=\"{ subtitleFormat: '[value]%' }\"\n        hover-scale=\".1\"\n        inner-cut=\"60\"\n        animation\n        hide-slice\n      >\n        <template v-slot:center>\n          <div class=\"text-center\">\n            <v-icon class=\"opacity-60\" icon=\"mdi-leaf\" size=\"44\"></v-icon>\n          </div>\n        </template>\n      </v-pie>\n    </div>\n  </v-container>\n</template>\n\n<script setup>\n  const items = [\n    { key: 1, title: 'Walnut', value: 57, color: '#607322', pattern: 'url(#pattern-1)' },\n    { key: 2, title: 'Oak', value: 31, color: '#c19a00', pattern: 'url(#pattern-2)' },\n    { key: 3, title: 'Pine', value: 12, color: '#ffa600', pattern: 'url(#pattern-3)' },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        { key: 1, title: 'Walnut', value: 57, color: '#607322', pattern: 'url(#pattern-1)' },\n        { key: 2, title: 'Oak', value: 31, color: '#c19a00', pattern: 'url(#pattern-2)' },\n        { key: 3, title: 'Pine', value: 12, color: '#ffa600', pattern: 'url(#pattern-3)' },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-pie/prop-formats.vue",
    "content": "<template>\n  <div class=\"d-flex justify-center py-3\">\n    <v-pie\n      :items=\"items\"\n      :legend=\"{ textFormat: '[title] ([value]%)' }\"\n      :tooltip=\"{ subtitleFormat: '[value]%' }\"\n      gap=\"4\"\n      hover-scale=\"0\"\n      inner-cut=\"85\"\n      size=\"300\"\n      animation\n      hide-slice\n    ></v-pie>\n  </div>\n</template>\n\n<script setup>\n  const items = [\n    { key: 1, title: 'TypeScript', value: 52.3, color: '#13475c' },\n    { key: 2, title: 'Elm', value: 11.6, color: '#006c71' },\n    { key: 3, title: 'CoffeeScript', value: 6.2, color: '#008e59' },\n    { key: 4, title: 'Civet', value: 3.0, color: '#ffa600' },\n    { key: 5, title: 'N/A', value: 26.9, color: '#6662' },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        { key: 1, title: 'TypeScript', value: 17674, color: '#13475c' },\n        { key: 2, title: 'Elm', value: 3550, color: '#006c71' },\n        { key: 3, title: 'CoffeeScript', value: 1251, color: '#008e59' },\n        { key: 4, title: 'Civet', value: 531, color: '#ffa600' },\n        { key: 5, title: 'N/A', value: 9821, color: '#6662' },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-pie/prop-legend.vue",
    "content": "<template>\n  <v-container class=\"d-flex flex-column align-center justify-center\">\n    <v-select\n      v-model=\"legendMode\"\n      :items=\"[\n        { prependIcon: 'mdi-arrow-up', value: 'top', title :'top' },\n        { prependIcon: 'mdi-arrow-right', value: 'right', title :'right' },\n        { prependIcon: 'mdi-arrow-down', value: 'bottom', title :'bottom' },\n        { prependIcon: 'mdi-arrow-left', value: 'left', title :'left' },\n        { prependIcon: 'mdi-eye-off', value: 'hidden', title :'hidden' },\n      ]\"\n      prefix=\"Legend mode: \"\n      rounded=\"xl\"\n      variant=\"solo\"\n      width=\"350\"\n      item-props\n      single-line\n    ></v-select>\n\n    <v-sheet class=\"pa-6\" elevation=\"2\" rounded=\"xl\">\n      <v-pie\n        :items=\"items\"\n        :legend=\"legendConfig\"\n        :tooltip=\"{ subtitleFormat: (s) => `${formatNumber(s.value)} respondents (${(100 * s.value / total).toFixed(1)}%)` }\"\n        inner-cut=\"85\"\n        size=\"300\"\n        animation\n        hide-slice\n      >\n        <template v-slot:legend-text=\"{ item }\">\n          <div class=\"d-flex ga-6\">\n            <div>{{ item.title }}</div>\n\n            <div class=\"ml-auto font-weight-bold\">\n              {{ formatNumber(item.value) }}\n            </div>\n          </div>\n        </template>\n      </v-pie>\n    </v-sheet>\n  </v-container>\n</template>\n\n<script setup>\n  import { computed, ref, watch } from 'vue'\n\n  const numberFormatter = new Intl.NumberFormat('en', { useGrouping: true })\n  function formatNumber (v) {\n    return numberFormatter.format(v)\n  }\n\n  const legendMode = ref('right')\n  const legendConfig = ref({ position: 'right' })\n  const items = [\n    { key: 2, title: 'Google', value: 75, color: '#0080bb' },\n    { key: 1, title: 'Bing', value: 20, color: '#58508d' },\n    { key: 3, title: 'DuckDuckGo', value: 17, color: '#bc5090' },\n    { key: 4, title: 'Brave', value: 15, color: '#ff6361' },\n    { key: 5, title: 'Kagi', value: 5, color: '#ffa600' },\n  ]\n  const total = computed(() => items.reduce((sum, n) => sum + n.value, 0))\n\n  watch(legendMode, mode => {\n    legendConfig.value = mode === 'hidden'\n      ? { visible: false }\n      : { position: mode }\n  })\n</script>\n\n<script>\n  const numberFormatter = new Intl.NumberFormat('en', { useGrouping: true })\n  export default {\n    data: () => ({\n      legendMode: 'right',\n      legendConfig: { position: 'right' },\n      items: [\n        { key: 2, title: 'Google', value: 75, color: '#0080bb' },\n        { key: 1, title: 'Bing', value: 20, color: '#58508d' },\n        { key: 3, title: 'DuckDuckGo', value: 17, color: '#bc5090' },\n        { key: 4, title: 'Brave', value: 15, color: '#ff6361' },\n        { key: 5, title: 'Kagi', value: 5, color: '#ffa600' },\n      ],\n    }),\n    computed: {\n      total () {\n        return this.items.reduce((sum, n) => sum + n.value, 0)\n      },\n    },\n    watch: {\n      legendMode (mode) {\n        this.legendConfig = mode === 'hidden'\n          ? { visible: false }\n          : { position: mode }\n      },\n    },\n    methods: {\n      formatNumber (v) {\n        return numberFormatter.format(v)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-pie/prop-palette.vue",
    "content": "<template>\n  <div class=\"d-flex justify-center py-6\">\n    <div class=\"h-0\">\n      <svg height=\"0\" version=\"1.1\" width=\"0\" xmlns=\"http://www.w3.org/2000/svg\">\n        <defs>\n          <pattern\n            id=\"pattern-0\"\n            height=\"20\"\n            patternTransform=\"rotate(145) scale(.2)\"\n            patternUnits=\"userSpaceOnUse\"\n            width=\"20\"\n          >\n            <path d=\"M0 10h20zm0 20h20zm0 20h20zm0 20h20z\" fill=\"none\" stroke=\"rgb(var(--v-theme-surface))\" stroke-width=\"3\" />\n          </pattern>\n        </defs>\n      </svg>\n    </div>\n\n    <div class=\"d-flex flex-wrap justify-center align-center ga-12\">\n      <v-pie\n        :items=\"items\"\n        :palette=\"palettes[currentPalette]\"\n        hover-scale=\"0\"\n        inner-cut=\"75\"\n        hide-slice\n        tooltip\n      ></v-pie>\n\n      <v-list v-model:selected=\"currentPalette\" class=\"flex-shrink-0 py-0 bg-transparent\" mandatory selectable>\n        <v-list-item v-for=\"(palette, pi) in palettes\" :key=\"pi\" :value=\"pi\" border=\"t b\">\n          <v-avatar\n            v-for=\"(c, ci) in palette\"\n            :key=\"ci\"\n            :color=\"c.color || c\"\n            class=\"ma-2 elevation-1\"\n            rounded=\"lg\"\n            size=\"24\"\n          >\n            <svg v-if=\"c.pattern\" height=\"24\" width=\"24\">\n              <rect :fill=\"c.pattern\" height=\"24\" width=\"24\" />\n            </svg>\n          </v-avatar>\n        </v-list-item>\n      </v-list>\n    </div>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const currentPalette = ref(0)\n  const palettes = [\n    ['#00876c', '#88af77', '#e3d49c', '#df915c', '#d43d51'],\n    ['#004c6d', '#056890', '#0885b4', '#08a4d9', '#00c4ff'],\n    ['#003f5c', '#58508d', '#bc5090', '#ff6361', '#ffa600'],\n    [{ color: '#1dc690', pattern: 'url(#pattern-0)' }, '#278ab0', '#1c4670', '#7a7aff', '#daba50'],\n  ]\n\n  const items = [\n    { key: 1, title: 'TypeScript', value: 52.3 },\n    { key: 2, title: 'Elm', value: 11.6 },\n    { key: 3, title: 'CoffeeScript', value: 6.2 },\n    { key: 4, title: 'Civet', value: 3.0 },\n    { key: 5, title: 'N/A', value: 26.9 },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      currentPalette: 0,\n      palettes: [\n        ['#00876c', '#88af77', '#e3d49c', '#df915c', '#d43d51'],\n        ['#004c6d', '#056890', '#0885b4', '#08a4d9', '#00c4ff'],\n        ['#003f5c', '#58508d', '#bc5090', '#ff6361', '#ffa600'],\n        [{ color: '#1dc690', pattern: 'url(#pattern-0)' }, '#278ab0', '#1c4670', '#7a7aff', '#daba50'],\n      ],\n      items: [\n        { key: 1, title: 'TypeScript', value: 17674 },\n        { key: 2, title: 'Elm', value: 3550 },\n        { key: 3, title: 'CoffeeScript', value: 1251 },\n        { key: 4, title: 'Civet', value: 531 },\n        { key: 5, title: 'N/A', value: 9821 },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-pie/prop-size.vue",
    "content": "<template>\n  <v-container class=\"d-flex flex-wrap justify-center align-start ga-6\" fluid>\n\n    <div>\n      <v-sheet class=\"pa-3\" rounded=\"xl\" variant=\"outlined\">\n        <v-pie :items=\"items\" hover-scale=\".2\" size=\"150\"></v-pie>\n      </v-sheet>\n      <ul class=\"mt-3 pl-6\">\n        <li><v-code>size: 150px</v-code></li>\n        <li><v-code>20% reserved</v-code></li>\n      </ul>\n    </div>\n\n    <v-divider class=\"hidden-sm-and-down\" vertical></v-divider>\n\n    <div>\n      <v-sheet class=\"pa-3\" rounded=\"xl\" variant=\"outlined\">\n        <v-pie :items=\"items\" hover-scale=\".1\" size=\"200\"></v-pie>\n      </v-sheet>\n      <ul class=\"mt-3 pl-6\">\n        <li><v-code>size: 200px</v-code></li>\n        <li><v-code>10% reserved</v-code></li>\n      </ul>\n    </div>\n\n    <v-divider class=\"hidden-sm-and-down\" vertical></v-divider>\n\n    <div>\n      <v-sheet class=\"pa-3\" rounded=\"xl\" variant=\"outlined\">\n        <v-pie :items=\"items\" hover-scale=\"0\" size=\"250\"></v-pie>\n      </v-sheet>\n      <ul class=\"mt-3 pl-6\">\n        <li><v-code>size: 250px</v-code></li>\n        <li><v-code>no zoom on hover</v-code></li>\n      </ul>\n    </div>\n\n  </v-container>\n</template>\n\n<script setup>\n  const items = [\n    { key: 1, title: 'Series A', value: 45, color: '#2b6d40' },\n    { key: 2, title: 'Series B', value: 30, color: '#4e9963' },\n    { key: 3, title: 'Series C', value: 15, color: '#72c789' },\n    { key: 4, title: 'Series D', value: 10, color: '#97f7b0' },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        { key: 1, title: 'Series A', value: 45, color: '#2b6d40' },\n        { key: 2, title: 'Series B', value: 30, color: '#4e9963' },\n        { key: 3, title: 'Series C', value: 15, color: '#72c789' },\n        { key: 4, title: 'Series D', value: 10, color: '#97f7b0' },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-pie/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n    :script=\"script\"\n  >\n    <div class=\"d-flex justify-center\">\n      <v-pie :key=\"reveal\" v-bind=\"{ ...props, items }\"></v-pie>\n    </div>\n\n    <template v-slot:configuration>\n      <div class=\"d-flex flex-column ga-2\">\n        <v-checkbox v-model=\"animation\" label=\"Animate on interaction\" hide-details></v-checkbox>\n        <v-checkbox v-model=\"legend\" label=\"Show legend\" hide-details></v-checkbox>\n        <v-checkbox v-model=\"tooltip\" label=\"Show tooltip\" hide-details></v-checkbox>\n        <v-checkbox v-model=\"reveal\" label=\"Reveal animation\" hide-details></v-checkbox>\n\n        <v-slider\n          v-if=\"model !== 'gauge'\"\n          v-model=\"rotate\"\n          label=\"Rotation\"\n          max=\"180\"\n          min=\"0\"\n        ></v-slider>\n\n        <v-slider\n          v-model=\"size\"\n          label=\"Size\"\n          max=\"400\"\n          min=\"150\"\n        ></v-slider>\n\n        <template v-if=\"model !== 'default'\">\n          <v-slider\n            v-model=\"innerCut\"\n            label=\"Inner cut\"\n            max=\"99\"\n            min=\"0\"\n          ></v-slider>\n\n          <v-slider\n            v-model=\"gap\"\n            label=\"Gap\"\n            max=\"10\"\n            min=\"0\"\n          ></v-slider>\n\n          <v-slider\n            v-model=\"rounded\"\n            label=\"Rounded\"\n            max=\"10\"\n            min=\"0\"\n          ></v-slider>\n\n          <v-slider\n            v-if=\"model === 'gauge'\"\n            v-model=\"gaugeCut\"\n            label=\"Gauge cut\"\n            max=\"220\"\n            min=\"100\"\n          ></v-slider>\n\n          <v-checkbox\n            v-if=\"model !== 'gauge'\"\n            v-model=\"hideSlice\"\n            label=\"Hide inner slice\"\n          ></v-checkbox>\n        </template>\n      </div>\n\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-pie'\n  const model = ref('default')\n  const options = ['donut', 'gauge']\n  const items = [\n    { key: 1, title: 'Yes', value: 45 },\n    { key: 2, title: 'No', value: 40 },\n    { key: 3, title: 'Maybe', value: 15 },\n  ]\n  const animation = ref(false)\n  const legend = ref(false)\n  const tooltip = ref(false)\n  const hideSlice = ref(true)\n  const reveal = ref(false)\n  const size = ref(250)\n\n  const innerCut = ref(85)\n  const rotate = ref()\n  const rounded = ref(0)\n  const gap = ref(0)\n  const gaugeCut = ref(120)\n  const props = computed(() => {\n    return {\n      title: { default: 'Basic pie', donut: 'Do you like donuts?' }[model.value],\n      gap: (model.value !== 'default' && gap.value) || undefined,\n      'gauge-cut': (model.value === 'gauge' && gaugeCut.value) || undefined,\n      'hide-slice': model.value === 'gauge' || (model.value === 'donut' && hideSlice.value) || undefined,\n      'inner-cut': model.value !== 'default' ? innerCut.value : undefined,\n      animation: animation.value || undefined,\n      legend: legend.value || undefined,\n      palette: ['#048BA8', '#99C24D', '#F18F01'],\n      rotate: rotate.value || undefined,\n      rounded: (model.value !== 'default' && rounded.value) || undefined,\n      size: size.value !== 250 ? size.value : undefined,\n      tooltip: tooltip.value || undefined,\n      reveal: reveal.value || undefined,\n    }\n  })\n\n  const script = computed(() => {\n    function itemToString ({ key, title, value }) {\n      return `    { key: ${key}, title: \"${title}\", value: ${value} },`\n    }\n\n    return `<script setup>\n  const items = [\n${items.map(itemToString).join('\\n')}\n  ]\n<` + '/script>'\n  })\n\n  const code = computed(() => {\n    return `<${name} ${propsToString(props.value)}  :items=\"items\"\n/>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-progress/misc-card-loader.vue",
    "content": "<template>\n  <v-card\n    border=\"md opacity-30\"\n    class=\"mx-auto pa-1\"\n    height=\"300\"\n    rounded=\"xl\"\n    variant=\"outlined\"\n    width=\"300\"\n  >\n    <v-fade-transition mode=\"out-in\">\n      <v-img\n        v-if=\"done\"\n        key=\"image\"\n        height=\"292\"\n        src=\"https://cdn.vuetifyjs.com/images/carousel/sky.jpg\"\n        style=\"border-radius: 18px;\"\n        cover\n      ></v-img>\n\n      <v-progress\n        v-else\n        :model-value=\"progress\"\n        details-position=\"bottom\"\n        label=\"Loading application\"\n        absolute\n        hide-label\n      >\n        <template v-slot:default=\"{ percent }\">\n          <v-progress-circular\n            :model-value=\"percent\"\n            color=\"lime-darken-2\"\n            rotate=\"180\"\n            size=\"140\"\n            width=\"6\"\n            rounded\n          >\n            <div class=\"d-flex align-baseline mr-n3\">\n              <div class=\"text-headline-large text-medium-emphasis\">\n                {{ percent.toFixed() }}\n              </div>\n              <span class=\"ml-1\">%</span>\n            </div>\n          </v-progress-circular>\n        </template>\n\n        <template v-slot:value=\"{ percent }\">\n          <div class=\"text-body-medium\">\n            <v-scroll-y-transition mode=\"out-in\">\n              <div v-if=\"percent > 75\" key=\"finalizing\">Finalizing...</div>\n              <div v-else key=\"loading\">Loading...</div>\n            </v-scroll-y-transition>\n          </div>\n        </template>\n      </v-progress>\n    </v-fade-transition>\n  </v-card>\n</template>\n\n<script setup lang=\"ts\">\n  import { onUnmounted, shallowRef } from 'vue'\n\n  const progress = shallowRef(0)\n  const done = shallowRef(false)\n  let timer: ReturnType<typeof setInterval>\n\n  function startLoading () {\n    done.value = false\n    progress.value = 0\n    timer = setInterval(() => {\n      progress.value += progress.value > 70 ? 4 : 7.5\n      if (progress.value >= 100) {\n        clearInterval(timer)\n        done.value = true\n        setTimeout(startLoading, 4000)\n      }\n    }, 600)\n  }\n\n  startLoading()\n\n  onUnmounted(() => clearInterval(timer))\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-progress/prop-label.vue",
    "content": "<template>\n  <v-container>\n    <v-row>\n      <v-col cols=\"12\" md=\"6\">\n        <v-progress\n          :model-value=\"65\"\n          color=\"primary\"\n          label=\"Downloading...\"\n        ></v-progress>\n      </v-col>\n\n      <v-col cols=\"12\" md=\"6\">\n        <v-progress\n          :model-value=\"40\"\n          color=\"warning\"\n          label=\"Operation in progress...\"\n          label-position=\"bottom\"\n          hide-value\n          indeterminate\n        ></v-progress>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-progress/prop-value-format.vue",
    "content": "<template>\n  <v-container>\n    <v-row>\n      <v-col cols=\"12\" md=\"6\">\n        <v-progress\n          label=\"Uploading...\"\n          max=\"76.8\"\n          model-value=\"15.2\"\n          value-format=\"[value] / [max] GB\"\n        ></v-progress>\n      </v-col>\n\n      <v-col cols=\"12\" md=\"6\">\n        <v-progress\n          :value-format=\"formatUploaded\"\n          label=\"Processing...\"\n          max=\"120\"\n          model-value=\"65\"\n        ></v-progress>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script lang=\"ts\" setup>\n  function formatUploaded ({ value, max } : { value: number, max: number }) {\n    return `${Math.floor(value)} out of ${max} items`\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-progress/slot-label-and-value.vue",
    "content": "<template>\n  <v-sheet\n    class=\"py-6 px-6 mx-auto\"\n    color=\"deep-purple-lighten-5\"\n    max-width=\"400\"\n    rounded=\"xl\"\n    variant=\"flat\"\n  >\n\n    <div class=\"d-flex align-baseline ga-2\">\n      <span class=\"text-display-large text-deep-purple font-weight-bold\">{{ uploaded.value }}</span>{{ uploaded.unit }}\n    </div>\n    <v-progress\n      :max=\"totalBytes\"\n      :model-value=\"uploadedBytes\"\n      color=\"deep-purple\"\n      details-position=\"bottom\"\n      label=\"Transfer progress\"\n      rounded\n    >\n      <template v-slot:label>~5 mins to transfer</template>\n      <template v-slot:value>{{ total.value }} {{ total.unit }} total</template>\n    </v-progress>\n  </v-sheet>\n</template>\n\n<script setup lang=\"ts\">\n  import { computed, onUnmounted, shallowRef } from 'vue'\n\n  const totalBytes = 2 * 1024 * 1024 * 1024 // 128 GB\n  const uploadedBytes = shallowRef(0)\n  const increment = totalBytes / 50 // finish in ~25s\n\n  const interval = setInterval(() => {\n    uploadedBytes.value += increment\n    if (uploadedBytes.value >= totalBytes) {\n      uploadedBytes.value = 0\n    }\n  }, 500)\n\n  onUnmounted(() => clearInterval(interval))\n\n  function formatBytes (v: number) {\n    if (Number.isNaN(Number(v))) return { value: 0, unit: 'B' }\n\n    const kB = v / 1024\n    if (kB < 1) return { value: Math.round(v), unit: 'B' }\n\n    const MB = kB / 1024\n    if (MB < 1) return { value: Math.round(kB * 10) / 10, unit: 'kB' }\n\n    const GB = MB / 1024\n    if (GB < 1) return { value: Math.round(MB * 10) / 10, unit: 'MB' }\n\n    return { value: Math.round(GB * 10) / 10, unit: 'GB' }\n  }\n\n  const total = computed(() => formatBytes(totalBytes))\n  const uploaded = computed(() => formatBytes(uploadedBytes.value))\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-progress/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <v-container max-width=\"400\">\n      <v-progress v-bind=\"props\"></v-progress>\n    </v-container>\n\n    <template v-slot:configuration>\n      <v-slider\n        v-model=\"value\"\n        :max=\"100\"\n        :min=\"0\"\n        label=\"Value\"\n      ></v-slider>\n\n      <v-select\n        v-model=\"color\"\n        :items=\"['primary', 'warning', 'success', 'teal-accent-3']\"\n        label=\"Color\"\n        clearable\n      ></v-select>\n\n      <v-select\n        v-model=\"detailsPosition\"\n        :items=\"['top', 'bottom']\"\n        label=\"Details position\"\n      ></v-select>\n\n      <v-checkbox-btn v-model=\"hideLabel\" label=\"Hide label\"></v-checkbox-btn>\n\n      <v-checkbox-btn v-model=\"hideValue\" label=\"Hide value\"></v-checkbox-btn>\n\n      <v-checkbox-btn v-model=\"indeterminate\" label=\"Indeterminate\"></v-checkbox-btn>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-progress'\n  const model = shallowRef('default')\n  const options = ['circular']\n  const value = shallowRef(50)\n  const color = shallowRef('primary')\n  const hideLabel = shallowRef(false)\n  const hideValue = shallowRef(false)\n  const indeterminate = shallowRef(false)\n  const detailsPosition = shallowRef('top')\n\n  const props = computed(() => {\n    return {\n      color: color.value || undefined,\n      'hide-label': hideLabel.value || undefined,\n      'hide-value': hideValue.value || undefined,\n      indeterminate: indeterminate.value || undefined,\n      label: 'Loading...',\n      'details-position': detailsPosition.value !== 'top' ? detailsPosition.value : undefined,\n      'model-value': value.value,\n      type: model.value !== 'default' ? model.value : undefined,\n    }\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}></${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-progress-circular/prop-color.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-progress-circular\n      color=\"blue-grey\"\n      model-value=\"100\"\n    ></v-progress-circular>\n\n    <v-progress-circular\n      color=\"deep-orange-lighten-2\"\n      model-value=\"80\"\n    ></v-progress-circular>\n\n    <v-progress-circular\n      color=\"brown\"\n      model-value=\"60\"\n    ></v-progress-circular>\n\n    <v-progress-circular\n      color=\"lime\"\n      model-value=\"40\"\n    ></v-progress-circular>\n\n    <v-progress-circular\n      color=\"indigo-darken-2\"\n      model-value=\"20\"\n    ></v-progress-circular>\n  </div>\n</template>\n\n<style scoped>\n.v-progress-circular {\n  margin: 1rem;\n}\n</style>\n"
  },
  {
    "path": "packages/docs/src/examples/v-progress-circular/prop-indeterminate.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-progress-circular\n      color=\"primary\"\n      indeterminate\n    ></v-progress-circular>\n\n    <v-progress-circular\n      color=\"red\"\n      indeterminate\n    ></v-progress-circular>\n\n    <v-progress-circular\n      color=\"purple\"\n      indeterminate\n    ></v-progress-circular>\n\n    <v-progress-circular\n      color=\"green\"\n      indeterminate\n    ></v-progress-circular>\n\n    <v-progress-circular\n      color=\"amber\"\n      indeterminate\n    ></v-progress-circular>\n  </div>\n</template>\n\n<style scoped>\n.v-progress-circular {\n  margin: 1rem;\n}\n</style>\n"
  },
  {
    "path": "packages/docs/src/examples/v-progress-circular/prop-reveal.vue",
    "content": "<template>\n  <div>\n    <v-container class=\"d-flex flex-wrap ga-4 px-0 justify-center\">\n      <v-card\n        v-for=\"(c, i) in cards\"\n        :key=\"i\"\n        elevation=\"6\"\n        mode=\"out-in\"\n        rounded=\"pill\"\n        width=\"330\"\n      >\n        <div class=\"d-flex align-center pa-3 justify-space-between\">\n          <div class=\"mt-n2\">\n            <v-card-title v-text=\"c.title\"></v-card-title>\n            <v-card-subtitle class=\"mt-n1\" v-text=\"c.subtitle\"></v-card-subtitle>\n          </div>\n          <v-progress-circular\n            :key=\"`${updateTrigger}_${i}`\"\n            :model-value=\"c.value\"\n            :size=\"100\"\n            :width=\"12\"\n            bg-color=\"surface-light\"\n            class=\"ma-3\"\n            color=\"orange-accent-2\"\n            reveal\n            rounded\n          >\n            <v-avatar color=\"surface-light\" size=\"70\">{{ c.value }}%</v-avatar>\n          </v-progress-circular>\n        </div>\n      </v-card>\n    </v-container>\n    <div class=\"d-flex justify-center\">\n      <v-btn color=\"primary\" text=\"Reload\" @click=\"updateTrigger++\"></v-btn>\n    </div>\n  </div>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const updateTrigger = shallowRef(0)\n\n  const cards = [\n    { title: 'CPU Usage', subtitle: '0.63 / 2 units', value: 31.5 },\n    { title: 'Memory Usage', subtitle: '13.43 / 16 GB', value: 83.9 },\n  ]\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        updateTrigger: 0,\n        cards: [\n          { title: 'CPU Usage', subtitle: '0.23 / 2 units', value: 11.3 },\n          { title: 'Memory Usage', subtitle: '6.43 / 16 GB', value: 40.1 },\n          { title: 'Nodes', subtitle: '1 / 1 Ready', value: 100 },\n        ],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-progress-circular/prop-rotate.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-progress-circular\n      :model-value=\"value\"\n      :rotate=\"360\"\n      :size=\"100\"\n      :width=\"15\"\n      color=\"teal\"\n    >\n      {{ value }}\n    </v-progress-circular>\n\n    <v-progress-circular\n      :model-value=\"value\"\n      :rotate=\"-90\"\n      :size=\"100\"\n      :width=\"15\"\n      color=\"primary\"\n    >\n      {{ value }}\n    </v-progress-circular>\n\n    <v-progress-circular\n      :model-value=\"value\"\n      :rotate=\"90\"\n      :size=\"100\"\n      :width=\"15\"\n      color=\"red\"\n    >\n      {{ value }}\n    </v-progress-circular>\n\n    <v-progress-circular\n      :model-value=\"value\"\n      :rotate=\"180\"\n      :size=\"100\"\n      :width=\"15\"\n      color=\"pink\"\n    >\n      {{ value }}\n    </v-progress-circular>\n  </div>\n</template>\n\n<script setup>\n  import { onBeforeUnmount, onMounted, ref } from 'vue'\n\n  const value = ref(0)\n\n  let interval = -1\n  onMounted(() => {\n    interval = setInterval(() => {\n      if (value.value === 100) {\n        return (value.value = 0)\n      }\n      value.value += 10\n    }, 1000)\n  })\n  onBeforeUnmount(() => {\n    clearInterval(interval)\n  })\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        interval: {},\n        value: 0,\n      }\n    },\n    beforeUnmount () {\n      clearInterval(this.interval)\n    },\n    mounted () {\n      this.interval = setInterval(() => {\n        if (this.value === 100) {\n          return (this.value = 0)\n        }\n        this.value += 10\n      }, 1000)\n    },\n  }\n</script>\n\n<style scoped>\n.v-progress-circular {\n  margin: 1rem;\n}\n</style>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2747-79337&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-progress-circular/prop-size-and-width.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-progress-circular\n      :size=\"50\"\n      color=\"primary\"\n      indeterminate\n    ></v-progress-circular>\n\n    <v-progress-circular\n      :width=\"3\"\n      color=\"red\"\n      indeterminate\n    ></v-progress-circular>\n\n    <v-progress-circular\n      :size=\"70\"\n      :width=\"7\"\n      color=\"purple\"\n      indeterminate\n    ></v-progress-circular>\n\n    <v-progress-circular\n      :width=\"3\"\n      color=\"green\"\n      indeterminate\n    ></v-progress-circular>\n\n    <v-progress-circular\n      :size=\"50\"\n      color=\"amber\"\n      indeterminate\n    ></v-progress-circular>\n  </div>\n</template>\n\n<style scoped>\n.v-progress-circular {\n  margin: 1rem;\n}\n</style>\n"
  },
  {
    "path": "packages/docs/src/examples/v-progress-circular/prop-slot-default.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-progress-circular :model-value=\"value\" :rotate=\"360\" :size=\"100\" :width=\"15\" color=\"teal\">\n      <template v-slot:default> {{ value }} % </template>\n    </v-progress-circular>\n  </div>\n</template>\n\n<script setup>\n  import { onBeforeUnmount, onMounted, ref } from 'vue'\n\n  const value = ref(0)\n\n  let interval = -1\n  onMounted(() => {\n    interval = setInterval(() => {\n      if (value.value === 100) {\n        return (value.value = 0)\n      }\n      value.value += 10\n    }, 1000)\n  })\n  onBeforeUnmount(() => {\n    clearInterval(interval)\n  })\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        interval: -1,\n        value: 0,\n      }\n    },\n    mounted () {\n      this.interval = setInterval(() => {\n        if (this.value === 100) {\n          return (this.value = 0)\n        }\n        this.value += 10\n      }, 1000)\n    },\n    beforeUnmount () {\n      clearInterval(this.interval)\n    },\n  }\n</script>\n\n<style scoped>\n.v-progress-circular {\n  margin: 1rem;\n}\n</style>\n"
  },
  {
    "path": "packages/docs/src/examples/v-progress-circular/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div class=\"text-center\">\n      <v-progress-circular v-bind=\"props\"></v-progress-circular>\n    </div>\n\n    <template v-slot:configuration>\n      <v-select\n        v-model=\"color\"\n        :items=\"['primary', 'blue-lighten-3', 'error', 'dark-blue']\"\n        label=\"Color\"\n        clearable\n      ></v-select>\n\n      <v-slider\n        v-model=\"size\"\n        label=\"Size\"\n        max=\"128\"\n        min=\"32\"\n        step=\"1\"\n      ></v-slider>\n\n      <v-slider\n        v-model=\"width\"\n        label=\"Width\"\n        max=\"12\"\n        min=\"4\"\n        step=\"1\"\n      ></v-slider>\n\n      <v-checkbox v-model=\"indeterminate\" label=\"Indeterminate\"></v-checkbox>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-progress-circular'\n  const model = ref('default')\n  const color = ref()\n  const indeterminate = ref(false)\n  const size = ref()\n  const width = ref()\n  const options = []\n  const props = computed(() => {\n    return {\n      color: color.value || undefined,\n      indeterminate: indeterminate.value || undefined,\n      'model-value': !indeterminate.value ? '20' : undefined,\n      size: size.value !== 32 ? size.value : undefined,\n      width: width.value !== 4 ? width.value : undefined,\n    }\n  })\n\n  const slots = computed(() => {\n    return ``\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-progress-linear/misc-buffer-color.vue",
    "content": "<template>\n  <v-sheet\n    class=\"d-flex align-center px-4 py-8 mx-auto\"\n    color=\"#181a1b\"\n    max-width=\"250\"\n    rounded=\"lg\"\n  >\n    <v-progress-linear\n      :location=\"null\"\n      bg-color=\"#92aed9\"\n      buffer-color=\"#6a3e0b\"\n      buffer-opacity=\"1\"\n      buffer-value=\"3\"\n      color=\"#12512a\"\n      height=\"12\"\n      max=\"9\"\n      min=\"0\"\n      model-value=\"2\"\n      rounded\n    ></v-progress-linear>\n\n    <div class=\"ms-4 text-title-large\">3/9</div>\n  </v-sheet>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-progress-linear/misc-determinate.vue",
    "content": "<template>\n  <div>\n    <v-progress-linear\n      v-model=\"valueDeterminate\"\n      color=\"deep-purple-accent-4\"\n    ></v-progress-linear>\n    <br>\n    <v-progress-linear\n      v-model=\"valueDeterminate\"\n      color=\"pink\"\n    ></v-progress-linear>\n    <br>\n    <v-progress-linear\n      v-model=\"valueDeterminate\"\n      color=\"indigo-darken-2\"\n    ></v-progress-linear>\n    <br>\n    <v-progress-linear\n      v-model=\"valueDeterminate\"\n      color=\"amber\"\n    ></v-progress-linear>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const valueDeterminate = ref(50)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        valueDeterminate: 50,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-progress-linear/misc-file-loader.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"344\"\n  >\n    <v-toolbar color=\"deep-purple-accent-4\">\n      <v-app-bar-nav-icon></v-app-bar-nav-icon>\n\n      <v-toolbar-title>My Files</v-toolbar-title>\n\n      <v-btn\n        color=\"white\"\n        location=\"bottom left\"\n        absolute\n        icon\n      >\n        <v-icon>mdi-plus</v-icon>\n      </v-btn>\n\n      <v-btn icon>\n        <v-icon>mdi-share-variant</v-icon>\n      </v-btn>\n\n      <v-btn icon>\n        <v-icon>mdi-magnify</v-icon>\n      </v-btn>\n\n      <v-btn icon>\n        <v-icon>mdi-dots-vertical</v-icon>\n      </v-btn>\n    </v-toolbar>\n\n    <v-container style=\"height: 400px;\">\n      <v-row class=\"fill-height align-content-center justify-center\">\n        <v-col\n          class=\"text-body-large text-center\"\n          cols=\"12\"\n        >\n          Getting your files\n        </v-col>\n        <v-col cols=\"6\">\n          <v-progress-linear\n            color=\"deep-purple-accent-4\"\n            height=\"6\"\n            indeterminate\n            rounded\n          ></v-progress-linear>\n        </v-col>\n      </v-row>\n    </v-container>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-progress-linear/misc-toolbar-loader.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto mt-6\"\n    width=\"344\"\n  >\n    <v-toolbar>\n      <v-btn icon>\n        <v-icon>mdi-arrow-left</v-icon>\n      </v-btn>\n\n      <v-toolbar-title>My Recipes</v-toolbar-title>\n\n      <v-progress-linear\n        :active=\"loading\"\n        :indeterminate=\"loading\"\n        color=\"deep-purple-accent-4\"\n        location=\"bottom\"\n        absolute\n      ></v-progress-linear>\n\n      <v-btn icon>\n        <v-icon>mdi-magnify</v-icon>\n      </v-btn>\n\n      <v-btn icon>\n        <v-icon>mdi-dots-vertical</v-icon>\n      </v-btn>\n    </v-toolbar>\n\n    <v-container style=\"height: 282px;\">\n      <v-row class=\"fill-height align-center justify-center\">\n        <v-scale-transition>\n          <div\n            v-if=\"!loading\"\n            class=\"text-center\"\n          >\n            <v-btn\n              color=\"primary\"\n              @click=\"loading = true\"\n            >\n              Start loading\n            </v-btn>\n          </div>\n        </v-scale-transition>\n      </v-row>\n    </v-container>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref, watch } from 'vue'\n\n  const loading = ref(false)\n\n  watch(loading, val => {\n    if (!val) return\n    setTimeout(() => (loading.value = false), 3000)\n  })\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      loading: false,\n    }),\n\n    watch: {\n      loading (val) {\n        if (!val) return\n\n        setTimeout(() => (this.loading = false), 3000)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-progress-linear/prop-buffer-value.vue",
    "content": "<template>\n  <div>\n    <v-progress-linear\n      v-model=\"value\"\n      :buffer-value=\"bufferValue\"\n    ></v-progress-linear>\n    <br>\n    <v-progress-linear\n      v-model=\"value\"\n      :buffer-value=\"bufferValue\"\n      color=\"purple\"\n    ></v-progress-linear>\n    <br>\n    <v-progress-linear\n      v-model=\"value\"\n      :buffer-value=\"bufferValue\"\n      color=\"red-lighten-2\"\n    ></v-progress-linear>\n    <br>\n    <v-progress-linear\n      v-model=\"value\"\n      :buffer-value=\"bufferValue\"\n      color=\"black\"\n    ></v-progress-linear>\n  </div>\n</template>\n\n<script setup>\n  import { onBeforeUnmount, onMounted, ref, watch } from 'vue'\n\n  const value = ref(10)\n  const bufferValue = ref(20)\n  const interval = ref(0)\n\n  watch(value, val => {\n    if (val < 100) return\n    value.value = 0\n    bufferValue.value = 10\n    startBuffer()\n  })\n\n  onMounted(() => {\n    startBuffer()\n  })\n  onBeforeUnmount(() => {\n    clearInterval(interval.value)\n  })\n\n  function startBuffer () {\n    clearInterval(interval.value)\n    interval.value = setInterval(() => {\n      value.value += Math.random() * (15 - 5) + 5\n      bufferValue.value += Math.random() * (15 - 5) + 6\n    }, 2000)\n  }\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        value: 10,\n        bufferValue: 20,\n        interval: 0,\n      }\n    },\n\n    watch: {\n      value (val) {\n        if (val < 100) return\n\n        this.value = 0\n        this.bufferValue = 10\n        this.startBuffer()\n      },\n    },\n\n    mounted () {\n      this.startBuffer()\n    },\n\n    beforeUnmount () {\n      clearInterval(this.interval)\n    },\n\n    methods: {\n      startBuffer () {\n        clearInterval(this.interval)\n\n        this.interval = setInterval(() => {\n          this.value += Math.random() * (15 - 5) + 5\n          this.bufferValue += Math.random() * (15 - 5) + 6\n        }, 2000)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-progress-linear/prop-chunks.vue",
    "content": "<template>\n  <div>\n    <v-progress-linear\n      v-model=\"value\"\n      chunk-width=\"4\"\n      color=\"purple\"\n      height=\"15\"\n      rounded=\"lg\"\n      clickable\n    ></v-progress-linear>\n\n    <br>\n\n    <v-progress-linear\n      v-model=\"value\"\n      chunk-gap=\"2\"\n      chunk-width=\"50\"\n      color=\"primary\"\n      height=\"10\"\n      clickable\n      rounded\n    ></v-progress-linear>\n\n    <br>\n\n    <v-progress-linear\n      v-model=\"value\"\n      bg-color=\"#888\"\n      chunk-count=\"50\"\n      chunk-gap=\"3\"\n      color=\"green\"\n      height=\"25\"\n      rounded=\"sm\"\n      clickable\n    ></v-progress-linear>\n\n    <br>\n\n    <v-progress-linear\n      v-model=\"value\"\n      bg-color=\"#888\"\n      chunk-count=\"15\"\n      chunk-gap=\"6\"\n      color=\"pink\"\n      height=\"25\"\n      rounded=\"sm\"\n      clickable\n    ></v-progress-linear>\n\n    <br>\n\n    <div class=\"d-flex ga-2 align-center\">\n      <v-progress-linear\n        v-model=\"value\"\n        chunk-count=\"5\"\n        chunk-gap=\"9\"\n        color=\"indigo\"\n        height=\"25\"\n        rounded=\"sm\"\n        clickable\n      >\n        <small class=\"text-white\">{{ value.toFixed() }}%</small>\n      </v-progress-linear>\n      <v-btn icon=\"mdi-skip-previous\" size=\"x-small\" @click=\"value = 0\"></v-btn>\n      <v-btn icon=\"$complete\" size=\"x-small\" @click=\"value = 100\"></v-btn>\n    </div>\n\n  </div>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const value = shallowRef(63)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        value: 63,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-progress-linear/prop-colors.vue",
    "content": "<template>\n  <div>\n    <v-progress-linear\n      bg-color=\"pink-lighten-3\"\n      color=\"pink-lighten-1\"\n      model-value=\"15\"\n    ></v-progress-linear>\n    <br>\n    <v-progress-linear\n      bg-color=\"blue-grey\"\n      color=\"lime\"\n      model-value=\"30\"\n    ></v-progress-linear>\n    <br>\n    <v-progress-linear\n      bg-color=\"success\"\n      color=\"error\"\n      model-value=\"45\"\n    ></v-progress-linear>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-progress-linear/prop-indeterminate.vue",
    "content": "<template>\n  <div>\n    <v-progress-linear\n      color=\"yellow-darken-2\"\n      indeterminate\n    ></v-progress-linear>\n    <br>\n    <v-progress-linear\n      color=\"green\"\n      indeterminate\n    ></v-progress-linear>\n    <br>\n    <v-progress-linear\n      color=\"teal\"\n      indeterminate\n    ></v-progress-linear>\n    <br>\n    <v-progress-linear\n      color=\"cyan\"\n      indeterminate\n    ></v-progress-linear>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-progress-linear/prop-query.vue",
    "content": "<template>\n  <div style=\"min-height: 4px;\">\n    <v-progress-linear\n      v-model=\"value\"\n      :active=\"show\"\n      :indeterminate=\"query\"\n      :query=\"true\"\n    ></v-progress-linear>\n  </div>\n</template>\n\n<script setup>\n  import { onBeforeUnmount, onMounted, ref } from 'vue'\n\n  const value = ref(0)\n  const query = ref(false)\n  const show = ref(true)\n\n  let interval = -1\n  onMounted(() => {\n    queryAndIndeterminate()\n  })\n  onBeforeUnmount(() => {\n    clearInterval(interval)\n  })\n\n  function queryAndIndeterminate () {\n    query.value = true\n    show.value = true\n    value.value = 0\n    setTimeout(() => {\n      query.value = false\n      interval = setInterval(() => {\n        if (value.value === 100) {\n          clearInterval(interval)\n          show.value = false\n          return setTimeout(queryAndIndeterminate, 2000)\n        }\n        value.value += 25\n      }, 1000)\n    }, 2500)\n  }\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        value: 0,\n        query: false,\n        show: true,\n        interval: 0,\n      }\n    },\n\n    mounted () {\n      this.queryAndIndeterminate()\n    },\n\n    beforeUnmount () {\n      clearInterval(this.interval)\n    },\n\n    methods: {\n      queryAndIndeterminate () {\n        this.query = true\n        this.show = true\n        this.value = 0\n\n        setTimeout(() => {\n          this.query = false\n\n          this.interval = setInterval(() => {\n            if (this.value === 100) {\n              clearInterval(this.interval)\n              this.show = false\n              return setTimeout(this.queryAndIndeterminate, 2000)\n            }\n            this.value += 25\n          }, 1000)\n        }, 2500)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-progress-linear/prop-reverse.vue",
    "content": "<template>\n  <div>\n    <v-progress-linear\n      color=\"pink\"\n      model-value=\"15\"\n      reverse\n    ></v-progress-linear>\n\n    <br>\n\n    <v-progress-linear\n      color=\"lime\"\n      indeterminate\n      reverse\n    ></v-progress-linear>\n\n    <br>\n\n    <v-progress-linear\n      buffer-value=\"55\"\n      color=\"success\"\n      model-value=\"30\"\n      reverse\n      streams\n    ></v-progress-linear>\n\n    <br>\n\n    <p>In specific cases you may want progress to display in left-to-right mode regardless of the application direction (LTR or RTL):</p>\n\n    <v-progress-linear\n      :reverse=\"$vuetify.locale.isRtl\"\n      model-value=\"15\"\n    ></v-progress-linear>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-progress-linear/prop-rounded.vue",
    "content": "<template>\n  <div>\n    <v-progress-linear\n      color=\"red-darken-2\"\n      model-value=\"100\"\n      rounded\n    ></v-progress-linear>\n    <br>\n    <v-progress-linear\n      color=\"indigo\"\n      model-value=\"100\"\n      rounded\n    ></v-progress-linear>\n    <br>\n    <v-progress-linear\n      color=\"teal\"\n      model-value=\"100\"\n      rounded\n    ></v-progress-linear>\n    <br>\n    <v-progress-linear\n      color=\"cyan-darken-2\"\n      model-value=\"100\"\n      rounded\n    ></v-progress-linear>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-progress-linear/prop-stream.vue",
    "content": "<template>\n  <div>\n    <v-progress-linear\n      buffer-value=\"0\"\n      color=\"red-lighten-2\"\n      stream\n    ></v-progress-linear>\n    <br>\n    <v-progress-linear\n      buffer-value=\"0\"\n      color=\"teal\"\n      model-value=\"20\"\n      stream\n    ></v-progress-linear>\n    <br>\n    <v-progress-linear\n      buffer-value=\"50\"\n      color=\"cyan\"\n      stream\n    ></v-progress-linear>\n    <br>\n    <v-progress-linear\n      buffer-value=\"60\"\n      color=\"orange\"\n      model-value=\"40\"\n      stream\n    ></v-progress-linear>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-progress-linear/prop-striped.vue",
    "content": "<template>\n  <div>\n    <v-progress-linear\n      color=\"light-blue\"\n      height=\"10\"\n      model-value=\"10\"\n      striped\n    ></v-progress-linear>\n    <br>\n    <v-progress-linear\n      color=\"light-green-darken-4\"\n      height=\"10\"\n      model-value=\"20\"\n      striped\n    ></v-progress-linear>\n    <br>\n    <v-progress-linear\n      color=\"lime\"\n      height=\"10\"\n      model-value=\"45\"\n      striped\n    ></v-progress-linear>\n    <br>\n    <v-progress-linear\n      color=\"deep-orange\"\n      height=\"10\"\n      model-value=\"60\"\n      striped\n    ></v-progress-linear>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-progress-linear/slot-default.vue",
    "content": "<template>\n  <div>\n    <v-progress-linear\n      v-model=\"power\"\n      color=\"amber\"\n      height=\"25\"\n    ></v-progress-linear>\n\n    <br>\n\n    <v-progress-linear\n      v-model=\"skill\"\n      color=\"blue-grey\"\n      height=\"25\"\n    >\n      <template v-slot:default=\"{ value }\">\n        <strong>{{ Math.ceil(value) }}%</strong>\n      </template>\n    </v-progress-linear>\n\n    <br>\n\n    <v-progress-linear\n      v-model=\"knowledge\"\n      height=\"25\"\n    >\n      <strong>{{ Math.ceil(knowledge) }}%</strong>\n    </v-progress-linear>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const skill = ref(20)\n  const knowledge = ref(33)\n  const power = ref(78)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      skill: 20,\n      knowledge: 33,\n      power: 78,\n    }),\n  }\n</script>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2747-79615&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-progress-linear/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div>\n      <v-progress-linear v-bind=\"props\"></v-progress-linear>\n    </div>\n\n    <template v-slot:configuration>\n      <v-select\n        v-model=\"color\"\n        :items=\"['primary', 'blue-lighten-3', 'error', 'blue-darken-3']\"\n        label=\"Color\"\n        clearable\n      ></v-select>\n\n      <v-slider\n        v-model=\"height\"\n        label=\"Height\"\n        max=\"12\"\n        min=\"4\"\n        step=\"1\"\n      ></v-slider>\n\n      <v-checkbox v-model=\"indeterminate\" label=\"Indeterminate\"></v-checkbox>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-progress-linear'\n  const model = ref('default')\n  const color = ref()\n  const indeterminate = ref(false)\n  const height = ref()\n  const options = []\n  const props = computed(() => {\n    return {\n      color: color.value || undefined,\n      indeterminate: indeterminate.value || undefined,\n      'model-value': !indeterminate.value ? '20' : undefined,\n      height: height.value !== 4 ? height.value : undefined,\n    }\n  })\n\n  const slots = computed(() => {\n    return ``\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-pull-to-refresh/usage.vue",
    "content": "<template>\n  <div class=\"scrollable-container bg-surface-light\">\n    <v-pull-to-refresh\n      :pull-down-threshold=\"pullDownThreshold\"\n      @load=\"load\"\n    >\n      <v-list>\n        <v-list-item\n          v-for=\"item in items\"\n          :key=\"item.value\"\n          :title=\"item.title\"\n        ></v-list-item>\n      </v-list>\n    </v-pull-to-refresh>\n  </div>\n</template>\n\n<script setup>\n  const pullDownThreshold = ref(64)\n\n  let items = [\n    {\n      title: '1',\n      value: 1,\n    },\n    {\n      title: '2',\n      value: 2,\n    },\n    {\n      title: '3',\n      value: 3,\n    },\n  ]\n\n  let count = 2\n\n  async function load ({ done }) {\n    console.log('loading')\n    await new Promise(resolve => setTimeout(() => resolve(), 2000))\n    items = Array.from({ length: count * 3 }, (k, v) => ({\n      title: `${v + 1}`,\n      value: v + 1,\n    }))\n    console.log('load finish')\n    count++\n    done('ok')\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      pullDownThreshold: 64,\n      items: [\n        {\n          title: '1',\n          value: 1,\n        },\n        {\n          title: '2',\n          value: 2,\n        },\n        {\n          title: '3',\n          value: 3,\n        },\n      ],\n    }),\n\n    methods: {\n      async load ({ done }) {\n        // Perform API call\n        console.log('loading')\n        await new Promise(resolve => setTimeout(() => resolve(), 2000))\n        this.items = Array.from({ length: 3 }, (k, v) => ({\n          title: `${v + 1}`,\n          value: v + 1,\n        }))\n        console.log('load finish')\n        done('ok')\n      },\n    },\n  }\n</script>\n\n<style>\n.scrollable-container {\n  max-height: 300px;\n  overflow-y: scroll;\n}\n</style>\n"
  },
  {
    "path": "packages/docs/src/examples/v-radio-group/prop-colors.vue",
    "content": "<template>\n  <v-card flat>\n    <v-card-text>\n      <v-container fluid>\n        <v-row>\n          <v-col\n            cols=\"12\"\n            md=\"6\"\n            sm=\"6\"\n          >\n            <v-radio-group v-model=\"ex7\">\n              <v-radio\n                color=\"red\"\n                label=\"red\"\n                value=\"red\"\n              ></v-radio>\n              <v-radio\n                color=\"red-darken-3\"\n                label=\"red-darken-3\"\n                value=\"red-darken-3\"\n              ></v-radio>\n              <v-radio\n                color=\"indigo\"\n                label=\"indigo\"\n                value=\"indigo\"\n              ></v-radio>\n              <v-radio\n                color=\"indigo-darken-3\"\n                label=\"indigo-darken-3\"\n                value=\"indigo-darken-3\"\n              ></v-radio>\n              <v-radio\n                color=\"orange\"\n                label=\"orange\"\n                value=\"orange\"\n              ></v-radio>\n              <v-radio\n                color=\"orange-darken-3\"\n                label=\"orange-darken-3\"\n                value=\"orange-darken-3\"\n              ></v-radio>\n            </v-radio-group>\n          </v-col>\n          <v-col\n            cols=\"12\"\n            md=\"6\"\n            sm=\"6\"\n          >\n            <v-radio-group v-model=\"ex8\">\n              <v-radio\n                color=\"primary\"\n                label=\"primary\"\n                value=\"primary\"\n              ></v-radio>\n              <v-radio\n                color=\"secondary\"\n                label=\"secondary\"\n                value=\"secondary\"\n              ></v-radio>\n              <v-radio\n                color=\"success\"\n                label=\"success\"\n                value=\"success\"\n              ></v-radio>\n              <v-radio\n                color=\"info\"\n                label=\"info\"\n                value=\"info\"\n              ></v-radio>\n              <v-radio\n                color=\"warning\"\n                label=\"warning\"\n                value=\"warning\"\n              ></v-radio>\n              <v-radio\n                color=\"error\"\n                label=\"error\"\n                value=\"error\"\n              ></v-radio>\n            </v-radio-group>\n          </v-col>\n        </v-row>\n      </v-container>\n    </v-card-text>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const ex7 = ref('red')\n  const ex8 = ref('primary')\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        ex7: 'red',\n        ex8: 'primary',\n      }\n    },\n  }\n</script>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2070-83999&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-radio-group/prop-direction.vue",
    "content": "<template>\n  <v-container fluid>\n    <v-radio-group v-model=\"column\">\n      <v-radio\n        label=\"Option 1\"\n        value=\"radio-1\"\n      ></v-radio>\n      <v-radio\n        label=\"Option 2\"\n        value=\"radio-2\"\n      ></v-radio>\n    </v-radio-group>\n    <hr>\n    <v-radio-group\n      v-model=\"inline\"\n      inline\n    >\n      <v-radio\n        label=\"Option 1\"\n        value=\"radio-1\"\n      ></v-radio>\n      <v-radio\n        label=\"Option 2\"\n        value=\"radio-2\"\n      ></v-radio>\n    </v-radio-group>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const column = ref(null)\n  const inline = ref(null)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        column: null,\n        inline: null,\n      }\n    },\n  }\n</script>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2073-36010&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-radio-group/prop-model-group.vue",
    "content": "<template>\n  <v-container fluid>\n    <p>Selected Button: {{ radios }}</p>\n    <v-radio-group v-model=\"radios\">\n      <v-radio label=\"Option One\" value=\"one\"></v-radio>\n      <v-radio label=\"Option 2 (string)\" value=\"2\"></v-radio>\n      <v-radio :value=\"3\" label=\"Option 3 (integer)\"></v-radio>\n    </v-radio-group>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const radios = ref('one')\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        radios: 'one',\n      }\n    },\n  }\n</script>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2070-80534&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-radio-group/prop-model-radio.vue",
    "content": "<template>\n  <v-container fluid>\n    <v-select\n      v-model=\"radio\"\n      :items=\"['Option 1', 'Option 2']\"\n      label=\"Select Option\"\n    ></v-select>\n    <v-radio\n      v-model=\"radio\"\n      false-value=\"Option 2\"\n      label=\"Option 1\"\n      true-value=\"Option 1\"\n      readonly\n    ></v-radio>\n    <v-radio\n      v-model=\"radio\"\n      false-value=\"Option 1\"\n      label=\"Option 2\"\n      true-value=\"Option 2\"\n      readonly\n    ></v-radio>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const radio = ref('Option 1')\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        radio: 'Option 1',\n      }\n    },\n  }\n</script>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2070-80768&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-radio-group/slot-label.vue",
    "content": "<template>\n  <v-container fluid>\n    <v-radio-group v-model=\"radios\">\n      <template v-slot:label>\n        <div>Your favourite <strong>search engine</strong></div>\n      </template>\n      <v-radio value=\"Google\">\n        <template v-slot:label>\n          <div>Of course it's <strong class=\"text-success\">Google</strong></div>\n        </template>\n      </v-radio>\n      <v-radio value=\"Duckduckgo\">\n        <template v-slot:label>\n          <div>Definitely <strong class=\"text-primary\">Duckduckgo</strong></div>\n        </template>\n      </v-radio>\n    </v-radio-group>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const radios = ref('Duckduckgo')\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        radios: 'Duckduckgo',\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-radio-group/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div>\n      <v-radio-group v-bind=\"props\" hide-details>\n        <v-radio label=\"Radio One\" value=\"one\"></v-radio>\n        <v-radio label=\"Radio Two\" value=\"two\"></v-radio>\n        <v-radio label=\"Radio Three\" value=\"three\"></v-radio>\n      </v-radio-group>\n    </div>\n\n    <template v-slot:configuration>\n      <v-checkbox v-model=\"label\" label=\"Radio group label\"></v-checkbox>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-radio-group'\n  const model = ref('default')\n  const options = ['inline']\n  const label = ref(false)\n  const props = computed(() => {\n    return {\n      inline: model.value === 'inline' || undefined,\n      label: label.value ? 'Radio group label' : undefined,\n    }\n  })\n\n  const slots = computed(() => {\n    return `\n  <v-radio label=\"Radio One\" value=\"one\"></v-radio>\n  <v-radio label=\"Radio Two\" value=\"two\"></v-radio>\n  <v-radio label=\"Radio Three\" value=\"three\"></v-radio>\n`\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-range-slider/prop-disabled.vue",
    "content": "<template>\n  <v-container fluid>\n    <v-row>\n      <v-col cols=\"12\">\n        <v-range-slider\n          v-model=\"value\"\n          label=\"Disabled\"\n          disabled\n        ></v-range-slider>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const value = ref([30, 60])\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        value: [30, 60],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-range-slider/prop-min-and-max.vue",
    "content": "<template>\n  <v-range-slider\n    v-model=\"range\"\n    :max=\"10\"\n    :min=\"-10\"\n    :step=\"1\"\n    class=\"align-center\"\n    hide-details\n  >\n    <template v-slot:prepend>\n      <v-text-field\n        v-model=\"range[0]\"\n        density=\"compact\"\n        style=\"width: 70px\"\n        type=\"number\"\n        variant=\"outlined\"\n        hide-details\n        single-line\n      ></v-text-field>\n    </template>\n    <template v-slot:append>\n      <v-text-field\n        v-model=\"range[1]\"\n        density=\"compact\"\n        style=\"width: 70px\"\n        type=\"number\"\n        variant=\"outlined\"\n        hide-details\n        single-line\n      ></v-text-field>\n    </template>\n  </v-range-slider>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const range = ref([-5, 5])\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        range: [-5, 5],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-range-slider/prop-step.vue",
    "content": "<template>\n  <v-range-slider\n    v-model=\"value\"\n    step=\"10\"\n    thumb-label=\"always\"\n  ></v-range-slider>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const value = ref([20, 40])\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        value: [20, 40],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-range-slider/prop-strict.vue",
    "content": "<template>\n  <v-card>\n    <v-card-text>\n      <v-range-slider\n        v-model=\"value\"\n        strict\n      ></v-range-slider>\n    </v-card-text>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const value = ref([20, 40])\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        value: [20, 40],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-range-slider/prop-vertical.vue",
    "content": "<template>\n  <v-range-slider\n    v-model=\"value\"\n    direction=\"vertical\"\n  ></v-range-slider>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const value = ref([20, 40])\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        value: [20, 40],\n      }\n    },\n  }\n</script>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2074-1156&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-range-slider/slot-thumb-label.vue",
    "content": "<template>\n  <v-row>\n    <v-col class=\"pa-12\">\n      <v-range-slider\n        :model-value=\"[0, 1]\"\n        :step=\"1\"\n        :ticks=\"seasons\"\n        max=\"3\"\n        min=\"0\"\n        show-ticks=\"always\"\n        thumb-label=\"always\"\n        tick-size=\"4\"\n      >\n        <template v-slot:thumb-label=\"{ modelValue }\">\n          <v-icon :icon=\"season(modelValue)\" theme=\"dark\"></v-icon>\n        </template>\n      </v-range-slider>\n    </v-col>\n  </v-row>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const seasons = ref({\n    0: 'Winter',\n    1: 'Spring',\n    2: 'Summer',\n    3: 'Fall',\n  })\n  const icons = ref([\n    'mdi-snowflake',\n    'mdi-leaf',\n    'mdi-fire',\n    'mdi-water',\n  ])\n  function season (val) {\n    return icons.value[val]\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      seasons: {\n        0: 'Winter',\n        1: 'Spring',\n        2: 'Summer',\n        3: 'Fall',\n      },\n      icons: [\n        'mdi-snowflake',\n        'mdi-leaf',\n        'mdi-fire',\n        'mdi-water',\n      ],\n    }),\n\n    methods: {\n      season (val) {\n        return this.icons[val]\n      },\n    },\n  }\n</script>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2073-37216&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-range-slider/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div>\n      <v-range-slider v-bind=\"props\"></v-range-slider>\n    </div>\n\n    <template v-slot:configuration>\n      <v-checkbox v-model=\"disabled\" label=\"Disabled\"></v-checkbox>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-range-slider'\n  const model = ref('default')\n  const options = ['vertical']\n  const disabled = ref(false)\n  const props = computed(() => {\n    return {\n      direction: model.value === 'vertical' ? 'vertical' : undefined,\n      disabled: disabled.value || undefined,\n    }\n  })\n\n  const slots = computed(() => {\n    return ``\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-rating/misc-advanced.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto overflow-hidden\"\n    max-width=\"600\"\n  >\n    <v-row>\n      <v-col\n        class=\"d-flex\"\n        cols=\"6\"\n      >\n        <v-img src=\"https://cdn.vuetifyjs.com/images/ratings/fortnite1.png\"></v-img>\n      </v-col>\n\n      <v-col cols=\"6\">\n        <v-container class=\"pa-0 ps-2 my-n1\">\n          <v-row>\n            <v-col\n              class=\"d-flex\"\n              cols=\"7\"\n            >\n              <v-img src=\"https://cdn.vuetifyjs.com/images/ratings/fortnite2.png\"></v-img>\n            </v-col>\n\n            <v-col\n              class=\"d-flex\"\n              cols=\"5\"\n            >\n              <v-img src=\"https://cdn.vuetifyjs.com/images/ratings/fortnite3.png\"></v-img>\n            </v-col>\n\n            <v-col\n              class=\"d-flex\"\n              cols=\"5\"\n            >\n              <v-img src=\"https://cdn.vuetifyjs.com/images/ratings/fortnite4.png\"></v-img>\n            </v-col>\n\n            <v-col\n              class=\"d-flex\"\n              cols=\"7\"\n            >\n              <v-img src=\"https://cdn.vuetifyjs.com/images/ratings/fortnite5.png\"></v-img>\n            </v-col>\n          </v-row>\n        </v-container>\n      </v-col>\n    </v-row>\n\n    <v-card-title class=\"align-start\">\n      <div>\n        <span class=\"text-headline-small\">FORTNITE</span>\n        <div class=\"text-grey font-weight-light\">\n          Video game\n        </div>\n      </div>\n\n      <v-spacer></v-spacer>\n\n      <v-dialog\n        v-model=\"dialog\"\n        width=\"400\"\n      >\n        <template v-slot:activator=\"{ props }\">\n          <v-icon v-bind=\"props\" icon=\"mdi-share-variant\"></v-icon>\n        </template>\n\n        <v-card>\n          <v-card-title class=\"d-flex\">\n            <span class=\"text-title-large font-weight-bold\">Share</span>\n            <v-spacer></v-spacer>\n\n            <v-btn class=\"mx-0\" icon @click=\"dialog = false\">\n              <v-icon>mdi-close-circle-outline</v-icon>\n            </v-btn>\n          </v-card-title>\n\n          <v-list>\n            <v-list-item prepend-icon=\"mdi-facebook\" title=\"Facebook\"></v-list-item>\n            <v-list-item prepend-icon=\"mdi-twitter\" title=\"Twitter\"></v-list-item>\n            <v-list-item prepend-icon=\"mdi-email\" title=\"Email\"></v-list-item>\n          </v-list>\n\n          <v-text-field\n            ref=\"link\"\n            :label=\"copied ? 'Link copied' : 'Click to copy link'\"\n            class=\"pa-4\"\n            model-value=\"https://g.co/kgs/nkrK43\"\n            readonly\n            @click=\"copy\"\n          ></v-text-field>\n        </v-card>\n      </v-dialog>\n    </v-card-title>\n\n    <v-divider></v-divider>\n\n    <v-card-actions>\n      <span class=\"ps-2 text-grey-darken-2 font-weight-light text-body-small\">16,544 reviews</span>\n\n      <v-spacer></v-spacer>\n\n      <v-rating\n        v-model=\"rating\"\n        length=\"10\"\n        readonly\n      >\n        <template v-slot:item=\"props\">\n          <v-icon\n            :color=\"props.isFilled ? 'purple-darken-4' : ''\"\n            :icon=\"`mdi-numeric-${props.index}-box`\"\n            size=\"large\"\n          ></v-icon>\n        </template>\n      </v-rating>\n    </v-card-actions>\n    <div class=\"pa-4 pt-0 text-body-small\">\n      <em>Portions of the materials used are trademarks and/or copyrighted works of Epic Games, Inc. All rights reserved by Epic. This material is not official and is not endorsed by Epic.</em>\n    </div>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const link = ref()\n\n  const copied = ref(false)\n  const dialog = ref(false)\n  const rating = ref(10)\n\n  function copy () {\n    link.value.focus()\n    document.execCommand('selectAll', false, null)\n    copied.value = document.execCommand('copy')\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      copied: false,\n      dialog: false,\n      rating: 10,\n    }),\n\n    methods: {\n      copy () {\n        this.$refs.link.focus()\n\n        document.execCommand('selectAll', false, null)\n\n        this.copied = document.execCommand('copy')\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-rating/misc-card-overview.vue",
    "content": "<template>\n  <v-card\n    class=\"d-flex flex-column mx-auto py-8\"\n    elevation=\"3\"\n    height=\"500\"\n    width=\"360\"\n  >\n    <div class=\"d-flex justify-center mt-auto text-headline-small \">\n      Rating overview\n    </div>\n\n    <div class=\"d-flex align-center flex-column my-auto\">\n      <div class=\"text-display-large mt-5\">\n        3.5\n        <span class=\"text-title-large ml-n3\">/5</span>\n      </div>\n\n      <v-rating\n        :model-value=\"3.5\"\n        color=\"yellow-darken-3\"\n        half-increments\n      ></v-rating>\n      <div class=\"px-3\">3,360 ratings</div>\n    </div>\n\n    <v-list\n      bg-color=\"transparent\"\n      class=\"d-flex flex-column-reverse\"\n      density=\"compact\"\n    >\n      <v-list-item v-for=\"(rating,i) in 5\" :key=\"i\">\n        <v-progress-linear\n          :model-value=\"rating * 15\"\n          class=\"mx-n5\"\n          color=\"yellow-darken-3\"\n          height=\"20\"\n          rounded\n        ></v-progress-linear>\n\n        <template v-slot:prepend>\n          <span>{{ rating }}</span>\n          <v-icon class=\"mx-3\" icon=\"mdi-star\"></v-icon>\n        </template>\n\n        <template v-slot:append>\n          <div class=\"rating-values\">\n            <span class=\"d-flex justify-end\"> {{ rating * 224 }} </span>\n          </div>\n        </template>\n      </v-list-item>\n    </v-list>\n  </v-card>\n</template>\n\n<style>\n.rating-values {\n   width: 25px;\n}\n</style>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2263-61824&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-rating/misc-card.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    color=\"purple\"\n    elevation=\"3\"\n    width=\"360\"\n  >\n    <div class=\"d-flex justify-between\">\n      <v-card-title class=\"flex-grow-1 flex-column align-start\">\n        <div class=\"text-headline-small\">\n          Halycon Days\n        </div>\n        <div class=\"text-title-large font-weight-thin\">Ellie Goulding</div>\n\n        <div class=\"text-title-large font-weight-thin\">(2013)</div>\n      </v-card-title>\n\n      <v-img\n        class=\"flex-grow-0\"\n        height=\"125px\"\n        src=\"https://cdn.vuetifyjs.com/images/cards/halcyon.png\"\n        style=\"flex-basis: 125px\"\n      ></v-img>\n    </div>\n\n    <v-divider></v-divider>\n\n    <v-card-actions class=\"pa-4\">\n      Rate this album\n\n      <v-spacer></v-spacer>\n\n      <span class=\"text-grey-lighten-2 text-body-small me-2\">\n        ({{ rating }})\n      </span>\n\n      <v-rating\n        v-model=\"rating\"\n        active-color=\"yellow-accent-4\"\n        color=\"white\"\n        size=\"18\"\n        half-increments\n        hover\n      ></v-rating>\n    </v-card-actions>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const rating = ref(4.5)\n</script>\n\n<script>\n  export default {\n    data: () => ({ rating: 4.5 }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-rating/prop-clearable.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-rating\n      v-model=\"rating\"\n      clearable\n    ></v-rating>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const rating = ref(3)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      rating: 3,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-rating/prop-color.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-rating\n      v-model=\"rating\"\n      active-color=\"blue\"\n      color=\"orange-lighten-1\"\n    ></v-rating>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const rating = ref(3)\n</script>\n\n<script>\n  export default {\n    data: () => ({ rating: 3 }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-rating/prop-density.vue",
    "content": "<template>\n  <div class=\"d-flex flex-column align-center justify-center\">\n    <v-rating\n      v-model=\"rating\"\n      class=\"ma-2\"\n      density=\"default\"\n    ></v-rating>\n\n    <v-rating\n      v-model=\"rating\"\n      class=\"ma-2\"\n      density=\"comfortable\"\n    ></v-rating>\n\n    <v-rating\n      v-model=\"rating\"\n      class=\"ma-2\"\n      density=\"compact\"\n    ></v-rating>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const rating = ref(3)\n</script>\n\n<script>\n  export default {\n    data: () => ({ rating: 3 }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-rating/prop-half-increments.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-rating\n      v-model=\"rating\"\n      half-increments\n      hover\n    ></v-rating>\n    <pre>{{ rating }}</pre>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const rating = ref(3.5)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      rating: 3.5,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-rating/prop-hover.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-rating\n      v-model=\"rating\"\n      hover\n    ></v-rating>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const rating = ref(3)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      rating: 3,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-rating/prop-icon-label.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-rating\n      v-model=\"rating\"\n      item-aria-label=\"custom icon label text {0} of {1}\"\n    ></v-rating>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const rating = ref(4)\n</script>\n\n<script>\n  export default {\n    data: () => ({ rating: 4 }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-rating/prop-icons.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-rating\n      v-model=\"rating\"\n      empty-icon=\"mdi-circle-outline\"\n      full-icon=\"mdi-circle\"\n      half-increments\n      hover\n    ></v-rating>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const rating = ref(3.5)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      rating: 3.5,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-rating/prop-item-labels.vue",
    "content": "<template>\n  <div class=\"d-flex align-center justify-center flex-column\">\n    <v-rating\n      v-model=\"rating\"\n      :item-labels=\"['sad', '', '', '', 'happy']\"\n      class=\"ma-2\"\n      item-label-position=\"top\"\n    ></v-rating>\n\n    <v-rating\n      v-model=\"rating\"\n      :item-labels=\"['sad', '', '', '', 'happy']\"\n      class=\"ma-2\"\n      item-label-position=\"bottom\"\n    ></v-rating>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const rating = ref(4)\n</script>\n\n<script>\n  export default {\n    data: () => ({ rating: 4 }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-rating/prop-length.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-rating\n      v-model=\"rating\"\n      length=\"10\"\n    ></v-rating>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const rating = ref(2)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      rating: 2,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-rating/prop-readonly.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-rating\n      v-model=\"rating\"\n      readonly\n    ></v-rating>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const rating = ref(3)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      rating: 3,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-rating/prop-size.vue",
    "content": "<template>\n  <div class=\"d-flex flex-column align-center\">\n    <v-rating\n      model-value=\"3\"\n      size=\"x-small\"\n    ></v-rating>\n\n    <v-rating\n      model-value=\"3\"\n      size=\"small\"\n    ></v-rating>\n\n    <v-rating\n      model-value=\"3\"\n    ></v-rating>\n\n    <v-rating\n      model-value=\"3\"\n      size=\"large\"\n    ></v-rating>\n\n    <v-rating\n      model-value=\"3\"\n      size=\"x-large\"\n    ></v-rating>\n\n    <v-rating\n      model-value=\"3\"\n      size=\"72\"\n    ></v-rating>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-rating/slot-item-label.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-rating\n      v-model=\"rating\"\n      :item-labels=\"labels\"\n    >\n      <template v-slot:item-label=\"props\">\n        <span\n          :class=\"`text-${colors[props.index]}`\"\n          class=\"font-weight-black text-body-small\"\n        >\n          {{ props.label }}\n        </span>\n      </template>\n    </v-rating>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const rating = ref(4)\n  const colors = ref(['red', 'orange', 'grey', 'cyan', 'green'])\n  const labels = ref(['bad', 'so so', 'ok', 'good', 'great'])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      rating: 4,\n      colors: ['red', 'orange', 'grey', 'cyan', 'green'],\n      labels: ['bad', 'so so', 'ok', 'good', 'great'],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-rating/slot-item.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-rating v-model=\"rating\">\n      <template v-slot:item=\"props\">\n        <v-icon\n          :color=\"props.isFilled ? colors[props.index] : 'grey-lighten-1'\"\n          size=\"large\"\n        >\n          {{ props.isFilled ? 'mdi-star-circle' : 'mdi-star-circle-outline' }}\n        </v-icon>\n      </template>\n    </v-rating>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const colors = ['green', 'purple', 'orange', 'indigo', 'red']\n\n  const rating = ref(4.5)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      colors: ['green', 'purple', 'orange', 'indigo', 'red'],\n      rating: 4.5,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-rating/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"selectedOption\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"['Hearts']\"\n  >\n    <div class=\"text-center\">\n      <v-rating v-bind=\"props\"></v-rating>\n    </div>\n\n    <template v-slot:configuration>\n      <v-checkbox v-model=\"options['half-increments']\" label=\"Half increments\"></v-checkbox>\n      <v-checkbox v-model=\"options.hover\" label=\"Hover\"></v-checkbox>\n      <v-checkbox v-model=\"options.readonly\" label=\"Readonly\"></v-checkbox>\n\n      <br>\n\n      <v-slider v-model=\"options.length\" :max=\"8\" :min=\"1\" label=\"Length\"></v-slider>\n      <v-slider v-model=\"options.size\" :max=\"128\" :min=\"16\" label=\"Size\"></v-slider>\n      <v-slider v-model=\"options['model-value']\" :max=\"options.length\" :min=\"0\" :step=\"options['half-increments'] ? 0.5 : 1\" label=\"Value\"></v-slider>\n\n      <br>\n\n      <v-select v-model=\"options.color\" :items=\"colorOptions\" label=\"Color\"></v-select>\n      <v-select v-model=\"options['active-color']\" :items=\"colorOptions\" label=\"Active color\"></v-select>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const selectedOption = ref()\n\n  const options = reactive({\n    'half-increments': false,\n    hover: true,\n    readonly: false,\n\n    length: 5,\n    size: 32,\n    'model-value': 3,\n\n    color: null,\n    'active-color': 'primary',\n  })\n\n  const name = 'v-rating'\n  const props = computed(() => {\n    return Object.fromEntries(\n      Object.entries({\n        ...options,\n        ...(selectedOption.value === 'Hearts' ? {\n          'empty-icon': 'mdi-heart-outline',\n          'half-icon': 'mdi-heart-half-full',\n          'full-icon': 'mdi-heart',\n        } : undefined),\n      }).filter(([key, value]) => value)\n    )\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)} />`\n  })\n\n  const colorOptions = [\n    'primary',\n    'warning',\n    'green',\n    'red',\n    'blue',\n    'error',\n    'teal',\n    'red-lighten-3',\n  ]\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-resize/usage.vue",
    "content": "<template>\n  <v-row\n    class=\"align-center justify-center\"\n    v-resize=\"onResize\"\n  >\n    <v-col class=\"text-center\">\n      <div class=\"text-title-small\">Window Size</div>\n      {{ windowSize }}\n    </v-col>\n  </v-row>\n</template>\n\n<script>\n  export default {\n    data: () => ({\n      windowSize: {\n        x: 0,\n        y: 0,\n      },\n    }),\n\n    mounted () {\n      this.onResize()\n    },\n\n    methods: {\n      onResize () {\n        this.windowSize = { x: window.innerWidth, y: window.innerHeight }\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-responsive/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div>\n      <v-responsive\n        v-bind=\"props\"\n        :aspect-ratio=\"model.split(' / ')[0] / model.split(' / ')[1]\"\n      >\n        Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!\n      </v-responsive>\n    </div>\n\n    <template v-slot:configuration>\n      <v-checkbox v-model=\"contentClass\" label=\"Content class\"></v-checkbox>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-responsive'\n  const model = ref('default')\n  const options = ['16 / 9', '4 / 3']\n  const contentClass = ref(false)\n  const props = computed(() => {\n    return {\n      'aspect-ratio': model.value !== 'default' ? model.value : undefined,\n      class: 'border pa-4',\n      'content-class': contentClass.value ? 'bg-primary' : undefined,\n    }\n  })\n\n  const slots = computed(() => {\n    return ``\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value, ['aspect-ratio'])}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-ripple/misc-custom-color.vue",
    "content": "<template>\n  <v-list>\n    <v-list-item\n      v-for=\"color in ['primary', 'secondary', 'info', 'success', 'warning', 'error']\"\n      :key=\"color\"\n      v-ripple=\"{ class: `text-${color}` }\"\n    >\n      <v-list-item-title>Item with \"{{ color }}\" class</v-list-item-title>\n    </v-list-item>\n  </v-list>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-ripple/misc-ripple-in-components.vue",
    "content": "<script>\n// TODO\n// @ts-disable\n</script>\n\n<template>\n  <v-row class=\"py-12 justify-space-around\">\n    <v-btn\n      color=\"primary\"\n    >\n      With ripple (default)\n    </v-btn>\n    <v-btn\n      :ripple=\"false\"\n      color=\"primary\"\n    >\n      Without ripple\n    </v-btn>\n    <v-btn\n      :ripple=\"{ class: 'text-red' }\"\n      variant=\"text\"\n    >\n      With red ripple\n    </v-btn>\n  </v-row>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-ripple/option-center.vue",
    "content": "<template>\n  <div\n    class=\"text-center elevation-1 pa-12 text-headline-small\"\n    v-ripple.center\n  >\n    HTML element with centered ripple\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-ripple/stop.vue",
    "content": "<template>\n  <v-row>\n    <v-col cols=\"12\">\n      <v-card v-ripple>\n        <v-card-text>Card with ripple</v-card-text>\n        <v-card-actions>\n          <v-btn>Button with ripple</v-btn>\n        </v-card-actions>\n      </v-card>\n    </v-col>\n    <v-col cols=\"12\">\n      <v-card v-ripple>\n        <v-card-text>\n          Outer card with ripple\n          <v-card-actions>\n            <v-card v-ripple.stop>\n              <v-card-text>\n                Inner card with <code>ripple.stop</code>\n              </v-card-text>\n            </v-card>\n          </v-card-actions>\n        </v-card-text>\n      </v-card>\n    </v-col>\n  </v-row>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-ripple/usage.vue",
    "content": "<template>\n  <div\n    class=\"text-center elevation-1 pa-12 text-headline-small\"\n    v-ripple\n  >\n    HTML element with v-ripple\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-scroll/option-self.vue",
    "content": "<template>\n  <v-card\n    class=\"overflow-y-auto\"\n    max-height=\"400\"\n    v-scroll.self=\"onScroll\"\n  >\n    <v-banner\n      class=\"justify-center text-headline-small font-weight-light\"\n      sticky\n    >\n      Scroll Me - Method invoked\n\n      <span\n        class=\"font-weight-bold\"\n        v-text=\"scrollInvoked\"\n      ></span>\n\n      times\n    </v-banner>\n\n    <v-card-text>\n      <div\n        v-for=\"n in 12\"\n        :key=\"n\"\n        class=\"mb-4\"\n      >\n        Lorem ipsum dolor sit amet consectetur adipisicing elit. Modi commodi earum tenetur. Asperiores dolorem placeat ab nobis iusto culpa, autem molestias molestiae quidem pariatur. Debitis beatae expedita nam facere perspiciatis. Lorem ipsum dolor sit amet consectetur adipisicing elit. Repellendus ducimus cupiditate rerum officiis consequuntur laborum doloremque quaerat ipsa voluptates, nobis nam quis nulla ullam at corporis, similique ratione quasi illo!\n      </div>\n    </v-card-text>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const scrollInvoked = ref(0)\n  function onScroll () {\n    scrollInvoked.value++\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      scrollInvoked: 0,\n    }),\n\n    methods: {\n      onScroll () {\n        this.scrollInvoked++\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-scroll/option-target.vue",
    "content": "<template>\n  <div>\n    <v-row class=\"align-center justify-center\">\n      <v-col class=\"text-center\">\n        <div class=\"text-title-small\">Offset Top</div>\n        {{ offsetTop }}\n      </v-col>\n    </v-row>\n    <v-container\n      id=\"scroll-target\"\n      class=\"overflow-y-auto\"\n      style=\"max-height: 400px\"\n    >\n      <v-row\n        class=\"align-center justify-center\"\n        style=\"height: 1000px\"\n        v-scroll:#scroll-target=\"onScroll\"\n      >\n      </v-row>\n    </v-container>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const offsetTop = ref(0)\n  function onScroll (e) {\n    offsetTop.value = e.target.scrollTop\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      offsetTop: 0,\n    }),\n\n    methods: {\n      onScroll (e) {\n        this.offsetTop = e.target.scrollTop\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-scroll/usage.vue",
    "content": "<template>\n  <v-container>\n    <v-row>\n      <v-col cols=\"12\">\n        <h3\n          ref=\"radio\"\n          class=\"text-headline-small my-0\"\n        >\n          Target\n        </h3>\n\n        <v-radio-group\n          v-model=\"type\"\n          inline\n        >\n          <v-radio\n            label=\"Number\"\n            value=\"number\"\n          ></v-radio>\n\n          <v-radio\n            label=\"Selector\"\n            value=\"selector\"\n          ></v-radio>\n\n          <v-radio\n            label=\"DOMElement\"\n            value=\"element\"\n          ></v-radio>\n        </v-radio-group>\n\n        <v-text-field\n          v-if=\"type === 'number'\"\n          v-model=\"number\"\n          label=\"Number\"\n          type=\"number\"\n        ></v-text-field>\n\n        <v-text-field\n          v-if=\"type === 'selector'\"\n          v-model=\"selector\"\n          label=\"Selector\"\n        ></v-text-field>\n\n        <v-select\n          v-if=\"type === 'element'\"\n          v-model=\"selected\"\n          :items=\"elements\"\n          label=\"DOMElement\"\n        ></v-select>\n      </v-col>\n\n      <v-col cols=\"12\">\n        <h3 class=\"text-headline-small my-0\">\n          Options\n        </h3>\n\n        <v-select\n          v-model=\"easing\"\n          :items=\"easings\"\n          label=\"Easing\"\n        ></v-select>\n\n        <v-slider\n          v-model=\"duration\"\n          label=\"Duration\"\n          max=\"1000\"\n          min=\"0\"\n          thumb-label\n        ></v-slider>\n\n        <v-slider\n          v-model=\"offset\"\n          label=\"Offset\"\n          max=\"500\"\n          min=\"-500\"\n          thumb-label\n        ></v-slider>\n      </v-col>\n\n      <v-col>\n        <v-btn\n          ref=\"button\"\n          color=\"primary\"\n          block\n          @click=\"$vuetify.goTo(target, options)\"\n        >\n          scroll\n        </v-btn>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script>\n  // import * as easings from 'vuetify/lib/services/goto/easing-patterns'\n\n  export default {\n    data () {\n      return {\n        type: 'number',\n        number: 9999,\n        selector: '#scroll-with-options',\n        selected: 'Button',\n        elements: ['Button', 'Radio group'],\n        duration: 300,\n        offset: 0,\n        easing: 'easeInOutCubic',\n        easings: [], // TODO: fix import? Object.keys(easings),\n      }\n    },\n    computed: {\n      target () {\n        const value = this[this.type]\n        if (!isNaN(value)) return Number(value)\n        else return value\n      },\n      options () {\n        return {\n          duration: this.duration,\n          offset: this.offset,\n          easing: this.easing,\n        }\n      },\n      element () {\n        if (this.selected === 'Button') return this.$refs.button\n        else if (this.selected === 'Radio group') return this.$refs.radio\n        else return null\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-select/prop-avoid-duplicate-text.vue",
    "content": "<template>\n  <v-container>\n    <v-select v-model=\"model\" :items=\"items\">\n      <template v-slot:item=\"{ props, item }\">\n        <v-list-item v-bind=\"props\" :title=\"null\">\n          <v-list-item-title>{{ item }}</v-list-item-title>\n        </v-list-item>\n      </template>\n    </v-select>\n  </v-container>\n</template>\n\n<script>\n  export default {\n    data: () => ({\n      items: ['Foo', 'Bar', 'Fizz', 'Buzz'],\n      model: 'Foo',\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-select/prop-chips.vue",
    "content": "<template>\n  <v-select\n    v-model=\"value\"\n    :items=\"items\"\n    label=\"Chips\"\n    chips\n    multiple\n  ></v-select>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const items = shallowRef(['foo', 'bar', 'fizz', 'buzz'])\n  const value = shallowRef(['foo', 'bar', 'fizz', 'buzz'])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: ['foo', 'bar', 'fizz', 'buzz'],\n      value: ['foo', 'bar', 'fizz', 'buzz'],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-select/prop-custom-title-and-value.vue",
    "content": "<template>\n  <v-select\n    v-model=\"select\"\n    :hint=\"`${select.state}, ${select.abbr}`\"\n    :items=\"items\"\n    item-title=\"state\"\n    item-value=\"abbr\"\n    label=\"Select\"\n    persistent-hint\n    return-object\n    single-line\n  ></v-select>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const select = shallowRef({ state: 'Florida', abbr: 'FL' })\n\n  const items = [\n    { state: 'Florida', abbr: 'FL' },\n    { state: 'Georgia', abbr: 'GA' },\n    { state: 'Nebraska', abbr: 'NE' },\n    { state: 'California', abbr: 'CA' },\n    { state: 'New York', abbr: 'NY' },\n  ]\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        select: { state: 'Florida', abbr: 'FL' },\n        items: [\n          { state: 'Florida', abbr: 'FL' },\n          { state: 'Georgia', abbr: 'GA' },\n          { state: 'Nebraska', abbr: 'NE' },\n          { state: 'California', abbr: 'CA' },\n          { state: 'New York', abbr: 'NY' },\n        ],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-select/prop-dense.vue",
    "content": "<template>\n  <v-select\n    :items=\"items\"\n    density=\"compact\"\n    label=\"Compact\"\n  ></v-select>\n\n  <v-select\n    :items=\"items\"\n    density=\"comfortable\"\n    label=\"Comfortable\"\n  ></v-select>\n\n  <v-select\n    :items=\"items\"\n    label=\"Default\"\n  ></v-select>\n</template>\n\n<script setup>\n  const items = ['Foo', 'Bar', 'Fizz', 'Buzz']\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: ['Foo', 'Bar', 'Fizz', 'Buzz'],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-select/prop-disabled.vue",
    "content": "<template>\n  <v-select\n    :items=\"items\"\n    label=\"Disabled\"\n    disabled\n  ></v-select>\n</template>\n\n<script setup>\n  const items = ['Foo', 'Bar', 'Fizz', 'Buzz']\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: ['Foo', 'Bar', 'Fizz', 'Buzz'],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-select/prop-item-props.vue",
    "content": "<template>\n  <v-select\n    :item-props=\"itemProps\"\n    :items=\"items\"\n    label=\"User\"\n  ></v-select>\n</template>\n\n<script setup>\n  const items = [\n    {\n      name: 'John',\n      department: 'Marketing',\n    },\n    {\n      name: 'Jane',\n      department: 'Engineering',\n    },\n    {\n      name: 'Joe',\n      department: 'Sales',\n    },\n    {\n      name: 'Janet',\n      department: 'Engineering',\n    },\n    {\n      name: 'Jake',\n      department: 'Marketing',\n    },\n    {\n      name: 'Jack',\n      department: 'Sales',\n    },\n  ]\n\n  function itemProps (item) {\n    return {\n      title: item.name,\n      subtitle: item.department,\n    }\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        {\n          name: 'John',\n          department: 'Marketing',\n        },\n        {\n          name: 'Jane',\n          department: 'Engineering',\n        },\n        {\n          name: 'Joe',\n          department: 'Sales',\n        },\n        {\n          name: 'Janet',\n          department: 'Engineering',\n        },\n        {\n          name: 'Jake',\n          department: 'Marketing',\n        },\n        {\n          name: 'Jack',\n          department: 'Sales',\n        },\n      ],\n    }),\n\n    methods: {\n      itemProps (item) {\n        return {\n          title: item.name,\n          subtitle: item.department,\n        }\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-select/prop-list-props.vue",
    "content": "<template>\n  <v-select\n    v-model=\"selected\"\n    :items=\"['Apple', 'Orange', 'Banana', 'Pear']\"\n    :list-props=\"{ bgColor: 'purple' }\"\n    item-color=\"yellow\"\n    label=\"Label\"\n    multiple\n  ></v-select>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const selected = ref(['Apple'])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      selected: ['Apple'],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-select/prop-menu-props.vue",
    "content": "<template>\n  <v-select\n    :items=\"items\"\n    :menu-props=\"{ scrim: true, scrollStrategy: 'close' }\"\n    label=\"Label\"\n  ></v-select>\n</template>\n\n<script setup>\n  const items = ['Foo', 'Bar', 'Fizz', 'Buzz']\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: ['Foo', 'Bar', 'Fizz', 'Buzz'],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-select/prop-multiple.vue",
    "content": "<template>\n  <v-select\n    v-model=\"favorites\"\n    :items=\"states\"\n    hint=\"Pick your favorite states\"\n    label=\"Select\"\n    multiple\n    persistent-hint\n  ></v-select>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const favorites = shallowRef([])\n\n  const states = [\n    'Alabama',\n    'Alaska',\n    'American Samoa',\n    'Arizona',\n    'Arkansas',\n    'California',\n    'Colorado',\n    'Connecticut',\n    'Delaware',\n    'District of Columbia',\n    'Federated States of Micronesia',\n    'Florida',\n    'Georgia',\n    'Guam',\n    'Hawaii',\n    'Idaho',\n    'Illinois',\n    'Indiana',\n    'Iowa',\n    'Kansas',\n    'Kentucky',\n    'Louisiana',\n    'Maine',\n    'Marshall Islands',\n    'Maryland',\n    'Massachusetts',\n    'Michigan',\n    'Minnesota',\n    'Mississippi',\n    'Missouri',\n    'Montana',\n    'Nebraska',\n    'Nevada',\n    'New Hampshire',\n    'New Jersey',\n    'New Mexico',\n    'New York',\n    'North Carolina',\n    'North Dakota',\n    'Northern Mariana Islands',\n    'Ohio',\n    'Oklahoma',\n    'Oregon',\n    'Palau',\n    'Pennsylvania',\n    'Puerto Rico',\n    'Rhode Island',\n    'South Carolina',\n    'South Dakota',\n    'Tennessee',\n    'Texas',\n    'Utah',\n    'Vermont',\n    'Virgin Island',\n    'Virginia',\n    'Washington',\n    'West Virginia',\n    'Wisconsin',\n    'Wyoming',\n  ]\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        favorites: [],\n        states: [\n          'Alabama', 'Alaska', 'American Samoa', 'Arizona',\n          'Arkansas', 'California', 'Colorado', 'Connecticut',\n          'Delaware', 'District of Columbia', 'Federated States of Micronesia',\n          'Florida', 'Georgia', 'Guam', 'Hawaii', 'Idaho',\n          'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky',\n          'Louisiana', 'Maine', 'Marshall Islands', 'Maryland',\n          'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi',\n          'Missouri', 'Montana', 'Nebraska', 'Nevada',\n          'New Hampshire', 'New Jersey', 'New Mexico', 'New York',\n          'North Carolina', 'North Dakota', 'Northern Mariana Islands', 'Ohio',\n          'Oklahoma', 'Oregon', 'Palau', 'Pennsylvania', 'Puerto Rico',\n          'Rhode Island', 'South Carolina', 'South Dakota', 'Tennessee',\n          'Texas', 'Utah', 'Vermont', 'Virgin Island', 'Virginia',\n          'Washington', 'West Virginia', 'Wisconsin', 'Wyoming',\n        ],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-select/prop-readonly.vue",
    "content": "<template>\n  <v-select\n    v-model=\"model\"\n    :items=\"items\"\n    label=\"Read-only\"\n    readonly\n  ></v-select>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const model = shallowRef('Foo')\n  const items = ['Foo', 'Bar', 'Fizz', 'Buzz']\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: ['Foo', 'Bar', 'Fizz', 'Buzz'],\n      model: 'Foo',\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-select/slot-append-and-prepend-item.vue",
    "content": "<template>\n  <v-select\n    v-model=\"selectedFruits\"\n    :items=\"fruits\"\n    label=\"Favorite Fruits\"\n    multiple\n  >\n    <template v-slot:prepend-item>\n      <v-list-item\n        title=\"Select All\"\n        @click=\"toggle\"\n      >\n        <template v-slot:prepend>\n          <v-checkbox-btn\n            :color=\"likesSomeFruit ? 'indigo-darken-4' : undefined\"\n            :indeterminate=\"likesSomeFruit && !likesAllFruit\"\n            :model-value=\"likesAllFruit\"\n          ></v-checkbox-btn>\n        </template>\n      </v-list-item>\n\n      <v-divider class=\"mt-2\"></v-divider>\n    </template>\n\n    <template v-slot:append-item>\n      <v-divider class=\"mb-2\"></v-divider>\n\n      <v-list-item\n        :subtitle=\"subtitle\"\n        :title=\"title\"\n        disabled\n      >\n        <template v-slot:prepend>\n          <v-avatar color=\"primary\" icon=\"mdi-food-apple\"></v-avatar>\n        </template>\n      </v-list-item>\n    </template>\n  </v-select>\n</template>\n\n<script setup>\n  import { computed, shallowRef } from 'vue'\n\n  const fruits = [\n    'Apples',\n    'Apricots',\n    'Avocado',\n    'Bananas',\n    'Blueberries',\n    'Blackberries',\n    'Boysenberries',\n    'Bread fruit',\n    'Cantaloupes (cantalope)',\n    'Cherries',\n    'Cranberries',\n    'Cucumbers',\n    'Currants',\n    'Dates',\n    'Eggplant',\n    'Figs',\n    'Grapes',\n    'Grapefruit',\n    'Guava',\n    'Honeydew melons',\n    'Huckleberries',\n    'Kiwis',\n    'Kumquat',\n    'Lemons',\n    'Limes',\n    'Mangos',\n    'Mulberries',\n    'Muskmelon',\n    'Nectarines',\n    'Olives',\n    'Oranges',\n    'Papaya',\n    'Peaches',\n    'Pears',\n    'Persimmon',\n    'Pineapple',\n    'Plums',\n    'Pomegranate',\n    'Raspberries',\n    'Rose Apple',\n    'Starfruit',\n    'Strawberries',\n    'Tangerines',\n    'Tomatoes',\n    'Watermelons',\n    'Zucchini',\n  ]\n\n  const selectedFruits = shallowRef([])\n\n  const likesAllFruit = computed(() => {\n    return selectedFruits.value.length === fruits.length\n  })\n  const likesSomeFruit = computed(() => {\n    return selectedFruits.value.length > 0\n  })\n  const title = computed(() => {\n    if (likesAllFruit.value) return 'Holy smokes, someone call the fruit police!'\n    if (likesSomeFruit.value) return 'Fruit Count'\n    return 'How could you not like fruit?'\n  })\n  const subtitle = computed(() => {\n    if (likesAllFruit.value) return undefined\n    if (likesSomeFruit.value) return selectedFruits.value.length\n    return 'Go ahead, make a selection above!'\n  })\n\n  function toggle () {\n    if (likesAllFruit.value) {\n      selectedFruits.value = []\n    } else {\n      selectedFruits.value = fruits.slice()\n    }\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      fruits: [\n        'Apples',\n        'Apricots',\n        'Avocado',\n        'Bananas',\n        'Blueberries',\n        'Blackberries',\n        'Boysenberries',\n        'Bread fruit',\n        'Cantaloupes (cantalope)',\n        'Cherries',\n        'Cranberries',\n        'Cucumbers',\n        'Currants',\n        'Dates',\n        'Eggplant',\n        'Figs',\n        'Grapes',\n        'Grapefruit',\n        'Guava',\n        'Honeydew melons',\n        'Huckleberries',\n        'Kiwis',\n        'Kumquat',\n        'Lemons',\n        'Limes',\n        'Mangos',\n        'Mulberries',\n        'Muskmelon',\n        'Nectarines',\n        'Olives',\n        'Oranges',\n        'Papaya',\n        'Peaches',\n        'Pears',\n        'Persimmon',\n        'Pineapple',\n        'Plums',\n        'Pomegranate',\n        'Raspberries',\n        'Rose Apple',\n        'Starfruit',\n        'Strawberries',\n        'Tangerines',\n        'Tomatoes',\n        'Watermelons',\n        'Zucchini',\n      ],\n      selectedFruits: [],\n    }),\n\n    computed: {\n      likesAllFruit () {\n        return this.selectedFruits.length === this.fruits.length\n      },\n      likesSomeFruit () {\n        return this.selectedFruits.length > 0\n      },\n      title () {\n        if (this.likesAllFruit) return 'Holy smokes, someone call the fruit police!'\n\n        if (this.likesSomeFruit) return 'Fruit Count'\n\n        return 'How could you not like fruit?'\n      },\n      subtitle () {\n        if (this.likesAllFruit) return undefined\n\n        if (this.likesSomeFruit) return this.selectedFruits.length\n\n        return 'Go ahead, make a selection above!'\n      },\n    },\n\n    methods: {\n      toggle () {\n        if (this.likesAllFruit) {\n          this.selectedFruits = []\n        } else {\n          this.selectedFruits = this.fruits.slice()\n        }\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-select/slot-item.vue",
    "content": "<template>\n  <v-select :items=\"items\" item-title=\"name\" label=\"User\">\n    <template v-slot:item=\"{ props: itemProps, item }\">\n      <v-list-item v-bind=\"itemProps\" :subtitle=\"item.department\"></v-list-item>\n    </template>\n  </v-select>\n</template>\n\n<script setup>\n  const items = [\n    {\n      name: 'John',\n      department: 'Marketing',\n    },\n    {\n      name: 'Jane',\n      department: 'Engineering',\n    },\n    {\n      name: 'Joe',\n      department: 'Sales',\n    },\n    {\n      name: 'Janet',\n      department: 'Engineering',\n    },\n    {\n      name: 'Jake',\n      department: 'Marketing',\n    },\n    {\n      name: 'Jack',\n      department: 'Sales',\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        {\n          name: 'John',\n          department: 'Marketing',\n        },\n        {\n          name: 'Jane',\n          department: 'Engineering',\n        },\n        {\n          name: 'Joe',\n          department: 'Sales',\n        },\n        {\n          name: 'Janet',\n          department: 'Engineering',\n        },\n        {\n          name: 'Jake',\n          department: 'Marketing',\n        },\n        {\n          name: 'Jack',\n          department: 'Sales',\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-select/slot-menu-header-and-footer.vue",
    "content": "<template>\n  <v-container>\n    <v-select\n      v-model=\"model\"\n      v-model:menu=\"menu\"\n      :items=\"items\"\n      item-title=\"value\"\n      item-value=\"id\"\n      multiple\n    >\n      <template v-slot:menu-header=\"{ search, filteredItems }\">\n        <div class=\"pa-2 border-b\">\n          <v-text-field\n            v-model=\"search.value\"\n            :error=\"!!search.value && !filteredItems.length\"\n            density=\"compact\"\n            placeholder=\"Search...\"\n            prepend-inner-icon=\"mdi-magnify\"\n            variant=\"outlined\"\n            clearable\n            hide-details\n          ></v-text-field>\n        </div>\n      </template>\n\n      <template v-slot:menu-footer=\"{ search, filteredItems }\">\n        <div class=\"d-flex align-center pa-2 pl-4 border-t\">\n          <span v-if=\"search.value\" class=\"text-body-2\">\n            Found {{ filteredItems.length }} of {{ items.length }}\n          </span>\n\n          <v-btn\n            class=\"ml-auto\"\n            text=\"Done\"\n            variant=\"tonal\"\n            @click=\"menu = false\"\n          ></v-btn>\n        </div>\n      </template>\n    </v-select>\n  </v-container>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const items = [\n    { id: 1, value: 'Apple' },\n    { id: 2, value: 'Banana' },\n    { id: 3, value: 'Cherry' },\n    { id: 4, value: 'Mango' },\n    { id: 5, value: 'Orange' },\n    { id: 6, value: 'Peach' },\n    { id: 7, value: 'Pineapple' },\n    { id: 8, value: 'Strawberry' },\n  ]\n\n  const model = shallowRef([])\n  const menu = shallowRef(false)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        { id: 1, value: 'Apple' },\n        { id: 2, value: 'Banana' },\n        { id: 3, value: 'Cherry' },\n        { id: 4, value: 'Mango' },\n        { id: 5, value: 'Orange' },\n        { id: 6, value: 'Peach' },\n        { id: 7, value: 'Pineapple' },\n        { id: 8, value: 'Strawberry' },\n      ],\n      model: [],\n      menu: false,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-select/slot-selection.vue",
    "content": "<template>\n  <v-select\n    v-model=\"value\"\n    :items=\"items\"\n    label=\"Select Item\"\n    multiple\n  >\n    <template v-slot:selection=\"{ item, index }\">\n      <v-chip v-if=\"index < 2\" :text=\"item\"></v-chip>\n\n      <span\n        v-if=\"index === 2\"\n        class=\"text-grey text-body-small align-self-center\"\n      >\n        (+{{ value.length - 2 }} others)\n      </span>\n    </template>\n  </v-select>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const value = shallowRef(['foo', 'bar', 'fizz'])\n  const items = ['foo', 'bar', 'fizz', 'buzz', 'fizzbuzz', 'foobar']\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      value: ['foo', 'bar', 'fizz'],\n      items: ['foo', 'bar', 'fizz', 'buzz', 'fizzbuzz', 'foobar'],\n    }),\n  }\n</script>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2074-33165&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-select/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div>\n      <v-select v-bind=\"props\"></v-select>\n    </div>\n\n    <template v-slot:configuration>\n      <v-checkbox v-model=\"clear\" label=\"Clearable\"></v-checkbox>\n\n      <v-checkbox v-model=\"chips\" label=\"Chips\"></v-checkbox>\n\n      <v-checkbox v-model=\"multiple\" label=\"Multiple\"></v-checkbox>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-select'\n  const model = shallowRef('default')\n  const clear = shallowRef(false)\n  const chips = shallowRef(false)\n  const multiple = shallowRef(false)\n  const options = ['outlined', 'underlined', 'solo', 'solo-filled', 'solo-inverted']\n  const props = computed(() => {\n    return {\n      clearable: clear.value || undefined,\n      chips: chips.value || undefined,\n      label: 'Select',\n      items: ['California', 'Colorado', 'Florida', 'Georgia', 'Texas', 'Wyoming'],\n      multiple: multiple.value || undefined,\n      variant: model.value === 'default' ? undefined : model.value,\n    }\n  })\n\n  const slots = computed(() => {\n    return ``\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-sheet/misc-congratulations.vue",
    "content": "<template>\n  <v-sheet\n    class=\"d-flex align-center justify-center flex-wrap text-center mx-auto px-4\"\n    elevation=\"2\"\n    height=\"250\"\n    max-width=\"800\"\n    width=\"100%\"\n    rounded\n  >\n    <div>\n      <h2 class=\"text-headline-large font-weight-black text-orange my-0\">Congratulations!</h2>\n\n      <div class=\"text-headline-small font-weight-medium mb-2\">\n        You are officially a part of the Vuetify Community!\n      </div>\n\n      <p class=\"text-body-medium mb-4\">\n        Please head over to your inbox/spam or others folder to find our verification email.\n      </p>\n\n      <v-btn color=\"orange\" variant=\"text\">Go to Login</v-btn>\n    </div>\n  </v-sheet>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-sheet/misc-privacy-policy.vue",
    "content": "<template>\n  <v-sheet\n    border=\"md\"\n    class=\"pa-6 text-white mx-auto\"\n    color=\"#141518\"\n    max-width=\"400\"\n  >\n    <h4 class=\"text-headline-small font-weight-bold mt-0 mb-4\">Your Privacy</h4>\n\n    <p class=\"mb-8\">\n      This business determines the use of personal data collected on our media properties and across the internet. We may collect data that you submit to us directly or data that we collect automatically including from cookies (such as device information or IP address).\n\n      <br>\n      <br>\n\n      Please read our <a class=\"text-red-accent-2\" href=\"#\">Privacy Policy</a> to learn about our privacy practices or click \"Your Preferences\" to exercise control over your data.\n    </p>\n\n    <v-btn\n      class=\"text-none text-black mb-4\"\n      color=\"red-accent-2\"\n      size=\"x-large\"\n      variant=\"flat\"\n      block\n    >\n      Accept\n    </v-btn>\n\n    <v-btn\n      class=\"text-none text-black\"\n      color=\"red-accent-2\"\n      size=\"x-large\"\n      variant=\"outlined\"\n      block\n    >\n      Your Preferences\n    </v-btn>\n  </v-sheet>\n</template>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=1646-137533&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-sheet/misc-reconcile.vue",
    "content": "<template>\n  <v-sheet\n    class=\"pa-4 text-center mx-auto\"\n    elevation=\"4\"\n    max-width=\"600\"\n    rounded=\"lg\"\n    width=\"100%\"\n  >\n    <v-icon\n      class=\"mb-5\"\n      color=\"success\"\n      icon=\"mdi-check-circle\"\n      size=\"112\"\n    ></v-icon>\n\n    <h2 class=\"text-headline-small mt-0 mb-6\">You reconciled this account</h2>\n\n    <p class=\"mb-4 text-medium-emphasis text-body-medium\">\n      To see a report on this reconciliation, click <a class=\"text-decoration-none text-info\" href=\"#\">View reconciliation report.</a>\n\n      <br>\n\n      Otherwise, you're done!\n    </p>\n\n    <v-divider class=\"mb-4\"></v-divider>\n\n    <div class=\"text-end\">\n      <v-btn\n        class=\"text-none\"\n        color=\"success\"\n        variant=\"flat\"\n        width=\"90\"\n        rounded\n      >\n        Done\n      </v-btn>\n    </div>\n  </v-sheet>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-sheet/misc-referral-program.vue",
    "content": "<template>\n  <v-sheet\n    border=\"lg opacity-12\"\n    class=\"text-body-medium mx-auto\"\n    max-width=\"550\"\n  >\n    <v-container fluid>\n      <v-row>\n        <v-col cols=\"12\" md=\"3\">\n          <v-img height=\"88\" src=\"https://cdn.vuetifyjs.com/docs/images/graphics/img-placeholder.png\" cover></v-img>\n        </v-col>\n\n        <v-col cols=\"12\" md=\"9\">\n          <p class=\"mb-4\">\n            This is part of our <a href=\"#\">Most Comprehensive Guide to Referral Programs</a> > <a href=\"#\">Do I Need A Referral Program?</a> section. You may enjoy other related articles:\n          </p>\n\n          <ul class=\"ps-4 mb-6\">\n            <li>\n              <a href=\"#\">5 Ways to See if Referral Programs Can Work for You</a>\n            </li>\n            <li>\n              <a href=\"#\">The 6 Key Benefits of Referral Marketing</a>\n            </li>\n            <li>\n              <a href=\"#\">Leading Indicators of Referral Program Success</a>\n            </li>\n            <li>\n              <a href=\"#\">Debunking the Top 5 Worst Referral Program Myths</a>\n            </li>\n          </ul>\n\n          <v-btn\n            class=\"text-none\"\n            color=\"info\"\n            rounded=\"0\"\n            variant=\"flat\"\n            block\n          >\n            <span class=\"hidden-sm-and-down\">\n              Explore our 38+ Referral Program Resources\n            </span>\n\n            <span class=\"hidden-md-and-up\">\n              Explore Referral Resources\n            </span>\n          </v-btn>\n        </v-col>\n      </v-row>\n    </v-container>\n  </v-sheet>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-sheet/prop-color.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"flex-child text-title-small\">\n      <v-col\n        class=\"d-flex\"\n        cols=\"12\"\n        md=\"4\"\n      >\n        <v-sheet\n          class=\"d-flex\"\n          color=\"grey-lighten-3\"\n          height=\"424\"\n        >\n          <sheet-footer>\n            #1: (3r x 2c)\n          </sheet-footer>\n        </v-sheet>\n      </v-col>\n\n      <v-col\n        class=\"d-flex\"\n        cols=\"12\"\n        md=\"4\"\n      >\n        <v-row class=\"ma-n3\">\n          <v-col cols=\"6\">\n            <v-sheet\n              class=\"d-flex\"\n              color=\"green-lighten-3\"\n              height=\"150\"\n            >\n              <sheet-footer>\n                #2: (1r x 1c)\n              </sheet-footer>\n            </v-sheet>\n          </v-col>\n\n          <v-col cols=\"6\">\n            <v-sheet\n              class=\"d-flex\"\n              color=\"yellow-lighten-3\"\n              height=\"150\"\n            >\n              <sheet-footer>\n                #3: (1r x 1c)\n              </sheet-footer>\n            </v-sheet>\n          </v-col>\n\n          <v-col cols=\"12\">\n            <v-sheet\n              class=\"d-flex\"\n              color=\"red-lighten-3\"\n              height=\"250\"\n            >\n              <sheet-footer>\n                #5: (2r x 2c)\n              </sheet-footer>\n            </v-sheet>\n          </v-col>\n        </v-row>\n      </v-col>\n\n      <v-col\n        cols=\"6\"\n        md=\"2\"\n      >\n        <v-sheet\n          class=\"d-flex\"\n          color=\"teal-lighten-3\"\n          height=\"300\"\n        >\n          <sheet-footer>\n            #4: (2r x 1c)\n          </sheet-footer>\n        </v-sheet>\n      </v-col>\n\n      <v-col\n        class=\"d-flex\"\n        cols=\"6\"\n        md=\"2\"\n      >\n        <v-sheet\n          class=\"d-flex mt-auto\"\n          color=\"purple-lighten-3\"\n          height=\"300\"\n        >\n          <sheet-footer>\n            #6: (2r x 1c)\n          </sheet-footer>\n        </v-sheet>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { h } from 'vue'\n\n  const SheetFooter = {\n    setup (_, { slots }) {\n      return () => h('v-sheet', {\n        class: 'ma-auto px-4',\n        color: 'rgba(0, 0, 0, .36)',\n        height: 50,\n      }, slots.default())\n    },\n  }\n</script>\n\n<script>\n  import { h } from 'vue'\n\n  export default {\n    components: {\n      // A simple helper component\n      SheetFooter: {\n        setup (_, { slots }) {\n          return () => h('v-sheet', {\n            class: 'ma-auto px-4',\n            color: 'rgba(0, 0, 0, .36)',\n            height: 50,\n          }, slots.default())\n        },\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-sheet/prop-elevation.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"justify-space-around\">\n      <v-col\n        v-for=\"elevation in [0, 1, 2, 3, 4, 5]\"\n        :key=\"elevation\"\n        cols=\"12\"\n        md=\"4\"\n      >\n        <v-sheet\n          class=\"pa-12\"\n          color=\"grey-lighten-3\"\n        >\n          <v-sheet\n            :elevation=\"elevation\"\n            class=\"mx-auto\"\n            height=\"100\"\n            width=\"100\"\n          ></v-sheet>\n        </v-sheet>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-sheet/prop-rounded.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"justify-space-around\">\n      <v-col\n        v-for=\"rounded in [false, true, 'xl']\"\n        :key=\"String(rounded)\"\n        cols=\"12\"\n        md=\"4\"\n      >\n        <v-sheet\n          class=\"pa-12\"\n          color=\"grey-lighten-3\"\n        >\n          <div></div>\n          <v-sheet\n            :rounded=\"rounded\"\n            class=\"mx-auto\"\n            height=\"100\"\n            width=\"100\"\n          ></v-sheet>\n          <div></div>\n        </v-sheet>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-sheet/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div class=\"py-8 bg-surface-bright\">\n      <v-sheet\n        v-if=\"sheet\"\n        v-model=\"sheet\"\n        v-bind=\"props\"\n        class=\"mx-auto\"\n      >\n        <template v-slot:text>\n          Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!\n        </template>\n      </v-sheet>\n\n      <div class=\"text-center\">\n        <v-btn v-if=\"!sheet\" @click=\"sheet = true\">\n          Show sheet\n        </v-btn>\n      </div>\n    </div>\n\n    <template v-slot:configuration>\n      <v-select\n        v-model=\"color\"\n        :items=\"[\n          'success',\n          'info',\n          'warning',\n          'error',\n        ]\"\n        label=\"Color\"\n        clearable\n      ></v-select>\n\n      <v-checkbox v-model=\"border\" label=\"Border\"></v-checkbox>\n\n      <v-checkbox v-model=\"rounded\" label=\"Rounded\"></v-checkbox>\n\n      <v-slider\n        v-model=\"elevation\"\n        label=\"Elevation\"\n        max=\"5\"\n        min=\"0\"\n      ></v-slider>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-sheet'\n  const model = ref('default')\n  const sheet = ref(true)\n  const border = ref(false)\n  const elevation = ref(0)\n  const rounded = ref(false)\n  const color = ref()\n  const options = []\n  const props = computed(() => {\n    return {\n      elevation: elevation.value || undefined,\n      height: 200,\n      width: 200,\n      border: border.value || undefined,\n      color: color.value || undefined,\n      rounded: rounded.value || undefined,\n    }\n  })\n\n  const slots = computed(() => {\n    return ''\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-skeleton-loader/misc-ice-cream.vue",
    "content": "<template>\n  <div>\n    <div class=\"text-center\">\n      <v-btn\n        class=\"mb-12\"\n        size=\"x-large\"\n        @click=\"loading = !loading\"\n      >\n        Toggle Loading\n      </v-btn>\n    </div>\n\n    <v-card\n      max-width=\"800\"\n      rounded=\"lg\"\n      theme=\"dark\"\n    >\n      <v-container>\n        <v-row>\n          <v-col\n            v-for=\"{ src, title, subtitle } in cards\"\n            :key=\"title\"\n            cols=\"12\"\n            lg=\"4\"\n            md=\"6\"\n          >\n            <v-skeleton-loader\n              :loading=\"loading\"\n              height=\"240\"\n              type=\"image, list-item-two-line\"\n            >\n              <v-responsive>\n                <v-img\n                  :src=\"src\"\n                  class=\"rounded-lg mb-2\"\n                  height=\"184\"\n                  cover\n                ></v-img>\n\n                <v-list-item\n                  :subtitle=\"subtitle\"\n                  :title=\"title\"\n                  class=\"px-0\"\n                ></v-list-item>\n              </v-responsive>\n            </v-skeleton-loader>\n          </v-col>\n        </v-row>\n\n        <br>\n\n        <v-chip\n          prepend-icon=\"mdi-check-circle\"\n          size=\"large\"\n          variant=\"text\"\n          border\n        >\n          <template v-slot:prepend>\n            <v-icon color=\"disabled\"></v-icon>\n          </template>\n\n          <span class=\"text-body-large\">\n            Homemade Dulce de Leche Ice Cream with Chocolate Chips\n          </span>\n        </v-chip>\n      </v-container>\n    </v-card>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const cards = [\n    {\n      title: 'Homemade Dulce de Leche Ice Cream with Chocolate Chips',\n      subtitle: 'Happy Foods',\n      src: 'https://cdn.vuetifyjs.com/docs/images/graphics/dulce-ice-cream.png',\n    },\n    {\n      title: 'Salted Caramel Swirl Ice Cream',\n      subtitle: 'Stone Kitchen',\n      src: 'https://cdn.vuetifyjs.com/docs/images/graphics/salted-caramel-ice-cream.png',\n    },\n    {\n      title: 'Peanut Butter No-Churn Ice Cream',\n      subtitle: 'The Sweeter Side',\n      src: 'https://cdn.vuetifyjs.com/docs/images/graphics/peanut-butter-ice-cream.png',\n    },\n  ]\n\n  const loading = ref(true)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      cards: [\n        {\n          title: 'Homemade Dulce de Leche Ice Cream with Chocolate Chips',\n          subtitle: 'Happy Foods',\n          src: 'https://cdn.vuetifyjs.com/docs/images/graphics/dulce-ice-cream.png',\n        },\n        {\n          title: 'Salted Caramel Swirl Ice Cream',\n          subtitle: 'Stone Kitchen',\n          src: 'https://cdn.vuetifyjs.com/docs/images/graphics/salted-caramel-ice-cream.png',\n        },\n        {\n          title: 'Peanut Butter No-Churn Ice Cream',\n          subtitle: 'The Sweeter Side',\n          src: 'https://cdn.vuetifyjs.com/docs/images/graphics/peanut-butter-ice-cream.png',\n        },\n      ],\n      loading: true,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-skeleton-loader/prop-boilerplate.vue",
    "content": "<template>\n  <v-skeleton-loader\n    class=\"mx-auto\"\n    elevation=\"1\"\n    max-width=\"360\"\n    type=\"card-avatar, article, actions\"\n    boilerplate\n  ></v-skeleton-loader>\n</template>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2268-64260&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-skeleton-loader/prop-elevation.vue",
    "content": "<template>\n  <v-skeleton-loader\n    class=\"mx-auto\"\n    elevation=\"4\"\n    max-width=\"400\"\n    type=\"table-heading, list-item-two-line, image, table-tfoot\"\n  ></v-skeleton-loader>\n</template>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2268-64190&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-skeleton-loader/prop-loading.vue",
    "content": "<template>\n  <v-container>\n    <div class=\"text-center mb-12\">\n      <v-btn\n        size=\"x-large\"\n        @click=\"loading = !loading\"\n      >\n        Toggle Loading\n      </v-btn>\n    </div>\n\n    <v-row class=\"justify-center\">\n      <v-col\n        class=\"mb-12\"\n        cols=\"12\"\n        md=\"6\"\n      >\n        <div class=\"text-headline-small text-center\">\n          Using slot\n        </div>\n\n        <v-skeleton-loader\n          :loading=\"loading\"\n          type=\"list-item-two-line\"\n        >\n          <v-list-item\n            lines=\"two\"\n            subtitle=\"Subtitle\"\n            title=\"Title\"\n            rounded\n          ></v-list-item>\n        </v-skeleton-loader>\n      </v-col>\n\n      <v-col\n        cols=\"12\"\n        md=\"6\"\n      >\n        <div class=\"text-headline-small text-center\">\n          Using if\n        </div>\n\n        <v-skeleton-loader\n          v-if=\"loading\"\n          type=\"list-item-two-line\"\n        ></v-skeleton-loader>\n\n        <v-list-item\n          v-else\n          lines=\"two\"\n          subtitle=\"Subtitle\"\n          title=\"Title\"\n          rounded\n        ></v-list-item>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const loading = ref(true)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      loading: true,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-skeleton-loader/prop-type.vue",
    "content": "<template>\n  <v-container>\n    <v-row>\n      <v-col cols=\"12\" md=\"6\">\n        <v-skeleton-loader\n          class=\"mx-auto border\"\n          max-width=\"300\"\n          type=\"card-avatar, actions\"\n        ></v-skeleton-loader>\n      </v-col>\n\n      <v-col cols=\"12\" md=\"6\">\n        <v-skeleton-loader\n          class=\"mx-auto border\"\n          max-width=\"300\"\n          type=\"image, article\"\n        ></v-skeleton-loader>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2766-81686&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-skeleton-loader/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div>\n      <v-skeleton-loader\n        v-bind=\"props\"\n        class=\"mx-auto\"\n        max-width=\"300\"\n      ></v-skeleton-loader>\n    </div>\n\n    <template v-slot:configuration>\n      <v-select\n        v-model=\"type\"\n        :items=\"types\"\n        label=\"Type\"\n        clearable\n      ></v-select>\n\n      <v-select\n        v-model=\"color\"\n        :items=\"colors\"\n        label=\"Color\"\n        clearable\n      ></v-select>\n\n      <v-slider\n        v-model=\"elevation\"\n        label=\"Elevation\"\n        max=\"5\"\n        min=\"0\"\n      ></v-slider>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-skeleton-loader'\n  const model = ref('default')\n  const options = ['boilerplate']\n  const elevation = ref()\n  const color = ref()\n  const colors = ['primary', 'secondary', 'success', 'info', 'warning', 'error']\n  const type = ref('card')\n  const types = ['card', 'paragraph', 'list-item-avatar', 'article', 'card-avatar']\n\n  const props = computed(() => {\n    return {\n      elevation: elevation.value || undefined,\n      boilerplate: model.value === 'boilerplate' || undefined,\n      color: color.value || undefined,\n      type: type.value || undefined,\n    }\n  })\n\n  const slots = computed(() => {\n    return ''\n  })\n\n  const code = computed(() => {\n    return `<v-skeleton-loader${propsToString(props.value)}>${slots.value}</v-skeleton-loader>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-slide-group/misc-pseudo-carousel.vue",
    "content": "<template>\n  <v-sheet\n    class=\"mx-auto\"\n    elevation=\"3\"\n    max-width=\"800\"\n  >\n    <v-slide-group\n      v-model=\"model\"\n      class=\"pa-4\"\n      selected-class=\"bg-primary\"\n      show-arrows\n    >\n      <v-slide-group-item\n        v-for=\"n in 15\"\n        :key=\"n\"\n        v-slot=\"{ isSelected, toggle, selectedClass }\"\n      >\n        <v-card\n          :class=\"['ma-4', selectedClass]\"\n          color=\"grey-lighten-1\"\n          height=\"200\"\n          width=\"100\"\n          @click=\"toggle\"\n        >\n          <div class=\"d-flex fill-height align-center justify-center\">\n            <v-scale-transition>\n              <v-icon\n                v-if=\"isSelected\"\n                color=\"white\"\n                icon=\"mdi-close-circle-outline\"\n                size=\"48\"\n              ></v-icon>\n            </v-scale-transition>\n          </div>\n        </v-card>\n      </v-slide-group-item>\n    </v-slide-group>\n\n    <v-expand-transition>\n      <v-sheet\n        v-if=\"model != null\"\n        height=\"200\"\n      >\n        <div class=\"d-flex fill-height align-center justify-center\">\n          <h3 class=\"text-title-large my-0\">\n            Selected {{ model }}\n          </h3>\n        </div>\n      </v-sheet>\n    </v-expand-transition>\n  </v-sheet>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const model = ref(null)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      model: null,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-slide-group/prop-active-class.vue",
    "content": "<template>\n  <v-sheet\n    class=\"mx-auto\"\n    elevation=\"3\"\n    max-width=\"800\"\n  >\n    <v-slide-group\n      v-model=\"model\"\n      class=\"pa-4\"\n      selected-class=\"bg-success\"\n      show-arrows\n    >\n      <v-slide-group-item\n        v-for=\"n in 15\"\n        :key=\"n\"\n        v-slot=\"{ isSelected, toggle, selectedClass }\"\n      >\n        <v-card\n          :class=\"['ma-4', selectedClass]\"\n          color=\"grey-lighten-1\"\n          height=\"200\"\n          width=\"100\"\n          @click=\"toggle\"\n        >\n          <div class=\"d-flex fill-height align-center justify-center\">\n            <v-scale-transition>\n              <v-icon\n                v-if=\"isSelected\"\n                color=\"white\"\n                icon=\"mdi-close-circle-outline\"\n                size=\"48\"\n              ></v-icon>\n            </v-scale-transition>\n          </div>\n        </v-card>\n      </v-slide-group-item>\n    </v-slide-group>\n  </v-sheet>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const model = ref(null)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      model: null,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-slide-group/prop-center-active.vue",
    "content": "<template>\n  <v-sheet\n    class=\"mx-auto\"\n    elevation=\"3\"\n    max-width=\"800\"\n  >\n    <v-slide-group\n      v-model=\"model\"\n      class=\"pa-4\"\n      center-active\n      show-arrows\n    >\n      <v-slide-group-item\n        v-for=\"n in 15\"\n        :key=\"n\"\n        v-slot=\"{ isSelected, toggle }\"\n      >\n        <v-card\n          :color=\"isSelected ? 'primary' : 'grey-lighten-1'\"\n          class=\"ma-4\"\n          height=\"200\"\n          width=\"100\"\n          @click=\"toggle\"\n        >\n          <div class=\"d-flex fill-height align-center justify-center\">\n            <v-scale-transition>\n              <v-icon\n                v-if=\"isSelected\"\n                color=\"white\"\n                icon=\"mdi-close-circle-outline\"\n                size=\"48\"\n              ></v-icon>\n            </v-scale-transition>\n          </div>\n        </v-card>\n      </v-slide-group-item>\n    </v-slide-group>\n  </v-sheet>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const model = ref(null)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      model: null,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-slide-group/prop-custom-icons.vue",
    "content": "<template>\n  <v-sheet\n    class=\"mx-auto\"\n    elevation=\"3\"\n    max-width=\"800\"\n  >\n    <v-slide-group\n      v-model=\"model\"\n      class=\"pa-4\"\n      next-icon=\"mdi-plus\"\n      prev-icon=\"mdi-minus\"\n      selected-class=\"bg-primary\"\n      show-arrows\n    >\n      <v-slide-group-item\n        v-for=\"n in 15\"\n        :key=\"n\"\n        v-slot=\"{ isSelected, toggle, selectedClass }\"\n      >\n        <v-card\n          :class=\"['ma-4', selectedClass]\"\n          color=\"grey-lighten-1\"\n          height=\"200\"\n          width=\"100\"\n          @click=\"toggle\"\n        >\n          <div class=\"d-flex fill-height align-center justify-center\">\n            <v-scale-transition>\n              <v-icon\n                v-if=\"isSelected\"\n                color=\"white\"\n                icon=\"mdi-close-circle-outline\"\n                size=\"48\"\n              ></v-icon>\n            </v-scale-transition>\n          </div>\n        </v-card>\n      </v-slide-group-item>\n    </v-slide-group>\n  </v-sheet>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const model = ref(null)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      model: null,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-slide-group/prop-mandatory.vue",
    "content": "<template>\n  <v-sheet\n    class=\"mx-auto\"\n    elevation=\"3\"\n    max-width=\"800\"\n  >\n    <v-slide-group\n      v-model=\"model\"\n      class=\"pa-4\"\n      selected-class=\"bg-primary\"\n      mandatory\n      show-arrows\n    >\n      <v-slide-group-item\n        v-for=\"n in 15\"\n        :key=\"n\"\n        v-slot=\"{ isSelected, toggle, selectedClass }\"\n      >\n        <v-card\n          :class=\"['ma-4', selectedClass]\"\n          color=\"grey-lighten-1\"\n          height=\"200\"\n          width=\"100\"\n          @click=\"toggle\"\n        >\n          <div class=\"d-flex fill-height align-center justify-center\">\n            <v-scale-transition>\n              <v-icon\n                v-if=\"isSelected\"\n                color=\"white\"\n                icon=\"mdi-close-circle-outline\"\n                size=\"48\"\n              ></v-icon>\n            </v-scale-transition>\n          </div>\n        </v-card>\n      </v-slide-group-item>\n    </v-slide-group>\n  </v-sheet>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const model = ref(null)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      model: null,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-slide-group/prop-multiple.vue",
    "content": "<template>\n  <v-sheet\n    class=\"mx-auto\"\n    elevation=\"3\"\n    max-width=\"800\"\n  >\n    <v-slide-group\n      v-model=\"model\"\n      class=\"pa-4\"\n      selected-class=\"bg-primary\"\n      multiple\n      show-arrows\n    >\n      <v-slide-group-item\n        v-for=\"n in 15\"\n        :key=\"n\"\n        v-slot=\"{ isSelected, toggle, selectedClass }\"\n      >\n        <v-card\n          :class=\"['ma-4', selectedClass]\"\n          color=\"grey-lighten-1\"\n          height=\"200\"\n          width=\"100\"\n          @click=\"toggle\"\n        >\n          <div class=\"d-flex fill-height align-center justify-center\">\n            <v-scale-transition>\n              <v-icon\n                v-if=\"isSelected\"\n                color=\"white\"\n                icon=\"mdi-close-circle-outline\"\n                size=\"48\"\n              ></v-icon>\n            </v-scale-transition>\n          </div>\n        </v-card>\n      </v-slide-group-item>\n    </v-slide-group>\n  </v-sheet>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const model = ref([])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      model: [],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-slide-group/usage.vue",
    "content": "<template>\n  <v-sheet\n    class=\"mx-auto\"\n    max-width=\"600\"\n  >\n    <v-slide-group\n      show-arrows\n    >\n      <v-slide-group-item\n        v-for=\"n in 25\"\n        :key=\"n\"\n        v-slot=\"{ isSelected, toggle }\"\n      >\n        <v-btn\n          :color=\"isSelected ? 'primary' : undefined\"\n          class=\"ma-2\"\n          rounded\n          @click=\"toggle\"\n        >\n          Options {{ n }}\n        </v-btn>\n      </v-slide-group-item>\n    </v-slide-group>\n  </v-sheet>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-slider/prop-colors.vue",
    "content": "<template>\n  <div>\n    <v-slider\n      v-model=\"slider1\"\n      color=\"orange\"\n      label=\"color\"\n    ></v-slider>\n\n    <v-slider\n      v-model=\"slider2\"\n      label=\"track-color\"\n      track-color=\"green\"\n    ></v-slider>\n\n    <v-slider\n      v-model=\"slider3\"\n      label=\"thumb-color\"\n      thumb-color=\"purple\"\n    ></v-slider>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const slider1 = ref(0)\n  const slider2 = ref(50)\n  const slider3 = ref(100)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      slider1: 0,\n      slider2: 50,\n      slider3: 100,\n    }),\n  }\n</script>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2723-45045&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-slider/prop-disabled.vue",
    "content": "<template>\n  <v-slider\n    model-value=\"30\"\n    disabled\n  ></v-slider>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-slider/prop-icons.vue",
    "content": "<template>\n  <div>\n    <div class=\"text-body-small\">Media volume</div>\n\n    <v-slider\n      v-model=\"media\"\n      prepend-icon=\"mdi-volume-high\"\n    ></v-slider>\n\n    <div class=\"text-body-small\">Alarm volume</div>\n\n    <v-slider\n      v-model=\"alarm\"\n      append-icon=\"mdi-alarm\"\n    ></v-slider>\n\n    <div class=\"text-body-small\">Icon click callback</div>\n\n    <v-slider\n      v-model=\"zoom\"\n      append-icon=\"mdi-magnify-plus-outline\"\n      prepend-icon=\"mdi-magnify-minus-outline\"\n      @click:append=\"zoomIn\"\n      @click:prepend=\"zoomOut\"\n    ></v-slider>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const media = ref(0)\n  const alarm = ref(0)\n  const zoom = ref(0)\n\n  function zoomOut () {\n    zoom.value = (zoom.value - 10) || 0\n  }\n  function zoomIn () {\n    zoom.value = (zoom.value + 10) || 100\n  }\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        media: 0,\n        alarm: 0,\n        zoom: 0,\n      }\n    },\n\n    methods: {\n      zoomOut () {\n        this.zoom = (this.zoom - 10) || 0\n      },\n      zoomIn () {\n        this.zoom = (this.zoom + 10) || 100\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-slider/prop-min-and-max.vue",
    "content": "<template>\n  <v-slider\n    v-model=\"slider\"\n    :max=\"max\"\n    :min=\"min\"\n    class=\"align-center\"\n    hide-details\n  >\n    <template v-slot:append>\n      <v-text-field\n        v-model=\"slider\"\n        density=\"compact\"\n        style=\"width: 70px\"\n        type=\"number\"\n        hide-details\n        single-line\n      ></v-text-field>\n    </template>\n  </v-slider>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const min = ref(-50)\n  const max = ref(90)\n  const slider = ref(40)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        min: -50,\n        max: 90,\n        slider: 40,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-slider/prop-readonly.vue",
    "content": "<template>\n  <v-slider\n    label=\"Readonly\"\n    model-value=\"30\"\n    readonly\n  ></v-slider>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-slider/prop-step.vue",
    "content": "<template>\n  <v-slider\n    v-model=\"value\"\n    :max=\"1\"\n    :min=\"0\"\n    :step=\"0.2\"\n    thumb-label\n  ></v-slider>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const value = ref(0)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        value: 0,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-slider/prop-thumb.vue",
    "content": "<template>\n  <div class=\"d-flex flex-column\">\n    <div>\n      <div class=\"text-body-small\">\n        Show thumb when using slider\n      </div>\n      <v-slider\n        v-model=\"slider1\"\n        thumb-label\n      ></v-slider>\n    </div>\n\n    <div>\n      <div class=\"text-body-small\">\n        Always show thumb label\n      </div>\n      <v-slider\n        v-model=\"slider2\"\n        thumb-label=\"always\"\n      ></v-slider>\n    </div>\n\n    <div>\n      <div class=\"text-body-small\">\n        Show thumb label on hover and focus\n      </div>\n      <v-slider\n        v-model=\"slider5\"\n        thumb-label=\"hover\"\n      ></v-slider>\n    </div>\n\n    <div>\n      <div class=\"text-body-small\">\n        Show thumb label on hover and focus\n      </div>\n      <v-slider\n        v-model=\"slider5\"\n        thumb-label=\"hover\"\n      ></v-slider>\n    </div>\n\n    <div>\n      <div class=\"text-body-small\">\n        Custom thumb size\n      </div>\n      <v-slider\n        v-model=\"slider3\"\n        :thumb-size=\"36\"\n        thumb-label=\"always\"\n      ></v-slider>\n    </div>\n\n    <div>\n      <div class=\"text-body-small\">\n        Custom thumb label\n      </div>\n      <v-slider\n        v-model=\"slider4\"\n        thumb-label=\"always\"\n      >\n        <template v-slot:thumb-label=\"{ modelValue }\">\n          {{ satisfactionEmojis[Math.min(Math.floor(modelValue / 10), 9)] }}\n        </template>\n      </v-slider>\n    </div>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const slider1 = ref(50)\n  const slider2 = ref(50)\n  const slider3 = ref(50)\n  const slider4 = ref(50)\n  const slider5 = ref(50)\n\n  const satisfactionEmojis = ['\\uD83D\\uDE2D', '\\uD83D\\uDE22', '\\u2639\\uFE0F', '\\uD83D\\uDE41', '\\uD83D\\uDE10', '\\uD83D\\uDE42', '\\uD83D\\uDE0A', '\\uD83D\\uDE01', '\\uD83D\\uDE04', '\\uD83D\\uDE0D']\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        slider1: 50,\n        slider2: 50,\n        slider3: 50,\n        slider4: 50,\n        slider5: 50,\n        satisfactionEmojis: ['😭', '😢', '☹️', '🙁', '😐', '🙂', '😊', '😁', '😄', '😍'],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-slider/prop-ticks.vue",
    "content": "<template>\n  <div>\n    <div class=\"text-body-small\">Show ticks when using slider</div>\n\n    <v-slider\n      step=\"10\"\n      show-ticks\n    ></v-slider>\n\n    <div class=\"text-body-small\">Always show ticks</div>\n\n    <v-slider\n      show-ticks=\"always\"\n      step=\"10\"\n    ></v-slider>\n\n    <div class=\"text-body-small\">Tick size</div>\n\n    <v-slider\n      show-ticks=\"always\"\n      step=\"10\"\n      tick-size=\"4\"\n    ></v-slider>\n\n    <div class=\"text-body-small\">Tick labels</div>\n\n    <v-slider\n      :max=\"3\"\n      :ticks=\"tickLabels\"\n      show-ticks=\"always\"\n      step=\"1\"\n      tick-size=\"4\"\n    ></v-slider>\n  </div>\n</template>\n\n<script setup>\n  const tickLabels = {\n    0: 'Figs',\n    1: 'Lemon',\n    2: 'Pear',\n    3: 'Apple',\n  }\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        tickLabels: {\n          0: 'Figs',\n          1: 'Lemon',\n          2: 'Pear',\n          3: 'Apple',\n        },\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-slider/prop-validation.vue",
    "content": "<template>\n  <v-card\n    color=\"transparent\"\n    flat\n  >\n    <div class=\"text-title-small\">Rules</div>\n\n    <v-card-text class=\"pt-0\">\n      <v-slider\n        v-model=\"value\"\n        :rules=\"rules\"\n        label=\"How many?\"\n        step=\"10\"\n        thumb-label=\"always\"\n        ticks\n      ></v-slider>\n    </v-card-text>\n\n    <div class=\"text-title-small\">Persistent hint</div>\n\n    <v-card-text class=\"pt-0\">\n      <v-slider\n        v-model=\"value\"\n        :rules=\"rules\"\n        hint=\"40 in stock\"\n        label=\"How many?\"\n        step=\"10\"\n        thumb-label=\"always\"\n        persistent-hint\n        ticks\n      ></v-slider>\n    </v-card-text>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const value = ref(30)\n\n  const rules = [\n    v => v <= 40 || 'Only 40 in stock',\n  ]\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        value: 30,\n        rules: [\n          v => v <= 40 || 'Only 40 in stock',\n        ],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-slider/prop-vertical.vue",
    "content": "<template>\n  <v-slider\n    v-model=\"value\"\n    direction=\"vertical\"\n    label=\"Regular\"\n  ></v-slider>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const value = ref(10)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        value: 10,\n      }\n    },\n  }\n</script>\n\n<style scoped>\n  .v-slider :deep(> .v-input__control) {\n    /* overrides $slider-vertical-min-height: 300px */\n    min-height: 150px;\n  }\n</style>\n"
  },
  {
    "path": "packages/docs/src/examples/v-slider/slot-append-and-prepend.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"600\"\n  >\n    <v-toolbar\n      dense\n      flat\n    >\n      <v-toolbar-title>\n        <span class=\"text-subheading\">METRONOME</span>\n      </v-toolbar-title>\n      <v-btn icon=\"mdi-share-variant\" variant=\"text\"></v-btn>\n    </v-toolbar>\n\n    <v-card-text>\n      <v-row class=\"mb-4 justify-space-between\">\n        <v-col class=\"text-left\">\n          <span\n            class=\"text-display-large font-weight-light\"\n            v-text=\"bpm\"\n          ></span>\n          <span class=\"subheading font-weight-light me-1\">BPM</span>\n          <v-fade-transition>\n            <v-avatar\n              v-if=\"isPlaying\"\n              :color=\"color\"\n              :style=\"{\n                animationDuration: animationDuration\n              }\"\n              class=\"mb-1 v-avatar--metronome\"\n              size=\"12\"\n            ></v-avatar>\n          </v-fade-transition>\n        </v-col>\n        <v-col class=\"text-right\">\n          <v-btn\n            :color=\"color\"\n            elevation=\"0\"\n            theme=\"dark\"\n            icon\n            @click=\"toggle\"\n          >\n            <v-icon :icon=\"isPlaying ? 'mdi-pause' : 'mdi-play'\" size=\"large\"></v-icon>\n          </v-btn>\n        </v-col>\n      </v-row>\n\n      <v-slider\n        v-model=\"bpm\"\n        :color=\"color\"\n        :step=\"1\"\n        max=\"218\"\n        min=\"40\"\n        track-color=\"grey\"\n      >\n        <template v-slot:prepend>\n          <v-btn\n            :color=\"color\"\n            icon=\"mdi-minus\"\n            size=\"small\"\n            variant=\"text\"\n            @click=\"decrement\"\n          ></v-btn>\n        </template>\n\n        <template v-slot:append>\n          <v-btn\n            :color=\"color\"\n            icon=\"mdi-plus\"\n            size=\"small\"\n            variant=\"text\"\n            @click=\"increment\"\n          ></v-btn>\n        </template>\n      </v-slider>\n    </v-card-text>\n  </v-card>\n</template>\n\n<script setup>\n  import { computed, ref } from 'vue'\n\n  const bpm = ref(40)\n  const isPlaying = ref(false)\n\n  const color = computed(() => {\n    if (bpm.value < 100) return 'indigo'\n    if (bpm.value < 125) return 'teal'\n    if (bpm.value < 140) return 'green'\n    if (bpm.value < 175) return 'orange'\n    return 'red'\n  })\n  const animationDuration = computed(() => {\n    return `${60 / bpm.value}s`\n  })\n\n  function decrement () {\n    bpm.value--\n  }\n  function increment () {\n    bpm.value++\n  }\n  function toggle () {\n    isPlaying.value = !isPlaying.value\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      bpm: 40,\n      isPlaying: false,\n    }),\n\n    computed: {\n      color () {\n        if (this.bpm < 100) return 'indigo'\n        if (this.bpm < 125) return 'teal'\n        if (this.bpm < 140) return 'green'\n        if (this.bpm < 175) return 'orange'\n        return 'red'\n      },\n      animationDuration () {\n        return `${60 / this.bpm}s`\n      },\n    },\n\n    methods: {\n      decrement () {\n        this.bpm--\n      },\n      increment () {\n        this.bpm++\n      },\n      toggle () {\n        this.isPlaying = !this.isPlaying\n      },\n    },\n  }\n</script>\n\n<style>\n  @keyframes metronome-example {\n    from {\n      transform: scale(.5);\n    }\n\n    to {\n      transform: scale(1);\n    }\n  }\n\n  .v-avatar--metronome {\n    animation-name: metronome-example;\n    animation-iteration-count: infinite;\n    animation-direction: alternate;\n  }\n</style>\n"
  },
  {
    "path": "packages/docs/src/examples/v-slider/slot-append-text-field.vue",
    "content": "<template>\n  <v-card style=\"margin: auto\" width=\"400\">\n    <v-responsive\n      :style=\"{ background: `rgb(${red}, ${green}, ${blue})` }\"\n      height=\"300px\"\n    ></v-responsive>\n\n    <v-card-text>\n      <v-slider\n        v-model=\"red\"\n        :max=\"255\"\n        :step=\"1\"\n        class=\"ma-4\"\n        label=\"R\"\n        hide-details\n      >\n        <template v-slot:append>\n          <v-text-field\n            v-model=\"red\"\n            density=\"compact\"\n            style=\"width: 80px\"\n            type=\"number\"\n            variant=\"outlined\"\n            hide-details\n          ></v-text-field>\n        </template>\n      </v-slider>\n\n      <v-slider\n        v-model=\"green\"\n        :max=\"255\"\n        :step=\"1\"\n        class=\"ma-4\"\n        label=\"G\"\n        hide-details\n      >\n        <template v-slot:append>\n          <v-text-field\n            v-model=\"green\"\n            density=\"compact\"\n            style=\"width: 80px\"\n            type=\"number\"\n            variant=\"outlined\"\n            hide-details\n          ></v-text-field>\n        </template>\n      </v-slider>\n\n      <v-slider\n        v-model=\"blue\"\n        :max=\"255\"\n        :step=\"1\"\n        class=\"ma-4\"\n        label=\"B\"\n        hide-details\n      >\n        <template v-slot:append>\n          <v-text-field\n            v-model=\"blue\"\n            density=\"compact\"\n            style=\"width: 80px\"\n            type=\"number\"\n            variant=\"outlined\"\n            hide-details\n          ></v-text-field>\n        </template>\n      </v-slider>\n    </v-card-text>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const red = ref(64)\n  const green = ref(128)\n  const blue = ref(10)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        red: 64,\n        green: 128,\n        blue: 10,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-slider/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div>\n      <v-slider v-bind=\"props\"></v-slider>\n    </div>\n\n    <template v-slot:configuration>\n      <v-checkbox v-model=\"disabled\" label=\"Disabled\"></v-checkbox>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-slider'\n  const model = ref('default')\n  const options = ['vertical']\n  const disabled = ref(false)\n  const props = computed(() => {\n    return {\n      direction: model.value === 'vertical' ? 'vertical' : undefined,\n      disabled: disabled.value || undefined,\n    }\n  })\n\n  const slots = computed(() => {\n    return ``\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-snackbar/prop-loading.vue",
    "content": "<template>\n  <v-layout min-height=\"100\">\n    <v-snackbar\n      v-model=\"loadingSnackbar\"\n      :timeout=\"-1\"\n      text=\"Uploading file...\"\n      contained\n      loading\n    ></v-snackbar>\n    <v-snackbar\n      v-model=\"successSnackbar\"\n      :timeout=\"2000\"\n      color=\"success\"\n      prepend-icon=\"$complete\"\n      text=\"Uploading successful!\"\n      contained\n    ></v-snackbar>\n  </v-layout>\n</template>\n\n<script setup>\n  import { shallowRef, watch } from 'vue'\n\n  const loadingSnackbar = shallowRef(true)\n  const successSnackbar = shallowRef(false)\n\n  watch(loadingSnackbar, val => {\n    if (val) {\n      setTimeout(() => {\n        loadingSnackbar.value = false\n        successSnackbar.value = true\n      }, 2000)\n    } else {\n      setTimeout(() => {\n        loadingSnackbar.value = true\n      }, 3000)\n    }\n  }, { immediate: true })\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      loadingSnackbar: true,\n      successSnackbar: false,\n    }),\n    watch: {\n      loadingSnackbar: {\n        handler (val) {\n          if (val) {\n            setTimeout(() => {\n              this.loadingSnackbar = false\n              this.successSnackbar = true\n            }, 2000)\n          } else {\n            setTimeout(() => {\n              this.loadingSnackbar = true\n            }, 3000)\n          }\n        },\n        immediate: true,\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-snackbar/prop-prepend-avatar.vue",
    "content": "<template>\n  <v-layout min-height=\"100\">\n    <v-snackbar\n      color=\"indigo\"\n      prepend-avatar=\"https://cdn.vuetifyjs.com/images/john.jpg\"\n      text=\"Hey, are you available for a quick call?\"\n      timeout=\"-1\"\n      title=\"John Leider\"\n      contained\n      model-value\n    ></v-snackbar>\n  </v-layout>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-snackbar/prop-prepend-icon.vue",
    "content": "<template>\n  <v-layout min-height=\"250\">\n    <v-snackbar\n      color=\"success\"\n      location=\"bottom start\"\n      prepend-icon=\"$success\"\n      text=\"Your changes have been saved.\"\n      timeout=\"-1\"\n      title=\"Success\"\n      contained\n      model-value\n    >\n      <template v-slot:actions>\n        <v-btn\n          class=\"px-3\"\n          density=\"comfortable\"\n          rounded=\"lg\"\n          text=\"Got it!\"\n          variant=\"tonal\"\n          @click.stop\n        ></v-btn>\n      </template>\n    </v-snackbar>\n\n    <v-snackbar\n      color=\"warning\"\n      location=\"top end\"\n      prepend-icon=\"mdi-wifi-strength-alert-outline\"\n      text=\"Connection has been lost.\"\n      timeout=\"-1\"\n      title=\"Network issue\"\n      variant=\"elevated\"\n      contained\n      model-value\n    ></v-snackbar>\n\n    <v-snackbar\n      color=\"error\"\n      location=\"center\"\n      prepend-icon=\"mdi-cancel\"\n      rounded=\"pill\"\n      text=\"Operation is not allowed\"\n      timeout=\"-1\"\n      variant=\"tonal\"\n      contained\n      model-value\n    ></v-snackbar>\n  </v-layout>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-snackbar/prop-timeout.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-btn\n      color=\"orange-darken-2\"\n      @click=\"snackbar = true\"\n    >\n      Open Snackbar\n    </v-btn>\n\n    <v-snackbar\n      v-model=\"snackbar\"\n      :timeout=\"timeout\"\n    >\n      {{ text }}\n\n      <template v-slot:actions>\n        <v-btn\n          color=\"blue\"\n          variant=\"text\"\n          @click=\"snackbar = false\"\n        >\n          Close\n        </v-btn>\n      </template>\n    </v-snackbar>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const snackbar = ref(false)\n  const text = ref('My timeout is set to 2000.')\n  const timeout = ref(2000)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      snackbar: false,\n      text: 'My timeout is set to 2000.',\n      timeout: 2000,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-snackbar/prop-timer-position.vue",
    "content": "<template>\n  <v-layout height=\"150\">\n    <v-container class=\"d-flex flex-wrap ga-3 justify-center\">\n      <v-btn text=\"Timer Top\" @click=\"current = 1\"></v-btn>\n      <v-btn text=\"Timer bottom\" @click=\"current = 2\"></v-btn>\n      <v-btn text=\"Top Reversed\" @click=\"current = 3\"></v-btn>\n      <v-btn text=\"Bottom Reversed\" @click=\"current = 4\"></v-btn>\n    </v-container>\n\n    <v-snackbar\n      :model-value=\"current === 1\"\n      text=\"Timer at the top\"\n      timer=\"top\"\n      timer-color=\"green\"\n      contained\n      @update:model-value=\"current = -1\"\n    ></v-snackbar>\n\n    <v-snackbar\n      :model-value=\"current === 2\"\n      text=\"Timer at the bottom\"\n      timer=\"bottom\"\n      timer-color=\"info\"\n      contained\n      @update:model-value=\"current = -1\"\n    ></v-snackbar>\n\n    <v-snackbar\n      :model-value=\"current === 3\"\n      text=\"Reversed timer\"\n      timer-color=\"warning\"\n      contained\n      reverse-timer\n      timer\n      @update:model-value=\"current = -1\"\n    ></v-snackbar>\n\n    <v-snackbar\n      :model-value=\"current === 4\"\n      text=\"Reversed bottom timer\"\n      timer=\"bottom\"\n      timer-color=\"error\"\n      contained\n      reverse-timer\n      @update:model-value=\"current = -1\"\n    ></v-snackbar>\n  </v-layout>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const current = shallowRef(-1)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      current: -1,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-snackbar/prop-variants.vue",
    "content": "<template>\n  <v-sheet\n    class=\"d-flex flex-column\"\n  >\n    <v-snackbar\n      :timeout=\"2000\"\n    >\n      <template v-slot:activator=\"{ props }\">\n        <v-btn class=\"ma-2\" v-bind=\"props\">open</v-btn>\n      </template>\n\n      Lorem ipsum dolor sit amet consectetur.\n    </v-snackbar>\n\n    <v-snackbar\n      :timeout=\"2000\"\n      color=\"blue-grey\"\n      rounded=\"pill\"\n    >\n      <template v-slot:activator=\"{ props }\">\n        <v-btn class=\"ma-2\" color=\"blue-grey\" rounded=\"pill\" v-bind=\"props\">open</v-btn>\n      </template>\n\n      Snackbar with <strong>rounded=\"pill\"</strong>.\n    </v-snackbar>\n\n    <v-snackbar\n      :timeout=\"2000\"\n      class=\"elevation-5\"\n      color=\"deep-purple-accent-4\"\n    >\n      <template v-slot:activator=\"{ props }\">\n        <v-btn class=\"ma-2\" color=\"deep-purple-accent-4\" v-bind=\"props\">open</v-btn>\n      </template>\n\n      Snackbar with <strong>elevation=\"2\"</strong>.\n    </v-snackbar>\n\n    <v-snackbar\n      :timeout=\"2000\"\n      color=\"primary\"\n      variant=\"tonal\"\n    >\n      <template v-slot:activator=\"{ props }\">\n        <v-btn class=\"ma-2\" color=\"primary\" variant=\"tonal\" v-bind=\"props\">open</v-btn>\n      </template>\n\n      Snackbar with <strong>tonal</strong> variant.\n    </v-snackbar>\n\n    <v-snackbar\n      :timeout=\"2000\"\n      color=\"success\"\n      variant=\"outlined\"\n    >\n      <template v-slot:activator=\"{ props }\">\n        <v-btn class=\"ma-2\" color=\"success\" variant=\"outlined\" v-bind=\"props\">open</v-btn>\n      </template>\n\n      Snackbar with <strong>outlined</strong> variant.\n    </v-snackbar>\n  </v-sheet>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-snackbar/prop-vertical.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-btn\n      color=\"indigo\"\n      @click=\"snackbar = true\"\n    >\n      Open Snackbar\n    </v-btn>\n\n    <v-snackbar\n      v-model=\"snackbar\"\n      vertical\n    >\n      <div class=\"text-body-large pb-2\">This is a snackbar message</div>\n\n      <p>This is a longer paragraph explaining something</p>\n\n      <template v-slot:actions>\n        <v-btn\n          color=\"indigo\"\n          variant=\"text\"\n          @click=\"snackbar = false\"\n        >\n          Close\n        </v-btn>\n      </template>\n    </v-snackbar>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const snackbar = ref(false)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      snackbar: false,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-snackbar/slot-header.vue",
    "content": "<template>\n  <v-layout min-height=\"120\">\n    <v-snackbar\n      max-width=\"400\"\n      prepend-avatar=\"https://cdn.vuetifyjs.com/images/lists/2.jpg\"\n      text=\"The reproduction is missing. Would you...\"\n      timeout=\"-1\"\n      title=\"@marley4122\"\n      contained\n      model-value\n    >\n      <template v-slot:header>\n        <div class=\"d-flex text-body-small pa-3 pb-0\">\n          <div class=\"text-uppercase\">Signal</div>\n          <v-spacer></v-spacer>\n          <div>2 min ago</div>\n        </div>\n      </template>\n    </v-snackbar>\n  </v-layout>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-snackbar/slot-prepend.vue",
    "content": "<template>\n  <v-layout min-height=\"100\">\n    <v-snackbar\n      color=\"amber-lighten-3\"\n      text=\"There are new reports...\"\n      timeout=\"-1\"\n      title=\"New notifications\"\n      contained\n      model-value\n    >\n      <template v-slot:prepend>\n        <v-avatar class=\"bell-shake\" color=\"amber\" icon=\"mdi-bell-ring-outline\" variant=\"elevated\"></v-avatar>\n      </template>\n    </v-snackbar>\n  </v-layout>\n</template>\n\n<style scoped>\n  .bell-shake :deep(.v-icon) {\n    animation: bell-shake 1.8s ease 2s infinite;\n  }\n\n  @keyframes bell-shake {\n    0%, 100% { transform: rotate(0deg) }\n    5% { transform: rotate(14deg) }\n    10% { transform: rotate(-14deg) }\n    15% { transform: rotate(10deg) }\n    20% { transform: rotate(-8deg) }\n    25% { transform: rotate(4deg) }\n    30% { transform: rotate(0deg) }\n  }\n</style>\n"
  },
  {
    "path": "packages/docs/src/examples/v-snackbar/usage.vue",
    "content": "<template>\n  <div class=\"text-center ma-2\">\n    <v-btn\n      @click=\"snackbar = true\"\n    >\n      Open Snackbar\n    </v-btn>\n    <v-snackbar\n      v-model=\"snackbar\"\n    >\n      {{ text }}\n\n      <template v-slot:actions>\n        <v-btn\n          color=\"pink\"\n          variant=\"text\"\n          @click=\"snackbar = false\"\n        >\n          Close\n        </v-btn>\n      </template>\n    </v-snackbar>\n  </div>\n</template>\n\n<script>\n  export default {\n    data: () => ({\n      snackbar: false,\n      text: `Hello, I'm a snackbar`,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-snackbar-queue/misc-promise.vue",
    "content": "<template>\n  <v-layout height=\"200\">\n    <v-container class=\"d-flex justify-center ga-3\">\n      <v-btn color=\"success\" @click=\"addSuccess\">\n        Succeeding Task\n      </v-btn>\n\n      <v-btn color=\"error\" @click=\"addError\">\n        Failing Task\n      </v-btn>\n    </v-container>\n\n    <v-snackbar-queue\n      v-model=\"messages\"\n      :total-visible=\"3\"\n      contained\n    ></v-snackbar-queue>\n  </v-layout>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const messages = ref([])\n\n  function addSuccess () {\n    messages.value.push({\n      text: 'Saving...',\n      promise: new Promise(resolve => setTimeout(() => resolve('Done'), 1500)),\n      success: onSuccess,\n      error: onError,\n    })\n  }\n\n  function addError () {\n    messages.value.push({\n      text: 'Deleting...',\n      promise: new Promise((resolve, reject) => setTimeout(() => reject(new Error('500')), 1500)),\n      success: onSuccess,\n      error: onError,\n    })\n  }\n\n  function onSuccess () {\n    return {\n      text: 'Saved successfully!',\n      color: 'success',\n      prependIcon: '$success',\n      timeout: 1500,\n    }\n  }\n\n  function onError (data) {\n    return {\n      text: `Failed to save. Error code: ${data.message}`,\n      color: 'error',\n      prependIcon: '$error',\n      timeout: 3000,\n      timer: 'bottom',\n      reverseTimer: true,\n    }\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      messages: [],\n    }),\n    methods: {\n      addSuccess () {\n        this.messages.push({\n          text: 'Saving...',\n          promise: new Promise(resolve => setTimeout(() => resolve('Done'), 1500)),\n          success: this.onSuccess,\n          error: this.onError,\n        })\n      },\n      addError () {\n        this.messages.push({\n          text: 'Deleting...',\n          promise: new Promise((resolve, reject) => setTimeout(() => reject(new Error('500')), 1500)),\n          success: this.onSuccess,\n          error: this.onError,\n        })\n      },\n      onSuccess () {\n        return {\n          text: 'Saved successfully!',\n          color: 'success',\n          prependIcon: '$success',\n          timeout: 1500,\n        }\n      },\n      onError (data) {\n        return {\n          text: `Failed to save. Error code: ${data.message}`,\n          color: 'error',\n          prependIcon: '$error',\n          timeout: 3000,\n          timer: 'bottom',\n          reverseTimer: true,\n        }\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-snackbar-queue/prop-total-visible.vue",
    "content": "<template>\n  <v-layout height=\"300\">\n    <v-container class=\"d-flex flex-wrap gc-3 justify-center align-self-start\">\n      <v-btn color=\"primary\" height=\"50\" prepend-icon=\"$arrowleft\" spaced=\"start\" @click=\"addMessage1\">\n        <span class=\"text-right\">\n          <div class=\"mb-1\">Add Message</div>\n          <small class=\"opacity-80\">default (hold)</small>\n        </span>\n      </v-btn>\n      <v-btn append-icon=\"$arrowright\" color=\"primary\" height=\"50\" spaced=\"end\" @click=\"addMessage2\">\n        <span class=\"text-left\">\n          <div class=\"mb-1\">Add Message</div>\n          <small class=\"opacity-80\">overflow</small>\n        </span>\n      </v-btn>\n      <v-divider class=\"mt-4\"></v-divider>\n      <v-switch v-model=\"collapsed\" color=\"primary\" density=\"comfortable\" label=\"Collapsed\" hide-details></v-switch>\n      <v-divider class=\"mb-4\"></v-divider>\n      <v-btn text=\"Clear all\" @click=\"clearAll\"></v-btn>\n    </v-container>\n\n    <v-snackbar-queue\n      ref=\"queue1\"\n      v-model=\"messages1\"\n      :collapsed=\"collapsed\"\n      :total-visible=\"3\"\n      location=\"bottom start\"\n      closable\n      contained\n    >\n      <template v-slot:actions=\"{ props }\">\n        <v-icon-btn\n          aria-label=\"Close\"\n          icon=\"$close\"\n          size=\"small\"\n          variant=\"text\"\n          v-bind=\"props\"\n        ></v-icon-btn>\n      </template>\n    </v-snackbar-queue>\n\n    <v-snackbar-queue\n      ref=\"queue2\"\n      v-model=\"messages2\"\n      :collapsed=\"collapsed\"\n      :total-visible=\"3\"\n      display-strategy=\"overflow\"\n      location=\"bottom end\"\n      closable\n      contained\n    >\n      <template v-slot:actions=\"{ props }\">\n        <v-icon-btn\n          aria-label=\"Close\"\n          icon=\"$close\"\n          size=\"small\"\n          variant=\"text\"\n          v-bind=\"props\"\n        ></v-icon-btn>\n      </template>\n    </v-snackbar-queue>\n  </v-layout>\n</template>\n\n<script setup>\n  import { ref, shallowRef } from 'vue'\n\n  const queue1 = ref()\n  const queue2 = ref()\n  const messages1 = ref([])\n  const messages2 = ref([])\n  const collapsed = shallowRef(false)\n\n  let count = 0\n  let typeIndex = 1\n\n  function addMessage1 () {\n    messages1.value.push({\n      text: `Message #${++count}`,\n      colors: typeIndex++ % 3 === 1 ? 'success'\n        : typeIndex++ % 3 === 2 ? 'error'\n          : 'info',\n      zIndex: count,\n    })\n  }\n\n  function addMessage2 () {\n    messages2.value.push({\n      text: `Message #${++count}`,\n      colors: typeIndex++ % 3 === 1 ? 'success'\n        : typeIndex++ % 3 === 2 ? 'error'\n          : 'info',\n      zIndex: count,\n    })\n  }\n\n  function clearAll () {\n    queue1.value.clear()\n    queue2.value.clear()\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      messages1: [],\n      messages2: [],\n      collapsed: false,\n      count: 0,\n      typeIndex: 1,\n    }),\n    methods: {\n      addMessage1 () {\n        this.messages1.push({\n          text: `Message #${++this.count}`,\n          colors: this.typeIndex++ % 3 === 1 ? 'success'\n            : this.typeIndex++ % 3 === 2 ? 'error'\n              : 'info',\n          zIndex: this.count,\n        })\n      },\n      addMessage2 () {\n        this.messages2.push({\n          text: `Message #${++this.count}`,\n          colors: this.typeIndex++ % 3 === 1 ? 'success'\n            : this.typeIndex++ % 3 === 2 ? 'error'\n              : 'info',\n          zIndex: this.count,\n        })\n      },\n      clearAll () {\n        this.$refs.queue1.clear()\n        this.$refs.queue2.clear()\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-snackbar-queue/prop-transition.vue",
    "content": "<template>\n  <v-layout height=\"250\">\n    <v-container class=\"d-flex flex-column align-center gr-4 align-self-start\">\n      <v-icon-btn\n        color=\"primary\"\n        icon=\"mdi-refresh\"\n        @click=\"replay\"\n      ></v-icon-btn>\n      <v-code class=\"px-3 pb-0\">{{ currentLocation }}</v-code>\n    </v-container>\n\n    <v-snackbar-queue\n      ref=\"queue\"\n      v-model=\"messages\"\n      :location=\"currentLocation\"\n      timeout=\"3000\"\n      total-visible=\"4\"\n      transition=\"bouncy-slide-auto\"\n      closable\n      contained\n    >\n      <template v-slot:actions=\"{ item, props }\">\n        <v-icon-btn\n          v-if=\"!item.vertical\"\n          aria-label=\"Close\"\n          icon=\"$close\"\n          size=\"small\"\n          variant=\"text\"\n          v-bind=\"props\"\n        ></v-icon-btn>\n        <v-btn\n          v-else\n          text=\"Close\"\n          variant=\"text\"\n          v-bind=\"props\"\n        ></v-btn>\n      </template>\n    </v-snackbar-queue>\n  </v-layout>\n</template>\n\n<script setup>\n  import { ref, shallowRef, toRef, useTemplateRef } from 'vue'\n\n  const messages = ref([])\n  const queue = useTemplateRef('queue')\n\n  const locationIndex = shallowRef(0)\n  const locations = [\n    'top start',\n    'top end',\n    'bottom start',\n    'bottom end',\n  ]\n  const currentLocation = toRef(() => locations[locationIndex.value % 4])\n  let timeouts = []\n\n  async function replay () {\n    timeouts.forEach(clearTimeout)\n    queue.value?.clear()\n\n    await new Promise(resolve => setTimeout(resolve, 500))\n\n    timeouts = []\n    locationIndex.value++\n\n    messages.value = []\n\n    timeouts.push(setTimeout(() => {\n      messages.value.push({\n        text: 'Inbox check... please wait.',\n        color: 'info',\n      })\n    }, 300))\n    timeouts.push(setTimeout(() => {\n      messages.value.push({\n        text: 'You have 3 new messages in your Inbox.',\n        color: 'primary',\n      })\n    }, 700))\n    timeouts.push(setTimeout(() => {\n      messages.value.push({\n        text: 'Task submitted.',\n        color: 'success',\n      })\n    }, 1200))\n    timeouts.push(setTimeout(() => {\n      messages.value.push({\n        text: 'Your session will expire in 5 minutes.',\n        color: 'warning',\n      })\n    }, 1700))\n  }\n\n  replay()\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      messages: [],\n      locationIndex: 0,\n      timeouts: [],\n    }),\n    computed: {\n      currentLocation () {\n        const locations = [\n          'top start',\n          'top end',\n          'bottom start',\n          'bottom end',\n        ]\n        return locations[this.locationIndex % 4]\n      },\n    },\n    mounted () {\n      this.replay()\n    },\n    methods: {\n      async replay () {\n        this.timeouts.forEach(clearTimeout)\n        this.$refs.queue?.clear()\n\n        await new Promise(resolve => setTimeout(resolve, 500))\n\n        this.timeouts = []\n        this.locationIndex++\n        this.messages = []\n\n        this.timeouts.push(setTimeout(() => {\n          this.messages.push({\n            text: 'Inbox check... please wait.',\n            color: 'info',\n          })\n        }, 300))\n        this.timeouts.push(setTimeout(() => {\n          this.messages.push({\n            text: 'You have 3 new messages in your Inbox.',\n            color: 'primary',\n          })\n        }, 700))\n        this.timeouts.push(setTimeout(() => {\n          this.messages.push({\n            text: 'Task submitted.',\n            color: 'success',\n          })\n        }, 1200))\n        this.timeouts.push(setTimeout(() => {\n          this.messages.push({\n            text: 'Your session will expire in 5 minutes.',\n            color: 'warning',\n          })\n        }, 1700))\n      },\n    },\n  }\n</script>\n\n<style>\n.bouncy-slide-x-transition-enter-active,\n.bouncy-slide-x-transition-leave-active,\n.bouncy-slide-x-transition-move,\n.bouncy-slide-x-reverse-transition-enter-active,\n.bouncy-slide-x-reverse-transition-leave-active,\n.bouncy-slide-x-reverse-transition-move {\n  transition: transform, opacity;\n  transition-duration: 0.5s;\n  transition-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1);\n}\n.bouncy-slide-x-transition-enter-from,\n.bouncy-slide-x-transition-leave-to {\n  opacity: 0;\n  transform: translateX(-30%);\n}\n.bouncy-slide-x-reverse-transition-enter-from,\n.bouncy-slide-x-reverse-transition-leave-to {\n  opacity: 0;\n  transform: translateX(30%);\n}\n</style>\n"
  },
  {
    "path": "packages/docs/src/examples/v-snackbar-queue/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n    :script=\"script\"\n  >\n    <div style=\"height: 188px\">\n      <div class=\"d-flex ga-2\">\n        <v-btn color=\"success\" @click=\"addMessage('success')\">Success</v-btn>\n        <v-btn color=\"info\" @click=\"addMessage('info')\">Info</v-btn>\n        <v-btn color=\"error\" @click=\"addMessage('error')\">Error</v-btn>\n        <v-btn color=\"surface-variant\" @click=\"addMessage()\">Default</v-btn>\n        <v-btn prepend-icon=\"mdi-refresh\" variant=\"outlined\" @click=\"snackbarQueue?.clear()\">Clear</v-btn>\n      </div>\n\n      <v-list density=\"compact\" variant=\"tonal\" nav>\n        <v-list-subheader>Queue:</v-list-subheader>\n        <v-fade-transition\n          v-for=\"message in queue\"\n          :key=\"message\"\n          appear\n        >\n          <v-list-item\n            :color=\"message.color\"\n            :subtitle=\"message.timeout + 'ms'\"\n            :title=\"message.text\"\n          ></v-list-item>\n        </v-fade-transition>\n\n        <v-list-subheader>Logs:</v-list-subheader>\n        <v-list-item>\n          <pre\n            v-if=\"logs.length\"\n            class=\"overflow-y-auto text-caption text-pre-wrap my-0\"\n            style=\"max-height: 80px\"\n          >{{ logs.join('\\n') }}</pre>\n        </v-list-item>\n      </v-list>\n\n      <v-snackbar-queue\n        ref=\"snackbarQueue\"\n        v-model=\"queue\"\n        :collapsed=\"collapsed\"\n        :display-strategy=\"displayStrategy\"\n        :timeout=\"timeout\"\n        :total-visible=\"totalVisible\"\n        closable\n      ></v-snackbar-queue>\n    </div>\n\n    <template v-slot:configuration>\n      <v-select\n        v-model=\"displayStrategy\"\n        :items=\"['hold', 'overflow']\"\n        label=\"Display strategy\"\n      ></v-select>\n      <v-checkbox v-model=\"collapsed\" label=\"Collapsed\" hide-details></v-checkbox>\n      <v-slider\n        v-model=\"totalVisible\"\n        :max=\"10\"\n        :min=\"1\"\n        :step=\"1\"\n        label=\"Total visible\"\n        hide-details\n        thumb-label\n      ></v-slider>\n      <v-slider\n        v-model=\"timeout\"\n        :max=\"9000\"\n        :min=\"2000\"\n        :step=\"500\"\n        label=\"Timeout\"\n        hide-details\n        thumb-label\n      ></v-slider>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-snackbar-queue'\n  const model = ref('default')\n  const options = []\n  const timeout = shallowRef(5000)\n  const displayStrategy = shallowRef('hold')\n  const collapsed = shallowRef(false)\n  const totalVisible = shallowRef(5)\n  const snackbarQueue = ref()\n  const queue = ref([])\n  const logs = ref([])\n  let messageCount = 0\n\n  function addMessage (color) {\n    const id = ++messageCount\n    queue.value.push({\n      text: `Message #${id}`,\n      timeout: timeout.value,\n      color,\n      onDismiss (reason) {\n        logs.value.unshift(`Message #${id}: Closed (${reason})`)\n      },\n    })\n  }\n\n  const props = computed(() => {\n    return {\n      'v-model': 'messages',\n      'display-strategy': displayStrategy.value !== 'hold' ? displayStrategy.value : undefined,\n      collapsed: collapsed.value || undefined,\n      'total-visible': totalVisible.value > 1 ? totalVisible.value : undefined,\n      timeout: timeout.value !== 5000 ? timeout.value : undefined,\n      closable: true,\n    }\n  })\n\n  const slots = computed(() => {\n    return ''\n  })\n\n  const code = computed(() => {\n    return `<div class=\"d-flex ga-2\">\n  <v-btn color=\"success\" @click=\"addMessage('success')\">Success</v-btn>\n  <v-btn color=\"info\" @click=\"addMessage('info')\">Info</v-btn>\n  <v-btn color=\"error\" @click=\"addMessage('error')\">Error</v-btn>\n  <v-btn color=\"surface-variant\" @click=\"addMessage()\">Default</v-btn>\n  <v-btn prepend-icon=\"mdi-refresh\" variant=\"outlined\" @click=\"snackbarQueue?.clear()\">Clear</v-btn>\n</div>\n\n<pre>{{ logs.join('\\\\n') }}</pre>\n\n<v-snackbar-queue${propsToString(props.value)}>${slots.value}</v-snackbar-queue>`\n  })\n\n  const script = computed(() => {\n    return `<script setup>\n  import { ref } from 'vue'\n\n  const messages = ref([])\n  const logs = ref([])\n  let messageCount = 0\n\n  function addMessage (color) {\n    const id = ++messageCount\n    messages.value.push({\n      text: \\`Message #\\${id}\\`,\n      color,\n      onDismiss (reason) {\n        logs.value.unshift(\\`Message #\\${id}: Closed (\\${reason})\\`)\n      },\n    })\n  }\n<` + '/script>'\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-sparkline/misc-custom-labels.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto text-center\"\n    color=\"green\"\n    max-width=\"600\"\n    dark\n  >\n    <v-card-text>\n      <v-sheet color=\"rgba(0, 0, 0, .12)\">\n        <v-sparkline\n          :model-value=\"value\"\n          color=\"rgba(255, 255, 255, .7)\"\n          height=\"100\"\n          padding=\"24\"\n          stroke-linecap=\"round\"\n          smooth\n        >\n          <template v-slot:label=\"item\">\n            ${{ item.value }}\n          </template>\n        </v-sparkline>\n      </v-sheet>\n    </v-card-text>\n\n    <v-card-text>\n      <div class=\"text-headline-large font-weight-thin\">\n        Sales Last 24h\n      </div>\n    </v-card-text>\n\n    <v-divider></v-divider>\n\n    <v-card-actions class=\"justify-center\">\n      <v-btn\n        variant=\"text\"\n        block\n      >\n        Go to Report\n      </v-btn>\n    </v-card-actions>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const value = ref([\n    423,\n    446,\n    675,\n    510,\n    590,\n    610,\n    760,\n  ])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      value: [\n        423,\n        446,\n        675,\n        510,\n        590,\n        610,\n        760,\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-sparkline/misc-dashboard-card.vue",
    "content": "<template>\n  <v-card\n    class=\"mt-8 mx-auto overflow-visible\"\n    max-width=\"400\"\n  >\n    <v-sheet\n      class=\"v-sheet--offset mx-auto\"\n      color=\"cyan\"\n      elevation=\"4\"\n      max-width=\"calc(100% - 32px)\"\n      rounded=\"lg\"\n    >\n      <v-sparkline\n        :labels=\"labels\"\n        :model-value=\"value\"\n        color=\"white\"\n        line-width=\"2\"\n        padding=\"16\"\n      ></v-sparkline>\n    </v-sheet>\n\n    <v-card-text class=\"pt-0\">\n      <div class=\"text-title-large font-weight-light mb-2\">\n        User Registrations\n      </div>\n      <div class=\"subheading font-weight-light text-grey\">\n        Last Campaign Performance\n      </div>\n      <v-divider class=\"my-2\"></v-divider>\n      <v-icon\n        class=\"me-2\"\n        size=\"small\"\n      >\n        mdi-clock\n      </v-icon>\n      <span class=\"text-body-small text-grey font-weight-light\">last registration 26 minutes ago</span>\n    </v-card-text>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const labels = ref([\n    '12am',\n    '3am',\n    '6am',\n    '9am',\n    '12pm',\n    '3pm',\n    '6pm',\n    '9pm',\n  ])\n  const value = ref([\n    200,\n    675,\n    410,\n    390,\n    310,\n    460,\n    250,\n    240,\n  ])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      labels: [\n        '12am',\n        '3am',\n        '6am',\n        '9am',\n        '12pm',\n        '3pm',\n        '6pm',\n        '9pm',\n      ],\n      value: [\n        200,\n        675,\n        410,\n        390,\n        310,\n        460,\n        250,\n        240,\n      ],\n    }),\n  }\n</script>\n\n<style>\n  .v-sheet--offset {\n    top: -24px;\n    position: relative;\n  }\n</style>\n"
  },
  {
    "path": "packages/docs/src/examples/v-sparkline/misc-heart-rate.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    color=\"surface-light\"\n    max-width=\"600\"\n  >\n    <template v-slot:prepend>\n      <v-icon\n        :color=\"checking ? 'red lighten-2' : 'indigo-lighten-2'\"\n        class=\"me-8\"\n        icon=\"mdi-heart-pulse\"\n        size=\"64\"\n        @click=\"takePulse\"\n      ></v-icon>\n    </template>\n\n    <template v-slot:title>\n      <div class=\"text-body-small text-grey text-uppercase\">\n        Heart rate\n      </div>\n\n      <span\n        class=\"text-display-medium font-weight-black\"\n        v-text=\"avg || '—'\"\n      ></span>\n      <strong v-if=\"avg\">BPM</strong>\n    </template>\n\n    <template v-slot:append>\n      <v-btn\n        class=\"align-self-start\"\n        icon=\"mdi-arrow-right-thick\"\n        size=\"34\"\n        variant=\"text\"\n      ></v-btn>\n    </template>\n\n    <v-sheet color=\"transparent\">\n      <v-sparkline\n        :key=\"String(avg)\"\n        :gradient=\"['#f72047', '#ffd200', '#1feaea']\"\n        :line-width=\"3\"\n        :model-value=\"heartbeats\"\n        :smooth=\"16\"\n        stroke-linecap=\"round\"\n        auto-draw\n      ></v-sparkline>\n    </v-sheet>\n  </v-card>\n</template>\n\n<script setup>\n  import { computed, ref } from 'vue'\n\n  const exhale = ms => new Promise(resolve => setTimeout(resolve, ms))\n  const checking = ref(false)\n  const heartbeats = ref([])\n  const avg = computed(() => {\n    const sum = heartbeats.value.reduce((acc, cur) => acc + cur, 0)\n    const length = heartbeats.value.length\n    if (!sum && !length) return 0\n    return Math.ceil(sum / length)\n  })\n  function heartbeat () {\n    return Math.ceil(Math.random() * (120 - 80) + 80)\n  }\n  async function takePulse (inhale = true) {\n    checking.value = true\n    inhale && await exhale(1000)\n    heartbeats.value = Array.from({ length: 20 }, heartbeat)\n    checking.value = false\n  }\n  takePulse(false)\n</script>\n\n<script>\n  const exhale = ms =>\n    new Promise(resolve => setTimeout(resolve, ms))\n\n  export default {\n    data: () => ({\n      checking: false,\n      heartbeats: [],\n    }),\n\n    computed: {\n      avg () {\n        const sum = this.heartbeats.reduce((acc, cur) => acc + cur, 0)\n        const length = this.heartbeats.length\n\n        if (!sum && !length) return 0\n\n        return Math.ceil(sum / length)\n      },\n    },\n\n    created () {\n      this.takePulse(false)\n    },\n\n    methods: {\n      heartbeat () {\n        return Math.ceil(Math.random() * (120 - 80) + 80)\n      },\n      async takePulse (inhale = true) {\n        this.checking = true\n\n        inhale && await exhale(1000)\n\n        this.heartbeats = Array.from({ length: 20 }, this.heartbeat)\n\n        this.checking = false\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-sparkline/prop-fill.vue",
    "content": "<template>\n  <v-container fluid>\n    <v-sparkline\n      :fill=\"fill\"\n      :gradient=\"selectedGradient\"\n      :line-width=\"lineWidth\"\n      :model-value=\"value\"\n      :padding=\"padding\"\n      :smooth=\"smooth\"\n      auto-draw\n    ></v-sparkline>\n\n    <v-divider></v-divider>\n\n    <v-row>\n      <v-col\n        cols=\"12\"\n        md=\"6\"\n      >\n        <v-row class=\"fill-height align-center\">\n          <v-item-group\n            v-model=\"selectedGradient\"\n            mandatory\n          >\n            <v-row class=\"pt-6 pl-6\">\n              <v-item\n                v-for=\"(gradient, i) in gradients\"\n                :key=\"i\"\n                v-slot=\"{ active, toggle }\"\n                :value=\"gradient\"\n              >\n                <v-card\n                  :style=\"{\n                    background: gradient.length > 1\n                      ? `linear-gradient(0deg, ${gradient})`\n                      : gradient[0],\n                    border: '2px solid',\n                    borderColor: active ? '#222' : 'white'\n                  }\"\n                  class=\"me-2\"\n                  height=\"30\"\n                  width=\"30\"\n                  @click=\"toggle\"\n                ></v-card>\n              </v-item>\n            </v-row>\n          </v-item-group>\n        </v-row>\n      </v-col>\n    </v-row>\n\n    <v-row class=\"mt-5\">\n      <v-col\n        cols=\"2\"\n      >\n        Filled\n      </v-col>\n      <v-col\n        cols=\"3\"\n      >\n        <v-switch\n          v-model=\"fill\"\n          class=\"switch\"\n        ></v-switch>\n      </v-col>\n      <v-col\n        cols=\"3\"\n      >\n        Line width\n      </v-col>\n      <v-col\n        cols=\"3\"\n      >\n        <v-slider\n          v-model=\"lineWidth\"\n          max=\"10\"\n          min=\"0.1\"\n          step=\"0.1\"\n          thumb-label\n        ></v-slider>\n      </v-col>\n    </v-row>\n\n    <v-row>\n      <v-col\n        cols=\"2\"\n      >\n        Smooth\n      </v-col>\n      <v-col\n        cols=\"3\"\n      >\n        <v-switch\n          v-model=\"smooth\"\n          class=\"switch\"\n        ></v-switch>\n      </v-col>\n      <v-col\n        cols=\"3\"\n      >\n        Padding\n      </v-col>\n      <v-col\n        cols=\"3\"\n      >\n        <v-slider\n          v-model=\"padding\"\n          cols=\"3\"\n          max=\"25\"\n          min=\"0\"\n          thumb-label\n        ></v-slider>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const gradients = [\n    ['#222'],\n    ['#42b3f4'],\n    ['red', 'orange', 'yellow'],\n    ['purple', 'violet'],\n    ['#00c6ff', '#F0F', '#FF0'],\n    ['#f72047', '#ffd200', '#1feaea'],\n  ]\n  const fill = ref(true)\n  const selectedGradient = ref(gradients[4])\n  const padding = ref(8)\n  const smooth = ref(true)\n  const value = ref([0, 2, 5, 9, 5, 10, 3, 5, 0, 0, 1, 8, 2, 9, 0])\n  const lineWidth = ref(2)\n</script>\n\n<script>\n  const gradients = [\n    ['#222'],\n    ['#42b3f4'],\n    ['red', 'orange', 'yellow'],\n    ['purple', 'violet'],\n    ['#00c6ff', '#F0F', '#FF0'],\n    ['#f72047', '#ffd200', '#1feaea'],\n  ]\n\n  export default {\n    data: () => ({\n      fill: true,\n      selectedGradient: gradients[4],\n      gradients,\n      padding: 8,\n      smooth: true,\n      value: [0, 2, 5, 9, 5, 10, 3, 5, 0, 0, 1, 8, 2, 9, 0],\n      lineWidth: 2,\n    }),\n  }\n</script>\n\n<style scoped>\n.switch {\n  position: relative;\n  top: -12px;\n}\n</style>\n"
  },
  {
    "path": "packages/docs/src/examples/v-sparkline/usage.vue",
    "content": "<template>\n  <v-sparkline\n    :auto-line-width=\"autoLineWidth\"\n    :fill=\"fill\"\n    :gradient=\"gradient\"\n    :gradient-direction=\"gradientDirection\"\n    :line-width=\"width\"\n    :model-value=\"value\"\n    :padding=\"padding\"\n    :smooth=\"radius || false\"\n    :stroke-linecap=\"lineCap\"\n    :type=\"type\"\n    auto-draw\n  ></v-sparkline>\n</template>\n\n<script>\n  const gradients = [\n    ['#222'],\n    ['#42b3f4'],\n    ['red', 'orange', 'yellow'],\n    ['purple', 'violet'],\n    ['#00c6ff', '#F0F', '#FF0'],\n    ['#f72047', '#ffd200', '#1feaea'],\n  ]\n\n  export default {\n    data: () => ({\n      width: 2,\n      radius: 10,\n      padding: 8,\n      lineCap: 'round',\n      gradient: gradients[5],\n      value: [0, 2, 5, 9, 5, 10, 3, 5, 0, 0, 1, 8, 2, 9, 0],\n      gradientDirection: 'top',\n      gradients,\n      fill: false,\n      type: 'trend',\n      autoLineWidth: false,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-speed-dial/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <v-sheet class=\"text-center\" height=\"420\">\n      <v-fab icon=\"$vuetify\" size=\"large\">\n        <v-icon></v-icon>\n\n        <v-speed-dial\n          activator=\"parent\"\n          v-bind=\"props\"\n        >\n          <v-btn key=\"1\" color=\"surface-variant\" icon=\"$success\"></v-btn>\n          <v-btn key=\"2\" color=\"surface-variant\" icon=\"$info\"></v-btn>\n          <v-btn key=\"3\" color=\"surface-variant\" icon=\"$warning\"></v-btn>\n          <v-btn key=\"4\" color=\"surface-variant\" icon=\"$error\"></v-btn>\n        </v-speed-dial>\n      </v-fab>\n    </v-sheet>\n\n    <template v-slot:configuration>\n      <v-select v-model=\"location1\" :items=\"locations1\" label=\"Location 1\"></v-select>\n      <v-select v-model=\"location2\" :items=\"locations2\" label=\"Location 2\"></v-select>\n      <v-select v-model=\"transition\" :items=\"transitions\" label=\"Transition\"></v-select>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-speed-dial'\n  const model = shallowRef('default')\n  const options = []\n  const location1 = shallowRef('Bottom')\n  const locations1 = ['Top', 'Bottom', 'Left', 'Right']\n  const location2 = shallowRef('Center')\n  const locations2 = ['Top', 'Bottom', 'Center', 'Left', 'Right']\n  const location = computed(() => `${location1.value.toLowerCase()} ${location2.value.toLowerCase()}`)\n  const transition = shallowRef('fade-transition')\n  const transitions = ['scale-transition', 'slide-x-transition', 'slide-y-transition', 'slide-x-reverse-transition', 'slide-y-reverse-transition']\n  const props = computed(() => {\n    return {\n      location: location.value,\n      transition: transition.value,\n    }\n  })\n\n  const slots = computed(() => {\n    return `\n  <template v-slot:activator=\"{ props: activatorProps }\">\n    <v-fab\n      v-bind=\"activatorProps\"\n      size=\"large\"\n      icon=\"$vuetify\"\n    ></v-fab>\n  </template>\n\n  <v-btn key=\"1\" icon=\"$success\"></v-btn>\n  <v-btn key=\"2\" icon=\"$info\"></v-btn>\n  <v-btn key=\"3\" icon=\"$warning\"></v-btn>\n  <v-btn key=\"4\" icon=\"$error\"></v-btn>\n`\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-stepper/misc-alternate-error.vue",
    "content": "<template>\n  <v-stepper alt-labels>\n    <v-stepper-header>\n      <v-stepper-item\n        value=\"1\"\n        complete\n      >\n        <template v-slot:title>\n          Ad type\n        </template>\n      </v-stepper-item>\n\n      <v-divider></v-divider>\n\n      <v-stepper-item\n        value=\"2\"\n        complete\n      >\n        <template v-slot:title>\n          Ad style\n        </template>\n      </v-stepper-item>\n\n      <v-divider></v-divider>\n\n      <v-stepper-item\n        :rules=\"[() => false]\"\n        value=\"3\"\n      >\n        <template v-slot:title>\n          Custom channels\n        </template>\n\n        <template v-slot:subtitle>\n          Alert message\n        </template>\n      </v-stepper-item>\n\n      <v-divider></v-divider>\n\n      <v-stepper-item value=\"46\">\n        <template v-slot:title>\n          Get code\n        </template>\n      </v-stepper-item>\n    </v-stepper-header>\n  </v-stepper>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-stepper/misc-dynamic.vue",
    "content": "<template>\n  <div>\n    <v-card class=\"mb-4\">\n      <v-card-text>\n        <v-select\n          v-model=\"steps\"\n          :items=\"[2, 3, 4, 5, 6]\"\n          label=\"# of steps\"\n        ></v-select>\n      </v-card-text>\n    </v-card>\n\n    <v-stepper v-model=\"e1\">\n      <template v-slot:default=\"{ prev, next }\">\n        <v-stepper-header>\n          <template v-for=\"n in steps\" :key=\"`${n}-step`\">\n            <v-stepper-item\n              :complete=\"e1 > n\"\n              :step=\"`Step {{ n }}`\"\n              :value=\"n\"\n              editable\n            ></v-stepper-item>\n\n            <v-divider\n              v-if=\"n !== steps\"\n              :key=\"n\"\n            ></v-divider>\n          </template>\n        </v-stepper-header>\n\n        <v-stepper-window>\n          <v-stepper-window-item\n            v-for=\"n in steps\"\n            :key=\"`${n}-content`\"\n            :value=\"n\"\n          >\n            <v-card\n              color=\"grey-lighten-1\"\n              height=\"200\"\n            ></v-card>\n          </v-stepper-window-item>\n        </v-stepper-window>\n\n        <v-stepper-actions\n          :disabled=\"disabled\"\n          @click:next=\"next\"\n          @click:prev=\"prev\"\n        ></v-stepper-actions>\n      </template>\n    </v-stepper>\n  </div>\n</template>\n\n<script setup>\n  import { computed, ref } from 'vue'\n\n  const e1 = ref(1)\n  const steps = ref(2)\n\n  const disabled = computed(() => {\n    return e1.value === 1 ? 'prev' : e1.value === steps.value ? 'next' : undefined\n  })\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        e1: 1,\n        steps: 2,\n      }\n    },\n\n    computed: {\n      disabled () {\n        return this.e1 === 1 ? 'prev' : this.e1 === this.steps ? 'next' : undefined\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-stepper/misc-editable.vue",
    "content": "<template>\n  <v-stepper>\n    <v-stepper-header>\n      <v-stepper-item\n        title=\"Select campaign settings\"\n        value=\"1\"\n        complete\n        editable\n      ></v-stepper-item>\n\n      <v-divider></v-divider>\n\n      <v-stepper-item\n        title=\"Create an ad group\"\n        value=\"2\"\n        complete\n      ></v-stepper-item>\n\n      <v-divider></v-divider>\n\n      <v-stepper-item\n        title=\"Create an ad\"\n        value=\"3\"\n        editable\n      ></v-stepper-item>\n    </v-stepper-header>\n  </v-stepper>\n</template>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2747-64290&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-stepper/misc-error.vue",
    "content": "<template>\n  <v-stepper model-value=\"3\">\n    <v-stepper-header>\n      <v-stepper-item\n        title=\"Job Search\"\n        value=\"1\"\n        complete\n      ></v-stepper-item>\n\n      <v-divider></v-divider>\n\n      <v-stepper-item\n        :rules=\"[() => false]\"\n        subtitle=\"Missing Details\"\n        title=\"Submit Application\"\n        value=\"2\"\n      ></v-stepper-item>\n\n      <v-divider></v-divider>\n\n      <v-stepper-item\n        title=\"Interview Process\"\n        value=\"3\"\n      ></v-stepper-item>\n\n      <v-divider></v-divider>\n\n      <v-stepper-item\n        title=\"Hiring Decision\"\n        value=\"4\"\n      ></v-stepper-item>\n    </v-stepper-header>\n  </v-stepper>\n</template>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2747-64572&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-stepper/misc-horizontal.vue",
    "content": "<template>\n  <v-stepper\n    v-model=\"step\"\n    :items=\"items\"\n    show-actions\n  >\n    <template v-slot:item.1>\n      <h3 class=\"text-title-large my-0\">Order</h3>\n\n      <br>\n\n      <v-sheet border>\n        <v-table>\n          <thead>\n            <tr>\n              <th>Description</th>\n              <th class=\"text-end\">Quantity</th>\n              <th class=\"text-end\">Price</th>\n            </tr>\n          </thead>\n\n          <tbody>\n            <tr v-for=\"(product, index) in products\" :key=\"index\">\n              <td v-text=\"product.name\"></td>\n              <td class=\"text-end\" v-text=\"product.quantity\"></td>\n              <td class=\"text-end\" v-text=\"product.quantity * product.price\"></td>\n            </tr>\n\n            <tr>\n              <th>Total</th>\n              <th></th>\n              <th class=\"text-end\">\n                ${{ subtotal }}\n              </th>\n            </tr>\n          </tbody>\n        </v-table>\n      </v-sheet>\n    </template>\n\n    <template v-slot:item.2>\n      <h3 class=\"text-title-large my-0\">Shipping</h3>\n\n      <br>\n\n      <v-radio-group v-model=\"shipping\" label=\"Delivery Method\">\n        <v-radio label=\"Standard Shipping\" value=\"5\"></v-radio>\n        <v-radio label=\"Priority Shipping\" value=\"10\"></v-radio>\n        <v-radio label=\"Express Shipping\" value=\"15\"></v-radio>\n      </v-radio-group>\n    </template>\n\n    <template v-slot:item.3>\n      <h3 class=\"text-title-large my-0\">Confirm</h3>\n\n      <br>\n\n      <v-sheet border>\n        <v-table>\n          <thead>\n            <tr>\n              <th>Description</th>\n              <th class=\"text-end\">Quantity</th>\n              <th class=\"text-end\">Price</th>\n            </tr>\n          </thead>\n\n          <tbody>\n            <tr v-for=\"(product, index) in products\" :key=\"index\">\n              <td v-text=\"product.name\"></td>\n              <td class=\"text-end\" v-text=\"product.quantity\"></td>\n              <td class=\"text-end\" v-text=\"product.quantity * product.price\"></td>\n            </tr>\n\n            <tr>\n              <td>Shipping</td>\n              <td></td>\n              <td class=\"text-end\" v-text=\"shipping\"></td>\n            </tr>\n\n            <tr>\n              <th>Total</th>\n              <th></th>\n              <th class=\"text-end\">\n                ${{ total }}\n              </th>\n            </tr>\n          </tbody>\n        </v-table>\n      </v-sheet>\n    </template>\n  </v-stepper>\n</template>\n\n<script setup>\n  import { computed, ref } from 'vue'\n\n  const shipping = ref(0)\n  const step = ref(1)\n  const subtotal = computed(() => products.reduce((acc, product) => acc + product.quantity * product.price, 0))\n  const total = computed(() => subtotal.value + Number(shipping.value ?? 0))\n\n  const items = [\n    'Review Order',\n    'Select Shipping',\n    'Submit',\n  ]\n  const products = [\n    {\n      name: 'Product 1',\n      price: 10,\n      quantity: 2,\n    },\n    {\n      name: 'Product 2',\n      price: 15,\n      quantity: 10,\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      shipping: 0,\n      step: 1,\n      items: [\n        'Review Order',\n        'Select Shipping',\n        'Submit',\n      ],\n      products: [\n        {\n          name: 'Product 1',\n          price: 10,\n          quantity: 2,\n        },\n        {\n          name: 'Product 2',\n          price: 15,\n          quantity: 10,\n        },\n      ],\n    }),\n\n    computed: {\n      subtotal () {\n        return this.products.reduce((acc, product) => acc + product.quantity * product.price, 0)\n      },\n      total () {\n        return this.subtotal + Number(this.shipping ?? 0)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-stepper/misc-linear.vue",
    "content": "<template>\n  <v-stepper>\n    <v-stepper-header>\n      <v-stepper-item\n        title=\"Select campaign settings\"\n        value=\"1\"\n      ></v-stepper-item>\n\n      <v-divider></v-divider>\n\n      <v-stepper-item\n        title=\"Create an ad group\"\n        value=\"2\"\n      ></v-stepper-item>\n\n      <v-divider></v-divider>\n\n      <v-stepper-item\n        title=\"Create an ad\"\n        value=\"3\"\n      ></v-stepper-item>\n    </v-stepper-header>\n  </v-stepper>\n\n  <br>\n\n  <v-stepper model-value=\"2\">\n    <v-stepper-header>\n      <v-stepper-item\n        title=\"Select campaign settings\"\n        value=\"1\"\n        complete\n      ></v-stepper-item>\n\n      <v-divider></v-divider>\n\n      <v-stepper-item\n        title=\"Create an ad group\"\n        value=\"2\"\n      ></v-stepper-item>\n\n      <v-divider></v-divider>\n\n      <v-stepper-item\n        title=\"Create an ad\"\n        value=\"3\"\n      ></v-stepper-item>\n    </v-stepper-header>\n  </v-stepper>\n\n  <br>\n\n  <v-stepper model-value=\"3\">\n    <v-stepper-header>\n      <v-stepper-item\n        title=\"Select campaign settings\"\n        value=\"1\"\n        complete\n      ></v-stepper-item>\n\n      <v-divider></v-divider>\n\n      <v-stepper-item\n        title=\"Create an ad group\"\n        value=\"2\"\n        complete\n      ></v-stepper-item>\n\n      <v-divider></v-divider>\n\n      <v-stepper-item\n        title=\"Create an ad\"\n        value=\"3\"\n      ></v-stepper-item>\n    </v-stepper-header>\n  </v-stepper>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-stepper/misc-non-editable.vue",
    "content": "<template>\n  <v-stepper model-value=\"2\">\n    <v-stepper-header>\n      <v-stepper-item\n        title=\"Select campaign settings\"\n        value=\"1\"\n        complete\n      ></v-stepper-item>\n\n      <v-divider></v-divider>\n\n      <v-stepper-item\n        title=\"Create an ad group\"\n        value=\"2\"\n      ></v-stepper-item>\n\n      <v-divider></v-divider>\n\n      <v-stepper-item\n        title=\"Create an ad\"\n        value=\"3\"\n      ></v-stepper-item>\n    </v-stepper-header>\n  </v-stepper>\n</template>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2747-63988&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-stepper/misc-optional.vue",
    "content": "<template>\n  <v-stepper model-value=\"1\">\n    <v-stepper-header>\n      <v-stepper-item\n        title=\"Select campaign settings\"\n        value=\"1\"\n      ></v-stepper-item>\n\n      <v-divider></v-divider>\n\n      <v-stepper-item\n        subtitle=\"Optional\"\n        title=\"Create an ad group\"\n        value=\"2\"\n      ></v-stepper-item>\n\n      <v-divider></v-divider>\n\n      <v-stepper-item\n        title=\"Create an ad\"\n        value=\"3\"\n      ></v-stepper-item>\n    </v-stepper-header>\n  </v-stepper>\n\n  <br>\n\n  <v-stepper model-value=\"2\">\n    <v-stepper-header>\n      <v-stepper-item\n        title=\"Select campaign settings\"\n        value=\"1\"\n        complete\n      ></v-stepper-item>\n\n      <v-divider></v-divider>\n\n      <v-stepper-item\n        subtitle=\"Optional\"\n        title=\"Create an ad group\"\n        value=\"2\"\n      ></v-stepper-item>\n\n      <v-divider></v-divider>\n\n      <v-stepper-item\n        title=\"Create an ad\"\n        value=\"3\"\n      ></v-stepper-item>\n    </v-stepper-header>\n  </v-stepper>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-stepper/misc-vertical-error.vue",
    "content": "<template>\n  <v-stepper\n    v-model=\"e13\"\n    vertical\n  >\n    <v-stepper-step\n      step=\"1\"\n      complete\n    >\n      Name of step 1\n    </v-stepper-step>\n\n    <v-stepper-content step=\"1\">\n      <v-card\n        class=\"mb-12\"\n        color=\"grey-lighten-1\"\n        height=\"200px\"\n      ></v-card>\n      <v-btn\n        color=\"primary\"\n        @click=\"e13 = 2\"\n      >\n        Continue\n      </v-btn>\n      <v-btn variant=\"text\">\n        Cancel\n      </v-btn>\n    </v-stepper-content>\n\n    <v-stepper-step\n      step=\"2\"\n      complete\n    >\n      Name of step 2\n    </v-stepper-step>\n\n    <v-stepper-content step=\"2\">\n      <v-card\n        class=\"mb-12\"\n        color=\"grey-lighten-1\"\n        height=\"200px\"\n      ></v-card>\n      <v-btn\n        color=\"primary\"\n        @click=\"e13 = 3\"\n      >\n        Continue\n      </v-btn>\n      <v-btn variant=\"text\">\n        Cancel\n      </v-btn>\n    </v-stepper-content>\n\n    <v-stepper-step\n      :rules=\"[() => false]\"\n      step=\"3\"\n    >\n      Ad templates\n      <small>Alert message</small>\n    </v-stepper-step>\n\n    <v-stepper-content step=\"3\">\n      <v-card\n        class=\"mb-12\"\n        color=\"grey-lighten-1\"\n        height=\"200px\"\n      ></v-card>\n      <v-btn\n        color=\"primary\"\n        @click=\"e13 = 4\"\n      >\n        Continue\n      </v-btn>\n      <v-btn variant=\"text\">\n        Cancel\n      </v-btn>\n    </v-stepper-content>\n\n    <v-stepper-step step=\"4\">\n      View setup instructions\n    </v-stepper-step>\n\n    <v-stepper-content step=\"4\">\n      <v-card\n        class=\"mb-12\"\n        color=\"grey-lighten-1\"\n        height=\"200px\"\n      ></v-card>\n      <v-btn\n        color=\"primary\"\n        @click=\"e13 = 1\"\n      >\n        Continue\n      </v-btn>\n      <v-btn variant=\"text\">\n        Cancel\n      </v-btn>\n    </v-stepper-content>\n  </v-stepper>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const e13 = ref(2)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        e13: 2,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-stepper/prop-alternate-label.vue",
    "content": "<template>\n  <v-stepper alt-labels>\n    <v-stepper-header>\n      <v-stepper-item title=\"Ad unit details\" value=\"1\"></v-stepper-item>\n\n      <v-divider></v-divider>\n\n      <v-stepper-item title=\"Ad sizes\" value=\"2\"></v-stepper-item>\n\n      <v-divider></v-divider>\n\n      <v-stepper-item title=\"Ad templates\" value=\"3\"></v-stepper-item>\n    </v-stepper-header>\n  </v-stepper>\n</template>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2747-64411&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-stepper/prop-mobile.vue",
    "content": "<template>\n  <v-stepper mobile>\n    <v-stepper-header>\n      <template v-for=\"(item, i) in items\" :key=\"i\">\n        <v-divider v-if=\"i\"></v-divider>\n\n        <v-stepper-item v-bind=\"item\"></v-stepper-item>\n      </template>\n    </v-stepper-header>\n  </v-stepper>\n</template>\n\n<script setup>\n  const items = Array.from({ length: 10 }).map((_, i) => ({\n    title: `Step ${i + 1}`,\n    subtitle: `Step ${i + 1} subtitle`,\n    value: i + 1,\n  }))\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: Array.from({ length: 10 }).map((_, i) => ({\n        title: `Step ${i + 1}`,\n        subtitle: `Step ${i + 1} subtitle`,\n        value: i + 1,\n      })),\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-stepper/prop-non-linear.vue",
    "content": "<template>\n  <div>\n    <v-stepper non-linear>\n      <v-stepper-header>\n        <v-stepper-item\n          value=\"1\"\n          editable\n        >\n          Select campaign settings\n        </v-stepper-item>\n\n        <v-divider></v-divider>\n\n        <v-stepper-item\n          value=\"2\"\n          editable\n        >\n          Create an ad group\n        </v-stepper-item>\n\n        <v-divider></v-divider>\n\n        <v-stepper-item\n          value=\"3\"\n          editable\n        >\n          Create an ad\n        </v-stepper-item>\n      </v-stepper-header>\n    </v-stepper>\n\n    <v-stepper\n      class=\"mt-12\"\n      non-linear\n    >\n      <v-stepper-header>\n        <v-stepper-item\n          value=\"1\"\n          complete\n          editable\n        >\n          Select campaign settings\n        </v-stepper-item>\n\n        <v-divider></v-divider>\n\n        <v-stepper-item\n          value=\"2\"\n          editable\n        >\n          Create an ad group\n        </v-stepper-item>\n\n        <v-divider></v-divider>\n\n        <v-stepper-item\n          value=\"3\"\n          complete\n          editable\n        >\n          Create an ad\n        </v-stepper-item>\n      </v-stepper-header>\n    </v-stepper>\n\n    <v-stepper\n      class=\"mt-12\"\n      value=\"3\"\n      non-linear\n    >\n      <v-stepper-header>\n        <v-stepper-item\n          value=\"1\"\n          complete\n          editable\n        >\n          Select campaign settings\n        </v-stepper-item>\n\n        <v-divider></v-divider>\n\n        <v-stepper-item\n          value=\"2\"\n          complete\n          editable\n        >\n          Create an ad group\n        </v-stepper-item>\n\n        <v-divider></v-divider>\n\n        <v-stepper-item\n          value=\"3\"\n          complete\n          editable\n        >\n          Create an ad\n        </v-stepper-item>\n      </v-stepper-header>\n    </v-stepper>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-stepper/prop-vertical.vue",
    "content": "<template>\n  <v-stepper\n    v-model=\"e6\"\n    vertical\n  >\n    <v-stepper-step\n      :complete=\"e6 > 1\"\n      step=\"1\"\n    >\n      Select an app\n      <small>Summarize if needed</small>\n    </v-stepper-step>\n\n    <v-stepper-content step=\"1\">\n      <v-card\n        class=\"mb-12\"\n        color=\"grey-lighten-1\"\n        height=\"200px\"\n      ></v-card>\n      <v-btn\n        color=\"primary\"\n        @click=\"e6 = 2\"\n      >\n        Continue\n      </v-btn>\n      <v-btn variant=\"text\">\n        Cancel\n      </v-btn>\n    </v-stepper-content>\n\n    <v-stepper-step\n      :complete=\"e6 > 2\"\n      step=\"2\"\n    >\n      Configure analytics for this app\n    </v-stepper-step>\n\n    <v-stepper-content step=\"2\">\n      <v-card\n        class=\"mb-12\"\n        color=\"grey-lighten-1\"\n        height=\"200px\"\n      ></v-card>\n      <v-btn\n        color=\"primary\"\n        @click=\"e6 = 3\"\n      >\n        Continue\n      </v-btn>\n      <v-btn variant=\"text\">\n        Cancel\n      </v-btn>\n    </v-stepper-content>\n\n    <v-stepper-step\n      :complete=\"e6 > 3\"\n      step=\"3\"\n    >\n      Select an ad format and name ad unit\n    </v-stepper-step>\n\n    <v-stepper-content step=\"3\">\n      <v-card\n        class=\"mb-12\"\n        color=\"grey-lighten-1\"\n        height=\"200px\"\n      ></v-card>\n      <v-btn\n        color=\"primary\"\n        @click=\"e6 = 4\"\n      >\n        Continue\n      </v-btn>\n      <v-btn variant=\"text\">\n        Cancel\n      </v-btn>\n    </v-stepper-content>\n\n    <v-stepper-step step=\"4\">\n      View setup instructions\n    </v-stepper-step>\n    <v-stepper-content step=\"4\">\n      <v-card\n        class=\"mb-12\"\n        color=\"grey-lighten-1\"\n        height=\"200px\"\n      ></v-card>\n      <v-btn\n        color=\"primary\"\n        @click=\"e6 = 1\"\n      >\n        Continue\n      </v-btn>\n      <v-btn variant=\"text\">\n        Cancel\n      </v-btn>\n    </v-stepper-content>\n  </v-stepper>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const e6 = ref(1)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        e6: 1,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-stepper/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <v-stepper v-bind=\"props\" v-model=\"step\">\n      <template v-slot:item.1>\n        <v-card title=\"Step One\" flat>\n          <template v-slot:text>\n            <div @blur=\"onBlur\" @dblclick=\"onDblClick\">\n              Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!\n            </div>\n          </template>\n        </v-card>\n      </template>\n\n      <template v-slot:item.2>\n        <v-card title=\"Step Two\" flat>\n          <template v-slot:text>\n            <div @blur=\"onBlur\" @dblclick=\"onDblClick\">\n              Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus!\n            </div>\n          </template>\n        </v-card>\n      </template>\n\n      <template v-slot:item.3>\n        <v-card title=\"Step Three\" flat>\n          <template v-slot:text>\n            <div @blur=\"onBlur\" @dblclick=\"onDblClick\">\n              Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!\n\n              Lorem ipsum dolor sit amet consectetur adipisicing elit.\n            </div>\n          </template>\n        </v-card>\n      </template>\n    </v-stepper>\n\n    <template v-slot:configuration>\n      <v-text-field v-model=\"prev\" label=\"Previous text\"></v-text-field>\n\n      <v-text-field v-model=\"next\" label=\"Next text\"></v-text-field>\n\n      <v-checkbox v-model=\"hideActions\" label=\"Hide actions\"></v-checkbox>\n\n      <v-checkbox v-model=\"editable\" label=\"Editable\"></v-checkbox>\n\n      <v-checkbox v-model=\"altLabels\" label=\"Alt labels\"></v-checkbox>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-stepper'\n  const model = ref('default')\n  const options = []\n  const step = ref(1)\n  const altLabels = ref(false)\n  const editable = ref(false)\n  const hideActions = ref(false)\n  const prev = ref('$vuetify.stepper.prev')\n  const next = ref('$vuetify.stepper.next')\n\n  function onDblClick (e) {\n    e.target.contentEditable = true\n  }\n\n  function onBlur (e) {\n    e.target.contentEditable = false\n  }\n\n  const props = computed(() => {\n    return {\n      'alt-labels': altLabels.value || undefined,\n      editable: editable.value || undefined,\n      'hide-actions': hideActions.value || undefined,\n      'prev-text': prev.value.startsWith('$vuetify') ? undefined : prev.value,\n      'next-text': next.value.startsWith('$vuetify') ? undefined : next.value,\n      items: [\n        'Step 1',\n        'Step 2',\n        'Step 3',\n      ],\n    }\n  })\n\n  const slots = computed(() => {\n    return `\n  <template v-slot:item.1>\n    <v-card title=\"Step One\" flat>...</v-card>\n  </template>\n\n  <template v-slot:item.2>\n    <v-card title=\"Step Two\" flat>...</v-card>\n  </template>\n\n  <template v-slot:item.3>\n    <v-card title=\"Step Three\" flat>...</v-card>\n  </template>\n`\n  })\n\n  const code = computed(() => {\n    return `<v-stepper${propsToString(props.value)}>${slots.value}</v-stepper>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-stepper-vertical/prop-non-linear.vue",
    "content": "<template>\n  <div>\n    <v-stepper-vertical\n      v-model=\"step\"\n      :mandatory=\"false\"\n      hide-actions\n      multiple\n      non-linear\n    >\n      <v-stepper-vertical-item title=\"Select campaign settings\" value=\"1\" editable>\n        Step content\n      </v-stepper-vertical-item>\n\n      <v-stepper-vertical-item title=\"Create an ad group\" value=\"2\" editable>\n        Step content\n      </v-stepper-vertical-item>\n\n      <v-stepper-vertical-item title=\"Create an ad\" value=\"3\" editable>\n        Step content\n      </v-stepper-vertical-item>\n    </v-stepper-vertical>\n  </div>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const step = shallowRef([1])\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-stepper-vertical/slot-actions.vue",
    "content": "<template>\n  <v-stepper-vertical>\n    <template v-slot:default=\"{ step }\">\n      <v-stepper-vertical-item\n        :complete=\"step > 1\"\n        subtitle=\"Personal details\"\n        title=\"Step one\"\n        value=\"1\"\n      >\n        Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!\n\n        <template v-slot:next=\"{ next }\">\n          <v-btn color=\"primary\" @click=\"next\"></v-btn>\n        </template>\n\n        <template v-slot:prev></template>\n      </v-stepper-vertical-item>\n\n      <v-stepper-vertical-item\n        :complete=\"step > 2\"\n        subtitle=\"Contact Details\"\n        title=\"Step two\"\n        value=\"2\"\n      >\n        Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!\n\n        <template v-slot:next=\"{ next }\">\n          <v-btn color=\"primary\" @click=\"next\"></v-btn>\n        </template>\n\n        <template v-slot:prev=\"{ prev }\">\n          <v-btn variant=\"plain\" @click=\"prev\"></v-btn>\n        </template>\n      </v-stepper-vertical-item>\n\n      <v-stepper-vertical-item\n        subtitle=\"Confirmation\"\n        title=\"Step three\"\n        value=\"3\"\n        @click:next=\"onClickFinish\"\n      >\n        Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!\n\n        <template v-slot:next=\"{ next }\">\n          <v-btn color=\"primary\" text=\"Finish\" @click=\"next\"></v-btn>\n        </template>\n\n        <template v-slot:prev=\"{ prev }\">\n          <v-btn v-if=\"!finished\" variant=\"plain\" @click=\"prev\"></v-btn>\n\n          <v-btn v-else text=\"Reset\" variant=\"plain\" @click=\"finished = false\"></v-btn>\n        </template>\n      </v-stepper-vertical-item>\n    </template>\n  </v-stepper-vertical>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const finished = shallowRef(false)\n\n  function onClickFinish () {\n    finished.value = true\n\n    alert('Finished')\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      finished: false,\n    }),\n\n    methods: {\n      onClickFinish () {\n        this.finished = true\n\n        alert('Finished')\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-stepper-vertical/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <v-container>\n      <v-stepper-vertical :items=\"items\">\n        <template v-slot:item.1>\n          Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!\n        </template>\n\n        <template v-slot:item.2>\n          Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!\n        </template>\n\n        <template v-slot:item.3>\n          Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!\n        </template>\n      </v-stepper-vertical>\n    </v-container>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-stepper-vertical'\n  const model = ref('default')\n  const options = []\n\n  const items = [\n    'Step 1',\n    'Step 2',\n    'Step 3',\n  ]\n  const props = computed(() => {\n    return {\n      items: [\n        'Step 1',\n        'Step 2',\n        'Step 3',\n      ],\n    }\n  })\n\n  const slots = computed(() => {\n    return ''\n  })\n\n  const code = computed(() => {\n    return `<v-stepper-vertical${propsToString(props.value)}>${slots.value}</v-stepper-vertical>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-switch/prop-colors.vue",
    "content": "<template>\n  <v-card flat>\n    <v-card-text>\n      <v-container fluid>\n        <v-row>\n          <v-col\n            cols=\"12\"\n            md=\"4\"\n            sm=\"4\"\n          >\n            <v-switch\n              v-model=\"ex11\"\n              color=\"red\"\n              label=\"red\"\n              value=\"red\"\n              hide-details\n            ></v-switch>\n            <v-switch\n              v-model=\"ex11\"\n              color=\"red-darken-3\"\n              label=\"red-darken-3\"\n              value=\"red-darken-3\"\n              hide-details\n            ></v-switch>\n          </v-col>\n          <v-col\n            cols=\"12\"\n            md=\"4\"\n            sm=\"4\"\n          >\n            <v-switch\n              v-model=\"ex11\"\n              color=\"indigo\"\n              label=\"indigo\"\n              value=\"indigo\"\n              hide-details\n            ></v-switch>\n            <v-switch\n              v-model=\"ex11\"\n              color=\"indigo-darken-3\"\n              label=\"indigo-darken-3\"\n              value=\"indigo-darken-3\"\n              hide-details\n            ></v-switch>\n          </v-col>\n          <v-col\n            cols=\"12\"\n            md=\"4\"\n            sm=\"4\"\n          >\n            <v-switch\n              v-model=\"ex11\"\n              color=\"orange\"\n              label=\"orange\"\n              value=\"orange\"\n              hide-details\n            ></v-switch>\n            <v-switch\n              v-model=\"ex11\"\n              color=\"orange-darken-3\"\n              label=\"orange-darken-3\"\n              value=\"orange-darken-3\"\n              hide-details\n            ></v-switch>\n          </v-col>\n        </v-row>\n\n        <v-row class=\"mt-12\">\n          <v-col\n            cols=\"12\"\n            md=\"4\"\n            sm=\"4\"\n          >\n            <v-switch\n              v-model=\"ex11\"\n              color=\"primary\"\n              label=\"primary\"\n              value=\"primary\"\n              hide-details\n            ></v-switch>\n            <v-switch\n              v-model=\"ex11\"\n              color=\"secondary\"\n              label=\"secondary\"\n              value=\"secondary\"\n              hide-details\n            ></v-switch>\n          </v-col>\n          <v-col\n            cols=\"12\"\n            md=\"4\"\n            sm=\"4\"\n          >\n            <v-switch\n              v-model=\"ex11\"\n              color=\"success\"\n              label=\"success\"\n              value=\"success\"\n              hide-details\n            ></v-switch>\n            <v-switch\n              v-model=\"ex11\"\n              color=\"info\"\n              label=\"info\"\n              value=\"info\"\n              hide-details\n            ></v-switch>\n          </v-col>\n          <v-col\n            cols=\"12\"\n            md=\"4\"\n            sm=\"4\"\n          >\n            <v-switch\n              v-model=\"ex11\"\n              color=\"warning\"\n              label=\"warning\"\n              value=\"warning\"\n              hide-details\n            ></v-switch>\n            <v-switch\n              v-model=\"ex11\"\n              color=\"error\"\n              label=\"error\"\n              value=\"error\"\n              hide-details\n            ></v-switch>\n          </v-col>\n        </v-row>\n      </v-container>\n    </v-card-text>\n  </v-card>\n</template>\n\n<script setup>\n  const ex11 = ['red', 'indigo', 'orange', 'primary', 'secondary', 'success', 'info', 'warning', 'error', 'red-darken-3', 'indigo-darken-3', 'orange-darken-3']\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        ex11: ['red', 'indigo', 'orange', 'primary', 'secondary', 'success', 'info', 'warning', 'error', 'red-darken-3', 'indigo-darken-3', 'orange-darken-3'],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-switch/prop-custom-values.vue",
    "content": "<template>\n  <v-switch\n    v-model=\"model\"\n    :label=\"`Switch: ${model}`\"\n    false-value=\"no\"\n    true-value=\"yes\"\n    hide-details\n  ></v-switch>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const model = ref('no')\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      model: 'no',\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-switch/prop-flat.vue",
    "content": "<template>\n  <v-switch\n    v-model=\"model\"\n    :label=\"`Switch: ${model.toString()}`\"\n    flat\n    hide-details\n  ></v-switch>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const model = ref(true)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        model: true,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-switch/prop-inset.vue",
    "content": "<template>\n  <v-switch\n    v-model=\"model\"\n    :label=\"`Switch: ${model.toString()}`\"\n    hide-details\n    inset\n  ></v-switch>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const model = ref(true)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        model: true,\n      }\n    },\n  }\n</script>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2723-45692&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-switch/prop-model-as-array.vue",
    "content": "<template>\n  <v-container fluid>\n    <p>{{ people }}</p>\n    <v-switch\n      v-model=\"people\"\n      color=\"primary\"\n      label=\"John\"\n      value=\"John\"\n      hide-details\n    ></v-switch>\n    <v-switch\n      v-model=\"people\"\n      color=\"primary\"\n      label=\"Jacob\"\n      value=\"Jacob\"\n      hide-details\n    ></v-switch>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const people = ref(['John'])\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        people: ['John'],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-switch/prop-states.vue",
    "content": "<template>\n  <v-container fluid>\n    <v-row>\n      <v-col cols=\"6\">\n        <v-switch\n          :model-value=\"true\"\n          color=\"primary\"\n          label=\"on\"\n        ></v-switch>\n      </v-col>\n      <v-col cols=\"6\">\n        <v-switch\n          :model-value=\"false\"\n          color=\"primary\"\n          label=\"off\"\n        ></v-switch>\n      </v-col>\n    </v-row>\n\n    <v-row>\n      <v-col cols=\"6\">\n        <v-switch\n          :model-value=\"true\"\n          color=\"primary\"\n          label=\"on disabled\"\n          disabled\n        ></v-switch>\n      </v-col>\n      <v-col cols=\"6\">\n        <v-switch\n          :model-value=\"false\"\n          color=\"primary\"\n          label=\"off disabled\"\n          disabled\n        ></v-switch>\n      </v-col>\n    </v-row>\n\n    <v-row>\n      <v-col cols=\"6\">\n        <v-switch\n          :model-value=\"true\"\n          label=\"on loading\"\n          loading=\"warning\"\n        ></v-switch>\n      </v-col>\n      <v-col cols=\"6\">\n        <v-switch\n          :model-value=\"false\"\n          label=\"off loading\"\n          loading=\"warning\"\n        ></v-switch>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-switch/slot-label.vue",
    "content": "<template>\n  <v-switch v-model=\"switchMe\">\n    <template v-slot:label>\n      Turn on the progress:\n      <v-progress-circular\n        :indeterminate=\"switchMe\"\n        class=\"ms-2\"\n        size=\"24\"\n      ></v-progress-circular>\n    </template>\n  </v-switch>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const switchMe = ref(false)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        switchMe: false,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-switch/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div>\n      <v-switch v-bind=\"props\"></v-switch>\n    </div>\n\n    <template v-slot:configuration>\n      <v-checkbox v-model=\"indeterminate\" label=\"Indeterminate\"></v-checkbox>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-switch'\n  const model = ref('default')\n  const indeterminate = ref(false)\n  const options = ['inset']\n  const props = computed(() => {\n    return {\n      label: 'Switch',\n      inset: model.value === 'inset' || undefined,\n      indeterminate: indeterminate.value || undefined,\n    }\n  })\n\n  watch(model, () => indeterminate.value = false)\n\n  const slots = computed(() => {\n    return ``\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-system-bar/prop-color.vue",
    "content": "<template>\n  <div>\n    <v-layout style=\"height: 50px\">\n      <v-system-bar color=\"primary\">\n        <v-icon class=\"ms-2\" icon=\"mdi-wifi-strength-4\"></v-icon>\n\n        <v-icon class=\"ms-2\" icon=\"mdi-signal-cellular-outline\"></v-icon>\n\n        <v-icon class=\"ms-2\" icon=\"mdi-battery\"></v-icon>\n\n        <span class=\"ms-2\">08:30</span>\n      </v-system-bar>\n    </v-layout>\n\n    <v-layout style=\"height: 50px\">\n      <v-system-bar color=\"red-lighten-2\">\n        <v-icon class=\"ms-2\" icon=\"mdi-wifi-strength-2\"></v-icon>\n\n        <v-icon class=\"ms-2\" icon=\"mdi-signal-cellular-outline\"></v-icon>\n\n        <v-icon class=\"ms-2\" icon=\"mdi-battery\"></v-icon>\n\n        <span class=\"ms-2\">18:30</span>\n      </v-system-bar>\n    </v-layout>\n\n    <v-layout style=\"height: 50px\">\n      <v-system-bar color=\"indigo-darken-2\">\n        <v-icon class=\"ms-2\" icon=\"mdi-wifi-strength-3\"></v-icon>\n\n        <v-icon class=\"ms-2\" icon=\"mdi-signal-cellular-outline\"></v-icon>\n\n        <v-icon class=\"ms-2\" icon=\"mdi-battery\"></v-icon>\n\n        <span class=\"ms-2\">13:24</span>\n      </v-system-bar>\n    </v-layout>\n  </div>\n</template>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2796-130312&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-system-bar/prop-window.vue",
    "content": "<template>\n  <v-layout style=\"height: 50px\">\n    <v-system-bar window>\n      <v-icon class=\"me-2\" icon=\"mdi-message\"></v-icon>\n\n      <span>10 unread messages</span>\n\n      <v-spacer></v-spacer>\n\n      <v-btn icon=\"mdi-minus\" variant=\"text\"></v-btn>\n\n      <v-btn class=\"ms-2\" icon=\"mdi-checkbox-blank-outline\" variant=\"text\"></v-btn>\n\n      <v-btn class=\"ms-2\" icon=\"mdi-close\" variant=\"text\"></v-btn>\n    </v-system-bar>\n  </v-layout>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-system-bar/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <v-layout\n      class=\"elevation-1 rounded mx-auto bg-white\"\n      style=\"max-width: 448px; height: 150px\"\n    >\n      <v-system-bar v-bind=\"props\">\n        <v-icon icon=\"mdi-wifi-strength-4\"></v-icon>\n        <v-icon class=\"ms-2\" icon=\"mdi-signal\"></v-icon>\n        <v-icon class=\"ms-2\" icon=\"mdi-battery\"></v-icon>\n\n        <span class=\"ms-2\">3:13PM</span>\n      </v-system-bar>\n\n      <v-main></v-main>\n    </v-layout>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-system-bar'\n  const model = ref('default')\n  const options = ['window']\n\n  const props = computed(() => {\n    return {\n      window: model.value === 'window' || undefined,\n    }\n  })\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>\n  <v-icon icon=\"mdi-wifi-strength-4\"></v-icon>\n  <v-icon icon=\"mdi-signal\" class=\"ms-2\"></v-icon>\n  <v-icon icon=\"mdi-battery\" class=\"ms-2\"></v-icon>\n\n  <span class=\"ms-2\">3:13PM</span>\n</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-table/prop-dark.vue",
    "content": "<template>\n  <v-table theme=\"dark\">\n    <thead>\n      <tr>\n        <th class=\"text-left\">\n          Name\n        </th>\n        <th class=\"text-left\">\n          Calories\n        </th>\n      </tr>\n    </thead>\n    <tbody>\n      <tr\n        v-for=\"item in desserts\"\n        :key=\"item.name\"\n      >\n        <td>{{ item.name }}</td>\n        <td>{{ item.calories }}</td>\n      </tr>\n    </tbody>\n  </v-table>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const desserts = ref([\n    {\n      name: 'Frozen Yogurt',\n      calories: 159,\n    },\n    {\n      name: 'Ice cream sandwich',\n      calories: 237,\n    },\n    {\n      name: 'Eclair',\n      calories: 262,\n    },\n    {\n      name: 'Cupcake',\n      calories: 305,\n    },\n    {\n      name: 'Gingerbread',\n      calories: 356,\n    },\n    {\n      name: 'Jelly bean',\n      calories: 375,\n    },\n    {\n      name: 'Lollipop',\n      calories: 392,\n    },\n    {\n      name: 'Honeycomb',\n      calories: 408,\n    },\n    {\n      name: 'Donut',\n      calories: 452,\n    },\n    {\n      name: 'KitKat',\n      calories: 518,\n    },\n  ])\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        desserts: [\n          {\n            name: 'Frozen Yogurt',\n            calories: 159,\n          },\n          {\n            name: 'Ice cream sandwich',\n            calories: 237,\n          },\n          {\n            name: 'Eclair',\n            calories: 262,\n          },\n          {\n            name: 'Cupcake',\n            calories: 305,\n          },\n          {\n            name: 'Gingerbread',\n            calories: 356,\n          },\n          {\n            name: 'Jelly bean',\n            calories: 375,\n          },\n          {\n            name: 'Lollipop',\n            calories: 392,\n          },\n          {\n            name: 'Honeycomb',\n            calories: 408,\n          },\n          {\n            name: 'Donut',\n            calories: 452,\n          },\n          {\n            name: 'KitKat',\n            calories: 518,\n          },\n        ],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-table/prop-dense.vue",
    "content": "<template>\n  <v-table density=\"compact\">\n    <thead>\n      <tr>\n        <th class=\"text-left\">\n          Name\n        </th>\n        <th class=\"text-left\">\n          Calories\n        </th>\n      </tr>\n    </thead>\n    <tbody>\n      <tr\n        v-for=\"item in desserts\"\n        :key=\"item.name\"\n      >\n        <td>{{ item.name }}</td>\n        <td>{{ item.calories }}</td>\n      </tr>\n    </tbody>\n  </v-table>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const desserts = ref([\n    {\n      name: 'Frozen Yogurt',\n      calories: 159,\n    },\n    {\n      name: 'Ice cream sandwich',\n      calories: 237,\n    },\n    {\n      name: 'Eclair',\n      calories: 262,\n    },\n    {\n      name: 'Cupcake',\n      calories: 305,\n    },\n    {\n      name: 'Gingerbread',\n      calories: 356,\n    },\n    {\n      name: 'Jelly bean',\n      calories: 375,\n    },\n    {\n      name: 'Lollipop',\n      calories: 392,\n    },\n    {\n      name: 'Honeycomb',\n      calories: 408,\n    },\n    {\n      name: 'Donut',\n      calories: 452,\n    },\n    {\n      name: 'KitKat',\n      calories: 518,\n    },\n  ])\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        desserts: [\n          {\n            name: 'Frozen Yogurt',\n            calories: 159,\n          },\n          {\n            name: 'Ice cream sandwich',\n            calories: 237,\n          },\n          {\n            name: 'Eclair',\n            calories: 262,\n          },\n          {\n            name: 'Cupcake',\n            calories: 305,\n          },\n          {\n            name: 'Gingerbread',\n            calories: 356,\n          },\n          {\n            name: 'Jelly bean',\n            calories: 375,\n          },\n          {\n            name: 'Lollipop',\n            calories: 392,\n          },\n          {\n            name: 'Honeycomb',\n            calories: 408,\n          },\n          {\n            name: 'Donut',\n            calories: 452,\n          },\n          {\n            name: 'KitKat',\n            calories: 518,\n          },\n        ],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-table/prop-fixed-header.vue",
    "content": "<template>\n  <v-table\n    height=\"300px\"\n    fixed-header\n  >\n    <thead>\n      <tr>\n        <th class=\"text-left\">\n          Name\n        </th>\n        <th class=\"text-left\">\n          Calories\n        </th>\n      </tr>\n    </thead>\n    <tbody>\n      <tr\n        v-for=\"item in desserts\"\n        :key=\"item.name\"\n      >\n        <td>{{ item.name }}</td>\n        <td>{{ item.calories }}</td>\n      </tr>\n    </tbody>\n  </v-table>\n</template>\n\n<script setup>\n  const desserts = [\n    {\n      name: 'Frozen Yogurt',\n      calories: 159,\n    },\n    {\n      name: 'Ice cream sandwich',\n      calories: 237,\n    },\n    {\n      name: 'Eclair',\n      calories: 262,\n    },\n    {\n      name: 'Cupcake',\n      calories: 305,\n    },\n    {\n      name: 'Gingerbread',\n      calories: 356,\n    },\n    {\n      name: 'Jelly bean',\n      calories: 375,\n    },\n    {\n      name: 'Lollipop',\n      calories: 392,\n    },\n    {\n      name: 'Honeycomb',\n      calories: 408,\n    },\n    {\n      name: 'Donut',\n      calories: 452,\n    },\n    {\n      name: 'KitKat',\n      calories: 518,\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        desserts: [\n          {\n            name: 'Frozen Yogurt',\n            calories: 159,\n          },\n          {\n            name: 'Ice cream sandwich',\n            calories: 237,\n          },\n          {\n            name: 'Eclair',\n            calories: 262,\n          },\n          {\n            name: 'Cupcake',\n            calories: 305,\n          },\n          {\n            name: 'Gingerbread',\n            calories: 356,\n          },\n          {\n            name: 'Jelly bean',\n            calories: 375,\n          },\n          {\n            name: 'Lollipop',\n            calories: 392,\n          },\n          {\n            name: 'Honeycomb',\n            calories: 408,\n          },\n          {\n            name: 'Donut',\n            calories: 452,\n          },\n          {\n            name: 'KitKat',\n            calories: 518,\n          },\n        ],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-table/prop-height.vue",
    "content": "<template>\n  <v-table height=\"300px\">\n    <thead>\n      <tr>\n        <th class=\"text-left\">\n          Name\n        </th>\n        <th class=\"text-left\">\n          Calories\n        </th>\n      </tr>\n    </thead>\n    <tbody>\n      <tr\n        v-for=\"item in desserts\"\n        :key=\"item.name\"\n      >\n        <td>{{ item.name }}</td>\n        <td>{{ item.calories }}</td>\n      </tr>\n    </tbody>\n  </v-table>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const desserts = ref([\n    {\n      name: 'Frozen Yogurt',\n      calories: 159,\n    },\n    {\n      name: 'Ice cream sandwich',\n      calories: 237,\n    },\n    {\n      name: 'Eclair',\n      calories: 262,\n    },\n    {\n      name: 'Cupcake',\n      calories: 305,\n    },\n    {\n      name: 'Gingerbread',\n      calories: 356,\n    },\n    {\n      name: 'Jelly bean',\n      calories: 375,\n    },\n    {\n      name: 'Lollipop',\n      calories: 392,\n    },\n    {\n      name: 'Honeycomb',\n      calories: 408,\n    },\n    {\n      name: 'Donut',\n      calories: 452,\n    },\n    {\n      name: 'KitKat',\n      calories: 518,\n    },\n  ])\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        desserts: [\n          {\n            name: 'Frozen Yogurt',\n            calories: 159,\n          },\n          {\n            name: 'Ice cream sandwich',\n            calories: 237,\n          },\n          {\n            name: 'Eclair',\n            calories: 262,\n          },\n          {\n            name: 'Cupcake',\n            calories: 305,\n          },\n          {\n            name: 'Gingerbread',\n            calories: 356,\n          },\n          {\n            name: 'Jelly bean',\n            calories: 375,\n          },\n          {\n            name: 'Lollipop',\n            calories: 392,\n          },\n          {\n            name: 'Honeycomb',\n            calories: 408,\n          },\n          {\n            name: 'Donut',\n            calories: 452,\n          },\n          {\n            name: 'KitKat',\n            calories: 518,\n          },\n        ],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-table/prop-striped.vue",
    "content": "<template>\n  <v-table striped=\"even\">\n    <thead>\n      <tr>\n        <th class=\"text-left\">\n          Name\n        </th>\n        <th class=\"text-left\">\n          Calories\n        </th>\n      </tr>\n    </thead>\n    <tbody>\n      <tr\n        v-for=\"item in desserts\"\n        :key=\"item.name\"\n      >\n        <td>{{ item.name }}</td>\n        <td>{{ item.calories }}</td>\n      </tr>\n    </tbody>\n  </v-table>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const desserts = ref([\n    {\n      name: 'Frozen Yogurt',\n      calories: 159,\n    },\n    {\n      name: 'Ice cream sandwich',\n      calories: 237,\n    },\n    {\n      name: 'Eclair',\n      calories: 262,\n    },\n    {\n      name: 'Cupcake',\n      calories: 305,\n    },\n    {\n      name: 'Gingerbread',\n      calories: 356,\n    },\n    {\n      name: 'Jelly bean',\n      calories: 375,\n    },\n    {\n      name: 'Lollipop',\n      calories: 392,\n    },\n    {\n      name: 'Honeycomb',\n      calories: 408,\n    },\n    {\n      name: 'Donut',\n      calories: 452,\n    },\n    {\n      name: 'KitKat',\n      calories: 518,\n    },\n  ])\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        desserts: [\n          {\n            name: 'Frozen Yogurt',\n            calories: 159,\n          },\n          {\n            name: 'Ice cream sandwich',\n            calories: 237,\n          },\n          {\n            name: 'Eclair',\n            calories: 262,\n          },\n          {\n            name: 'Cupcake',\n            calories: 305,\n          },\n          {\n            name: 'Gingerbread',\n            calories: 356,\n          },\n          {\n            name: 'Jelly bean',\n            calories: 375,\n          },\n          {\n            name: 'Lollipop',\n            calories: 392,\n          },\n          {\n            name: 'Honeycomb',\n            calories: 408,\n          },\n          {\n            name: 'Donut',\n            calories: 452,\n          },\n          {\n            name: 'KitKat',\n            calories: 518,\n          },\n        ],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-table/usage.vue",
    "content": "<template>\n  <v-table>\n    <thead>\n      <tr>\n        <th class=\"text-left\">\n          Name\n        </th>\n        <th class=\"text-left\">\n          Calories\n        </th>\n      </tr>\n    </thead>\n    <tbody>\n      <tr\n        v-for=\"item in desserts\"\n        :key=\"item.name\"\n      >\n        <td>{{ item.name }}</td>\n        <td>{{ item.calories }}</td>\n      </tr>\n    </tbody>\n  </v-table>\n</template>\n\n<script>\n  export default {\n    data () {\n      return {\n        desserts: [\n          {\n            name: 'Frozen Yogurt',\n            calories: 159,\n          },\n          {\n            name: 'Ice cream sandwich',\n            calories: 237,\n          },\n          {\n            name: 'Eclair',\n            calories: 262,\n          },\n          {\n            name: 'Cupcake',\n            calories: 305,\n          },\n          {\n            name: 'Gingerbread',\n            calories: 356,\n          },\n          {\n            name: 'Jelly bean',\n            calories: 375,\n          },\n          {\n            name: 'Lollipop',\n            calories: 392,\n          },\n          {\n            name: 'Honeycomb',\n            calories: 408,\n          },\n          {\n            name: 'Donut',\n            calories: 452,\n          },\n          {\n            name: 'KitKat',\n            calories: 518,\n          },\n        ],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-tabs/misc-content.vue",
    "content": "<template>\n  <v-card>\n    <v-toolbar color=\"primary\">\n      <v-app-bar-nav-icon></v-app-bar-nav-icon>\n\n      <v-toolbar-title>Page title</v-toolbar-title>\n\n      <v-btn icon=\"mdi-magnify\"></v-btn>\n\n      <v-btn icon=\"mdi-dots-vertical\"></v-btn>\n\n      <template v-slot:extension>\n        <v-tabs\n          v-model=\"model\"\n          align-tabs=\"center\"\n        >\n          <v-tab\n            v-for=\"i in 3\"\n            :key=\"i\"\n            :text=\"`Item ${i}`\"\n            :value=\"i\"\n          ></v-tab>\n        </v-tabs>\n      </template>\n    </v-toolbar>\n\n    <v-tabs-window v-model=\"model\">\n      <v-tabs-window-item\n        v-for=\"i in 3\"\n        :key=\"i\"\n        :value=\"i\"\n      >\n        <v-card>\n          <v-card-text>{{ text }}</v-card-text>\n        </v-card>\n      </v-tabs-window-item>\n    </v-tabs-window>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.'\n\n  const model = ref('tab-2')\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        model: 'tab-2',\n        text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.',\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-tabs/misc-dynamic-height.vue",
    "content": "<template>\n  <v-card>\n    <v-toolbar color=\"purple\" flat>\n      <v-text-field\n        append-icon=\"mdi-microphone\"\n        class=\"mx-4\"\n        label=\"Search\"\n        prepend-inner-icon=\"mdi-magnify\"\n        variant=\"solo-inverted\"\n        flat\n        hide-details\n      ></v-text-field>\n\n      <template v-slot:extension>\n        <v-tabs\n          v-model=\"tabs\"\n          align-tabs=\"center\"\n        >\n          <v-tab\n            v-for=\"n in 3\"\n            :key=\"n\"\n            :text=\"`Item ${n}`\"\n          ></v-tab>\n        </v-tabs>\n      </template>\n    </v-toolbar>\n\n    <v-tabs-window v-model=\"tabs\">\n      <v-tabs-window-item>\n        <v-card flat>\n          <v-card-text>\n            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n          </v-card-text>\n        </v-card>\n      </v-tabs-window-item>\n      <v-tabs-window-item>\n        <v-card flat>\n          <v-card-title class=\"text-headline-small\">\n            An awesome title\n          </v-card-title>\n          <v-card-text>\n            <p>\n              Duis lobortis massa imperdiet quam. Donec vitae orci sed dolor rutrum auctor. Vestibulum facilisis, purus nec pulvinar iaculis, ligula mi congue nunc, vitae euismod ligula urna in dolor. Praesent congue erat at massa.\n            </p>\n\n            <p>\n              Aenean posuere, tortor sed cursus feugiat, nunc augue blandit nunc, eu sollicitudin urna dolor sagittis lacus. Pellentesque egestas, neque sit amet convallis pulvinar, justo nulla eleifend augue, ac auctor orci leo non est. Etiam sit amet orci eget eros faucibus tincidunt. Donec sodales sagittis magna.\n            </p>\n\n            <p class=\"mb-0\">\n              Ut leo. Suspendisse potenti. Duis vel nibh at velit scelerisque suscipit. Fusce pharetra convallis urna.\n            </p>\n          </v-card-text>\n        </v-card>\n      </v-tabs-window-item>\n      <v-tabs-window-item>\n        <v-card flat>\n          <v-card-title class=\"text-headline-small\">\n            An even better title\n          </v-card-title>\n          <v-card-text>\n            <p>\n              Maecenas ullamcorper, dui et placerat feugiat, eros pede varius nisi, condimentum viverra felis nunc et lorem. Sed hendrerit. Maecenas malesuada. Vestibulum ullamcorper mauris at ligula. Proin faucibus arcu quis ante.\n            </p>\n\n            <p class=\"mb-0\">\n              Etiam vitae tortor. Curabitur ullamcorper ultricies nisi. Sed magna purus, fermentum eu, tincidunt eu, varius ut, felis. Aliquam lobortis. Suspendisse potenti.\n            </p>\n          </v-card-text>\n        </v-card>\n      </v-tabs-window-item>\n    </v-tabs-window>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const tabs = ref(null)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        tabs: null,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-tabs/misc-dynamic.vue",
    "content": "<template>\n  <v-card>\n    <v-tabs\n      v-model=\"tab\"\n      bg-color=\"red-lighten-2\"\n    >\n      <v-tab\n        v-for=\"n in length\"\n        :key=\"n\"\n        :text=\"`Item ${n}`\"\n        :value=\"n\"\n      ></v-tab>\n    </v-tabs>\n\n    <v-card-text class=\"text-center\">\n      <v-btn\n        :disabled=\"!length\"\n        text=\"Remove Tab\"\n        variant=\"text\"\n        @click=\"length--\"\n      ></v-btn>\n\n      <v-divider\n        class=\"mx-4\"\n        vertical\n      ></v-divider>\n\n      <v-btn\n        text=\"Add Tab\"\n        variant=\"text\"\n        @click=\"length++\"\n      ></v-btn>\n    </v-card-text>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref, watch } from 'vue'\n\n  const length = ref(15)\n  const tab = ref(null)\n\n  watch(length, val => {\n    tab.value = val - 1\n  })\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      length: 15,\n      tab: null,\n    }),\n\n    watch: {\n      length (val) {\n        this.tab = val - 1\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-tabs/misc-mobile.vue",
    "content": "<template>\n  <v-card class=\"mx-auto\" width=\"350px\">\n    <v-toolbar color=\"surface\">\n      <v-app-bar-nav-icon></v-app-bar-nav-icon>\n\n      <v-toolbar-title>Contacts</v-toolbar-title>\n\n      <v-btn icon=\"mdi-magnify\"></v-btn>\n\n      <v-btn icon=\"mdi-dots-vertical\"></v-btn>\n\n      <template v-slot:extension>\n        <v-tabs\n          v-model=\"tabs\"\n          color=\"primary\"\n          grow\n        >\n          <v-tab\n            :value=\"1\"\n          >\n            <v-icon icon=\"mdi-phone\"></v-icon>\n          </v-tab>\n\n          <v-tab\n            :value=\"2\"\n          >\n            <v-icon icon=\"mdi-heart\"></v-icon>\n          </v-tab>\n\n          <v-tab\n            :value=\"3\"\n          >\n            <v-icon icon=\"mdi-account-box\"></v-icon>\n          </v-tab>\n        </v-tabs>\n      </template>\n    </v-toolbar>\n\n    <v-tabs-window v-model=\"tabs\">\n      <v-tabs-window-item\n        v-for=\"i in 3\"\n        :key=\"i\"\n        :value=\"i\"\n      >\n        <v-card>\n          <v-card-text>\n            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n          </v-card-text>\n        </v-card>\n      </v-tabs-window-item>\n    </v-tabs-window>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const tabs = ref(null)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        tabs: null,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-tabs/misc-overflow-to-menu.vue",
    "content": "<template>\n  <v-card>\n    <v-toolbar\n      color=\"deep-purple-accent-4\"\n    >\n      <v-app-bar-nav-icon></v-app-bar-nav-icon>\n\n      <v-toolbar-title>Page title</v-toolbar-title>\n\n      <v-btn icon=\"mdi-magnify\"></v-btn>\n\n      <v-btn icon=\"mdi-dots-vertical\"></v-btn>\n\n      <template v-slot:extension>\n        <v-tabs\n          v-model=\"currentItem\"\n          fixed-tabs\n        >\n          <v-tab\n            v-for=\"item in items\"\n            :key=\"item\"\n            :text=\"item\"\n            :value=\"'tab-' + item\"\n          ></v-tab>\n\n          <v-menu v-if=\"more.length\">\n            <template v-slot:activator=\"{ props }\">\n              <v-btn\n                class=\"align-self-center me-4\"\n                height=\"100%\"\n                rounded=\"0\"\n                variant=\"plain\"\n                v-bind=\"props\"\n              >\n                more\n\n                <v-icon icon=\"mdi-menu-down\" end></v-icon>\n              </v-btn>\n            </template>\n\n            <v-list class=\"bg-grey-lighten-3\">\n              <v-list-item\n                v-for=\"item in more\"\n                :key=\"item\"\n                :title=\"item\"\n                @click=\"addItem(item)\"\n              ></v-list-item>\n            </v-list>\n          </v-menu>\n        </v-tabs>\n      </template>\n    </v-toolbar>\n\n    <v-tabs-window v-model=\"currentItem\">\n      <v-tabs-window-item\n        v-for=\"item in items.concat(more)\"\n        :key=\"item\"\n        :value=\"'tab-' + item\"\n      >\n        <v-card flat>\n          <v-card-text>\n            <h2 class=\"my-0\">{{ item }}</h2>\n            {{ text }}\n          </v-card-text>\n        </v-card>\n      </v-tabs-window-item>\n    </v-tabs-window>\n  </v-card>\n</template>\n\n<script setup>\n  import { nextTick, ref } from 'vue'\n\n  const text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.'\n\n  const currentItem = ref('tab-Web')\n  const items = ref([\n    'Web',\n    'Shopping',\n    'Videos',\n    'Images',\n  ])\n  const more = ref([\n    'News',\n    'Maps',\n    'Books',\n    'Flights',\n    'Apps',\n  ])\n\n  function addItem (item) {\n    const removed = items.value.splice(0, 1)\n    items.value.push(...more.value.splice(more.value.indexOf(item), 1))\n    more.value.push(...removed)\n    nextTick(() => { currentItem.value = 'tab-' + item })\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      currentItem: 'tab-Web',\n      items: [\n        'Web', 'Shopping', 'Videos', 'Images',\n      ],\n      more: [\n        'News', 'Maps', 'Books', 'Flights', 'Apps',\n      ],\n      text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.',\n    }),\n\n    methods: {\n      addItem (item) {\n        const removed = this.items.splice(0, 1)\n        this.items.push(\n          ...this.more.splice(this.more.indexOf(item), 1),\n        )\n        this.more.push(...removed)\n        this.$nextTick(() => { this.currentItem = 'tab-' + item })\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-tabs/misc-pagination.vue",
    "content": "<template>\n  <v-card>\n    <v-tabs\n      bg-color=\"teal-darken-3\"\n      slider-color=\"teal-lighten-3\"\n      show-arrows\n    >\n      <v-tab\n        v-for=\"i in 30\"\n        :key=\"i\"\n        :text=\"'Item ' + i\"\n        :value=\"'tab-' + i\"\n      ></v-tab>\n    </v-tabs>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-tabs/misc-tab-items.vue",
    "content": "<template>\n  <v-card>\n    <v-tabs\n      v-model=\"tab\"\n      bg-color=\"primary\"\n    >\n      <v-tab\n        v-for=\"item in items\"\n        :key=\"item.tab\"\n        :title=\"item.tab\"\n      ></v-tab>\n    </v-tabs>\n\n    <v-tabs-window v-model=\"tab\">\n      <v-tabs-window-item\n        v-for=\"item in items\"\n        :key=\"item.tab\"\n      >\n        <v-card flat>\n          <v-card-text>{{ item.content }}</v-card-text>\n        </v-card>\n      </v-tabs-window-item>\n    </v-tabs-window>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const items = [\n    { tab: 'One', content: 'Tab 1 Content' },\n    { tab: 'Two', content: 'Tab 2 Content' },\n    { tab: 'Three', content: 'Tab 3 Content' },\n    { tab: 'Four', content: 'Tab 4 Content' },\n    { tab: 'Five', content: 'Tab 5 Content' },\n    { tab: 'Six', content: 'Tab 6 Content' },\n    { tab: 'Seven', content: 'Tab 7 Content' },\n    { tab: 'Eight', content: 'Tab 8 Content' },\n    { tab: 'Nine', content: 'Tab 9 Content' },\n    { tab: 'Ten', content: 'Tab 10 Content' },\n  ]\n\n  const tab = ref(null)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        tab: null,\n        items: [\n          { tab: 'One', content: 'Tab 1 Content' },\n          { tab: 'Two', content: 'Tab 2 Content' },\n          { tab: 'Three', content: 'Tab 3 Content' },\n          { tab: 'Four', content: 'Tab 4 Content' },\n          { tab: 'Five', content: 'Tab 5 Content' },\n          { tab: 'Six', content: 'Tab 6 Content' },\n          { tab: 'Seven', content: 'Tab 7 Content' },\n          { tab: 'Eight', content: 'Tab 8 Content' },\n          { tab: 'Nine', content: 'Tab 9 Content' },\n          { tab: 'Ten', content: 'Tab 10 Content' },\n        ],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-tabs/prop-align-tabs-center.vue",
    "content": "<template>\n  <v-card>\n    <v-tabs\n      v-model=\"tab\"\n      align-tabs=\"center\"\n      color=\"deep-purple-accent-4\"\n    >\n      <v-tab :value=\"1\">Landscape</v-tab>\n      <v-tab :value=\"2\">City</v-tab>\n      <v-tab :value=\"3\">Abstract</v-tab>\n    </v-tabs>\n\n    <v-tabs-window v-model=\"tab\">\n      <v-tabs-window-item\n        v-for=\"n in 3\"\n        :key=\"n\"\n        :value=\"n\"\n      >\n        <v-container fluid>\n          <v-row>\n            <v-col\n              v-for=\"i in 6\"\n              :key=\"i\"\n              cols=\"12\"\n              md=\"4\"\n            >\n              <v-img\n                :lazy-src=\"`https://picsum.photos/10/6?image=${i * n * 5 + 10}`\"\n                :src=\"`https://picsum.photos/500/300?image=${i * n * 5 + 10}`\"\n                height=\"205\"\n                cover\n              ></v-img>\n            </v-col>\n          </v-row>\n        </v-container>\n      </v-tabs-window-item>\n    </v-tabs-window>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const tab = ref(null)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      tab: null,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-tabs/prop-align-tabs-end.vue",
    "content": "<template>\n  <v-card>\n    <v-tabs\n      v-model=\"tab\"\n      align-tabs=\"end\"\n      color=\"deep-purple-accent-4\"\n    >\n      <v-tab :value=\"1\">Landscape</v-tab>\n      <v-tab :value=\"2\">City</v-tab>\n      <v-tab :value=\"3\">Abstract</v-tab>\n    </v-tabs>\n\n    <v-tabs-window v-model=\"tab\">\n      <v-tabs-window-item\n        v-for=\"n in 3\"\n        :key=\"n\"\n        :value=\"n\"\n      >\n        <v-container fluid>\n          <v-row>\n            <v-col\n              v-for=\"i in 6\"\n              :key=\"i\"\n              cols=\"12\"\n              md=\"4\"\n            >\n              <v-img\n                :lazy-src=\"`https://picsum.photos/10/6?image=${i * n * 5 + 10}`\"\n                :src=\"`https://picsum.photos/500/300?image=${i * n * 5 + 10}`\"\n                height=\"205\"\n                cover\n              ></v-img>\n            </v-col>\n          </v-row>\n        </v-container>\n      </v-tabs-window-item>\n    </v-tabs-window>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const tab = ref(null)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      tab: null,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-tabs/prop-align-tabs-title.vue",
    "content": "<template>\n  <v-card>\n    <v-toolbar color=\"primary\">\n      <v-app-bar-nav-icon></v-app-bar-nav-icon>\n\n      <v-toolbar-title>Your Dashboard</v-toolbar-title>\n\n      <v-btn icon=\"mdi-magnify\"></v-btn>\n\n      <v-btn icon=\"mdi-dots-vertical\"></v-btn>\n\n      <template v-slot:extension>\n        <v-tabs\n          v-model=\"tab\"\n          align-tabs=\"title\"\n        >\n          <v-tab\n            v-for=\"item in items\"\n            :key=\"item\"\n            :text=\"item\"\n            :value=\"item\"\n          ></v-tab>\n        </v-tabs>\n      </template>\n    </v-toolbar>\n\n    <v-tabs-window v-model=\"tab\">\n      <v-tabs-window-item\n        v-for=\"item in items\"\n        :key=\"item\"\n        :value=\"item\"\n      >\n        <v-card flat>\n          <v-card-text v-text=\"text\"></v-card-text>\n        </v-card>\n      </v-tabs-window-item>\n    </v-tabs-window>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const tab = ref(null)\n\n  const items = ['Web', 'Shopping', 'Videos', 'Images', 'News']\n  const text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.'\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        tab: null,\n        items: ['Web', 'Shopping', 'Videos', 'Images', 'News'],\n        text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.',\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-tabs/prop-center-active.vue",
    "content": "<template>\n  <v-card>\n    <v-tabs\n      bg-color=\"deep-purple-darken-4\"\n      center-active\n    >\n      <v-tab>One</v-tab>\n      <v-tab>Two</v-tab>\n      <v-tab>Three</v-tab>\n      <v-tab>Four</v-tab>\n      <v-tab>Five</v-tab>\n      <v-tab>Six</v-tab>\n      <v-tab>Seven</v-tab>\n      <v-tab>Eight</v-tab>\n      <v-tab>Nine</v-tab>\n      <v-tab>Ten</v-tab>\n      <v-tab>Eleven</v-tab>\n      <v-tab>Twelve</v-tab>\n      <v-tab>Thirteen</v-tab>\n      <v-tab>Fourteen</v-tab>\n      <v-tab>Fifteen</v-tab>\n      <v-tab>Sixteen</v-tab>\n      <v-tab>Seventeen</v-tab>\n      <v-tab>Eighteen</v-tab>\n      <v-tab>Nineteen</v-tab>\n      <v-tab>Twenty</v-tab>\n    </v-tabs>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-tabs/prop-direction.vue",
    "content": "<template>\n  <v-card>\n    <v-toolbar color=\"primary\" title=\"User Profile\">\n    </v-toolbar>\n\n    <div class=\"d-flex flex-row\">\n      <v-tabs\n        v-model=\"tab\"\n        color=\"primary\"\n        direction=\"vertical\"\n      >\n        <v-tab prepend-icon=\"mdi-account\" text=\"Option 1\" value=\"option-1\"></v-tab>\n        <v-tab prepend-icon=\"mdi-lock\" text=\"Option 2\" value=\"option-2\"></v-tab>\n        <v-tab prepend-icon=\"mdi-access-point\" text=\"Option 3\" value=\"option-3\"></v-tab>\n      </v-tabs>\n\n      <v-tabs-window v-model=\"tab\">\n        <v-tabs-window-item value=\"option-1\">\n          <v-card flat>\n            <v-card-text>\n              <p>\n                Sed aliquam ultrices mauris. Donec posuere vulputate arcu. Morbi ac felis. Etiam feugiat lorem non metus. Sed a libero.\n              </p>\n\n              <p>\n                Nam ipsum risus, rutrum vitae, vestibulum eu, molestie vel, lacus. Aenean tellus metus, bibendum sed, posuere ac, mattis non, nunc. Aliquam lobortis. Aliquam lobortis. Suspendisse non nisl sit amet velit hendrerit rutrum.\n              </p>\n\n              <p class=\"mb-0\">\n                Phasellus dolor. Fusce neque. Fusce fermentum odio nec arcu. Pellentesque libero tortor, tincidunt et, tincidunt eget, semper nec, quam. Phasellus blandit leo ut odio.\n              </p>\n            </v-card-text>\n          </v-card>\n        </v-tabs-window-item>\n\n        <v-tabs-window-item value=\"option-2\">\n          <v-card flat>\n            <v-card-text>\n              <p>\n                Morbi nec metus. Suspendisse faucibus, nunc et pellentesque egestas, lacus ante convallis tellus, vitae iaculis lacus elit id tortor. Sed mollis, eros et ultrices tempus, mauris ipsum aliquam libero, non adipiscing dolor urna a orci. Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo. Nunc sed turpis.\n              </p>\n\n              <p>\n                Suspendisse feugiat. Suspendisse faucibus, nunc et pellentesque egestas, lacus ante convallis tellus, vitae iaculis lacus elit id tortor. Proin viverra, ligula sit amet ultrices semper, ligula arcu tristique sapien, a accumsan nisi mauris ac eros. In hac habitasse platea dictumst. Fusce ac felis sit amet ligula pharetra condimentum.\n              </p>\n\n              <p>\n                Sed consequat, leo eget bibendum sodales, augue velit cursus nunc, quis gravida magna mi a libero. Nam commodo suscipit quam. In consectetuer turpis ut velit. Sed cursus turpis vitae tortor. Aliquam eu nunc.\n              </p>\n\n              <p>\n                Etiam ut purus mattis mauris sodales aliquam. Ut varius tincidunt libero. Aenean viverra rhoncus pede. Duis leo. Fusce fermentum odio nec arcu.\n              </p>\n\n              <p class=\"mb-0\">\n                Donec venenatis vulputate lorem. Aenean viverra rhoncus pede. In dui magna, posuere eget, vestibulum et, tempor auctor, justo. Fusce commodo aliquam arcu. Suspendisse enim turpis, dictum sed, iaculis a, condimentum nec, nisi.\n              </p>\n            </v-card-text>\n          </v-card>\n        </v-tabs-window-item>\n\n        <v-tabs-window-item value=\"option-3\">\n          <v-card flat>\n            <v-card-text>\n              <p>\n                Fusce a quam. Phasellus nec sem in justo pellentesque facilisis. Nam eget dui. Proin viverra, ligula sit amet ultrices semper, ligula arcu tristique sapien, a accumsan nisi mauris ac eros. In dui magna, posuere eget, vestibulum et, tempor auctor, justo.\n              </p>\n\n              <p class=\"mb-0\">\n                Cras sagittis. Phasellus nec sem in justo pellentesque facilisis. Proin sapien ipsum, porta a, auctor quis, euismod ut, mi. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nam at tortor in tellus interdum sagittis.\n              </p>\n            </v-card-text>\n          </v-card>\n        </v-tabs-window-item>\n      </v-tabs-window>\n    </div>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const tab = ref('option-1')\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      tab: 'option-1',\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-tabs/prop-fixed-tabs.vue",
    "content": "<template>\n  <v-tabs\n    bg-color=\"indigo-darken-2\"\n    fixed-tabs\n  >\n    <v-tab text=\"Option\"></v-tab>\n\n    <v-tab text=\"Another Option\"></v-tab>\n  </v-tabs>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-tabs/prop-grow.vue",
    "content": "<template>\n  <v-card color=\"basil\">\n    <v-card-title class=\"text-center justify-center py-6\">\n      <h1 class=\"font-weight-bold text-display-large text-basil my-0\">\n        BASiL\n      </h1>\n    </v-card-title>\n\n    <v-tabs\n      v-model=\"tab\"\n      color=\"basil\"\n      grow\n    >\n      <v-tab\n        v-for=\"item in items\"\n        :key=\"item\"\n        :text=\"item\"\n        :value=\"item\"\n      ></v-tab>\n    </v-tabs>\n\n    <v-tabs-window v-model=\"tab\">\n      <v-tabs-window-item\n        v-for=\"item in items\"\n        :key=\"item\"\n        :value=\"item\"\n      >\n        <v-card\n          color=\"basil\"\n          flat\n        >\n          <v-card-text>{{ text }}</v-card-text>\n        </v-card>\n      </v-tabs-window-item>\n    </v-tabs-window>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const tab = ref('Appetizers')\n\n  const items = [\n    'Appetizers',\n    'Entrees',\n    'Deserts',\n    'Cocktails',\n  ]\n  const text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.'\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        tab: 'Appetizers',\n        items: [\n          'Appetizers', 'Entrees', 'Deserts', 'Cocktails',\n        ],\n        text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.',\n      }\n    },\n  }\n</script>\n\n<style>\n/* Helper classes */\n.bg-basil {\n  background-color: #FFFBE6 !important;\n  color: #000 !important;\n}\n.text-basil {\n  color: #356859 !important;\n}\n</style>\n"
  },
  {
    "path": "packages/docs/src/examples/v-tabs/prop-icons.vue",
    "content": "<template>\n  <v-sheet elevation=\"2\">\n    <v-tabs\n      bg-color=\"indigo\"\n      next-icon=\"mdi-arrow-right-bold-box-outline\"\n      prev-icon=\"mdi-arrow-left-bold-box-outline\"\n      show-arrows\n    >\n      <v-tab\n        v-for=\"i in 30\"\n        :key=\"i\"\n        :text=\"`Item ${i}`\"\n      ></v-tab>\n    </v-tabs>\n  </v-sheet>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-tabs/prop-slider-transition.vue",
    "content": "<template>\n  <v-defaults-provider :defaults=\"{ VTab: { ripple: false } }\">\n    <v-card class=\"pa-3\">\n      <h5 class=\"my-0\">slider-transition: fade, duration 900ms</h5>\n      <v-tabs slider-transition=\"fade\" slider-transition-duration=\"900\" fixed-tabs>\n        <v-tab>Tab 1</v-tab>\n        <v-tab>Tab 2</v-tab>\n        <v-tab>Tab 3</v-tab>\n      </v-tabs>\n    </v-card>\n    <v-card class=\"pa-3 mt-3\">\n      <h5 class=\"my-0\">slider-transition: grow</h5>\n      <v-tabs slider-transition=\"grow\" fixed-tabs>\n        <v-tab>Tab 1</v-tab>\n        <v-tab>Tab 2</v-tab>\n        <v-tab>Tab 3</v-tab>\n      </v-tabs>\n    </v-card>\n  </v-defaults-provider>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-tabs/prop-spaced.vue",
    "content": "<template>\n  <v-container max-width=\"800\">\n    <v-row class=\"justify-space-around\">\n      <v-col cols=\"12\" sm=\"auto\">\n        <v-tabs\n          :items=\"example1\"\n          direction=\"vertical\"\n          slider-color=\"purple\"\n          spaced=\"end\"\n        ></v-tabs>\n      </v-col>\n\n      <v-col cols=\"12\" sm=\"auto\">\n        <v-tabs\n          direction=\"vertical\"\n          slider-color=\"primary\"\n          spaced=\"start\"\n        >\n          <v-tab\n            v-for=\"(tab, i) in example2\"\n            :key=\"tab\"\n            :prepend-icon=\"`mdi-numeric-${i + 1}-box`\"\n            :text=\"tab\"\n            spaced=\"start\"\n            width=\"200\"\n          ></v-tab>\n        </v-tabs>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  const example1 = [\n    { text: 'My Files', appendIcon: 'mdi-folder', width: 250 },\n    { text: 'Shared with me', appendIcon: 'mdi-account-multiple', width: 250 },\n    { text: 'Starred', appendIcon: 'mdi-star', width: 250 },\n    { text: 'Recent', appendIcon: 'mdi-update', width: 250 },\n    { text: 'Backups', appendIcon: 'mdi-cloud-upload', width: 250 },\n  ]\n\n  const example2 = [\n    'Profile',\n    'Settings',\n    'Security',\n    'Compliance',\n    'Statistics',\n  ]\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        example1: [\n          { text: 'My Files', appendIcon: 'mdi-folder', width: 250 },\n          { text: 'Shared with me', appendIcon: 'mdi-account-multiple', width: 250 },\n          { text: 'Starred', appendIcon: 'mdi-star', width: 250 },\n          { text: 'Recent', appendIcon: 'mdi-update', width: 250 },\n          { text: 'Backups', appendIcon: 'mdi-cloud-upload', width: 250 },\n        ],\n        example2: [\n          'Profile',\n          'Settings',\n          'Security',\n          'Compliance',\n          'Statistics',\n        ],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-tabs/prop-stacked.vue",
    "content": "<template>\n  <v-card>\n    <v-tabs\n      v-model=\"tab\"\n      align-tabs=\"center\"\n      bg-color=\"deep-purple-accent-4\"\n      stacked\n    >\n      <v-tab value=\"tab-1\">\n        <v-icon icon=\"mdi-phone\"></v-icon>\n\n        Recents\n      </v-tab>\n\n      <v-tab value=\"tab-2\">\n        <v-icon icon=\"mdi-heart\"></v-icon>\n\n        Favorites\n      </v-tab>\n\n      <v-tab value=\"tab-3\">\n        <v-icon icon=\"mdi-account-box\"></v-icon>\n\n        Nearby\n      </v-tab>\n    </v-tabs>\n\n    <v-tabs-window v-model=\"tab\">\n      <v-tabs-window-item\n        v-for=\"i in 3\"\n        :key=\"i\"\n        :value=\"'tab-' + i\"\n      >\n        <v-card>\n          <v-card-text>{{ text }}</v-card-text>\n        </v-card>\n      </v-tabs-window-item>\n    </v-tabs-window>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const tab = ref(null)\n\n  const text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.'\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        tab: null,\n        text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.',\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-tabs/slot-tabs.vue",
    "content": "<template>\n  <v-sheet color=\"#0d1117\" elevation=\"1\" rounded=\"lg\">\n    <v-tabs\n      v-model=\"tab\"\n      :items=\"tabs\"\n      align-tabs=\"center\"\n      color=\"white\"\n      height=\"60\"\n      slider-color=\"#f78166\"\n    >\n      <template v-slot:tab=\"{ item }\">\n        <v-tab\n          :prepend-icon=\"item.icon\"\n          :text=\"item.text\"\n          :value=\"item.value\"\n          class=\"text-none\"\n        ></v-tab>\n      </template>\n\n      <template v-slot:item=\"{ item }\">\n        <v-tabs-window-item :value=\"item.value\" class=\"pa-4\">\n          Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!\n        </v-tabs-window-item>\n      </template>\n    </v-tabs>\n  </v-sheet>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const tab = shallowRef('tab-1')\n  const tabs = [\n    {\n      icon: 'mdi-book-open-page-variant',\n      text: 'Readme',\n      value: 'tab-1',\n    },\n    {\n      icon: 'mdi-handshake-outline',\n      text: 'Code of Conduct',\n      value: 'tab-2',\n    },\n    {\n      icon: 'mdi-license',\n      text: 'MIT License',\n      value: 'tab-3',\n    },\n    {\n      icon: 'mdi-shield-lock-outline',\n      text: 'Security',\n      value: 'tab-4',\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      tab: 'tab-1',\n      tabs: [\n        {\n          icon: 'mdi-book-open-page-variant',\n          text: 'Readme',\n          value: 'tab-1',\n        },\n        {\n          icon: 'mdi-handshake-outline',\n          text: 'Code of Conduct',\n          value: 'tab-2',\n        },\n        {\n          icon: 'mdi-license',\n          text: 'MIT License',\n          value: 'tab-3',\n        },\n        {\n          icon: 'mdi-shield-lock-outline',\n          text: 'Security',\n          value: 'tab-4',\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-tabs/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n    :script=\"script\"\n  >\n    <v-card :class=\"direction === 'vertical' ? 'd-flex' : ''\" elevation=\"2\">\n      <v-tabs\n        v-model=\"tab\"\n        v-bind=\"props\"\n      >\n        <v-tab value=\"one\">Item One</v-tab>\n        <v-tab value=\"two\">Item Two</v-tab>\n        <v-tab value=\"three\">Item Three</v-tab>\n      </v-tabs>\n\n      <v-divider v-if=\"!inset\" :vertical=\"direction === 'vertical'\"></v-divider>\n\n      <v-tabs-window v-model=\"tab\" :class=\"{ 'flex-fill': direction === 'vertical' }\">\n        <v-tabs-window-item value=\"one\">\n          <v-sheet class=\"pa-5\" color=\"purple\" min-height=\"200\">One</v-sheet>\n        </v-tabs-window-item>\n        <v-tabs-window-item value=\"two\">\n          <v-sheet class=\"pa-5\" color=\"orange\" min-height=\"200\">Two</v-sheet>\n        </v-tabs-window-item>\n        <v-tabs-window-item value=\"three\">\n          <v-sheet class=\"pa-5\" color=\"cyan\" min-height=\"200\">Three</v-sheet>\n        </v-tabs-window-item>\n      </v-tabs-window>\n    </v-card>\n\n    <template v-slot:configuration>\n      <v-select\n        v-model=\"direction\"\n        :items=\"['horizontal', 'vertical']\"\n        label=\"Direction\"\n        mandatory\n      ></v-select>\n      <v-select\n        v-model=\"color\"\n        :items=\"['primary', 'cyan', 'red']\"\n        label=\"Color\"\n        clearable\n      ></v-select>\n      <v-select\n        v-model=\"bgColor\"\n        :items=\"['blue-grey-darken-4', 'indigo-lighten-1']\"\n        label=\"Background\"\n        clearable\n      ></v-select>\n      <v-select\n        v-model=\"sliderColor\"\n        :items=\"['teal-darken-2', 'indigo-lighten-4']\"\n        label=\"Slider color\"\n        clearable\n      ></v-select>\n      <v-checkbox v-model=\"grow\" label=\"Grow\" hide-details></v-checkbox>\n      <v-checkbox v-if=\"model !== 'inset'\" v-model=\"hideSlider\" label=\"Hide slider\" hide-details></v-checkbox>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-tabs'\n  const model = ref('default')\n  const options = ['inset']\n  const tab = shallowRef(0)\n\n  const direction = shallowRef('horizontal')\n  const color = shallowRef('primary')\n  const bgColor = shallowRef(null)\n  const sliderColor = shallowRef(null)\n  const grow = shallowRef(false)\n  const hideSlider = shallowRef(false)\n\n  const props = computed(() => {\n    return {\n      color: color.value || undefined,\n      'bg-color': bgColor.value || undefined,\n      direction: direction.value === 'vertical' ? direction.value : undefined,\n      'slider-color': sliderColor.value || undefined,\n      grow: grow.value || undefined,\n      'hide-slider': (model.value !== 'inset' && hideSlider.value) || undefined,\n      inset: model.value === 'inset' || undefined,\n      class: model.value === 'inset' ? 'mb-2' : undefined,\n    }\n  })\n\n  const code = computed(() => {\n    return `\n<v-sheet${direction.value === 'vertical' ? ' class=\"d-flex\"' : ''} elevation=\"2\">\n  <${name} v-model=\"tab\"${propsToString(props.value, [], 2)}>\n    <v-tab value=\"one\">Item One</v-tab>\n    <v-tab value=\"two\">Item Two</v-tab>\n    <v-tab value=\"three\">Item Three</v-tab>\n  </${name}>${model.value !== 'inset' ? `\\n\\n  <v-divider${direction.value === 'vertical' ? ' vertical' : ''}></v-divider>` : ''}\n\n  <v-tabs-window v-model=\"tab\"${direction.value === 'vertical' ? ' class=\"flex-fill\"' : ''}>\n    <v-tabs-window-item value=\"one\">\n      <v-sheet class=\"pa-5\" color=\"purple\">One</v-sheet>\n    </v-tabs-window-item>\n    <v-tabs-window-item value=\"two\">\n      <v-sheet class=\"pa-5\" color=\"orange\">Two</v-sheet>\n    </v-tabs-window-item>\n    <v-tabs-window-item value=\"three\">\n      <v-sheet class=\"pa-5\" color=\"brown\">Three</v-sheet>\n    </v-tabs-window-item>\n  </v-tabs-window>\n</v-sheet>`\n  })\n\n  const script = computed(() => {\n    return `<script setup>\n  import { ref } from 'vue'\n\n  const tab = ref('one')\n<` + '/script>'\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-text-field/event-icons.vue",
    "content": "<template>\n  <v-form>\n    <v-container>\n      <v-row>\n        <v-col cols=\"12\">\n          <v-text-field\n            v-model=\"message\"\n            :append-icon=\"message ? 'mdi-send' : 'mdi-microphone'\"\n            :append-inner-icon=\"marker ? 'mdi-map-marker' : 'mdi-map-marker-off'\"\n            :prepend-icon=\"icon\"\n            clear-icon=\"mdi-close-circle\"\n            label=\"Message\"\n            type=\"text\"\n            variant=\"filled\"\n            clearable\n            @click:append=\"sendMessage\"\n            @click:append-inner=\"toggleMarker\"\n            @click:clear=\"clearMessage\"\n            @click:prepend=\"changeIcon\"\n          ></v-text-field>\n        </v-col>\n      </v-row>\n    </v-container>\n  </v-form>\n</template>\n\n<script setup>\n  import { computed, ref } from 'vue'\n\n  const icons = [\n    'mdi-emoticon',\n    'mdi-emoticon-cool',\n    'mdi-emoticon-dead',\n    'mdi-emoticon-excited',\n    'mdi-emoticon-happy',\n    'mdi-emoticon-neutral',\n    'mdi-emoticon-sad',\n    'mdi-emoticon-tongue',\n  ]\n\n  const message = ref('Hey!')\n  const marker = ref(true)\n  const iconIndex = ref(0)\n\n  const icon = computed(() => {\n    return icons[iconIndex.value]\n  })\n  function toggleMarker () {\n    marker.value = !marker.value\n  }\n\n  function sendMessage () {\n    resetIcon()\n    clearMessage()\n  }\n  function clearMessage () {\n    message.value = ''\n  }\n  function resetIcon () {\n    iconIndex.value = 0\n  }\n  function changeIcon () {\n    iconIndex.value === icons.length - 1\n      ? iconIndex.value = 0\n      : iconIndex.value++\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      message: 'Hey!',\n      marker: true,\n      iconIndex: 0,\n      icons: [\n        'mdi-emoticon',\n        'mdi-emoticon-cool',\n        'mdi-emoticon-dead',\n        'mdi-emoticon-excited',\n        'mdi-emoticon-happy',\n        'mdi-emoticon-neutral',\n        'mdi-emoticon-sad',\n        'mdi-emoticon-tongue',\n      ],\n    }),\n\n    computed: {\n      icon () {\n        return this.icons[this.iconIndex]\n      },\n    },\n\n    methods: {\n      toggleMarker () {\n        this.marker = !this.marker\n      },\n      sendMessage () {\n        this.resetIcon()\n        this.clearMessage()\n      },\n      clearMessage () {\n        this.message = ''\n      },\n      resetIcon () {\n        this.iconIndex = 0\n      },\n      changeIcon () {\n        this.iconIndex === this.icons.length - 1\n          ? this.iconIndex = 0\n          : this.iconIndex++\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-text-field/misc-custom-validation.vue",
    "content": "<template>\n  <v-row class=\"justify-center\">\n    <v-col\n      cols=\"12\"\n      lg=\"6\"\n      md=\"8\"\n      sm=\"10\"\n    >\n      <v-card ref=\"form\">\n        <v-card-text>\n          <v-text-field\n            ref=\"name\"\n            v-model=\"name\"\n            :error-messages=\"errorMessages\"\n            :rules=\"[() => !!name || 'This field is required']\"\n            label=\"Full Name\"\n            placeholder=\"John Doe\"\n            required\n          ></v-text-field>\n          <v-text-field\n            ref=\"address\"\n            v-model=\"address\"\n            :rules=\"[\n              () => !!address || 'This field is required',\n              () => !!address && address.length <= 25 || 'Address must be less than 25 characters',\n              addressCheck\n            ]\"\n            counter=\"25\"\n            label=\"Address Line\"\n            placeholder=\"Snowy Rock Pl\"\n            required\n          ></v-text-field>\n          <v-text-field\n            ref=\"city\"\n            v-model=\"city\"\n            :rules=\"[() => !!city || 'This field is required', addressCheck]\"\n            label=\"City\"\n            placeholder=\"El Paso\"\n            required\n          ></v-text-field>\n          <v-text-field\n            ref=\"state\"\n            v-model=\"state\"\n            :rules=\"[() => !!state || 'This field is required']\"\n            label=\"State/Province/Region\"\n            placeholder=\"TX\"\n            required\n          ></v-text-field>\n          <v-text-field\n            ref=\"zip\"\n            v-model=\"zip\"\n            :rules=\"[() => !!zip || 'This field is required']\"\n            label=\"ZIP / Postal Code\"\n            placeholder=\"79938\"\n            required\n          ></v-text-field>\n          <v-autocomplete\n            ref=\"country\"\n            v-model=\"country\"\n            :items=\"countries\"\n            :rules=\"[() => !!country || 'This field is required']\"\n            label=\"Country\"\n            placeholder=\"Select...\"\n            required\n          ></v-autocomplete>\n        </v-card-text>\n        <v-divider class=\"mt-12\"></v-divider>\n        <v-card-actions>\n          <v-btn variant=\"text\">\n            Cancel\n          </v-btn>\n          <v-spacer></v-spacer>\n          <v-slide-x-reverse-transition>\n            <v-tooltip\n              v-if=\"formHasErrors\"\n              location=\"left\"\n            >\n              <template v-slot:activator=\"{ props }\">\n                <v-btn\n                  icon\n                  v-bind=\"props\"\n                  @click=\"resetForm\"\n                >\n                  <v-icon>mdi-refresh</v-icon>\n                </v-btn>\n              </template>\n              <span>Refresh form</span>\n            </v-tooltip>\n          </v-slide-x-reverse-transition>\n          <v-btn\n            color=\"primary\"\n            variant=\"text\"\n            @click=\"submit\"\n          >\n            Submit\n          </v-btn>\n        </v-card-actions>\n      </v-card>\n    </v-col>\n  </v-row>\n</template>\n\n<script>\n  export default {\n    data: () => ({\n      countries: ['Afghanistan', 'Albania', 'Algeria', 'Andorra', 'Angola', 'Anguilla', 'Antigua &amp; Barbuda', 'Argentina', 'Armenia', 'Aruba', 'Australia', 'Austria', 'Azerbaijan', 'Bahamas', 'Bahrain', 'Bangladesh', 'Barbados', 'Belarus', 'Belgium', 'Belize', 'Benin', 'Bermuda', 'Bhutan', 'Bolivia', 'Bosnia &amp; Herzegovina', 'Botswana', 'Brazil', 'British Virgin Islands', 'Brunei', 'Bulgaria', 'Burkina Faso', 'Burundi', 'Cambodia', 'Cameroon', 'Cape Verde', 'Cayman Islands', 'Chad', 'Chile', 'China', 'Colombia', 'Congo', 'Cook Islands', 'Costa Rica', 'Cote D Ivoire', 'Croatia', 'Cruise Ship', 'Cuba', 'Cyprus', 'Czech Republic', 'Denmark', 'Djibouti', 'Dominica', 'Dominican Republic', 'Ecuador', 'Egypt', 'El Salvador', 'Equatorial Guinea', 'Estonia', 'Ethiopia', 'Falkland Islands', 'Faroe Islands', 'Fiji', 'Finland', 'France', 'French Polynesia', 'French West Indies', 'Gabon', 'Gambia', 'Georgia', 'Germany', 'Ghana', 'Gibraltar', 'Greece', 'Greenland', 'Grenada', 'Guam', 'Guatemala', 'Guernsey', 'Guinea', 'Guinea Bissau', 'Guyana', 'Haiti', 'Honduras', 'Hong Kong', 'Hungary', 'Iceland', 'India', 'Indonesia', 'Iran', 'Iraq', 'Ireland', 'Isle of Man', 'Israel', 'Italy', 'Jamaica', 'Japan', 'Jersey', 'Jordan', 'Kazakhstan', 'Kenya', 'Kuwait', 'Kyrgyz Republic', 'Laos', 'Latvia', 'Lebanon', 'Lesotho', 'Liberia', 'Libya', 'Liechtenstein', 'Lithuania', 'Luxembourg', 'Macau', 'Macedonia', 'Madagascar', 'Malawi', 'Malaysia', 'Maldives', 'Mali', 'Malta', 'Mauritania', 'Mauritius', 'Mexico', 'Moldova', 'Monaco', 'Mongolia', 'Montenegro', 'Montserrat', 'Morocco', 'Mozambique', 'Namibia', 'Nepal', 'Netherlands', 'Netherlands Antilles', 'New Caledonia', 'New Zealand', 'Nicaragua', 'Niger', 'Nigeria', 'Norway', 'Oman', 'Pakistan', 'Palestine', 'Panama', 'Papua New Guinea', 'Paraguay', 'Peru', 'Philippines', 'Poland', 'Portugal', 'Puerto Rico', 'Qatar', 'Reunion', 'Romania', 'Russia', 'Rwanda', 'Saint Pierre &amp; Miquelon', 'Samoa', 'San Marino', 'Satellite', 'Saudi Arabia', 'Senegal', 'Serbia', 'Seychelles', 'Sierra Leone', 'Singapore', 'Slovakia', 'Slovenia', 'South Africa', 'South Korea', 'Spain', 'Sri Lanka', 'St Kitts &amp; Nevis', 'St Lucia', 'St Vincent', 'St. Lucia', 'Sudan', 'Suriname', 'Swaziland', 'Sweden', 'Switzerland', 'Syria', 'Taiwan', 'Tajikistan', 'Tanzania', 'Thailand', `Timor L'Este`, 'Togo', 'Tonga', 'Trinidad &amp; Tobago', 'Tunisia', 'Turkey', 'Turkmenistan', 'Turks &amp; Caicos', 'Uganda', 'Ukraine', 'United Arab Emirates', 'United Kingdom', 'United States', 'Uruguay', 'Uzbekistan', 'Venezuela', 'Vietnam', 'Virgin Islands (US)', 'Yemen', 'Zambia', 'Zimbabwe'],\n      errorMessages: '',\n      name: null,\n      address: null,\n      city: null,\n      state: null,\n      zip: null,\n      country: null,\n      formHasErrors: false,\n    }),\n\n    computed: {\n      form () {\n        return {\n          name: this.name,\n          address: this.address,\n          city: this.city,\n          state: this.state,\n          zip: this.zip,\n          country: this.country,\n        }\n      },\n    },\n\n    watch: {\n      name () {\n        this.errorMessages = ''\n      },\n    },\n\n    methods: {\n      addressCheck () {\n        this.errorMessages = this.address && !this.name\n          ? `Hey! I'm required`\n          : ''\n\n        return true\n      },\n      resetForm () {\n        this.errorMessages = []\n        this.formHasErrors = false\n\n        Object.keys(this.form).forEach(f => {\n          this.$refs[f].reset()\n        })\n      },\n      submit () {\n        this.formHasErrors = false\n\n        Object.keys(this.form).forEach(f => {\n          if (!this.form[f]) this.formHasErrors = true\n\n          this.$refs[f].validate(true)\n        })\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-text-field/misc-full-width-with-counter.vue",
    "content": "<template>\n  <v-form>\n    <v-autocomplete\n      v-model=\"selected\"\n      :items=\"items\"\n      label=\"To\"\n      chips\n      hide-details\n      hide-no-data\n      hide-selected\n      multiple\n      single-line\n    ></v-autocomplete>\n\n    <v-divider></v-divider>\n\n    <v-text-field\n      v-model=\"subject\"\n      label=\"Subject\"\n      hide-details\n      single-line\n    ></v-text-field>\n\n    <v-divider></v-divider>\n\n    <v-textarea\n      v-model=\"title\"\n      label=\"Message\"\n      maxlength=\"120\"\n      counter\n      single-line\n    ></v-textarea>\n  </v-form>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const items = ['Trevor Handsen', 'Alex Nelson']\n\n  const selected = ref(['Trevor Handsen'])\n  const subject = ref('Plans for the weekend')\n  const title = ref('Hi,\\nI just wanted to check in and see if you had any plans the upcoming weekend. We are thinking of heading up to Napa')\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: ['Trevor Handsen', 'Alex Nelson'],\n      selected: ['Trevor Handsen'],\n      subject: 'Plans for the weekend',\n      title: 'Hi,\\nI just wanted to check in and see if you had any plans the upcoming weekend. We are thinking of heading up to Napa',\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-text-field/misc-guide.vue",
    "content": "<template>\n  <v-sheet class=\"bg-deep-purple pa-12\" rounded>\n    <v-card class=\"mx-auto px-6 py-8\" max-width=\"344\">\n      <v-form\n        v-model=\"form\"\n        @submit.prevent=\"onSubmit\"\n      >\n        <v-text-field\n          v-model=\"email\"\n          :readonly=\"loading\"\n          :rules=\"[required]\"\n          class=\"mb-2\"\n          label=\"Email\"\n          clearable\n        ></v-text-field>\n\n        <v-text-field\n          v-model=\"password\"\n          :readonly=\"loading\"\n          :rules=\"[required]\"\n          label=\"Password\"\n          placeholder=\"Enter your password\"\n          clearable\n        ></v-text-field>\n\n        <br>\n\n        <v-btn\n          :disabled=\"!form\"\n          :loading=\"loading\"\n          color=\"success\"\n          size=\"large\"\n          type=\"submit\"\n          variant=\"elevated\"\n          block\n        >\n          Sign In\n        </v-btn>\n      </v-form>\n    </v-card>\n  </v-sheet>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const form = ref(false)\n  const email = ref(null)\n  const password = ref(null)\n  const loading = ref(false)\n\n  function onSubmit () {\n    if (!form.value) return\n    loading.value = true\n    setTimeout(() => (loading.value = false), 2000)\n  }\n  function required (v) {\n    return !!v || 'Field is required'\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      form: false,\n      email: null,\n      password: null,\n      loading: false,\n    }),\n\n    methods: {\n      onSubmit () {\n        if (!this.form) return\n\n        this.loading = true\n\n        setTimeout(() => (this.loading = false), 2000)\n      },\n      required (v) {\n        return !!v || 'Field is required'\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-text-field/misc-login-form.vue",
    "content": "<template>\n  <div>\n    <v-img\n      class=\"mx-auto my-6\"\n      max-width=\"228\"\n      src=\"https://cdn.vuetifyjs.com/docs/images/logos/vuetify-logo-v3-slim-text-light.svg\"\n    ></v-img>\n\n    <v-card\n      class=\"mx-auto pa-12 pb-8\"\n      elevation=\"3\"\n      max-width=\"448\"\n      rounded=\"lg\"\n    >\n      <div class=\"text-body-large text-medium-emphasis\">Account</div>\n\n      <v-text-field\n        density=\"compact\"\n        placeholder=\"Email address\"\n        prepend-inner-icon=\"mdi-email-outline\"\n        variant=\"outlined\"\n      ></v-text-field>\n\n      <div class=\"text-body-large text-medium-emphasis d-flex align-center justify-space-between\">\n        Password\n\n        <a\n          class=\"text-body-small text-decoration-none text-blue\"\n          href=\"#\"\n          rel=\"noopener noreferrer\"\n          target=\"_blank\"\n        >\n          Forgot login password?</a>\n      </div>\n\n      <v-text-field\n        :append-inner-icon=\"visible ? 'mdi-eye-off' : 'mdi-eye'\"\n        :type=\"visible ? 'text' : 'password'\"\n        density=\"compact\"\n        placeholder=\"Enter your password\"\n        prepend-inner-icon=\"mdi-lock-outline\"\n        variant=\"outlined\"\n        @click:append-inner=\"visible = !visible\"\n      ></v-text-field>\n\n      <v-card\n        class=\"mb-12\"\n        color=\"surface-variant\"\n        variant=\"tonal\"\n      >\n        <v-card-text class=\"text-medium-emphasis text-body-small\">\n          Warning: After 3 consecutive failed login attempts, you account will be temporarily locked for three hours. If you must login now, you can also click \"Forgot login password?\" below to reset the login password.\n        </v-card-text>\n      </v-card>\n\n      <v-btn\n        class=\"mb-8\"\n        color=\"blue\"\n        size=\"large\"\n        variant=\"tonal\"\n        block\n      >\n        Log In\n      </v-btn>\n\n      <v-card-text class=\"text-center\">\n        <a\n          class=\"text-blue text-decoration-none\"\n          href=\"#\"\n          rel=\"noopener noreferrer\"\n          target=\"_blank\"\n        >\n          Sign up now <v-icon icon=\"mdi-chevron-right\"></v-icon>\n        </a>\n      </v-card-text>\n    </v-card>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const visible = ref(false)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      visible: false,\n    }),\n  }\n</script>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2723-35227&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-text-field/misc-password.vue",
    "content": "<template>\n  <v-form>\n    <v-container fluid>\n      <v-row>\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            v-model=\"password\"\n            :append-icon=\"show1 ? 'mdi-eye' : 'mdi-eye-off'\"\n            :rules=\"[rules.required, rules.min]\"\n            :type=\"show1 ? 'text' : 'password'\"\n            hint=\"At least 8 characters\"\n            label=\"Normal with hint text\"\n            name=\"input-10-1\"\n            counter\n            @click:append=\"show1 = !show1\"\n          ></v-text-field>\n        </v-col>\n\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            :append-icon=\"show2 ? 'mdi-eye' : 'mdi-eye-off'\"\n            :rules=\"[rules.required, rules.min]\"\n            :type=\"show2 ? 'text' : 'password'\"\n            class=\"input-group--focused\"\n            hint=\"At least 8 characters\"\n            label=\"Visible\"\n            name=\"input-10-2\"\n            @click:append=\"show2 = !show2\"\n          ></v-text-field>\n        </v-col>\n      </v-row>\n    </v-container>\n  </v-form>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const rules = {\n    required: value => !!value || 'Required.',\n    min: v => v.length >= 8 || 'Min 8 characters',\n    emailMatch: () => (`The email and password you entered don't match`),\n  }\n\n  const show1 = ref(false)\n  const show2 = ref(true)\n  const password = ref('Password')\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        show1: false,\n        show2: true,\n        password: 'Password',\n        rules: {\n          required: value => !!value || 'Required.',\n          min: v => v.length >= 8 || 'Min 8 characters',\n          emailMatch: () => (`The email and password you entered don't match`),\n        },\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-text-field/prop-clearable.vue",
    "content": "<template>\n  <v-responsive\n    class=\"mx-auto\"\n    max-width=\"344\"\n  >\n    <v-text-field\n      v-model=\"model\"\n      hide-details=\"auto\"\n      label=\"Last name\"\n      clearable\n    ></v-text-field>\n  </v-responsive>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const model = ref('Leider')\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      model: 'Leider',\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-text-field/prop-contained.vue",
    "content": "<template>\n  <v-form>\n    <v-container>\n      <v-row>\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            v-model=\"first\"\n            label=\"First Name\"\n            variant=\"solo\"\n          ></v-text-field>\n        </v-col>\n\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            v-model=\"last\"\n            label=\"Last Name\"\n            variant=\"solo\"\n          ></v-text-field>\n        </v-col>\n      </v-row>\n    </v-container>\n  </v-form>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const first = ref('John')\n  const last = ref('Doe')\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      first: 'John',\n      last: 'Doe',\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-text-field/prop-counter.vue",
    "content": "<template>\n  <v-form>\n    <v-container>\n      <v-row>\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            v-model=\"title\"\n            :rules=\"rules\"\n            counter=\"25\"\n            hint=\"This field uses counter prop\"\n            label=\"Regular\"\n          ></v-text-field>\n        </v-col>\n\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            v-model=\"description\"\n            :rules=\"rules\"\n            hint=\"This field uses maxlength attribute\"\n            label=\"Limit exceeded\"\n            maxlength=\"25\"\n            counter\n          ></v-text-field>\n        </v-col>\n\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            v-model=\"title\"\n            :counter-value=\"v => v.trim().split(' ').length\"\n            :rules=\"wordsRules\"\n            counter=\"5\"\n            hint=\"This field counts words instead of characters\"\n            label=\"Custom counter from prop\"\n          ></v-text-field>\n        </v-col>\n\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            v-model=\"title\"\n            :rules=\"wordsRules\"\n            counter=\"5\"\n            hint=\"This field counts words instead of characters\"\n            label=\"Custom counter from slot\"\n          >\n            <template v-slot:counter=\"{ props }\">\n              <v-counter v-bind=\"props\" :value=\"title.trim().split(' ').length\"></v-counter>\n            </template>\n          </v-text-field>\n        </v-col>\n      </v-row>\n    </v-container>\n  </v-form>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const rules = [v => v.length <= 25 || 'Max 25 characters']\n  const wordsRules = [v => v.trim().split(' ').length <= 5 || 'Max 5 words']\n\n  const title = ref('Preliminary report')\n  const description = ref('California is a state in the western United States')\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        title: 'Preliminary report',\n        description: 'California is a state in the western United States',\n        rules: [v => v.length <= 25 || 'Max 25 characters'],\n        wordsRules: [v => v.trim().split(' ').length <= 5 || 'Max 5 words'],\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-text-field/prop-custom-colors.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"344\"\n    title=\"User Registration\"\n  >\n    <v-container>\n      <v-text-field\n        v-model=\"first\"\n        color=\"primary\"\n        label=\"First name\"\n        variant=\"underlined\"\n      ></v-text-field>\n\n      <v-text-field\n        v-model=\"last\"\n        color=\"primary\"\n        label=\"Last name\"\n        variant=\"underlined\"\n      ></v-text-field>\n\n      <v-text-field\n        v-model=\"email\"\n        color=\"primary\"\n        label=\"Email\"\n        variant=\"underlined\"\n      ></v-text-field>\n\n      <v-text-field\n        v-model=\"password\"\n        color=\"primary\"\n        label=\"Password\"\n        placeholder=\"Enter your password\"\n        variant=\"underlined\"\n      ></v-text-field>\n\n      <v-checkbox\n        v-model=\"terms\"\n        color=\"secondary\"\n        label=\"I agree to site terms and conditions\"\n      ></v-checkbox>\n    </v-container>\n\n    <v-divider></v-divider>\n\n    <v-card-actions>\n      <v-spacer></v-spacer>\n\n      <v-btn color=\"success\">\n        Complete Registration\n\n        <v-icon icon=\"mdi-chevron-right\" end></v-icon>\n      </v-btn>\n    </v-card-actions>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const first = ref(null)\n  const last = ref(null)\n  const email = ref(null)\n  const password = ref(null)\n  const terms = ref(false)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      first: null,\n      last: null,\n      email: null,\n      password: null,\n      terms: false,\n    }),\n  }\n</script>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2103-5977&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-text-field/prop-dense.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    color=\"surface-light\"\n    max-width=\"400\"\n  >\n    <v-card-text>\n      <v-text-field\n        :loading=\"loading\"\n        append-inner-icon=\"mdi-magnify\"\n        density=\"compact\"\n        label=\"Search templates\"\n        variant=\"solo\"\n        hide-details\n        single-line\n        @click:append-inner=\"onClick\"\n      ></v-text-field>\n    </v-card-text>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const loaded = ref(false)\n  const loading = ref(false)\n\n  function onClick () {\n    loading.value = true\n    setTimeout(() => {\n      loading.value = false\n      loaded.value = true\n    }, 2000)\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      loaded: false,\n      loading: false,\n    }),\n\n    methods: {\n      onClick () {\n        this.loading = true\n\n        setTimeout(() => {\n          this.loading = false\n          this.loaded = true\n        }, 2000)\n      },\n    },\n  }\n</script>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2103-37391&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-text-field/prop-disabled-and-readonly.vue",
    "content": "<template>\n  <v-form>\n    <v-container>\n      <v-row>\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            label=\"Regular\"\n            model-value=\"John Doe\"\n            disabled\n          ></v-text-field>\n        </v-col>\n\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            label=\"Regular\"\n            model-value=\"John Doe\"\n            readonly\n          ></v-text-field>\n        </v-col>\n\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            label=\"Solo\"\n            model-value=\"John Doe\"\n            variant=\"solo\"\n            disabled\n          ></v-text-field>\n        </v-col>\n\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            label=\"Solo\"\n            model-value=\"John Doe\"\n            variant=\"solo\"\n            readonly\n          ></v-text-field>\n        </v-col>\n\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            label=\"Outlined\"\n            model-value=\"John Doe\"\n            variant=\"outlined\"\n            disabled\n          ></v-text-field>\n        </v-col>\n\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            label=\"Outlined\"\n            model-value=\"John Doe\"\n            variant=\"outlined\"\n            readonly\n          ></v-text-field>\n        </v-col>\n\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            label=\"underlined\"\n            model-value=\"John Doe\"\n            variant=\"underlined\"\n            disabled\n          ></v-text-field>\n        </v-col>\n\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            label=\"underlined\"\n            model-value=\"John Doe\"\n            variant=\"underlined\"\n            readonly\n          ></v-text-field>\n        </v-col>\n      </v-row>\n    </v-container>\n  </v-form>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-text-field/prop-filled.vue",
    "content": "<template>\n  <v-form>\n    <v-container>\n      <v-row>\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            v-model=\"first\"\n            label=\"First Name\"\n            variant=\"filled\"\n          ></v-text-field>\n        </v-col>\n\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            v-model=\"last\"\n            label=\"Last Name\"\n            variant=\"filled\"\n          ></v-text-field>\n        </v-col>\n      </v-row>\n    </v-container>\n  </v-form>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const first = ref('John')\n  const last = ref('Doe')\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      first: 'John',\n      last: 'Doe',\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-text-field/prop-focused.vue",
    "content": "<template>\n  <v-container>\n    <v-text-field v-model=\"msg\" :focused=\"true\" @update:focused=\"\"></v-text-field>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const msg = ref('Hello World!')\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-text-field/prop-hide-details.vue",
    "content": "<template>\n  <div>\n    <v-text-field\n      :rules=\"rules\"\n      hide-details=\"auto\"\n      label=\"Main input\"\n    ></v-text-field>\n    <v-text-field label=\"Another input\"></v-text-field>\n  </div>\n</template>\n\n<script setup>\n  const rules = [\n    value => !!value || 'Required.',\n    value => (value && value.length >= 3) || 'Min 3 characters',\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      rules: [\n        value => !!value || 'Required.',\n        value => (value && value.length >= 3) || 'Min 3 characters',\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-text-field/prop-hint.vue",
    "content": "<template>\n  <v-form>\n    <v-container>\n      <v-row>\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            hint=\"For example, flowers or used cars\"\n            label=\"Your product or service\"\n            model-value=\"Grocery delivery\"\n          ></v-text-field>\n        </v-col>\n\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            hint=\"www.example.com/page\"\n            label=\"Your landing page\"\n            persistent-hint\n          ></v-text-field>\n        </v-col>\n\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            hint=\"For example, flowers or used cars\"\n            label=\"Your product or service\"\n            model-value=\"Grocery delivery\"\n            variant=\"solo\"\n          ></v-text-field>\n        </v-col>\n\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            hint=\"www.example.com/page\"\n            label=\"Your landing page\"\n            variant=\"solo\"\n            persistent-hint\n          ></v-text-field>\n        </v-col>\n\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            hint=\"For example, flowers or used cars\"\n            label=\"Your product or service\"\n            model-value=\"Grocery delivery\"\n            variant=\"outlined\"\n          ></v-text-field>\n        </v-col>\n\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            hint=\"www.example.com/page\"\n            label=\"Your landing page\"\n            variant=\"outlined\"\n            persistent-hint\n          ></v-text-field>\n        </v-col>\n      </v-row>\n    </v-container>\n  </v-form>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-text-field/prop-icon.vue",
    "content": "<template>\n  <v-form>\n    <v-container>\n      <v-row>\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            label=\"Prepend\"\n            prepend-icon=\"mdi-map-marker\"\n          ></v-text-field>\n\n          <v-text-field\n            label=\"Prepend inner\"\n            prepend-inner-icon=\"mdi-map-marker\"\n          ></v-text-field>\n\n          <v-text-field\n            append-icon=\"mdi-map-marker\"\n            label=\"Append\"\n          ></v-text-field>\n\n          <v-text-field\n            append-inner-icon=\"mdi-map-marker\"\n            label=\"Append inner\"\n          ></v-text-field>\n        </v-col>\n\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            label=\"Prepend\"\n            prepend-icon=\"mdi-map-marker\"\n            variant=\"solo\"\n          ></v-text-field>\n\n          <v-text-field\n            label=\"Prepend inner\"\n            prepend-inner-icon=\"mdi-map-marker\"\n            variant=\"solo\"\n          ></v-text-field>\n\n          <v-text-field\n            append-icon=\"mdi-map-marker\"\n            label=\"Append\"\n            variant=\"solo\"\n          ></v-text-field>\n\n          <v-text-field\n            append-inner-icon=\"mdi-map-marker\"\n            label=\"Append inner\"\n            variant=\"solo\"\n          ></v-text-field>\n        </v-col>\n\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            label=\"Prepend\"\n            prepend-icon=\"mdi-map-marker\"\n            variant=\"outlined\"\n          ></v-text-field>\n\n          <v-text-field\n            label=\"Prepend inner\"\n            prepend-inner-icon=\"mdi-map-marker\"\n            variant=\"outlined\"\n          ></v-text-field>\n\n          <v-text-field\n            append-icon=\"mdi-map-marker\"\n            label=\"Append\"\n            variant=\"outlined\"\n          ></v-text-field>\n\n          <v-text-field\n            append-inner-icon=\"mdi-map-marker\"\n            label=\"Append inner\"\n            variant=\"outlined\"\n          ></v-text-field>\n        </v-col>\n\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            label=\"Prepend\"\n            prepend-icon=\"mdi-map-marker\"\n            variant=\"underlined\"\n          ></v-text-field>\n\n          <v-text-field\n            label=\"Prepend inner\"\n            prepend-inner-icon=\"mdi-map-marker\"\n            variant=\"underlined\"\n          ></v-text-field>\n\n          <v-text-field\n            append-icon=\"mdi-map-marker\"\n            label=\"Append\"\n            variant=\"underlined\"\n          ></v-text-field>\n\n          <v-text-field\n            append-inner-icon=\"mdi-map-marker\"\n            label=\"Append inner\"\n            variant=\"underlined\"\n          ></v-text-field>\n        </v-col>\n      </v-row>\n    </v-container>\n  </v-form>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-text-field/prop-label.vue",
    "content": "<template>\n  <v-responsive\n    class=\"mx-auto\"\n    max-width=\"344\"\n  >\n    <v-text-field\n      hide-details=\"auto\"\n      label=\"First name\"\n    ></v-text-field>\n  </v-responsive>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-text-field/prop-messages.vue",
    "content": "<template>\n  <v-responsive\n    class=\"mx-auto\"\n    max-width=\"344\"\n  >\n    <v-text-field\n      hint=\"Enter your password to access this website\"\n      label=\"Password\"\n      type=\"input\"\n    ></v-text-field>\n  </v-responsive>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-text-field/prop-outlined.vue",
    "content": "<template>\n  <v-form>\n    <v-container>\n      <v-row>\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            v-model=\"first\"\n            label=\"First Name\"\n            variant=\"outlined\"\n          ></v-text-field>\n        </v-col>\n\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            v-model=\"last\"\n            label=\"Last Name\"\n            variant=\"outlined\"\n          ></v-text-field>\n        </v-col>\n      </v-row>\n    </v-container>\n  </v-form>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const first = ref('John')\n  const last = ref('Doe')\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      first: 'John',\n      last: 'Doe',\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-text-field/prop-placeholder.vue",
    "content": "<template>\n  <v-responsive\n    class=\"mx-auto\"\n    max-width=\"344\"\n  >\n    <v-text-field\n      hide-details=\"auto\"\n      label=\"Email address\"\n      placeholder=\"johndoe@gmail.com\"\n      type=\"email\"\n    ></v-text-field>\n  </v-responsive>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-text-field/prop-prefixes-and-suffixes.vue",
    "content": "<template>\n  <v-container fluid>\n    <v-row>\n      <v-col cols=\"4\">\n        <v-list-subheader>Prefix for dollar currency</v-list-subheader>\n      </v-col>\n\n      <v-col cols=\"8\">\n        <v-text-field\n          label=\"Amount\"\n          model-value=\"10.00\"\n          prefix=\"$\"\n        ></v-text-field>\n      </v-col>\n    </v-row>\n\n    <v-row>\n      <v-col cols=\"4\">\n        <v-list-subheader>Suffix for weight</v-list-subheader>\n      </v-col>\n\n      <v-col cols=\"8\">\n        <v-text-field\n          label=\"Weight\"\n          model-value=\"28.00\"\n          suffix=\"lbs\"\n        ></v-text-field>\n      </v-col>\n    </v-row>\n\n    <v-row>\n      <v-col cols=\"4\">\n        <v-list-subheader>Suffix for email domain</v-list-subheader>\n      </v-col>\n\n      <v-col cols=\"8\">\n        <v-text-field\n          label=\"Email address\"\n          model-value=\"example\"\n          suffix=\"@gmail.com\"\n        ></v-text-field>\n      </v-col>\n    </v-row>\n\n    <v-row>\n      <v-col cols=\"4\">\n        <v-list-subheader>Suffix for time zone</v-list-subheader>\n      </v-col>\n\n      <v-col cols=\"8\">\n        <v-text-field\n          label=\"Label Text\"\n          model-value=\"12:30:00\"\n          suffix=\"PST\"\n          type=\"time\"\n        ></v-text-field>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-text-field/prop-rules.vue",
    "content": "<template>\n  <v-responsive\n    class=\"mx-auto\"\n    max-width=\"344\"\n  >\n    <v-text-field\n      :rules=\"[rules.required]\"\n      label=\"Last name\"\n      clearable\n    ></v-text-field>\n  </v-responsive>\n</template>\n\n<script setup>\n  const rules = {\n    required: value => !!value || 'Field is required',\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      rules: {\n        required: value => !!value || 'Field is required',\n      },\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-text-field/prop-single-line.vue",
    "content": "<template>\n  <v-form>\n    <v-container>\n      <v-row>\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            label=\"Regular\"\n            single-line\n          ></v-text-field>\n        </v-col>\n\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            label=\"Solo\"\n            variant=\"solo\"\n            single-line\n          ></v-text-field>\n        </v-col>\n\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            label=\"Filled\"\n            variant=\"filled\"\n            single-line\n          ></v-text-field>\n        </v-col>\n\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            label=\"Outlined\"\n            variant=\"outlined\"\n            single-line\n          ></v-text-field>\n        </v-col>\n      </v-row>\n    </v-container>\n  </v-form>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-text-field/prop-validation.vue",
    "content": "<template>\n  <v-form>\n    <v-container>\n      <v-row>\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            v-model=\"title\"\n            :rules=\"[rules.required, rules.counter]\"\n            label=\"Title\"\n            maxlength=\"20\"\n            counter\n          ></v-text-field>\n        </v-col>\n\n        <v-col\n          cols=\"12\"\n          sm=\"6\"\n        >\n          <v-text-field\n            v-model=\"email\"\n            :rules=\"[rules.required, rules.email]\"\n            label=\"E-mail\"\n          ></v-text-field>\n        </v-col>\n      </v-row>\n    </v-container>\n  </v-form>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const title = ref('Preliminary report')\n  const email = ref('')\n\n  const rules = {\n    required: value => !!value || 'Required.',\n    counter: value => value.length <= 20 || 'Max 20 characters',\n    email: value => {\n      const pattern = /^(([^<>()[\\]\\\\.,;:\\s@\"]+(\\.[^<>()[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$/\n      return pattern.test(value) || 'Invalid e-mail.'\n    },\n  }\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        title: 'Preliminary report',\n        email: '',\n        rules: {\n          required: value => !!value || 'Required.',\n          counter: value => value.length <= 20 || 'Max 20 characters',\n          email: value => {\n            const pattern = /^(([^<>()[\\]\\\\.,;:\\s@\"]+(\\.[^<>()[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$/\n            return pattern.test(value) || 'Invalid e-mail.'\n          },\n        },\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-text-field/prop-variant.vue",
    "content": "<template>\n  <v-form>\n    <v-container>\n      <v-row>\n        <v-col\n          cols=\"12\"\n          md=\"4\"\n          sm=\"6\"\n        >\n          <v-text-field\n            label=\"Regular\"\n            placeholder=\"Placeholder\"\n          ></v-text-field>\n        </v-col>\n\n        <v-col\n          cols=\"12\"\n          md=\"4\"\n          sm=\"6\"\n        >\n          <v-text-field\n            label=\"Solo\"\n            placeholder=\"Placeholder\"\n            variant=\"solo\"\n          ></v-text-field>\n        </v-col>\n\n        <v-col\n          cols=\"12\"\n          md=\"4\"\n          sm=\"6\"\n        >\n          <v-text-field\n            label=\"Filled\"\n            placeholder=\"Placeholder\"\n            variant=\"filled\"\n          ></v-text-field>\n        </v-col>\n\n        <v-col\n          cols=\"12\"\n          md=\"4\"\n          sm=\"6\"\n        >\n          <v-text-field\n            label=\"Outlined\"\n            placeholder=\"Placeholder\"\n            variant=\"outlined\"\n          ></v-text-field>\n        </v-col>\n\n        <v-col\n          cols=\"12\"\n          md=\"4\"\n          sm=\"6\"\n        >\n          <v-text-field\n            label=\"Plain\"\n            placeholder=\"Placeholder\"\n            variant=\"plain\"\n          ></v-text-field>\n        </v-col>\n\n        <v-col\n          cols=\"12\"\n          md=\"4\"\n          sm=\"6\"\n        >\n          <v-text-field\n            label=\"Underlined\"\n            placeholder=\"Placeholder\"\n            variant=\"underlined\"\n          ></v-text-field>\n        </v-col>\n      </v-row>\n    </v-container>\n  </v-form>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-text-field/slot-icons.vue",
    "content": "<template>\n  <v-form>\n    <v-container>\n      <v-row>\n        <v-col cols=\"12\">\n          <v-text-field\n            v-model=\"message\"\n            label=\"Message\"\n            type=\"text\"\n            variant=\"outlined\"\n            clearable\n          >\n            <template v-slot:prepend>\n              <v-tooltip location=\"bottom\">\n                <template v-slot:activator=\"{ props }\">\n                  <v-icon v-bind=\"props\" icon=\"mdi-help-circle-outline\"></v-icon>\n                </template>\n\n                I'm a tooltip\n              </v-tooltip>\n            </template>\n\n            <template v-slot:append-inner>\n              <v-fade-transition leave-absolute>\n                <v-progress-circular\n                  v-if=\"loading\"\n                  color=\"info\"\n                  size=\"24\"\n                  indeterminate\n                ></v-progress-circular>\n\n                <img\n                  v-else\n                  alt=\"\"\n                  height=\"24\"\n                  src=\"https://cdn.vuetifyjs.com/images/logos/v-alt.svg\"\n                  width=\"24\"\n                >\n              </v-fade-transition>\n            </template>\n\n            <template v-slot:append>\n              <v-menu>\n                <template v-slot:activator=\"{ props }\">\n                  <v-btn v-bind=\"props\" class=\"mt-n2\">\n                    <v-icon icon=\"mdi-menu\" start></v-icon>\n\n                    Menu\n                  </v-btn>\n                </template>\n\n                <v-card>\n                  <v-card-text class=\"pa-6\">\n                    <v-btn\n                      color=\"primary\"\n                      size=\"large\"\n                      variant=\"text\"\n                      @click=\"clickMe\"\n                    >\n                      <v-icon icon=\"mdi-target\" start></v-icon>\n\n                      Click me\n                    </v-btn>\n                  </v-card-text>\n                </v-card>\n              </v-menu>\n            </template>\n          </v-text-field>\n        </v-col>\n      </v-row>\n    </v-container>\n  </v-form>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const message = ref('Hey!')\n  const loading = ref(false)\n\n  function clickMe () {\n    loading.value = true\n    message.value = 'Wait for it...'\n    setTimeout(() => {\n      loading.value = false\n      message.value = `You've clicked me!`\n    }, 2000)\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      message: 'Hey!',\n      loading: false,\n    }),\n\n    methods: {\n      clickMe () {\n        this.loading = true\n        this.message = 'Wait for it...'\n        setTimeout(() => {\n          this.loading = false\n          this.message = `You've clicked me!`\n        }, 2000)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-text-field/slot-label.vue",
    "content": "<template>\n  <v-form>\n    <v-container>\n      <v-text-field>\n        <template v-slot:label>\n          <span>\n            What about an <strong>icon</strong> here? <v-icon icon=\"mdi-file-find\"></v-icon>\n          </span>\n        </template>\n      </v-text-field>\n    </v-container>\n  </v-form>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-text-field/slot-progress.vue",
    "content": "<template>\n  <v-container fluid>\n    <v-checkbox-btn\n      v-model=\"custom\"\n      label=\"Loading\"\n    ></v-checkbox-btn>\n\n    <v-text-field\n      v-model=\"value\"\n      label=\"Type characters to change the loader color\"\n      placeholder=\"Start typing...\"\n      loading\n    >\n      <template v-slot:loader>\n        <v-progress-linear\n          :active=\"custom\"\n          :color=\"color\"\n          :model-value=\"progress\"\n          height=\"7\"\n          indeterminate\n        ></v-progress-linear>\n      </template>\n    </v-text-field>\n  </v-container>\n</template>\n\n<script setup>\n  import { computed, ref } from 'vue'\n\n  const value = ref('')\n  const custom = ref(false)\n  const progress = computed(() => {\n    return Math.min(100, value.value.length * 10)\n  })\n  const color = computed(() => {\n    return ['error', 'warning', 'success'][Math.floor(progress.value / 40)]\n  })\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      value: '',\n      custom: false,\n    }),\n\n    computed: {\n      progress () {\n        return Math.min(100, this.value.length * 10)\n      },\n      color () {\n        return ['error', 'warning', 'success'][Math.floor(this.progress / 40)]\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-text-field/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div>\n      <v-text-field v-bind=\"props\" v-model=\"field\"></v-text-field>\n    </div>\n\n    <template v-slot:configuration>\n      <v-text-field v-model=\"label\" label=\"Label\"></v-text-field>\n\n      <v-checkbox v-model=\"prepend\" label=\"Prepend icon\"></v-checkbox>\n\n      <v-checkbox v-model=\"clearable\" label=\"Clearable\"></v-checkbox>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-text-field'\n  const model = ref('default')\n  const clearable = ref(false)\n  const field = ref()\n  const label = ref('Label')\n  const prepend = ref(false)\n  const options = ['outlined', 'underlined', 'solo', 'solo-filled', 'solo-inverted']\n  const props = computed(() => {\n    return {\n      clearable: clearable.value || undefined,\n      label: label.value,\n      'prepend-icon': prepend.value ? '$vuetify' : undefined,\n      variant: model.value === 'default' ? undefined : model.value,\n    }\n  })\n\n  const slots = computed(() => {\n    return ``\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n\n  watch(clearable, () => {\n    if (!field.value) field.value = 'Hover to Clear me'\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-textarea/misc-signup-form.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    style=\"max-width: 500px;\"\n  >\n    <v-toolbar\n      color=\"deep-purple-accent-4\"\n      cards\n      dark\n      flat\n    >\n      <v-btn icon>\n        <v-icon>mdi-arrow-left</v-icon>\n      </v-btn>\n      <v-card-title class=\"text-title-large font-weight-regular\">\n        Sign up\n      </v-card-title>\n      <v-spacer></v-spacer>\n      <v-btn icon>\n        <v-icon>mdi-magnify</v-icon>\n      </v-btn>\n      <v-btn icon>\n        <v-icon>mdi-dots-vertical</v-icon>\n      </v-btn>\n    </v-toolbar>\n    <v-form\n      ref=\"form\"\n      v-model=\"isValid\"\n      class=\"pa-4 pt-6\"\n    >\n      <v-text-field\n        v-model=\"password\"\n        :rules=\"[rules.password, rules.length(6)]\"\n        color=\"deep-purple\"\n        counter=\"6\"\n        label=\"Password\"\n        style=\"min-height: 96px\"\n        type=\"password\"\n        variant=\"filled\"\n      ></v-text-field>\n      <v-text-field\n        v-model=\"phone\"\n        color=\"deep-purple\"\n        label=\"Phone number\"\n        variant=\"filled\"\n      ></v-text-field>\n      <v-text-field\n        v-model=\"email\"\n        :rules=\"[rules.email]\"\n        color=\"deep-purple\"\n        label=\"Email address\"\n        type=\"email\"\n        variant=\"filled\"\n      ></v-text-field>\n      <v-textarea\n        v-model=\"bio\"\n        color=\"deep-purple\"\n        label=\"Bio\"\n        rows=\"1\"\n        variant=\"filled\"\n        auto-grow\n      ></v-textarea>\n      <v-checkbox\n        v-model=\"agreement\"\n        :rules=\"[rules.required]\"\n        color=\"deep-purple\"\n      >\n        <template v-slot:label>\n          I agree to the&nbsp;\n          <a\n            href=\"#\"\n            @click.stop.prevent=\"dialog = true\"\n          >Terms of Service</a>\n          &nbsp;and&nbsp;\n          <a\n            href=\"#\"\n            @click.stop.prevent=\"dialog = true\"\n          >Privacy Policy</a>*\n        </template>\n      </v-checkbox>\n    </v-form>\n    <v-divider></v-divider>\n    <v-card-actions>\n      <v-btn\n        variant=\"text\"\n        @click=\"form.reset()\"\n      >\n        Clear\n      </v-btn>\n      <v-spacer></v-spacer>\n      <v-btn\n        :disabled=\"!isValid\"\n        :loading=\"isLoading\"\n        color=\"deep-purple-accent-4\"\n      >\n        Submit\n      </v-btn>\n    </v-card-actions>\n    <v-dialog\n      v-model=\"dialog\"\n      max-width=\"400\"\n      persistent\n    >\n      <v-card>\n        <v-card-title class=\"text-headline-small text-center mt-5\">\n          Legal\n        </v-card-title>\n        <v-card-text>\n          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n        </v-card-text>\n        <v-divider></v-divider>\n        <v-card-actions>\n          <v-btn\n            variant=\"text\"\n            @click=\"agreement = false, dialog = false\"\n          >\n            No\n          </v-btn>\n          <v-spacer></v-spacer>\n          <v-btn\n            color=\"deep-purple\"\n            variant=\"tonal\"\n            @click=\"agreement = true, dialog = false\"\n          >\n            Yes\n          </v-btn>\n        </v-card-actions>\n      </v-card>\n    </v-dialog>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const rules = {\n    email: v => !!(v || '').match(/@/) || 'Please enter a valid email',\n    length: len => v => (v || '').length >= len || `Invalid character length, required ${len}`,\n    password: v => !!(v || '').match(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*(_|[^\\w])).+$/) || 'Password must contain an upper case letter, a numeric character, and a special character',\n    required: v => !!v || 'This field is required',\n  }\n\n  const form = ref()\n\n  const agreement = ref(false)\n  const bio = ref('Far far away, behind the word mountains, far from the countries Vokalia and Consonantia, there live the blind texts')\n  const dialog = ref(false)\n  const email = ref()\n  const isValid = ref(false)\n  const isLoading = ref(false)\n  const password = ref()\n  const phone = ref()\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      agreement: false,\n      bio: 'Far far away, behind the word mountains, far from the countries Vokalia and Consonantia, there live the blind texts',\n      dialog: false,\n      email: undefined,\n      isValid: false,\n      isLoading: false,\n      password: undefined,\n      phone: undefined,\n      rules: {\n        email: v => !!(v || '').match(/@/) || 'Please enter a valid email',\n        length: len => v => (v || '').length >= len || `Invalid character length, required ${len}`,\n        password: v => !!(v || '').match(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*(_|[^\\w])).+$/) ||\n          'Password must contain an upper case letter, a numeric character, and a special character',\n        required: v => !!v || 'This field is required',\n      },\n    }),\n  }\n</script>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2115-39998&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-textarea/prop-auto-grow.vue",
    "content": "<template>\n  <v-container class=\"d-flex ga-3 align-start\" fluid>\n    <v-textarea\n      v-model=\"text\"\n      hint=\"Growing without limit\"\n      auto-grow\n      persistent-hint\n    ></v-textarea>\n\n    <v-textarea\n      v-model=\"text\"\n      hint=\"Growing up to 7 rows\"\n      max-rows=\"7\"\n      auto-grow\n      persistent-hint\n    ></v-textarea>\n\n    <v-textarea\n      v-model=\"text\"\n      hint=\"Growing up to 300px\"\n      max-height=\"300\"\n      auto-grow\n      persistent-hint\n    ></v-textarea>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const text = ref('The Woodman set to work at once, and so sharp was his axe that the tree was soon chopped nearly through.')\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-textarea/prop-background-color.vue",
    "content": "<template>\n  <v-container>\n    <v-textarea\n      bg-color=\"light-blue\"\n      color=\"black\"\n      label=\"Label\"\n    ></v-textarea>\n\n    <v-textarea\n      bg-color=\"grey-lighten-2\"\n      color=\"cyan\"\n      label=\"Label\"\n    ></v-textarea>\n\n    <v-textarea\n      bg-color=\"amber-lighten-4\"\n      color=\"orange orange-darken-4\"\n      label=\"Label\"\n    ></v-textarea>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-textarea/prop-browser-autocomplete.vue",
    "content": "<template>\n  <v-container fluid>\n    <v-textarea\n      autocomplete=\"email\"\n      label=\"Email\"\n    ></v-textarea>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-textarea/prop-clearable.vue",
    "content": "<template>\n  <v-container fluid>\n    <v-textarea\n      clear-icon=\"mdi-close-circle\"\n      label=\"Text\"\n      model-value=\"This is clearable text.\"\n      clearable\n    ></v-textarea>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-textarea/prop-counter.vue",
    "content": "<template>\n  <v-container fluid>\n    <v-textarea\n      :model-value=\"value\"\n      :rules=\"rules\"\n      label=\"Text\"\n      counter\n    ></v-textarea>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const rules = [v => v.length <= 25 || 'Max 25 characters']\n\n  const value = ref('Hello!')\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      rules: [v => v.length <= 25 || 'Max 25 characters'],\n      value: 'Hello!',\n    }),\n  }\n</script>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2115-38836&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-textarea/prop-icons.vue",
    "content": "<template>\n  <v-container>\n    <v-row>\n      <v-col\n        cols=\"12\"\n        sm=\"6\"\n      >\n        <v-textarea\n          class=\"mx-2\"\n          label=\"prepend-icon\"\n          prepend-icon=\"mdi-comment\"\n          rows=\"1\"\n        ></v-textarea>\n      </v-col>\n      <v-col\n        cols=\"12\"\n        sm=\"6\"\n      >\n        <v-textarea\n          append-icon=\"mdi-comment\"\n          class=\"mx-2\"\n          label=\"append-icon\"\n          rows=\"1\"\n        ></v-textarea>\n      </v-col>\n      <v-col\n        cols=\"12\"\n        sm=\"6\"\n      >\n        <v-textarea\n          class=\"mx-2\"\n          label=\"prepend-inner-icon\"\n          prepend-inner-icon=\"mdi-comment\"\n          rows=\"1\"\n        ></v-textarea>\n      </v-col>\n      <v-col\n        cols=\"12\"\n        sm=\"6\"\n      >\n        <v-textarea\n          append-inner-icon=\"mdi-comment\"\n          class=\"mx-2\"\n          label=\"append-inner-icon\"\n          rows=\"1\"\n        ></v-textarea>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-textarea/prop-no-resize.vue",
    "content": "<template>\n  <v-container fluid>\n    <v-textarea\n      :model-value=\"value\"\n      label=\"Text\"\n      rows=\"1\"\n      no-resize\n    ></v-textarea>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const value = ref('Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.')\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      value: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.',\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-textarea/prop-rows.vue",
    "content": "<template>\n  <v-container fluid>\n    <v-row>\n      <v-col\n        cols=\"12\"\n        sm=\"6\"\n      >\n        <v-textarea\n          label=\"One row\"\n          row-height=\"15\"\n          rows=\"1\"\n          variant=\"outlined\"\n          auto-grow\n        ></v-textarea>\n      </v-col>\n      <v-col\n        cols=\"12\"\n        sm=\"6\"\n      >\n        <v-textarea\n          label=\"Two rows\"\n          row-height=\"20\"\n          rows=\"2\"\n          variant=\"filled\"\n          auto-grow\n        ></v-textarea>\n      </v-col>\n      <v-col\n        cols=\"12\"\n        sm=\"6\"\n      >\n        <v-textarea\n          label=\"Three rows\"\n          row-height=\"25\"\n          rows=\"3\"\n          variant=\"outlined\"\n          auto-grow\n        ></v-textarea>\n      </v-col>\n      <v-col\n        cols=\"12\"\n        sm=\"6\"\n      >\n        <v-textarea\n          label=\"Four rows\"\n          row-height=\"30\"\n          rows=\"4\"\n          variant=\"filled\"\n          auto-grow\n        ></v-textarea>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-textarea/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div>\n      <v-textarea v-bind=\"props\" v-model=\"field\" hide-details></v-textarea>\n    </div>\n\n    <template v-slot:configuration>\n      <v-text-field v-model=\"label\" label=\"Label\"></v-text-field>\n\n      <v-checkbox v-model=\"prepend\" label=\"Prepend icon\"></v-checkbox>\n\n      <v-checkbox v-model=\"clearable\" label=\"Clearable\"></v-checkbox>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-textarea'\n  const model = ref('default')\n  const clearable = ref(false)\n  const field = ref()\n  const label = ref('Label')\n  const prepend = ref(false)\n  const options = ['outlined', 'underlined', 'solo', 'solo-filled', 'solo-inverted']\n  const props = computed(() => {\n    return {\n      clearable: clearable.value || undefined,\n      label: label.value,\n      'prepend-icon': prepend.value ? '$vuetify' : undefined,\n      variant: model.value === 'default' ? undefined : model.value,\n    }\n  })\n\n  const slots = computed(() => {\n    return ``\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n\n  watch(clearable, () => {\n    if (!field.value) field.value = 'Hover to Clear me'\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-theme-provider/prop-with-background.vue",
    "content": "<template>\n  <v-theme-provider class=\"pa-10\" theme=\"dark\" with-background>\n    <v-card subtitle=\"Subtitle\" title=\"Title\"></v-card>\n  </v-theme-provider>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-time-picker/misc-dialog-and-menu.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"justify-space-around\">\n      <v-col cols=\"11\" sm=\"5\">\n        <v-text-field\n          :model-value=\"time\"\n          label=\"Picker in menu\"\n          prepend-icon=\"mdi-clock-time-four-outline\"\n          readonly\n        >\n          <v-menu\n            v-model=\"showMenu\"\n            :close-on-content-click=\"false\"\n            activator=\"parent\"\n            min-width=\"0\"\n          >\n            <v-time-picker v-model=\"time\"></v-time-picker>\n          </v-menu>\n        </v-text-field>\n      </v-col>\n\n      <v-col cols=\"11\" sm=\"5\">\n        <v-text-field\n          :model-value=\"time\"\n          label=\"Picker in dialog\"\n          prepend-icon=\"mdi-clock-time-four-outline\"\n          readonly\n        >\n          <v-dialog v-model=\"showDialog\" activator=\"parent\" width=\"auto\">\n            <v-time-picker v-model=\"time\"></v-time-picker>\n          </v-dialog>\n        </v-text-field>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const time = ref(null)\n  const showMenu = ref(false)\n  const showDialog = ref(false)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        time: null,\n        showMenu: false,\n        showDialog: false,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-time-picker/prop-allowed-times.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"justify-space-around\">\n      <v-time-picker\n        v-model=\"time\"\n        :allowed-hours=\"allowedHours\"\n        :allowed-minutes=\"allowedMinutes\"\n        format=\"24hr\"\n        max=\"22:15\"\n        min=\"9:30\"\n        scrollable\n      ></v-time-picker>\n\n      <v-time-picker\n        v-model=\"timeStep\"\n        :allowed-minutes=\"allowedStep\"\n        format=\"24hr\"\n      ></v-time-picker>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const time = ref('11:15')\n  const timeStep = ref('10:10')\n\n  const allowedHours = v => v % 2\n  const allowedMinutes = v => v >= 10 && v <= 50\n  const allowedStep = m => m % 10 === 0\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        time: '11:15',\n        timeStep: '10:10',\n      }\n    },\n    methods: {\n      allowedHours: v => v % 2,\n      allowedMinutes: v => v >= 10 && v <= 50,\n      allowedStep: m => m % 10 === 0,\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-time-picker/prop-ampm-in-title.vue",
    "content": "<template>\n  <v-row class=\"align-center justify-space-around\">\n    <v-time-picker\n      v-model=\"picker\"\n      ampm-in-title\n    ></v-time-picker>\n    <v-time-picker\n      v-model=\"picker\"\n      :landscape=\"$vuetify.display.smAndUp\"\n      ampm-in-title\n    ></v-time-picker>\n  </v-row>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const picker = ref(null)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        picker: null,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-time-picker/prop-color.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"justify-space-around\">\n      <v-time-picker color=\"green-lighten-1\"></v-time-picker>\n\n      <v-time-picker color=\"primary\"></v-time-picker>\n    </v-row>\n  </v-container>\n</template>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2771-107051&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-time-picker/prop-disabled.vue",
    "content": "<template>\n  <v-row class=\"align-center justify-space-around\">\n    <v-time-picker\n      v-model=\"picker\"\n      disabled\n    ></v-time-picker>\n    <v-time-picker\n      v-model=\"picker\"\n      :landscape=\"$vuetify.display.smAndUp\"\n      disabled\n    ></v-time-picker>\n  </v-row>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const picker = ref(null)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        picker: null,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-time-picker/prop-elevation.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"justify-center\">\n      <v-time-picker\n        elevation=\"4\"\n      ></v-time-picker>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-time-picker/prop-format.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"justify-center\">\n      <v-time-picker format=\"24hr\"></v-time-picker>\n    </v-row>\n  </v-container>\n</template>\n\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2270-65133&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-time-picker/prop-hide-header.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"justify-center\">\n      <v-time-picker hide-header></v-time-picker>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-time-picker/prop-range.vue",
    "content": "<template>\n  <div>\n    <h1 class=\"my-0\">Plan your event:</h1>\n    <v-row class=\"align-center justify-space-around\">\n      <v-col style=\"width: 350px; flex: 0 1 auto;\">\n        <h2 class=\"my-0\">Start:</h2>\n        <v-time-picker\n          v-model=\"start\"\n          :max=\"end\"\n        ></v-time-picker>\n      </v-col>\n      <v-col style=\"width: 350px; flex: 0 1 auto;\">\n        <h2 class=\"my-0\">End:</h2>\n        <v-time-picker\n          v-model=\"end\"\n          :min=\"start\"\n        ></v-time-picker>\n      </v-col>\n    </v-row>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const start = ref(null)\n  const end = ref(null)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        start: null,\n        end: null,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-time-picker/prop-readonly.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"justify-center\">\n      <v-time-picker readonly></v-time-picker>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-time-picker/prop-scrollable.vue",
    "content": "<template>\n  <v-row class=\"align-center justify-space-around\">\n    <v-time-picker\n      v-model=\"picker\"\n      scrollable\n    ></v-time-picker>\n  </v-row>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const picker = ref(null)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        picker: null,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-time-picker/prop-use-seconds.vue",
    "content": "<template>\n  <v-container>\n    <v-row class=\"justify-center\">\n      <v-time-picker use-seconds></v-time-picker>\n    </v-row>\n  </v-container>\n</template>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2268-64361&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-time-picker/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <v-row class=\"justify-center\">\n      <v-time-picker v-bind=\"props\"></v-time-picker>\n    </v-row>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-time-picker'\n  const model = ref('default')\n  const options = []\n\n  const props = computed(() => {\n    return {\n      //\n    }\n  })\n\n  const slots = computed(() => {\n    return ''\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-timeline/misc-advanced.vue",
    "content": "<template>\n  <v-container style=\"max-width: 600px;\">\n    <v-timeline\n      density=\"compact\"\n      side=\"end\"\n    >\n      <v-timeline-item\n        class=\"mb-12\"\n        dot-color=\"orange\"\n        size=\"large\"\n        fill-dot\n      >\n        <template v-slot:icon>\n          <span>JL</span>\n        </template>\n        <v-text-field\n          v-model=\"input\"\n          density=\"compact\"\n          label=\"Leave a comment...\"\n          hide-details\n          @keydown.enter=\"comment\"\n        >\n          <template v-slot:append>\n            <v-btn\n              class=\"mx-0\"\n              variant=\"text\"\n              @click=\"comment\"\n            >\n              Post\n            </v-btn>\n          </template>\n        </v-text-field>\n      </v-timeline-item>\n\n      <v-slide-x-transition group>\n        <v-timeline-item\n          v-for=\"event in timeline\"\n          :key=\"event.id\"\n          class=\"mb-4\"\n          dot-color=\"pink\"\n          size=\"small\"\n        >\n          <div class=\"d-flex justify-space-between flex-grow-1\">\n            <div>{{ event.text }}</div>\n            <div class=\"flex-shrink-0\">{{ event.time }}</div>\n          </div>\n        </v-timeline-item>\n      </v-slide-x-transition>\n\n      <v-timeline-item\n        class=\"mb-6\"\n        hide-dot\n      >\n        <span>TODAY</span>\n      </v-timeline-item>\n\n      <v-timeline-item\n        class=\"mb-4\"\n        dot-color=\"grey\"\n        size=\"small\"\n      >\n        <div class=\"d-flex justify-space-between flex-grow-1\">\n          <div>\n            This order was archived.\n          </div>\n          <div class=\"flex-shrink-0\">\n            15:26 EDT\n          </div>\n        </div>\n      </v-timeline-item>\n\n      <v-timeline-item\n        class=\"mb-4\"\n        dot-color=\"primary\"\n        size=\"small\"\n      >\n        <div class=\"d-flex justify-space-between flex-grow-1\">\n          <div>\n            <v-chip\n              class=\"ms-0\"\n              color=\"purple\"\n              size=\"small\"\n              label\n            >\n              APP\n            </v-chip>\n            Digital Downloads fulfilled 1 item.\n          </div>\n          <div class=\"flex-shrink-0\">\n            15:25 EDT\n          </div>\n        </div>\n      </v-timeline-item>\n\n      <v-timeline-item\n        class=\"mb-4\"\n        dot-color=\"grey\"\n        size=\"small\"\n      >\n        <div class=\"d-flex justify-space-between flex-grow-1\">\n          <div>\n            Order confirmation email was sent to John Leider (john@google.com).\n          </div>\n          <div class=\"flex-shrink-0\">\n            15:25 EDT\n          </div>\n        </div>\n      </v-timeline-item>\n\n      <v-timeline-item\n        class=\"mb-4\"\n        hide-dot\n      >\n        <v-btn\n          variant=\"outlined\"\n        >\n          Resend Email\n        </v-btn>\n      </v-timeline-item>\n\n      <v-timeline-item\n        class=\"mb-4\"\n        dot-color=\"grey\"\n        size=\"small\"\n      >\n        <div class=\"d-flex justify-space-between flex-grow-1\">\n          <div>\n            A $15.00 USD payment was processed on PayPal Express Checkout\n          </div>\n          <div class=\"flex-shrink-0\">\n            15:25 EDT\n          </div>\n        </div>\n      </v-timeline-item>\n\n      <v-timeline-item\n        dot-color=\"grey\"\n        size=\"small\"\n      >\n        <div class=\"d-flex justify-space-between flex-grow-1\">\n          <div>\n            John Leider placed this order on Online Store (checkout #1937432132572).\n          </div>\n          <div class=\"flex-shrink-0\">\n            15:25 EDT\n          </div>\n        </div>\n      </v-timeline-item>\n    </v-timeline>\n  </v-container>\n</template>\n\n<script setup>\n  import { computed, ref } from 'vue'\n\n  const events = ref([])\n  const input = ref(null)\n  const nonce = ref(0)\n\n  const timeline = computed(() => {\n    return events.value.slice().reverse()\n  })\n\n  function comment () {\n    const time = (new Date()).toTimeString()\n    events.value.push({\n      id: nonce.value++,\n      text: input.value,\n      time: time.replace(/:\\d{2}\\sGMT-\\d{4}\\s\\((.*)\\)/, (match, contents, offset) => {\n        return ` ${contents.split(' ').map(v => v.charAt(0)).join('')}`\n      }),\n    })\n    input.value = null\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      events: [],\n      input: null,\n      nonce: 0,\n    }),\n\n    computed: {\n      timeline () {\n        return this.events.slice().reverse()\n      },\n    },\n\n    methods: {\n      comment () {\n        const time = (new Date()).toTimeString()\n        this.events.push({\n          id: this.nonce++,\n          text: this.input,\n          time: time.replace(/:\\d{2}\\sGMT-\\d{4}\\s\\((.*)\\)/, (match, contents, offset) => {\n            return ` ${contents.split(' ').map(v => v.charAt(0)).join('')}`\n          }),\n        })\n\n        this.input = null\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-timeline/prop-align.vue",
    "content": "<template>\n  <v-timeline align=\"start\">\n    <v-timeline-item>\n      <template v-slot:opposite>\n        Opposite content\n      </template>\n      <div>\n        <div class=\"text-title-large\">Content title</div>\n        <p>\n          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n        </p>\n      </div>\n    </v-timeline-item>\n\n    <v-timeline-item>\n      <template v-slot:opposite>\n        Opposite content\n      </template>\n      <div>\n        <div class=\"text-title-large\">Content title</div>\n        <p>\n          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n        </p>\n      </div>\n    </v-timeline-item>\n\n    <v-timeline-item>\n      <template v-slot:opposite>\n        Opposite content\n      </template>\n      <div>\n        <div class=\"text-title-large\">Content title</div>\n        <p>\n          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n        </p>\n      </div>\n    </v-timeline-item>\n  </v-timeline>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-timeline/prop-color.vue",
    "content": "<template>\n  <v-timeline align=\"start\" side=\"end\">\n    <v-timeline-item\n      dot-color=\"pink\"\n      size=\"small\"\n    >\n      <div class=\"d-flex\">\n        <strong class=\"me-4\">5pm</strong>\n        <div>\n          <strong>New Icon</strong>\n          <div class=\"text-body-small\">\n            Mobile App\n          </div>\n        </div>\n      </div>\n    </v-timeline-item>\n\n    <v-timeline-item\n      dot-color=\"teal-lighten-3\"\n      size=\"small\"\n    >\n      <div class=\"d-flex\">\n        <strong class=\"me-4\">3-4pm</strong>\n        <div>\n          <strong>Design Stand Up</strong>\n          <div class=\"text-body-small mb-2\">\n            Hangouts\n          </div>\n        </div>\n      </div>\n    </v-timeline-item>\n\n    <v-timeline-item\n      dot-color=\"pink\"\n      size=\"small\"\n    >\n      <div class=\"d-flex\">\n        <strong class=\"me-4\">12pm</strong>\n        <div>\n          <strong>Lunch break</strong>\n        </div>\n      </div>\n    </v-timeline-item>\n\n    <v-timeline-item\n      dot-color=\"teal-lighten-3\"\n      size=\"small\"\n    >\n      <div class=\"d-flex\">\n        <strong class=\"me-4\">9-11am</strong>\n        <div>\n          <strong>Finish Home Screen</strong>\n          <div class=\"text-body-small\">\n            Web App\n          </div>\n        </div>\n      </div>\n    </v-timeline-item>\n  </v-timeline>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-timeline/prop-direction.vue",
    "content": "<template>\n  <v-timeline direction=\"horizontal\">\n    <v-timeline-item>\n      <template v-slot:opposite>\n        Opposite content\n      </template>\n      <div>\n        <div class=\"text-title-large\">Content title</div>\n        <p>\n          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n        </p>\n      </div>\n    </v-timeline-item>\n\n    <v-timeline-item>\n      <template v-slot:opposite>\n        Opposite content\n      </template>\n      <div>\n        <div class=\"text-title-large\">Content title</div>\n        <p>\n          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n        </p>\n      </div>\n    </v-timeline-item>\n\n    <v-timeline-item>\n      <template v-slot:opposite>\n        Opposite content\n      </template>\n      <div>\n        <div class=\"text-title-large\">Content title</div>\n        <p>\n          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n        </p>\n      </div>\n    </v-timeline-item>\n  </v-timeline>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-timeline/prop-icon-dots.vue",
    "content": "<template>\n  <v-timeline align=\"start\">\n    <v-timeline-item\n      v-for=\"(item, i) in items\"\n      :key=\"i\"\n      :dot-color=\"item.color\"\n      :icon=\"item.icon\"\n      fill-dot\n    >\n      <v-card>\n        <v-card-title :class=\"['text-title-large', `bg-${item.color}`]\">\n          Lorem Ipsum Dolor\n        </v-card-title>\n        <v-card-text class=\"bg-white text--primary\">\n          <p>Lorem ipsum dolor sit amet, no nam oblique veritus. Commune scaevola imperdiet nec ut, sed euismod convenire principes at. Est et nobis iisque percipit, an vim zril disputando voluptatibus, vix an salutandi sententiae.</p>\n          <v-btn\n            :color=\"item.color\"\n            variant=\"outlined\"\n          >\n            Button\n          </v-btn>\n        </v-card-text>\n      </v-card>\n    </v-timeline-item>\n  </v-timeline>\n</template>\n\n<script setup>\n  const items = [\n    {\n      color: 'red-lighten-2',\n      icon: 'mdi-star',\n    },\n    {\n      color: 'purple-lighten-2',\n      icon: 'mdi-book-variant',\n    },\n    {\n      color: 'green-lighten-1',\n      icon: 'mdi-airballoon',\n    },\n    {\n      color: 'indigo-lighten-2',\n      icon: 'mdi-layers-triple',\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        {\n          color: 'red-lighten-2',\n          icon: 'mdi-star',\n        },\n        {\n          color: 'purple-lighten-2',\n          icon: 'mdi-book-variant',\n        },\n        {\n          color: 'green-lighten-1',\n          icon: 'mdi-airballoon',\n        },\n        {\n          color: 'indigo-lighten-2',\n          icon: 'mdi-layers-triple',\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-timeline/prop-line-inset.vue",
    "content": "<template>\n  <v-timeline direction=\"horizontal\" line-inset=\"12\">\n    <v-timeline-item>\n      <template v-slot:opposite>\n        Opposite\n      </template>\n      Content\n    </v-timeline-item>\n\n    <v-timeline-item>\n      <template v-slot:opposite>\n        Opposite\n      </template>\n      Content\n    </v-timeline-item>\n\n    <v-timeline-item>\n      <template v-slot:opposite>\n        Opposite\n      </template>\n      Content\n    </v-timeline-item>\n  </v-timeline>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-timeline/prop-mirror.vue",
    "content": "<template>\n  <div>\n    <v-switch\n      v-model=\"mirror\"\n      label=\"Toggle mirror\"\n    ></v-switch>\n    <v-timeline\n      :mirror=\"mirror\"\n    >\n      <v-timeline-item\n        v-for=\"n in 2\"\n        :key=\"n\"\n      >\n        <template v-slot:opposite>\n          <span>Tus eu perfecto</span>\n        </template>\n        <v-card class=\"elevation-1\">\n          <v-card-title class=\"text-headline-small\">\n            Lorem ipsum\n          </v-card-title>\n          <v-card-text>\n            Lorem ipsum dolor sit amet, no nam oblique veritus. Commune scaevola imperdiet nec ut, sed euismod convenire principes at. Est et nobis iisque percipit, an vim zril disputando voluptatibus, vix an salutandi sententiae.\n          </v-card-text>\n        </v-card>\n      </v-timeline-item>\n    </v-timeline>\n    <v-timeline\n      :mirror=\"mirror\"\n      single-side=\"before\"\n    >\n      <v-timeline-item\n        v-for=\"n in 2\"\n        :key=\"n\"\n      >\n        <template v-slot:opposite>\n          <span>Tus eu perfecto</span>\n        </template>\n        <v-card class=\"elevation-1\">\n          <v-card-title class=\"text-headline-small\">\n            Lorem ipsum\n          </v-card-title>\n          <v-card-text>\n            Lorem ipsum dolor sit amet, no nam oblique veritus. Commune scaevola imperdiet nec ut, sed euismod convenire principes at. Est et nobis iisque percipit, an vim zril disputando voluptatibus, vix an salutandi sententiae.\n          </v-card-text>\n        </v-card>\n      </v-timeline-item>\n    </v-timeline>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const mirror = ref(true)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      mirror: true,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-timeline/prop-single-side.vue",
    "content": "<template>\n  <v-timeline side=\"end\">\n    <v-timeline-item\n      v-for=\"item in items\"\n      :key=\"item.id\"\n      :dot-color=\"item.color\"\n      size=\"small\"\n    >\n      <v-alert\n        :color=\"item.color\"\n        :icon=\"item.icon\"\n        :value=\"true\"\n      >\n        Lorem ipsum dolor sit amet, no nam oblique veritus. Commune scaevola imperdiet nec ut, sed euismod convenire principes at. Est et nobis iisque percipit, an vim zril disputando voluptatibus, vix an salutandi sententiae.\n      </v-alert>\n    </v-timeline-item>\n  </v-timeline>\n</template>\n\n<script setup>\n  const items = [\n    {\n      id: 1,\n      color: 'info',\n      icon: 'mdi-information',\n    },\n    {\n      id: 2,\n      color: 'error',\n      icon: 'mdi-alert-circle',\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        {\n          id: 1,\n          color: 'info',\n          icon: 'mdi-information',\n        },\n        {\n          id: 2,\n          color: 'error',\n          icon: 'mdi-alert-circle',\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-timeline/prop-size.vue",
    "content": "<template>\n  <v-timeline>\n    <v-timeline-item\n      dot-color=\"purple-lighten-2\"\n      fill-dot\n    >\n      <v-card>\n        <v-card-title class=\"bg-purple-lighten-2\">\n          <v-icon\n            class=\"me-4\"\n            icon=\"mdi-magnify\"\n            size=\"large\"\n          ></v-icon>\n          <h2 class=\"font-weight-light my-0\">\n            Title 1\n          </h2>\n        </v-card-title>\n        <v-card-text>\n          Lorem ipsum dolor sit amet, no nam oblique veritus. Commune scaevola imperdiet nec ut, sed euismod convenire principes at. Est et nobis iisque percipit.\n        </v-card-text>\n      </v-card>\n    </v-timeline-item>\n\n    <v-timeline-item\n      dot-color=\"amber-lighten-1\"\n      size=\"x-small\"\n      fill-dot\n    >\n      <v-card>\n        <v-card-title class=\"bg-amber-lighten-1 justify-end\">\n          <h2 class=\"mt-0 me-4 font-weight-light\">\n            Title 2\n          </h2>\n          <v-icon\n            icon=\"mdi-home-outline\"\n            size=\"large\"\n          ></v-icon>\n        </v-card-title>\n        <v-card-text>\n          Lorem ipsum dolor sit amet, no nam oblique veritus. Commune scaevola imperdiet nec ut, sed euismod convenire principes at. Est et nobis iisque percipit.\n        </v-card-text>\n      </v-card>\n    </v-timeline-item>\n\n    <v-timeline-item\n      dot-color=\"cyan-lighten-1\"\n      fill-dot\n    >\n      <v-card>\n        <v-card-title class=\"bg-cyan-lighten-1\">\n          <v-icon\n            class=\"me-4\"\n            icon=\"mdi-email-outline\"\n            size=\"large\"\n          ></v-icon>\n          <h2 class=\"font-weight-light my-0\">\n            Title 3\n          </h2>\n        </v-card-title>\n        <v-card-text>\n          Lorem ipsum dolor sit amet, no nam oblique veritus. Commune scaevola imperdiet nec ut, sed euismod convenire principes at. Est et nobis iisque percipit.\n        </v-card-text>\n      </v-card>\n    </v-timeline-item>\n\n    <v-timeline-item\n      dot-color=\"red-lighten-1\"\n      size=\"x-small\"\n      fill-dot\n    >\n      <v-card>\n        <v-card-title class=\"bg-red-lighten-1 justify-end\">\n          <h2 class=\"mt-0 me-4 font-weight-light\">\n            Title 4\n          </h2>\n          <v-icon\n            icon=\"mdi-account-multiple-outline\"\n            size=\"large\"\n          ></v-icon>\n        </v-card-title>\n        <v-card-text>\n          Lorem ipsum dolor sit amet, no nam oblique veritus. Commune scaevola imperdiet nec ut, sed euismod convenire principes at. Est et nobis iisque percipit.\n        </v-card-text>\n      </v-card>\n    </v-timeline-item>\n\n    <v-timeline-item\n      dot-color=\"green-lighten-1\"\n      fill-dot\n    >\n      <v-card>\n        <v-card-title class=\"bg-green-lighten-1\">\n          <v-icon\n            class=\"me-4\"\n            icon=\"mdi-phone-in-talk\"\n            size=\"large\"\n          ></v-icon>\n          <h2 class=\"font-weight-light my-0\">\n            Title 5\n          </h2>\n        </v-card-title>\n        <v-card-text>\n          Lorem ipsum dolor sit amet, no nam oblique veritus. Commune scaevola imperdiet nec ut, sed euismod convenire principes at. Est et nobis iisque percipit.\n        </v-card-text>\n      </v-card>\n    </v-timeline-item>\n  </v-timeline>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-timeline/prop-truncate-line.vue",
    "content": "<template>\n  <div class=\"d-flex justify-space-around\">\n    <v-timeline truncate-line=\"start\">\n      <v-timeline-item>\n        <template v-slot:opposite>\n          Opposite\n        </template>\n        Content\n      </v-timeline-item>\n\n      <v-timeline-item>\n        <template v-slot:opposite>\n          Opposite\n        </template>\n        Content\n      </v-timeline-item>\n\n      <v-timeline-item>\n        <template v-slot:opposite>\n          Opposite\n        </template>\n        Content\n      </v-timeline-item>\n    </v-timeline>\n\n    <v-timeline truncate-line=\"end\">\n      <v-timeline-item>\n        <template v-slot:opposite>\n          Opposite\n        </template>\n        Content\n      </v-timeline-item>\n\n      <v-timeline-item>\n        <template v-slot:opposite>\n          Opposite\n        </template>\n        Content\n      </v-timeline-item>\n\n      <v-timeline-item>\n        <template v-slot:opposite>\n          Opposite\n        </template>\n        Content\n      </v-timeline-item>\n    </v-timeline>\n\n    <v-timeline truncate-line=\"both\">\n      <v-timeline-item>\n        <template v-slot:opposite>\n          Opposite\n        </template>\n        Content\n      </v-timeline-item>\n\n      <v-timeline-item>\n        <template v-slot:opposite>\n          Opposite\n        </template>\n        Content\n      </v-timeline-item>\n\n      <v-timeline-item>\n        <template v-slot:opposite>\n          Opposite\n        </template>\n        Content\n      </v-timeline-item>\n    </v-timeline>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-timeline/slot-icon.vue",
    "content": "<template>\n  <v-timeline>\n    <v-timeline-item size=\"large\">\n      <template v-slot:icon>\n        <v-avatar image=\"https://i.pravatar.cc/64\"></v-avatar>\n      </template>\n      <template v-slot:opposite>\n        <span>Tus eu perfecto</span>\n      </template>\n      <v-card class=\"elevation-1\">\n        <v-card-title class=\"text-headline-small\">\n          Lorem ipsum\n        </v-card-title>\n        <v-card-text>Lorem ipsum dolor sit amet, no nam oblique veritus. Commune scaevola imperdiet nec ut, sed euismod convenire principes at. Est et nobis iisque percipit, an vim zril disputando voluptatibus, vix an salutandi sententiae.</v-card-text>\n      </v-card>\n    </v-timeline-item>\n  </v-timeline>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-timeline/slot-opposite.vue",
    "content": "<template>\n  <v-timeline align=\"start\">\n    <v-timeline-item\n      v-for=\"(year, i) in years\"\n      :key=\"i\"\n      :dot-color=\"year.color\"\n      size=\"small\"\n    >\n      <template v-slot:opposite>\n        <div\n          :class=\"`pt-1 headline font-weight-bold text-${year.color}`\"\n          v-text=\"year.year\"\n        ></div>\n      </template>\n      <div>\n        <h2 :class=\"`mt-n1 headline font-weight-light mb-4 text-${year.color}`\">\n          Lorem ipsum\n        </h2>\n        <div>\n          Lorem ipsum dolor sit amet, no nam oblique veritus. Commune scaevola imperdiet nec ut, sed euismod convenire principes at. Est et nobis iisque percipit, an vim zril disputando voluptatibus, vix an salutandi sententiae.\n        </div>\n      </div>\n    </v-timeline-item>\n  </v-timeline>\n</template>\n\n<script setup>\n  const years = [\n    {\n      color: 'cyan',\n      year: '1960',\n    },\n    {\n      color: 'green',\n      year: '1970',\n    },\n    {\n      color: 'pink',\n      year: '1980',\n    },\n    {\n      color: 'amber',\n      year: '1990',\n    },\n    {\n      color: 'orange',\n      year: '2000',\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      years: [\n        {\n          color: 'cyan',\n          year: '1960',\n        },\n        {\n          color: 'green',\n          year: '1970',\n        },\n        {\n          color: 'pink',\n          year: '1980',\n        },\n        {\n          color: 'amber',\n          year: '1990',\n        },\n        {\n          color: 'orange',\n          year: '2000',\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-timeline/usage.vue",
    "content": "<template>\n  <v-timeline>\n    <v-timeline-item>timeline item</v-timeline-item>\n    <v-timeline-item>\n      timeline item\n    </v-timeline-item>\n    <v-timeline-item>timeline item</v-timeline-item>\n  </v-timeline>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-toolbar/misc-contextual-action-bar.vue",
    "content": "<template>\n  <v-card class=\"mx-auto\" max-width=\"500\">\n    <v-toolbar :color=\"selection.length ? 'surface-variant' : 'deep-purple accent-4'\">\n      <template v-slot:prepend>\n        <v-fade-transition hide-on-leave>\n          <v-btn\n            :key=\"selection.length > 0\"\n            :icon=\"selection.length ? 'mdi-close' : 'mdi-menu'\"\n            @click=\"onClick\"\n          ></v-btn>\n        </v-fade-transition>\n      </template>\n\n      <v-toolbar-title :text=\"selection.length ? `${selection.length} selected` : 'Photos'\"></v-toolbar-title>\n\n      <template v-slot:append>\n        <v-fade-transition hide-on-leave>\n          <v-btn\n            v-if=\"selection.length\"\n            key=\"export\"\n            icon=\"mdi-export-variant\"\n          ></v-btn>\n        </v-fade-transition>\n\n        <v-fade-transition hide-on-leave>\n          <v-btn\n            v-if=\"selection.length\"\n            key=\"delete\"\n            icon=\"mdi-delete\"\n          ></v-btn>\n        </v-fade-transition>\n\n        <v-btn icon=\"mdi-dots-vertical\"></v-btn>\n      </template>\n    </v-toolbar>\n\n    <v-card-text>\n      <v-select\n        v-model=\"selection\"\n        :items=\"items\"\n        hint=\"Make a selection\"\n        label=\"Select an option\"\n        clearable\n        multiple\n        open-on-clear\n        persistent-hint\n      ></v-select>\n    </v-card-text>\n  </v-card>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const items = ['Foo', 'Bar', 'Fizz', 'Buzz']\n\n  const selection = shallowRef([])\n\n  function onClick () {\n    if (!selection.value.length) return\n\n    selection.value = []\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      selection: [],\n      items: ['Foo', 'Bar', 'Fizz', 'Buzz'],\n    }),\n\n    methods: {\n      onClick () {\n        if (!this.selection.length) return\n\n        this.selection = []\n      },\n    },\n  }\n</script>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=1646-137681&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-toolbar/misc-flexible-and-card.vue",
    "content": "<template>\n  <v-card rounded=\"lg\" border flat>\n    <v-toolbar\n      color=\"primary\"\n      extended\n      flat\n    >\n      <template v-slot:prepend>\n        <v-btn icon=\"mdi-menu\"></v-btn>\n      </template>\n    </v-toolbar>\n\n    <v-card\n      class=\"mx-auto mt-n16 mb-4\"\n      elevation=\"2\"\n      height=\"200\"\n      max-width=\"600\"\n    >\n      <v-toolbar>\n        <v-toolbar-title text=\"Title\"></v-toolbar-title>\n\n        <template v-slot:append>\n          <div class=\"d-flex ga-1\">\n            <v-btn icon=\"mdi-magnify\">\n            </v-btn>\n\n            <v-btn icon=\"mdi-apps\">\n            </v-btn>\n\n            <v-btn icon=\"mdi-dots-vertical\">\n            </v-btn>\n          </div>\n        </template>\n      </v-toolbar>\n\n      <v-divider></v-divider>\n    </v-card>\n\n    <v-footer class=\"justify-center text-body-small\" color=\"surface-variant\">\n      {{ new Date().getFullYear() }} — <strong>Vuetify, LLC</strong>\n    </v-footer>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-toolbar/misc-tooltips-and-speed-dial.vue",
    "content": "<template>\n  <v-card>\n    <v-toolbar :collapse=\"collapse\" title=\"Toolbar\">\n      <v-btn\n        class=\"ml-3\"\n        icon=\"mdi-magnify\"\n        v-tooltip:bottom=\"'Search all products'\"\n      ></v-btn>\n\n      <v-btn\n        class=\"mr-3\"\n        icon=\"mdi-dots-vertical\"\n        size=\"small\"\n        variant=\"elevated\"\n      >\n        <v-icon></v-icon>\n        <v-speed-dial :location=\"dialLocation\" activator=\"parent\" open-on-hover>\n          <v-btn\n            v-for=\"(item, i) in dialActions\"\n            :key=\"i\"\n            :color=\"item.color\"\n            :icon=\"item.icon\"\n            v-tooltip=\"{ location: tooltipLocation, text: item.tooltip }\"\n          ></v-btn>\n        </v-speed-dial>\n      </v-btn>\n    </v-toolbar>\n\n    <v-card-text class=\"text-center pa-8\">\n      <v-btn\n        :text=\"collapse ? 'Expand' : 'Collapse'\"\n        color=\"surface-variant\"\n        @click=\"collapse = !collapse\"\n      ></v-btn>\n    </v-card-text>\n  </v-card>\n</template>\n\n<script setup>\n  import { shallowRef, toRef } from 'vue'\n\n  const collapse = shallowRef(false)\n  const dialLocation = toRef(() => collapse.value ? 'right center' : 'bottom center')\n  const tooltipLocation = toRef(() => collapse.value ? 'bottom' : 'left')\n\n  const dialActions = [\n    { color: 'success', icon: '$success', tooltip: 'Share feedback' },\n    { color: 'warning', icon: 'mdi-alert', tooltip: 'Report problem' },\n    { color: 'purple', icon: 'mdi-bell', tooltip: 'Open notifications' },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      collapse: false,\n      dialActions: [\n        { color: 'success', icon: '$success', tooltip: 'Share feedback' },\n        { color: 'warning', icon: 'mdi-alert', tooltip: 'Report problem' },\n        { color: 'purple', icon: 'mdi-bell', tooltip: 'Open notifications' },\n      ],\n    }),\n    computed: {\n      dialLocation () {\n        return this.collapse ? 'right center' : 'bottom center'\n      },\n      tooltipLocation () {\n        return this.collapse ? 'bottom' : 'left'\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-toolbar/prop-background.vue",
    "content": "<template>\n  <v-card height=\"200\">\n    <v-toolbar class=\"text-white\" image=\"https://cdn.vuetifyjs.com/images/backgrounds/vbanner.jpg\">\n      <v-btn icon=\"mdi-menu\"></v-btn>\n\n      <v-toolbar-title text=\"Toolbar\"></v-toolbar-title>\n\n      <v-btn icon=\"mdi-export\"></v-btn>\n    </v-toolbar>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-toolbar/prop-collapse.vue",
    "content": "<template>\n  <v-card>\n    <v-toolbar\n      :collapse=\"collapse\"\n      :collapse-position=\"collapsePosition\"\n      title=\"Toolbar\"\n    >\n      <template v-slot:append>\n        <div class=\"d-flex ga-1\">\n          <v-btn icon=\"mdi-magnify\"></v-btn>\n          <v-btn icon=\"mdi-dots-vertical\"></v-btn>\n        </div>\n      </template>\n    </v-toolbar>\n\n    <v-card-text class=\"d-flex flex-column align-center\">\n      <v-btn\n        color=\"surface-variant\"\n        text=\"Toggle\"\n        @click=\"collapse = !collapse\"\n      ></v-btn>\n      <span class=\"mt-4\">Collapse position:</span>\n      <v-chip-group v-model=\"collapsePosition\" variant=\"outlined\" border mandatory>\n        <v-chip\n          class=\"px-6\"\n          prepend-icon=\"mdi-arrow-collapse-left\"\n          selected-class=\"v-chip--variant-flat\"\n          text=\"start\"\n          value=\"start\"\n          label\n        ></v-chip>\n        <v-chip\n          append-icon=\"mdi-arrow-collapse-right\"\n          class=\"px-6 mr-0\"\n          selected-class=\"v-chip--variant-flat\"\n          text=\"end\"\n          value=\"end\"\n          label\n        ></v-chip>\n      </v-chip-group>\n    </v-card-text>\n  </v-card>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const collapse = shallowRef(true)\n  const collapsePosition = shallowRef('start')\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      collapse: false,\n      collapsePosition: 'start',\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-toolbar/prop-dense.vue",
    "content": "<template>\n  <v-card height=\"200\">\n    <v-toolbar density=\"compact\" title=\"Toolbar\"></v-toolbar>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-toolbar/prop-extended.vue",
    "content": "<template>\n  <v-card height=\"200\">\n    <v-toolbar extended>\n      <v-toolbar-title text=\"Toolbar\"></v-toolbar-title>\n\n      <template v-slot:append>\n        <v-btn icon=\"mdi-magnify\"></v-btn>\n\n        <v-btn icon=\"mdi-heart\"></v-btn>\n\n        <v-btn icon=\"mdi-dots-vertical\"></v-btn>\n      </template>\n    </v-toolbar>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-toolbar/prop-extension-height.vue",
    "content": "<template>\n  <v-card height=\"200\">\n    <v-toolbar extension-height=\"100\" title=\"Toolbar\" extended>\n\n      <template v-slot:append>\n        <v-btn icon=\"mdi-magnify\"></v-btn>\n        <v-btn icon=\"mdi-heart\"></v-btn>\n        <v-btn icon=\"mdi-dots-vertical\"></v-btn>\n      </template>\n    </v-toolbar>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-toolbar/prop-floating-with-search.vue",
    "content": "<template>\n  <v-card\n    height=\"300\"\n    image=\"https://cdn.vuetifyjs.com/images/toolbar/map.jpg\"\n    border\n    flat\n  >\n    <template v-slot:text>\n      <v-toolbar rounded=\"lg\" border floating>\n        <div class=\"px-4\">\n          <v-text-field\n            density=\"compact\"\n            placeholder=\"Search\"\n            prepend-inner-icon=\"mdi-magnify\"\n            variant=\"solo\"\n            width=\"200\"\n            flat\n            hide-details\n            single-line\n          ></v-text-field>\n        </div>\n\n        <template v-slot:append>\n          <v-btn\n            color=\"medium-emphasis\"\n            density=\"comfortable\"\n            icon=\"mdi-crosshairs-gps\"\n          ></v-btn>\n\n          <v-btn\n            class=\"ms-1\"\n            color=\"medium-emphasis\"\n            density=\"comfortable\"\n            icon=\"mdi-dots-vertical\"\n          ></v-btn>\n        </template>\n      </v-toolbar>\n    </template>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-toolbar/prop-location.vue",
    "content": "<template>\n  <v-container class=\"position-relative\" min-height=\"150\">\n    <v-toolbar\n      color=\"primary\"\n      density=\"compact\"\n      location=\"top left\"\n      title=\"Application\"\n      absolute\n      floating\n      rounded\n    >\n      <template v-slot:prepend>\n        <v-btn icon=\"mdi-menu\"></v-btn>\n      </template>\n\n      <template v-slot:append>\n        <v-btn icon=\"mdi-magnify\"></v-btn>\n        <v-btn icon=\"mdi-heart\"></v-btn>\n      </template>\n    </v-toolbar>\n\n    <v-toolbar\n      color=\"secondary\"\n      density=\"compact\"\n      location=\"top end\"\n      absolute\n      floating\n      rounded\n    >\n      <template v-slot:prepend>\n        <v-btn icon=\"mdi-bell\"></v-btn>\n      </template>\n\n      <template v-slot:append>\n        <v-btn icon=\"mdi-account\"></v-btn>\n        <v-btn icon=\"mdi-cog\"></v-btn>\n      </template>\n    </v-toolbar>\n\n    <v-toolbar\n      class=\"mb-2\"\n      color=\"surface\"\n      density=\"compact\"\n      location=\"bottom center\"\n      rounded=\"pill\"\n      absolute\n      floating\n    >\n      <template v-slot:prepend>\n        <v-btn icon=\"mdi-skip-previous\"></v-btn>\n        <v-btn icon=\"mdi-play\"></v-btn>\n        <v-btn icon=\"mdi-skip-next\"></v-btn>\n      </template>\n\n      <v-slider class=\"mx-6\" min-width=\"100\" hide-details></v-slider>\n\n      <template v-slot:append>\n        <v-btn icon=\"mdi-volume-high\"></v-btn>\n      </template>\n    </v-toolbar>\n  </v-container>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-toolbar/slot-extension.vue",
    "content": "<template>\n  <v-card height=\"200\">\n    <v-toolbar extended>\n      <v-toolbar-title text=\"Toolbar\"></v-toolbar-title>\n\n      <template v-slot:extension>\n        <v-tabs>\n          <v-tab text=\"Tab 1\"></v-tab>\n          <v-tab text=\"Tab 2\"></v-tab>\n          <v-tab text=\"Tab 3\"></v-tab>\n        </v-tabs>\n      </template>\n    </v-toolbar>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-toolbar/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div>\n      <v-toolbar v-bind=\"props\">\n        <template v-slot:append>\n          <v-btn icon=\"mdi-menu\"></v-btn>\n\n          <v-btn icon=\"mdi-dots-vertical\"></v-btn>\n        </template>\n      </v-toolbar>\n    </div>\n\n    <template v-slot:configuration>\n      <v-select v-model=\"density\" :items=\"['default', 'comfortable', 'compact']\" label=\"Density\"></v-select>\n\n      <v-text-field v-model=\"title\" label=\"Title\" clearable></v-text-field>\n\n      <v-checkbox v-model=\"collapse\" label=\"Collapsed\"></v-checkbox>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-toolbar'\n  const model = ref('default')\n  const collapse = ref()\n  const density = ref('default')\n  const title = ref('Toolbar')\n  const options = ['elevated', 'bordered']\n  const props = computed(() => {\n    return {\n      border: model.value === 'bordered' ? true : undefined,\n      collapse: collapse.value || undefined,\n      density: density.value === 'default' ? undefined : density.value,\n      elevation: model.value === 'elevated' ? 3 : undefined,\n      title: title.value || undefined,\n    }\n  })\n\n  const slots = computed(() => {\n    return ``\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-tooltip/misc-at-cursor.vue",
    "content": "<template>\n  <div class=\"d-flex justify-center\" @mouseout=\"tooltipVisible = false\">\n    <v-tooltip v-model=\"tooltipVisible\" :open-on-hover=\"false\" target=\"cursor\" open-on-click>\n      <template v-slot:activator=\"{ props: activatorProps }\">\n        <v-card\n          v-bind=\"activatorProps\"\n          height=\"300\"\n          image=\"https://picsum.photos/600/300\"\n          width=\"600\"\n        ></v-card>\n      </template>\n      <span>I will appear at cursor</span>\n    </v-tooltip>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const tooltipVisible = ref(false)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      tooltipVisible: false,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-tooltip/prop-color.vue",
    "content": "<template>\n  <div class=\"text-center d-flex align-center justify-space-around\">\n    <v-tooltip color=\"primary\" location=\"bottom\">\n      <template v-slot:activator=\"{ props }\">\n        <v-btn\n          color=\"primary\"\n          v-bind=\"props\"\n        >\n          primary\n        </v-btn>\n      </template>\n      <span>Primary tooltip</span>\n    </v-tooltip>\n\n    <v-tooltip color=\"success\" location=\"bottom\">\n      <template v-slot:activator=\"{ props }\">\n        <v-btn\n          color=\"success\"\n          v-bind=\"props\"\n        >\n          success\n        </v-btn>\n      </template>\n      <span>Success tooltip</span>\n    </v-tooltip>\n\n    <v-tooltip color=\"warning\" location=\"bottom\">\n      <template v-slot:activator=\"{ props }\">\n        <v-btn\n          color=\"warning\"\n          v-bind=\"props\"\n        >\n          warning\n        </v-btn>\n      </template>\n      <span>Warning tooltip</span>\n    </v-tooltip>\n\n    <v-tooltip color=\"error\" location=\"bottom\">\n      <template v-slot:activator=\"{ props }\">\n        <v-btn\n          color=\"error\"\n          v-bind=\"props\"\n        >\n          error\n        </v-btn>\n      </template>\n      <span>Error tooltip</span>\n    </v-tooltip>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-tooltip/prop-interactive.vue",
    "content": "<template>\n  <div class=\"d-flex justify-center\">\n    <v-tooltip interactive>\n      <template v-slot:activator=\"{ props: activatorProps }\">\n        <v-icon-btn icon=\"mdi-information-outline\" v-bind=\"activatorProps\"></v-icon-btn>\n      </template>\n      <div>\n        <a class=\"text-primary font-weight-medium\" href=\"/blog/announcing-vuetify-3.8/#vtooltip-interactive\">\n          Learn more\n        </a>\n        about interactive tooltip.\n      </div>\n    </v-tooltip>\n  </div>\n</template>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=1902-32416&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-tooltip/prop-location.vue",
    "content": "<template>\n  <div class=\"d-flex justify-space-around\">\n    <v-btn>\n      Start\n      <v-tooltip\n        activator=\"parent\"\n        location=\"start\"\n      >Tooltip</v-tooltip>\n    </v-btn>\n\n    <v-btn>\n      End\n      <v-tooltip\n        activator=\"parent\"\n        location=\"end\"\n      >Tooltip</v-tooltip>\n    </v-btn>\n\n    <v-btn>\n      Top\n      <v-tooltip\n        activator=\"parent\"\n        location=\"top\"\n      >Tooltip</v-tooltip>\n    </v-btn>\n\n    <v-btn>\n      Bottom\n      <v-tooltip\n        activator=\"parent\"\n        location=\"bottom\"\n      >Tooltip</v-tooltip>\n    </v-btn>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-tooltip/prop-open-on-click.vue",
    "content": "<template>\n  <div class=\"text-center\">\n    <v-tooltip :open-on-hover=\"false\" open-on-click>\n      <template v-slot:activator=\"{ props }\">\n        <v-btn v-bind=\"props\">Click me</v-btn>\n      </template>\n      <span>Open on click tooltip</span>\n    </v-tooltip>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-tooltip/prop-visibility.vue",
    "content": "<template>\n  <v-container\n    class=\"text-center\"\n    fluid\n  >\n    <v-row class=\"flex justify-space-between\">\n      <v-col cols=\"12\">\n        <v-btn @click=\"show = !show\">\n          toggle\n        </v-btn>\n      </v-col>\n\n      <v-col\n        class=\"mt-12\"\n        cols=\"12\"\n      >\n        <v-tooltip\n          v-model=\"show\"\n          location=\"top\"\n        >\n          <template v-slot:activator=\"{ props }\">\n            <v-btn\n              icon\n              v-bind=\"props\"\n            >\n              <v-icon color=\"grey-lighten-1\">\n                mdi-cart\n              </v-icon>\n            </v-btn>\n          </template>\n          <span>Programmatic tooltip</span>\n        </v-tooltip>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const show = ref(false)\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        show: false,\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-tooltip/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div class=\"text-center\">\n      <v-tooltip v-bind=\"props\">\n        <template v-slot:activator=\"{ props: activatorProps }\">\n          <v-btn v-bind=\"activatorProps\">Hover Over Me</v-btn>\n        </template>\n\n        {{ text }}\n      </v-tooltip>\n    </div>\n\n    <template v-slot:configuration>\n      <v-text-field v-model=\"text\" label=\"Text\"></v-text-field>\n\n      <v-checkbox v-model=\"active\" label=\"Always show\"></v-checkbox>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-tooltip'\n  const model = ref('default')\n  const text = ref('Tooltip')\n  const active = ref()\n  const options = []\n  const props = computed(() => {\n    const props = {\n      text: text.value || undefined,\n    }\n\n    if (active.value) {\n      props['model-value'] = true\n      props['onUpdate:model-value'] = true\n    }\n\n    return props\n  })\n\n  const slots = computed(() => {\n    return `\n  <template v-slot:activator=\"{ props }\">\n    <v-btn v-bind=\"props\">Hover Over Me</v-btn>\n  </template>\n`\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-tooltip-directive/args.vue",
    "content": "<template>\n  <div class=\"d-flex justify-center ga-4 py-10\">\n    <v-btn v-tooltip:start=\"'Tooltip at the start'\">\n      Start\n    </v-btn>\n\n    <v-btn v-tooltip:end=\"'Tooltip at the end'\">\n      End\n    </v-btn>\n\n    <v-btn v-tooltip:top=\"'Tooltip at the top'\">\n      Top\n    </v-btn>\n\n    <v-btn v-tooltip:bottom=\"'Tooltip at the bottom'\">\n      Bottom\n    </v-btn>\n\n    <v-btn v-tooltip:bottom-end=\"'Tooltip at the bottom end'\">\n      Bottom end\n    </v-btn>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-tooltip-directive/object-literals.vue",
    "content": "<template>\n  <div class=\"text-center py-10\">\n    <v-btn text=\"Click me\" v-tooltip=\"tooltip\"></v-btn>\n  </div>\n</template>\n\n<script setup>\n  const tooltip = {\n    text: 'Scroll up ↑',\n    scrollStrategy: 'close',\n    scrim: true,\n    persistent: false,\n    openOnClick: true,\n    openOnHover: false,\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      tooltip: {\n        text: 'Scroll up ↑',\n        scrollStrategy: 'close',\n        scrim: true,\n        persistent: false,\n        openOnClick: true,\n        openOnHover: false,\n      },\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-tooltip-directive/text.vue",
    "content": "<template>\n  <div class=\"d-flex justify-center ga-4 py-10\">\n    <v-btn v-tooltip>\n      From activator\n    </v-btn>\n\n    <v-btn v-tooltip=\"'Custom text'\">\n      From value\n    </v-btn>\n\n    <v-btn v-tooltip=\"{ text: 'Custom text' }\">\n      From props\n    </v-btn>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-tooltip-directive/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div class=\"text-center\">\n      <v-btn :key=\"text\" text=\"Tooltip\" v-tooltip=\"text\"></v-btn>\n    </div>\n\n    <template v-slot:configuration>\n      <v-text-field v-model=\"text\" label=\"Text\"></v-text-field>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-tooltip'\n  const model = ref('default')\n  const text = ref('Tooltip')\n  const options = []\n\n  const code = computed(() => {\n    return `<v-btn v-tooltip=\"'${text.value}'\"></v-btn>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-touch/usage.vue",
    "content": "<template>\n  <v-row\n    class=\"bg-grey-lighten-2 align-center justify-center\"\n    style=\"height: 500px\"\n    v-touch=\"{\n      left: () => swipe('Left'),\n      right: () => swipe('Right'),\n      up: () => swipe('Up'),\n      down: () => swipe('Down')\n    }\"\n  >\n    <v-col class=\"text-center\">\n      <div class=\"text-title-small\">Swipe Direction</div>\n      {{ swipeDirection }}\n    </v-col>\n  </v-row>\n</template>\n\n<script>\n  export default {\n    data: () => ({\n      swipeDirection: 'None',\n    }),\n\n    methods: {\n      swipe (direction) {\n        this.swipeDirection = direction\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-treeview/misc-indent-lines.vue",
    "content": "<template>\n  <div>\n    <v-sheet class=\"px-6 py-2 border-b\" color=\"surface\">\n      <div class=\"d-flex gx-3 flex-wrap\">\n        <div class=\"d-flex align-center ga-3\">\n          <span class=\"mr-3\">Lines:</span>\n          <v-chip-group v-model=\"indentLines\">\n            <v-chip :value=\"false\" text=\"none\" filter label></v-chip>\n            <v-chip :value=\"true\" text=\"default\" filter label></v-chip>\n            <v-chip text=\"simple\" value=\"simple\" filter label></v-chip>\n          </v-chip-group>\n        </div>\n        <v-spacer></v-spacer>\n        <div class=\"d-flex align-center ga-6 text-no-wrap\">\n          <v-switch\n            v-model=\"actionIcons\"\n            color=\"success\"\n            density=\"comfortable\"\n            label=\"action icons\"\n            hide-details\n          ></v-switch>\n          <v-switch\n            v-model=\"prependIcons\"\n            color=\"success\"\n            density=\"comfortable\"\n            label=\"prepend icons\"\n            hide-details\n          ></v-switch>\n          <v-switch\n            v-model=\"separateRoots\"\n            :disabled=\"indentLines !== true\"\n            color=\"success\"\n            density=\"comfortable\"\n            label=\"separate roots\"\n            hide-details\n          ></v-switch>\n        </div>\n      </div>\n    </v-sheet>\n    <v-container class=\"d-flex ga-8 justify-center flex-wrap\" fluid>\n\n      <v-sheet width=\"400\">\n        <v-treeview\n          :hide-actions=\"!actionIcons\"\n          :indent-lines=\"indentLines\"\n          :items=\"items1\"\n          :separate-roots=\"separateRoots\"\n          density=\"compact\"\n          item-value=\"id\"\n          max-width=\"400\"\n          open-all\n          open-on-click\n        >\n          <template v-if=\"prependIcons\" v-slot:prepend=\"{ item, isOpen }\">\n            <v-icon :icon=\"getIcon(item, isOpen)\"></v-icon>\n          </template>\n        </v-treeview>\n      </v-sheet>\n\n      <v-sheet width=\"400\">\n        <v-treeview\n          :hide-actions=\"!actionIcons\"\n          :indent-lines=\"indentLines\"\n          :items=\"items2\"\n          :separate-roots=\"separateRoots\"\n          density=\"compact\"\n          item-value=\"id\"\n          open-all\n          open-on-click\n        >\n          <template v-if=\"prependIcons\" v-slot:prepend=\"{ item, isOpen }\">\n            <v-icon :icon=\"getIcon(item, isOpen)\"></v-icon>\n          </template>\n        </v-treeview>\n      </v-sheet>\n    </v-container>\n  </div>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const separateRoots = shallowRef(false)\n  const actionIcons = shallowRef(true)\n  const prependIcons = shallowRef(true)\n  const indentLines = shallowRef(true)\n\n  const files = {\n    html: 'mdi-language-html5',\n    js: 'mdi-nodejs',\n    pdf: 'mdi-file-pdf-box',\n    png: 'mdi-file-image',\n    mov: 'mdi-video-outline',\n    mp4: 'mdi-video-outline',\n  }\n\n  function getIcon (item, isOpen) {\n    if (item.children) return isOpen ? 'mdi-folder-open' : 'mdi-folder'\n    return files[item.title.split('.').at(-1)] ?? 'mdi-file-outline'\n  }\n\n  const items1 = [\n    {\n      id: 5,\n      title: 'Documents',\n      children: [\n        {\n          id: 6,\n          title: 'vuetify',\n          children: [\n            {\n              id: 7,\n              title: 'src',\n              children: [{ id: 8, title: 'index.js' }],\n            },\n          ],\n        },\n        {\n          id: 101,\n          title: 'material1',\n          children: [\n            {\n              id: 111,\n              title: 'src',\n              children: [\n                { id: 112, title: 'v-chip.js' },\n                { id: 113, title: 'v-slider.js' },\n              ],\n            },\n          ],\n        },\n        {\n          id: 10,\n          title: 'material2',\n          children: [\n            {\n              id: 11,\n              title: 'src',\n              children: [\n                { id: 12, title: 'v-btn.js' },\n                { id: 13, title: 'v-card.js' },\n                { id: 14, title: 'v-window.js' },\n              ],\n            },\n          ],\n        },\n      ],\n    },\n  ]\n\n  const items2 = [\n    {\n      id: 115,\n      title: 'Documents',\n      children: [\n        {\n          id: 116,\n          title: 'Financial',\n          children: [\n            { id: 17, title: 'November.pdf' },\n          ],\n        },\n        {\n          id: 117,\n          title: 'Taxes',\n          children: [\n            { id: 118, title: 'December.pdf' },\n            { id: 119, title: 'January.pdf' },\n          ],\n        },\n        {\n          id: 120,\n          title: 'Later',\n          children: [\n            { id: 121, title: 'Company logo.png' },\n          ],\n        },\n      ],\n    },\n    {\n      id: 15,\n      title: 'Downloads',\n      children: [\n        { id: 16, title: '2022-03-01 Report.pdf' },\n        { id: 18, title: 'Tutorial.html' },\n      ],\n    },\n    {\n      id: 19,\n      title: 'Videos',\n      children: [\n        {\n          id: 20,\n          title: 'Tutorials',\n          children: [\n            { id: 21, title: 'Basic layouts.mp4' },\n            { id: 23, title: 'Empty folder', children: [] },\n            { id: 22, title: 'Advanced techniques.mp4' },\n          ],\n        },\n        { id: 24, title: 'Intro.mov' },\n        { id: 25, title: 'Conference introduction.mov' },\n      ],\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      separateRoots: false,\n      actionIcons: true,\n      prependIcons: true,\n      files: {\n        html: 'mdi-language-html5',\n        js: 'mdi-nodejs',\n        pdf: 'mdi-file-pdf-box',\n        png: 'mdi-file-image',\n        mov: 'mdi-file-video-outline',\n        mp4: 'mdi-video-outline',\n      },\n      items1: [\n        {\n          id: 5,\n          title: 'Documents',\n          children: [\n            {\n              id: 6,\n              title: 'vuetify',\n              children: [\n                {\n                  id: 7,\n                  title: 'src',\n                  children: [{ id: 8, title: 'index.js' }],\n                },\n              ],\n            },\n            {\n              id: 101,\n              title: 'material1',\n              children: [\n                {\n                  id: 111,\n                  title: 'src',\n                  children: [\n                    { id: 112, title: 'v-chip.js' },\n                    { id: 113, title: 'v-slider.js' },\n                  ],\n                },\n              ],\n            },\n            {\n              id: 10,\n              title: 'material2',\n              children: [\n                {\n                  id: 11,\n                  title: 'src',\n                  children: [\n                    { id: 12, title: 'v-btn.js' },\n                    { id: 13, title: 'v-card.js' },\n                    { id: 14, title: 'v-window.js' },\n                  ],\n                },\n              ],\n            },\n          ],\n        },\n      ],\n      items2: [\n        {\n          id: 115,\n          title: 'Documents',\n          children: [\n            {\n              id: 116,\n              title: 'Financial',\n              children: [\n                { id: 17, title: 'November.pdf' },\n              ],\n            },\n            {\n              id: 117,\n              title: 'Taxes',\n              children: [\n                { id: 118, title: 'December.pdf' },\n                { id: 119, title: 'January.pdf' },\n              ],\n            },\n            {\n              id: 120,\n              title: 'Later',\n              children: [\n                { id: 121, title: 'Company logo.png' },\n              ],\n            },\n          ],\n        },\n        {\n          id: 15,\n          title: 'Downloads',\n          children: [\n            { id: 16, title: '2022-03-01 Report.pdf' },\n            { id: 18, title: 'Tutorial.html' },\n          ],\n        },\n        {\n          id: 19,\n          title: 'Videos',\n          children: [\n            {\n              id: 20,\n              title: 'Tutorials',\n              children: [\n                { id: 21, title: 'Basic layouts.mp4' },\n                { id: 23, title: 'Empty folder', children: [] },\n                { id: 22, title: 'Advanced techniques.mp4' },\n              ],\n            },\n            { id: 24, title: 'Intro.mov' },\n            { id: 25, title: 'Conference introduction.mov' },\n          ],\n        },\n      ],\n    }),\n    methods: {\n      getIcon (item, isOpen) {\n        if (item.children) return isOpen ? 'mdi-folder-open' : 'mdi-folder'\n        return this.files[item.title.split('.').at(-1)] ?? 'mdi-file-outline'\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-treeview/misc-search-and-filter.vue",
    "content": "<template>\n  <v-card class=\"mx-auto\" max-width=\"500\">\n    <v-sheet class=\"pa-4\" color=\"surface-variant\">\n      <v-text-field\n        v-model=\"search\"\n        clear-icon=\"mdi-close-circle-outline\"\n        label=\"Search Company Directory\"\n        variant=\"solo\"\n        clearable\n        flat\n        hide-details\n      ></v-text-field>\n\n      <v-checkbox-btn\n        v-model=\"caseSensitive\"\n        label=\"Case sensitive search\"\n      ></v-checkbox-btn>\n    </v-sheet>\n\n    <v-treeview\n      v-model:opened=\"open\"\n      :custom-filter=\"filter\"\n      :items=\"items\"\n      :search=\"search\"\n      item-value=\"id\"\n      open-on-click\n    >\n      <template v-slot:prepend=\"{ item }\">\n        <v-icon\n          v-if=\"item.children\"\n          :icon=\"`mdi-${item.id === 1 ? 'home-variant' : 'folder-network'}`\"\n        ></v-icon>\n      </template>\n    </v-treeview>\n  </v-card>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const items = [\n    {\n      id: 1,\n      title: 'Vuetify Human Resources',\n      children: [\n        {\n          id: 2,\n          title: 'Core team',\n          children: [\n            {\n              id: 201,\n              title: 'John',\n            },\n            {\n              id: 202,\n              title: 'Kael',\n            },\n            {\n              id: 203,\n              title: 'Nekosaur',\n            },\n            {\n              id: 204,\n              title: 'Jacek',\n            },\n            {\n              id: 205,\n              title: 'Andrew',\n            },\n          ],\n        },\n        {\n          id: 3,\n          title: 'Administrators',\n          children: [\n            {\n              id: 301,\n              title: 'Blaine',\n            },\n            {\n              id: 302,\n              title: 'Yuchao',\n            },\n          ],\n        },\n        {\n          id: 4,\n          title: 'Contributors',\n          children: [\n            {\n              id: 401,\n              title: 'Phlow',\n            },\n            {\n              id: 402,\n              title: 'Brandon',\n            },\n            {\n              id: 403,\n              title: 'Sean',\n            },\n          ],\n        },\n      ],\n    },\n  ]\n\n  const open = shallowRef([1, 2])\n  const search = shallowRef(null)\n  const caseSensitive = shallowRef(false)\n\n  function filter (value, search, item) {\n    return caseSensitive.value ? value.indexOf(search) > -1 : value.toLowerCase().indexOf(search.toLowerCase()) > -1\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        {\n          id: 1,\n          title: 'Vuetify Human Resources',\n          children: [\n            {\n              id: 2,\n              title: 'Core team',\n              children: [\n                { id: 201, title: 'John' },\n                { id: 202, title: 'Kael' },\n                { id: 203, title: 'Nekosaur' },\n                { id: 204, title: 'Jacek' },\n                { id: 205, title: 'Andrew' },\n              ],\n            },\n            {\n              id: 3,\n              title: 'Administrators',\n              children: [\n                { id: 301, title: 'Blaine' },\n                { id: 302, title: 'Yuchao' },\n              ],\n            },\n            {\n              id: 4,\n              title: 'Contributors',\n              children: [\n                { id: 401, title: 'Phlow' },\n                { id: 402, title: 'Brandon' },\n                { id: 403, title: 'Sean' },\n              ],\n            },\n          ],\n        },\n      ],\n      open: [1, 2],\n      search: null,\n      caseSensitive: false,\n    }),\n\n    methods: {\n      filter (value, search, item) {\n        return this.caseSensitive ? value.indexOf(search) > -1 : value.toLowerCase().indexOf(search.toLowerCase()) > -1\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-treeview/misc-selectable-icons.vue",
    "content": "<template>\n  <v-card>\n    <v-toolbar\n      color=\"surface-light\"\n      density=\"compact\"\n      title=\"Local hotspots\"\n      flat\n    ></v-toolbar>\n\n    <v-row density=\"comfortable\">\n      <v-col class=\"d-flex align-center\" cols=\"12\" sm=\"6\">\n        <v-treeview\n          v-model:selected=\"tree\"\n          :items=\"items\"\n          :load-children=\"load\"\n          class=\"flex-1-0\"\n          false-icon=\"mdi-bookmark-outline\"\n          indeterminate-icon=\"mdi-bookmark-minus\"\n          item-title=\"name\"\n          item-value=\"id\"\n          select-strategy=\"classic\"\n          true-icon=\"mdi-bookmark\"\n          return-object\n          selectable\n        ></v-treeview>\n      </v-col>\n\n      <v-divider :vertical=\"$vuetify.display.mdAndUp\" class=\"my-md-3\"></v-divider>\n\n      <v-col cols=\"12\" sm=\"6\">\n        <v-card-text>\n          <div\n            v-if=\"tree.length === 0\"\n            class=\"text-title-large font-weight-light text-grey pa-4 text-center\"\n          >\n            Select your favorite breweries\n          </div>\n\n          <div class=\"d-flex flex-wrap ga-1\">\n            <v-scroll-x-transition group hide-on-leave>\n              <v-chip\n                v-for=\"selection in tree\"\n                :key=\"selection.id\"\n                :prepend-icon=\"getIcon()\"\n                :text=\"selection.name\"\n                color=\"grey\"\n                size=\"small\"\n                border\n                closable\n                label\n                @click:close=\"onClickClose(selection)\"\n              ></v-chip>\n            </v-scroll-x-transition>\n          </div>\n        </v-card-text>\n      </v-col>\n    </v-row>\n\n    <v-divider></v-divider>\n\n    <template v-slot:actions>\n      <v-btn\n        text=\"Reset\"\n        @click=\"tree = []\"\n      ></v-btn>\n\n      <v-spacer></v-spacer>\n\n      <v-btn\n        append-icon=\"mdi-content-save\"\n        color=\"surface-light\"\n        text=\"Save\"\n        variant=\"flat\"\n        border\n      ></v-btn>\n    </template>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref, watch } from 'vue'\n\n  const icons = [\n    'mdi-beer',\n    'mdi-glass-mug',\n    'mdi-liquor',\n    'mdi-glass-mug-variant',\n  ]\n\n  const breweries = ref([])\n  const tree = ref([])\n  const types = ref([])\n  const items = ref([{\n    id: 1,\n    name: 'All Breweries',\n    children: [],\n  }])\n\n  watch(breweries, val => {\n    types.value = val.reduce((acc, cur) => {\n      const type = cur.brewery_type\n      if (!acc.includes(type)) acc.push(type)\n      return acc\n    }, []).sort()\n\n    const children = types.value.map(type => ({\n      id: type,\n      name: getName(type),\n      children: getChildren(type),\n    }))\n    const rootObj = items.value[0]\n    rootObj.children = children\n    items.value = [rootObj]\n  })\n\n  function load () {\n    if (breweries.value.length) return\n\n    return fetch('https://api.openbrewerydb.org/v1/breweries').then(res => res.json()).then(data => (breweries.value = data)).catch(err => console.log(err))\n  }\n\n  function getChildren (type) {\n    const _breweries = []\n    for (const brewery of breweries.value) {\n      if (brewery.brewery_type !== type) continue\n      _breweries.push({\n        ...brewery,\n        name: getName(brewery.name),\n      })\n    }\n    return _breweries.sort((a, b) => {\n      return a.name > b.name ? 1 : -1\n    })\n  }\n\n  function getIcon () {\n    return icons[Math.floor(Math.random() * icons.length)]\n  }\n\n  function getName (name) {\n    return `${name.charAt(0).toUpperCase()}${name.slice(1)}`\n  }\n\n  function onClickClose (selection) {\n    tree.value = tree.value.filter(item => item.id !== selection.id)\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-treeview/playground.vue",
    "content": "<template>\n  <div>\n    <v-row class=\"justify-space-around\">\n      <v-switch\n        v-model=\"dense\"\n        label=\"Dense\"\n      ></v-switch>\n      <v-switch\n        v-model=\"selectable\"\n        label=\"Selectable\"\n      ></v-switch>\n      <v-switch\n        v-model=\"activatable\"\n        label=\"Activatable\"\n      ></v-switch>\n      <v-switch\n        v-model=\"hoverable\"\n        label=\"Hoverable\"\n      ></v-switch>\n      <v-switch\n        v-model=\"shaped\"\n        label=\"Shaped\"\n      ></v-switch>\n      <v-switch\n        v-model=\"rounded\"\n        label=\"Rounded\"\n      ></v-switch>\n      <v-switch\n        v-model=\"openOnClick\"\n        label=\"Open on any item click\"\n      ></v-switch>\n      <v-col cols=\"12\">\n        <v-select\n          v-model=\"selectedColor\"\n          :disabled=\"!selectable\"\n          :items=\"selectedColors\"\n          label=\"Selected checkbox color\"\n        ></v-select>\n      </v-col>\n      <v-col cols=\"12\">\n        <v-select\n          v-model=\"color\"\n          :disabled=\"!activatable\"\n          :items=\"selectedColors\"\n          label=\"Active node color\"\n        ></v-select>\n      </v-col>\n    </v-row>\n\n    <v-treeview\n      :activatable=\"activatable\"\n      :color=\"color\"\n      :dense=\"dense\"\n      :hoverable=\"hoverable\"\n      :items=\"items\"\n      :open-on-click=\"openOnClick\"\n      :rounded=\"rounded\"\n      :selectable=\"selectable\"\n      :selected-color=\"selectedColor\"\n      :shaped=\"shaped\"\n      item-title=\"name\"\n      item-value=\"id\"\n    ></v-treeview>\n  </div>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const items = ref([\n    {\n      id: 1,\n      name: 'Applications :',\n      children: [\n        { id: 2, name: 'Calendar : app' },\n        { id: 3, name: 'Chrome : app' },\n        { id: 4, name: 'Webstorm : app' },\n      ],\n    },\n    {\n      id: 5,\n      name: 'Documents :',\n      children: [\n        {\n          id: 6,\n          name: 'vuetify :',\n          children: [\n            {\n              id: 7,\n              name: 'src :',\n              children: [\n                { id: 8, name: 'index : ts' },\n                { id: 9, name: 'bootstrap : ts' },\n              ],\n            },\n          ],\n        },\n        {\n          id: 10,\n          name: 'material2 :',\n          children: [\n            {\n              id: 11,\n              name: 'src :',\n              children: [\n                { id: 12, name: 'v-btn : ts' },\n                { id: 13, name: 'v-card : ts' },\n                { id: 14, name: 'v-window : ts' },\n              ],\n            },\n          ],\n        },\n      ],\n    },\n    {\n      id: 15,\n      name: 'Downloads :',\n      children: [\n        { id: 16, name: 'October : pdf' },\n        { id: 17, name: 'November : pdf' },\n        { id: 18, name: 'Tutorial : html' },\n      ],\n    },\n    {\n      id: 19,\n      name: 'Videos :',\n      children: [\n        {\n          id: 20,\n          name: 'Tutorials :',\n          children: [\n            { id: 21, name: 'Basic layouts : mp4' },\n            { id: 22, name: 'Advanced techniques : mp4' },\n            { id: 23, name: 'All about app : dir' },\n          ],\n        },\n        { id: 24, name: 'Intro : mov' },\n        { id: 25, name: 'Conference introduction : avi' },\n      ],\n    },\n  ])\n  const dense = ref(false)\n  const selectable = ref(false)\n  const activatable = ref(false)\n  const hoverable = ref(false)\n  const openOnClick = ref(false)\n  const shaped = ref(false)\n  const rounded = ref(false)\n  const color = ref('primary')\n  const selectedColor = ref('accent')\n  const selectedColors = ref([\n    'accent',\n    'teal',\n    'red',\n    'success',\n    'warning lighten-2',\n  ])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        {\n          id: 1,\n          name: 'Applications :',\n          children: [\n            { id: 2, name: 'Calendar : app' },\n            { id: 3, name: 'Chrome : app' },\n            { id: 4, name: 'Webstorm : app' },\n          ],\n        },\n        {\n          id: 5,\n          name: 'Documents :',\n          children: [\n            {\n              id: 6,\n              name: 'vuetify :',\n              children: [\n                {\n                  id: 7,\n                  name: 'src :',\n                  children: [\n                    { id: 8, name: 'index : ts' },\n                    { id: 9, name: 'bootstrap : ts' },\n                  ],\n                },\n              ],\n            },\n            {\n              id: 10,\n              name: 'material2 :',\n              children: [\n                {\n                  id: 11,\n                  name: 'src :',\n                  children: [\n                    { id: 12, name: 'v-btn : ts' },\n                    { id: 13, name: 'v-card : ts' },\n                    { id: 14, name: 'v-window : ts' },\n                  ],\n                },\n              ],\n            },\n          ],\n        },\n        {\n          id: 15,\n          name: 'Downloads :',\n          children: [\n            { id: 16, name: 'October : pdf' },\n            { id: 17, name: 'November : pdf' },\n            { id: 18, name: 'Tutorial : html' },\n          ],\n        },\n        {\n          id: 19,\n          name: 'Videos :',\n          children: [\n            {\n              id: 20,\n              name: 'Tutorials :',\n              children: [\n                { id: 21, name: 'Basic layouts : mp4' },\n                { id: 22, name: 'Advanced techniques : mp4' },\n                { id: 23, name: 'All about app : dir' },\n              ],\n            },\n            { id: 24, name: 'Intro : mov' },\n            { id: 25, name: 'Conference introduction : avi' },\n          ],\n        },\n      ],\n      dense: false,\n      selectable: false,\n      activatable: false,\n      hoverable: false,\n      openOnClick: false,\n      shaped: false,\n      rounded: false,\n      color: 'primary',\n      selectedColor: 'accent',\n      selectedColors: [\n        'accent',\n        'teal',\n        'red',\n        'success',\n        'warning lighten-2',\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-treeview/prop-activatable.vue",
    "content": "<template>\n  <v-treeview\n    :items=\"items\"\n    item-value=\"id\"\n    activatable\n  ></v-treeview>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const items = ref([\n    {\n      id: 1,\n      title: 'Applications :',\n      children: [\n        { id: 2, title: 'Calendar : app' },\n        { id: 3, title: 'Chrome : app' },\n        { id: 4, title: 'Webstorm : app' },\n      ],\n    },\n    {\n      id: 5,\n      title: 'Documents :',\n      children: [\n        {\n          id: 6,\n          title: 'vuetify :',\n          children: [\n            {\n              id: 7,\n              title: 'src :',\n              children: [\n                { id: 8, title: 'index : ts' },\n                { id: 9, title: 'bootstrap : ts' },\n              ],\n            },\n          ],\n        },\n        {\n          id: 10,\n          title: 'material2 :',\n          children: [\n            {\n              id: 11,\n              title: 'src :',\n              children: [\n                { id: 12, title: 'v-btn : ts' },\n                { id: 13, title: 'v-card : ts' },\n                { id: 14, title: 'v-window : ts' },\n              ],\n            },\n          ],\n        },\n      ],\n    },\n    {\n      id: 15,\n      title: 'Downloads :',\n      children: [\n        { id: 16, title: 'October : pdf' },\n        { id: 17, title: 'November : pdf' },\n        { id: 18, title: 'Tutorial : html' },\n      ],\n    },\n    {\n      id: 19,\n      title: 'Videos :',\n      children: [\n        {\n          id: 20,\n          title: 'Tutorials :',\n          children: [\n            { id: 21, title: 'Basic layouts : mp4' },\n            { id: 22, title: 'Advanced techniques : mp4' },\n            { id: 23, title: 'All about app : dir' },\n          ],\n        },\n        { id: 24, title: 'Intro : mov' },\n        { id: 25, title: 'Conference introduction : avi' },\n      ],\n    },\n  ])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        {\n          id: 1,\n          title: 'Applications :',\n          children: [\n            { id: 2, title: 'Calendar : app' },\n            { id: 3, title: 'Chrome : app' },\n            { id: 4, title: 'Webstorm : app' },\n          ],\n        },\n        {\n          id: 5,\n          title: 'Documents :',\n          children: [\n            {\n              id: 6,\n              title: 'vuetify :',\n              children: [\n                {\n                  id: 7,\n                  title: 'src :',\n                  children: [\n                    { id: 8, title: 'index : ts' },\n                    { id: 9, title: 'bootstrap : ts' },\n                  ],\n                },\n              ],\n            },\n            {\n              id: 10,\n              title: 'material2 :',\n              children: [\n                {\n                  id: 11,\n                  title: 'src :',\n                  children: [\n                    { id: 12, title: 'v-btn : ts' },\n                    { id: 13, title: 'v-card : ts' },\n                    { id: 14, title: 'v-window : ts' },\n                  ],\n                },\n              ],\n            },\n          ],\n        },\n        {\n          id: 15,\n          title: 'Downloads :',\n          children: [\n            { id: 16, title: 'October : pdf' },\n            { id: 17, title: 'November : pdf' },\n            { id: 18, title: 'Tutorial : html' },\n          ],\n        },\n        {\n          id: 19,\n          title: 'Videos :',\n          children: [\n            {\n              id: 20,\n              title: 'Tutorials :',\n              children: [\n                { id: 21, title: 'Basic layouts : mp4' },\n                { id: 22, title: 'Advanced techniques : mp4' },\n                { id: 23, title: 'All about app : dir' },\n              ],\n            },\n            { id: 24, title: 'Intro : mov' },\n            { id: 25, title: 'Conference introduction : avi' },\n          ],\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-treeview/prop-color.vue",
    "content": "<template>\n  <v-treeview\n    :items=\"items\"\n    color=\"warning\"\n    item-value=\"id\"\n    activatable\n  ></v-treeview>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const items = ref([\n    {\n      id: 1,\n      title: 'Applications :',\n      children: [\n        { id: 2, title: 'Calendar : app' },\n        { id: 3, title: 'Chrome : app' },\n        { id: 4, title: 'Webstorm : app' },\n      ],\n    },\n    {\n      id: 5,\n      title: 'Documents :',\n      children: [\n        {\n          id: 6,\n          title: 'vuetify :',\n          children: [\n            {\n              id: 7,\n              title: 'src :',\n              children: [\n                { id: 8, title: 'index : ts' },\n                { id: 9, title: 'bootstrap : ts' },\n              ],\n            },\n          ],\n        },\n        {\n          id: 10,\n          title: 'material2 :',\n          children: [\n            {\n              id: 11,\n              title: 'src :',\n              children: [\n                { id: 12, title: 'v-btn : ts' },\n                { id: 13, title: 'v-card : ts' },\n                { id: 14, title: 'v-window : ts' },\n              ],\n            },\n          ],\n        },\n      ],\n    },\n    {\n      id: 15,\n      title: 'Downloads :',\n      children: [\n        { id: 16, title: 'October : pdf' },\n        { id: 17, title: 'November : pdf' },\n        { id: 18, title: 'Tutorial : html' },\n      ],\n    },\n    {\n      id: 19,\n      title: 'Videos :',\n      children: [\n        {\n          id: 20,\n          title: 'Tutorials :',\n          children: [\n            { id: 21, title: 'Basic layouts : mp4' },\n            { id: 22, title: 'Advanced techniques : mp4' },\n            { id: 23, title: 'All about app : dir' },\n          ],\n        },\n        { id: 24, title: 'Intro : mov' },\n        { id: 25, title: 'Conference introduction : avi' },\n      ],\n    },\n  ])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        {\n          id: 1,\n          title: 'Applications :',\n          children: [\n            { id: 2, title: 'Calendar : app' },\n            { id: 3, title: 'Chrome : app' },\n            { id: 4, title: 'Webstorm : app' },\n          ],\n        },\n        {\n          id: 5,\n          title: 'Documents :',\n          children: [\n            {\n              id: 6,\n              title: 'vuetify :',\n              children: [\n                {\n                  id: 7,\n                  title: 'src :',\n                  children: [\n                    { id: 8, title: 'index : ts' },\n                    { id: 9, title: 'bootstrap : ts' },\n                  ],\n                },\n              ],\n            },\n            {\n              id: 10,\n              title: 'material2 :',\n              children: [\n                {\n                  id: 11,\n                  title: 'src :',\n                  children: [\n                    { id: 12, title: 'v-btn : ts' },\n                    { id: 13, title: 'v-card : ts' },\n                    { id: 14, title: 'v-window : ts' },\n                  ],\n                },\n              ],\n            },\n          ],\n        },\n        {\n          id: 15,\n          title: 'Downloads :',\n          children: [\n            { id: 16, title: 'October : pdf' },\n            { id: 17, title: 'November : pdf' },\n            { id: 18, title: 'Tutorial : html' },\n          ],\n        },\n        {\n          id: 19,\n          title: 'Videos :',\n          children: [\n            {\n              id: 20,\n              title: 'Tutorials :',\n              children: [\n                { id: 21, title: 'Basic layouts : mp4' },\n                { id: 22, title: 'Advanced techniques : mp4' },\n                { id: 23, title: 'All about app : dir' },\n              ],\n            },\n            { id: 24, title: 'Intro : mov' },\n            { id: 25, title: 'Conference introduction : avi' },\n          ],\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-treeview/prop-dense.vue",
    "content": "<template>\n  <v-treeview\n    :items=\"items\"\n    density=\"compact\"\n    item-value=\"id\"\n  ></v-treeview>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const items = ref([\n    {\n      id: 1,\n      title: 'Applications :',\n      children: [\n        { id: 2, title: 'Calendar : app' },\n        { id: 3, title: 'Chrome : app' },\n        { id: 4, title: 'Webstorm : app' },\n      ],\n    },\n    {\n      id: 5,\n      title: 'Documents :',\n      children: [\n        {\n          id: 6,\n          title: 'vuetify :',\n          children: [\n            {\n              id: 7,\n              title: 'src :',\n              children: [\n                { id: 8, title: 'index : ts' },\n                { id: 9, title: 'bootstrap : ts' },\n              ],\n            },\n          ],\n        },\n        {\n          id: 10,\n          title: 'material2 :',\n          children: [\n            {\n              id: 11,\n              title: 'src :',\n              children: [\n                { id: 12, title: 'v-btn : ts' },\n                { id: 13, title: 'v-card : ts' },\n                { id: 14, title: 'v-window : ts' },\n              ],\n            },\n          ],\n        },\n      ],\n    },\n    {\n      id: 15,\n      title: 'Downloads :',\n      children: [\n        { id: 16, title: 'October : pdf' },\n        { id: 17, title: 'November : pdf' },\n        { id: 18, title: 'Tutorial : html' },\n      ],\n    },\n    {\n      id: 19,\n      title: 'Videos :',\n      children: [\n        {\n          id: 20,\n          title: 'Tutorials :',\n          children: [\n            { id: 21, title: 'Basic layouts : mp4' },\n            { id: 22, title: 'Advanced techniques : mp4' },\n            { id: 23, title: 'All about app : dir' },\n          ],\n        },\n        { id: 24, title: 'Intro : mov' },\n        { id: 25, title: 'Conference introduction : avi' },\n      ],\n    },\n  ])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        {\n          id: 1,\n          title: 'Applications :',\n          children: [\n            { id: 2, title: 'Calendar : app' },\n            { id: 3, title: 'Chrome : app' },\n            { id: 4, title: 'Webstorm : app' },\n          ],\n        },\n        {\n          id: 5,\n          title: 'Documents :',\n          children: [\n            {\n              id: 6,\n              title: 'vuetify :',\n              children: [\n                {\n                  id: 7,\n                  title: 'src :',\n                  children: [\n                    { id: 8, title: 'index : ts' },\n                    { id: 9, title: 'bootstrap : ts' },\n                  ],\n                },\n              ],\n            },\n            {\n              id: 10,\n              title: 'material2 :',\n              children: [\n                {\n                  id: 11,\n                  title: 'src :',\n                  children: [\n                    { id: 12, title: 'v-btn : ts' },\n                    { id: 13, title: 'v-card : ts' },\n                    { id: 14, title: 'v-window : ts' },\n                  ],\n                },\n              ],\n            },\n          ],\n        },\n        {\n          id: 15,\n          title: 'Downloads :',\n          children: [\n            { id: 16, title: 'October : pdf' },\n            { id: 17, title: 'November : pdf' },\n            { id: 18, title: 'Tutorial : html' },\n          ],\n        },\n        {\n          id: 19,\n          title: 'Videos :',\n          children: [\n            {\n              id: 20,\n              title: 'Tutorials :',\n              children: [\n                { id: 21, title: 'Basic layouts : mp4' },\n                { id: 22, title: 'Advanced techniques : mp4' },\n                { id: 23, title: 'All about app : dir' },\n              ],\n            },\n            { id: 24, title: 'Intro : mov' },\n            { id: 25, title: 'Conference introduction : avi' },\n          ],\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-treeview/prop-fluid.vue",
    "content": "<template>\n  <v-treeview\n    :items=\"items\"\n    item-value=\"id\"\n    fluid\n  ></v-treeview>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const items = ref([\n    {\n      id: 1,\n      title: 'Applications :',\n      children: [\n        { id: 2, title: 'Calendar : app' },\n        { id: 3, title: 'Chrome : app' },\n        { id: 4, title: 'Webstorm : app' },\n      ],\n    },\n    {\n      id: 5,\n      title: 'Documents :',\n      children: [\n        {\n          id: 6,\n          title: 'vuetify :',\n          children: [\n            {\n              id: 7,\n              title: 'src :',\n              children: [\n                { id: 8, title: 'index : ts' },\n                { id: 9, title: 'bootstrap : ts' },\n              ],\n            },\n          ],\n        },\n        {\n          id: 10,\n          title: 'material2 :',\n          children: [\n            {\n              id: 11,\n              title: 'src :',\n              children: [\n                { id: 12, title: 'v-btn : ts' },\n                { id: 13, title: 'v-card : ts' },\n                { id: 14, title: 'v-window : ts' },\n              ],\n            },\n          ],\n        },\n      ],\n    },\n    {\n      id: 15,\n      title: 'Downloads :',\n      children: [\n        { id: 16, title: 'October : pdf' },\n        { id: 17, title: 'November : pdf' },\n        { id: 18, title: 'Tutorial : html' },\n      ],\n    },\n    {\n      id: 19,\n      title: 'Videos :',\n      children: [\n        {\n          id: 20,\n          title: 'Tutorials :',\n          children: [\n            { id: 21, title: 'Basic layouts : mp4' },\n            { id: 22, title: 'Advanced techniques : mp4' },\n            { id: 23, title: 'All about app : dir' },\n          ],\n        },\n        { id: 24, title: 'Intro : mov' },\n        { id: 25, title: 'Conference introduction : avi' },\n      ],\n    },\n  ])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        {\n          id: 1,\n          title: 'Applications :',\n          children: [\n            { id: 2, title: 'Calendar : app' },\n            { id: 3, title: 'Chrome : app' },\n            { id: 4, title: 'Webstorm : app' },\n          ],\n        },\n        {\n          id: 5,\n          title: 'Documents :',\n          children: [\n            {\n              id: 6,\n              title: 'vuetify :',\n              children: [\n                {\n                  id: 7,\n                  title: 'src :',\n                  children: [\n                    { id: 8, title: 'index : ts' },\n                    { id: 9, title: 'bootstrap : ts' },\n                  ],\n                },\n              ],\n            },\n            {\n              id: 10,\n              title: 'material2 :',\n              children: [\n                {\n                  id: 11,\n                  title: 'src :',\n                  children: [\n                    { id: 12, title: 'v-btn : ts' },\n                    { id: 13, title: 'v-card : ts' },\n                    { id: 14, title: 'v-window : ts' },\n                  ],\n                },\n              ],\n            },\n          ],\n        },\n        {\n          id: 15,\n          title: 'Downloads :',\n          children: [\n            { id: 16, title: 'October : pdf' },\n            { id: 17, title: 'November : pdf' },\n            { id: 18, title: 'Tutorial : html' },\n          ],\n        },\n        {\n          id: 19,\n          title: 'Videos :',\n          children: [\n            {\n              id: 20,\n              title: 'Tutorials :',\n              children: [\n                { id: 21, title: 'Basic layouts : mp4' },\n                { id: 22, title: 'Advanced techniques : mp4' },\n                { id: 23, title: 'All about app : dir' },\n              ],\n            },\n            { id: 24, title: 'Intro : mov' },\n            { id: 25, title: 'Conference introduction : avi' },\n          ],\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-treeview/prop-hoverable.vue",
    "content": "<template>\n  <v-treeview\n    :items=\"items\"\n    item-title=\"name\"\n    item-value=\"id\"\n    hoverable\n  ></v-treeview>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const items = ref([\n    {\n      id: 1,\n      name: 'Applications :',\n      children: [\n        { id: 2, name: 'Calendar : app' },\n        { id: 3, name: 'Chrome : app' },\n        { id: 4, name: 'Webstorm : app' },\n      ],\n    },\n    {\n      id: 5,\n      name: 'Documents :',\n      children: [\n        {\n          id: 6,\n          name: 'vuetify :',\n          children: [\n            {\n              id: 7,\n              name: 'src :',\n              children: [\n                { id: 8, name: 'index : ts' },\n                { id: 9, name: 'bootstrap : ts' },\n              ],\n            },\n          ],\n        },\n        {\n          id: 10,\n          name: 'material2 :',\n          children: [\n            {\n              id: 11,\n              name: 'src :',\n              children: [\n                { id: 12, name: 'v-btn : ts' },\n                { id: 13, name: 'v-card : ts' },\n                { id: 14, name: 'v-window : ts' },\n              ],\n            },\n          ],\n        },\n      ],\n    },\n    {\n      id: 15,\n      name: 'Downloads :',\n      children: [\n        { id: 16, name: 'October : pdf' },\n        { id: 17, name: 'November : pdf' },\n        { id: 18, name: 'Tutorial : html' },\n      ],\n    },\n    {\n      id: 19,\n      name: 'Videos :',\n      children: [\n        {\n          id: 20,\n          name: 'Tutorials :',\n          children: [\n            { id: 21, name: 'Basic layouts : mp4' },\n            { id: 22, name: 'Advanced techniques : mp4' },\n            { id: 23, name: 'All about app : dir' },\n          ],\n        },\n        { id: 24, name: 'Intro : mov' },\n        { id: 25, name: 'Conference introduction : avi' },\n      ],\n    },\n  ])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        {\n          id: 1,\n          name: 'Applications :',\n          children: [\n            { id: 2, name: 'Calendar : app' },\n            { id: 3, name: 'Chrome : app' },\n            { id: 4, name: 'Webstorm : app' },\n          ],\n        },\n        {\n          id: 5,\n          name: 'Documents :',\n          children: [\n            {\n              id: 6,\n              name: 'vuetify :',\n              children: [\n                {\n                  id: 7,\n                  name: 'src :',\n                  children: [\n                    { id: 8, name: 'index : ts' },\n                    { id: 9, name: 'bootstrap : ts' },\n                  ],\n                },\n              ],\n            },\n            {\n              id: 10,\n              name: 'material2 :',\n              children: [\n                {\n                  id: 11,\n                  name: 'src :',\n                  children: [\n                    { id: 12, name: 'v-btn : ts' },\n                    { id: 13, name: 'v-card : ts' },\n                    { id: 14, name: 'v-window : ts' },\n                  ],\n                },\n              ],\n            },\n          ],\n        },\n        {\n          id: 15,\n          name: 'Downloads :',\n          children: [\n            { id: 16, name: 'October : pdf' },\n            { id: 17, name: 'November : pdf' },\n            { id: 18, name: 'Tutorial : html' },\n          ],\n        },\n        {\n          id: 19,\n          name: 'Videos :',\n          children: [\n            {\n              id: 20,\n              name: 'Tutorials :',\n              children: [\n                { id: 21, name: 'Basic layouts : mp4' },\n                { id: 22, name: 'Advanced techniques : mp4' },\n                { id: 23, name: 'All about app : dir' },\n              ],\n            },\n            { id: 24, name: 'Intro : mov' },\n            { id: 25, name: 'Conference introduction : avi' },\n          ],\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-treeview/prop-item-props.vue",
    "content": "<template>\n  <v-treeview\n    :items=\"items\"\n    item-value=\"id\"\n    item-props\n    selectable\n  ></v-treeview>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const items = ref([\n    {\n      id: 1,\n      title: 'Applications :',\n      disabled: true,\n      children: [\n        { id: 2, title: 'Calendar : app' },\n        { id: 3, title: 'Chrome : app' },\n        { id: 4, title: 'Webstorm : app' },\n      ],\n    },\n    {\n      id: 5,\n      title: 'Documents :',\n      children: [\n        {\n          id: 6,\n          title: 'vuetify :',\n          children: [\n            {\n              id: 7,\n              title: 'src :',\n              disabled: true,\n              children: [\n                { id: 8, title: 'index : ts' },\n                { id: 9, title: 'bootstrap : ts' },\n              ],\n            },\n          ],\n        },\n        {\n          id: 10,\n          title: 'material2 :',\n          children: [\n            {\n              id: 11,\n              title: 'src :',\n              children: [\n                { id: 12, title: 'v-btn : ts' },\n                { id: 13, title: 'v-card : ts' },\n                { id: 14, title: 'v-window : ts' },\n              ],\n            },\n          ],\n        },\n      ],\n    },\n    {\n      id: 15,\n      title: 'Downloads :',\n      children: [\n        { id: 16, title: 'October : pdf', disabled: true },\n        { id: 17, title: 'November : pdf', disabled: true },\n        { id: 18, title: 'Tutorial : html', disabled: true },\n      ],\n    },\n    {\n      id: 19,\n      title: 'Videos :',\n      children: [\n        {\n          id: 20,\n          title: 'Tutorials :',\n          children: [\n            { id: 21, title: 'Basic layouts : mp4' },\n            { id: 22, title: 'Advanced techniques : mp4' },\n            { id: 23, title: 'All about app : dir' },\n          ],\n        },\n        { id: 24, title: 'Intro : mov' },\n        { id: 25, title: 'Conference introduction : avi' },\n      ],\n    },\n  ])\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-treeview/prop-items-registration.vue",
    "content": "<template>\n  <v-sheet class=\"overflow-y-auto\" max-height=\"300\">\n    <v-treeview\n      :items=\"items\"\n      items-registration=\"props\"\n      open-on-click\n    ></v-treeview>\n  </v-sheet>\n</template>\n\n<script setup>\n  const items = Array.from({ length: 5 })\n    .map((_, i) => ({\n      id: i,\n      title: `Example item #${i} with 200 children`,\n      children: Array.from({ length: 200 })\n        .map((_, ci) => ({\n          id: `${i}-${ci}`,\n          title: `Example child item #${i}-${ci}`,\n        })),\n    }))\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: Array.from({ length: 100 })\n        .map((_, i) => ({\n          id: i,\n          title: `Example item ${i}`,\n          children: Array.from({ length: 100 })\n            .map((_, ci) => ({\n              id: `${i}-${ci}`,\n              title: `Example child item ${ci}`,\n            })),\n        })),\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-treeview/prop-load-children.vue",
    "content": "<template>\n  <v-container fluid>\n    <v-row class=\"justify-space-between\" density=\"comfortable\">\n      <v-col cols=\"12\" md=\"5\">\n        <v-treeview\n          v-model:activated=\"active\"\n          v-model:opened=\"open\"\n          :items=\"items\"\n          :load-children=\"fetchUsers\"\n          density=\"compact\"\n          item-title=\"name\"\n          item-value=\"id\"\n          activatable\n          border\n          fluid\n          open-on-click\n          rounded\n        >\n          <template v-slot:prepend=\"{ item }\">\n            <v-icon v-if=\"!item.children\" icon=\"mdi-account\"></v-icon>\n          </template>\n        </v-treeview>\n      </v-col>\n\n      <v-col class=\"d-flex text-center\" cols=\"12\" md=\"7\">\n        <v-card\n          class=\"text-title-large justify-center align-center flex-1-1 d-flex\"\n          color=\"surface-light\"\n          height=\"100%\"\n          flat\n          rounded\n        >\n          <template v-slot:text>\n            <div v-if=\"!selected\" class=\"text-body-large\">Select a User</div>\n\n            <template v-else>\n              <v-avatar :image=\"`https://avataaars.io/${avatar}`\" class=\"mb-2\" size=\"88\"></v-avatar>\n\n              <h3 class=\"text-headline-small my-0\">{{ selected.name }}</h3>\n\n              <div class=\"text-medium-emphasis\">{{ selected.email }}</div>\n\n              <div class=\"text-medium-emphasis font-weight-bold\">{{ selected.username }}</div>\n\n              <v-divider class=\"my-4\"></v-divider>\n\n              <v-text-field\n                :model-value=\"selected.company.name\"\n                class=\"mx-auto mb-2\"\n                density=\"compact\"\n                max-width=\"250\"\n                prefix=\"Company:\"\n                variant=\"solo\"\n                flat\n                hide-details\n                readonly\n              ></v-text-field>\n\n              <v-text-field\n                :model-value=\"selected.website\"\n                class=\"mx-auto mb-2\"\n                density=\"compact\"\n                max-width=\"250\"\n                prefix=\"Website:\"\n                variant=\"solo\"\n                flat\n                hide-details\n                readonly\n              ></v-text-field>\n\n              <v-text-field\n                :model-value=\"selected.phone\"\n                class=\"mx-auto\"\n                density=\"compact\"\n                max-width=\"250\"\n                prefix=\"Phone:\"\n                variant=\"solo\"\n                flat\n                hide-details\n                readonly\n              ></v-text-field>\n            </template>\n          </template>\n        </v-card>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<script setup>\n  import { computed, ref, watch } from 'vue'\n\n  const avatars = [\n    '?accessoriesType=Blank&avatarStyle=Circle&clotheColor=PastelGreen&clotheType=ShirtScoopNeck&eyeType=Wink&eyebrowType=UnibrowNatural&facialHairColor=Black&facialHairType=MoustacheMagnum&hairColor=Platinum&mouthType=Concerned&skinColor=Tanned&topType=Turban',\n    '?accessoriesType=Sunglasses&avatarStyle=Circle&clotheColor=Gray02&clotheType=ShirtScoopNeck&eyeType=EyeRoll&eyebrowType=RaisedExcited&facialHairColor=Red&facialHairType=BeardMagestic&hairColor=Red&hatColor=White&mouthType=Twinkle&skinColor=DarkBrown&topType=LongHairBun',\n    '?accessoriesType=Prescription02&avatarStyle=Circle&clotheColor=Black&clotheType=ShirtVNeck&eyeType=Surprised&eyebrowType=Angry&facialHairColor=Blonde&facialHairType=Blank&hairColor=Blonde&hatColor=PastelOrange&mouthType=Smile&skinColor=Black&topType=LongHairNotTooLong',\n    '?accessoriesType=Round&avatarStyle=Circle&clotheColor=PastelOrange&clotheType=Overall&eyeType=Close&eyebrowType=AngryNatural&facialHairColor=Blonde&facialHairType=Blank&graphicType=Pizza&hairColor=Black&hatColor=PastelBlue&mouthType=Serious&skinColor=Light&topType=LongHairBigHair',\n    '?accessoriesType=Kurt&avatarStyle=Circle&clotheColor=Gray01&clotheType=BlazerShirt&eyeType=Surprised&eyebrowType=Default&facialHairColor=Red&facialHairType=Blank&graphicType=Selena&hairColor=Red&hatColor=Blue02&mouthType=Twinkle&skinColor=Pale&topType=LongHairCurly',\n  ]\n\n  const pause = ms => new Promise(resolve => setTimeout(resolve, ms))\n\n  const active = ref([])\n  const avatar = ref(null)\n  const open = ref([])\n  const users = ref([])\n\n  const items = computed(() => [\n    {\n      name: 'Users',\n      children: users.value,\n      id: 'users',\n    },\n  ])\n\n  const selected = computed(() => {\n    if (!active.value.length) return undefined\n\n    const id = active.value[0]\n\n    return users.value.find(user => user.id === id)\n  })\n\n  watch(selected, () => {\n    randomAvatar()\n  })\n\n  async function fetchUsers (item) {\n    await pause(1500)\n\n    return fetch('https://jsonplaceholder.typicode.com/users')\n      .then(res => res.json())\n      .then(json => (item.children.push(...json)))\n      .catch(err => console.warn(err))\n  }\n\n  function randomAvatar () {\n    avatar.value = avatars[Math.floor(Math.random() * avatars.length)]\n  }\n</script>\n\n<script>\n  const avatars = [\n    '?accessoriesType=Blank&avatarStyle=Circle&clotheColor=PastelGreen&clotheType=ShirtScoopNeck&eyeType=Wink&eyebrowType=UnibrowNatural&facialHairColor=Black&facialHairType=MoustacheMagnum&hairColor=Platinum&mouthType=Concerned&skinColor=Tanned&topType=Turban',\n    '?accessoriesType=Sunglasses&avatarStyle=Circle&clotheColor=Gray02&clotheType=ShirtScoopNeck&eyeType=EyeRoll&eyebrowType=RaisedExcited&facialHairColor=Red&facialHairType=BeardMagestic&hairColor=Red&hatColor=White&mouthType=Twinkle&skinColor=DarkBrown&topType=LongHairBun',\n    '?accessoriesType=Prescription02&avatarStyle=Circle&clotheColor=Black&clotheType=ShirtVNeck&eyeType=Surprised&eyebrowType=Angry&facialHairColor=Blonde&facialHairType=Blank&hairColor=Blonde&hatColor=PastelOrange&mouthType=Smile&skinColor=Black&topType=LongHairNotTooLong',\n    '?accessoriesType=Round&avatarStyle=Circle&clotheColor=PastelOrange&clotheType=Overall&eyeType=Close&eyebrowType=AngryNatural&facialHairColor=Blonde&facialHairType=Blank&graphicType=Pizza&hairColor=Black&hatColor=PastelBlue&mouthType=Serious&skinColor=Light&topType=LongHairBigHair',\n    '?accessoriesType=Kurt&avatarStyle=Circle&clotheColor=Gray01&clotheType=BlazerShirt&eyeType=Surprised&eyebrowType=Default&facialHairColor=Red&facialHairType=Blank&graphicType=Selena&hairColor=Red&hatColor=Blue02&mouthType=Twinkle&skinColor=Pale&topType=LongHairCurly',\n  ]\n\n  const pause = ms => new Promise(resolve => setTimeout(resolve, ms))\n\n  export default {\n    data: () => ({\n      active: [],\n      avatar: null,\n      open: [],\n      users: [],\n    }),\n\n    computed: {\n      items () {\n        return [\n          {\n            name: 'Users',\n            children: this.users,\n          },\n        ]\n      },\n      selected () {\n        if (!this.active.length) return undefined\n\n        const id = this.active[0]\n\n        return this.users.find(user => user.id === id)\n      },\n    },\n\n    watch: {\n      selected: 'randomAvatar',\n    },\n\n    methods: {\n      async fetchUsers (item) {\n        // Remove in 6 months and say\n        // you've made optimizations! :)\n        await pause(1500)\n\n        return fetch('https://jsonplaceholder.typicode.com/users')\n          .then(res => res.json())\n          .then(json => (item.children.push(...json)))\n          .catch(err => console.warn(err))\n      },\n      randomAvatar () {\n        this.avatar = avatars[Math.floor(Math.random() * avatars.length)]\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-treeview/prop-open-all.vue",
    "content": "<template>\n  <v-treeview\n    :items=\"items\"\n    item-value=\"id\"\n    open-all\n  ></v-treeview>\n</template>\n\n<script setup>\n  const items = [\n    {\n      id: 1,\n      title: 'Applications :',\n      children: [\n        { id: 2, title: 'Calendar : app' },\n        { id: 3, title: 'Chrome : app' },\n        { id: 4, title: 'Webstorm : app' },\n      ],\n    },\n    {\n      id: 5,\n      title: 'Documents :',\n      children: [\n        {\n          id: 6,\n          title: 'vuetify :',\n          children: [\n            {\n              id: 7,\n              title: 'src :',\n              children: [\n                { id: 8, title: 'index : ts' },\n                { id: 9, title: 'bootstrap : ts' },\n              ],\n            },\n          ],\n        },\n        {\n          id: 10,\n          title: 'material2 :',\n          children: [\n            {\n              id: 11,\n              title: 'src :',\n              children: [\n                { id: 12, title: 'v-btn : ts' },\n                { id: 13, title: 'v-card : ts' },\n                { id: 14, title: 'v-window : ts' },\n              ],\n            },\n          ],\n        },\n      ],\n    },\n    {\n      id: 15,\n      title: 'Downloads :',\n      children: [\n        { id: 16, title: 'October : pdf' },\n        { id: 17, title: 'November : pdf' },\n        { id: 18, title: 'Tutorial : html' },\n      ],\n    },\n    {\n      id: 19,\n      title: 'Videos :',\n      children: [\n        {\n          id: 20,\n          title: 'Tutorials :',\n          children: [\n            { id: 21, title: 'Basic layouts : mp4' },\n            { id: 22, title: 'Advanced techniques : mp4' },\n            { id: 23, title: 'All about app : dir' },\n          ],\n        },\n        { id: 24, title: 'Intro : mov' },\n        { id: 25, title: 'Conference introduction : avi' },\n      ],\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        {\n          id: 1,\n          title: 'Applications :',\n          children: [\n            { id: 2, title: 'Calendar : app' },\n            { id: 3, title: 'Chrome : app' },\n            { id: 4, title: 'Webstorm : app' },\n          ],\n        },\n        {\n          id: 5,\n          title: 'Documents :',\n          children: [\n            {\n              id: 6,\n              title: 'vuetify :',\n              children: [\n                {\n                  id: 7,\n                  title: 'src :',\n                  children: [\n                    { id: 8, title: 'index : ts' },\n                    { id: 9, title: 'bootstrap : ts' },\n                  ],\n                },\n              ],\n            },\n            {\n              id: 10,\n              title: 'material2 :',\n              children: [\n                {\n                  id: 11,\n                  title: 'src :',\n                  children: [\n                    { id: 12, title: 'v-btn : ts' },\n                    { id: 13, title: 'v-card : ts' },\n                    { id: 14, title: 'v-window : ts' },\n                  ],\n                },\n              ],\n            },\n          ],\n        },\n        {\n          id: 15,\n          title: 'Downloads :',\n          children: [\n            { id: 16, title: 'October : pdf' },\n            { id: 17, title: 'November : pdf' },\n            { id: 18, title: 'Tutorial : html' },\n          ],\n        },\n        {\n          id: 19,\n          title: 'Videos :',\n          children: [\n            {\n              id: 20,\n              title: 'Tutorials :',\n              children: [\n                { id: 21, title: 'Basic layouts : mp4' },\n                { id: 22, title: 'Advanced techniques : mp4' },\n                { id: 23, title: 'All about app : dir' },\n              ],\n            },\n            { id: 24, title: 'Intro : mov' },\n            { id: 25, title: 'Conference introduction : avi' },\n          ],\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-treeview/prop-rounded.vue",
    "content": "<template>\n  <v-treeview\n    :items=\"items\"\n    item-value=\"id\"\n    activatable\n    rounded\n  ></v-treeview>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const items = ref([\n    {\n      id: 1,\n      title: 'Applications :',\n      children: [\n        { id: 2, title: 'Calendar : app' },\n        { id: 3, title: 'Chrome : app' },\n        { id: 4, title: 'Webstorm : app' },\n      ],\n    },\n    {\n      id: 5,\n      title: 'Documents :',\n      children: [\n        {\n          id: 6,\n          title: 'vuetify :',\n          children: [\n            {\n              id: 7,\n              title: 'src :',\n              children: [\n                { id: 8, title: 'index : ts' },\n                { id: 9, title: 'bootstrap : ts' },\n              ],\n            },\n          ],\n        },\n        {\n          id: 10,\n          title: 'material2 :',\n          children: [\n            {\n              id: 11,\n              title: 'src :',\n              children: [\n                { id: 12, title: 'v-btn : ts' },\n                { id: 13, title: 'v-card : ts' },\n                { id: 14, title: 'v-window : ts' },\n              ],\n            },\n          ],\n        },\n      ],\n    },\n    {\n      id: 15,\n      title: 'Downloads :',\n      children: [\n        { id: 16, title: 'October : pdf' },\n        { id: 17, title: 'November : pdf' },\n        { id: 18, title: 'Tutorial : html' },\n      ],\n    },\n    {\n      id: 19,\n      title: 'Videos :',\n      children: [\n        {\n          id: 20,\n          title: 'Tutorials :',\n          children: [\n            { id: 21, title: 'Basic layouts : mp4' },\n            { id: 22, title: 'Advanced techniques : mp4' },\n            { id: 23, title: 'All about app : dir' },\n          ],\n        },\n        { id: 24, title: 'Intro : mov' },\n        { id: 25, title: 'Conference introduction : avi' },\n      ],\n    },\n  ])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        {\n          id: 1,\n          title: 'Applications :',\n          children: [\n            { id: 2, title: 'Calendar : app' },\n            { id: 3, title: 'Chrome : app' },\n            { id: 4, title: 'Webstorm : app' },\n          ],\n        },\n        {\n          id: 5,\n          title: 'Documents :',\n          children: [\n            {\n              id: 6,\n              title: 'vuetify :',\n              children: [\n                {\n                  id: 7,\n                  title: 'src :',\n                  children: [\n                    { id: 8, title: 'index : ts' },\n                    { id: 9, title: 'bootstrap : ts' },\n                  ],\n                },\n              ],\n            },\n            {\n              id: 10,\n              title: 'material2 :',\n              children: [\n                {\n                  id: 11,\n                  title: 'src :',\n                  children: [\n                    { id: 12, title: 'v-btn : ts' },\n                    { id: 13, title: 'v-card : ts' },\n                    { id: 14, title: 'v-window : ts' },\n                  ],\n                },\n              ],\n            },\n          ],\n        },\n        {\n          id: 15,\n          title: 'Downloads :',\n          children: [\n            { id: 16, title: 'October : pdf' },\n            { id: 17, title: 'November : pdf' },\n            { id: 18, title: 'Tutorial : html' },\n          ],\n        },\n        {\n          id: 19,\n          title: 'Videos :',\n          children: [\n            {\n              id: 20,\n              title: 'Tutorials :',\n              children: [\n                { id: 21, title: 'Basic layouts : mp4' },\n                { id: 22, title: 'Advanced techniques : mp4' },\n                { id: 23, title: 'All about app : dir' },\n              ],\n            },\n            { id: 24, title: 'Intro : mov' },\n            { id: 25, title: 'Conference introduction : avi' },\n          ],\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-treeview/prop-selected-color.vue",
    "content": "<template>\n  <div class=\"d-flex ga-4 flex-wrap\">\n    <v-treeview\n      v-model:selected=\"selection\"\n      :items=\"items\"\n      class=\"flex-1-1-0\"\n      item-value=\"id\"\n      select-strategy=\"classic\"\n      selected-color=\"primary\"\n      open-all\n      selectable\n    ></v-treeview>\n    <v-treeview\n      v-model:selected=\"selection\"\n      :items=\"items\"\n      class=\"flex-1-1-0\"\n      item-value=\"id\"\n      select-strategy=\"classic\"\n      selected-color=\"success\"\n      open-all\n      selectable\n    ></v-treeview>\n    <v-treeview\n      v-model:selected=\"selection\"\n      :items=\"items\"\n      class=\"flex-1-1-0\"\n      item-value=\"id\"\n      select-strategy=\"classic\"\n      selected-color=\"red\"\n      open-all\n      selectable\n    ></v-treeview>\n  </div>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const selection = shallowRef([2])\n  const items = [\n    {\n      id: 1,\n      title: 'Today',\n      children: [\n        { id: 2, title: 'Gym' },\n        { id: 3, title: 'Coffee' },\n      ],\n    },\n    {\n      id: 4,\n      title: 'Tomorrow',\n      children: [\n        { id: 5, title: 'Work' },\n        { id: 6, title: 'Hackathon' },\n      ],\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      selection: [2],\n      items: [\n        {\n          id: 1,\n          title: 'Today',\n          children: [\n            { id: 2, title: 'Cleanup the desk' },\n            { id: 3, title: 'Make a great coffee' },\n          ],\n        },\n        {\n          id: 4,\n          title: 'Tomorrow',\n          children: [\n            { id: 5, title: 'Contribute to Vuetify' },\n            { id: 6, title: 'Hit the Gym' },\n          ],\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-treeview/prop-selection-type.vue",
    "content": "<template>\n  <v-sheet border rounded>\n    <v-container fluid>\n      <v-select\n        v-model=\"strategy\"\n        :items=\"['leaf', 'single-leaf', 'independent', 'single-independent', 'classic', 'trunk', 'branch']\"\n        label=\"Selection type\"\n      ></v-select>\n\n      <v-row>\n        <v-col cols=\"12\" md=\"6\">\n          <v-treeview\n            v-model:selected=\"selected\"\n            :items=\"items\"\n            :select-strategy=\"strategy\"\n            item-value=\"id\"\n            return-object\n            selectable\n          ></v-treeview>\n        </v-col>\n\n        <v-divider vertical></v-divider>\n\n        <v-col class=\"pa-6\" cols=\"12\" md=\"6\">\n          <template v-if=\"!selected.length\">No nodes selected.</template>\n\n          <template v-else>\n            <div v-for=\"node in selected\" :key=\"node.id\">\n              {{ node.title }}\n            </div>\n          </template>\n        </v-col>\n      </v-row>\n    </v-container>\n  </v-sheet>\n</template>\n\n<script setup>\n  import { ref, shallowRef } from 'vue'\n\n  const strategy = shallowRef('leaf')\n  const selected = shallowRef([])\n  const items = ref([\n    {\n      id: 1,\n      title: 'Root',\n      children: [\n        { id: 2, title: 'Child #1' },\n        { id: 3, title: 'Child #2' },\n        {\n          id: 4,\n          title: 'Child #3',\n          children: [\n            { id: 5, title: 'Grandchild #1' },\n            { id: 6, title: 'Grandchild #2' },\n          ],\n        },\n      ],\n    },\n  ])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      strategy: 'leaf',\n      selected: [],\n      items: [\n        {\n          id: 1,\n          title: 'Root',\n          children: [\n            { id: 2, title: 'Child #1' },\n            { id: 3, title: 'Child #2' },\n            {\n              id: 4,\n              title: 'Child #3',\n              children: [\n                { id: 5, title: 'Grandchild #1' },\n                { id: 6, title: 'Grandchild #2' },\n              ],\n            },\n          ],\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-treeview/slot-append-and-label.vue",
    "content": "<template>\n  <v-treeview\n    v-model:opened=\"open\"\n    :items=\"items\"\n    density=\"compact\"\n    item-value=\"title\"\n    activatable\n    open-on-click\n  >\n    <template v-slot:prepend=\"{ item, isOpen }\">\n      <v-icon v-if=\"!item.file\" :icon=\"isOpen ? 'mdi-folder-open' : 'mdi-folder'\"></v-icon>\n\n      <v-icon v-else :icon=\"files[item.file]\"></v-icon>\n    </template>\n  </v-treeview>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const open = shallowRef(['public'])\n  const files = shallowRef({\n    html: 'mdi-language-html5',\n    js: 'mdi-nodejs',\n    json: 'mdi-code-json',\n    md: 'mdi-language-markdown',\n    pdf: 'mdi-file-pdf-box',\n    png: 'mdi-file-image',\n    txt: 'mdi-file-document-outline',\n    xls: 'mdi-file-excel',\n  })\n\n  const items = [\n    {\n      title: '.git',\n    },\n    {\n      title: 'node_modules',\n    },\n    {\n      title: 'public',\n      children: [\n        {\n          title: 'static',\n          children: [{\n            title: 'logo.png',\n            file: 'png',\n          }],\n        },\n        {\n          title: 'favicon.ico',\n          file: 'png',\n        },\n        {\n          title: 'index.html',\n          file: 'html',\n        },\n      ],\n    },\n    {\n      title: '.gitignore',\n      file: 'txt',\n    },\n    {\n      title: 'babel.config.js',\n      file: 'js',\n    },\n    {\n      title: 'package.json',\n      file: 'json',\n    },\n    {\n      title: 'README.md',\n      file: 'md',\n    },\n    {\n      title: 'vue.config.js',\n      file: 'js',\n    },\n    {\n      title: 'yarn.lock',\n      file: 'txt',\n    },\n  ]\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-treeview/slot-append-and-prepend-item.vue",
    "content": "<template>\n  <v-treeview\n    v-model:activated=\"activated\"\n    :items=\"items\"\n    item-key=\"id\"\n    item-value=\"id\"\n    activatable\n    open-all\n  >\n    <template v-slot:append=\"{ item, depth, isFirst, isLast }\">\n      <v-icon-btn :disabled=\"!depth\" icon=\"mdi-arrow-left\" @click.stop=\"move(item, 'left')\"></v-icon-btn>\n      <v-icon-btn :disabled=\"isFirst\" icon=\"mdi-arrow-up\" @click.stop=\"move(item, 'up')\"></v-icon-btn>\n      <v-icon-btn :disabled=\"isLast\" icon=\"mdi-arrow-down\" @click.stop=\"move(item, 'down')\"></v-icon-btn>\n      <v-icon-btn :disabled=\"isFirst\" icon=\"mdi-arrow-right\" @click.stop=\"move(item, 'right')\"></v-icon-btn>\n    </template>\n  </v-treeview>\n</template>\n\n<script setup>\n  import { ref, shallowRef } from 'vue'\n\n  const activated = ref([])\n  const root = {\n    id: 0,\n    children: [\n      {\n        id: 1,\n        title: 'Office Tools',\n        children: [\n          { id: 2, title: 'Calendar' },\n          { id: 3, title: 'Notepad' },\n        ],\n      },\n      {\n        id: 4,\n        title: 'Dev Tools',\n        children: [\n          { id: 5, title: 'VS Code' },\n          { id: 6, title: 'Figma' },\n          { id: 7, title: 'Webstorm' },\n        ],\n      },\n    ],\n  }\n  const items = shallowRef([...root.children])\n\n  function findParent (id, items = [root]) {\n    if (items.length === 0) return null\n    return items.find(item => item.children?.some(c => c.id === id)) ??\n      findParent(id, items.flatMap(item => item.children ?? []))\n  }\n\n  function findItemBefore (item) {\n    return findParent(item.id).children\n      .find((_, i, all) => all[i + 1]?.id === item.id)\n  }\n\n  function findItemAfter (item) {\n    return findParent(item.id).children\n      .find((_, i, all) => all[i - 1]?.id === item.id)\n  }\n\n  function detach (item) {\n    const parent = findParent(item.id)\n    parent.children.splice(parent.children.indexOf(item), 1)\n    if (parent.children.length === 0) parent.children = undefined\n  }\n\n  function injectNextTo (item, target, after = true) {\n    if (!target || target === root) return\n    detach(item)\n    const targetParent = findParent(target.id)\n    targetParent.children.splice(targetParent.children.indexOf(target) + (after ? 1 : 0), 0, item)\n    activated.value = [item.id]\n  }\n\n  function appendTo (item, target) {\n    if (!target) return\n    detach(item)\n    target.children ??= []\n    target.children.push(item)\n    activated.value = [item.id]\n  }\n\n  function move (item, direction) {\n    switch (direction) {\n      case 'left':\n        injectNextTo(item, findParent(item.id))\n        break\n      case 'up':\n        injectNextTo(item, findItemBefore(item), false)\n        break\n      case 'right':\n        appendTo(item, findItemBefore(item))\n        break\n      case 'down':\n        injectNextTo(item, findItemAfter(item))\n        break\n    }\n    items.value = [...root.children]\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      activated: [],\n      root: {\n        id: 0,\n        children: [\n          {\n            id: 1,\n            title: 'Office Tools',\n            children: [\n              { id: 2, title: 'Calendar' },\n              { id: 3, title: 'Notepad' },\n            ],\n          },\n          {\n            id: 4,\n            title: 'Dev Tools',\n            children: [\n              { id: 5, title: 'VS Code' },\n              { id: 6, title: 'Figma' },\n              { id: 7, title: 'Webstorm' },\n            ],\n          },\n        ],\n      },\n      items: [],\n    }),\n    mounted () {\n      this.items = [...this.root.children]\n    },\n    methods: {\n      findParent (id, items) {\n        items ??= [this.root]\n        if (items.length === 0) return null\n        return items.find(item => item.children?.some(c => c.id === id)) ??\n          this.findParent(id, items.flatMap(item => item.children ?? []))\n      },\n      findItemBefore (item) {\n        return this.findParent(item.id).children\n          .find((_, i, all) => all[i + 1]?.id === item.id)\n      },\n      findItemAfter (item) {\n        return this.findParent(item.id).children\n          .find((_, i, all) => all[i - 1]?.id === item.id)\n      },\n      detach (item) {\n        const parent = this.findParent(item.id)\n        parent.children.splice(parent.children.indexOf(item), 1)\n        if (parent.children.length === 0) parent.children = undefined\n      },\n      injectNextTo (item, target, after = true) {\n        if (!target || target === this.root) return\n        this.detach(item)\n        const targetParent = this.findParent(target.id)\n        targetParent.children.splice(targetParent.children.indexOf(target) + (after ? 1 : 0), 0, item)\n        this.activated = [item.id]\n      },\n      appendTo (item, target) {\n        if (!target) return\n        this.detach(item)\n        target.children ??= []\n        target.children.push(item)\n        this.activated = [item.id]\n      },\n      move (item, direction) {\n        switch (direction) {\n          case 'left':\n            this.injectNextTo(item, this.findParent(item.id))\n            break\n          case 'up':\n            this.injectNextTo(item, this.findItemBefore(item), false)\n            break\n          case 'right':\n            this.appendTo(item, this.findItemBefore(item))\n            break\n          case 'down':\n            this.injectNextTo(item, this.findItemAfter(item))\n            break\n        }\n        this.items = [...this.root.children]\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-treeview/slot-no-data.vue",
    "content": "<template>\n  <v-select\n    v-model=\"search\"\n    :items=\"['group 1', 'group 2', 'group 3']\"\n    label=\"Pick category\"\n  ></v-select>\n\n  <v-treeview\n    :items=\"items\"\n    :search=\"search\"\n    item-value=\"id\"\n  >\n    <template v-slot:no-data>\n      <v-btn\n        prepend-icon=\"mdi-backup-restore\"\n        rounded=\"lg\"\n        text=\"Reset category\"\n        variant=\"text\"\n        border\n        open-all\n        @click=\"search = ''\"\n      ></v-btn>\n    </template>\n  </v-treeview>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const search = ref('group 3')\n  const items = [\n    {\n      id: 1,\n      title: 'group 1',\n      children: [\n        { id: 11, title: 'Calendar : app' },\n      ],\n    },\n    {\n      id: 2,\n      title: 'group 2',\n      children: [\n        { id: 21, title: 'Chrome : app' },\n        { id: 22, title: 'Webstorm : app' },\n      ],\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      search: 'group 2',\n      items: [\n        {\n          id: 1,\n          title: 'group 1',\n          children: [\n            { id: 11, title: 'Calendar : app' },\n          ],\n        },\n        {\n          id: 2,\n          title: 'group 2',\n          children: [\n            { id: 21, title: 'Chrome : app' },\n            { id: 22, title: 'Webstorm : app' },\n          ],\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-treeview/slot-title.vue",
    "content": "<template>\n  <v-treeview\n    v-model=\"model\"\n    :items=\"items\"\n    :lines=\"false\"\n    collapse-icon=\"mdi-chevron-down\"\n    density=\"compact\"\n    expand-icon=\"mdi-chevron-right\"\n    select-strategy=\"leaf\"\n    fluid\n    selectable\n  >\n    <template v-slot:title=\"{ item }\">\n      <span :class=\"['text-body-small', model.includes(item.value) && 'text-decoration-line-through']\">\n        {{ item.title }}\n      </span>\n    </template>\n  </v-treeview>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const items = Array.from({ length: 10 }, (_, i) => ({\n    value: `${i}`,\n    title: `Example item ${i + 1}`,\n    children: Array.from({ length: 25 }, (_, j) => ({\n      value: `${i}-${j}`,\n      title: `Example child item ${j}`,\n    })),\n  }))\n\n  const model = shallowRef([])\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: Array.from({ length: 10 }, (_, i) => ({\n        value: `${i}`,\n        title: `Example item ${i + 1}`,\n        children: Array.from({ length: 25 }, (_, j) => ({\n          value: `${i}-${j}`,\n          title: `Example child item ${j}`,\n        })),\n      })),\n      model: [],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-treeview/slot-toggle.vue",
    "content": "<template>\n  <v-treeview\n    v-model:selected=\"model\"\n    :items=\"items\"\n    item-value=\"id\"\n    select-strategy=\"classic\"\n    open-all\n    selectable\n  >\n    <template v-slot:toggle=\"{ props: toggleProps, isOpen, isSelected, isIndeterminate, path, item }\">\n      <v-badge\n        :color=\"isSelected ? 'success' : 'warning'\"\n        :model-value=\"isSelected || isIndeterminate\"\n      >\n        <template v-slot:badge>\n          <v-icon\n            v-if=\"isSelected\"\n            icon=\"$complete\"\n            v-tooltip=\"`All elements in ${item.title} are selected`\"\n          ></v-icon>\n          <span v-if=\"isIndeterminate\">{{ selectionsInfo(path) }}</span>\n        </template>\n        <v-btn\n          v-bind=\"toggleProps\"\n          :color=\"isIndeterminate ? 'warning' : isSelected ? 'success' : 'medium-emphasis'\"\n          :variant=\"isOpen ? 'outlined' : 'tonal'\"\n        ></v-btn>\n      </v-badge>\n    </template>\n  </v-treeview>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const model = shallowRef([])\n\n  function selectionsInfo (path) {\n    const node = path.reduce((current, i) => current.children[i], { children: items })\n\n    const allLeafsIds = (function flatten (n) {\n      return n.children?.flatMap(flatten) ?? [n.id]\n    })(node)\n\n    const selectedCount = allLeafsIds\n      .filter(id => model.value.includes(id))\n      .length\n\n    return `${selectedCount}/${allLeafsIds.length}`\n  }\n\n  const items = [\n    {\n      id: '1',\n      title: 'Dashboard',\n      children: [\n        {\n          id: '1-1',\n          title: 'Analytics',\n        },\n        {\n          id: '1-2',\n          title: 'Reports',\n        },\n        {\n          id: '1-3',\n          title: 'Financial',\n          children: [\n            {\n              id: '1-3-1',\n              title: 'Budget',\n            },\n            {\n              id: '1-3-2',\n              title: 'Operations',\n            },\n            {\n              id: '1-3-3',\n              title: 'Costs',\n            },\n          ],\n        },\n      ],\n    },\n  ]\n</script>\n\n<script>\n  export default {\n    data () {\n      return {\n        model: [],\n        items: [\n          {\n            id: '1',\n            title: 'Dashboard',\n            children: [\n              {\n                id: '1-1',\n                title: 'Analytics',\n              },\n              {\n                id: '1-2',\n                title: 'Reports',\n              },\n              {\n                id: '1-3',\n                title: 'Financial',\n                children: [\n                  {\n                    id: '1-3-1',\n                    title: 'Budget',\n                  },\n                  {\n                    id: '1-3-2',\n                    title: 'Operations',\n                  },\n                  {\n                    id: '1-3-3',\n                    title: 'Costs',\n                  },\n                ],\n              },\n            ],\n          },\n        ],\n      }\n    },\n    methods: {\n      selectionsInfo (path) {\n        const node = path.reduce((current, i) => current.children[i], { children: this.items })\n\n        const allLeafsIds = (function flatten (n) {\n          return n.children?.flatMap(flatten) ?? [n.id]\n        })(node)\n\n        const selectedCount = allLeafsIds\n          .filter(id => this.model.includes(id))\n          .length\n\n        return `${selectedCount}/${allLeafsIds.length}`\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-treeview/usage.vue",
    "content": "<template>\n  <v-treeview :items=\"items\" item-value=\"id\"></v-treeview>\n</template>\n\n<script>\n  export default {\n    data: () => ({\n      items: [\n        {\n          id: 1,\n          title: 'Applications :',\n          children: [\n            { id: 2, title: 'Calendar : app' },\n            { id: 3, title: 'Chrome : app' },\n            { id: 4, title: 'Webstorm : app' },\n          ],\n        },\n        {\n          id: 5,\n          title: 'Documents :',\n          children: [\n            {\n              id: 6,\n              title: 'vuetify :',\n              children: [\n                {\n                  id: 7,\n                  title: 'src :',\n                  children: [\n                    { id: 8, title: 'index : ts' },\n                    { id: 9, title: 'bootstrap : ts' },\n                  ],\n                },\n              ],\n            },\n            {\n              id: 10,\n              title: 'material2 :',\n              children: [\n                {\n                  id: 11,\n                  title: 'src :',\n                  children: [\n                    { id: 12, title: 'v-btn : ts' },\n                    { id: 13, title: 'v-card : ts' },\n                    { id: 14, title: 'v-window : ts' },\n                  ],\n                },\n              ],\n            },\n          ],\n        },\n        {\n          id: 15,\n          title: 'Downloads :',\n          children: [\n            { id: 16, title: 'October : pdf' },\n            { id: 17, title: 'November : pdf' },\n            { id: 18, title: 'Tutorial : html' },\n          ],\n        },\n        {\n          id: 19,\n          title: 'Videos :',\n          children: [\n            {\n              id: 20,\n              title: 'Tutorials :',\n              children: [\n                { id: 21, title: 'Basic layouts : mp4' },\n                { id: 22, title: 'Advanced techniques : mp4' },\n                { id: 23, title: 'All about app : dir' },\n              ],\n            },\n            { id: 24, title: 'Intro : mov' },\n            { id: 25, title: 'Conference introduction : avi' },\n          ],\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-video/misc-in-card.vue",
    "content": "<template>\n  <div class=\"d-flex justify-center\">\n    <v-card elevation=\"2\" rounded=\"xl\" width=\"400\">\n      <v-card-item class=\"py-4\">\n        <v-skeleton-loader type=\"list-item-avatar-two-line\"></v-skeleton-loader>\n      </v-card-item>\n      <v-card-text class=\"pb-4 px-6\">\n        <v-video\n          :volume=\"50\"\n          aspect-ratio=\"4 / 3\"\n          background-color=\"transparent\"\n          color=\"orange\"\n          controls-transition=\"slide-y-transition\"\n          elevation=\"0\"\n          image=\"https://cdn.jsek.work/cdn/vt-video-poster.jpg\"\n          rounded=\"xl\"\n          src=\"https://cdn.jsek.work/cdn/vt-video.mp4\"\n          width=\"100%\"\n          detached\n          eager\n          floating\n          hide-play\n          no-fullscreen\n          split-time\n        ></v-video>\n      </v-card-text>\n    </v-card>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-video/misc-mini.vue",
    "content": "<template>\n  <div class=\"d-flex align-center justify-center ga-6 flex-wrap\">\n    <v-defaults-provider :defaults=\"{ VVideoControls: { VIconBtn: { color: 'red', border: 'sm' } } }\">\n      <v-video\n        aspect-ratio=\"1\"\n        color=\"blue\"\n        controls-variant=\"mini\"\n        image=\"https://cdn.jsek.work/cdn/vt-sunflowers.jpg\"\n        rounded=\"lg\"\n        src=\"https://cdn.jsek.work/cdn/vt-sunflowers.mp4\"\n        style=\"--v-video-controls-pill-border-radius: 8px\"\n        width=\"300\"\n        eager\n        hide-fullscreen\n        hide-volume\n        muted\n        pills\n      >\n        <template v-slot:prepend>\n          <VIconBtn class=\"mx-n1\" icon=\"mdi-skip-previous\"></VIconBtn>\n        </template>\n        <template v-slot:append>\n          <VIconBtn class=\"mx-n1\" icon=\"mdi-skip-next\"></VIconBtn>\n        </template>\n      </v-video>\n    </v-defaults-provider>\n\n    <v-video\n      aspect-ratio=\"1\"\n      controls-variant=\"mini\"\n      image=\"https://cdn.jsek.work/cdn/vt-sunflowers.jpg\"\n      rounded=\"xl\"\n      src=\"https://cdn.jsek.work/cdn/vt-sunflowers.mp4\"\n      width=\"300\"\n      eager\n      hide-overlay\n      no-fullscreen\n      pills\n    >\n      <template v-slot:controls=\"{ play, pause, playing, progress }\">\n        <div class=\"ml-auto\" style=\"display: grid\">\n          <v-progress-circular\n            :model-value=\"progress\"\n            color=\"#fffa\"\n            size=\"58\"\n            style=\"grid-area: 1/1; margin: -5px\"\n            width=\"3\"\n          ></v-progress-circular>\n          <v-icon-btn\n            :icon=\"playing ? 'mdi-pause' : 'mdi-play'\"\n            color=\"primary\"\n            size=\"large\"\n            style=\"grid-area: 1/1\"\n            variant=\"flat\"\n            @click=\"() => playing ? pause() : play()\"\n          ></v-icon-btn>\n        </div>\n      </template>\n    </v-video>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-video/misc-tube.vue",
    "content": "<template>\n  <v-video\n    :volume=\"50\"\n    :volume-props=\"{ direction: 'horizontal', menuProps: { location: 'top left' } }\"\n    class=\"mx-auto\"\n    controls-variant=\"tube\"\n    density=\"comfortable\"\n    image=\"https://cdn.jsek.work/cdn/vt-video-poster.jpg\"\n    max-width=\"450\"\n    rounded=\"lg\"\n    src=\"https://cdn.jsek.work/cdn/vt-video.mp4\"\n    track-color=\"red\"\n    eager\n  >\n    <template v-slot:prepend>\n      <v-icon-btn icon=\"mdi-skip-next\"></v-icon-btn>\n    </template>\n    <template v-slot:append>\n      <v-icon-btn icon=\"mdi-closed-caption\"></v-icon-btn>\n      <v-icon-btn icon=\"mdi-cog\"></v-icon-btn>\n      <v-icon-btn icon=\"mdi-picture-in-picture-bottom-right\"></v-icon-btn>\n      <v-icon-btn icon=\"mdi-cast\"></v-icon-btn>\n    </template>\n  </v-video>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-video/prop-color.vue",
    "content": "<template>\n  <div>\n    <v-sheet class=\"px-6 py-2 border-b mb-3\" color=\"surface\">\n      <div class=\"d-flex ga-2 ga-md-12 flex-wrap align-center justify-center\">\n        <div class=\"d-flex align-center ga-3\">\n          <v-chip-group v-model=\"controlsVariant\" mandatory>\n            <v-chip text=\"default\" value=\"default\" filter label></v-chip>\n            <v-chip text=\"tube\" value=\"tube\" filter label></v-chip>\n            <v-chip text=\"mini\" value=\"mini\" filter label></v-chip>\n          </v-chip-group>\n        </div>\n        <div class=\"d-flex align-center ga-3\">\n          <v-chip-group v-model=\"features\" multiple>\n            <v-chip text=\"pills\" value=\"pills\" filter label></v-chip>\n            <v-chip text=\"floating\" value=\"floating\" filter label></v-chip>\n            <v-chip text=\"detached\" value=\"detached\" filter label></v-chip>\n          </v-chip-group>\n        </div>\n      </div>\n    </v-sheet>\n\n    <div class=\"d-flex justify-center ga-3 mb-3\">\n      <v-btn\n        v-for=\"key in ['color', 'background', 'track']\"\n        :key=\"key\"\n        variant=\"text\"\n      >\n        <v-icon v-if=\"colors[key]\" :color=\"colors[key]\" icon=\"mdi-circle\" start></v-icon>\n        <v-icon v-else icon=\"mdi-circle-outline\" start></v-icon>\n        {{ key }}\n        <v-menu :close-on-content-click=\"false\" activator=\"parent\">\n          <v-color-picker\n            v-model=\"colors[key]\"\n            hide-canvas\n            hide-inputs\n            hide-sliders\n            show-swatches\n          ></v-color-picker>\n          <v-btn text=\"Clear\" @click=\"colors[key] = null\"></v-btn>\n        </v-menu>\n      </v-btn>\n    </div>\n\n    <v-video\n      :background-color=\"colors.background\"\n      :color=\"colors.color\"\n      :controls-variant=\"controlsVariant\"\n      :detached=\"features.includes('detached')\"\n      :floating=\"features.includes('floating')\"\n      :pills=\"features.includes('pills')\"\n      :start-at=\"10\"\n      :track-color=\"colors.track\"\n      class=\"mx-auto mb-3\"\n      image=\"https://cdn.jsek.work/cdn/vt-sunflowers.jpg\"\n      max-width=\"450\"\n      src=\"https://cdn.jsek.work/cdn/vt-sunflowers.mp4\"\n      eager\n      muted\n      no-fullscreen\n    >\n      <template v-slot:append>\n        <v-icon-btn icon=\"mdi-cog\"></v-icon-btn>\n        <v-divider opacity=\".7\" thickness=\"2\" inset vertical></v-divider>\n        <v-icon-btn icon=\"mdi-picture-in-picture-bottom-right\"></v-icon-btn>\n        <v-icon-btn class=\"mr-2\" icon=\"mdi-cast\"></v-icon-btn>\n      </template>\n    </v-video>\n  </div>\n</template>\n\n<script setup>\n  import { reactive, shallowRef } from 'vue'\n\n  const features = shallowRef([])\n  const controlsVariant = shallowRef('default')\n  const colors = reactive({\n    color: '#4cd2de',\n    background: null,\n    track: null,\n  })\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      features: [],\n      controlsVariant: 'default',\n      colors: {\n        color: '#4cd2de',\n        background: null,\n        track: null,\n      },\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-video/prop-density.vue",
    "content": "<template>\n  <div class=\"d-flex flex-wrap align-start justify-center ga-6\">\n    <div v-for=\"density in options\" :key=\"density\">\n      <v-video\n        :density=\"density\"\n        height=\"150\"\n        image=\"https://cdn.jsek.work/cdn/vt-sunflowers.jpg\"\n        rounded=\"lg\"\n        src=\"https://cdn.jsek.work/cdn/vt-sunflowers.mp4\"\n        start-at=\"10\"\n        volume=\"80\"\n        width=\"250\"\n        detached\n        eager\n      ></v-video>\n      <v-overlay>\n        <v-chip class=\"ma-2\">{{ density }}</v-chip>\n      </v-overlay>\n    </div>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\n  const options = ['default', 'comfortable', 'compact'] as const\n</script>\n\n<script lang=\"ts\">\n  export default {\n    data: () => ({\n      options: ['default', 'comfortable', 'compact'] as const,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-video/prop-image.vue",
    "content": "<template>\n  <div>\n    <v-video\n      :key=\"resetToPoster\"\n      :image=\"posterUrl\"\n      class=\"mx-auto mb-3\"\n      max-width=\"450\"\n      src=\"https://cdn.jsek.work/cdn/vt-sunflowers.mp4\"\n      muted\n      @loaded=\"loaded = true\"\n    ></v-video>\n\n    <div class=\"d-flex justify-center ga-3\">\n      <v-btn text=\"randomize image\" @click=\"randomizePoster\"></v-btn>\n      <v-btn text=\"restore original\" @click=\"posterId = null\"></v-btn>\n      <v-btn\n        :disabled=\"!loaded\"\n        prepend-icon=\"mdi-refresh\"\n        text=\"reset\"\n        @click=\"resetToPoster++; loaded = false\"\n      ></v-btn>\n    </div>\n  </div>\n</template>\n\n<script setup>\n  import { shallowRef, toRef } from 'vue'\n\n  const loaded = shallowRef(false)\n  const resetToPoster = shallowRef(0)\n\n  const posterId = shallowRef()\n  function randomizePoster () {\n    posterId.value = 1 + Math.ceil(Math.random() * 100)\n  }\n\n  const posterUrl = toRef(() => {\n    return posterId.value\n      ? `https://picsum.photos/500/300?image=${posterId.value}`\n      : 'https://cdn.jsek.work/cdn/vt-sunflowers.jpg'\n  })\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      loaded: false,\n      resetToPoster: 0,\n      posterId: null,\n    }),\n    computed: {\n      posterUrl () {\n        return this.posterId\n          ? `https://picsum.photos/500/300?image=${this.posterId}`\n          : 'https://cdn.jsek.work/cdn/vt-sunflowers.jpg'\n      },\n    },\n    methods: {\n      randomizePoster () {\n        this.posterId = 1 + Math.ceil(Math.random() * 100)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-video/prop-rounded.vue",
    "content": "<template>\n  <div class=\"pb-3\">\n    <v-video\n      :controls-props=\"{ class: 'px-4' }\"\n      :rounded=\"['lg', 'pill']\"\n      :start-at=\"10\"\n      class=\"mx-auto\"\n      height=\"260\"\n      image=\"https://cdn.jsek.work/cdn/vt-sunflowers.jpg\"\n      max-width=\"450\"\n      src=\"https://cdn.jsek.work/cdn/vt-sunflowers.mp4\"\n      eager\n      floating\n      muted\n    ></v-video>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-video/prop-start-at.vue",
    "content": "<template>\n  <div class=\"d-flex justify-center\">\n    <v-video\n      :start-at=\"10\"\n      class=\"align-self-center\"\n      image=\"https://cdn.jsek.work/cdn/vt-sunflowers.jpg\"\n      max-width=\"450\"\n      src=\"https://cdn.jsek.work/cdn/vt-sunflowers.mp4\"\n      eager\n      muted\n    ></v-video>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-video/slot-append-and-prepend.vue",
    "content": "<template>\n  <div class=\"d-flex justify-center\">\n    <v-video\n      :start-at=\"10\"\n      class=\"align-self-center\"\n      image=\"https://cdn.jsek.work/cdn/vt-sunflowers.jpg\"\n      max-width=\"450\"\n      src=\"https://cdn.jsek.work/cdn/vt-sunflowers.mp4\"\n      eager\n      muted\n    >\n      <template v-slot:prepend>\n        <v-icon-btn icon=\"mdi-skip-next\"></v-icon-btn>\n      </template>\n      <template v-slot:append>\n        <v-icon-btn icon=\"mdi-closed-caption\"></v-icon-btn>\n        <v-icon-btn icon=\"mdi-cog\"></v-icon-btn>\n        <v-icon-btn icon=\"mdi-picture-in-picture-bottom-right\"></v-icon-btn>\n        <v-icon-btn icon=\"mdi-cast\"></v-icon-btn>\n      </template>\n    </v-video>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-video/slot-controls.vue",
    "content": "<template>\n  <div>\n    <v-video\n      :start-at=\"10\"\n      :volume-props=\"{ inline: true }\"\n      class=\"mx-auto\"\n      controls-variant=\"mini\"\n      height=\"300\"\n      image=\"https://cdn.jsek.work/cdn/vt-sunflowers.jpg\"\n      max-width=\"500\"\n      rounded=\"lg\"\n      src=\"https://cdn.jsek.work/cdn/vt-sunflowers.mp4\"\n      eager\n      hide-overlay\n      pills\n    >\n      <template v-slot:controls=\"{ play, pause, playing, progress, skipTo, volume, toggleMuted, fullscreen, toggleFullscreen, labels }\">\n        <v-defaults-provider :defaults=\"{ VIconBtn: { color: 'red', rounded: 'lg', size: '36', variant: 'flat' }, VSlider: { color: 'red', trackColor: 'white' } }\">\n          <div class=\"d-flex ga-3 w-100 px-2\">\n            <v-icon-btn\n              :aria-label=\"labels.playAction\"\n              :icon=\"playing ? 'mdi-pause' : 'mdi-play'\"\n              v-tooltip:top=\"labels.playAction\"\n              @click=\"() => playing ? pause() : play()\"\n            ></v-icon-btn>\n            <v-slider\n              :aria-label=\"labels.seek\"\n              :model-value=\"progress\"\n              width=\"75%\"\n              no-keyboard\n              @update:model-value=\"skipTo\"\n            ></v-slider>\n            <v-video-volume\n              v-model=\"volume.value\"\n              :label=\"labels.volumeAction\"\n              :slider-props=\"{ maxWidth: 100, width: '25%' }\"\n              class=\"ga-3\"\n              inline\n              @click=\"toggleMuted\"\n            ></v-video-volume>\n            <v-icon-btn\n              :aria-label=\"labels.fullscreenAction\"\n              :icon=\"fullscreen ? '$fullscreenExit' : '$fullscreen'\"\n              v-tooltip:top=\"labels.fullscreenAction\"\n              @click=\"toggleFullscreen\"\n            ></v-icon-btn>\n          </div>\n        </v-defaults-provider>\n      </template>\n    </v-video>\n  </div>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/v-video/slot-error.vue",
    "content": "<template>\n  <v-container class=\"d-flex flex-wrap justify-center align-center ga-8\">\n\n    <v-video\n      max-width=\"450\"\n      src=\"https://www.pexels.com/download/video/3620220\"\n      error\n    >\n      <template v-slot:error>\n        <div class=\"d-flex align-center ga-4\">\n          <v-icon class=\"opacity-60\" color=\"error\"></v-icon>\n          <div>\n            <div class=\"font-weight-bold mb-1\">Video unavailable</div>\n            <div class=\"text-body-medium\">Report problem to our <a href=\"\">support</a></div>\n          </div>\n        </div>\n      </template>\n    </v-video>\n\n    <v-video\n      ref=\"secondVideoRef\"\n      max-width=\"450\"\n      src=\"https://www.pexels.com/download/video/3620220\"\n      error\n    >\n      <template v-slot:error>\n        <div\n          class=\"d-flex align-center ga-4 pl-4 pr-8 py-3 rounded-pill border cursor-pointer\"\n          @click=\"secondVideoRef.retry()\"\n        >\n          <v-icon class=\"opacity-60\" icon=\"$loading\"></v-icon>\n          <div>\n            <div class=\"font-weight-bold mb-1\">Connection timout</div>\n            <div class=\"text-body-medium\">Tap to reload</div>\n          </div>\n        </div>\n      </template>\n    </v-video>\n  </v-container>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const secondVideoRef = ref()\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-video/slot-header.vue",
    "content": "<template>\n  <div class=\"d-flex justify-center\">\n    <v-video\n      class=\"align-self-center\"\n      image=\"https://cdn.jsek.work/cdn/vt-sunflowers.jpg\"\n      max-width=\"450\"\n      src=\"https://cdn.jsek.work/cdn/vt-sunflowers.mp4\"\n      eager\n      muted\n    >\n      <template v-slot:header>\n        <div class=\"d-flex pa-2 pointer-pass-through\">\n          <v-list-item\n            class=\"py-2 pl-3 pr-8 video-header-element\"\n            prepend-avatar=\"https://cdn.jsek.work/cdn/vt-sunflowers.jpg\"\n            rounded=\"pill\"\n            subtitle=\"Example video\"\n            title=\"Sunflowers\"\n          ></v-list-item>\n          <v-icon-btn\n            class=\"ml-auto video-header-element\"\n            icon=\"mdi-share-variant\"\n            variant=\"text\"\n          ></v-icon-btn>\n        </div>\n      </template>\n    </v-video>\n  </div>\n</template>\n\n<style scoped>\n.video-header-element {\n  background: #0008;\n  color: #fff;\n}\n</style>\n"
  },
  {
    "path": "packages/docs/src/examples/v-video/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"controlsVariants\"\n  >\n    <div>\n      <v-video class=\"mx-auto\" v-bind=\"props\"></v-video>\n    </div>\n\n    <template v-slot:configuration>\n      <v-select v-model=\"theme\" :items=\"['light', 'dark']\" label=\"Theme\" clearable></v-select>\n      <v-select v-model=\"color\" :items=\"colorOptions\" label=\"Color\" clearable></v-select>\n      <v-select v-model=\"elevation\" :items=\"[1, 3, 5]\" label=\"Elevation\" clearable></v-select>\n      <v-select v-model=\"aspectRatio\" :items=\"['16/9', '3/2', '1']\" label=\"Aspect ratio\" clearable></v-select>\n      <v-checkbox v-if=\"!isHidden\" v-model=\"hidePlay\" label=\"Hide play\"></v-checkbox>\n      <v-checkbox v-if=\"!isHidden\" v-model=\"hideVolume\" label=\"Hide volume\"></v-checkbox>\n      <v-checkbox v-if=\"!isHidden\" v-model=\"noFullscreen\" label=\"No fullscreen\"></v-checkbox>\n    </template>\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-video'\n  const controlsVariants = ['tube', 'mini', 'hidden']\n\n  const model = shallowRef('default')\n  const hidePlay = shallowRef(false)\n  const hideVolume = shallowRef(false)\n  const noFullscreen = shallowRef(false)\n  const theme = shallowRef(null)\n  const color = shallowRef(null)\n  const elevation = shallowRef(null)\n  const aspectRatio = shallowRef('16/9')\n\n  const isHidden = toRef(() => model.value === 'hidden')\n\n  const colorOptions = [\n    'primary',\n    'green',\n    'cyan',\n    'lime-accent-4',\n  ]\n\n  const props = computed(() => {\n    return {\n      theme: theme.value || undefined,\n      color: color.value || undefined,\n      elevation: elevation.value || undefined,\n      'aspect-ratio': aspectRatio.value || undefined,\n      'hide-play': (!isHidden.value && hidePlay.value) || undefined,\n      'hide-volume': (!isHidden.value && hideVolume.value) || undefined,\n      noFullscreen: (!isHidden.value && noFullscreen.value) || undefined,\n      'controls-variant': controlsVariants.includes(model.value) ? model.value : undefined,\n      image: 'https://cdn.jsek.work/cdn/vt-sunflowers.jpg',\n      src: 'https://cdn.jsek.work/cdn/vt-sunflowers.mp4',\n    }\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)} />`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-virtual-scroll/misc-user-directory.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"400\"\n  >\n    <v-card-item class=\"bg-orange-darken-4\">\n      <v-card-title>\n        User Directory\n      </v-card-title>\n\n      <template v-slot:append>\n        <v-btn\n          color=\"white\"\n          icon=\"mdi-plus\"\n          size=\"small\"\n        ></v-btn>\n      </template>\n    </v-card-item>\n\n    <v-card-text class=\"pt-4\">\n      Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quasi nobis a at voluptates culpa optio amet! Inventore deserunt voluptatem maxime a veniam placeat, eos impedit nulla quos? Officiis, aperiam ducimus.\n    </v-card-text>\n\n    <v-divider></v-divider>\n\n    <v-virtual-scroll\n      :items=\"items\"\n      height=\"300\"\n      item-height=\"50\"\n    >\n      <template v-slot:default=\"{ item }\">\n        <v-list-item>\n          <template v-slot:prepend>\n            <v-avatar\n              :color=\"item.color\"\n              class=\"text-white\"\n              size=\"40\"\n            >\n              {{ item.initials }}\n            </v-avatar>\n          </template>\n\n          <v-list-item-title>{{ item.fullName }}</v-list-item-title>\n\n          <template v-slot:append>\n            <v-btn\n              size=\"small\"\n              variant=\"tonal\"\n            >\n              View User\n\n              <v-icon\n                color=\"orange-darken-4\"\n                end\n              >\n                mdi-open-in-new\n              </v-icon>\n            </v-btn>\n          </template>\n        </v-list-item>\n      </template>\n    </v-virtual-scroll>\n  </v-card>\n</template>\n\n<script setup>\n  import { computed } from 'vue'\n\n  const colors = ['#2196F3', '#90CAF9', '#64B5F6', '#42A5F5', '#1E88E5', '#1976D2', '#1565C0', '#0D47A1', '#82B1FF', '#448AFF', '#2979FF', '#2962FF']\n  const names = ['Oliver', 'Jake', 'Noah', 'James', 'Jack', 'Connor', 'Liam', 'John', 'Harry', 'Callum', 'Mason', 'Robert', 'Jacob', 'Jacob', 'Jacob', 'Michael', 'Charlie', 'Kyle', 'William', 'William', 'Thomas', 'Joe', 'Ethan', 'David', 'George', 'Reece', 'Michael', 'Richard', 'Oscar', 'Rhys', 'Alexander', 'Joseph', 'James', 'Charlie', 'James', 'Charles', 'William', 'Damian', 'Daniel', 'Thomas', 'Amelia', 'Margaret', 'Emma', 'Mary', 'Olivia', 'Samantha', 'Olivia', 'Patricia', 'Isla', 'Bethany']\n  const surnames = ['Smith', 'Anderson', 'Clark', 'Wright', 'Mitchell', 'Johnson', 'Thomas', 'Rodriguez', 'Lopez', 'Perez', 'Williams', 'Jackson', 'Lewis', 'Hill', 'Roberts', 'Jones', 'White', 'Lee', 'Scott', 'Turner', 'Brown', 'Harris', 'Walker', 'Green', 'Phillips', 'Davis', 'Martin', 'Hall', 'Adams', 'Campbell', 'Miller', 'Thompson', 'Allen', 'Baker', 'Parker', 'Wilson', 'Garcia', 'Young', 'Gonzalez', 'Evans', 'Moore', 'Martinez', 'Hernandez', 'Nelson', 'Edwards', 'Taylor', 'Robinson', 'King', 'Carter', 'Collins']\n\n  const items = computed(() => {\n    const namesLength = names.length\n    const surnamesLength = surnames.length\n    const colorsLength = colors.length\n\n    return Array.from({ length: 10000 }, () => {\n      const name = names[genRandomIndex(namesLength)]\n      const surname = surnames[genRandomIndex(surnamesLength)]\n\n      return {\n        color: colors[genRandomIndex(colorsLength)],\n        fullName: `${name} ${surname}`,\n        initials: `${name[0]} ${surname[0]}`,\n      }\n    })\n  })\n\n  function genRandomIndex (length) {\n    return Math.ceil(Math.random() * (length - 1))\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      colors: ['#2196F3', '#90CAF9', '#64B5F6', '#42A5F5', '#1E88E5', '#1976D2', '#1565C0', '#0D47A1', '#82B1FF', '#448AFF', '#2979FF', '#2962FF'],\n      names: ['Oliver', 'Jake', 'Noah', 'James', 'Jack', 'Connor', 'Liam', 'John', 'Harry', 'Callum', 'Mason', 'Robert', 'Jacob', 'Jacob', 'Jacob', 'Michael', 'Charlie', 'Kyle', 'William', 'William', 'Thomas', 'Joe', 'Ethan', 'David', 'George', 'Reece', 'Michael', 'Richard', 'Oscar', 'Rhys', 'Alexander', 'Joseph', 'James', 'Charlie', 'James', 'Charles', 'William', 'Damian', 'Daniel', 'Thomas', 'Amelia', 'Margaret', 'Emma', 'Mary', 'Olivia', 'Samantha', 'Olivia', 'Patricia', 'Isla', 'Bethany'],\n      surnames: ['Smith', 'Anderson', 'Clark', 'Wright', 'Mitchell', 'Johnson', 'Thomas', 'Rodriguez', 'Lopez', 'Perez', 'Williams', 'Jackson', 'Lewis', 'Hill', 'Roberts', 'Jones', 'White', 'Lee', 'Scott', 'Turner', 'Brown', 'Harris', 'Walker', 'Green', 'Phillips', 'Davis', 'Martin', 'Hall', 'Adams', 'Campbell', 'Miller', 'Thompson', 'Allen', 'Baker', 'Parker', 'Wilson', 'Garcia', 'Young', 'Gonzalez', 'Evans', 'Moore', 'Martinez', 'Hernandez', 'Nelson', 'Edwards', 'Taylor', 'Robinson', 'King', 'Carter', 'Collins'],\n    }),\n\n    computed: {\n      items () {\n        const namesLength = this.names.length\n        const surnamesLength = this.surnames.length\n        const colorsLength = this.colors.length\n\n        return Array.from({ length: 10000 }, () => {\n          const name = this.names[this.genRandomIndex(namesLength)]\n          const surname = this.surnames[this.genRandomIndex(surnamesLength)]\n\n          return {\n            color: this.colors[this.genRandomIndex(colorsLength)],\n            fullName: `${name} ${surname}`,\n            initials: `${name[0]} ${surname[0]}`,\n          }\n        })\n      },\n    },\n\n    methods: {\n      genRandomIndex (length) {\n        return Math.ceil(Math.random() * (length - 1))\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-virtual-scroll/prop-dynamic-item-height.vue",
    "content": "<template>\n  <v-virtual-scroll\n    :items=\"items\"\n    height=\"400\"\n  >\n    <template v-slot:default=\"{ item, index }\">\n      <div\n        :class=\"[\n          index % 2 === 0 ? 'py-2' : index % 5 == 0 ? 'py-8' : 'py-4',\n          index % 2 === 0 ? 'bg-grey-lighten-2' : index % 5 === 0 ? 'bg-grey-darken-2' : '',\n          'px-2'\n        ]\"\n      >\n        Dynamic item {{ item }}\n      </div>\n    </template>\n  </v-virtual-scroll>\n</template>\n\n<script setup>\n  const items = Array.from({ length: 1000 }, (k, v) => v + 1)\n</script>\n\n<script>\n  export default {\n    computed: {\n      items () {\n        return Array.from({ length: 1000 }, (k, v) => v + 1)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-virtual-scroll/prop-height-parent.vue",
    "content": "<template>\n  <div style=\"display: flex; height: 200px;\">\n    <v-virtual-scroll :items=\"items\">\n      <template v-slot:default=\"{ item }\">\n        Virtual Item {{ item }}\n      </template>\n    </v-virtual-scroll>\n  </div>\n</template>\n\n<script setup>\n  const items = Array.from({ length: 1000 }, (k, v) => v + 1)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: Array.from({ length: 1000 }, (k, v) => v + 1),\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-virtual-scroll/prop-height.vue",
    "content": "<template>\n  <v-virtual-scroll :items=\"items\" height=\"200\">\n    <template v-slot:default=\"{ item }\">\n      Virtual Item {{ item }}\n    </template>\n  </v-virtual-scroll>\n</template>\n\n<script setup>\n  const items = Array.from({ length: 1000 }, (k, v) => v + 1)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: Array.from({ length: 1000 }, (k, v) => v + 1),\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-virtual-scroll/prop-item-height.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"500\"\n  >\n    <v-card-title>\n      Company Employee List\n    </v-card-title>\n\n    <v-divider></v-divider>\n\n    <v-virtual-scroll\n      :items=\"items\"\n      height=\"320\"\n      item-height=\"48\"\n    >\n      <template v-slot:default=\"{ item }\">\n        <v-list-item\n          :subtitle=\"`Badge #${item}`\"\n          :title=\"`Employee Name`\"\n        >\n          <template v-slot:prepend>\n            <v-icon class=\"bg-primary\">mdi-account</v-icon>\n          </template>\n\n          <template v-slot:append>\n            <v-btn\n              icon=\"mdi-pencil\"\n              size=\"x-small\"\n              variant=\"tonal\"\n            ></v-btn>\n          </template>\n        </v-list-item>\n      </template>\n    </v-virtual-scroll>\n  </v-card>\n</template>\n\n<script setup>\n  const items = Array.from({ length: 1000 }, (k, v) => v + 1)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      items: Array.from({ length: 1000 }, (k, v) => v + 1),\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-virtual-scroll/prop-renderless.vue",
    "content": "<template>\n  <v-container>\n    <p class=\"text-body-small opacity-80\">\n      💡 The <code>height</code> prop should be a plain number,\n      or a value with units like <code>px</code> and <code>vh</code>, but not the percentage\n      (<code>%</code>).\n    </p>\n\n    <v-table height=\"300\" fixed-header>\n      <thead>\n        <tr>\n          <th>#</th>\n          <th>Name</th>\n          <th>Icon</th>\n        </tr>\n      </thead>\n      <tbody>\n        <v-virtual-scroll :items=\"items\" renderless>\n          <template v-slot:default=\"{ item, index, itemRef }\">\n            <tr :ref=\"itemRef\">\n              <td>{{ index + 1 }}</td>\n              <td>{{ item.name }}</td>\n              <td>{{ item.icon }}</td>\n            </tr>\n          </template>\n        </v-virtual-scroll>\n      </tbody>\n    </v-table>\n  </v-container>\n</template>\n\n<script setup>\n  const icons = ['🍄', '🌼', '🌵', '🌲', '🌰', '🍅', '🍊', '🍓']\n  const items = Array.from({ length: 1000 }, (k, v) => ({\n    name: `Item #${String(v + 1).padStart(4, '0')}`,\n    icon: icons[v % icons.length],\n  }))\n</script>\n\n<script>\n  const icons = ['🍄', '🌼', '🌵', '🌲', '🌰', '🍅', '🍊', '🍓']\n  export default {\n    data: () => ({\n      items: Array.from({ length: 1000 }, (k, v) => ({\n        name: `Item #${String(v + 1).padStart(4, '0')}`,\n        icon: icons[v % icons.length],\n      })),\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-virtual-scroll/usage.vue",
    "content": "<template>\n  <ExamplesUsageExample\n    v-model=\"model\"\n    :code=\"code\"\n    :name=\"name\"\n    :options=\"options\"\n  >\n    <div>\n      <v-virtual-scroll v-bind=\"props\" :items=\"items\">\n        <template v-slot:default=\"{ item }\">\n          Item {{ item }}\n        </template>\n      </v-virtual-scroll>\n    </div>\n\n    <!-- <template v-slot:configuration>\n    </template> -->\n  </ExamplesUsageExample>\n</template>\n\n<script setup>\n  const name = 'v-virtual-scroll'\n  const model = ref('default')\n  const items = Array.from({ length: 1000 }, (k, v) => v + 1)\n  const options = []\n  const props = computed(() => {\n    return {\n      height: 300,\n      items: Array.from({ length: 1000 }, (k, v) => v + 1).slice(0, 30),\n    }\n  })\n\n  const slots = computed(() => {\n    return `\n  <template v-slot:default=\"{ item }\">\n    Item {{ item }}\n  </template>\n`\n  })\n\n  const code = computed(() => {\n    return `<${name}${propsToString(props.value)}>${slots.value}</${name}>`\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-window/misc-account-creation.vue",
    "content": "<template>\n  <v-card\n    class=\"mx-auto\"\n    max-width=\"500\"\n  >\n    <v-card-title class=\"text-title-large font-weight-regular justify-space-between\">\n      <span>{{ currentTitle }}</span>\n      <v-avatar\n        color=\"primary\"\n        size=\"24\"\n        v-text=\"step\"\n      ></v-avatar>\n    </v-card-title>\n\n    <v-window v-model=\"step\">\n      <v-window-item :value=\"1\">\n        <v-card-text>\n          <v-text-field\n            label=\"Email\"\n            placeholder=\"john@google.com\"\n          ></v-text-field>\n          <span class=\"text-body-small text-grey-darken-1\">\n            This is the email you will use to login to your Vuetify account\n          </span>\n        </v-card-text>\n      </v-window-item>\n\n      <v-window-item :value=\"2\">\n        <v-card-text>\n          <v-text-field\n            label=\"Password\"\n            type=\"password\"\n          ></v-text-field>\n          <v-text-field\n            label=\"Confirm Password\"\n            type=\"password\"\n          ></v-text-field>\n          <span class=\"text-body-small text-grey-darken-1\">\n            Please enter a password for your account\n          </span>\n        </v-card-text>\n      </v-window-item>\n\n      <v-window-item :value=\"3\">\n        <div class=\"pa-4 text-center\">\n          <v-img\n            class=\"mb-4\"\n            height=\"128\"\n            src=\"https://cdn.vuetifyjs.com/images/logos/v.svg\"\n          ></v-img>\n          <h3 class=\"text-title-large font-weight-light mt-0 mb-2\">\n            Welcome to Vuetify\n          </h3>\n          <span class=\"text-body-small text-grey\">Thanks for signing up!</span>\n        </div>\n      </v-window-item>\n    </v-window>\n\n    <v-divider></v-divider>\n\n    <v-card-actions>\n      <v-btn\n        v-if=\"step > 1\"\n        variant=\"text\"\n        @click=\"step--\"\n      >\n        Back\n      </v-btn>\n      <v-spacer></v-spacer>\n      <v-btn\n        v-if=\"step < 3\"\n        color=\"primary\"\n        variant=\"flat\"\n        @click=\"step++\"\n      >\n        Next\n      </v-btn>\n    </v-card-actions>\n  </v-card>\n</template>\n\n<script setup>\n  import { computed, ref } from 'vue'\n\n  const step = ref(1)\n\n  const currentTitle = computed(() => {\n    switch (step.value) {\n      case 1: return 'Sign-up'\n      case 2: return 'Create a password'\n      default: return 'Account created'\n    }\n  })\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      step: 1,\n    }),\n\n    computed: {\n      currentTitle () {\n        switch (this.step) {\n          case 1: return 'Sign-up'\n          case 2: return 'Create a password'\n          default: return 'Account created'\n        }\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-window/misc-onboarding.vue",
    "content": "<template>\n  <v-card\n    rounded=\"0\"\n    theme=\"dark\"\n    flat\n  >\n    <v-window v-model=\"onboarding\">\n      <v-window-item\n        v-for=\"n in length\"\n        :key=\"`card-${n}`\"\n        :value=\"n\"\n      >\n        <v-card\n          class=\"d-flex justify-center align-center\"\n          height=\"200\"\n        >\n          <span class=\"text-display-large\">\n            Card {{ n }}\n          </span>\n        </v-card>\n      </v-window-item>\n    </v-window>\n\n    <v-card-actions class=\"justify-space-between\">\n      <v-btn\n        icon=\"mdi-chevron-left\"\n        variant=\"plain\"\n        @click=\"prev\"\n      ></v-btn>\n      <v-item-group\n        v-model=\"onboarding\"\n        class=\"text-center\"\n        mandatory\n      >\n        <v-item\n          v-for=\"n in length\"\n          :key=\"`btn-${n}`\"\n          v-slot=\"{ isSelected, toggle }\"\n          :value=\"n\"\n        >\n          <v-btn\n            :variant=\"isSelected ? 'outlined' : 'text'\"\n            icon=\"mdi-record\"\n            @click=\"toggle\"\n          ></v-btn>\n        </v-item>\n      </v-item-group>\n      <v-btn\n        icon=\"mdi-chevron-right\"\n        variant=\"plain\"\n        @click=\"next\"\n      ></v-btn>\n    </v-card-actions>\n  </v-card>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const length = ref(3)\n  const onboarding = ref(1)\n\n  function next () {\n    onboarding.value = onboarding.value + 1 > length.value ? 1 : onboarding.value + 1\n  }\n  function prev () {\n    onboarding.value = onboarding.value - 1 <= 0 ? length.value : onboarding.value - 1\n  }\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      length: 3,\n      onboarding: 1,\n    }),\n\n    methods: {\n      next () {\n        this.onboarding = this.onboarding + 1 > this.length\n          ? 1\n          : this.onboarding + 1\n      },\n      prev () {\n        this.onboarding = this.onboarding - 1 <= 0\n          ? this.length\n          : this.onboarding - 1\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-window/prop-direction.vue",
    "content": "<template>\n  <v-window\n    v-model=\"onboarding\"\n    direction=\"vertical\"\n    show-arrows\n  >\n    <v-window-item\n      v-for=\"n in length\"\n      :key=\"`card-${n}`\"\n    >\n      <v-card\n        class=\"d-flex align-center justify-center ma-2\"\n        elevation=\"1\"\n        height=\"200\"\n      >\n        <h1 class=\"text-display-large my-0\">\n          Slide {{ n }}\n        </h1>\n      </v-card>\n    </v-window-item>\n  </v-window>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const length = ref(3)\n  const onboarding = ref(0)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      length: 3,\n      onboarding: 0,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-window/prop-reverse.vue",
    "content": "<template>\n  <v-window\n    v-model=\"onboarding\"\n    reverse\n    show-arrows\n  >\n    <v-window-item\n      v-for=\"n in length\"\n      :key=\"`card-${n}`\"\n    >\n      <v-card\n        class=\"d-flex align-center justify-center ma-2\"\n        elevation=\"1\"\n        height=\"200\"\n      >\n        <h1 class=\"text-display-large my-0\">\n          Slide {{ n }}\n        </h1>\n      </v-card>\n    </v-window-item>\n  </v-window>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const length = ref(3)\n  const onboarding = ref(0)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      length: 3,\n      onboarding: 0,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/v-window/prop-show-arrows.vue",
    "content": "<template>\n  <v-window\n    v-model=\"onboarding\"\n    show-arrows=\"hover\"\n  >\n    <v-window-item\n      v-for=\"n in length\"\n      :key=\"`card-${n}`\"\n    >\n      <v-card\n        class=\"d-flex align-center justify-center ma-2\"\n        elevation=\"1\"\n        height=\"200\"\n      >\n        <h1 class=\"text-display-large my-0\">\n          Slide {{ n }}\n        </h1>\n      </v-card>\n    </v-window-item>\n  </v-window>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const length = ref(3)\n  const onboarding = ref(0)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      length: 3,\n      onboarding: 0,\n    }),\n  }\n</script>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2801-155682&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-window/slots-next-prev.vue",
    "content": "<template>\n  <v-window show-arrows>\n    <template v-slot:prev=\"{ props }\">\n      <v-btn\n        color=\"success\"\n        @click=\"props.onClick\"\n      >\n        Previous slide\n      </v-btn>\n    </template>\n    <template v-slot:next=\"{ props }\">\n      <v-btn\n        color=\"info\"\n        @click=\"props.onClick\"\n      >\n        Next slide\n      </v-btn>\n    </template>\n    <v-window-item\n      v-for=\"n in 3\"\n      :key=\"`card-${n}`\"\n    >\n      <v-card\n        class=\"d-flex align-center justify-center ma-2\"\n        elevation=\"1\"\n        height=\"200\"\n      >\n        <h1 class=\"text-display-large my-0\">\n          Slide {{ n }}\n        </h1>\n      </v-card>\n    </v-window-item>\n  </v-window>\n</template>\n<example-meta lang=\"json\">\n  {\n    \"figma\": \"https://www.figma.com/design/5f4g4pbbBsk9TTWX4Xvlx1/PRO-v3.0---Official-Vuetify-3-UI-Kit?node-id=2800-83891&t=tC3y53U3XKPv8ZyJ-4\"\n  }\n</example-meta>\n"
  },
  {
    "path": "packages/docs/src/examples/v-window/usage.vue",
    "content": "<template>\n  <v-window\n    v-model=\"window\"\n    show-arrows\n  >\n    <v-window-item\n      v-for=\"n in length\"\n      :key=\"n\"\n    >\n      <v-card class=\"d-flex justify-center align-center\" height=\"200px\">\n        <span class=\"text-display-large\">Card {{ n }}</span>\n      </v-card>\n    </v-window-item>\n  </v-window>\n</template>\n\n<script>\n  export default {\n    data: () => ({\n      length: 3,\n      window: 0,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/why-vuetify/card-components.vue",
    "content": "<template>\n  <v-card>\n    <v-card-text>\n      Lorem ipsum dolor sit amet <strong>consectetur</strong> adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! <span class=\"text-primary\">Eaque cupiditate minima</span>, at placeat totam, <i>magni doloremque veniam neque</i> porro libero rerum unde voluptatem!\n    </v-card-text>\n\n    <v-card-title>Title</v-card-title>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/why-vuetify/card-props.vue",
    "content": "<template>\n  <v-card\n    text=\"Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! Eaque cupiditate minima, at placeat totam, magni doloremque veniam neque porro libero rerum unde voluptatem!\"\n    title=\"Title\"\n  ></v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/why-vuetify/card-slots.vue",
    "content": "<template>\n  <v-card>\n    <template v-slot:title>\n      Title\n    </template>\n\n    <template v-slot:text>\n      Lorem ipsum dolor sit amet <strong>consectetur</strong> adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus! <span class=\"text-primary\">Eaque cupiditate minima</span>, at placeat totam, <i>magni doloremque veniam neque</i> porro libero rerum unde voluptatem!\n    </template>\n  </v-card>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/wireframes/baseline.vue",
    "content": "<template>\n  <v-app id=\"inspire\">\n    <v-navigation-drawer v-model=\"drawer\">\n      <!--  -->\n    </v-navigation-drawer>\n\n    <v-app-bar>\n      <v-app-bar-nav-icon @click=\"drawer = !drawer\"></v-app-bar-nav-icon>\n\n      <v-app-bar-title>Application</v-app-bar-title>\n    </v-app-bar>\n\n    <v-main>\n      <!--  -->\n    </v-main>\n  </v-app>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const drawer = ref(null)\n</script>\n\n<script>\n  export default {\n    data: () => ({ drawer: null }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/wireframes/constrained.vue",
    "content": "<template>\n  <v-app id=\"inspire\">\n    <v-app-bar flat>\n      <v-container class=\"mx-auto d-flex align-center justify-center\">\n        <v-avatar\n          class=\"me-4 \"\n          color=\"grey-darken-1\"\n          size=\"32\"\n        ></v-avatar>\n\n        <v-btn\n          v-for=\"link in links\"\n          :key=\"link\"\n          :text=\"link\"\n          variant=\"text\"\n        ></v-btn>\n\n        <v-spacer></v-spacer>\n\n        <v-responsive max-width=\"160\">\n          <v-text-field\n            density=\"compact\"\n            label=\"Search\"\n            rounded=\"lg\"\n            variant=\"solo-filled\"\n            flat\n            hide-details\n            single-line\n          ></v-text-field>\n        </v-responsive>\n      </v-container>\n    </v-app-bar>\n\n    <v-main class=\"bg-grey-lighten-3\">\n      <v-container>\n        <v-row>\n          <v-col cols=\"2\">\n            <v-sheet rounded=\"lg\">\n              <v-list rounded=\"lg\">\n                <v-list-item\n                  v-for=\"n in 5\"\n                  :key=\"n\"\n                  :title=\"`List Item ${n}`\"\n                  link\n                ></v-list-item>\n\n                <v-divider class=\"my-2\"></v-divider>\n\n                <v-list-item\n                  color=\"grey-lighten-4\"\n                  title=\"Refresh\"\n                  link\n                ></v-list-item>\n              </v-list>\n            </v-sheet>\n          </v-col>\n\n          <v-col>\n            <v-sheet\n              min-height=\"70vh\"\n              rounded=\"lg\"\n            >\n              <!--  -->\n            </v-sheet>\n          </v-col>\n        </v-row>\n      </v-container>\n    </v-main>\n  </v-app>\n</template>\n\n<script setup>\n  const links = [\n    'Dashboard',\n    'Messages',\n    'Profile',\n    'Updates',\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      links: [\n        'Dashboard',\n        'Messages',\n        'Profile',\n        'Updates',\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/wireframes/discord.vue",
    "content": "<template>\n  <v-app id=\"inspire\">\n    <v-system-bar>\n      <v-spacer></v-spacer>\n\n      <v-icon>mdi-square</v-icon>\n\n      <v-icon>mdi-circle</v-icon>\n\n      <v-icon>mdi-triangle</v-icon>\n    </v-system-bar>\n\n    <v-navigation-drawer\n      color=\"grey-lighten-3\"\n      rail\n    >\n      <v-avatar\n        class=\"d-block text-center mx-auto mt-4\"\n        color=\"grey-darken-1\"\n        size=\"36\"\n      ></v-avatar>\n\n      <v-divider class=\"mx-3 my-5\"></v-divider>\n\n      <v-avatar\n        v-for=\"n in 6\"\n        :key=\"n\"\n        class=\"d-block text-center mx-auto mb-9\"\n        color=\"grey-lighten-1\"\n        size=\"28\"\n      ></v-avatar>\n    </v-navigation-drawer>\n\n    <v-navigation-drawer width=\"244\">\n      <v-sheet\n        color=\"grey-lighten-5\"\n        height=\"128\"\n        width=\"100%\"\n      ></v-sheet>\n\n      <v-list>\n        <v-list-item\n          v-for=\"n in 5\"\n          :key=\"n\"\n          :title=\"`Item ${ n }`\"\n          link\n        ></v-list-item>\n      </v-list>\n    </v-navigation-drawer>\n\n    <v-app-bar\n      class=\"px-3\"\n      color=\"grey-lighten-4\"\n      height=\"72\"\n      flat\n    >\n      <v-spacer></v-spacer>\n\n      <v-responsive max-width=\"156\">\n        <v-text-field\n          bg-color=\"grey-lighten-1\"\n          density=\"compact\"\n          rounded=\"pill\"\n          variant=\"solo-filled\"\n          flat\n          hide-details\n        ></v-text-field>\n      </v-responsive>\n    </v-app-bar>\n\n    <v-main><!--  --></v-main>\n\n    <v-navigation-drawer location=\"right\">\n      <v-list>\n        <v-list-item\n          v-for=\"n in 5\"\n          :key=\"n\"\n          :title=\"`Item ${ n }`\"\n          link\n        ></v-list-item>\n      </v-list>\n    </v-navigation-drawer>\n\n    <v-footer\n      height=\"72\"\n      app\n    >\n      <v-text-field\n        bg-color=\"grey-lighten-1\"\n        class=\"overflow-hidden\"\n        density=\"compact\"\n        rounded=\"pill\"\n        variant=\"solo-filled\"\n        flat\n        hide-details\n      ></v-text-field>\n    </v-footer>\n  </v-app>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/wireframes/extended-toolbar.vue",
    "content": "<template>\n  <v-app id=\"inspire\">\n    <v-app-bar extended>\n      <v-app-bar-nav-icon></v-app-bar-nav-icon>\n\n      <v-app-bar-title>Application</v-app-bar-title>\n\n      <v-btn icon=\"mdi-dots-vertical\">\n      </v-btn>\n    </v-app-bar>\n\n    <v-main>\n      <v-container>\n        <v-row>\n          <v-col\n            v-for=\"n in 24\"\n            :key=\"n\"\n            cols=\"4\"\n          >\n            <v-card height=\"200\"></v-card>\n          </v-col>\n        </v-row>\n      </v-container>\n    </v-main>\n  </v-app>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/wireframes/inbox.vue",
    "content": "<template>\n  <v-app id=\"inspire\">\n    <v-system-bar>\n      <v-spacer></v-spacer>\n\n      <v-icon>mdi-square</v-icon>\n\n      <v-icon>mdi-circle</v-icon>\n\n      <v-icon>mdi-triangle</v-icon>\n    </v-system-bar>\n\n    <v-navigation-drawer v-model=\"drawer\">\n      <v-sheet\n        class=\"pa-4\"\n        color=\"grey-lighten-4\"\n      >\n        <v-avatar\n          class=\"mb-4\"\n          color=\"grey-darken-1\"\n          size=\"64\"\n        ></v-avatar>\n\n        <div>john@google.com</div>\n      </v-sheet>\n\n      <v-divider></v-divider>\n\n      <v-list>\n        <v-list-item\n          v-for=\"[icon, text] in links\"\n          :key=\"icon\"\n          :prepend-icon=\"icon\"\n          :title=\"text\"\n          link\n        ></v-list-item>\n      </v-list>\n    </v-navigation-drawer>\n\n    <v-main>\n      <v-container\n        class=\"py-8 px-6\"\n        fluid\n      >\n        <v-row>\n          <v-col\n            v-for=\"card in cards\"\n            :key=\"card\"\n            cols=\"12\"\n          >\n            <v-card>\n              <v-list lines=\"two\">\n                <v-list-subheader :title=\"card\"></v-list-subheader>\n\n                <template v-for=\"n in 6\" :key=\"n\">\n                  <v-list-item>\n                    <template v-slot:prepend>\n                      <v-avatar color=\"grey-darken-1\"></v-avatar>\n                    </template>\n\n                    <v-list-item-title :title=\"`Message ${n}`\"></v-list-item-title>\n\n                    <v-list-item-subtitle title=\"Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nihil repellendus distinctio similique\"></v-list-item-subtitle>\n                  </v-list-item>\n\n                  <v-divider\n                    v-if=\"n !== 6\"\n                    :key=\"`divider-${n}`\"\n                    inset\n                  ></v-divider>\n                </template>\n              </v-list>\n            </v-card>\n          </v-col>\n        </v-row>\n      </v-container>\n    </v-main>\n  </v-app>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const cards = ['Today', 'Yesterday']\n  const links = [\n    ['mdi-inbox-arrow-down', 'Inbox'],\n    ['mdi-send', 'Send'],\n    ['mdi-delete', 'Trash'],\n    ['mdi-alert-octagon', 'Spam'],\n  ]\n\n  const drawer = ref(null)\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      cards: ['Today', 'Yesterday'],\n      drawer: null,\n      links: [\n        ['mdi-inbox-arrow-down', 'Inbox'],\n        ['mdi-send', 'Send'],\n        ['mdi-delete', 'Trash'],\n        ['mdi-alert-octagon', 'Spam'],\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/wireframes/side-navigation.vue",
    "content": "<template>\n  <v-app id=\"inspire\">\n    <v-navigation-drawer\n      class=\"pt-4\"\n      color=\"grey-lighten-3\"\n      model-value\n      rail\n    >\n      <v-avatar\n        v-for=\"n in 6\"\n        :key=\"n\"\n        :color=\"`grey-${n === 1 ? 'darken' : 'lighten'}-1`\"\n        :size=\"n === 1 ? 36 : 20\"\n        class=\"d-block text-center mx-auto mb-9\"\n      ></v-avatar>\n    </v-navigation-drawer>\n\n    <v-main>\n      <!--  -->\n    </v-main>\n  </v-app>\n</template>\n"
  },
  {
    "path": "packages/docs/src/examples/wireframes/steam.vue",
    "content": "<template>\n  <v-app id=\"inspire\">\n    <v-system-bar>\n      <v-spacer></v-spacer>\n\n      <v-icon>mdi-square</v-icon>\n\n      <v-icon>mdi-circle</v-icon>\n\n      <v-icon>mdi-triangle</v-icon>\n    </v-system-bar>\n\n    <v-app-bar\n      color=\"grey-lighten-4\"\n      height=\"72\"\n      flat\n    >\n      <v-avatar\n        class=\"ms-2\"\n        color=\"surface-variant\"\n        size=\"32\"\n        variant=\"flat\"\n      ></v-avatar>\n      <v-avatar\n        class=\"mx-2\"\n        color=\"surface-variant\"\n        size=\"32\"\n        variant=\"flat\"\n      ></v-avatar>\n\n      <v-btn\n        class=\"me-2\"\n        color=\"grey\"\n        height=\"40\"\n        variant=\"flat\"\n        width=\"80\"\n      ></v-btn>\n\n      <v-btn\n        class=\"me-2\"\n        color=\"grey\"\n        height=\"40\"\n        variant=\"flat\"\n        width=\"100\"\n      ></v-btn>\n\n      <v-btn\n        class=\"me-2\"\n        color=\"grey\"\n        height=\"40\"\n        variant=\"flat\"\n        width=\"120\"\n      ></v-btn>\n\n      <v-btn\n        class=\"me-2\"\n        color=\"grey\"\n        height=\"40\"\n        variant=\"flat\"\n        width=\"120\"\n      ></v-btn>\n\n      <v-spacer></v-spacer>\n    </v-app-bar>\n\n    <v-footer\n      color=\"grey\"\n      height=\"44\"\n      app\n    ></v-footer>\n\n    <v-navigation-drawer floating>\n      <div class=\"d-flex px-2 my-2\">\n        <v-btn\n          class=\"flex-grow-1\"\n          color=\"grey\"\n          height=\"40\"\n          variant=\"flat\"\n        ></v-btn>\n\n        <v-avatar\n          class=\"ms-2\"\n          color=\"surface-variant\"\n          variant=\"flat\"\n          rounded\n        ></v-avatar>\n      </div>\n\n      <div class=\"d-flex px-2 my-2 align-center\">\n        <v-btn\n          class=\"flex-grow-1 me-2\"\n          color=\"grey-lighten-4\"\n          height=\"40\"\n          variant=\"flat\"\n        ></v-btn>\n\n        <v-avatar\n          color=\"surface-variant\"\n          size=\"18\"\n        ></v-avatar>\n\n        <v-avatar\n          class=\"ms-1\"\n          color=\"surface-variant\"\n          size=\"18\"\n        ></v-avatar>\n      </div>\n\n      <div class=\"px-2 my-2\">\n        <v-text-field\n          class=\"mb-4\"\n          density=\"compact\"\n          prepend-inner-icon=\"mdi-magnify\"\n          variant=\"solo-filled\"\n          flat\n          hide-details\n        ></v-text-field>\n\n        <v-sheet\n          class=\"mb-2\"\n          color=\"surface-variant\"\n          height=\"24\"\n          rounded=\"pill\"\n          width=\"50%\"\n        ></v-sheet>\n\n        <v-sheet\n          class=\"mb-1\"\n          color=\"grey-lighten-1\"\n          height=\"12\"\n          rounded=\"pill\"\n          width=\"40%\"\n        ></v-sheet>\n\n        <v-sheet\n          class=\"mb-1\"\n          color=\"grey-lighten-1\"\n          height=\"12\"\n          rounded=\"pill\"\n          width=\"20%\"\n        ></v-sheet>\n\n        <v-sheet\n          class=\"mb-1\"\n          color=\"grey-lighten-1\"\n          height=\"12\"\n          rounded=\"pill\"\n          width=\"90%\"\n        ></v-sheet>\n\n        <v-sheet\n          color=\"grey-lighten-1\"\n          height=\"12\"\n          rounded=\"pill\"\n          width=\"70%\"\n        ></v-sheet>\n\n        <v-divider class=\"my-6\"></v-divider>\n\n        <v-sheet\n          class=\"mb-2\"\n          color=\"surface-variant\"\n          height=\"24\"\n          rounded=\"pill\"\n          width=\"30%\"\n        ></v-sheet>\n\n        <v-sheet\n          class=\"mb-1\"\n          color=\"grey-lighten-1\"\n          height=\"12\"\n          rounded=\"pill\"\n          width=\"65%\"\n        ></v-sheet>\n\n        <v-sheet\n          class=\"mb-1\"\n          color=\"grey-lighten-1\"\n          height=\"12\"\n          rounded=\"pill\"\n          width=\"70%\"\n        ></v-sheet>\n\n        <v-sheet\n          class=\"mb-1\"\n          color=\"grey-lighten-1\"\n          height=\"12\"\n          rounded=\"pill\"\n          width=\"40%\"\n        ></v-sheet>\n\n        <v-sheet\n          color=\"grey-lighten-1\"\n          height=\"12\"\n          rounded=\"pill\"\n          width=\"100%\"\n        ></v-sheet>\n\n        <v-divider class=\"my-6\"></v-divider>\n      </div>\n    </v-navigation-drawer>\n\n    <v-main>\n      <v-sheet\n        class=\"mx-auto pa-2 pt-6\"\n        color=\"grey-lighten-4\"\n      >\n        <v-sheet\n          color=\"grey-lighten-2\"\n          height=\"24\"\n          rounded=\"pill\"\n          width=\"88\"\n        ></v-sheet>\n\n        <v-slide-group show-arrows>\n          <v-slide-group-item\n            v-for=\"n in 5\"\n            :key=\"n\"\n          >\n            <v-sheet\n              class=\"ma-3\"\n              color=\"grey-lighten-1\"\n              height=\"200\"\n              width=\"250\"\n              rounded\n            ></v-sheet>\n          </v-slide-group-item>\n        </v-slide-group>\n      </v-sheet>\n\n      <v-sheet\n        class=\"mx-auto pa-2 pt-6\"\n        color=\"grey-lighten-2\"\n      >\n        <v-sheet\n          color=\"grey\"\n          height=\"24\"\n          rounded=\"pill\"\n          width=\"88\"\n        ></v-sheet>\n\n        <v-slide-group show-arrows>\n          <v-slide-group-item\n            v-for=\"n in 15\"\n            :key=\"n\"\n          >\n            <v-sheet\n              :width=\"n === 1 ? 300 : 150\"\n              class=\"ma-3\"\n              color=\"grey-lighten-1\"\n              height=\"200\"\n              rounded\n            ></v-sheet>\n          </v-slide-group-item>\n        </v-slide-group>\n\n        <v-container fluid>\n          <v-row>\n            <v-col\n              v-for=\"n in 24\"\n              :key=\"n\"\n              cols=\"2\"\n            >\n              <v-sheet\n                color=\"grey-lighten-1\"\n                height=\"200\"\n                rounded\n              ></v-sheet>\n            </v-col>\n          </v-row>\n        </v-container>\n      </v-sheet>\n    </v-main>\n  </v-app>\n</template>\n\n<script setup>\n  //\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/wireframes/system-bar.vue",
    "content": "<template>\n  <v-app id=\"inspire\">\n    <v-system-bar>\n      <v-spacer></v-spacer>\n\n      <v-icon>mdi-square</v-icon>\n\n      <v-icon>mdi-circle</v-icon>\n\n      <v-icon>mdi-triangle</v-icon>\n    </v-system-bar>\n\n    <v-app-bar>\n      <v-app-bar-nav-icon @click=\"drawer = !drawer\"></v-app-bar-nav-icon>\n\n      <v-app-bar-title>Application</v-app-bar-title>\n    </v-app-bar>\n\n    <v-navigation-drawer\n      v-model=\"drawer\"\n      temporary\n    >\n      <!--  -->\n    </v-navigation-drawer>\n\n    <v-main class=\"bg-grey-lighten-2\">\n      <v-container>\n        <v-row>\n          <template v-for=\"n in 4\" :key=\"n\">\n            <v-col\n              class=\"mt-2\"\n              cols=\"12\"\n            >\n              <strong>Category {{ n }}</strong>\n            </v-col>\n\n            <v-col\n              v-for=\"j in 6\"\n              :key=\"`${n}${j}`\"\n              cols=\"6\"\n              md=\"2\"\n            >\n              <v-sheet height=\"150\"></v-sheet>\n            </v-col>\n          </template>\n        </v-row>\n      </v-container>\n    </v-main>\n  </v-app>\n</template>\n\n<script setup>\n  import { ref } from 'vue'\n\n  const drawer = ref(null)\n</script>\n\n<script>\n  export default {\n    data: () => ({ drawer: null }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/examples/wireframes/three-column.vue",
    "content": "<template>\n  <v-app id=\"inspire\">\n    <v-app-bar\n      class=\"px-3\"\n      density=\"compact\"\n      flat\n    >\n      <v-avatar\n        class=\"hidden-md-and-up\"\n        color=\"grey-darken-1\"\n        size=\"32\"\n      ></v-avatar>\n\n      <v-spacer></v-spacer>\n\n      <v-tabs\n        align-tabs=\"center\"\n        color=\"grey-darken-2\"\n      >\n        <v-tab\n          v-for=\"link in links\"\n          :key=\"link\"\n          :text=\"link\"\n        ></v-tab>\n      </v-tabs>\n      <v-spacer></v-spacer>\n\n      <v-avatar\n        class=\"hidden-sm-and-down\"\n        color=\"grey-darken-1\"\n        size=\"32\"\n      ></v-avatar>\n    </v-app-bar>\n\n    <v-main class=\"bg-grey-lighten-3\">\n      <v-container>\n        <v-row>\n          <v-col\n            cols=\"12\"\n            md=\"2\"\n          >\n            <v-sheet\n              min-height=\"268\"\n              rounded=\"lg\"\n            >\n              <!--  -->\n            </v-sheet>\n          </v-col>\n\n          <v-col\n            cols=\"12\"\n            md=\"8\"\n          >\n            <v-sheet\n              min-height=\"70vh\"\n              rounded=\"lg\"\n            >\n              <!--  -->\n            </v-sheet>\n          </v-col>\n\n          <v-col\n            cols=\"12\"\n            md=\"2\"\n          >\n            <v-sheet\n              min-height=\"268\"\n              rounded=\"lg\"\n            >\n              <!--  -->\n            </v-sheet>\n          </v-col>\n        </v-row>\n      </v-container>\n    </v-main>\n  </v-app>\n</template>\n\n<script setup>\n  const links = [\n    'Dashboard',\n    'Messages',\n    'Profile',\n    'Updates',\n  ]\n</script>\n\n<script>\n  export default {\n    data: () => ({\n      links: [\n        'Dashboard',\n        'Messages',\n        'Profile',\n        'Updates',\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/docs/src/i18n/locales.json",
    "content": "[\n  {\n    \"title\": \"English\",\n    \"locale\": \"en\",\n    \"enabled\": true\n  },\n  {\n    \"title\": \"Español\",\n    \"locale\": \"es-MX\",\n    \"enabled\": true\n  },\n  {\n    \"title\": \"日本語\",\n    \"locale\": \"ja-JP\",\n    \"alternate\": \"ja\",\n    \"enabled\": true\n  },\n  {\n    \"title\": \"简体中文\",\n    \"locale\": \"zh-CN\",\n    \"alternate\": \"zh-Hans\",\n    \"enabled\": true\n  },\n  {\n    \"title\": \"Deutsch\",\n    \"locale\": \"de-DE\",\n    \"alternate\": \"de\",\n    \"enabled\": false\n  },\n  {\n    \"title\": \"Français\",\n    \"locale\": \"fr-FR\",\n    \"alternate\": \"fr\",\n    \"enabled\": false\n  },\n  {\n    \"title\": \"Русский\",\n    \"locale\": \"ru-RU\",\n    \"alternate\": \"ru\",\n    \"enabled\": false\n  },\n  {\n    \"title\": \"한국어\",\n    \"locale\": \"ko-KR\",\n    \"alternate\": \"ko\",\n    \"enabled\": false\n  }\n]\n"
  },
  {
    "path": "packages/docs/src/i18n/messages/.gitignore",
    "content": "*\n!.gitignore\n!en.json"
  },
  {
    "path": "packages/docs/src/i18n/messages/en.json",
    "content": "{\n  \"home\": {\n    \"get-started\": \"Get Started\",\n    \"why-vuetify\": \"Why Vuetify?\",\n    \"entry\": {\n      \"chip\": \"#1 Vue UI Library\",\n      \"title-prefix\": \"A complete\",\n      \"title-highlight\": \"design system\",\n      \"title-suffix\": \"that works.\",\n      \"subtitle\": \"Built by the Vue Community, Backed by Sponsors.\",\n      \"latest\": \"Latest\",\n      \"hello-vuetify\": \"Hello Vuetify\"\n    },\n    \"special-sponsor\": \"Special Sponsor\",\n    \"sponsors\": {\n      \"title\": \"Sponsors & Backers\",\n      \"description\": \"Vuetify is proudly supported by these amazing companies and individuals. If you'd like to join them, please consider sponsoring Vuetify's development.\",\n      \"become-sponsor\": \"Become a Sponsor\"\n    },\n    \"ecosystem\": {\n      \"title\": \"More than just Components\",\n      \"subtitle\": \"A complete Vue ecosystem\",\n      \"description\": \"Vuetify is a complete Vue ecosystem that provides you with all of the tools necessary to create beautiful content rich web applications.\"\n    },\n    \"one\": {\n      \"title\": \"Vuetify One\",\n      \"subtitle\": \"Everything in One Place\",\n      \"description\": \"A unified platform providing powerful all Ecosystem Tools in one place. Build faster, collaborate better, and create stunning Vuetify applications.\",\n      \"see-benefits\": \"See Subscription Benefits\",\n      \"tools\": {\n        \"play\": \"An interactive playground to experiment with Vuetify components and features in real-time.\",\n        \"bin\": \"A code sharing platform tailored for Vuetify projects, enabling easy collaboration and sharing of code snippets.\",\n        \"studio\": \"A visual development environment for building Vuetify applications with drag-and-drop components and real-time previews.\",\n        \"link\": \"A URL shortening service designed for Vuetify developers to create and manage short links efficiently.\",\n        \"mcp\": \"Model Context Protocol (MCP) server providing Vuetify component information and documentation.\",\n        \"issues\": \"Easily report issues and request features for projects in the Vuetify Ecosystem.\"\n      }\n    },\n    \"tooling\": {\n      \"title\": \"Vuetify Tooling\",\n      \"subtitle\": \"Tools & Resources\",\n      \"description\": \"Vuetify provides a suite of tools for managing your Vuetify projects.\",\n      \"headers\": {\n        \"tool\": \"Tool\",\n        \"type\": \"Type\",\n        \"description\": \"Description\"\n      },\n      \"tools\": {\n        \"create\": {\n          \"title\": \"Vuetify Create\",\n          \"type\": \"Scaffolding\",\n          \"description\": \"Scaffold your next Vuetify application with just a few commands.\"\n        },\n        \"cli\": {\n          \"title\": \"Vuetify CLI\",\n          \"type\": \"CLI\",\n          \"description\": \"Command-line interface for managing Vuetify projects.\"\n        },\n        \"uikit\": {\n          \"title\": \"Vuetify UI Kit\",\n          \"type\": \"Design\",\n          \"description\": \"Figma UI Kit based on Material Design for creating custom components.\"\n        },\n        \"eslint-config\": {\n          \"title\": \"Vuetify ESLint Config\",\n          \"type\": \"Linting\",\n          \"description\": \"Opinionated ESLint config to keep your code clean and consistent.\"\n        },\n        \"eslint-plugin\": {\n          \"title\": \"Vuetify ESLint Plugin\",\n          \"type\": \"Migration\",\n          \"description\": \"Automated version upgrade plugin for seamless migrations.\"\n        },\n        \"loader\": {\n          \"title\": \"Vuetify Loader\",\n          \"type\": \"Build\",\n          \"description\": \"Vite and Webpack loader for automatic component imports.\"\n        }\n      }\n    },\n    \"snips\": {\n      \"subtitle\": \"Premium Examples\",\n      \"title-line1\": \"Beautiful UI snippets,\",\n      \"title-line2\": \"built with Vuetify\",\n      \"description\": \"Vuetify Snips is a collection of over 560 beautifully crafted UI snippets, built with Vuetify, aimed at making your development process easier and faster.\",\n      \"browse\": \"Browse Vuetify Snips\"\n    },\n    \"store\": {\n      \"title\": \"Vuetify Store\",\n      \"subtitle\": \"Premium Templates & Themes\",\n      \"description\": \"Browse our collection of premium templates, themes and UI kits. All themes are built with Vuetify and are available for everyone.\",\n      \"see-more\": \"See More Templates\"\n    },\n    \"support\": {\n      \"title\": \"Need support with your Vuetify project?\",\n      \"subtitle\": \"Vuetify Support Services\",\n      \"description\": \"We've got you covered. We offer a range of support options to help you get the most out of Vuetify.\",\n      \"get-support\": \"Get Support Now\",\n      \"services\": {\n        \"developer\": {\n          \"title\": \"Single Developer Support\",\n          \"subtitle\": \"Get professional support from the experts behind Vuetify.\"\n        },\n        \"consulting\": {\n          \"title\": \"Consulting Services\",\n          \"subtitle\": \"Epicmax provides consulting services for your project.\"\n        },\n        \"lts\": {\n          \"title\": \"Extended LTS support\",\n          \"subtitle\": \"HeroDevs provides extended long-term support for Vuetify 2 users.\"\n        }\n      }\n    },\n    \"discord\": {\n      \"title\": \"Join our community of 40k+ developers\",\n      \"description\": \"Join us to get help with your Vuetify projects, share your work, and connect with other developers on Discord.\",\n      \"join\": \"Join Our Discord\"\n    },\n    \"blogs\": {\n      \"title\": \"Vuetify Blog\",\n      \"subtitle\": \"Latest news and updates\",\n      \"description\": \"Stay up to date with the latest news and updates from the Vuetify team.\",\n      \"read-more\": \"Read more\",\n      \"read-more-posts\": \"Read More Posts\"\n    },\n    \"gallery\": {\n      \"title\": \"Component Gallery\",\n      \"description\": \"Vuetify provides a comprehensive collection of components that can be used to build your application.\",\n      \"system-bar\": \"Vuetify Gallery\",\n      \"application\": \"Application\",\n      \"settings\": \"Settings\",\n      \"logout\": \"Logout\"\n    }\n  },\n  \"about\": \"About\",\n  \"accessibility\": \"Accessibility (a11y)\",\n  \"ads\": \"Ads\",\n  \"ads-via-vuetify\": \"ads via Vuetify\",\n  \"all-components\": \"All Components\",\n  \"alpha\": \"Alpha\",\n  \"api\": \"API\",\n  \"api-headers\": {\n    \"links\": \"Component Pages\",\n    \"argument\": \"Argument\",\n    \"events\": \"Events\",\n    \"functions\": \"Functions\",\n    \"modifiers\": \"Modifiers\",\n    \"props\": \"Props\",\n    \"sass\": \"SASS Variables\",\n    \"slots\": \"Slots\",\n    \"exposed\": \"Exposed\",\n    \"value\": \"Value\"\n  },\n  \"api-explorer\": \"API Explorer\",\n  \"application\": \"Application\",\n  \"apply\": \"Apply\",\n  \"awesome\": \"Awesome\",\n  \"bars\": \"Bars\",\n  \"become-a-sponsor\": \"Become a sponsor\",\n  \"blackguard\": \"Blackguard\",\n  \"blog\": \"Blog\",\n  \"brand-kit\": \"Brand Kit\",\n  \"breakpoints-table\": {\n    \"caption\": \"Material Design Breakpoints\",\n    \"small-to-large-handset\": \"Small to large phone\",\n    \"small-to-medium-tablet\": \"Small to medium tablet\",\n    \"large-tablet-to-laptop\": \"Large tablet to laptop\",\n    \"desktop\": \"Laptop to desktop\",\n    \"large-to-extra-large\": \"1080p to 1440p desktop\",\n    \"extra-large-to-extra-extra-large\": \"4k and ultra-wide\",\n    \"spec\": \"Specification\"\n  },\n  \"breakpoints\": \"Breakpoints\",\n  \"browse-components\": \"Browse Components\",\n  \"dark-code\": \"Dark code blocks\",\n  \"dark-code-message\": \"Change all code blocks to use a dark theme.\",\n  \"documentation-build\": \"Documentation Build\",\n  \"business\": \"Business\",\n  \"cancel\": \"Cancel\",\n  \"close\": \"Close\",\n  \"code\": \"Code\",\n  \"colors\": \"Colors\",\n  \"composition\": \"Composition\",\n  \"copied\": \"Copied!\",\n  \"copy-link\": \"Copy link\",\n  \"configuration\": \"Configuration\",\n  \"company\": \"Company\",\n  \"comparison\": {\n    \"average\": \"**Based on average of all Major/Minor/Patch releases over the last 12 months.\",\n    \"a11y\": \"Accessibility and section 508 support\",\n    \"caption\": \"Vue Framework Comparison {year}\",\n    \"enterprise\": \"Business and enterprise support\",\n    \"lts\": \"18 months LTS (Long-term support)\",\n    \"release\": \"Release cadence**\",\n    \"rtl\": \"RTL support\",\n    \"themes\": \"Premium themes\",\n    \"tree\": \"Treeshaking\"\n  },\n  \"component\": \"Component\",\n  \"components\": \"Components\",\n  \"concepts\": \"Common concepts\",\n  \"contents\": \"Contents\",\n  \"containment\": \"Containment\",\n  \"contribute\": {\n    \"edit-page\": \"Edit this page on {url}\",\n    \"last-updated\": \"Last updated:\"\n  },\n  \"communication\": \"Communication\",\n  \"communication-message\": \"Vuetify will communicate with you through banners and notifications. You can disable these features here or reset your local notification cache.\",\n  \"community\": \"Community\",\n  \"community-support\": \"Community support\",\n  \"contact-us\": \"Contact Us\",\n  \"cookie-policy\": \"Cookie Policy\",\n  \"copy-as-markdown\": \"Copy Page as Markdown\",\n  \"copy-example-source\": \"Copy example source\",\n  \"copy-source\": \"Copy source\",\n  \"copyright\": \"Copyright {0}\",\n  \"create\": \"Create\",\n  \"css-utilities\": \"CSS Utilities\",\n  \"customization\": \"Customization\",\n  \"dark\": \"Dark\",\n  \"dashboard\": {\n    \"connected-accounts\": \"Connected accounts\",\n    \"advanced-options\": {\n      \"danger-zone\": \"Danger zone\",\n      \"danger-zone-message\": \"The following settings are for development purposes.\"\n    },\n    \"perks\": {\n      \"alert\": \"Support Vuetify and gain access to exclusive documentation perks and features for only\",\n      \"avatar\": \"Avatar\",\n      \"avatar-message\": \"Add a custom avatar image displayed on the user profile and user bar.\",\n      \"disable-ads\": \"Disable Ads\",\n      \"disable-ads-message\": \"Disable advertisements on all documentation pages.\",\n      \"enable-ads\": \"Enable Ads\",\n      \"experience\": \"Experience\",\n      \"experience-message\": \"These options change your browsing experience within the documentation.\",\n      \"layout\": \"Layout\",\n      \"layout-message\": \"Modify various the visibility and behavior of various elements of the documentation.\",\n      \"rail-drawer\": \"Rail drawer\",\n      \"rail-drawer-message\": \"Show the navigation drawer as a rail that expands on hover\",\n      \"disable-quickbar\": \"Disable Quickbar\",\n      \"disable-quickbar-message\": \"Hide the Quickbar actions located on the top right of the documentation\",\n      \"enable-pins\": \"Enable pins\",\n      \"enable-pins-message\": \"Bookmark and access vital documentation pages for a more efficient workflow.\"\n    }\n  },\n  \"data-tables\": \"Data tables\",\n  \"data-and-display\": \"Data & display\",\n  \"grids\": \"Grids\",\n  \"details\": \"Details\",\n  \"developer-mode\": \"Developer mode\",\n  \"developer-mode-message\": \"Developer mode enables new features and functionality within the documentation that are still in development.\",\n  \"device\": \"Device\",\n  \"design-spec\": \"Design Specification\",\n  \"direction\": \"Direction\",\n  \"directive\": \"Directive\",\n  \"directives\": \"Directives\",\n  \"discuss-on-discord\": \"Discuss on Discord\",\n  \"discuss-on-github\": \"Discuss on GitHub\",\n  \"discussions\": \"Discussions\",\n  \"display\": \"Display\",\n  \"display-message\": \"Toggle various elements of the documentation experience.\",\n  \"documentation\": \"Documentation\",\n  \"documentation-status\": \"Documentation status\",\n  \"download-brand-kit\": \"Download Brand Kit\",\n  \"drawer-navigation-grouping\": \"Drawer navigation grouping\",\n  \"direct-support\": \"Direct support\",\n  \"discord\": \"Discord\",\n  \"done\": \"All done\",\n  \"edit-in-playground\": \"Edit in Vuetify Playground\",\n  \"open-in-playground\": \"Open in Vuetify Playground\",\n  \"view-in-figma\": \"View in Figma\",\n  \"edit-this-page\": \"Edit this page on\",\n  \"edit\": \"Edit\",\n  \"enable-banners\": \"Enable banners\",\n  \"enable-banners-message\": \"Banners are located at the top of the screen and usually provide general information about Vuetify.\",\n  \"enable-composition\": \"Enable Composition API\",\n  \"enable-composition-message\": \"Determines the script shown in code examples for components.\",\n  \"enable-inline-api\": \"Enable Inline API\",\n  \"enable-inline-api-message\": \"Display API tables inline on documentation pages.\",\n  \"enable-notifications\": \"Enable notifications\",\n  \"enable-notifications-message\": \"Notifications are located at the top right of the screen in the actions bar and provide information about new releases, updates, and other important information.\",\n  \"enable-pwa-refresh\": \"Enable Refresh Prompt\",\n  \"enable-pwa-refresh-message\": \"Display the refresh prompt when new documentation updates have been downloaded.\",\n  \"enterprise\": \"Enterprise\",\n  \"epicmax\": {\n    \"learn-more\": \"Learn more\",\n    \"title\": \"Need support with your Vuetify project?\",\n    \"message\": \"Epicmax is here to support you - whether it's migrating to Vue3, adjusting your Vue.js code, or building custom front-ends.\"\n  },\n  \"email-address\": \"Email address\",\n  \"esc\": \"Esc\",\n  \"extra-extra-large\": \"Extra extra large\",\n  \"extra-large\": \"Extra large\",\n  \"extra-small\": \"Extra small\",\n  \"faq\": \"FAQs\",\n  \"feature-guides\": \"Feature guides\",\n  \"features\": \"Features\",\n  \"feature-introduced-in\": \"This feature was introduced in {0}\",\n  \"feedback\": \"Feedback\",\n  \"figma-design\": \"Figma Design\",\n  \"file-a-bug-report\": \"File a bug report\",\n  \"focus\": \"Focus\",\n  \"for-enterprise\": \"For Enterprise\",\n  \"form-inputs-and-controls\": \"Form inputs & controls\",\n  \"framework-services\": \"Framework services\",\n  \"functional\": \"Functional\",\n  \"funding\": \"Funding\",\n  \"getting-started\": \"Getting started\",\n  \"get-help\": \"Get help\",\n  \"github\": \"GitHub\",\n  \"github-discussions\": \"GitHub discussions\",\n  \"github-issues\": \"GitHub issues\",\n  \"github-releases\": \"GitHub releases\",\n  \"grid\": \"Grid\",\n  \"groups\": \"Groups\",\n  \"guide\": \"Guide\",\n  \"guides\": \"Guides\",\n  \"help-translate\": \"Help translate\",\n  \"help-and-support\": \"Help and support\",\n  \"hide-source\": \"Hide source\",\n  \"homepage\": \"Vuetify Home Page\",\n  \"icon\": \"Icon\",\n  \"icons\": \"Icons\",\n  \"images-and-icons\": \"Images & icons\",\n  \"inline\": \"Inline\",\n  \"introduction\": \"Introduction\",\n  \"invert-example-colors\": \"Invert example colors\",\n  \"jobs\": \"Jobs\",\n  \"jobs-for-vue\": \"Jobs for Vue\",\n  \"joined\": \"Joined {date}\",\n  \"labs\": \"Labs\",\n  \"laptop\": \"Laptop\",\n  \"languages\": \"Languages\",\n  \"large\": \"Large\",\n  \"latest-commit\": \"Latest commit\",\n  \"latest-release\": \"Latest release\",\n  \"latest-releases\": \"Latest releases\",\n  \"layout\": \"Layout\",\n  \"layout-link\": \"Link to layout for {name}\",\n  \"learn\": \"Learn\",\n  \"licensing\": \"Licensing\",\n  \"light\": \"Light\",\n  \"link-only\": \"Link Only\",\n  \"load-more\": \"Load more...\",\n  \"login\": {\n    \"login\": \"Log in\",\n    \"logout\": \"Log out\",\n    \"to-vuetify\": \"Log in to Vuetify\",\n    \"welcome-back\": \"Welcome back!\",\n    \"tagline\": \"Sign in with GitHub or Discord to save your settings and unlock exclusive subscriber perks.\",\n    \"last-used\": \"Last used\",\n    \"with-github\": \"Continue with GitHub\",\n    \"with-discord\": \"Continue with Discord\",\n    \"connect-github\": \"Connect GitHub\",\n    \"connect-discord\": \"Connect Discord\"\n  },\n  \"logo\": \"Logo\",\n  \"ltr\": \"LTR\",\n  \"marked-read\": \"Mark all read\",\n  \"marked-unread\": \"Mark all unread\",\n  \"md\": \"Material Design\",\n  \"medium\": \"Medium\",\n  \"miscellaneous\": \"Miscellaneous\",\n  \"missing\": \"Could not load example `{file}`\",\n  \"mit-license\": \"MIT License\",\n  \"mixed\": \"Mixed\",\n  \"more-coming-soon\": \"More coming soon...\",\n  \"my-dashboard\": \"My Dashboard\",\n  \"name\": \"Name\",\n  \"navigation\": \"Navigation\",\n  \"new\": \"New\",\n  \"new-in\": \"New in v{version}\",\n  \"newsletter\": \"Newsletter\",\n  \"notifications\": \"Notifications\",\n  \"not-found\": \"Not Found\",\n  \"one\": \"One\",\n  \"open-github-release\": \"Open GitHub release\",\n  \"open-in-vuetify-bin\": \"Open in Vuetify Bin\",\n  \"open-issues\": \"Open issues\",\n  \"options\": \"Options\",\n  \"overlays\": \"Overlays\",\n  \"overview\": \"Overview\",\n  \"output\": \"Output\",\n  \"pastebin\": \"Pastebin\",\n  \"page\": \"Page\",\n  \"phone\": \"Phone\",\n  \"pickers\": \"Pickers\",\n  \"platinum-sponsors\": \"Platinum Sponsors\",\n  \"playground\": \"Playground\",\n  \"policy\": \"Policy\",\n  \"premiere-sponsors\": \"Premiere Sponsors\",\n  \"premium\": \"Premium\",\n  \"privacy-policy\": \"Privacy Policy\",\n  \"professional-support\": \"Professional support\",\n  \"progress\": \"Progress\",\n  \"providers\": \"Providers\",\n  \"published\": \"Published: {date}\",\n  \"range\": \"Range\",\n  \"read\": \"View Read ({number})\",\n  \"ready-text\": \"Continue your learning with related content selected by the {team} or move between pages by using the navigation links below.\",\n  \"ready\": \"Ready for more?\",\n  \"reddit\": \"Reddit\",\n  \"bluesky\": \"Bluesky\",\n  \"release-notes\": \"Release notes\",\n  \"released-by\": \"Released by: {author}\",\n  \"release\": \"Release\",\n  \"releases\": \"Releases\",\n  \"released-under-the\": \"Released under the {0}\",\n  \"report-a-bug\": \"Report a Bug\",\n  \"reset\": \"Reset\",\n  \"reset-all\": \"Reset All\",\n  \"reset-all-settings\": \"Reset All Settings\",\n  \"resources-and-tools\": \"Resources and tools\",\n  \"resources\": \"Resources\",\n  \"roadmap\": \"Roadmap\",\n  \"rtl\": \"RTL\",\n  \"scroll-to-top\": \"Scroll to top\",\n  \"sass-variables\": \"SASS Variables\",\n  \"search\": {\n    \"icons\": \"Search for icons (e.g. account, close)\",\n    \"label\": \"Search\",\n    \"looking\": \"Looking for\",\n    \"key-hint\": \"Ctrl+K\",\n    \"key-hint-mac\": \"Cmd+K\",\n    \"key-hint-slash\": \"Press /\",\n    \"results\": \"Your search results will appear here\",\n    \"no-results\": \"No results found\",\n    \"recent\": \"Recent\",\n    \"favorite\": \"Favorite\"\n  },\n  \"search-api\": \"Search API\",\n  \"search-jobs\": \"Search Jobs\",\n  \"search-sass-api\": \"Search SASS Variables\",\n  \"section\": \"Section\",\n  \"see-more-projects\": \"See More Projects\",\n  \"see-more-themes-from\": \"See More Themes From {vendor}\",\n  \"selection\": \"Selection\",\n  \"services\": \"Services\",\n  \"settings\": {\n    \"header\": \"Documentation settings\",\n    \"offline\": {\n      \"header\": \"Available offline\",\n      \"message\": \"Install a service worker to cache the entire site locally.\",\n      \"active-message\": \"Disable this option to remove the service worker and clear the cache.\",\n      \"offline-message\": \"You are currently offline, the site is served from cache.\",\n      \"pending\": \"There is a pending update, reload the page to activate.\",\n      \"reload\": \"Reload\"\n    }\n  },\n  \"slash-search\": \"Use / for Search hotkey\",\n  \"slash-search-message\": \"This option sets the bound search key to '/' from Cmd/Ctrl+K.\",\n  \"small\": \"Small\",\n  \"snips\": \"Snips\",\n  \"social\": \"Social\",\n  \"sponsor\": \"Sponsor\",\n  \"sponsors\": \"Sponsors\",\n  \"stack-overflow\": \"Stack overflow\",\n  \"standard\": \"Standard\",\n  \"store\": \"Store\",\n  \"styles\": \"Styles and animations\",\n  \"subscribe\": \"Subscribe\",\n  \"subscribe-to-our\": \"Subscribe to our {0}\",\n  \"subscribe-to-unlock\": \"Subscribe to Unlock\",\n  \"sync-settings\": \"Sync settings\",\n  \"sync-settings-message\": \"When logged in w/ GitHub, sync settings across devices.\",\n  \"support\": \"Support\",\n  \"system\": \"System\",\n  \"tables\": \"Tables\",\n  \"tablet\": \"Tablet\",\n  \"team\": \"Team\",\n  \"template\": \"Template\",\n  \"text\": \"Text\",\n  \"theme\": \"Theme\",\n  \"theme-message\": \"Customize your documentation experience with light and dark themes, as well as a combination of both named.\",\n  \"themes\": \"Themes\",\n  \"tidelift\": {\n    \"demo\": \"Request a demo\",\n    \"more\": \"Learn more\"\n  },\n  \"toggle\": \"Toggle {0}\",\n  \"tools\": \"Tools\",\n  \"transition\": \"Transition\",\n  \"translations\": \"Translations\",\n  \"type\": \"Type | Types\",\n  \"types\": \"Types\",\n  \"twitter\": \"Twitter\",\n  \"ui-components\": \"UI Components\",\n  \"ui\": \"UI\",\n  \"ultra-wide\": \"Ultra-wide\",\n  \"upgrade-guide\": \"Upgrade guide\",\n  \"unit-testing\": \"Unit testing\",\n  \"unread\": \"View Unread ({number})\",\n  \"unlock-with-github\": \"Unlock with GitHub\",\n  \"updated\": \"Updated\",\n  \"utility-classes\": \"Utility classes\",\n  \"video-courses\": \"Video courses\",\n  \"view-in-github\": \"View on GitHub\",\n  \"view-source\": \"View source\",\n  \"viewport\": \"Viewport\",\n  \"vuetify\": \"Vuetify\",\n  \"vuetify-one\": \"Vuetify One\",\n  \"vuetify-create\": \"Vuetify Create\",\n  \"vuetify-figma\": \"Vuetify Figma\",\n  \"vuetify-mcp\": \"Vuetify MCP\",\n  \"vuetify-studio\": \"Vuetify Studio\",\n  \"vuetify-bin\": \"Vuetify Bin\",\n  \"vuetify-issues\": \"Vuetify Issues\",\n  \"vuetify-link\": \"Vuetify Link\",\n  \"vuetify-play\": \"Vuetify Play\",\n  \"vuetify-snips\": \"Vuetify Snips\",\n  \"vuetify-store\": \"Vuetify Store\",\n  \"x\": \"Xitter\"\n}\n"
  },
  {
    "path": "packages/docs/src/layouts/404.vue",
    "content": "<template>\n  <DefaultLayout>\n    <v-container :style=\"{ minHeight: '100%' }\" class=\"d-flex\">\n      <v-row class=\"align-center justify-center\">\n        <v-col cols=\"auto\">\n          <h1 class=\"text-h3 text-primary\">\n            Whoops, 404\n          </h1>\n\n          <p>The page you were looking for does not exist</p>\n\n          <p>\n            <v-btn\n              :to=\"rpath('/getting-started/installation/')\"\n              color=\"primary\"\n              variant=\"outlined\"\n            >\n              Get me out of here!\n            </v-btn>\n          </p>\n\n          <p>\n            <AppLink :href=\"'https://v3.vuetifyjs.com' + route.fullPath\">Looking for Vuetify 3?</AppLink>\n          </p>\n        </v-col>\n      </v-row>\n    </v-container>\n  </DefaultLayout>\n</template>\n\n<script setup lang=\"ts\">\n  // Components\n  import DefaultLayout from '@/layouts/default.vue'\n\n  // Utilities\n  import { useHead } from '@unhead/vue'\n\n  const route = useRoute()\n  useHead({\n    title: 'Page not found',\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/layouts/blank.vue",
    "content": "<template>\n  <router-view />\n</template>\n"
  },
  {
    "path": "packages/docs/src/layouts/blog.vue",
    "content": "<template>\n  <v-app>\n    <VoNotificationsBanner order=\"-1\" />\n\n    <AppSettingsDrawer />\n\n    <AppBarBar />\n\n    <v-main class=\"text-start font-weight-light\">\n      <v-container style=\"max-width: 968px;\">\n        <router-view />\n      </v-container>\n    </v-main>\n\n    <VoSocialFooter app />\n  </v-app>\n</template>\n\n<script setup>\n  //\n</script>\n\n<style lang=\"sass\" scoped>\n  :deep(ul)\n    li > p\n      margin: 0\n</style>\n"
  },
  {
    "path": "packages/docs/src/layouts/default.vue",
    "content": "<template>\n  <v-app>\n    <VoNotificationsBanner order=\"-1\" />\n\n    <AppSettingsDrawer />\n\n    <AppBarBar />\n\n    <AppDrawerDrawer />\n\n    <AppToc v-if=\"!route.meta.fluid\" />\n\n    <AppBackToTop />\n\n    <v-main>\n      <slot>\n        <v-container\n          :style=\"style\"\n          class=\"pa-4 pa-sm-6 pa-md-8\"\n          tag=\"section\"\n          fluid\n        >\n          <slot name=\"view\">\n            <router-view v-slot=\"{ Component }\">\n              <v-fade-transition hide-on-leave>\n                <div :key=\"route.name\">\n                  <component :is=\"Component\" />\n                </div>\n              </v-fade-transition>\n            </router-view>\n          </slot>\n\n          <Backmatter v-if=\"hasBackmatter\" :key=\"route.name\" />\n        </v-container>\n      </slot>\n      <SponsorSnackbarPopup />\n    </v-main>\n  </v-app>\n</template>\n\n<script setup>\n  const route = useRoute()\n\n  const isApi = computed(() => route.meta?.category === 'api')\n  const isDashboard = computed(() => route.meta?.category === 'user')\n  const style = computed(() => ({ maxWidth: isApi.value || isDashboard.value ? '1368px' : '960px' }))\n  const hasBackmatter = computed(() => !isApi.value && route.meta?.backmatter !== false)\n</script>\n"
  },
  {
    "path": "packages/docs/src/layouts/home.vue",
    "content": "<template>\n  <v-app>\n    <VoNotificationsBanner order=\"-1\" />\n\n    <AppSettingsDrawer />\n\n    <AppBarBar />\n\n    <AppBackToTop />\n\n    <v-main class=\"text-center\">\n      <router-view />\n    </v-main>\n\n    <HomeFooter />\n  </v-app>\n</template>\n\n<style lang=\"sass\">\n#vue-component-framework\n  h1, h2, h3, h4, h5, h6\n    > a\n      display: none\n</style>\n"
  },
  {
    "path": "packages/docs/src/layouts/user.vue",
    "content": "<template>\n  <v-app>\n    <VoNotificationsBanner order=\"-1\" />\n\n    <AppSettingsDrawer />\n\n    <AppBarBar />\n\n    <AppDrawerDrawer />\n\n    <v-main>\n      <router-view v-slot=\"{ Component }\">\n        <v-fade-transition hide-on-leave>\n          <div :key=\"route.name\">\n            <component :is=\"Component\" />\n          </div>\n        </v-fade-transition>\n      </router-view>\n    </v-main>\n  </v-app>\n</template>\n\n<script setup>\n  const route = useRoute()\n  const auth = useAuthStore()\n\n  onMounted(async () => {\n    await auth.verify()\n  })\n\n  onBeforeRouteUpdate(async () => {\n    await auth.verify()\n  })\n</script>\n"
  },
  {
    "path": "packages/docs/src/layouts/wireframe.vue",
    "content": "<template>\n  <router-view />\n\n  <v-btn\n    :href=\"href\"\n    color=\"primary\"\n    icon=\"mdi-github\"\n    rel=\"noopener\"\n    style=\"position: fixed; bottom: 12px; right: 12px; z-index: 2000;\"\n    target=\"_blank\"\n  />\n</template>\n\n<script setup>\n  const route = useRoute()\n  const paths = route.path.split('/').filter(p => p.length > 0)\n  const href = `https://github.com/vuetifyjs/vuetify/blob/master/packages/docs/src/examples/wireframes/${paths.at(-1)}.vue`\n</script>\n"
  },
  {
    "path": "packages/docs/src/main.scss",
    "content": "@layer vuetify-core, base, vuetify-components, vuetify-overrides, vuetify-utilities, vuetify-final;\n"
  },
  {
    "path": "packages/docs/src/main.ts",
    "content": "// Styles\nimport './main.scss'\nimport 'prism-theme-vars/base.css'\n\n// Plugins\nimport * as Swetrix from 'swetrix'\nimport * as Sentry from '@sentry/vue'\nimport { createApp } from 'vue'\nimport { createRouter, createWebHistory } from 'vue-router'\nimport { createHead } from '@unhead/vue/client'\nimport { installVuetify } from '@/plugins/vuetify'\nimport { installPinia, pinia } from '@/plugins/pinia'\nimport { installGlobalComponents } from '@/plugins/global-components'\nimport { installOne } from '@/plugins/one'\nimport { installI18n } from '@/plugins/i18n'\nimport { useAppStore } from '@/stores/app'\nimport { useLocaleStore } from '@/stores/locale'\nimport { installPwa } from '@/plugins/pwa'\nimport { useUserStore } from '@vuetify/one'\n\n// App\nimport App from './App.vue'\n\n// Virtual\n// import 'virtual:api'\nimport { setupLayouts } from 'virtual:generated-layouts'\n\n// Utilities\nimport {\n  disabledLanguagePattern,\n  generatedRoutes,\n  languagePattern,\n  redirectRoutes,\n  rpath,\n  trailingSlash,\n} from '@/utils/routes'\nimport { wrapInArray } from '@/utils/helpers'\n\n// Globals\nimport { IN_BROWSER } from '@/utils/globals'\n\nconst routes = setupLayouts(generatedRoutes)\n\nconst appStore = useAppStore(pinia)\nconst localeStore = useLocaleStore(pinia)\nconst userStore = useUserStore(pinia)\n\nconst app = createApp(App)\n\nif (IN_BROWSER) {\n  window.localStorage.setItem(\n    'userSessions',\n    String(Number(window.localStorage.getItem('userSessions') || 0) + 1)\n  )\n  localeStore.$subscribe((_, state) => {\n    window.localStorage.setItem('currentLocale', state.locale)\n  })\n  userStore.$subscribe(() => {\n    userStore.save()\n  })\n  Swetrix.init('ZMrLolxUmS0l', {\n    apiURL: 'https://swetrix-api.vuetifyjs.com/log',\n  })\n  Swetrix.trackViews()\n  Sentry.init({\n    app,\n    dsn: 'https://491ef7e8180648c488b1fcc158eb9ecc@glitchtip.vuetifyjs.com/1',\n    release: import.meta.env.VITE_GITHUB_SHA,\n    environment: import.meta.env.VITE_GITHUB_REF,\n    enabled: import.meta.env.VITE_GITHUB_SHA,\n\n    sampleRate: 1,\n    integrations: integrations => {\n      return integrations.filter(\n        integration => integration.name !== 'BrowserSession',\n      )\n    },\n  })\n}\n\nconst router = createRouter({\n  history: createWebHistory(),\n  routes: [\n    {\n      path: '/',\n      redirect: () => {\n        return { path: `/${localeStore.locale}/` }\n      },\n    },\n    ...routes,\n    ...redirectRoutes,\n    {\n      path: `/:locale(${disabledLanguagePattern})/:pathMatch(.*)*`,\n      redirect: to => {\n        return rpath(wrapInArray(to.params.pathMatch).join('/'))\n      },\n    },\n    {\n      path: `/:locale(${languagePattern})/:pathMatch(.*)*`,\n      component: () => import('@/layouts/404.vue'),\n    },\n    {\n      path: '/:pathMatch(.*)*',\n      redirect: to => {\n        return rpath(to.fullPath)\n      },\n    },\n  ],\n  async scrollBehavior (to, from, savedPosition) {\n    if (appStore.scrolling) return\n\n    let main = IN_BROWSER && document.querySelector('main')\n    // For default & hash navigation\n    let wait = 0\n\n    if (!main) {\n      // For initial page load\n      wait = 1500\n      main = document.querySelector('main')\n    } else if (to.path !== from.path && to.hash) {\n      // For cross page navigation\n      wait = 500\n    }\n\n    await (new Promise(resolve => setTimeout(resolve, wait)))\n\n    if (to.hash) {\n      return {\n        el: to.hash,\n        behavior: main ? 'smooth' : undefined,\n        top: main ? parseInt(getComputedStyle(main).getPropertyValue('--v-layout-top')) : 0,\n      }\n    } else if (savedPosition) return savedPosition\n    else return { top: 0 }\n  },\n})\n\napp.use(createHead())\napp.use(router)\n\napp.config.errorHandler = (err, vm, info) => {\n  console.error(err, vm, info)\n  Swetrix.trackError({\n    name: (err as any).name,\n    message: (err as any).message,\n    lineno: null,\n    colno: null,\n    filename: null,\n  })\n}\napp.config.warnHandler = (err, vm, info) => {\n  console.warn(err, vm, info)\n}\n\nrouter.beforeEach((to, from) => {\n  if (to.meta.locale !== from.meta.locale) {\n    localeStore.locale = to.meta.locale as string\n  }\n  if (!to.path.endsWith('/')) return `${trailingSlash(to.path)}` + to.hash\n})\nrouter.afterEach((to, from) => {\n  if (to.meta.locale !== from.meta.locale && from.meta.locale === 'eo-UY') {\n    setTimeout(() => window.location.reload(), 100)\n  }\n})\nrouter.onError((err, to) => {\n  if (err?.message?.includes?.('Failed to fetch dynamically imported module')) {\n    if (!localStorage.getItem('vuetify:dynamic-reload')) {\n      console.log('Reloading page to fix dynamic import error')\n      localStorage.setItem('vuetify:dynamic-reload', 'true')\n      location.assign(to.fullPath)\n    } else {\n      console.error('Dynamic import error, reloading page did not fix it', err)\n      Swetrix.trackError({\n        name: err.name,\n        message: err.message,\n        lineno: null,\n        colno: null,\n        filename: null,\n      })\n    }\n  } else {\n    console.error(err)\n    Swetrix.trackError({\n      name: err?.name,\n      message: err?.message,\n      lineno: null,\n      colno: null,\n      filename: null,\n    })\n  }\n})\n\ninstallGlobalComponents(app)\ninstallI18n(app)\ninstallPwa(router)\ninstallPinia(app, router)\ninstallVuetify(app)\ninstallOne(app)\n\nrouter.isReady().then(() => {\n  localStorage.removeItem('vuetify:dynamic-reload')\n  app.mount('#app')\n})\n"
  },
  {
    "path": "packages/docs/src/pages/en/about/code-of-conduct.md",
    "content": "---\nmeta:\n  title: Code of conduct\n  description: Vuetify provides a safe, inclusive, and judgment free community for developers from all walks of life!\n  keywords: vuetify code of conduct, vuetify coc, community conduct\n---\n\n# Code of conduct\n\nFor questions or concerns regarding our *Code of Conduct*, please reach out to us at [support@vuetifyjs.com](mailto:support@vuetifyjs.com).\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.\n\n## Our Standards\n\nExamples of behavior that contributes to creating a positive environment include:\n\n- Using welcoming and inclusive language\n- Being respectful of differing viewpoints and experiences\n- Gracefully accepting constructive criticism\n- Focusing on what is best for the community\n- Showing empathy towards other community members\n\nExamples of unacceptable behavior by participants include:\n\n- The use of sexualized language or imagery and unwelcome sexual attention or advances\n- Trolling, insulting/derogatory comments, and personal or political attacks\n- Public or private harassment\n- Publishing others' private information, such as a physical or electronic address, without explicit permission\n- Other conduct which could reasonably be considered inappropriate in a professional setting\n\n## Our Responsibilities\n\nProject maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.\n\nProject maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.\n\n## Scope\n\nThis Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at hello@vuetifyjs.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.\n\nProject maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant](https://contributor-covenant.org), version 1.4, available at [https://contributor-covenant.org/version/1/4](https://contributor-covenant.org/version/1/4/)\n"
  },
  {
    "path": "packages/docs/src/pages/en/about/licensing.md",
    "content": "---\nmeta:\n  nav: Licensing\n  title: Licensing\n  description: Explore the MIT License under which Vuetify is available, understand your freedoms for using, modifying, and distributing Vuetify, and learn about community contributions.\n  keywords: MIT License, open source, Vuetify license, free software\nrelated:\n  - /introduction/why-vuetify/\n  - /getting-started/contributing/\n  - /introduction/enterprise-support/\n---\n\n# Licensing\n\nThis document provides comprehensive details about the licensing of the Vuetify framework.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## Overview\n\nVuetify is an open-source project that is free to use. It is licensed under the [MIT License](https://github.com/vuetifyjs/vuetify/blob/master/LICENSE.md), one of the most permissive and flexible open source licenses available.\n\n## What is the MIT License?\n\nThe MIT License is one of the most widely used licenses in the open-source community, known for its simplicity and permissiveness. This license grants users significant freedom in how they use, modify, and distribute software. Here are its key features and what they mean for Vuetify users:\n\n- **Freedom to Use**: The MIT License allows you to use Vuetify for any purpose - whether it's a private hobby project, a high-scale commercial application, or a public service. This level of freedom ensures that Vuetify is accessible to everyone, regardless of their project's nature or scale.\n- **Freedom to Modify**: Flexibility is at the core of Vuetify, and the MIT License extends this principle. You have the freedom to tweak, customize, and modify Vuetify to suit your project's unique requirements. This feature is particularly beneficial for developers looking to tailor their UI/UX without constraints.\n- **Freedom to Distribute**: The license not only allows you to use and modify Vuetify but also to distribute your version of it. Whether you're distributing your Vuetify-based project openly or commercially, the MIT License supports your endeavors. This aspect is crucial for fostering a culture of sharing and innovation in the developer community.\n- **No Warranty**: Please note that Vuetify is provided \"as is\", without any warranty of any kind. This is a standard clause in open-source licenses, emphasizing that users should test and evaluate the software in their specific contexts. While there's no formal warranty, the Vuetify team is committed to delivering a high-quality, robust framework, continuously working to improve its reliability and functionality.\n\nThe MIT License's simplicity and breadth make it an ideal choice for Vuetify, aligning with our commitment to open-source values and community-driven development.\n\n## Why MIT License for Vuetify?\n\nChoosing the MIT License for Vuetify was a deliberate decision to align with our core values of openness, simplicity, and community collaboration. Here’s why this license is the perfect fit for Vuetify:\n\n- **Simplicity and Permissiveness**: The MIT License is renowned for its simplicity and clarity. It doesn't impose complex restrictions, making it straightforward for developers to use Vuetify in various projects. Whether you're building a small personal project or a large-scale commercial application, the MIT License keeps things simple and unrestricted.\n- **Broad Compatibility**: One of Vuetify's strengths is its compatibility with a wide range of other tools and libraries. The MIT License is known for its broad compatibility with other open-source licenses. This compatibility makes it easier for developers to integrate Vuetify with other software, fostering a more vibrant and versatile ecosystem.\n- **Encourages Open Source Contribution**: Vuetify thrives on community contributions. The permissive nature of the MIT License encourages developers from around the world to contribute to Vuetify, enhancing its features and functionality. This collaborative spirit has been pivotal in shaping Vuetify into the robust and versatile framework it is today.\n\nBy adopting the MIT License, Vuetify remains committed to promoting innovation, collaboration, and freedom in software development. We believe this approach not only benefits Vuetify but also the broader open-source community.\n\n## Using Vuetify in Your Projects\n\nYou are free to use Vuetify in your projects, be it personal, commercial, or for educational purposes. The flexibility of the MIT License allows for a wide range of applications. When redistributing Vuetify or derivative works, the only requirement is to include the original copyright and license notice in any copy of the software/source code.\n\nTo get inspired or see what's possible with Vuetify, check out [Awesome Vuetify](https://github.com/vuetifyjs/awesome-vuetify), a curated list of awesome Vuetify resources, libraries, and tools. Additionally, explore the [Made With Vuetify](/resources/made-with-vuetify/) page to see a showcase of applications and projects built using Vuetify. These resources can provide you with ideas and examples of how Vuetify can enhance your projects.\n\n## Contributions to Vuetify\n\nContributions to Vuetify are also subject to the MIT License. By contributing to the Vuetify project, you agree that your contributions will be licensed under the MIT License. See our [Contributing](/getting-started/contributing/) page for more details.\n\n## Questions and Comments\n\nIf you have any questions or comments about our licensing policy, or if you need clarification on legal aspects of using Vuetify in your projects, please [contact us](mailto:hello@vuetifyjs.com).\n\n## Legal Disclaimer\n\nThe information provided on this page is for general informational purposes only and is not intended as legal advice. For specific legal questions regarding the use of Vuetify, please consult with a qualified attorney.\n"
  },
  {
    "path": "packages/docs/src/pages/en/about/meet-the-team.md",
    "content": "---\nmeta:\n  title: Meet the team\n  description: Meet the team responsible for building Vuetify. These are the core individuals who drive the vision of the framework.\n  keywords: vuetify dev team, vuetify core team\nrelated:\n  - /introduction/enterprise-support/\n  - /introduction/long-term-support/\n  - /introduction/roadmap/\n---\n\n# Meet the team\n\nVuetify is _not_ a one person show. We have a very active and engaged team that is **constantly striving** to bring developers a better experience. Keep in mind the below is not an exhaustive list of all the individuals that help make Vuetify great.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## Company\n\nVuetify (the framework) is [MIT Licensed](https://github.com/vuetifyjs/vuetify/blob/master/LICENSE.md) and [Open Source](https://opensource.com/resources/what-open-source). You can support the ongoing development of Vuetify by sponsoring the project on [GitHub](https://github.com/sponsors/johnleider).\n\n<AboutTeamMembers team=\"company\" />\n\n## Core Team\n\nThe core development team are Open Source developers that help guide the direction of Vuetify and its ecosystem.\n\n<PromotedPromoted slug=\"vuetify-open-collective\" />\n\n<AboutTeamMembers team=\"core\" />\n\n## Legends\n\nLegends are inactive members of the core team. They have contributed a significant amount of time and effort to the project and are recognized for their contributions.\n\n<AboutTeamMembers team=\"legends\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/about/security-disclosure.md",
    "content": "---\nmeta:\n  nav: Security disclosure\n  title: Security disclosure procedures\n  description: This document outlines security procedures and general policies for the Vuetify project.\n  keywords: security, security vulnerability, disclosure policy, security disclosure\nrelated:\n  - /introduction/enterprise-support/\n  - /getting-started/contributing/\n  - /introduction/long-term-support/\n---\n\n# Security disclosure procedures\n\nThis document outlines security procedures and general policies for the Vuetify project.\n\n<PageFeatures />\n\n<PromotedPromoted slug=\"enterprise-support\" />\n\n## Reporting a Bug\n\nThe Vuetify team and community take all security bugs in Vuetify seriously. We appreciate your efforts and responsible disclosure and will make every effort to acknowledge your contributions.\n\nTo report a security issue, email [security@vuetifyjs.com](mailto:security@vuetifyjs.com?subject=SECURITY) and include the word **\\\"SECURITY\\\"** in the subject line.\n\nThe Vuetify team will send a response indicating the next steps in handling your report. After the initial reply to your report, the security team will keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance.\n\nReport security bugs in third-party modules to the person or team maintaining the module.\n\n## Disclosure Policy\n\nWhen the security team receives a security bug report, they will assign it to a primary handler. This person will coordinate the fix and release process, involving the following steps:\n\n- Confirm the problem and determine the affected versions.\n- Audit code to find any potential similar problems.\n- Prepare fixes for all releases still under maintenance.These fixes will be released as fast as possible to npm.\n\n## Comments on this Policy\n\nIf you have suggestions on how this process could be improved please submit a pull request using the [issue creator](https://issues.vuetifyjs.com).\n"
  },
  {
    "path": "packages/docs/src/pages/en/api/[name].md",
    "content": "---\nlayout: blank\nmeta:\n  title: API\n  description: API documentation\n  keywords: api, vuetify\n---\n\n<script setup>\n  const name = shallowRef('')\n</script>\n\n<ApiView v-on:update:name=\"name = $event\">\n\n# {{ name }} API\n\n<PageFeatures />\n\n<ApiBacklinks :name=\"name\" />\n\n<PromotedEntry />\n\n<ApiSearch />\n\n</ApiView>\n"
  },
  {
    "path": "packages/docs/src/pages/en/api/use-hotkey.md",
    "content": "---\nmeta:\n  title: useHotkey API\n  description: API documentation for the useHotkey composable\n  keywords: useHotkey, hotkey, keyboard shortcuts, composable, api\n---\n\n<script setup>\n  const name = 'useHotkey'\n</script>\n\n# useHotkey API\n\nHandle keyboard shortcuts within your application using the **useHotkey** composable.\n\n<PageFeatures />\n\n<ApiBacklinks :name=\"name\" />\n\n<PromotedEntry />\n\n<ApiSearch />\n\n## Function Signature\n\n```typescript\nfunction useHotkey(\n  keys: MaybeRef<string | undefined>,\n  callback: (e: KeyboardEvent) => void,\n  options?: HotkeyOptions\n): () => void\n```\n\n## Parameters\n\n<section id=\"parameters\" class=\"mb-4\">\n  <AppHeadline path=\"Parameters\" />\n  <AppSheet>\n    <v-table class=\"api-table\" density=\"comfortable\">\n      <thead>\n        <tr>\n          <th class=\"name\">Name</th>\n          <th class=\"type\">Type</th>\n          <th class=\"default\">Default</th>\n          <th class=\"description\">Description</th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr>\n          <td class=\"text-mono pt-4\">\n            <strong>keys</strong>\n          </td>\n          <td class=\"text-mono\">\n            <code>MaybeRef&lt;string | undefined&gt;</code>\n          </td>\n          <td class=\"text-mono\">\n            <em>required</em>\n          </td>\n          <td class=\"text-mono pt-4\">\n            <p>The key combination string or reactive reference to a key combination. Supports modifiers (ctrl, cmd, alt, shift, meta) and key sequences separated by dashes. Changes to reactive refs are automatically applied.</p>\n          </td>\n        </tr>\n        <tr>\n          <td class=\"text-mono pt-4\">\n            <strong>callback</strong>\n          </td>\n          <td class=\"text-mono\">\n            <code>(e: KeyboardEvent) =&gt; void</code>\n          </td>\n          <td class=\"text-mono\">\n            <em>required</em>\n          </td>\n          <td class=\"text-mono pt-4\">\n            <p>Function to execute when the hotkey is triggered. Receives the KeyboardEvent as a parameter.</p>\n          </td>\n        </tr>\n        <tr>\n          <td class=\"text-mono pt-4\">\n            <strong>options</strong>\n          </td>\n          <td class=\"text-mono\">\n            <code>HotkeyOptions</code>\n          </td>\n          <td class=\"text-mono\">\n            <code>{}</code>\n          </td>\n          <td class=\"text-mono pt-4\">\n            <p>Optional configuration object to customize hotkey behavior. All options support reactive refs and will update automatically when changed.</p>\n          </td>\n        </tr>\n      </tbody>\n    </v-table>\n  </AppSheet>\n</section>\n\n## Options\n\n<section id=\"options\" class=\"mb-4\">\n  <AppHeadline path=\"HotkeyOptions\" />\n  <AppSheet>\n    <v-table class=\"api-table\" density=\"comfortable\">\n      <thead>\n        <tr>\n          <th class=\"name\">Name</th>\n          <th class=\"type\">Type</th>\n          <th class=\"default\">Default</th>\n          <th class=\"description\">Description</th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr>\n          <td class=\"text-mono pt-4\">\n            <strong>event</strong>\n          </td>\n          <td class=\"text-mono\">\n            <code>MaybeRef&lt;'keydown' | 'keyup'&gt;</code>\n          </td>\n          <td class=\"text-mono\">\n            <code>'keydown'</code>\n          </td>\n          <td class=\"text-mono pt-4\">\n            <p>The keyboard event type to listen for. Can be reactive - changing this will automatically re-register the event listener.</p>\n          </td>\n        </tr>\n        <tr>\n          <td class=\"text-mono pt-4\">\n            <strong>inputs</strong>\n          </td>\n          <td class=\"text-mono\">\n            <code>MaybeRef&lt;boolean&gt;</code>\n          </td>\n          <td class=\"text-mono\">\n            <code>false</code>\n          </td>\n          <td class=\"text-mono pt-4\">\n            <p>Whether to trigger hotkeys when input elements (input, textarea, contenteditable) are focused. When false, hotkeys are disabled in input contexts. Changes to reactive refs take effect immediately.</p>\n          </td>\n        </tr>\n        <tr>\n          <td class=\"text-mono pt-4\">\n            <strong>preventDefault</strong>\n          </td>\n          <td class=\"text-mono\">\n            <code>MaybeRef&lt;boolean&gt;</code>\n          </td>\n          <td class=\"text-mono\">\n            <code>true</code>\n          </td>\n          <td class=\"text-mono pt-4\">\n            <p>Whether to call preventDefault() on the keyboard event when the hotkey matches. Can be reactive to dynamically control event prevention.</p>\n          </td>\n        </tr>\n        <tr>\n          <td class=\"text-mono pt-4\">\n            <strong>sequenceTimeout</strong>\n          </td>\n          <td class=\"text-mono\">\n            <code>MaybeRef&lt;number&gt;</code>\n          </td>\n          <td class=\"text-mono\">\n            <code>1000</code>\n          </td>\n          <td class=\"text-mono pt-4\">\n            <p>Timeout in milliseconds for key sequences. If the next key in a sequence isn't pressed within this time, the sequence resets. Changes to reactive refs apply to new sequences.</p>\n          </td>\n        </tr>\n      </tbody>\n    </v-table>\n  </AppSheet>\n</section>\n\n## Return Value\n\n<section id=\"return-value\" class=\"mb-4\">\n  <AppHeadline path=\"Return Value\" />\n  <AppSheet>\n    <v-table class=\"api-table\" density=\"comfortable\">\n      <thead>\n        <tr>\n          <th class=\"type\">Type</th>\n          <th class=\"description\">Description</th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr>\n          <td class=\"text-mono\">\n            <code>() =&gt; void</code>\n          </td>\n          <td class=\"text-mono pt-4\">\n            <p>Cleanup function that removes the keyboard event listener. Automatically called when the component unmounts if used within a Vue component setup context.</p>\n          </td>\n        </tr>\n      </tbody>\n    </v-table>\n  </AppSheet>\n</section>\n"
  },
  {
    "path": "packages/docs/src/pages/en/blog/announcing-vuetify-3.8.md",
    "content": "---\nlayout: blog\nmeta:\n  title: Announcing Vuetify v3.8\n  description: Vuetify v3.8 is here! Discover the latest features, improvements, and bug fixes in this minor release, including new components and form input enhancements.\n  keywords: Vuetify v3.8, VNumberInput, VSnackbarQueue, VDataTable, VTooltip, VDateInput, useRules, VIconBtn\n---\n\n# Announcing Vuetify v3.8\n\n---\n\n🖊️ John Leider • 📅 April 8th, 2025\n\n<PromotedEntry />\n\n---\n\n## Introduction\n\nToday we are excited to announce the release of Vuetify v3.8 \"Andromeda\"!\n\nThis minor release contains no breaking changes and is packed with new features, improvements, and bug fixes. This blog post will highlight some of the most notable changes—for a full list of changes and new features, please see [the full changelog](https://vuetifyjs.com/getting-started/release-notes/?version=v3.8.0).\n\n---\n\n- [Form input improvements](#form-input-improvements)\n  - [Multi-word search highlight](#multi-word-search-highlight)\n  - [Input icon states](#input-icon-states)\n- [New components](#new-components)\n  - [VNumberInput](#vnumberinput)\n  - [VSnackbarQueue](#vsnackbarqueue)\n- [Other updates](#other-updates)\n  - [VDataTable selection](#vdatatable-selection)\n  - [VTooltip interactive](#vtooltip-interactive)\n- [Labs](#labs)\n  - [VDateInput](#vdateinput)\n  - [useRules composable](#userules-composable)\n  - [VIconBtn](#viconbtn)\n\n## Form input improvements\n\nIn v3.8, we have made several improvements to form controls, including new styling options and additional components. These changes are designed to give you more control over the look and feel of inputs.\n\n### Multi-word search highlight\n\nSearch terms that match multiple words in the item text will now be highlighted in VAutocomplete and VCombobox. This enhancement makes it easier for users to see how their search terms match available options, improving the overall search experience.\n\n**Before:**\n![Image of Autocomplete with single word highlighting](https://cdn.vuetifyjs.com/docs/images/blog/announcing-vuetify-3.8/autocomplete-before.png \"Single-word highlighting\"){ height=300 }\n\n**After:**\n![Image of Autocomplete with multi word highlighting](https://cdn.vuetifyjs.com/docs/images/blog/announcing-vuetify-3.8/autocomplete-after.png \"Multi-word highlighting\"){ height=300 }\n\n**Details:** [PR#16462](https://github.com/vuetifyjs/vuetify/pull/16462)\n\n### Input icon states\n\nIn earlier versions of Vuetify, focused inputs would add color to their icons. This is now possible using the new **icon-color** and **glow** props. The former allows you to set the default color of the icon, when combined with the latter, the icon will change color when the input is focused.\n\n![Gif of input icon states](https://cdn.vuetifyjs.com/docs/images/blog/announcing-vuetify-3.8/icon-color-glow-prop.gif \"Input icon states\"){ height=300 }\n\nThis is perfect for drawing attention to active inputs or creating dynamic, responsive forms.\n\n**Details:** [PR#21076](https://github.com/vuetifyjs/vuetify/pull/21076)\n\n## New components\n\nBoth VNumberInput and VSnackbarQueue have been promoted from labs to the core framework. They offer a clean experience and are easy to use.\n\n### VNumberInput\n\nThe [v-number-input](https://vuetifyjs.com/components/number-inputs/) component has moved from Labs to the Core framework in v3.8. It's intended to be a replacement for the standard `<input type=\"number\">` and supports all of the standard Vuetify input variant props.\n\n![Gif of the NumberInput component](https://cdn.vuetifyjs.com/docs/images/blog/announcing-vuetify-3.8/number-input.gif \"VNumberInput component\"){ height=300 }\n\n**Details:**\n\n- [Documentation](https://vuetifyjs.com/components/number-inputs/)\n- [PR#18162](https://github.com/vuetifyjs/vuetify/pull/18162)\n\n### VSnackbarQueue\n\nThe [v-snackbar-queue](https://vuetifyjs.com/components/snackbar-queue/) component has moved from Labs to the Core framework in v3.8. This component makes it easy to create a queue of snackbars that can be displayed one after the other.\n\nSetting up a queue of snackbars is as simple as creating a store that holds the queue and passing it to the VSnackbarQueue component.\n\n```ts { resource=\"src/stores/queue.ts\" }\nimport { defineStore } from 'pinia'\nimport { Ref } from 'vue'\n\nexport type Snackbar = Record<string, any>\n\nexport interface SnackbarQueueState {\n  queue: Ref<Snackbar[]>\n  show: (text: Snackbar | string) => void\n}\n\nexport const useQueueStore = defineStore('Queue', () => {\n  const queue = ref<Snackbar[]>([])\n\n  function show (text: Snackbar) {\n    const record = typeof text === 'string' ? { text } : text\n\n    queue.value.push(record)\n  }\n\n  return {\n    queue,\n    show,\n  } as SnackbarQueueState\n})\n```\n\n```html { resource=\"src/App/AppSnackbarQueue.vue\"}\n<template>\n  <v-snackbar-queue v-model=\"queue.queue\" />\n</template>\n\n<script setup>\n  import { useQueueStore } from '@/stores/queue'\n\n  const queue = useQueueStore()\n\n  queue.show('Hello world!')\n</script>\n```\n\nQueue items support all [v-snackbar](https://vuetifyjs.com/components/snackbars/) props, including **timeout** and **color**.\n\n**Details:**\n\n- [Documentation](https://vuetifyjs.com/components/snackbar-queue/)\n- [PR#19629](https://github.com/vuetifyjs/vuetify/pull/19629)\n\n## Other updates\n\nSome other small updates in v3.8 involve quality of life improvements to existing components such as VDataTable and VTooltip.\n\n### VDataTable selection\n\nIn v3.8, when using the **show-select** property and VDataTable, you can hold the <v-kbd>shift</v-kbd> key when making a selection to select a range of items.\n\n![Gif of VDataTable selection](https://cdn.vuetifyjs.com/docs/images/blog/announcing-vuetify-3.8/data-table-select.gif \"v-data-table selection\"){ height=500 }\n\n**Details:** [Commit c9a2a22](https://github.com/vuetifyjs/vuetify/commit/c9a2a2269b0492cc3cd0b757888be9ddd96316ba)\n\n### VTooltip interactive\n\nv3.8 introduces the **interactive** property to the [v-tooltip](https://vuetifyjs.com/components/tooltips/) component. When enabled, this allows users to interact with and select text within the tooltip.\n\n![Gif of v-tooltip interactive](https://cdn.vuetifyjs.com/docs/images/blog/announcing-vuetify-3.8/tooltip-interactive.gif \"v-tooltip interactive\"){ height=300 }\n\n**Details:** [Commit 1599512](https://github.com/vuetifyjs/vuetify/commit/159951278e9a27309d4d1eb633b426c770989584)\n\n## Labs\n\nThe latest version of Vuetify also includes a number of updates to existing Labs components, including the new VIconBtn. In addition, we're also bringing a new composable for testing named **useRules**.\n\n### VDateInput\n\nThe [v-date-input](https://vuetifyjs.com/components/date-inputs) component received multiple quality of life improvements, including:\n\n- Now has actions hidden by default, reducing screen clutter\n- Improved inputmode usage on mobile\n- Normalized control button sizes giving the component a more consistent look\n\n![Image of v-date-input](https://cdn.vuetifyjs.com/docs/images/blog/announcing-vuetify-3.8/date-input-enhancements.png \"v-date-input component\"){ height=300 }\n\nThis component is getting close to being ready for production, keep an eye out for it in the next release!\n\n### useRules composable\n\nThe useRules composable is a new way to propagate shared rules through your application with full localization support. After following the [Installation Guide](https://vuetifyjs.com/features/rules/#installation), you can use the composable in your components.\n\n```html\n<template>\n  <v-app>\n    <v-container>\n      <v-form validate-on=\"submit\" @submit.prevent=\"submit\">\n        <v-text-field :rules=\"[rules.required(), rules.email()]\" label=\"Email\" />\n\n        <v-btn text=\"Submit\" type=\"submit\"/>\n      </v-form>\n    </v-container>\n  </v-app>\n</template>\n\n<script setup>\n  import { useRules } from 'vuetify/labs/rules'\n\n  const rules = useRules()\n\n  async function submit (event) {\n    await event\n  }\n</script>\n```\n\nRules also support localization, allowing text strings to change based upon the injected locale. This applies globally, as well as inline:\n\n```html\n<template>\n  <v-form validate-on=\"submit\" @submit.prevent=\"submit\">\n    // This field is required\n    <v-text-field :rules=\"[rules.required()]\" />\n\n    <v-locale-provider locale=\"es\">\n      // Este campo es obligatorio\n      <v-text-field :rules=\"[rules.required()]\" />\n    </v-locale-provider>\n  </v-form>\n</template>\n```\n\nThis simplifies managing validation rules across your app, ensuring consistency and easing localization.\n\n### VIconBtn\n\n[v-icon-btn](https://vuetifyjs.com/components/icon-buttons/) is a new component in testing that's intended to bridge the gap between VBtn and VIcon. Its size is meant to be more intentional and is ideal for compact UI patterns like toolbars, icon-only lists, or action grids.\n\n![Gif of v-icon-btn](https://cdn.vuetifyjs.com/docs/images/blog/announcing-vuetify-3.8/icon-btn.gif \"v-icon-btn component\"){ height=300 }\n\nWe're also experimenting with a new way of mapping sizes, moving the configuration from SCSS to props.\n\n```ts { resource=\"src/plugins/vuetify.ts\" }\nimport { createVuetify } from 'vuetify'\n\nexport default createVuetify({\n  defaults: {\n    VIconBtn: {\n      sizes: [\n        ['x-small', 16],\n        ['small', 20],\n        ['medium', 24],\n        ['large', 28],\n        ['x-large', 32],\n      ],\n      iconSizes: [\n        ['x-small', 10],\n        ['small', 12],\n        ['medium', 14],\n        ['large', 16],\n        ['x-large', 18],\n      ],\n      size: 'small',\n    }\n  }\n})\n```\n\nMoving to a system like this also opens up the ability to configure your own sizing names:\n\n```ts { resource=\"src/plugins/vuetify.ts\" }\n{\n  VIconBtn: {\n    sizes: [\n      ['xs', 16],\n      ['sm', 20],\n      ['md', 24],\n      ['lg', 28],\n      ['xl', 32],\n      ['2xl', 36],\n    ],\n    iconSizes: [\n      ['xs', 10],\n      ['sm', 12],\n      ['md', 14],\n      ['lg', 16],\n      ['xl', 18],\n      ['2xl', 20],\n    ],\n    size: 'xl',\n  }\n}\n```\n\nThis is still in testing so please give us your feedback by dropping a line on our [Discord](https://community.vuetifyjs.com/)\n\n**Details:** [PR#21114](https://github.com/vuetifyjs/vuetify/pull/21114)\n\n---\n\nFor a complete list of all the changes and features in v3.8, please see the [full changelog](https://vuetifyjs.com/getting-started/release-notes/?version=v3.8.0).\n"
  },
  {
    "path": "packages/docs/src/pages/en/blog/april-2025-update.md",
    "content": "---\nlayout: blog\nmeta:\n  title: April 2025 Update\n  description: April delivered tangible progress on MCP, the new theming engine, component refinements, docs, ESLint v4, and tooling across the Vuetify ecosystem.\n  keywords: Vuetify April 2025, Model Context Protocol, Vuetify theming, ESLint flat config, Vuetify Playground, Tailwind integration\n---\n\n# April 2025 Update\n\nThis month is packed full of exciting updates and progress across the Vuetify ecosystem.\n\n---\n\n🖊️ John Leider • 📅 May 1st, 2025\n\n<PromotedEntry />\n\n---\n\n## Building Momentum\n\nApril was a month of execution. Multiple long-standing features landed, foundational work for future flexibility accelerated, and we’re seeing clearer paths emerge around how Vuetify can scale—technically, visually, and in terms of contributor access.\n\nFrom labs promotions like VNumberInput and VSnackbarQueue, to the start of public-facing infrastructure like @vuetify/mcp, the team is pushing forward on all fronts. This kind of momentum is what sets up big things for the summer and fall—especially as we close in on shipping the new theming engine and continue to clean up performance bottlenecks.\n\n::: success\n\nCool example of the month: [VScrollSelect](https://play.vuetifyjs.com/playgrounds/CS5a9g) by [J-Sek](https://github.com/J-Sek)\n\n:::\n\n---\n\n## Table of Contents\n\n- [Building Momentum](#building-momentum)\n  - [Releases](#releases)\n  - [MCP soon](#mcp-soon)\n  - [Theming evolved](#theming-evolved)\n  - [Performance improvements](#performance-improvements)\n- [Ecosystem updates](#ecosystem-updates)\n  - [DX Efforts](#dx-efforts)\n  - [Unvuetify](#unvuetify)\n  - [Vuetify One teams](#vuetify-one-teams)\n  - [Vuetify Play](#vuetify-play)\n  - [Vuetify Issues](#vuetify-issues)\n- [The Road Ahead](#the-road-ahead)\n\n### Releases\n\nThe month of April saw the release of \"Andromeda\", the latest version of Vuetify, which includes a host of new features, improvements, and bug fixes. Most notably, [VNumberInput](https://vuetifyjs.com/components/number-inputs/) and [VSnackbarQueue](https://vuetifyjs.com/components/snackbar-queue/) were promoted from Labs to the Core framework! We've also followed up with several patch releases to address bugs and improve stability.\n\n![Hero image for andromeda release notes](https://cdn.vuetifyjs.com/docs/images/blog/april-2025-update/andromeda-release-banner.png \"Andromeda release notes hero image\"){ height=150}\n\n**Details:**\n\n- [v3.8.0](https://vuetifyjs.com/getting-started/release-notes/?version=v3.8.0)\n- [v3.8.1](https://vuetifyjs.com/getting-started/release-notes/?version=v3.8.1)\n- [v3.8.2](https://vuetifyjs.com/getting-started/release-notes/?version=v3.8.2)\n- [v3.8.3](https://vuetifyjs.com/getting-started/release-notes/?version=v3.8.3)\n\n### MCP soon\n\nOne of the most exciting developments underway is the creation of [MCP: Model Context Protocol](https://modelcontextprotocol.io/introduction) and our efforts to provide LLMs with the most up to date framework information using it. The **@vuetify/mcp** package represents our attempt to improve how developers interact with Vuetify through AI and LLM-powered tools.\n\n![Image of outdated LLM response showing Vuetify 2](https://cdn.vuetifyjs.com/docs/images/blog/april-2025-update/outdated-llm-responses.png \"Outdated LLM response\"){ height=500 }\n\nToday, developers often receive outdated or inaccurate help from AI chatbots because these models aren't trained on Vuetify’s latest updates and new innovations we're building. MCP is our answer to that problem.\n\nWe want to ensure developers have access to contextually accurate, up-to-date, and deeply integrated Vuetify tools, documentation, snippets and much more right when they need it.\n\n![Image of VSCode in Agent mode](https://cdn.vuetifyjs.com/docs/images/blog/april-2025-update/vuetify-mcp.png \"VSCode agent querying vuetify-mcp\"){ height=550 }\n\nThis initiative won't just improve AI responses—it will fundamentally change how accessible and powerful Vuetify development can be.\n\nMCP is a major step towards empowering our community even further and we look forward to making the package public soon (like very soon).\n\n**Details:** [@vuetify/mcp](https://github.com/vuetifyjs/mcp)\n\n### Theming evolved\n\nAlongside MCP, another major focus has been Vuetify’s theming system. Our goal is to enable full customization of Vuetify — allowing developers to use any UI library, support long-awaited Material Design 3, and adapt the framework effortlessly to a wide variety of design systems. This includes things such as:\n\n- First party Tailwind integration.\n- Support for unstyled mode that includes only the necessary styles for components to function.\n- New and improved ways of interacting with the theme system.\n\nThe work happening right now is a foundational step toward that vision. We're targeting an October reveal for this theming overhaul and will be teasing more about it in the months ahead. Here's a small preview of the new theming API in action:\n\n```html\n<template>\n  <v-app>\n    <v-main>\n      <v-container>\n        <!-- Change to a specific theme -->\n        <v-btn @click=\"theme.change('dark')\">Change to Dark</v-btn>\n\n        <!-- Toggle between Light / Dark -->\n        <v-btn @click=\"theme.toggle()\">Toggle Light / Dark</v-btn>\n\n        <!-- Toggle between specific themes -->\n        <v-btn @click=\"theme.toggle(['custom', 'light'])\">Toggle Custom / Light</v-btn>\n\n        <!-- Cycle between all themes -->\n        <v-btn @click=\"theme.cycle()\">Cycle All Themes</v-btn>\n\n        <!-- Cycle between specific themes -->\n        <v-btn @click=\"theme.cycle(['custom', 'light', 'utopia'])\">Cycle Specific Themes</v-btn>\n      </v-container>\n    </v-main>\n  </v-app>\n</template>\n\n<script setup>\n  import { useTheme } from 'vuetify'\n\n  const theme = useTheme()\n</script>\n```\n\nThese changes focus on expanding Vuetify’s flexibility, making it an even more powerful tool for projects of every scale and style.\n\n**Details:**\n\n- [PR#21244](https://github.com/vuetifyjs/vuetify/pull/21244)\n- [PR#21224](https://github.com/vuetifyjs/vuetify/pull/21224)\n- [Commit 3190331](https://github.com/vuetifyjs/vuetify/commit/3190331e70f42b7fdf4d7ee04f662b15eefde026)\n- [Commit abfdb77](https://github.com/vuetifyjs/vuetify/commit/abfdb777e0e00d4a1798f52d7e4c118e7409fcb9)\n\n### Performance improvements\n\nThis month, we focused on performance improvements across the board, including saving a bunch of overhead associated with computed caching and call frequency.\n\nFor those anticipating the release of [VTreeview](https://vuetifyjs.com/components/treeview), there has been movement on an [upstream](https://github.com/vuejs/babel-plugin-jsx/issues/712) issue that was bottlenecking performance. Once released, we will be able to wrap up the component and move it to the Core framework 🎉.\n\n**Details:**\n\n- [PR#21167](https://github.com/vuetifyjs/vuetify/pull/21167)\n- [Commit 8d798e3](https://github.com/vuetifyjs/vuetify/commit/8d798e36baf86f04eebf2828be0cffa0dc31053a)\n- [vue-macros#942](https://github.com/vue-macros/vue-macros/pull/942)\n\n## Ecosystem updates\n\nFrom the release of team subscriptions for Vuetify One, to major rewrites of tools like Vuetify Create and the modernized Vuetify Issues site, April was about refining the developer experience across the board. New tooling like @unvuetify is pushing boundaries with Nuxt and auto-import support, and MCP continues to bridge the gap between AI and accurate Vuetify usage.\n\n### DX efforts\n\nA major focus has been making Vuetify more accessible to developers at all levels.\n\n- **MCP**: Coding companion that provides contextually accurate, up-to-date, and deeply integrated Vuetify tools, documentation, snippets and much more right when you need it.\n- **Vuetify Create**: Multiple updates with improvements and planning for 3.0 representing a total rewrite of our project scaffolding tool.\n- **Labs Components**: Added auto-import support by default for labs components.\n- **Internationalization**: Expansion of translations including Spanish additions to the documentation.\n- **Modern ESLint Configuration**: Complete rewrite of our ESLint configuration with a functional approach, being rolled out across all repositories.\n\n**Details:**\n\n- [create/releases](https://github.com/vuetifyjs/create/releases)\n- [ESLint configuration](https://github.com/vuetifyjs/eslint-config-vuetify)\n- [Commit 98ef110](https://github.com/vuetifyjs/vuetify-loader/commit/98ef1106fb3875a5079d309986de61e12cd5683d)\n\n### Unvuetify\n\nThe motivation behind @unvuetify is simple: existing plugins aren’t keeping up with the evolving capabilities of Vue and Nuxt. Features like lazy hydration, auto-importing, and tree shaking are either missing or cumbersome in older tools.\n\nThis monorepo isn’t a hard replacement — you can still use vite-plugin-vuetify or webpack-plugin-vuetify if they suit your needs. But if you're working with Nuxt 3, Vue 3.5, or want more flexibility and performance, @unvuetify is built for you.\n\nCreated [@unvuetify](https://github.com/userquin/unvuetify-monorepo) repository to enable:\n\n- Vue Lazy Hydration support: ready to use Vue Lazy Hydration with Vuetify components and Nuxt 3/4.\n- Extensible: allow prefixing Vuetify components, directives and composables with Vuetify prefix.\n- VSCode directives suggestions.\n- Nuxt 3/4 utilities: drop a simple Nuxt module and it will auto-import all Vuetify components, directives and composables for you.\n- and more...\n\n**Details:**\n\n- [@unvuetify/shared](https://github.com/userquin/unvuetify-monorepo/tree/main/packages/shared): utilities to resolve Vuetify components and directives\n- [@unvuetify/unimport-presets](https://github.com/userquin/unvuetify-monorepo/tree/main/packages/unimport-presets): presets to auto-import Vuetify composables and directives\n- [@unvuetify/unplugin-vue-components-resolvers](https://github.com/userquin/unvuetify-monorepo/tree/main/packages/unplugin-vue-components-resolvers): resolvers to auto-import Vuetify components and directives\n- [@unvuetify/vite-styles-plugin](https://github.com/userquin/unvuetify-monorepo/tree/main/packages/styles-plugin): Vite plugin to load Vuetify sass/scss styles with Nuxt 3 SSR support\n- [@unvuetify/nuxt-utils](https://github.com/userquin/unvuetify-monorepo/tree/main/packages/nuxt-utils): utilities to configure Vuetify composables, directives, components and styles in your Nuxt 3 application\n\n### Vuetify One teams\n\nWe have recently updated Vuetify One to support teams, which allows you to invite up to 25 members to collaborate on your Vuetify projects. This update is designed to share subscription benefits across your team.\n\n![Image of Vuetify One teams subscription panel](https://cdn.vuetifyjs.com/docs/images/blog/april-2025-update/one-teams.png \"Vuetify One teams subscription panel\"){ height=400 }\n\nSubscribe by logging into Vuetify One (top right) and clicking on **Subscriptions**. If you have any issues or questions, please reach out to us on [Discord](https://community.vuetifyjs.com).\n\n**Details:** [PR#15](https://github.com/vuetifyjs/one/pull/15)\n\n### Vuetify Play\n\nOf the many changes coming to [Vuetify Play](https://play.vuetifyjs.com/), one of the longest requested features is finally here: **router support**! This means you can now create and share Vuetify Play projects that include Vue Router, allowing for more complex and interactive examples.\n\n![Image of Vuetify Play with router support](https://cdn.vuetifyjs.com/docs/images/blog/april-2025-update/play-router.png \"Vuetify Play with router support\"){ height=250 }\n\nWe are also in the process of updating the entire Vuetify Play interface to be more intuitive and user-friendly. This includes a new design, improved navigation, and better organization of examples and components. We look forward to sharing more details in the coming months.\n\n**Details:**\n\n- [PR#7](https://github.com/vuetifyjs/play/pull/7)\n- [Commit 0e89a33](https://github.com/vuetifyjs/play/commit/0e89a334f241d440987908a456c205bed53e96d6)\n\n### Vuetify Issues\n\nWe are wrapping up the new [Vuetify Issue Generator](https://issues.vuetifyjs.com/), which will replace the current system (still on Vuetify v1.5!).\n\n<video width=\"100%\" height=\"auto\" autoplay loop controls>\n  <source src=\"https://cdn.vuetifyjs.com/docs/images/blog/april-2025-update/vuetify-issues.mp4\" type=\"video/mp4\"></source>\n</video>\n\nThe new interface is faster, clearer, and built with Vuetify 3 from the ground up.\n\n## The Road Ahead\n\nMay is all about delivery. MCP will ship publicly, and early previews of the new theming system will start rolling out with documentation and migration guides. We're also beginning to lay the foundation for Vuetify 4. The focus is simple: ship real features, reduce friction, and keep moving fast.\n\nMore to come next month—stay tuned.\n"
  },
  {
    "path": "packages/docs/src/pages/en/blog/august-2025-update.md",
    "content": "---\nlayout: blog\nmeta:\n  title: August 2025 Update\n  description: August marks a pivotal moment in Vuetify's evolution as we prepare to release the pre-alpha of Vuetify0 (v0), launch our redesigned issues page, and continue delivering powerful components and improvements.\n  keywords: Vuetify August 2025, Vuetify0, v0 pre-alpha, VEditor, issues page redesign, theming webinar, performance optimization\n---\n\n# August 2025 Update\n\nWelcome to our August update! This month marks a pivotal moment in Vuetify's evolution as we prepare to release the pre-alpha of Vuetify0, launch our redesigned issues page, and continue delivering powerful components and improvements.\n\n![Hero image for August update](https://cdn.vuetifyjs.com/docs/images/blog/august-2025-update/august-hero.png \"August hero image\"){ height=112 }\n\n🖊️ John Leider • 📅 September 9th, 2025\n\n<PromotedEntry />\n\n---\n\n## From Zero\n\nVuetify0 reached pre-alpha status this month, delivering the first public release of our meta-framework for UI library development. The release includes foundational composables for registration and selection, plus core plugins for breakpoints, hydration, locale management, storage, and theming. These framework-agnostic tools represent the extracted intelligence that powers Vuetify, now available as standalone packages for any development environment.\n\nEcosystem improvements continued throughout August with significant team-community collaboration driving advances in foundational architecture, component refinements, and developer experience enhancements. The 87 pull requests merged this month reflect ongoing contributions that strengthen not just Vuetify0, but the entire ecosystem. This pre-alpha milestone sets the foundation for broader adoption while maintaining our commitment to developer productivity and framework flexibility.\n\n::: success\n\nCool example of the month: [VVideo Card](https://play.vuetifyjs.com/playgrounds/-10f7g) by [Vuetify](https://github.com/vuetifyjs)\n\n:::\n\n---\n\n## Table of Contents\n\n* [Releases](#releases)\n* [\"Mastering Vuetify Theming\" Webinar Recap](#mastering-vuetify-theming-webinar-recap)\n* [Vuetify0 in Pre-Alpha](#vuetify0-in-pre-alpha)\n* [Framework Updates](#framework-updates)\n* [Ecosystem Spotlight: Vuetify Issues](#ecosystem-spotlight-vuetify-issues)\n* [Free Premium Themes](#free-premium-themes)\n* [Building the Future](#building-the-future)\n\n---\n\n## Releases\n\nAugust focused on general component stability and bug fixes. View the complete list of changes in the [Full Changelog](#august-2025-changelog).\n\n**Details:**\n\n* [v3.9.4](https://vuetifyjs.com/getting-started/release-notes/?version=v3.9.4)\n* [v3.9.5](https://vuetifyjs.com/getting-started/release-notes/?version=v3.9.5)\n* [v3.9.6](https://vuetifyjs.com/getting-started/release-notes/?version=v3.9.6)\n\n## \"Mastering Vuetify Theming\" Webinar Recap\n\nOn August 27th, we hosted our second community webinar: **\"Mastering Vuetify's Theming Engine\"**. Following the success of July's migration webinar, this session dove deep into one of Vuetify's most powerful features.\n\n### What We Covered\n\n* **Theme Architecture**: Understanding how Vuetify's theming system works under the hood\n* **Custom Theme Creation**: Step-by-step guide to building professional themes\n* **Dynamic Theming**: Implementing runtime theme switching and user preferences\n* **Performance Optimization**: Best practices for theme efficiency\n* **Advanced Techniques**: CSS variables, theme inheritance, and component-specific theming\n\n### Community Response\n\nThe turnout exceeded our expectations, with developers from around the world joining to level up their theming skills. The Q&A session revealed common challenges that we're already addressing in our documentation and tooling improvements.\n\n### Recording\n\nWe have the event recorded and are working on what the process looks like to bring it to you. More than likely will end up on our [YouTube Channel](https://www.youtube.com/@vuetifyjs), make sure to subscribe if you haven't already.\n\n### Upcoming Webinar: \"Performance Crisis\"\n\nBased on your feedback, our September webinar will tackle one of the most requested topics: **\"Performance Crisis: Slash Your Bundle Size\"**. This session will show you how to dramatically reduce your Vuetify application's footprint through:\n\n* Advanced tree-shaking techniques\n* Component lazy loading strategies\n* Build optimization configurations\n* Real-world case studies with measurable results\n\n![Webinar highlights](https://cdn.vuetifyjs.com/docs/images/blog/august-2025-update/webinar.png \"Performance Crisis Webinar\"){ height=135 }\n\n**Details:**\n\n* Tuesday, September 30th at 9:00 AM CST\n* [Performance Crisis Sign-up](https://discord.gg/vuetify-340160225338195969?event=1414654608541749308)\n\n## Vuetify0 in Pre-Alpha\n\nIf you missed my initial mentions of it, [Vuetify0](https://0.vuetifyjs.com/) is a **meta framework** for building UI libraries. We've distilled the core of Vuetify into a collection of highly optimized, framework-agnostic composables. This means the power that drives Vuetify—its layout system, theming engine, localization setup, and component logic—will be available as a standalone package.\n\n**Modern Development Experience**: Built from the ground up for Vue 3, TypeScript, and modern build tools, v0 embraces the latest web platform features while maintaining broad compatibility.\n\n### What to Expect in the Pre-Alpha\n\nThe initial Vuetify0 release will focus on the foundational pillars of the framework. Some pages are still receiving their initial content so please pardon our dust. Here's what you'll be able to explore:\n\n**Composables:**\n\n* **Foundational** composables are the backbone of Vuetify0 and are the basic building blocks for creating a UI library.\n* **Registration** composables are the foundational pieces for selection and tokenization.\n* **Selection** composables serve as the core logic for managing selectable items, including single and multiple selection modes.\n* **Plugins**: [Breakpoints](https://0.vuetifyjs.com/composables/plugin/use-breakpoints), [Hydration](https://0.vuetifyjs.com/composables/plugin/use-hydration), [Locale](https://0.vuetifyjs.com/composables/plugin/use-locale), [Storage](https://0.vuetifyjs.com/composables/plugin/use-storage), and [Theme](https://0.vuetifyjs.com/composables/plugin/use-theme) plugins to manage global application state.\n\n::: info\n\nIf you're wondering how Vuetify0 will affect you as a Vuetify user, the short answer is: it won't—at least not immediately.\n\n:::\n\nThe long-term plan is to incrementally integrate Vuetify0 composables into Vuetify over time, starting with new components and gradually refactoring existing ones. This approach allows us to enhance the framework's architecture without disrupting your current projects. If you're wondering how Vuetify0 will affect you as a Vuetify user, the short answer is: it won't—at least not immediately. What it *will* do is open the door for new libraries and tools to be built on the same fundamentals that drive Vuetify. Allowing developers to opt into the Vuetify ecosystem without having to commit to \"Big Vuetify\" as we've started calling it internally.\n\n**Details:**\n\n* [Vuetify0 Composables](https://0.vuetifyjs.com/composables)\n* [v0.0.2 Release Notes](https://github.com/vuetifyjs/0/releases/tag/v0.0.2)\n* [Discussion on Discord](https://discord.gg/vK6T89eNP7)\n\n## Framework Updates\n\nWe've made significant progress on several key components and features this month. The team merged **87 pull requests** in August alone, primarily focusing on component enhancements, bug fixes, and developer experience improvements.\n\n### VEditor: Final Testing, Coming Soon\n\nVEditor is in the final stages of testing and will be available soon. This rich text editor brings professional content editing capabilities to Vuetify applications, including:\n\n![VEditor showcase](https://cdn.vuetifyjs.com/docs/images/blog/august-2025-update/veditor.png \"VEditor rich text formatting features\"){ height=135 }\n\n* **Rich Text Formatting:** Comprehensive formatting options like bold, italic, underline, strikethrough, code blocks, heading levels (H1-H6), subscript, superscript, and blockquotes\n* **Customizable Toolbar:** Choose which formatting options to display, hide the toolbar completely, or configure it dynamically at runtime with Material Design Icons\n* **Form Integration:** Full v-model support with Vuetify's validation system, including rules for required content, character limits, and seamless v-form compatibility\n* **Flexible Styling:** Configurable height, multiple variants (outlined, solo, underlined), responsive design, and full Vuetify theme integration\n* **Advanced Features:** Clearable content functionality, proper focus management, accessibility support with ARIA labels, and cross-browser contentEditable implementation\n\n**Details:**\n\n* [VEditor PR#21653](https://github.com/vuetifyjs/vuetify/pull/21653)\n\n## Ecosystem Spotlight: Vuetify Issues\n\nThe redesigned issues experience is now live at [issues.vuetifyjs.com](https://issues.vuetifyjs.com). This release focused on migrating the app from Vuetify v1.5 to v3 for a modern, consistent UI and better developer ergonomics. We also integrated Vuetify One to enable future enhancements—like special labels for subscribers—to streamline triage and improve visibility.\n\n<video width=\"100%\" height=\"auto\" loop controls class=\"mb-4\">\n  <source src=\"https://cdn.vuetifyjs.com/docs/images/blog/august-2025-update/issues.mp4\" type=\"video/mp4\"></source>\n</video>\n\n::: info\n\nThe previous issues page was originally built with Vuetify v1.5 in 2018\n\n:::\n\n**Details:**\n\n* [New Issues Page](https://issues.vuetifyjs.com)\n* [Contributing Guide](https://vuetifyjs.com/about/contributing/)\n* [Community Discord](https://community.vuetifyjs.com)\n\n## Free Premium Themes\n\nAll Vuetify‑made themes—designed, built, and maintained by the Vuetify team—are now free for **personal** use. Enjoy polished, production‑ready starting points to learn best practices, explore ideas, and accelerate side projects without licensing friction.\n\n### Now Available for Free\n\nThis move reflects our commitment to lowering barriers to entry and helping developers create beautiful applications faster. Visit the [Vuetify Store](https://store.vuetifyjs.com) to explore the expanded free collection.\n\n![Vuetify Store showcase](https://cdn.vuetifyjs.com/docs/images/blog/august-2025-update/store.png \"Free premium themes now available\"){ height=600 }\n\n**Details:**\n\n* [Crypto Coin Theme](https://store.vuetifyjs.com/products/crypto-coin-theme)\n* [Flairo Theme Pro](https://store.vuetifyjs.com/products/flairo-theme-pro)\n* [Vuetify 3 Nebula UI Kit](https://store.vuetifyjs.com/products/vuetify-3-nebula-ui-kit)\n* [Zero Theme Pro](https://store.vuetifyjs.com/products/zero-theme-pro)\n* [Made by Vuetify Bundle](https://store.vuetifyjs.com/products/made-by-vuetify-bundle)\n\n## August 2025 Changelog\n\nThe following section provides an overview of the changes made in August 2025, including new features, bug fixes, and enhancements across the Vuetify framework.\n\n**Key Improvements:**\n\n* Accessibility and high-contrast: forced-colors fixes in VBtn/VCard, ARIA labels in VColorPicker, role added to VTextField input\n* Smarter selection UX: VSelect fixes placeholder overlap and shows selected text\n* More reliable date picking: VDatePicker prioritizes allowed months/years and fixes year scroll/focus\n* Tables/inputs polish: VDataTable row/stripe fixes, VNumberInput focus/icons, VField clear, menu/tooltip reposition\n* Labs upgrades: VVideo aspect-ratio and visuals, VPie touch segments, VColorInput pip/focus, VIconBtn icon-color\n\n**Expand** this section to see the detailed changelog for August 2025:\n\n<details >\n\n### :wrench: Bug Fixes\n\n* **validation:** return aliases when called without arguments ([#21868](https://github.com/vuetifyjs/vuetify/issues/21868)) ([64a82d4](https://github.com/vuetifyjs/vuetify/commit/64a82d4776d22628db5d3a55fc070ce2463eb602)), closes [#21477](https://github.com/vuetifyjs/vuetify/issues/21477)\n* **VAlert:** restore unit-less support in Sass variable for title line-height ([#21843](https://github.com/vuetifyjs/vuetify/issues/21843)) ([8c1778a](https://github.com/vuetifyjs/vuetify/commit/8c1778a26a08d9d663681d83d6dd9160e3cb5c74)), closes [#21841](https://github.com/vuetifyjs/vuetify/issues/21841)\n* **VBtn:** render border in forced-colors mode ([#21848](https://github.com/vuetifyjs/vuetify/issues/21848)) ([25af169](https://github.com/vuetifyjs/vuetify/commit/25af169ae03c28bc6472f00347edaeaefb73aeb3))\n* **VCard:** hide progress border in forced-colors mode ([#21836](https://github.com/vuetifyjs/vuetify/issues/21836)) ([4335576](https://github.com/vuetifyjs/vuetify/commit/43355769444e256eed6111d23b75d7dc2838a093)), closes [#21835](https://github.com/vuetifyjs/vuetify/issues/21835)\n* **VColorPicker:** aria labels for main controls ([#21839](https://github.com/vuetifyjs/vuetify/issues/21839)) ([e2ab73a](https://github.com/vuetifyjs/vuetify/commit/e2ab73a7aafb1c443ad30b28134e41b4662c27fe)), closes [#21834](https://github.com/vuetifyjs/vuetify/issues/21834)\n* **VColorPicker:** keep canvas visible when width is not px ([22b828f](https://github.com/vuetifyjs/vuetify/commit/22b828f5cc625adeeb206e20746154dd79f33e0c))\n* **VColorPicker:** prevent sass nested deprecation warning ([8083db9](https://github.com/vuetifyjs/vuetify/commit/8083db971f7fe51151241447f90a4cd14cff32be)), closes [#21909](https://github.com/vuetifyjs/vuetify/issues/21909)\n* **VDataTable:** correct row height when with show-select and compact ([#21829](https://github.com/vuetifyjs/vuetify/issues/21829)) ([29b3bb0](https://github.com/vuetifyjs/vuetify/commit/29b3bb0b3363e8c295cf16286ed500e8ae269e98)), closes [#21767](https://github.com/vuetifyjs/vuetify/issues/21767)\n* **VDataTable:** missing stripes on fixed columns ([#21715](https://github.com/vuetifyjs/vuetify/issues/21715)) ([739a6c9](https://github.com/vuetifyjs/vuetify/commit/739a6c9aa8ac6064d7484e1e40dbf111d2ab75c5))\n* **VDatePicker:** prioritize allowed-months and allowed-years ([#21916](https://github.com/vuetifyjs/vuetify/issues/21916)) ([810645c](https://github.com/vuetifyjs/vuetify/commit/810645c5c37aeeb3aec1a575763c5e836b7bb8b6)), closes [#21911](https://github.com/vuetifyjs/vuetify/issues/21911)\n* **VDatePickerYears:** fix scroll/focus of selected year ([#21951](https://github.com/vuetifyjs/vuetify/issues/21951)) ([b531dbf](https://github.com/vuetifyjs/vuetify/commit/b531dbfa1ae6e08dddea41f965912b8cf60a55ce)), closes [#21950](https://github.com/vuetifyjs/vuetify/issues/21950)\n* **VField:** avoid duplicated emits on clear ([#21865](https://github.com/vuetifyjs/vuetify/issues/21865)) ([a97f103](https://github.com/vuetifyjs/vuetify/commit/a97f10306bd32e739c4cd52f4939e2b6d3b648d1)), closes [#21417](https://github.com/vuetifyjs/vuetify/issues/21417)\n* **VMenu, VTooltip:** apply scroll-strategy reposition for horizontal overflow ([#21309](https://github.com/vuetifyjs/vuetify/issues/21309)) ([bd48658](https://github.com/vuetifyjs/vuetify/commit/bd486588ae665014abe9a2af09bee12868e8574f)), closes [#20625](https://github.com/vuetifyjs/vuetify/issues/20625)\n* **VNumberInput:** consistent color of control icons ([#21936](https://github.com/vuetifyjs/vuetify/issues/21936)) ([6a50b44](https://github.com/vuetifyjs/vuetify/commit/6a50b44bf48b11f975c52c78074f99f52e34ab10)), closes [#21931](https://github.com/vuetifyjs/vuetify/issues/21931)\n* **VNumberInput:** keep focus when incrementing in the list ([#21824](https://github.com/vuetifyjs/vuetify/issues/21824)) ([d6b3384](https://github.com/vuetifyjs/vuetify/commit/d6b338465a1c55fa72838c668276dcc9855b4f54)), closes [#17083](https://github.com/vuetifyjs/vuetify/issues/17083)\n* **VOtpInput:** support composing character with IME ([42e15a3](https://github.com/vuetifyjs/vuetify/commit/42e15a349c1de7721c754d9aee2b437144b1a89b)), closes [#21918](https://github.com/vuetifyjs/vuetify/issues/21918)\n* **VOverlay:** don't use content element as scroll parent ([06c4c91](https://github.com/vuetifyjs/vuetify/commit/06c4c91f94d18af53041961f2c9fb0cc7e364cb2))\n* **VSelect:** select placeholder overlap ([#21923](https://github.com/vuetifyjs/vuetify/issues/21923)) ([5c06ba7](https://github.com/vuetifyjs/vuetify/commit/5c06ba7bd76bca370320433e7a0f058362d6028f)), closes [#21922](https://github.com/vuetifyjs/vuetify/issues/21922)\n* **VSelect:** use selected text instead of value ([#21902](https://github.com/vuetifyjs/vuetify/issues/21902)) ([d0ef001](https://github.com/vuetifyjs/vuetify/commit/d0ef0016adf8517620ce14c5e1e50e800195fb95)), closes [#21097](https://github.com/vuetifyjs/vuetify/issues/21097)\n* **VSlider:** avoid thumb label wedge gap ([#21847](https://github.com/vuetifyjs/vuetify/issues/21847)) ([059e578](https://github.com/vuetifyjs/vuetify/commit/059e578e21f376bf1059c59fbf72eb278664ed93))\n* **VSparkline:** accept a single number ([#21944](https://github.com/vuetifyjs/vuetify/issues/21944)) ([d7b0e34](https://github.com/vuetifyjs/vuetify/commit/d7b0e34e9d717ce96c898875c4e480ab89d81eea)), closes [#19697](https://github.com/vuetifyjs/vuetify/issues/19697)\n* **VStepper:** align title and subtitle to the avatar ([12735e6](https://github.com/vuetifyjs/vuetify/commit/12735e6797e1c482db74fd7615af7b484e282614)), closes [#21884](https://github.com/vuetifyjs/vuetify/issues/21884)\n* **VStepper:** correct cursor for readonly item ([aeb6f4d](https://github.com/vuetifyjs/vuetify/commit/aeb6f4d70291ebb5c907ebe86490bb622f2929ea)), closes [#21867](https://github.com/vuetifyjs/vuetify/issues/21867)\n* **VStepper:** keep correct alignment with alt-labels ([1a0a9e6](https://github.com/vuetifyjs/vuetify/commit/1a0a9e6f19d776fe104caaae4c659a3f6d3d3e55))\n* **VTextField:** assign role to input element ([#21903](https://github.com/vuetifyjs/vuetify/issues/21903)) ([d77285f](https://github.com/vuetifyjs/vuetify/commit/d77285fcae70522dfafbc66c775f72b03684bb38)), closes [#18125](https://github.com/vuetifyjs/vuetify/issues/18125)\n* **VTreeview:** allow expanding disabled nodes ([ed4d8cf](https://github.com/vuetifyjs/vuetify/commit/ed4d8cfb06079a231064dbc6ebedb05d3ad6ef06)), closes [#21075](https://github.com/vuetifyjs/vuetify/issues/21075) [#21116](https://github.com/vuetifyjs/vuetify/issues/21116)\n* **VWindow:** correctly reveal vertical arrows on hover ([521ba7b](https://github.com/vuetifyjs/vuetify/commit/521ba7b7a5749f495b13face6fabca7b971e56bf))\n\n### :microscope: Code Refactoring\n\n* **VDataTable:** avoid Array.toReversed() ([3894f98](https://github.com/vuetifyjs/vuetify/commit/3894f98c333abaad63fc2a651ae558ffbb75d620))\n\n### :test_tube: Labs\n\n* **VColorInput:** pip customization ([#21820](https://github.com/vuetifyjs/vuetify/issues/21820)) ([db389d5](https://github.com/vuetifyjs/vuetify/commit/db389d5bb0386eccb00302c0b3134f39c201a35a))\n* **VColorInput:** allow inner fields focus using mouse ([7657d52](https://github.com/vuetifyjs/vuetify/commit/7657d522ba5604ce53fad877e84033f7bf5ad960)), closes [#21897](https://github.com/vuetifyjs/vuetify/issues/21897)\n* **VIconBtn:** correctly apply `icon-color` ([b2ece2c](https://github.com/vuetifyjs/vuetify/commit/b2ece2c033ec8cc097f644cda912bb915d1df84e)), closes [#21930](https://github.com/vuetifyjs/vuetify/issues/21930)\n* **VPie:** support touch for segment interaction ([#21871](https://github.com/vuetifyjs/vuetify/issues/21871)) ([93f4218](https://github.com/vuetifyjs/vuetify/commit/93f421848601fe6f24e32395a7810c41790f92cf))\n* **VVideo:** prefer `max-width`, default to 100% ([22d5dd5](https://github.com/vuetifyjs/vuetify/commit/22d5dd5e5814c9aea59a5d4778c2d4ea6c3c9ba6))\n* **VVideo:** add `aspect-ratio` prop ([83e67d1](https://github.com/vuetifyjs/vuetify/commit/83e67d137b2659535da355ac23d9a24d8345537b))\n* **VVideo:** correct default track color with pills ([e98919d](https://github.com/vuetifyjs/vuetify/commit/e98919d0c3ec9ed128bc58fe5678b1821f7f5478))\n* **VVideo:** correct color customization ([13da3e1](https://github.com/vuetifyjs/vuetify/commit/13da3e1b33b7dfee1d506c4d47782ab47a3f7f6c))\n* **VVideo:** correctly move elevation to pills ([3df9494](https://github.com/vuetifyjs/vuetify/commit/3df9494480b80f091bef6e0f1e65066dbe4b5642))\n* **VVideo:** hide overlays for background variant ([466dc6f](https://github.com/vuetifyjs/vuetify/commit/466dc6fb87acf5a0e6e2d67f9196eaf3f6705e9f))\n\n</details>\n\n## Building the Future{ .mt-4 }\n\nAugust is about laying the foundation to begin integrating Vuetify0 into Vuetify. The pre‑alpha work is shaping the path for incremental adoption of Zero‑powered primitives across the framework.\n\nIn parallel, the ecosystem continues to be polished and expanded:\n\n* VEditor is nearing release with robust formatting and form integration.\n* VVideo and related media features are progressing.\n* Improvements to performance, theming, docs, and the redesigned issues experience are landing steadily.\n\nThanks for the feedback and contributions—these foundations will turn into practical wins shipping over the next few releases.\n\n---\n\n*Stay connected with Vuetify updates through our [GitHub repository](https://github.com/vuetifyjs/vuetify), [Discord community](https://discord.gg/eXubxyJ), and upcoming webinar series announcements.*\n"
  },
  {
    "path": "packages/docs/src/pages/en/blog/building-a-basic-nuxt-application-with-vuetify.md",
    "content": "---\nlayout: blog\nmeta:\n  title: Vuetify — Building a Basic Nuxt App with Vuetify\n  description: Learn how to build a basic Nuxt app with Vuetify\n  keywords: Vuetify, Nuxt, Vue, JavaScript, Web Development\n---\n\n# Building a Basic Nuxt Application with Vuetify\n\n---\n\n🖊️ Eric Sarrion • 📅 February 21st, 2025\n\n<PromotedEntry />\n\n---\n\n## Introduction\n\nIn this article, we will build a basic application using Vue.js and Vuetify, leveraging the Nuxt framework.\n\nWhy do we use the Nuxt framework?\n\n1. It allows us to easily create new pages in our application using URLs such as /contact to access the contact page, or /products to access the products page.\n1. It simplifies the use of Vuetify components through a simple configuration in the nuxt.config.ts file.\n1. It automatically loads Vue.js methods and the components of our application without the need to import them manually each time. No more instructions like import { ref } from \"vue\".\n\nFor the mere simplification of the code enabled by the automatic loading of Vue.js methods and our application’s components, using Nuxt in our projects is highly recommended.\n\nWhy do we use Vuetify?\n\n1. Vuetify was created in 2016 and has been regularly updated and improved since then. Version 3 fully utilizes the latest version of Vue.js, with the `<script setup>` syntax.\n1. Vuetify has a large variety of components, and here we will use a few of them to create the structure of an application that includes a toolbar and a menu for selecting which pages to display.\n\nNow, let’s present the application built with Vue.js and Vuetify.\n\n## Overview of the Application Built with Vuetify\n\nThe application will consist of three simple pages, each displaying plain text centered on the page. The application can, of course, be expanded by including more information on each page. However, this type of application is truly the foundation of many modern applications.\n\nWhen launching the application, the homepage will be displayed like this:\n\n![Homepage of the Nuxt and Vuetify application with a toolbar and footer.](https://cdn.vuetifyjs.com/docs/images/blog/building-a-basic-nuxt-application-with-vuetify/0.png){ height=500 }\n\nA toolbar is displayed at the top of the window, along with a footer at the bottom.\n\nThe toolbar contains the application's title (here, \"My Application\") and action buttons:\n\n1. The button on the left (to the left of the title) is a button that displays a navigation menu, allowing users to navigate between the different pages of the application. In this case, we have three main pages: the homepage, the products page, and the contact page.\n1. To the right of the navigation button is the name of the application, \"My Application\".\n1. Finally, on the right side of the toolbar, we have added three buttons that allow direct access to each page of the application. These buttons have the same functionality as the navigation menu. We included them to demonstrate that it is possible to access a page directly by clicking on a button.\n\nLet’s open the navigation menu by clicking the corresponding button on the left side of the toolbar:\n\n![Navigation menu opened from the sidebar.](https://cdn.vuetifyjs.com/docs/images/blog/building-a-basic-nuxt-application-with-vuetify/16.png){ height=500 }\n\nA sidebar has appeared on the left side of the screen. Each item in the displayed list allows direct navigation to the corresponding page. For example, let’s click on the \"Products\" item:\n\n![Homepage of the Nuxt and Vuetify application with a toolbar and footer.](https://cdn.vuetifyjs.com/docs/images/blog/building-a-basic-nuxt-application-with-vuetify/0.png){ height=500 }\n\nThe page displaying the products has now appeared.\n\nNotice that the URL shown in the browser's address bar now displays /products following the server name <http://localhost:3000>. This is because Nuxt makes it easy to use the Vue Router's built-in routing system with Nuxt.\n\nNow that we have demonstrated the main features of the application, let’s show how to build it using Vuetify and Nuxt.\n\n## Creating the Application in Nuxt.js\n\nNuxt makes it simple to create a Vue.js application that integrates Vuetify. Before proceeding, Node.js must be installed to use npm commands.\n\nTo do this, enter the following command in a terminal:\n\n```bash\nnpx nuxi init vuetify-app\n```\n\n<!-- ![Screenshot of the application](https://cdn.vuetifyjs.com/docs/images/blog/building-a-basic-nuxt-application-with-vuetify/1.png){ height=500 } -->\n\nThe command npx nuxi init vuetify-app is used to initialize a Nuxt project with a basic configuration in a directory named vuetify-app. This command breaks down as follows:\n\n1. npx: npx is a tool that comes with Node.js, allowing you to run npm packages without needing to install them globally on your system. This means you can use a tool or script directly without having to download it first.\n\nIn this case, npx runs nuxi, a utility provided by Nuxt.\n\n1. nuxi: nuxi is the command-line tool for Nuxt. It is used to create, start, and manage Nuxt projects. The features of nuxi include:\n\n- Creating new Nuxt projects.\n- Starting a development server.\n- Generating static files for static applications.\n\n1. init: init is a specific command for nuxi that initializes a new Nuxt project. It creates the basic project structure (configuration files) and sets up directories like pages, components, etc., which will contain the source files of our application.\n\n1. vuetify-app: This final argument is the name of the folder where the project will be created. In this example, vuetify-app is the directory where Nuxt will initialize a project with the default structure. This folder should not exist, it will be created. After running this command, you should get a folder containing the basic configuration files for a Nuxt project.\n\nAt the end of the command execution, you will get:\n\n![Terminal output showing the successful initialization of the Nuxt project.](https://cdn.vuetifyjs.com/docs/images/blog/building-a-basic-nuxt-application-with-vuetify/2.png){ height=500 }\n\nWe now need to enter the following two commands:\n\n1. The command cd vuetify-app allows you to navigate to the directory of the default Vue.js application that has been created.\n1. The command npm run dev starts the server, enabling us to view our application in a browser.\n\nLet’s enter these two commands:\n\n![Terminal output indicating the local server running on port 3000.](https://cdn.vuetifyjs.com/docs/images/blog/building-a-basic-nuxt-application-with-vuetify/3.png){ height=500 }\n\nA local server is now running, accessible on port 3000. Simply enter the URL <http://localhost:3000> in your browser to access the previously created application.\n\n![The default homepage displayed in the browser.](https://cdn.vuetifyjs.com/docs/images/blog/building-a-basic-nuxt-application-with-vuetify/4.png){ height=500 }\n\nThis displays the homepage of the Vue.js application created by the Nuxt framework.\n\nNow, let’s take a look at the main files and directories generated in the default application.\n\n## Main Files and Directories in the Nuxt-Created Application\n\nIn the vuetify-app directory, you can see the files and folders that have been created within the application:\n\n![Directory structure of the Nuxt project with components, pages, and plugins folders.](https://cdn.vuetifyjs.com/docs/images/blog/building-a-basic-nuxt-application-with-vuetify/5.png){ height=300 }\n\nFor our application, we will need three additional directories, which will be placed directly in the root directory of the application:\n\n- The **components** directory will contain the Vue.js components of our application.\n- The **pages** directory will contain the pages of our application. A page is a Vue.js component that will be displayed in the application using internal routing. For example, the contact.vue page, located in the pages directory, will be displayed using the URL <http://localhost:3000/contact>.\n- The **plugins** directory will contain the file associated with the Vuetify configuration, named vuetify.js in this case.\n\nThus, after creating the components, pages, and plugins directories, we will have the following structure:\n\n![Terminal output showing the successful initialization of the Nuxt project.](https://cdn.vuetifyjs.com/docs/images/blog/building-a-basic-nuxt-application-with-vuetify/6.png){ height=300 }\n\nWe have seen the main directories of the application created with Nuxt, now let’s configure this application to display components from the Vuetify library.\n\n## Configuring the Application to Use Vuetify Components\n\nThe Vue.js application created with Nuxt does not yet allow the use of Vuetify components like v-btn, which displays a stylized button.\n\nTo enable Vuetify components, we need to create a Vuetify configuration file in the plugins directory that we previously created. This JavaScript file will be named vuetify.js and will reside in the plugins directory.\n\nHere is the minimum content for the file plugins/vuetify.js:\n\n```js { resource=\"plugins/vuetify.js\" }\nimport { createVuetify } from 'vuetify'\nimport * as components from 'vuetify/components'\n\nexport default defineNuxtPlugin((nuxtApp) => {\n  const vuetify = createVuetify({ components })\n  nuxtApp.vueApp.use(vuetify)\n})\n```\n\nWe import the createVuetify() method defined by Vuetify, which allows us to define the vuetify object used in the Nuxt application. The Vuetify components are also imported to be used in the Vue.js application.\n\nWe also need to modify the nuxt.config.ts file, which is responsible for configuring Nuxt. This file is located in the root directory of the application.\n\nHere is how to update the nuxt.config.ts file:\n\n```ts { resource=\"nuxt.config.ts\" }\nexport default defineNuxtConfig({\n  pages: true,\n  ssr: false,\n  devtools: { enabled: false },\n  css: [\n    'vuetify/styles',\n    '@mdi/font/css/materialdesignicons.min.css',\n  ],\n  plugins: ['~/plugins/vuetify.js'],\n  components: true,\n  build: {\n    transpile: ['vuetify'],\n  },\n})\n ```\n\nTo define that the internal routing system is used with the pages, we configure access to Vuetify's CSS style files and the use of default MDI icons, as well as the location of the vuetify.js file previously created in the plugins directory.\n\nThe pages property set to true in the nuxt.config.ts file implies that the pages of the application will be defined in specific Vue.js components, which will be inserted into the pages directory created for this purpose. The first page to be displayed will be the homepage, corresponding to the index.vue component located in the pages directory.\n\nThe configuration is now complete, and we can use Vuetify components in our application.\n\n## Creating a Minimal Nuxt Application Using Vuetify Components\n\nTo create a minimal Nuxt application using Vuetify components, you need to:\n\n- Create the index.vue file for the homepage located in the pages directory.\n- Modify the app.vue component file to indicate the use of internal routing based on the URL. For example, the URL <http://localhost:3000/contact> will grant access to the contact.vue page located in the pages directory.\n\nLet’s start by modifying the app.vue component, which is the first component displayed in the Nuxt application. We will use the NuxtPage component from Nuxt to display the page corresponding to the indicated URL.\n\nHere is the content of app.vue:\n\n![Homepage of the Nuxt and Vuetify application with a toolbar and footer.](https://cdn.vuetifyjs.com/docs/images/blog/building-a-basic-nuxt-application-with-vuetify/0.png){ height=500 }\n\nThe use of the NuxtPage component is mandatory in a Nuxt-created application because it synchronizes the displayed page with the URL in the browser. This ensures that the contact.vue page in the pages directory corresponds to the /contact URL in the browser.\n\nNow, we need to create the index.vue page, which will be displayed by default when the URL is simply <http://localhost:3000>. In this page, we can use the Vuetify v-btn component to verify that we have access to Vuetify components.\n\nHere is the content of the pages/index.vue file:\n\n```html { resources=\"pages/index.vue\" }\n<template>\n  <v-container>\n    <v-btn color=\"primary\" text=\"Vuetify Button\"></v-btn>\n  </v-container>\n</template>\n```\n\nWe are using here the v-container component, which allows encapsulating one or more components with margins around them, and the v-btn component, which displays a button in the Vuetify style.\n\nWe verify that the components are indeed active in the index.vue page:\n\n![Screenshot showing the Vuetify button on the homepage.](https://cdn.vuetifyjs.com/docs/images/blog/building-a-basic-nuxt-application-with-vuetify/7.png){ height=300 }\n\nThe button is correctly displayed according to the attributes specified in the v-btn component, particularly the primary color. Additionally, the effect of the v-container component is visible because a margin has been applied around the button, preventing it from being positioned against the edges of the window.\n\nNow that we have seen how to structure the Vue.js application with Vuetify and Nuxt, let’s see how to modify it to integrate components that will display toolbars and a menu to access the pages of the application.\n\n## Displaying a Toolbar at the Top of the Window\n\nThe first thing to do is to display a toolbar at the top of the window. This toolbar will contain the title of the application, along with a button that will open a menu displaying the pages, allowing navigation within the application.\n\nTo do this, we modify the app.vue file of the application. This file contains the overall structure of the application and is the first to be displayed when the application starts in a browser.\n\nWe will use the v-app-bar component, which is a Vuetify component used to display the navigation bar.\n\n```html { resource=\"app.vue\" }\n<template>\n  <v-app>\n    <!-- Toolbar at the top of the screen -->\n    <v-app-bar color=\"primary\" height=\"48\">\n      <!-- Title of the application with adjusted margin and font size -->\n      <v-app-bar-title class=\"text-h6 ms-3\">\n        <v-icon icon=\"mdi-apps\"></v-icon>\n\n        <span class=\"ms-1\">My Application</span>\n      </v-app-bar-title>\n    </v-app-bar>\n\n    <!-- Main content of the application -->\n    <v-main>\n      <NuxtPage />\n    </v-main>\n  </v-app>\n</template>\n```\n\nWe see the necessary structure to display a toolbar with Vuetify:\n\n- The v-app-bar component uses the color and height attributes. The color attribute allows specifying a background color for the toolbar, while the height attribute allows specifying its height. If these attributes are not provided, Vuetify applies default values.\n- The v-app-bar-title component defines the content to be displayed in the toolbar's title. Here, we use a v-icon component to leverage the MDI icons defined in Vuetify (in this case, the mdi-apps icon, which displays an icon representing a set of applications), followed by a span element displaying the text. The Vuetify internal CSS class ml-1 adds a margin of 1 unit to the left side of the element. This helps visually separate the text from the preceding icon.\n\nLet's display the corresponding page:\n\n![Application with a toolbar featuring an icon and a title.](https://cdn.vuetifyjs.com/docs/images/blog/building-a-basic-nuxt-application-with-vuetify/8.png){ height=500 }\n\nThe toolbar has been displayed correctly, but the index.vue page still contains the previously inserted button.\n\nLet's modify this index.vue page to display more appropriate content for the homepage.\n\n## Create the homepage displayed at startup\n\nWe simply need to modify the index.vue page. In it, we display an mdi-home icon followed by the text of the page: My Application's Home Page. The entire content needs to be centered on the page.\n\n```html { resources=\"pages/index.vue\" }\n<template>\n  <v-container class=\"fill-height d-flex flex-column align-center justify-center text-center\">\n    <v-icon icon=\"mdi-home\" size=\"64\"></v-icon>\n\n    <div class=\"mt-3\">My Application's Home Page</div>\n  </v-container>\n</template>\n```\n\nWe use the v-container and v-icon components from Vuetify, as seen previously. We also apply the CSS classes defined in Vuetify to the v-container component, allowing the use of Flexbox.\n\nNow we get:\n\n![Homepage with an icon and text centered using Vuetify components.](https://cdn.vuetifyjs.com/docs/images/blog/building-a-basic-nuxt-application-with-vuetify/9.png){ height=500 }\n\nBefore handling the click on the mdi-apps button in the toolbar (which allows displaying the navigation menu), let's see how to integrate a footer into our application.\n\n## Display a footer at the bottom of the window\n\nThe insertion of a footer in the Vuetify application is similar to that of the toolbar. We use the v-footer component from Vuetify.\n\nThe app.vue file is therefore modified:\n\n```html { resource=\"app.vue\" }\n<template>\n  <v-app>\n    <!-- Toolbar at the top of the screen -->\n    <v-app-bar color=\"primary\" height=\"48\">\n    <!-- Title of the application with adjusted margin and font size -->\n      <v-app-bar-title class=\"text-h6 ms-3\">\n        <v-icon icon=\"mdi-apps\"></v-icon>\n\n        <span class=\"ms-1\">My Application</span>\n      </v-app-bar-title>\n    </v-app-bar>\n\n    <!-- Main content of the application -->\n    <v-main>\n      <NuxtPage />\n    </v-main>\n\n    <!-- Smaller footer at the bottom of the screen -->\n    <v-footer color=\"secondary\" height=\"30\">\n      <v-container class=\"text-center text-caption\">\n        © {{ new Date().getFullYear() }} My Application - All Rights Reserved\n      </v-container>\n    </v-footer>\n  </v-app>\n</template>\n```\n\nWe simply inserted the v-footer component, specifying the color and height attributes as before. The content is simply placed inside a v-container component.\n\nNow we get:\n\n![Footer displayed at the bottom of the application window.](https://cdn.vuetifyjs.com/docs/images/blog/building-a-basic-nuxt-application-with-vuetify/10.png){ height=500 }\n\nThe footer is not positioned at the desired height. Indeed, Vuetify requires correlating the toolbar and footer by using the app attribute in both components. This app attribute indicates that these components are linked to each other, making it essential.\n\nLet's add the app attribute to both our v-app-bar and v-footer components:\n\n```html { resource=\"app.vue\" }\n<template>\n  <v-app>\n    <!-- Toolbar at the top of the screen -->\n    <v-app-bar color=\"primary\" height=\"48\">\n      <!-- Title of the application with adjusted margin and font size -->\n      <v-app-bar-title class=\"text-h6 ms-3\">\n        <v-icon icon=\"mdi-apps\"></v-icon>\n\n        <span class=\"ms-1\">My Application</span>\n      </v-app-bar-title>\n    </v-app-bar>\n\n    <!-- Main content of the application -->\n    <v-main>\n      <NuxtPage />\n    </v-main>\n\n    <!-- Smaller footer at the bottom of the screen -->\n    <v-footer app color=\"secondary\" height=\"30\">\n      <v-container class=\"text-center text-caption\">\n        © {{ new Date().getFullYear() }} My Application - All Rights Reserved\n      </v-container>\n    </v-footer>\n  </v-app>\n</template>\n```\n\nThe app attribute has been added to the v-app-bar component and the v-footer component.\n\nLet's see the resulting output:\n\n![Footer correctly aligned at the bottom after using the app attribute.](https://cdn.vuetifyjs.com/docs/images/blog/building-a-basic-nuxt-application-with-vuetify/11.png){ height=500 }\n\nThe footer is now displayed correctly, taking into account the height attribute specified within it.\n\n## Using a navigation menu\n\nWe now need to add a navigation menu that allows selecting a page from the following options:\n\n1. The index.vue page, which is displayed by default.\n2. The products.vue page, which displays the products of our application.\n3. The contact.vue page, which allows contacting the management.\n\nThis navigation menu will be accessible by clicking on the mdi-apps icon in the toolbar.\n\nThe app.vue component is modified to integrate the navigation menu:\n\n```html { resource=\"app.vue\" }\n<template>\n  <v-app>\n  <!-- Toolbar at the top of the screen -->\n  <v-app-bar color=\"primary\" height=\"48\">\n    <!-- Title of the application with adjusted margin and font size -->\n    <v-app-bar-title class=\"text-h6 ms-3\">\n      <v-icon icon=\"mdi-apps\"></v-icon>\n\n      <span class=\"ms-1\">My Application</span>\n    </v-app-bar-title>\n  </v-app-bar>\n\n  <!-- Navigation drawer for menu actions -->\n  <v-navigation-drawer v-model=\"drawer\">\n    <v-list>\n      <!-- Menu items in the drawer with icons -->\n      <v-list-item\n        @click=\"navigateTo('/')\"\n        title=\"Home\"\n        prepend-icon=\"mdi-home\"\n      ></v-list-item>\n\n      <v-list-item\n        @click=\"navigateTo('/products')\"\n        title=\"Products\"\n        prepend-icon=\"mdi-cube-outline\"\n      ></v-list-item>\n\n      <v-list-item\n        @click=\"navigateTo('/contact')\"\n        title=\"Contact\"\n        prepend-icon=\"mdi-email\"\n      ></v-list-item>\n    </v-list>\n  </v-navigation-drawer>\n\n  <!-- Main content of the application -->\n  <v-main>\n    <NuxtPage />\n  </v-main>\n\n  <!-- Smaller footer at the bottom of the screen -->\n  <v-footer app color=\"secondary\" height=\"30\">\n    <v-container class=\"text-center text-caption\">\n      © {{ new Date().getFullYear() }} My Application - All Rights Reserved\n    </v-container>\n  </v-footer>\n  </v-app>\n</template>\n```\n\nThe v-navigation-drawer component from Vuetify allows defining the elements that make up the navigation menu. It is defined as a list using the v-list component:\n\n- Each list item is a v-list-item component, itself composed of a title (v-list-item-title component).\n- Each title is represented by an icon (v-icon component) and a text.\n\nThe appearance of the menu is controlled by a reactive variable, here named drawer. If it is set to false (default value), the menu is not displayed. As soon as it changes to true, the menu appears. The change from false to true (or vice versa) happens when the mdi-apps button in the toolbar is clicked.\n\nThe menu also needs to be linked to this reactive variable. To achieve this, Vuetify uses the v-model attribute in the v-navigation-drawer component. Many Vuetify components use the v-model attribute to link the component to a reactive variable in the program.\n\nClicking on each navigation menu item is handled by the @click attribute, which is a shorthand for v-on:click provided by Vue.js. We call the navigateTo(page) method, which displays the page specified as a parameter, such as \"/\" (to display index.vue), \"/products\" (to display products.vue), or \"/contact\" (to display the contact.vue page).\n\nLet's verify the proper functioning of this mechanism by displaying the products.vue page. We assume that each page of the application has been created similarly to the index.vue page. These pages will be created in the next section if needed.\n\n![Products page displayed after navigating using the sidebar menu.](https://cdn.vuetifyjs.com/docs/images/blog/building-a-basic-nuxt-application-with-vuetify/12.png){ height=500 }\n\nWe can now navigate from page to page within the application.\n\n## Creating the other pages of the application\n\nThe products.vue page, displayed previously, must first be created. We create it using the same principle as the index.vue page that was created earlier.\n\nHere is the code describing each of the components associated with the pages of the application:\n\n```html { resource=\"pages/products.vue\" }\n<template>\n  <v-container class=\"fill-height d-flex flex-column align-center justify-center text-center\">\n    <v-icon icon=\"mdi-cube-outline\" size=\"64\"></v-icon>\n\n    <div class=\"mt-3\">My Application's Products Page</div>\n  </v-container>\n</template>\n```\n\n## Adding buttons to the toolbar\n\nFinally, we might want to insert new buttons into the toolbar at the top of the screen, on the right side. These buttons can provide direct access to one of the application’s pages, without using the previously implemented navigation menu.\n\nWe therefore insert buttons in the form of icons into the application's toolbar. The app.vue component becomes:\n\n```html\n<template>\n  <v-app>\n    <!-- Toolbar at the top of the screen -->\n    <v-app-bar color=\"primary\" height=\"48\">\n      <!-- Title of the application with adjusted margin and font size -->\n      <v-app-bar-title class=\"text-h6 ms-3\">\n        <v-icon icon=\"mdi-apps\" @click=\"drawer = !drawer\"></v-icon>\n\n        <span class=\"ms-1\">My Application</span>\n      </v-app-bar-title>\n\n      <!-- Spacer to push the following elements to the right -->\n      <v-spacer />\n\n      <!-- Menu icons on the right side of the toolbar -->\n      <v-btn icon=\"mdi-home\" @click=\"navigateTo('/')\"></v-btn>\n\n      <v-btn icon=\"mdi-cube-outline\" @click=\"navigateTo('/products')\"></v-btn>\n\n      <v-btn icon=\"mdi-email\" @click=\"navigateTo('/contact')\"></v-btn>\n    </v-app-bar>\n\n    <!-- Navigation drawer for menu actions -->\n    <v-navigation-drawer v-model=\"drawer\">\n      <v-list>\n        <!-- Menu items in the drawer with icons -->\n        <v-list-item\n          @click=\"navigateTo('/')\"\n          title=\"Home\"\n          prepend-icon=\"mdi-home\"\n        ></v-list-item>\n\n\n        <v-list-item\n          @click=\"navigateTo('/products')\"\n          title=\"Products\"\n          prepend-icon=\"mdi-cube-outline\"\n        ></v-list-item>\n\n\n        <v-list-item\n          @click=\"navigateTo('/contact')\"\n          title=\"Contact\"\n          prepend-icon=\"mdi-email\"\n        ></v-list-item>\n      </v-list>\n    </v-navigation-drawer>\n\n    <!-- Main content of the application -->\n    <v-main>\n      <NuxtPage />\n    </v-main>\n\n    <!-- Smaller footer at the bottom of the screen -->\n    <v-footer app color=\"secondary\" height=\"30\">\n      <v-container class=\"text-caption text-center\">\n        © {{ new Date().getFullYear() }} My Application - All Rights Reserved\n      </v-container>\n    </v-footer>\n  </v-app>\n</template>\n\n<script setup>\n// Drawer state to open/close the navigation drawer\nconst drawer = shallowRef(false)\n</script>\n```\n\nVuetify offers the v-spacer component, which allows \"pushing\" the elements that follow it to the right. The buttons will therefore be positioned on the right side of the toolbar.\n\nTo display the buttons, we use the v-btn component with the icon attribute. This attribute allows the button to be displayed in a circular shape, according to the icon it contains. The @click attribute is also used to handle navigation to the desired page, just as we did in the navigation menu.\n\nThe application is now displayed:\n\n![Toolbar with additional navigation buttons for quick page access.](https://cdn.vuetifyjs.com/docs/images/blog/building-a-basic-nuxt-application-with-vuetify/14.png){ height=500 }\n\nClicking on the buttons displays the desired page. For example, the /contact page:\n\n![Contact page displayed after selecting it from the navigation menu.](https://cdn.vuetifyjs.com/docs/images/blog/building-a-basic-nuxt-application-with-vuetify/15.png){ height=500 }\n\n## Conclusion\n\nIn this article, we have covered fundamental aspects of using Vue.js and Vuetify in a Nuxt application.\n\nWe explored several Vuetify components that help design the application, and we learned how to break down the application into different pages, through which we navigated.\n"
  },
  {
    "path": "packages/docs/src/pages/en/blog/building-with-nuxt-and-unocss.md",
    "content": "---\nlayout: blog\nmeta:\n  title: Build with Nuxt and UnoCSS\n  description: Learn how to effectively integrate Vuetify v3 with UnoCSS taking into consideration breakpoints, theme, typography and CSS layers.\n  keywords: UnoCSS, TailwindCSS, Theme, CSS Layers\n---\n\n# Creating a highly optimized Vuetify 3 project with Nuxt and UnoCSS\n\nAlthough traditionally we tend to think about Vuetify as a great fit for large projects, it can also serve smaller projects that tend to prioritize performance. When scaffolding new projects it comes with tree-shaking out-of-the-box, but there is still some room for improvement as main CSS bundle ships hundreds of kB of CSS we might not need. If the users like your page loading animation and you can afford a bit of overhead, there is nothing wrong with simplified setup that does the job and let's you focus on the business logic or UX. That said, integrating UnoCSS (atomic CSS engine) will help us trim the bundle and enable dynamic utilities. With it's superpowers we not only avoid writing plain CSS (most of the time), but can also make use of TailwindCSS tooling (IDE extensions) or standardize certain utilities.\n\nThe article will walk through scaffolding a starter project, installing and wiring UnoCSS, customizing fonts, handling light/dark mode and aligning breakpoints. Finally, \"CSS layers\" section shows how to order Vuetify, UnoCSS, and app‑specific styles to avoid specificity conflicts.\n\n🖊️ Jacek Czarniecki • 📅 December 22nd, 2025\n\n<PromotedEntry />\n\n---\n\n## Table of Contents\n\n* [The steps ahead](#the-steps-ahead)\n* [Scaffold a new project](#scaffold-a-new-project)\n* [Keep an eye on the outputs](#keep-an-eye-on-the-outputs)\n* [Disable CSS for utilities](#disable-css-for-utilities)\n  * [Shortest way to setup UnoCSS](#shortest-way-to-setup-unocss)\n  * [Migrating to utilities from TailwindCSS v4](#migrating-to-utilities-from-tailwindcss-v4)\n  * [Resolve specificity issues (quickly)](#resolve-specificity-issues-quickly)\n  * [Font family configuration](#font-family-configuration)\n  * [Light/dark mode compatibility](#light-dark-mode-compatibility)\n  * [Custom typography (text variants)](#custom-typography-text-variants)\n  * [Customize breakpoints](#customize-breakpoints)\n* [Using CSS layers](#using-css-layers)\n\n---\n\n## The steps ahead\n\nRight after generating starter project we are going to disable all CSS for non-theme colors (Material colors palette) and CSS utilities. This leaves out styles for \"reset\", transitions and components. UnoCSS is going to generate them on the fly making sure we only bundle CSS we actually use.\n\nAlong the way we will keep in mind that successful integration has to correctly match following aspects:\n\n* themes (light / dark mode)\n* custom typography\n* responsive breakpoints\n\nLastly, we will enable CSS layers to establish order. This part is meant for advanced frontend developers and teams that have a solid knowledge of CSS and the layers can impact day to day work. It is not a free lunch and it might not always fit the workflow or the way you write CSS.\n\n## Scaffold a new project\n\n::: tabs\n\n```bash [pnpm]\npnpm create vuetify@2.8.0\n```\n\n```bash [yarn]\nyarn create vuetify@2.8.0\n```\n\n```bash [npm]\nnpm create vuetify@2.8.0\n```\n\n```bash [bun]\nbun create vuetify@2.8.0\n```\n\n:::\n\n...choose \"Nuxt Recommended\". Following questions don't matter much.\n\nStart the project on localhost\n\n::: tabs\n\n```bash [pnpm]\npnpm dev\n```\n\n```bash [yarn]\nyarn dev\n```\n\n```bash [npm]\nnpm run dev\n```\n\n```bash [bun]\nbun run dev\n```\n\n:::\n\n## Keep an eye on the outputs\n\nNuxt uses Vite under the hood to build assets for production. Sizes are all layed out in the logs.\n\n::: tabs\n\n```bash [pnpm]\npnpm build\n```\n\n```bash [yarn]\nyarn build\n```\n\n```bash [npm]\nnpm run build\n```\n\n```bash [bun]\nbun run build\n```\n\n:::\n\n![Log from Nuxt build showing entry bundle exceeding 500kB (unminified)](https://cdn.vuetifyjs.com/docs/images/blog/building-with-nuxt-and-unocss/nuxt-build-log.png)\n\nAnytime you build the project, bundle files are right there in the `.output/public/_nuxt` directory. The CSS bundle file named `entry{hash}.css` is one that might be particularly interesting.\n\n::: tip\nWhen inspecting bundles, keep in mind VSCode might refuse to format large files, freeze or even crash. I recommend Zed editor for the optimal experience.\n:::\n\n## Disable CSS for utilities\n\nLet's adjust the `app/assets/settings.scss`:\n\n```scss { resource=\"app/assets/settings.scss\" }\n@use 'vuetify/settings' with (\n  $utilities: false,\n);\n```\n\nIf you run `pnpm build` again, you may observe that `entry.*.css` bundle is significantly smaller. We could get even further by replacing MDI font icons with SVG icons or UnoCSS preset for icons, but it is out of scope for this article.\n\n### Shortest way to setup UnoCSS\n\n::: tabs\n\n```bash [pnpm]\npnpm add -D unocss unocss-preset-vuetify @unocss/nuxt\n```\n\n```bash [yarn]\nyarn add -D unocss unocss-preset-vuetify @unocss/nuxt\n```\n\n```bash [npm]\nnpm i -D unocss unocss-preset-vuetify @unocss/nuxt\n```\n\n```bash [bun]\nbun add -D unocss unocss-preset-vuetify @unocss/nuxt\n```\n\n:::\n\nRegister the module in `nuxt.config.ts` and paste initial configuration nearby:\n\n```ts { resource=\"nuxt.config.ts\" }\nimport { presetVuetify } from 'unocss-preset-vuetify'\n\nexport default defineNuxtConfig({\n  // ...\n\n  modules: [\n    '@unocss/nuxt',\n    // ... keep other modules\n  ],\n\n  // vuetify: { ... }\n\n  unocss: {\n    presets: [\n      presetVuetify(),\n    ],\n    safelist: [/* classes that have to be always generated */],\n  },\n})\n```\n\nWith the dedicated preset for Vuetify, we get all the utilities back. Except this time, UnoCSS scans the project files and generates CSS only for the classes we actually use.\n\nKeep in mind that this library was released fairly recently. If you notice any problem or limitation, reach out on [Discord](https://community.vuetifyjs.com) or post the issue on [GitHub](https://github.com/vuetifyjs/unocss-preset-vuetify).\n\n### Migrating to utilities from TailwindCSS v4\n\n::: tabs\n\n```bash [pnpm]\npnpm remove unocss-preset-vuetify\npnpm add -D @unocss/preset-wind4\n```\n\n```bash [yarn]\nyarn remove unocss-preset-vuetify\nyarn add -D @unocss/preset-wind4\n```\n\n```bash [npm]\nnpm un unocss-preset-vuetify\nnpm i -D @unocss/preset-wind4\n```\n\n```bash [bun]\nbun remove unocss-preset-vuetify\nbun add -D @unocss/preset-wind4\n```\n\n:::\n\nThe preset called [Wind4](https://unocss.dev/presets/wind4) is an official configuration builder providing making it easy to expose all the utilities from TailwindCSS v4 in your project. There are 2 configuration points - an object passed to the main `presetWind4` method and `theme` field next to the `presets`. Unlike using pure TailwindCSS v4 it let's us configure stuff in JavaScript code.\n\n```ts { resource=\"nuxt.config.ts\" }\nimport presetWind4 from '@unocss/preset-wind4'\n\nexport default defineNuxtConfig({\n  // ...\n  unocss: {\n    presets: [\n      presetWind4({\n        preflights: {\n          reset: false,\n        },\n      }),\n    ],\n    theme: {},\n  },\n})\n```\n\nThe code above ensures we use only CSS reset from Vuetify and won't experience conflicts.\n\nSince TailwindCSS preset comes with its color palette we can use it instead of the Material palette from Vuetify. It is not an equivalent replacement, but if you want to go all-in with TailwindCSS utilities, you probably know what to expect ahead. Let's change the `app/assets/settings.scss`:\n\n```scss { resource=\"app/assets/settings.scss\" }\n@use 'vuetify/settings' with (\n  $color-pack: false, // <- disable colors from Material palette\n  $utilities: false,\n);\n```\n\nWe can finish this part with small adjustment to the example content in `HelloWorld.vue` and `AppFooter.vue`\n\n* replace `fill-height` with `h-full`\n* replace `font-weight-` with `font-`\n* replace `mb-n1` with `-mb-1`\n\nOptionally replace typography classes if you intend to use utilities from TailwindCSS. Further in the article, we will configure UnoCSS to provide typography aligned with Vuetify conventions. If you already know you won't need it, these are the closest equivalents (for the font size only):\n\n* `text-h2` » `text-5xl`\n* `text-h5` » `text-2xl`\n* `text-subtitle-1` » `text-base`\n* `text-body-2` » `text-sm`\n\nTurns out `v-container` paired with `fill-height` class gets special additional styles when `v-row` is also on the page. So we need to add some more utility classes to move the content to the center:\n\n```html\n<v-container class=\"h-full flex items-center\" max-width=\"900\">\n```\n\nThere is one more component that relies on utility classes - `v-row`. Convenient props named `justify` and `align` rely on the utilitity classes for CSS properties `justify-content` and `align-items` respectively. TailwindCSS won't detect them though and even if we could force it to generate them, the classes in TailwindCSS are named slightly differently (e.g. `justify-space-between` vs `justify-between`). There are couple of ways to get around it.\n\n* just paste the classes in any CSS/SCSS file meant for global styles (e.g. `main.scss`)\n* spread `$utilites` to selectively disable most of them while keeping `justify-content` and `align-items`\n* don't use VRow/VCol or ban just those two problematic props (can be achieved by patching `vuetify-eslint-plugin`)\n\nIf you go with the first option, you can copy the classes below.\n\n```scss\n.justify-start { justify-content: flex-start }\n.justify-end { justify-content: flex-end }\n.justify-center { justify-content: center }\n.justify-space-between { justify-content: space-between }\n.justify-space-around { justify-content: space-around }\n.justify-space-evenly { justify-content: space-evenly }\n\n.align-start { align-items: flex-start }\n.align-end { align-items: flex-end }\n.align-center { align-items: center }\n.align-baseline { align-items: baseline }\n.align-stretch { align-items: stretch }\n\n.order-1 { order: 1 }\n// repeat until 12...\n.order-last { order: 13 }\n```\n\nSecond option is trading hardcoded styles for some noise in the Sass configuration.\n\n```scss { resource=\"app/assets/settings.scss\" }\n@use 'vuetify/settings' with (\n  $utilities: (\n    \"align-items\": (responsive: false, unimportant: (align-items)),\n    \"justify-content\": (responsive: false, unimportant: (justify-content)),\n    \"order\": (responsive: false, unimportant: (order)),\n    // followed by 80+ lines with all other utilities set to `false`\n  ),\n);\n```\n\nBy default, those utilities have `responsive: true` and `!important`. The example above is something I would recommend if you plan on using `@layer` which we will go over in the last section of this article.\n\n```scss { resource=\"app/assets/settings.scss\" }\n@use 'vuetify/settings' with (\n  $utilities: (\n    // \"align-items\"     // keep default\n    // \"justify-content\" // keep default\n    // \"order\"           // keep default\n    // followed by 80+ lines with all other utilities set to `false`\n  ),\n);\n```\n\nThe important thing to note here is that we did not use CSS layers so you might see that utility classes from TailwindCSS do not override default styles. An example would be:\n\n```scss { resource=\"app/components/HelloWorld.vue\" }\n<v-card class=\"h-[120px] flex items-center\">...</v-card>\n```\n\nSomething that is not really noticable at first glance is the card rounding. `rounded=\"lg\"` is not recognized by UnoCSS with TailwindCSS preset and `.rounded-lg` class won't appear in the output CSS.\n\n```scss\n.rounded-0 { border-radius: 0 }\n.rounded-sm { border-radius: 2px }\n.rounded { border-radius: 4px }\n.rounded-lg { border-radius: 8px }\n.rounded-xl { border-radius: 24px }\n.rounded-pill { border-radius: 9999px }\n.rounded-circle { border-radius: 50% }\n.rounded-shaped { border-radius: 24px 0 }\n```\n\nor\n\n```scss { resource=\"app/assets/settings.scss\" }\n@use 'vuetify/settings' with (\n  $utilities: (\n    // ...\n    \"rounded\": (responsive: false, unimportant: (border-radius)),\n    // ...\n  ),\n);\n```\n\nDid I mention we have the same problem with `border`? ...ugh... same story, let's move on.\n\nAssuming you want to use VRow and VCol and `$utilities` is no longer `false`, you might be surprised to notice that utilities like `elevation-*`, `hidden-*` (and 2 more) got re-enabled. Those do not have their dedicated flags in the `$utilities` configuration map and only get removed when using strictly `$utilities: false`. It will be resolved in the future - keep an eye on ([#22405](https://github.com/vuetifyjs/vuetify/pull/22405)).\n\n### Resolve specificity issues (quickly)\n\nIn our current configuration order in which the styles are loaded matters - which might make our application look differently after deployment, as usually Vite \"just loads\" assets when working on localhost. This means the order may be quite different for the production bundle.\n\nUsually the easiest fix would be to make UnoCSS generate all the styles with `!important`. This would make them equivalent to original Vuetify utility classes that all had `!important` by default. It is not very elegant, but get's the job done and is easy to reason about. If you are interested in using CSS layers instead, skip to the [final](#using-css-layers) part of this article.\n\n```ts { resource=\"nuxt.config.ts\" }\nexport default defineNuxtConfig({\n  // ...\n  unocss: {\n    presets: [\n      presetWind4({\n        important: true, // <- utility classes always win\n        preflights: { ... },\n      }),\n    ],\n    theme: {},\n  },\n})\n```\n\n### Font family configuration\n\nTo customize fonts we will rely on `@nuxt/fonts` to minimize the amount of configuration required to set up custom font family. Beware, it scans the output CSS - doing a magic trick similar to TailwindCSS, but for the fonts. So you might want to inspect the build logs and make sure there is no mention of Roboto after applying the changes described below.\n\n```ts { resource=\"nuxt.config.ts\" }\nexport default defineNuxtConfig({\n  // ...\n  unocss: {\n    presets: [ ... ],\n    theme: {\n      font: {\n        heading: \"'Bricolage Grotesque', sans-serif\",\n        body: \"Sen, sans-serif\",\n        mono: \"'Sometype Mono', monospace\",\n      },\n    },\n    safelist: ['font-heading', 'font-body', 'font-mono'],\n  },\n  fonts: {\n    defaults: {\n      weights: [300, 400, 500, 700],\n      styles: ['normal', 'italic'],\n      subsets: ['latin'],\n    },\n  },\n})\n```\n\n```scss { resource=\"app/assets/settings.scss\" }\n@use 'vuetify/settings' with (\n  $heading-font-family: var(--font-heading),\n  $body-font-family: var(--font-body),\n  // ...\n);\n```\n\nWe can also create `/assets/main.scss` to make use of monospace font in global styles. It is not strictly necessary, but apps usually need some custom global styles anyway.\n\n```scss { resource=\"app/assets/main.scss\" }\ncode,\npre,\n.v-code {\n  font-family: var(--font-mono);\n}\n```\n\nNew file has to be referenced or imported. Go ahead and include it in `nuxt.config.ts`:\n\n```ts { resource=\"nuxt.config.ts\" }\n  css: ['assets/main.scss'],\n```\n\n### Light/dark mode compatibility\n\nLet's add some colors and try using `dark:*` prefix for some classes to see what happens.\n\n```ts { resource=\"nuxt.config.ts\" }\nexport default defineNuxtConfig({\n  // ...\n  unocss: {\n    presets: [ ... ],\n    theme: {\n      font: { ... },\n      colors: {\n        primary: {\n          800: '#003256',\n        },\n        secondary: {\n          600: '#00677e',\n          800: '#003543',\n        },\n      },\n    },\n  },\n})\n```\n\nNow we can try `dark:bg-primary-800` to one of the cards, and `dark:bg-linear-to-r dark:from-secondary-800 dark:to-secondary-600` to another.\n\nIn order to toggle themes we can add a quick button in the corner of the page. Simply paste the following code anywhere (e.g. in `default.vue` layout file).\n\n```html\n<v-btn\n  icon=\"mdi-theme-light-dark\"\n  position=\"absolute\"\n  location=\"top right\"\n  class=\"ma-2\"\n  @click=\"$vuetify.theme.cycle()\"\n/>\n```\n\n> When adding new colors in `nuxt.config.ts` you might need to occasionally restart the Dev server.\n\nAt this point, toggling dark mode won't apply the background and gradient from classes generated by UnoCSS.\n\nUpon inspection of Elements tab in the browser DevTools, we can find the generated code by searching for `.dark\\:`\n\n```css\n.dark .dark\\:from-secondary-800 { ... }\n.dark .dark\\:to-secondary-600 { ... }\n.dark .dark\\:bg-linear-to-r { ... }\n```\n\nWhat we actually want there is `.v-theme--dark` not `.dark`.\n\nTo align UnoCSS with Vuetify we need add some more code inside `presetWind4({ ... })`\n\n```ts { resource=\"nuxt.config.ts\" }\nexport default defineNuxtConfig({\n  //...\n  unocss: {\n    presets: [\n      presetWind4({\n        preflights: { ... },\n        dark: {\n          dark: '.v-theme--dark',\n          light: '.v-theme--light',\n        },\n      }),\n    ],\n  },\n})\n```\n\n### Custom typography (text variants)\n\n> If you intend to fully rely on TailwindCSS classes or have some specific typography requirements, you can skip to the next part.\n\nLet's add a quick preview page for all the typography options that used to be provided by Vuetify.\n\n```html\n<template>\n  <v-container class=\"page\" max-width=\"800\">\n    <div class=\"flex flex-wrap sm:justify-center gap-6 mt-12\">\n      <div class=\"flex-grow-1\">\n        <div v-for=\"[name, cls] in headings\" :key=\"name\" class=\"my-1 pa-2 hover:bg-gray-500/20\">\n          <div :class=\"[cls, 'py-2']\">{{ name }}</div>\n          <div class=\"pb-2\">\n            <v-code class=\"font-medium px-2 bg-gray-500/20\">{{ cls }}</v-code>\n          </div>\n        </div>\n      </div>\n      <div class=\"flex-grow-1\">\n        <div v-for=\"[name, cls] in bodyText\" :key=\"name\" class=\"my-1 pa-2 hover:bg-gray-500/20\">\n          <div :class=\"[cls, 'py-2']\">{{ name }}</div>\n          <div class=\"pb-2\">\n            <v-code class=\"font-medium px-2 bg-gray-500/20\">{{ cls }}</v-code>\n          </div>\n        </div>\n      </div>\n    </div>\n  </v-container>\n</template>\n\n<script setup lang=\"ts\">\nconst headings = [\n  ['Heading 1', 'text-h1'],\n  ['Heading 2', 'text-h2'],\n  ['Heading 3', 'text-h3'],\n  ['Heading 4', 'text-h4'],\n  ['Heading 5', 'text-h5'],\n  ['Heading 6', 'text-h6'],\n]\nconst bodyText = [\n  ['Subtitle 1', 'text-subtitle-1'],\n  ['Subtitle 2', 'text-subtitle-2'],\n  ['Body 1', 'text-body-1'],\n  ['Body 2', 'text-body-2'],\n  ['Button', 'text-button'],\n  ['Caption', 'text-caption'],\n  ['Overline', 'text-overline'],\n]\n</script>\n```\n\nWe can see none of the usual helper classes work because we disabled `$utilities`. Theoretically we could opt out more granularly, but those classes won't work with responsive prefixes (`sm:*`, `md:*`, etc) - by default they are generated with responsive variants stuffed in the middle (e.g. `*-sm-*`, `*-md-*`, etc.). Having both conventions may be considered an unnecessary mental overhead, so the recommended approach would is to recreate the helpers in UnoCSS configuration `shortcuts`.\n\nFollowing configuration is aligned with defaults from Vuetify v3.11.x\n\n```ts { resource=\"nuxt.config.ts\" }\nexport default defineNuxtConfig({\n  //...\n  unocss: {\n    presets: [ ... ],\n    theme: { ... },\n    shortcuts: {\n      'text-h1': 'font-heading normal-case text-[6rem] font-[300] leading-[1] tracking-[-.015625em]',\n      'text-h2': 'font-heading normal-case text-[3.75rem] font-[300] leading-[1] tracking-[-.0083333333em]',\n      'text-h3': 'font-heading normal-case text-[3rem] font-[400] leading-[1.05] tracking-[normal]',\n      'text-h4': 'font-heading normal-case text-[2.125rem] font-[400] leading-[1.175] tracking-[.0073529412em]',\n      'text-h5': 'font-heading normal-case text-[1.5rem] font-[400] leading-[1.333] tracking-[normal]',\n      'text-h6': 'font-heading normal-case text-[1.25rem] font-[500] leading-[1.6] tracking-[.0125em]',\n      'text-subtitle-1': 'font-body normal-case text-[1rem] font-[400] leading-[1.75] tracking-[.009375em]',\n      'text-subtitle-2': 'font-body normal-case text-[.875rem] font-[500] leading-[1.6] tracking-[.0071428571em]',\n      'text-body-1': 'font-body normal-case text-[1rem] font-[400] leading-[1.5] tracking-[.03125em]',\n      'text-body-2': 'font-body normal-case text-[.875rem] font-[400] leading-[1.425] tracking-[.0178571429em]',\n      'text-button': 'font-body uppercase text-[.875rem] font-[500] leading-[2.6] tracking-[.0892857143em]',\n      'text-caption': 'font-body normal-case text-[.75rem] font-[400] leading-[1.667] tracking-[.0333333333em]',\n      'text-overline': 'font-body uppercase text-[.75rem] font-[500] leading-[2.667] tracking-[.1666666667em]',\n    },\n  },\n})\n```\n\n### Customize breakpoints\n\nDefault breakpoints provided by TailwindCSS preset are not compatible with Vuetify. This mismatch can lead to confusing layout bugs, so let's address this right away.\n\nUnlike other aspects of configuration, it is more challenging to have a squicky cleanup with a single definition. When we customize vanilla Vuetify project we end up having some duplication. This is true even without integrating Vuetify with UnoCSS or Tailwind. It is usually not a big deal, and we can add comments that remind us to keep both places in sync.\n\n* `settings.scss` - breakpoints for VContainer, VCol and responsive utilities (if we would keep any)\n* general Vuetify configuration `display` » `thresholds` for responsive logic in some components, `useDisplay` and `$vuetify.display.*`\n\nUnoCSS needs its own values and expects slightly different format, but we can still define them in a separate TS file and, so we won't end up with 3 places to maintain. As a side-note, integration with TailwindCSS v4 (without UnoCSS) would mean we are back with 3 definitions, because latest TailwindCSS expects pure CSS variables. Anyway, enough talking - let's jump right into the code.\n\nCreate `breakpoints.ts` under `./app/theme` (create new `theme` folder) with the following content:\n\n```ts { resource=\"app/theme/breakpoints.ts\" }\nimport type { DisplayThresholds } from 'vuetify'\n\n// repeated in settings.scss\nconst breakpoints: DisplayThresholds = {\n  xs: 0,\n  sm: 400,\n  md: 840,\n  lg: 1145,\n  xl: 1545,\n  xxl: 2138,\n}\n\nexport const forVuetify = breakpoints\n\nexport const forTailwind = Object.entries(breakpoints)\n  .reduce(\n    (o, [key, value]) => ({ ...o, [key]: `${value}px` }),\n    {} as Record<keyof DisplayThresholds, string>,\n  )\n```\n\nImport and apply it to both Vuetify in UnoCSS in `nuxt.config.ts`\n\n```ts { resource=\"nuxt.config.ts\" }\nimport * as breakpoints from './app/theme/breakpoints'\n\nexport default defineNuxtConfig({\n  // ...\n  unocss: {\n    presets: [ ... ],\n    theme: {\n      font: { ... },\n      colors: { ... },\n      breakpoint: breakpoints.forTailwind,\n    },\n    shortcuts: { ... },\n  },\n\n  vuetify: {\n    moduleOptions: { ... },\n    vuetifyOptions: {\n      display: {\n        mobileBreakpoint: 'md',\n        thresholds: breakpoints.forVuetify,\n      },\n    },\n  },\n}),\n```\n\nNow adjust the SCSS variables for Vuetify. Note that in **v3.x** the `$container-max-widths` would be calculated from breakpoints without rounding the values. If you prefer those values to be stable and rounded to `100px`, you can simply define them right below.\n\n```scss { resource=\"app/assets/settings.scss\" }\n@use 'vuetify/settings' with (\n  $grid-breakpoints: (\n    // repeated in breakpoints.ts\n    'xs': 0,\n    'sm': 400px,\n    'md': 840px,\n    'lg': 1145px,\n    'xl': 1545px,\n    'xxl': 2138px,\n  ),\n  $container-max-widths: (\n    // manually calculated (optional after https://github.com/vuetifyjs/vuetify/pull/19759)\n    'md': 700px,\n    'lg': 1000px,\n    'xl': 1400px,\n    'xxl': 2000px,\n  ),\n);\n```\n\nThe important next step is to verify the changes. I recommend creating and keeping a hidden technical page that will help verify changes or quickly troubleshoot the regression. Here is what you can paste into `app/pages/breakpoints.ts`:\n\n```html\n<template>\n  <v-container ref=\"container\" class=\"mt-12 outline-dashed\">\n    <v-sheet class=\"mx-auto pa-6\" max-width=\"400\">\n      <v-table>\n        <tbody>\n          <tr>\n            <td>Viewport width</td>\n            <td class=\"text-right\">\n              <v-code>{{ $vuetify.display.width }}px</v-code>\n            </td>\n          </tr>\n          <tr>\n            <td>Breakpoint</td>\n            <td class=\"text-right\">\n              <v-code>{{ $vuetify.display.name }}</v-code>\n            </td>\n          </tr>\n          <tr>\n            <td>VContainer width</td>\n            <td class=\"text-right\">\n              <v-code v-if=\"container\">{{ container.$el.clientWidth }}px</v-code>\n            </td>\n          </tr>\n        </tbody>\n      </v-table>\n      <br>\n      <v-row wrap dense>\n        <v-col\n          v-for=\"i in 12\" :key=\"i\"\n          cols=\"12\" sm=\"6\" md=\"4\" lg=\"3\" xl=\"2\" xxl=\"1\"\n        >\n          <div\n            class=\"\n              bg-red-500/50\n              sm:bg-lime-500/50\n              md:bg-sky-500/50\n              lg:bg-amber-500/50\n              xl:bg-teal-500/50\n              xxl:bg-pink-500/50\n              text-white/80\n              xxl:text-transparent\n              text-center\n            \"\n          >VCol</div>\n        </v-col>\n      </v-row>\n    </v-sheet>\n  </v-container>\n</template>\n\n<script setup lang=\"ts\">\nconst container = useTemplateRef('container')\n</script>\n```\n\nRestart the Dev server and open `localhost:3000/breakpoints`.\n\n## Using CSS layers\n\nCSS `@layer` is a relatively new feature designed to scope blocks of CSS and avoid conflicts over specificity. Layers establish a defined order and quite easy to reason about. Anything that is not wrapped in `@layer my-name { ... }` is applied on top. The only tricky part is how browser handles `!important`. If you never used them, you can read more on [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@layer) or an [excellent article from CSS Tricks](https://css-tricks.com/css-cascade-layers/).\n\nIn our example, all we want from CSS layers is to separate utility classes and ensure they get applied on top of base and components CSS without using `!important`. We will start by ensuring we don't have any leftover configuration in `nuxt.config.ts`:\n\n```ts { resource=\"nuxt.config.ts\" }\nexport default defineNuxtConfig({\n  // ...\n  unocss: {\n    presets: [\n      presetWind4({\n        // important: true, // <- we won't need it\n        preflights: { ... },\n      }),\n    ],\n  },\n})\n```\n\nCSS layers are going to be enabled by default in Vuetify v4. If you still use version 3.x, you can opt-in by changing two places: Sass variables and theme configuration.\n\n```scss { resource=\"app/assets/settings.scss\" }\n@use 'vuetify/settings' with (\n  $layers: true, // <- enable layers for CSS generated with Sass\n  // ...\n);\n```\n\nThis will ensure CSS reset, base styles, transitions, component-specific styles and utilities are all wrapped in the dedicated layers.\n\nUpdate Vuetify configuration to enable `@layers` for themes - CSS that is generated at runtime and injected into document `<head>`.\n\n```ts { resourcce=\"vuetify.config.ts\" }\nexport default defineVuetifyConfiguration({\n  theme: {\n    layers: true, // <- enable layers for theme CSS\n    defaultTheme: 'dark',\n    themes: { ... },\n    // ...\n  }\n  // ...\n})\n```\n\nFinally we update UnoCSS configuration\n\n```ts { resource=\"nuxt.config.ts\" }\nexport default defineNuxtConfig({\n  // ...\n  unocss: {\n    presets: [ ... ],\n    layers: {\n      'uno.theme': 0,\n      'uno.shortcuts': 1,\n      'uno.utilities': 2,\n    },\n    outputToCssLayers: {\n      cssLayerName: (layer) => layer === 'properties' ? null : `uno.${layer}`,\n    },\n    theme: { ... },\n    shortcuts: { ... },\n  },\n})\n```\n\nYou can now utilize them to manage overrides without fighting specificity.\nFor example:\n\n```scss { resource=\"app/assets/main.scss\" }\n@layer vuetify.base {\n  code, pre, .v-code {\n    font-family: var(--font-mono);\n  }\n}\n```\n\nWhen it comes to regular development, you should define layers you intend make sense for your app size. For medium projects I tend to start with no-brainer split into `base`, `components`, and custom `utilities`.\n\n```scss\n@layer app {\n  @layer base, components, utilities;\n}\n```\n\nHere are some examples that help visualize the purpose of each group.\n\n```scss { resource=\"app/assets/main.scss\" }\n@layer app.base {\n  .page {\n    padding: 0 2rem 4rem;\n\n    &__header {\n      padding: 2rem 0 1rem;\n    }\n  }\n\n  * {\n    scrollbar-width: thin;\n    scrollbar-color: #888a #8882;\n  }\n}\n\n@layer app.utilities {\n  .force-center {\n    display: grid;\n    place-items: center;\n  }\n\n  .flex-expand-even {\n    display: flex;\n    > * {\n      flex: 1;\n    }\n  }\n}\n```\n\n`@layer app.components { ... }` is meant to be used in `<style>` of reusable components.\n\n```html\n<style>\n@layer app.components {\n  .my-sortable-list { ... }\n}\n</style>\n```\n\n---\n\n## Summary\n\nWhoa! That's a lot. Integrating UnoCSS with a Vuetify + Nuxt project proves to be more than just `$utilities: false` and droping any configuration. Although we could take a shortcut with `important: true` I hope you will take an opportunity to use powerful `@layer` feature and elevate your development experience even more. Regardless, we achieved smaller CSS bundles and on-demand utility generation. Here are the key takeaways:\n\n* `unocss-preset-vuetify` (although experimental) can be a drop-in replacement of Vuetify utilities in projects that prefer to avoid full migration to TailwindCSS and its conventions\n* `@unocss/preset-wind4` is a go-to for developers eager to embrace widely adopted utilities\n* **Dark mode alignment**: Configure UnoCSS to use `.v-theme--dark` and `.v-theme--light` selectors instead of the default `.dark` class\n* **typography** can be fully restored using UnoCSS shortcuts also gaining responsive prefix support\n* **breakpoints** can be aligned across Vuetify's display config, Sass variables, and UnoCSS theme to avoid layout inconsistencies\n* **CSS layers**: enable `$layers: true` in Sass and configure UnoCSS layers to establish a clear cascade order without relying on `!important`\n\nThe result is a leaner, more maintainable styling setup that combines Vuetify's component library with atomic CSS utilities.\n\nIn the future we will explore similar setup based on Vite and pure TailwindCSS v4.\n\nHappy coding!\n"
  },
  {
    "path": "packages/docs/src/pages/en/blog/building-with-vite-and-tailwindcss.md",
    "content": "---\nlayout: blog\nmeta:\n  title: Build with Vite and TailwindCSS v4\n  description: Learn how to integrate Vuetify v4 with TailwindCSS v4 in a Vite project, covering theme colors, dark mode, fonts, breakpoints and CSS layers.\n  keywords: TailwindCSS v4, Vuetify v4, Vite, Theme, CSS Layers\n---\n\n# Integrating Vuetify v4 with TailwindCSS v4 in a Vite project\n\nIn the previous article we explored integrating UnoCSS with Vuetify v3 and Nuxt. This time we take a more direct route: pairing Vuetify v4 with TailwindCSS v4 on a plain Vite setup with both running as Vite plugins. Vuetify v4 ships with CSS layers enabled by default, which makes integrating TailwindCSS significantly smoother than before.\n\nWe will go through the following steps:\n\n* Scaffold a starter project and wire up TailwindCSS\n* Restore `rounded-*` utilities\n* Customize fonts\n* Discuss strategy for theme colors management\n* Ensure Vuetify's light/dark themes work with TailwindCSS `light:*` and `dark:*` prefixes\n* Align breakpoints configuration\n\n🖊️ Jacek Czarniecki • 📅 February 16th, 2026\n\n<PromotedEntry />\n\n---\n\n## Table of Contents\n\n* [Scaffold and install TailwindCSS](#scaffold-and-install-tailwindcss)\n  * [Create the project](#create-the-project)\n  * [Add TailwindCSS v4 via the Vite plugin](#add-tailwindcss-v4-via-the-vite-plugin)\n  * [Disable Vuetify utilities](#disable-vuetify-utilities)\n  * [Migrate HelloWorld.vue and AppFooter.vue](#migrate-helloworldvue-and-appfootervue)\n* [Restore classes for rounded corners](#restore-classes-for-rounded-corners)\n* [Customize fonts](#customize-fonts)\n* [Avoid conflicting color utilities](#avoid-conflicting-color-utilities)\n* [Configure class-based light/dark variants](#configure-class-based-lightdark-variants)\n* [Breakpoints](#breakpoints)\n* [Summary](#summary)\n\n---\n\n## Scaffold and install TailwindCSS\n\n### Create the project\n\n::: tabs\n\n```bash [pnpm]\npnpm create vuetify@latest\n```\n\n```bash [yarn]\nyarn create vuetify\n```\n\n```bash [npm]\nnpm create vuetify\n```\n\n```bash [bun]\nbun create vuetify\n```\n\n:::\n\n...choose the \"Base\" preset and \"None\" when asked for the CSS framework. The point is to learn how the pieces work together by performing code changes manually.\n\nVerify the boilerplate by building it with the standard NPM build script (e.g. `pnpm run build`).\n\nAdd a few generated files to `.gitignore`, so they won't annoy us when inspecting applied changes.\n\n```sh { resource=\".gitignore\" }\n# Generated files\nauto-imports.d.ts\ncomponents.d.ts\ntyped-router.d.ts\n.eslintrc-auto-import.json\n```\n\nCommit all files as a baseline. This way you can always diff against it and keep track of changes we are about to introduce.\n\n### Add TailwindCSS v4 via the Vite plugin\n\n::: tabs\n\n```bash [pnpm]\npnpm add -D tailwindcss @tailwindcss/vite\n```\n\n```bash [yarn]\nyarn add -D tailwindcss @tailwindcss/vite\n```\n\n```bash [npm]\nnpm i -D tailwindcss @tailwindcss/vite\n```\n\n```bash [bun]\nbun add -D tailwindcss @tailwindcss/vite\n```\n\n:::\n\nRegister `tailwindcss()` in the `plugins` array of `vite.config.ts` and create `src/styles/tailwind.css`. Vuetify v4 already provides its own reset, so we skip Tailwind's preflight to avoid two competing resets:\n\n```css { resource=\"src/styles/tailwind.css\" }\n@import \"tailwindcss/theme\" layer(tailwind.theme);\n/* @import \"tailwindcss/preflight.css\" layer(tailwind.reset); <-- skipped intentionally */\n@import \"tailwindcss/utilities\" layer(tailwind.utilities);\n```\n\n```ts { resource=\"src/main.ts\" }\nimport { registerPlugins } from '@/plugins'\nimport App from './App.vue'\nimport { createApp } from 'vue'\n\nimport 'unfonts.css'\nimport './styles/tailwind.css' // <-- include new file\n\nconst app = createApp(App)\nregisterPlugins(app)\napp.mount('#app')\n```\n\n```ts { resource=\"vite.config.mts\" }\nimport tailwindcss from '@tailwindcss/vite'\n// ...\n\nexport default defineConfig({\n  plugins: [\n    tailwindcss(), // <-- register the plugin\n    // ...\n  ],\n```\n\nIn order for Vuetify transitions to work properly, we have to ensure `tailwind.*` layers are placed before `vuetify-final`. Go ahead and add a new file called `layers.scss`:\n\n```css { resource=\"src/styles/layers.scss\" }\n@layer vuetify-core;\n@layer vuetify-components;\n@layer vuetify-overrides;\n@layer vuetify-utilities;\n\n@layer tailwind; /* <-- our new utilities */\n\n@layer vuetify-final;\n```\n\nThen reference it from `vuetify.ts` before importing `vuetify/styles`.\n\n```ts { resource=\"src/plugins/vuetify.ts\" }\n// Styles\nimport '../styles/layers.css'\nimport '@mdi/font/css/materialdesignicons.css'\nimport 'vuetify/styles'\n\n// followed by createVuetify({ ... })\n```\n\n![CSS Layers preview in browser DevTools](https://vuetifyjs.b-cdn.net/docs/images/blog/building-with-vite-and-tailwindcss/vuetify-tailwindcss-layers.png)\n\n### Disable Vuetify utilities\n\nLet's adjust `src/styles/settings.scss`:\n\n```scss { resource=\"src/styles/settings.scss\" }\n@use 'vuetify/settings' with (\n  $color-pack: false,\n  $utilities: false,\n);\n```\n\nIf you run the build again, you should observe that the CSS bundle shrinks noticeably:\n\n```md\nbefore: 658.40 kB │ gzip: 141.74 kB\nafter:  481.24 kB │ gzip: 115.70 kB\n```\n\nThe expected difference is substantial, but we still pay the tax of using the full MDI icon font. Switching to SVG icons (`@mdi/js`) is not a big deal, but we will keep this guide focused on integrating TailwindCSS. If you need to optimize the bundle size further, Vuetify documentation already covers [how to switch to SVG icon set](/features/icon-fonts/#mdi-js-svg).\n\n### Migrate HelloWorld.vue and AppFooter.vue\n\nWith utilities disabled, some classes used in the scaffolded template will stop working. Here are the replacements:\n\n* replace `fill-height` with `h-full`\n* replace `d-flex` with `flex`\n* replace `align-center` with `items-center`\n* replace `font-weight-*` with `font-*`\n* replace `mb-n1` with `-mb-1`\n* replace typography `text-*` classes with native TailwindCSS utilities to achieve similar font size and weight\n  * `text-body-2` » `text-sm`\n  * `text-h2` » `text-7xl`\n\nVRow/VCol can also be replaced with `grid md:grid-cols-2 gap-3` and `md:col-span-2` for the first VCard. However, you might be surprised to learn that Vuetify's grid engine got a major overhaul in v4.0.0 and is much leaner and more flexible than ever.\n\n## Restore classes for rounded corners\n\nSomething that is not really noticeable at first glance is the card rounding. Vuetify's `rounded` prop values (`rounded=\"lg\"`, etc.) emit classes like `.rounded-lg` that collide with Tailwind's naming but use different values.\n\nTailwindCSS lets us define rounding using CSS variables that are later applied by the specific CSS classes.\n\n```css\n.rounded-lg {\n  border-radius: var(--radius-lg);\n}\n```\n\nLooking at the default TailwindCSS configuration side-by-side with the default Vuetify classes generated from Sass, it is clear that those are not compatible and we will need some stitching.\n\n```css\n@theme {\n  --radius-xs: 0.125rem;\n  --radius-sm: 0.25rem;\n  --radius-md: 0.375rem;\n  --radius-lg: 0.5rem;\n  --radius-xl: 0.75rem;\n  --radius-2xl: 1rem;\n  --radius-3xl: 1.5rem;\n  --radius-4xl: 2rem;\n}\n\n/* default output from Vuetify, we disabled those with $utilities: false */\n.rounded-0 { border-radius: 0 }\n.rounded-sm { border-radius: 2px }\n.rounded { border-radius: 4px }\n.rounded-lg { border-radius: 8px }\n.rounded-xl { border-radius: 24px }\n.rounded-pill { border-radius: 9999px }\n.rounded-circle { border-radius: 50% }\n.rounded-shaped { border-radius: 24px 0 }\n```\n\nIn order to resolve this, we need to use `blocklist` and suppress certain utilities from TailwindCSS. Create a config file `tailwind.config.ts`:\n\n```ts { resource=\"tailwind.config.ts\" }\nimport type { Config } from 'tailwindcss'\n\nmodule.exports = {\n  blocklist: [\n    'rounded-xs',\n    'rounded-md',\n    'rounded-2xl',\n    'rounded-3xl',\n    'rounded-4xl',\n    'rounded-full',\n  ],\n} satisfies Config\n```\n\nThe new file has to be linked from `tailwind.css`. We also override the radius variables and register custom utilities for the values that don't exist in Tailwind out-of-the-box:\n\n```css { resource=\"src/styles/tailwind.css\" }\n@import \"tailwindcss/theme\" layer(theme);\n/* @import \"tailwindcss/preflight.css\" layer(reset); */\n@import \"tailwindcss/utilities\" layer(utilities);\n\n@config \"../../tailwind.config.ts\";\n\n@theme {\n  --radius-sm: 2px;\n  --radius-lg: 8px;\n  --radius-xl: 24px;\n}\n\n@utility rounded-0 { border-radius: 0 }\n@utility rounded-pill { border-radius: 9999px }\n@utility rounded-shaped { border-radius: 24px 0 }\n\n@source inline('rounded-0');\n@source inline('rounded-sm');\n@source inline('rounded'); /* leaving .25rem */\n@source inline('rounded-lg');\n@source inline('rounded-xl');\n@source inline('rounded-pill');\n@source inline('rounded-circle');\n@source inline('rounded-shaped');\n```\n\nIf you'd rather use the original TailwindCSS `rounded-*` utilities, it is recommended to disallow use of Vuetify's rounded classes, which can be enforced by patching `eslint-plugin-vuetify`. The actual process of patching is specific to the package manager of your choice, so we will skip it for now. If you are stuck, feel free to reach out on [Discord](https://community.vuetifyjs.com).\n\n---\n\n## Customize fonts\n\nThe `create-vuetify` utility we used at the beginning to scaffold the project uses `unplugin-fonts` to load Roboto. Let's update the configuration to make sure the target fonts are available.\n\n```ts { resource=\"vite.config.mts\" }\n    Fonts({\n      fontsource: {\n        families: [\n          {\n            name: 'Bricolage Grotesque',\n            weights: [300, 400, 500, 700],\n          },\n          {\n            name: 'Sen',\n            weights: [400, 500, 700],\n          },\n          {\n            name: 'Sometype Mono',\n            weights: [400, 700],\n          },\n        ],\n      },\n    }),\n```\n\nNext step is to add them as dependencies:\n\n::: tabs\n\n```bash [pnpm]\npnpm i @fontsource/bricolage-grotesque @fontsource/sen @fontsource/sometype-mono\n```\n\n```bash [yarn]\nyarn add @fontsource/bricolage-grotesque @fontsource/sen @fontsource/sometype-mono\n```\n\n```bash [npm]\nnpm i @fontsource/bricolage-grotesque @fontsource/sen @fontsource/sometype-mono\n```\n\n```bash [bun]\nbun add @fontsource/bricolage-grotesque @fontsource/sen @fontsource/sometype-mono\n```\n\n:::\n\nNow we can configure TailwindCSS theme variables. These will generate utility classes like `font-heading`, `font-body` and `font-mono`:\n\n```css { resource=\"src/styles/tailwind.css\" }\n@theme {\n  --font-heading: \"Bricolage Grotesque\", sans-serif;\n  --font-body: Sen, sans-serif;\n  --font-mono: \"Sometype Mono\", monospace;\n\n  /* ...breakpoints, radius, colors... */\n}\n\n/* ensure the variables are not skipped */\n@source inline('font-body');\n@source inline('font-heading');\n@source inline('font-mono');\n```\n\nThen we pass them to Vuetify through Sass variables so component typography picks them up too:\n\n```diff { resource=\"src/styles/settings.scss\" }\n@use 'vuetify/settings' with (\n  $color-pack: false,\n  $utilities: false,\n+  $heading-font-family: var(--font-heading),\n+  $body-font-family: var(--font-body),\n);\n```\n\nAt this point, I usually like to cover components that need a monospace font. We can also create `/styles/main.scss` to set it globally. It is not strictly necessary, but apps usually need some custom global styles anyway.\n\n```scss { resource=\"src/styles/main.scss\" }\n@layer vuetify-overrides {\n  code, pre, .v-code {\n    font-family: var(--font-mono);\n  }\n}\n```\n\nNew file has to be imported in `main.ts` alongside the Tailwind stylesheet.\n\n---\n\n## Avoid conflicting color utilities\n\n`bg-*` classes generated by Vuetify carry over a foreground color that is calculated to ensure text and icons have a sufficient contrast ratio. This makes them superior to regular TailwindCSS utilities, but also incompatible with variants (`hover:`, `sm:*`, `md:*`, etc).\n\n```css\n.bg-primary {\n  --v-theme-overlay-multiplier: var(--v-theme-primary-overlay-multiplier);\n  background-color: rgb(var(--v-theme-primary));\n  color: rgb(var(--v-theme-on-primary));\n}\n```\n\nWhen working with TailwindCSS, it is normal to split background and text colors into separate classes, and the responsibility of ensuring readability is on the developer writing the code.\n\nIn order to avoid the mental overhead of remembering where each `bg-*` is coming from, let's instruct Vuetify theme to generate only CSS variables and skip the classes:\n\n```diff { resource=\"src/plugins/vuetify.ts\" }\nexport default createVuetify({\n  theme: {\n    defaultTheme: 'system',\n+    utilities: false,\n  },\n})\n```\n\nNext, we can pass those theme colors to TailwindCSS. Since the values are raw comma-separated RGB channels (translated from hex on the fly by Vuetify), we need to wrap them in `rgb()` when registering them in Tailwind's `@theme`:\n\n```css { resource=\"src/styles/tailwind.css\" }\n@theme {\n  --color-background: rgb(var(--v-theme-background));\n  --color-primary: rgb(var(--v-theme-primary));\n  --color-surface: rgb(var(--v-theme-surface));\n  --color-success: rgb(var(--v-theme-success));\n  --color-error: rgb(var(--v-theme-error));\n  /* and the rest of colors you intend to use */\n}\n\n/* safelist common colors to be used with color=\"...\" attribute */\n@source inline('bg-primary');\n@source inline('text-primary');\n@source inline('bg-success');\n@source inline('text-success');\n@source inline('bg-error');\n@source inline('text-error');\n```\n\nNow you can use `bg-primary`, `text-success`, `hover:bg-error` and similar classes, all driven by Vuetify's theme definition.\n\n---\n\n## Configure class-based light/dark variants\n\nLet's add some color-dependent classes and try using the `dark:*` prefix to see what happens. By default, Tailwind's `dark:` variant targets `@media (prefers-color-scheme: dark)` or a `.dark` class. Vuetify uses `.v-theme--dark` instead, so the generated selectors won't match.\n\nTo align Tailwind with Vuetify, we need to redeclare theming variants:\n\n```css { resource=\"src/styles/tailwind.css\" }\n@custom-variant light (&:where(.v-theme--light, .v-theme--light *));\n@custom-variant dark (&:where(.v-theme--dark, .v-theme--dark *));\n```\n\nYou can verify it by toggling themes. Simply add a quick button somewhere (e.g. in `App.vue`):\n\n```html\n<v-btn\n  icon=\"mdi-theme-light-dark\"\n  position=\"absolute\"\n  location=\"top right\"\n  class=\"ma-2\"\n  @click=\"$vuetify.theme.cycle()\"\n/>\n```\n\nNow classes like `dark:bg-primary` and `light:text-error` should react correctly to Vuetify's theme toggle.\n\n---\n\n## Breakpoints\n\nDefault breakpoints provided by TailwindCSS are not compatible with Vuetify. This mismatch can lead to unexpected layout issues when `sm:` in Tailwind kicks in at a different width than `sm` in VCol. Let's align them.\n\nUnlike the UnoCSS setup from the previous article, where we could define breakpoints in a shared `.ts` file and feed them into both tools, TailwindCSS v4 expects breakpoints as pure CSS variables under `@theme`. This means we inevitably end up with the same values in three places. It's a minor inconvenience, but easy to manage with a comment pointing to the other two.\n\nFirst, clear out the Tailwind defaults and set our own in `tailwind.css`:\n\n```css { resource=\"src/styles/tailwind.css\" }\n@theme {\n  --breakpoint-*: initial;\n  /* repeated in vuetify.ts and settings.scss */\n  --breakpoint-xs: 0px;\n  --breakpoint-sm: 400px;\n  --breakpoint-md: 840px;\n  --breakpoint-lg: 1145px;\n  --breakpoint-xl: 1545px;\n  --breakpoint-xxl: 2138px;\n\n  /* ... fonts, radius, colors ... */\n}\n```\n\n`--breakpoint-*: initial` resets all built-in Tailwind breakpoints (`2xl`, `3xl`, etc.) so they don't interfere or confuse your teammates.\n\nNext, set Vuetify's `display.thresholds` in the plugin setup. This controls `useDisplay()` and `$vuetify.display.*`.\n\n```ts { resource=\"src/plugins/vuetify.ts\" }\nexport default createVuetify({\n  theme: { ... },\n  display: {\n    mobileBreakpoint: 'md',\n    thresholds: {\n      // repeated in tailwind.css and settings.scss\n      xs: 0,\n      sm: 400,\n      md: 840,\n      lg: 1145,\n      xl: 1545,\n      xxl: 2138,\n    },\n  },\n})\n```\n\nFinally, update the SCSS variables. `$grid-breakpoints` drives VCol's responsive columns, and `$container-max-widths` sets the maximum width of VContainer at each breakpoint.\n\n```scss { resource=\"src/styles/settings.scss\" }\n@use 'vuetify/settings' with (\n  $color-pack: false,\n  $utilities: false,\n  $heading-font-family: var(--font-heading),\n  $body-font-family: var(--font-body),\n  $grid-breakpoints: (\n    // repeated in tailwind.css and vuetify.ts\n    'xs': 0,\n    'sm': 400px,\n    'md': 840px,\n    'lg': 1145px,\n    'xl': 1545px,\n    'xxl': 2138px,\n  ),\n  $container-max-widths: (\n    // optional, computed from breakpoints\n    'md': 700px,\n    'lg': 1000px,\n    'xl': 1400px,\n    'xxl': 2000px,\n  ),\n);\n```\n\nThe `$container-max-widths` values are manually rounded to keep VContainer sizing clean and predictable.\n\nAt this point, a class like `sm:text-lg` in Tailwind and `sm=\"6\"` on VCol will both trigger at exactly `400px`.\n\n---\n\n## Summary\n\nCompared to the UnoCSS path, most of the setup lands in `tailwind.css` instead of `nuxt.config.ts`. We used custom directives like `@theme` and `@custom-variant`, but had to drop back to importing JS-based config to blacklist some styles provided by Tailwind. I hope it was an interesting journey and you can feel comfortable building upon this setup. Here are the key takeaways:\n\n* **Utilities**: we disabled Vuetify's built-in utilities to replace them with TailwindCSS utilities while keeping an eye on the correct order of CSS layers\n* **Rounded classes**: Vuetify's `rounded` prop and Tailwind's `rounded-*` utilities use the same class names with different values. It was a challenge, but we were able to bridge the gap\n* **Theme colors**: Vuetify theme can also be configured to skip utility classes and generate only CSS properties. We have passed them inside the `@theme` directive and \"safelisted\" global colors we intend to use with the `color` prop on cards, buttons and icons\n* **Dark mode**: Tailwind is flexible enough to accept Vuetify theme classes\n* **Typography**: `text-*` classes were skipped for simplicity - you can introduce your own classes with the `@utility` directive if needed\n* **Breakpoints**: we aligned configuration across three definitions (SCSS, Vuetify config, Tailwind `@theme`) to prevent layout bugs\n\nReference repository with final state: [J-Sek/vuetify-vite-and-tailwind](https://github.com/J-Sek/vuetify-vite-and-tailwind). If you find it useful, give it a ⭐.\n\nCheers!\n"
  },
  {
    "path": "packages/docs/src/pages/en/blog/december-2025-update.md",
    "content": "---\nlayout: blog\nmeta:\n  title: December 2025 Update\n  description: December delivered Vuetify 4.0.0-alpha.0 with CSS layers and theme improvements, five v3.11.x patch releases, the Vuetify CLI public release, PWA rollout across all ecosystem products, and significant Vuetify0 progress.\n  keywords: Vuetify December 2025, v4.0.0-alpha.0, Vuetify CLI, PWA, CSS layers, Vuetify0, MCP\n---\n\n<script setup>\n  import { useTheme } from 'vuetify'\n\n  const theme = useTheme()\n\n  const clilogo = computed(() => {\n    return `https://cdn.vuetifyjs.com/docs/images/one/logos/vcli-logo-${theme.current.value.dark ? 'dark' : 'light'}.png`\n  })\n  const mcplogo = computed(() => {\n    return `https://cdn.vuetifyjs.com/docs/images/one/logos/vmcp-logo-${theme.current.value.dark ? 'dark' : 'light'}.png`\n  })\n  const zerologo = computed(() => {\n    return `https://cdn.vuetifyjs.com/docs/images/one/logos/vzero-logo-${theme.current.value.dark ? 'dark' : 'light'}.png`\n  })\n  const vuetifylogo = computed(() => {\n    return `https://cdn.vuetifyjs.com/docs/images/one/logos/vuetify-logo-${theme.current.value.dark ? 'dark' : 'light'}.png`\n  })\n  const binlogo = computed(() => {\n    return `https://cdn.vuetifyjs.com/docs/images/one/logos/vbin-logo-${theme.current.value.dark ? 'dark' : 'light'}.png`\n  })\n  const playlogo = computed(() => {\n    return `https://cdn.vuetifyjs.com/docs/images/one/logos/vplay-logo-${theme.current.value.dark ? 'dark' : 'light'}.png`\n  })\n  const issueslogo = computed(() => {\n    return `https://cdn.vuetifyjs.com/docs/images/one/logos/vissues-logo-${theme.current.value.dark ? 'dark' : 'light'}.png`\n  })\n</script>\n\n# December 2025 Update\n\nWelcome to the December 2025 Vuetify update! The year closes with a bang—**v4.0.0-alpha.0** marks the beginning of Vuetify 4's public development, while five v3.11.x patch releases keep the stable branch polished. The **Vuetify CLI** shipped its first public release, PWA support rolled out across all ecosystem products, and Vuetify0 continued its rapid evolution with 6 releases.\n\n![Hero image for December update](https://cdn.vuetifyjs.com/docs/images/blog/december-2025-update/december-hero.png \"December hero image\"){ height=112 }\n\n🖊️ John Leider • 📅 January 12th, 2026\n\n<PromotedEntry />\n\n---\n\n## Closing the Year Strong\n\nDecember was our most productive month of 2025. With **522 commits** across 16 active repositories and **82 merged PRs**, the team shipped at an incredible pace. The release of v4.0.0-alpha.0 represents months of architectural planning finally landing for public testing—CSS layers, reduced breakpoints, and theme system improvements that set the stage for Vuetify 4.0 stable. Meanwhile, [J-Sek](https://github.com/J-Sek) continued his remarkable contribution streak with 16 PRs to the main framework, and [ikushum](https://github.com/ikushum) delivered 9 PRs across components. The CLI reached public release status just in time for the new year, and every ecosystem product now supports PWA installation.\n\n---\n\n## Table of Contents\n\n* [Releases](#releases)\n  * [Key Improvements](#key-improvements)\n* [Vuetify 4 Alpha](#vuetify-4-alpha)\n* [Ecosystem Spotlight: Vuetify CLI](#ecosystem-spotlight-vuetify-cli)\n  * [create-vuetify Updates](#create-vuetify-updates)\n* [Framework Updates](#framework-updates)\n  * [New Features](#new-features)\n  * [Accessibility & Compatibility](#accessibility-compatibility)\n* [Product Updates](#product-updates)\n  * [Vuetify Bin](#vuetify-bin)\n  * [Vuetify Play](#vuetify-play)\n  * [Vuetify Issues Reporter](#vuetify-issues-reporter)\n  * [Other Products](#other-products)\n* [Vuetify MCP: Rate Limiting & CLI Support](#vuetify-mcp-rate-limiting-cli-support)\n* [Vuetify0: Progress Update](#vuetify0-progress-update)\n* [December 2025 Changelog](#december-2025-changelog)\n* [What's Next](#whats-next)\n\n---\n\n## Releases\n\nDecember delivered six Vuetify releases—five v3.11.x patches maintaining stability and the landmark **v4.0.0-alpha.0** kicking off the next major version. The v3.x branch continues receiving attention with accessibility improvements, bug fixes, and new props across multiple components.\n\n![December Releases Banner](https://cdn.vuetifyjs.com/docs/images/blog/december-2025-update/releases.png \"December Releases Banner\")\n\n### Key Improvements\n\n* **[VWindow](/components/windows/)** keyboard controls for accessible navigation\n* **[VList](/components/lists/)** `navigation-strategy` prop to control focused item behavior\n* **[VImg](/components/images/)** attribute passthrough to underlying `<img>` element\n* **[VOtpInput](/components/otp-input/)** `density` prop for compact layouts\n* **[VColorInput](/components/color-input/)/[VDateInput](/components/date-input/)** `picker-props` for customizing picker appearance\n* **[VDataIterator](/components/data-iterators/)** `items-length` prop for virtual scrolling support\n* **[VDatePicker](/components/date-pickers/)** custom `control-height` support\n* **[nested](/components/treeview/)** `branch` select strategy for hierarchical selection\n\nView the complete list of changes in the [Full Changelog](#december-2025-changelog)\n\n**Details:**\n\n* [v3.11.2](https://vuetifyjs.com/getting-started/release-notes/?version=v3.11.2)\n* [v3.11.3](https://vuetifyjs.com/getting-started/release-notes/?version=v3.11.3)\n* [v3.11.4](https://vuetifyjs.com/getting-started/release-notes/?version=v3.11.4)\n* [v3.11.5](https://vuetifyjs.com/getting-started/release-notes/?version=v3.11.5)\n* [v3.11.6](https://vuetifyjs.com/getting-started/release-notes/?version=v3.11.6)\n* [v4.0.0-alpha.0](https://vuetifyjs.com/getting-started/release-notes/?version=v4.0.0-alpha.0)\n\n---\n\n## Vuetify 4 Alpha\n\nThe first alpha of **Vuetify 4.0** landed on December 30th, marking the start of public development for our next major version. This release contains significant architectural changes that improve performance, reduce bundle size, and modernize the CSS architecture.\n\n![Vuetify 4 Alpha](https://cdn.vuetifyjs.com/docs/images/blog/december-2025-update/v4-alpha.png \"Vuetify 4 Alpha\")\n\n### What's New in v4.0.0-alpha.0\n\n**CSS Layers**: Vuetify 4 uses CSS layers throughout, flattening layer names and replacing `!important` declarations with proper cascade management. This makes customization cleaner and reduces specificity conflicts.\n\n**Theme System**: The default theme changes from `light` to `system`, respecting user preferences. Transparent color support enables more sophisticated design patterns. The `unimportant` option has been removed in favor of layers.\n\n**Reduced Breakpoints**: Default breakpoint sizes have been adjusted for modern viewport distributions.\n\n**Style Architecture**:\n\n* Separate entry points allow opting out of misc styles\n* CSS reset has been streamlined (removed overflow-y)\n* [VRow](/api/v-row/)/[VCol](/api/v-col/) styles can be skipped when only using [VContainer](/api/v-container/) or [VSpacer](/api/v-spacer/)\n\n**Component Updates**:\n\n* **[VBtn](/components/buttons/)**: Default text transform removed, display converted from grid to flex\n* **[VField](/api/v-field/)**: Display converted from grid to flex, append/prepend fills height\n* **[VSnackbar](/components/snackbars/)**: `multi-line` prop removed in favor of CSS\n* **[VSelect](/components/selects/)/[VAutocomplete](/components/autocompletes/)/[VCombobox](/components/combobox/)**: `item` renamed to `internalItem` for clarity\n* **[VNumberInput](/components/number-inputs/)**: No longer clamps value on mount\n* **[VDatePicker](/components/date-pickers/)**: Only emits start and end range values\n* **[VForm](/components/forms/)**: Unref values in slot props\n* **[VInput](/api/v-input/)**: New `indent-details` prop\n* **[VListItem](/api/v-list-item/)**: Exposes `isDisabled` in slot props\n* **[VCounter](/api/v-counter/)**: Inherits color (aligns with [VMessages](/api/v-messages/))\n\n::: info\n\nv4.0.0-alpha.0 is for testing and feedback only. Production applications should continue using v3.11.x until v4 reaches stable release.\n\n:::\n\n**Details:**\n\n* [v4.0.0-alpha.0 Release Notes](https://vuetifyjs.com/getting-started/release-notes/?version=v4.0.0-alpha.0)\n* [Migration Guide](https://next.vuetifyjs.com/getting-started/upgrade-guide/)\n* [Remaining Issues](https://github.com/vuetifyjs/vuetify/milestone/62)\n\n---\n\n## Ecosystem Spotlight: Vuetify CLI\n\n<AppFigure :src=\"clilogo\" alt=\"Vuetify CLI Logo\" width=\"200\" height=\"auto\" class=\"mx-auto mt-4\" title=\"Vuetify CLI Logo\" />\n\n<br>\n\nThe **Vuetify CLI** reached its first public release in December with **25 commits** across versions v0.0.5 through v0.0.7. This new tooling ecosystem streamlines project scaffolding and integrates with the broader Vuetify ecosystem.\n\n![Vuetify CLI](https://cdn.vuetifyjs.com/docs/images/blog/december-2025-update/cli.png \"Vuetify CLI\")\n\n### CLI Ecosystem Overview\n\nThe Vuetify CLI ecosystem consists of three packages that share logic via `@vuetify/cli-shared`:\n\n**create-vuetify0** (`npm create vuetify0`) — Scaffolds new Vuetify0 projects with support for [Vue](https://vuejs.org/) or [Nuxt](https://nuxt.com/) platforms. Includes feature selection for router, pinia, and eslint. TypeScript by default.\n\n**@vuetify/cli** (`vuetify` command) — The main CLI with multiple commands:\n\n* `vuetify init` — Same as create-vuetify, scaffolds new projects (supports `--type vuetify0`)\n* `vuetify add eslint` — Adds ESLint + [eslint-config-vuetify](https://github.com/vuetifyjs/eslint-config-vuetify) to existing projects\n* `vuetify add mcp` — Adds [Vuetify MCP](https://github.com/vuetifyjs/mcp) server config for [Cursor](https://cursor.sh/)/[VS Code](https://code.visualstudio.com/)\n* `vuetify update` — Smart updates Vuetify + related packages\n* `vuetify docs` — Opens vuetifyjs.com (version-aware)\n* `vuetify upgrade` — Self-upgrades the CLI\n\n::: tabs\n\n```bash [pnpm]\n# Install the CLI globally\npnpm add -g @vuetify/cli\n\n# Initialize a new project\nvuetify init my-app\n\n# Or create a v0 project directly\npnpm create vuetify0@latest\n\n# Add ESLint to an existing project\nvuetify add eslint\n\n# Add MCP server configuration\nvuetify add mcp\n\n# Update Vuetify packages\nvuetify update\n```\n\n```bash [yarn]\n# Install the CLI globally\nyarn global add @vuetify/cli\n\n# Initialize a new project\nvuetify init my-app\n\n# Or create a v0 project directly\nyarn create vuetify0\n\n# Add ESLint to an existing project\nvuetify add eslint\n\n# Add MCP server configuration\nvuetify add mcp\n\n# Update Vuetify packages\nvuetify update\n```\n\n```bash [npm]\n# Install the CLI globally\nnpm install -g @vuetify/cli\n\n# Initialize a new project\nvuetify init my-app\n\n# Or create a v0 project directly\nnpm create vuetify0@latest\n\n# Add ESLint to an existing project\nvuetify add eslint\n\n# Add MCP server configuration\nvuetify add mcp\n\n# Update Vuetify packages\nvuetify update\n```\n\n```bash [bun]\n# Install the CLI globally\nbun add -g @vuetify/cli\n\n# Initialize a new project\nvuetify init my-app\n\n# Or create a v0 project directly\nbun create vuetify0\n\n# Add ESLint to an existing project\nvuetify add eslint\n\n# Add MCP server configuration\nvuetify add mcp\n\n# Update Vuetify packages\nvuetify update\n```\n\n:::\n\n### create-vuetify Updates\n\nThe **create-vuetify** scaffolding tool received **12 commits** and 4 releases in December:\n\n**v2.8.0-beta.1** (December 30th):\n\n* **Vuetify 4 Alpha Support**: Templates now support bootstrapping projects with Vuetify 4.0.0-alpha.0\n* **Dynamic Version Replacement**: Vuetify version is now dynamically replaced in templates, making it easier to stay current\n\n**v2.7.3** (December 20th):\n\n* **[Volar](https://volarjs.dev/) Rich Hover Hints**: Enabled by default for better IDE experience with component prop documentation\n\n**v2.7.1-v2.7.2** (December 16th):\n\n* **Nuxt Styles Fix**: Corrected styles loading when not using the Nuxt module\n* Various maintenance updates\n\n**Details:**\n\n* [Vuetify CLI GitHub Repository](https://github.com/vuetifyjs/cli)\n* [create-vuetify Releases](https://github.com/vuetifyjs/create-vuetify/releases)\n* [v2.8.0-beta.1 Release Notes](https://github.com/vuetifyjs/create-vuetify/releases/tag/v2.8.0-beta.1)\n\n---\n\n## Framework Updates\n\n<AppFigure :src=\"vuetifylogo\" alt=\"Vuetify logo\" width=\"200\" height=\"auto\" class=\"mx-auto mt-4\" title=\"Vuetify Logo\" />\n\n<br>\n\nDecember's framework work balanced new features with stability improvements. The team merged 49 PRs addressing everything from keyboard accessibility to field validation.\n\n### New Features\n\n**[VWindow](/components/windows/) Keyboard Controls**\n\nThe [VWindow](/components/windows/) component now supports keyboard navigation, enabling users to move between slides with arrow keys—essential for accessibility and power users.\n\n**[VList](/components/lists/) Navigation Strategy**\n\nA new `navigation-strategy` prop gives fine-grained control over which items receive focus during keyboard navigation. This is particularly useful for complex lists with nested content.\n\n**[VImg](/components/images/) Attribute Passthrough**\n\nAttributes passed to [VImg](/components/images/) now flow through to the underlying `<img>` element, enabling native image attributes like `loading=\"lazy\"` and custom data attributes.\n\n**[VOtpInput](/components/otp-input/) Density**\n\nThe [OTP input](/components/otp-input/) component now supports the `density` prop for compact layouts, and the `rounded` prop is properly applied to inner fields.\n\n**Details:**\n\n* [VWindow keyboard controls PR#22430](https://github.com/vuetifyjs/vuetify/pull/22430)\n* [VList navigation-strategy PR#22328](https://github.com/vuetifyjs/vuetify/pull/22328)\n* [VImg attribute passthrough PR#22439](https://github.com/vuetifyjs/vuetify/pull/22439)\n* [VOtpInput density PR#22401](https://github.com/vuetifyjs/vuetify/pull/22401)\n\n### Accessibility & Compatibility\n\n**Forced Colors Mode**\n\n[VColorPicker](/components/color-pickers/) now renders inner outlines correctly in Windows High Contrast Mode and other forced-colors environments, ensuring usability for users with visual impairments.\n\n**Screen Reader Improvements**\n\n[VTextArea](/components/textareas/) and [VSelect](/components/selects/) received accessibility improvements for better screen reader announcements, including proper ARIA attributes and field label reading.\n\n**[VSlider](/components/sliders/) ARIA Attributes**\n\nSlider components now correctly pass `aria-` attributes to the thumb element for assistive technology support.\n\n**[VTooltip](/components/tooltips/) Dismissable by Default**\n\nTooltips are now dismissable by default, improving keyboard accessibility and touch device support.\n\n**Fields ARIA Cleanup**\n\nAll field components received ARIA attribute cleanup for better screen reader compatibility.\n\n**Details:**\n\n* [VColorPicker forced-colors PR#22317](https://github.com/vuetifyjs/vuetify/pull/22317)\n* [VTextArea/VSelect screen reader PR#20339](https://github.com/vuetifyjs/vuetify/pull/20339)\n* [VSlider ARIA PR#22444](https://github.com/vuetifyjs/vuetify/pull/22444)\n* [VTooltip dismissable PR#22419](https://github.com/vuetifyjs/vuetify/pull/22419)\n* [Fields ARIA cleanup PR#22418](https://github.com/vuetifyjs/vuetify/pull/22418)\n\n---\n\n## Product Updates\n\nDecember saw significant updates across all Vuetify ecosystem products, with **PWA support** rolling out universally and major feature additions to [Bin](https://bin.vuetifyjs.com/) and [Play](https://play.vuetifyjs.com/).\n\n### Vuetify Bin\n\n<AppFigure :src=\"binlogo\" alt=\"Vuetify Bin logo\" width=\"200\" height=\"auto\" class=\"mx-auto mt-4\" title=\"Vuetify Bin Logo\" />\n\n<br>\n\n**41 commits** made December [Bin](https://bin.vuetifyjs.com/)'s most active month:\n\n* **Embeddable Bins**: New feature in testing for embedding bins in external documentation and blogs using [Shiki](https://shiki.style/) for lighter bundles. Available to Vuetify One subscribers.\n\n![Embeddable Bins](https://cdn.vuetifyjs.com/docs/images/blog/december-2025-update/embeddable-bins.png \"Bin embedded in documentation\")\n\n* **18 Language Support**: Expanded language support with auto-detection for pasted code\n* **Public/Private Visibility**: Users can now control bin visibility with proper 403 error pages for private bins\n* **Live Share Restrictions**: Limited to public bins with dashboard action\n* **Accessibility Audit**: Comprehensive a11y review completed\n* **PWA Support**: Install Bin as a standalone app\n* **Editor Improvements**: Line wrapping enabled by default, grouped secondary AppBar actions\n\n### Vuetify Play\n\n<AppFigure :src=\"playlogo\" alt=\"Vuetify Play logo\" width=\"200\" height=\"auto\" class=\"mx-auto mt-4\" title=\"Vuetify Play Logo\" />\n\n<br>\n\n**23 commits** delivered key improvements to [Play](https://play.vuetifyjs.com/):\n\n* **Multiple Templates**: Switch between project templates without losing work, with proper preservation of changes to system files\n\n![Play Template Switcher](https://cdn.vuetifyjs.com/docs/images/blog/december-2025-update/play-templates.png \"Template selection in Vuetify Play\")\n\n* **Editor Settings**: Customizable editor preferences\n* **Visibility Toggle**: Public/private playground support\n* **Version Selector**: Now includes prerelease versions for Vue and Vuetify\n* **v0 Template**: Updated to presetWind4\n* **PWA Support**: Install Play as a standalone app\n\n### Vuetify Issues\n\n<AppFigure :src=\"issueslogo\" alt=\"Vuetify Issues logo\" width=\"200\" height=\"auto\" class=\"mx-auto mt-4\" title=\"Vuetify Issues Logo\" />\n\n<br>\n\nThe **Vuetify Issues** reporter received **31 commits** with significant improvements to the issue creation workflow:\n\n![Issues Form](https://cdn.vuetifyjs.com/docs/images/blog/december-2025-update/vissues-form.png \"Improved issue creation form\")\n\n**Ecosystem Projects Support**:\n\n* Now supports non-library repositories (create-vuetify, admin, etc.)\n* Repo and type query parameters for direct linking\n* Project name displayed in title for ecosystem issues\n* Reproduction step hidden for ecosystem projects (not applicable)\n* Shows repo name instead of versions for ecosystem review\n\n**Form Validation Improvements**:\n\n* Required expected/actual behavior fields before save\n* Steps require content before adding new ones\n* New step auto-focus for better UX\n\n**Other Updates**:\n\n* **PWA Support**: Install as standalone app\n* **\"Used to work\" Switch**: Available for all repos, not just Vuetify\n* **New Favicon**: Fresh vissues branding\n* **UI Polish**: Fixed button spacing and v-confirm-edit actions\n\n**Details:**\n\n* [Vuetify Issues](https://issues.vuetifyjs.com/)\n\n### Other Products\n\n* **[Vuetify Snips](https://snips.vuetifyjs.com/)**: New button and pagination snippets in review, improved a11y for radio groups, PWA support added\n* **[Vuetify Studio](https://studio.vuetifyjs.com/)**: PWA support added, playground link generation updated\n* **[Vuetify Link](https://link.vuetifyjs.com/)**: Route handling refactored to use definePage, PWA support added\n\n**Details:**\n\n* [Vuetify Bin](https://bin.vuetifyjs.com/)\n* [Vuetify Play](https://play.vuetifyjs.com/)\n* [Vuetify Snips](https://snips.vuetifyjs.com/)\n* [Vuetify Issues](https://issues.vuetifyjs.com/)\n\n---\n\n## Vuetify MCP: Rate Limiting & CLI Support\n\n<AppFigure :src=\"mcplogo\" alt=\"Vuetify MCP logo\" width=\"200\" height=\"auto\" class=\"mx-auto mt-4\" title=\"Vuetify MCP Logo\" />\n\n<br>\n\nDecember brought four releases to the Vuetify MCP server (v0.2.4 through v0.4.1), adding important infrastructure improvements and new capabilities.\n\n### What's New\n\n**Rate Limiter**: The MCP server now includes rate limiting to ensure fair usage and stability across all consumers.\n\n**[Claude Code](https://docs.anthropic.com/en/docs/claude-code) CLI Support**: Native integration with Claude Code for seamless AI-assisted development workflows.\n\n**update_vuetify_bin Tool**: A new tool for updating existing Vuetify bins programmatically.\n\n**HTTP Transport Improvements**: Stateless mode improvements and auth propagation fixes.\n\n### Getting Started\n\n```json\n{\n  \"mcpServers\": {\n    \"vuetify\": {\n      \"url\": \"https://mcp.vuetifyjs.com/mcp\"\n    }\n  }\n}\n```\n\nOr run locally:\n\n```json\n{\n  \"mcpServers\": {\n    \"vuetify\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@vuetify/mcp\"]\n    }\n  }\n}\n```\n\n**Details:**\n\n* [Vuetify MCP GitHub Repository](https://github.com/vuetifyjs/mcp)\n* [Model Context Protocol Documentation](https://modelcontextprotocol.io/)\n\n---\n\n## Vuetify0: Progress Update\n\n<AppFigure :src=\"zerologo\" alt=\"Vuetify0 logo\" width=\"200\" height=\"auto\" class=\"mx-auto mt-4\" title=\"Vuetify0 Logo\" />\n\n<br>\n\nDecember was another strong month for Vuetify0, with **322 commits** and 6 releases (v0.0.15–v0.0.18, v0.0.20–v0.0.21). The headless meta-framework gained five new composables—including virtual scrolling and pagination primitives—along with accessibility improvements, observer enhancements, and significant documentation updates.\n\n![Vuetify0 Progress](https://cdn.vuetifyjs.com/docs/images/blog/december-2025-update/v0.png \"Vuetify0 Progress\")\n\nWith these additions, v0 now provides production-ready primitives for building accessible, high-performance UI components without the styling opinions of a traditional component library.\n\n### New Composables\n\nDecember added five composables covering pagination, virtualization, and UI utilities:\n\n**[usePagination](https://0.vuetifyjs.com/composables/utilities/use-pagination/)** — Full-featured pagination logic with first/prev/next/last navigation, ellipsis support for large page ranges, and computed `pageStart`/`pageStop` for efficient data slicing. Supports locale-aware formatting and customizable page sizes.\n\n**[useVirtual](https://0.vuetifyjs.com/composables/utilities/use-virtual/)** — High-performance virtual scrolling that renders only visible items plus an overscan buffer. Supports dynamic or fixed item heights, bidirectional scrolling (useful for chat interfaces), scroll anchoring to maintain position across data changes, and iOS momentum scrolling. Handles 100k+ items efficiently.\n\n**[useOverflow](https://0.vuetifyjs.com/composables/utilities/use-overflow/)** — Computes how many items fit in a container based on available width. Two modes: variable-width (measures each item individually, ideal for breadcrumbs) and uniform-width (samples one item, ideal for pagination buttons). Tracks container width via ResizeObserver and supports reserved space for navigation controls.\n\n**[useClickOutside](https://0.vuetifyjs.com/composables/system/use-click-outside/)** — Click outside detection for closing menus, dialogs, and popovers. Handles edge cases like portaled content and nested overlays.\n\n**[useToggleScope](https://0.vuetifyjs.com/composables/system/use-toggle-scope/)** — Manages Vue effect scopes based on a reactive boolean. Automatically cleans up effects when the condition becomes false—useful for conditional side effects and feature flags.\n\n### New Components\n\n**[PaginationStatus](https://0.vuetifyjs.com/components/semantic/pagination/)** — An accessibility-focused component that provides `aria-live` announcements when pagination state changes. Screen readers automatically announce the current page, helping users who rely on assistive technology stay oriented. Style it with `sr-only` CSS to keep it visually hidden while remaining accessible.\n\n### Observer Improvements\n\nAll three observer composables—[useResizeObserver](https://0.vuetifyjs.com/composables/system/use-resize-observer/), [useMutationObserver](https://0.vuetifyjs.com/composables/system/use-mutation-observer/), and [useIntersectionObserver](https://0.vuetifyjs.com/composables/system/use-intersection-observer/)—received enhancements:\n\n| Feature | Description |\n|---------|-------------|\n| `once` option | Automatically stops observing after first callback execution |\n| `isActive` return | Exposes whether the observer is currently monitoring |\n| Broader targets | [useIntersectionObserver](https://0.vuetifyjs.com/composables/system/use-intersection-observer/) accepts additional target types |\n\nThe `once` option is particularly useful for lazy-loading images or triggering one-time animations when elements enter the viewport.\n\n### Registry Enhancements\n\n[createRegistry](https://0.vuetifyjs.com/composables/registration/create-registry/) powers component coordination patterns like tabs, accordions, and steppers. December brought performance improvements for complex component trees:\n\n| Feature | Description |\n|---------|-------------|\n| `batch()` method | Bulk register/unregister operations in a single call, reducing reindexing overhead |\n| `ReadonlyMap` collection | Type changed from `Map` to `ReadonlyMap` to prevent accidental mutations |\n| Deferred reindexing | Unregister operations now batch index recalculations for better performance |\n\nThese changes particularly benefit applications with deeply nested or dynamically generated component hierarchies.\n\n### Documentation Updates\n\nThe [0.vuetifyjs.com](https://0.vuetifyjs.com/) documentation site received substantial improvements:\n\n**AI Q&A** — An intelligent search feature that answers questions about v0 composables, patterns, and usage. Ask natural language questions like \"How do I implement infinite scroll?\" and get contextual answers with code examples.\n\n![v0 AI Q&A](https://cdn.vuetifyjs.com/docs/images/blog/december-2025-update/v0-ai-qa.png \"AI-powered Q&A in Vuetify0 docs\")\n\n* **PWA support** — Install the documentation as a standalone app for offline access. Useful when working in environments with limited connectivity.\n* **Mobile improvements** — Redesigned navigation for smaller screens with proper iOS safe area support, making it easier to browse documentation on mobile devices.\n* **Code blocks** — Fence titles now display file paths above code examples, and syntax highlighting was improved across all supported languages.\n\n::: info\n\nThe v0 documentation at [0.vuetifyjs.com](https://0.vuetifyjs.com/) now includes AI-powered Q&A for finding information quickly.\n\n:::\n\n**Details:**\n\n* [Vuetify0 Documentation](https://0.vuetifyjs.com/)\n* [useVirtual](https://0.vuetifyjs.com/composables/use-virtual/)\n* [usePagination](https://0.vuetifyjs.com/composables/use-pagination/)\n* [useOverflow](https://0.vuetifyjs.com/composables/use-overflow/)\n* [useClickOutside](https://0.vuetifyjs.com/composables/use-click-outside/)\n* [v0.0.15](https://github.com/vuetifyjs/0/releases/tag/v0.0.15)–[v0.0.18](https://github.com/vuetifyjs/0/releases/tag/v0.0.18), [v0.0.20](https://github.com/vuetifyjs/0/releases/tag/v0.0.20)–[v0.0.21](https://github.com/vuetifyjs/0/releases/tag/v0.0.21)\n\n---\n\n## December 2025 Changelog\n\nThe following section provides an overview of the changes made in December 2025, including new features, bug fixes, and enhancements across the Vuetify framework.\n\n**Key Improvements:**\n\n* CSS layers architecture in v4 for cleaner customization\n* [VWindow](/components/windows/) keyboard controls for accessible slide navigation\n* [VList](/components/lists/) navigation-strategy prop for focus management\n* [VColorPicker](/components/color-pickers/) forced-colors mode compatibility\n* [VTreeview](/components/treeview/) selection state fixes with disabled items\n* [VSlider](/components/sliders/) ARIA attribute corrections\n* Strict TypeScript template support\n\n**Expand** this section to see the detailed changelog for December 2025:\n\n<details>\n\n### v3.11.2\n\n**:wrench: Bug Fixes**\n\n* **VDataTable:** hide checkbox for `mobile` without `show-select` ([d297f3f](https://github.com/vuetifyjs/vuetify/commit/d297f3f)), closes [#22375](https://github.com/vuetifyjs/vuetify/issues/22375)\n* **VDataTable:** hover icon should match `initial-sort-order` ([7a1ae83](https://github.com/vuetifyjs/vuetify/commit/7a1ae83))\n* **VDatePicker:** correctly render month when using Luxon adapter ([f98d9db](https://github.com/vuetifyjs/vuetify/commit/f98d9db)), closes [#22388](https://github.com/vuetifyjs/vuetify/issues/22388)\n* **VHotkey:** correct sass variables import order ([216b872](https://github.com/vuetifyjs/vuetify/commit/216b872)), closes [#22372](https://github.com/vuetifyjs/vuetify/issues/22372)\n* **VNumberInput:** avoid error state when using comma separator ([513e153](https://github.com/vuetifyjs/vuetify/commit/513e153)), closes [#22371](https://github.com/vuetifyjs/vuetify/issues/22371)\n* **VSlideGroup:** provide a way to never show arrows ([b76ffd5](https://github.com/vuetifyjs/vuetify/commit/b76ffd5))\n* **VTabs:** consistent padding for `inset` ([893eb71](https://github.com/vuetifyjs/vuetify/commit/893eb71))\n* **VTabs:** keep slider narrow when used without inset ([eb9477c](https://github.com/vuetifyjs/vuetify/commit/eb9477c)), closes [#22363](https://github.com/vuetifyjs/vuetify/issues/22363)\n* **VTextField:** check autofocus intersection on input wrapper element ([0409cde](https://github.com/vuetifyjs/vuetify/commit/0409cde)), closes [#22373](https://github.com/vuetifyjs/vuetify/issues/22373)\n\n**:test_tube: Labs**\n\n* **VStepperVertical:** avoid semi-transparent items with `non-linear` ([99a68e5](https://github.com/vuetifyjs/vuetify/commit/99a68e5)), closes [#22369](https://github.com/vuetifyjs/vuetify/issues/22369)\n\n---\n\n### v3.11.3\n\n**:wrench: Bug Fixes**\n\n* **fields:** clean up aria attributes ([#22418](https://github.com/vuetifyjs/vuetify/issues/22418)) ([054dbf4](https://github.com/vuetifyjs/vuetify/commit/054dbf4))\n* **types:** support strict TS checks in templates ([#22395](https://github.com/vuetifyjs/vuetify/issues/22395)) ([02710a6](https://github.com/vuetifyjs/vuetify/commit/02710a6))\n* **v-ripple:** remove mousedown and keydown listeners on unmount ([278a7e9](https://github.com/vuetifyjs/vuetify/commit/278a7e9))\n* **VAppBar:** prevent navbar pop-up when reaching page bottom ([#22224](https://github.com/vuetifyjs/vuetify/issues/22224)) ([8da1495](https://github.com/vuetifyjs/vuetify/commit/8da1495)), closes [#20352](https://github.com/vuetifyjs/vuetify/issues/20352)\n* **VAutocomplete, VCombobox:** skip subheader for `auto-select-first` ([#22402](https://github.com/vuetifyjs/vuetify/issues/22402)) ([9edd98c](https://github.com/vuetifyjs/vuetify/commit/9edd98c)), closes [#22398](https://github.com/vuetifyjs/vuetify/issues/22398)\n* **VBtn:** keep all styles within CSS layer ([c794da1](https://github.com/vuetifyjs/vuetify/commit/c794da1))\n* **VColorPicker:** render inner outlines in forced-colors mode ([#22317](https://github.com/vuetifyjs/vuetify/issues/22317)) ([c61c0d3](https://github.com/vuetifyjs/vuetify/commit/c61c0d3))\n* **VDataTable:** selecting group should respect selectable prop ([#22410](https://github.com/vuetifyjs/vuetify/issues/22410)) ([e295fa6](https://github.com/vuetifyjs/vuetify/commit/e295fa6)), closes [#22409](https://github.com/vuetifyjs/vuetify/issues/22409)\n* **VDataTable:** typo in header field `intent` » `indent` ([f44b2fd](https://github.com/vuetifyjs/vuetify/commit/f44b2fd))\n* **VDataTableFooter:** correct placement of aria label ([#22359](https://github.com/vuetifyjs/vuetify/issues/22359)) ([137cb95](https://github.com/vuetifyjs/vuetify/commit/137cb95)), closes [#20896](https://github.com/vuetifyjs/vuetify/issues/20896)\n* **VDatePicker:** correct year and month for jalali ([41067af](https://github.com/vuetifyjs/vuetify/commit/41067af)), closes [#22417](https://github.com/vuetifyjs/vuetify/issues/22417)\n* **VDatePicker:** correct next year button disabled condition ([04a4608](https://github.com/vuetifyjs/vuetify/commit/04a4608)), closes [#22408](https://github.com/vuetifyjs/vuetify/issues/22408)\n* **VHotkey:** avoid build errors when customizing VKbd sass variables ([fa1fb4f](https://github.com/vuetifyjs/vuetify/commit/fa1fb4f)), closes [#22372](https://github.com/vuetifyjs/vuetify/issues/22372)\n* **VInput:** prioritize slots over prepend/append icons ([#22406](https://github.com/vuetifyjs/vuetify/issues/22406)) ([2a998ee](https://github.com/vuetifyjs/vuetify/commit/2a998ee)), closes [#22332](https://github.com/vuetifyjs/vuetify/issues/22332)\n* **VNumberInput:** clean up listeners on unmount ([045bbaf](https://github.com/vuetifyjs/vuetify/commit/045bbaf))\n* **VOtpInput:** apply rounded prop to inner fields ([#21499](https://github.com/vuetifyjs/vuetify/issues/21499)) ([f49803a](https://github.com/vuetifyjs/vuetify/commit/f49803a)), closes [#20286](https://github.com/vuetifyjs/vuetify/issues/20286)\n* **VOverlay:** clean up focus trap listeners and data on unmount ([497ae4b](https://github.com/vuetifyjs/vuetify/commit/497ae4b)), closes [#22397](https://github.com/vuetifyjs/vuetify/issues/22397)\n* **VSelect:** don't skip continuing keyboard lookup match ([f1f3c45](https://github.com/vuetifyjs/vuetify/commit/f1f3c45)), closes [#22423](https://github.com/vuetifyjs/vuetify/issues/22423)\n* **VSelects:** no closable chips when `readonly` or `disabled` ([#22368](https://github.com/vuetifyjs/vuetify/issues/22368)) ([21c85eb](https://github.com/vuetifyjs/vuetify/commit/21c85eb)), closes [#22349](https://github.com/vuetifyjs/vuetify/issues/22349)\n* **VSlider:** clean up listeners on unmount ([f2621a3](https://github.com/vuetifyjs/vuetify/commit/f2621a3))\n* **VTextarea:** avoid placeholder obstructing the label ([27e854f](https://github.com/vuetifyjs/vuetify/commit/27e854f)), closes [#22416](https://github.com/vuetifyjs/vuetify/issues/22416)\n* **VTextArea/VSelects:** help screen readers read field labels ([#20339](https://github.com/vuetifyjs/vuetify/issues/20339)) ([04b6725](https://github.com/vuetifyjs/vuetify/commit/04b6725)), closes [#19155](https://github.com/vuetifyjs/vuetify/issues/19155) [#19156](https://github.com/vuetifyjs/vuetify/issues/19156)\n* **VTimePicker:** don't inherit defaults from VTextField ([3ffa749](https://github.com/vuetifyjs/vuetify/commit/3ffa749)), closes [#22407](https://github.com/vuetifyjs/vuetify/issues/22407)\n* **VTimePicker:** clean up listeners on unmount ([60183d7](https://github.com/vuetifyjs/vuetify/commit/60183d7))\n* **VTooltip:** should be dismissable by default ([#22419](https://github.com/vuetifyjs/vuetify/issues/22419)) ([c5ae129](https://github.com/vuetifyjs/vuetify/commit/c5ae129)), closes [#21501](https://github.com/vuetifyjs/vuetify/issues/21501)\n* **VVirtualScroll:** show more than 1 element when min height is 0 ([#22420](https://github.com/vuetifyjs/vuetify/issues/22420)) ([08550fd](https://github.com/vuetifyjs/vuetify/commit/08550fd))\n* **VWindow:** set transition-duration css variable ([4676b6d](https://github.com/vuetifyjs/vuetify/commit/4676b6d))\n\n**:test_tube: Labs**\n\n* **VVideo:** clean up listeners on unmount ([0d37af0](https://github.com/vuetifyjs/vuetify/commit/0d37af0))\n\n---\n\n### v3.11.4\n\n**:wrench: Bug Fixes**\n\n* **fields:** keep `inert` on root element ([8dea3bc](https://github.com/vuetifyjs/vuetify/commit/8dea3bc))\n* **VSelect:** clear on backspace ([#22435](https://github.com/vuetifyjs/vuetify/issues/22435)) ([f90f8ab](https://github.com/vuetifyjs/vuetify/commit/f90f8ab)), closes [#22422](https://github.com/vuetifyjs/vuetify/issues/22422)\n* **VSelects:** restore `appendInnerIcon` rendering ([#22431](https://github.com/vuetifyjs/vuetify/issues/22431)) ([5e9fa29](https://github.com/vuetifyjs/vuetify/commit/5e9fa29)), closes [#22429](https://github.com/vuetifyjs/vuetify/issues/22429)\n* **VSlider:** pass `aria-` attributes to thumb element ([#22444](https://github.com/vuetifyjs/vuetify/issues/22444)) ([83b55f5](https://github.com/vuetifyjs/vuetify/commit/83b55f5)), closes [#22432](https://github.com/vuetifyjs/vuetify/issues/22432)\n\n**:microscope: Code Refactoring**\n\n* **styles:** replace `if()` with `@if` ([5391930](https://github.com/vuetifyjs/vuetify/commit/5391930)), closes [#22421](https://github.com/vuetifyjs/vuetify/issues/22421)\n\n**:test_tube: Labs**\n\n* **VColorInput, VDateInput:** add `picker-props` ([#22437](https://github.com/vuetifyjs/vuetify/issues/22437)) ([ea6d861](https://github.com/vuetifyjs/vuetify/commit/ea6d861)), closes [#22436](https://github.com/vuetifyjs/vuetify/issues/22436)\n* **VDateInput,VMaskInput:** add specific classes ([#22447](https://github.com/vuetifyjs/vuetify/issues/22447)) ([f539630](https://github.com/vuetifyjs/vuetify/commit/f539630)), closes [#22334](https://github.com/vuetifyjs/vuetify/issues/22334)\n* **VDateInput:** make `prepend-icon` unfocusable ([#22445](https://github.com/vuetifyjs/vuetify/issues/22445)) ([c917533](https://github.com/vuetifyjs/vuetify/commit/c917533)), closes [#22333](https://github.com/vuetifyjs/vuetify/issues/22333)\n\n---\n\n### v3.11.5\n\n**:wrench: Bug Fixes**\n\n* **VDataTableVirtual:** show index from virtualized items ([#22324](https://github.com/vuetifyjs/vuetify/issues/22324)) ([29e3f09](https://github.com/vuetifyjs/vuetify/commit/29e3f09)), closes [#19108](https://github.com/vuetifyjs/vuetify/issues/19108)\n* **VList, VTreeview:** item should be selectable when `disabled` changes ([#22464](https://github.com/vuetifyjs/vuetify/issues/22464)) ([d6ca166](https://github.com/vuetifyjs/vuetify/commit/d6ca166)), closes [#22366](https://github.com/vuetifyjs/vuetify/issues/22366)\n* **VNumberInput:** respect `error` prop ([69862ea](https://github.com/vuetifyjs/vuetify/commit/69862ea)), closes [#22451](https://github.com/vuetifyjs/vuetify/issues/22451)\n* **VOtpInput:** hide placeholder on focus ([0852c8c](https://github.com/vuetifyjs/vuetify/commit/0852c8c))\n* **VTreeview:** bypass disabled when loading selection state ([#22465](https://github.com/vuetifyjs/vuetify/issues/22465)) ([70dd313](https://github.com/vuetifyjs/vuetify/commit/70dd313)), closes [#22353](https://github.com/vuetifyjs/vuetify/issues/22353)\n* **VTreeview:** prevent selection of disabled nodes ([0de4599](https://github.com/vuetifyjs/vuetify/commit/0de4599)), closes [#22352](https://github.com/vuetifyjs/vuetify/issues/22352)\n\n**:test_tube: Labs**\n\n* **VDateInput:** keep focus on input when opened with year view ([b58e361](https://github.com/vuetifyjs/vuetify/commit/b58e361)), closes [#22323](https://github.com/vuetifyjs/vuetify/issues/22323)\n* **VDateInput:** hide empty prepend slot ([28fe71e](https://github.com/vuetifyjs/vuetify/commit/28fe71e)), closes [#22456](https://github.com/vuetifyjs/vuetify/issues/22456)\n* **VDateInput:** clickable prepend icon when handler exists ([776a462](https://github.com/vuetifyjs/vuetify/commit/776a462))\n* **VStepperVertical:** restore default opacity of item title ([f30a081](https://github.com/vuetifyjs/vuetify/commit/f30a081)), closes [#22467](https://github.com/vuetifyjs/vuetify/issues/22467)\n\n---\n\n### v3.11.6\n\n**:wrench: Bug Fixes**\n\n* **VCalendar:** wrap unclamped timeToY ([3b4b5e6](https://github.com/vuetifyjs/vuetify/commit/3b4b5e6)), closes [#22413](https://github.com/vuetifyjs/vuetify/issues/22413)\n* **VCalendar:** extend start of event on following day ([4f7cc6a](https://github.com/vuetifyjs/vuetify/commit/4f7cc6a)), closes [#22480](https://github.com/vuetifyjs/vuetify/issues/22480)\n* **VColorPicker:** disable swatches ([#22472](https://github.com/vuetifyjs/vuetify/issues/22472)) ([8dbacad](https://github.com/vuetifyjs/vuetify/commit/8dbacad)), closes [#22471](https://github.com/vuetifyjs/vuetify/issues/22471)\n* **VDatePicker:** accept custom `control-height` ([#22479](https://github.com/vuetifyjs/vuetify/issues/22479)) ([b47a4ce](https://github.com/vuetifyjs/vuetify/commit/b47a4ce)), closes [#22478](https://github.com/vuetifyjs/vuetify/issues/22478)\n\n---\n\n### v4.0.0-alpha.0\n\n**:rocket: Features**\n\n* **display:** reduce default breakpoint sizes ([#19759](https://github.com/vuetifyjs/vuetify/issues/19759)) ([853ce33](https://github.com/vuetifyjs/vuetify/commit/853ce33))\n* **nested:** add branch select strategy ([4fcb72c](https://github.com/vuetifyjs/vuetify/commit/4fcb72c)), closes [#22404](https://github.com/vuetifyjs/vuetify/issues/22404)\n* **styles:** always use css layers ([f7123c6](https://github.com/vuetifyjs/vuetify/commit/f7123c6)), closes [#3400](https://github.com/vuetifyjs/vuetify/issues/3400) [#20232](https://github.com/vuetifyjs/vuetify/issues/20232)\n* **styles:** flatten layer names ([#22460](https://github.com/vuetifyjs/vuetify/issues/22460)) ([47bc400](https://github.com/vuetifyjs/vuetify/commit/47bc400)), closes [#22443](https://github.com/vuetifyjs/vuetify/issues/22443)\n* **styles:** possibility to opt-out from misc styles ([#22405](https://github.com/vuetifyjs/vuetify/issues/22405)) ([77d02f3](https://github.com/vuetifyjs/vuetify/commit/77d02f3))\n* **styles:** add separate entry points ([#22396](https://github.com/vuetifyjs/vuetify/issues/22396)) ([f00902c](https://github.com/vuetifyjs/vuetify/commit/f00902c)), closes [#20100](https://github.com/vuetifyjs/vuetify/issues/20100)\n* **styles:** cut down CSS reset ([#20960](https://github.com/vuetifyjs/vuetify/issues/20960)) ([ae3e8c9](https://github.com/vuetifyjs/vuetify/commit/ae3e8c9)), closes [#17633](https://github.com/vuetifyjs/vuetify/issues/17633)\n* **styles:** remove overflow-y from reset ([27868d5](https://github.com/vuetifyjs/vuetify/commit/27868d5)), closes [#1197](https://github.com/vuetifyjs/vuetify/issues/1197)\n* **theme:** change default theme to 'system' ([9c8506c](https://github.com/vuetifyjs/vuetify/commit/9c8506c))\n* **theme:** support transparent colors ([bb49662](https://github.com/vuetifyjs/vuetify/commit/bb49662)), closes [#10299](https://github.com/vuetifyjs/vuetify/issues/10299)\n* **theme:** remove unimportant option ([e8845ff](https://github.com/vuetifyjs/vuetify/commit/e8845ff))\n* **VDataIterator:** add `items-length` prop ([#22360](https://github.com/vuetifyjs/vuetify/issues/22360)) ([290836c](https://github.com/vuetifyjs/vuetify/commit/290836c)), closes [#19486](https://github.com/vuetifyjs/vuetify/issues/19486)\n* **VDatePicker:** only emit start and end range values ([#20621](https://github.com/vuetifyjs/vuetify/issues/20621)) ([eef80ad](https://github.com/vuetifyjs/vuetify/commit/eef80ad)), closes [#9098](https://github.com/vuetifyjs/vuetify/issues/9098) [#18701](https://github.com/vuetifyjs/vuetify/issues/18701) [#20599](https://github.com/vuetifyjs/vuetify/issues/20599)\n* **VForm:** unref values in slot props ([f92ae7a](https://github.com/vuetifyjs/vuetify/commit/f92ae7a)), closes [#18355](https://github.com/vuetifyjs/vuetify/issues/18355)\n* **VImg:** pass attributes to the underlying `<img>` ([#22439](https://github.com/vuetifyjs/vuetify/issues/22439)) ([71e01aa](https://github.com/vuetifyjs/vuetify/commit/71e01aa)), closes [#18860](https://github.com/vuetifyjs/vuetify/issues/18860) [#18907](https://github.com/vuetifyjs/vuetify/issues/18907)\n* **VInput:** add `indent-details` prop ([#21265](https://github.com/vuetifyjs/vuetify/issues/21265)) ([f483092](https://github.com/vuetifyjs/vuetify/commit/f483092)), closes [#16679](https://github.com/vuetifyjs/vuetify/issues/16679)\n* **VList:** add `navigation-strategy` to control focused item ([#22328](https://github.com/vuetifyjs/vuetify/issues/22328)) ([3815eee](https://github.com/vuetifyjs/vuetify/commit/3815eee))\n* **VListItem:** expose `isDisabled` in slot props ([9d92638](https://github.com/vuetifyjs/vuetify/commit/9d92638))\n* **VNumberInput:** do not clamp value on mounted ([#21826](https://github.com/vuetifyjs/vuetify/issues/21826)) ([4b4bfa5](https://github.com/vuetifyjs/vuetify/commit/4b4bfa5))\n* **VOtpInput:** add `density` prop ([#22401](https://github.com/vuetifyjs/vuetify/issues/22401)) ([aca7d30](https://github.com/vuetifyjs/vuetify/commit/aca7d30))\n* **VSelect/Autocomplete/Combobox:** rename item to internalItem ([2c1ac25](https://github.com/vuetifyjs/vuetify/commit/2c1ac25)), closes [#18354](https://github.com/vuetifyjs/vuetify/issues/18354)\n* **VSnackbar:** remove `multi-line` prop ([#22212](https://github.com/vuetifyjs/vuetify/issues/22212)) ([1371aba](https://github.com/vuetifyjs/vuetify/commit/1371aba)), closes [#15996](https://github.com/vuetifyjs/vuetify/issues/15996)\n* **VWindow:** add support for keyboard controls ([#22430](https://github.com/vuetifyjs/vuetify/issues/22430)) ([ab5b671](https://github.com/vuetifyjs/vuetify/commit/ab5b671)), closes [#11544](https://github.com/vuetifyjs/vuetify/issues/11544)\n\n**:wrench: Bug Fixes**\n\n* **styles:** skip VRow/VCol styles when using only VContainer or VSpacer ([f899803](https://github.com/vuetifyjs/vuetify/commit/f899803))\n* **theme:** re-merge default variables when themes is set ([a14c763](https://github.com/vuetifyjs/vuetify/commit/a14c763))\n* **theme:** helpers should override theme base ([2690877](https://github.com/vuetifyjs/vuetify/commit/2690877))\n* **theme:** override automatic text color with classes ([#22475](https://github.com/vuetifyjs/vuetify/issues/22475)) ([59b11d5](https://github.com/vuetifyjs/vuetify/commit/59b11d5))\n* **theme:** .text- classes always override color from .bg- ([7edf33a](https://github.com/vuetifyjs/vuetify/commit/7edf33a)), closes [#21787](https://github.com/vuetifyjs/vuetify/issues/21787)\n* **VContainer:** drop dependency on utility class ([47ca5c8](https://github.com/vuetifyjs/vuetify/commit/47ca5c8))\n* **VCounter:** inherit color (aligns with VMessages) ([#22424](https://github.com/vuetifyjs/vuetify/issues/22424)) ([ecd07b9](https://github.com/vuetifyjs/vuetify/commit/ecd07b9))\n* **VField:** append/prepend should fill height ([add5d2d](https://github.com/vuetifyjs/vuetify/commit/add5d2d))\n* **VOverlay:** apply scrollbar offset to body and VNavigationDrawer ([ec926d7](https://github.com/vuetifyjs/vuetify/commit/ec926d7))\n\n**:microscope: Code Refactoring**\n\n* **styles:** replace !important with layers ([7484c81](https://github.com/vuetifyjs/vuetify/commit/7484c81))\n* **VBtn:** remove default text transform ([#21079](https://github.com/vuetifyjs/vuetify/issues/21079)) ([712bdd6](https://github.com/vuetifyjs/vuetify/commit/712bdd6))\n* **VBtn:** convert display from grid to flex ([41b7768](https://github.com/vuetifyjs/vuetify/commit/41b7768))\n* **VField:** convert display from grid to flex ([#21035](https://github.com/vuetifyjs/vuetify/issues/21035)) ([b213e3b](https://github.com/vuetifyjs/vuetify/commit/b213e3b))\n\n</details>\n\n## What's Next{ .mt-4 }\n\nJanuary kicks off with continued development on Vuetify 4, incorporating feedback from the alpha release. We're targeting additional alpha releases throughout Q1 2026 as we refine the CSS layers architecture and modernize remaining components.\n\nThe v3.11.x branch will continue receiving maintenance releases with bug fixes and minor improvements. VCommandPalette is nearing [labs](/labs/introduction/) release, and we're expanding [v0](https://0.vuetifyjs.com/) with additional headless primitives for forms and data display.\n\nThe [CLI](https://github.com/vuetifyjs/cli) will gain additional commands for component generation and project management, while the [MCP server](https://github.com/vuetifyjs/mcp) continues to evolve with new tools for AI-assisted development.\n\nThank you for being part of the Vuetify community. Here's to an incredible 2026!\n\n---\n\n*Stay connected with Vuetify updates through our [GitHub repository](https://github.com/vuetifyjs/vuetify), [Discord community](https://discord.gg/vuetify), and follow [@vuetifyjs](https://twitter.com/vuetifyjs) for the latest announcements. The best is yet to come!*\n"
  },
  {
    "path": "packages/docs/src/pages/en/blog/february-2026-update.md",
    "content": "---\nlayout: blog\nmeta:\n  title: February 2026 Update\n  description: February marks Vuetify's most significant milestone—the stable release of Vuetify 4.0.0 with CSS layers, MD3 design system, and unstyled component foundations. The CLI hits v1.0.0, VAvatarGroup ships, and Vuetify0 gains createDataTable and Breadcrumbs composables.\n  keywords: Vuetify February 2026, Vuetify 4.0.0 Revisionist, v4 stable, VAvatarGroup, CLI v1.0.0, Vuetify0, createDataTable\n---\n\n<script setup>\n  import { computed } from 'vue'\n  import { useTheme } from 'vuetify'\n\n  const theme = useTheme()\n\n  const clilogo = computed(() => {\n    return `https://cdn.vuetifyjs.com/docs/images/one/logos/vcli-logo-${theme.current.value.dark ? 'dark' : 'light'}.png`\n  })\n  const mcplogo = computed(() => {\n    return `https://cdn.vuetifyjs.com/docs/images/one/logos/vmcp-logo-${theme.current.value.dark ? 'dark' : 'light'}.png`\n  })\n  const zerologo = computed(() => {\n    return `https://cdn.vuetifyjs.com/docs/images/one/logos/vzero-logo-${theme.current.value.dark ? 'dark' : 'light'}.png`\n  })\n  const vuetifylogo = computed(() => {\n    return `https://cdn.vuetifyjs.com/docs/images/one/logos/vuetify-logo-${theme.current.value.dark ? 'dark' : 'light'}.png`\n  })\n</script>\n\n# February 2026 Update\n\n**Vuetify 4 is here.** After four beta releases and months of community testing, **v4.0.0 (Revisionist)** shipped on February 23rd—bringing CSS layers, MD3 typography and elevation, and the architectural foundation for unstyled components. The **Vuetify CLI** also reached its **v1.0.0** milestone, and Vuetify0 continues building its headless composable layer with createDataTable, createNested, and Breadcrumbs.\n\n![Hero image for February update](https://cdn.vuetifyjs.com/docs/images/blog/february-2026-update/february-hero.png \"February hero image\"){ height=112 }\n\n🖊️ John Leider • 📅 March 9th, 2026\n\n<PromotedEntry />\n\n---\n\n## The big one\n\nThis is the release we've been building toward since the [2024 State of the Union](https://vuetifyjs.com/blog/state-of-the-union-2024/). **390 commits** across 15 active repositories, **68 merged PRs**, and 21 releases across the ecosystem—all driven by a month laser-focused on getting v4 stable. [J-Sek](https://github.com/J-Sek) delivered another prolific month with 20+ merged framework PRs including VAvatarGroup and new transitions, while [Andrei Elkin](https://github.com/AndreyYolkin) drove the [CLI](https://github.com/vuetifyjs/cli) to its first stable release with the Tailwind preset and project scaffolding presets.\n\n---\n\n## Table of Contents\n\n* [Releases](#releases)\n  * [Key Improvements](#key-improvements)\n* [Vuetify 4.0.0 Stable](#vuetify-400-stable)\n* [Framework Updates](#framework-updates)\n  * [New Features](#new-features)\n  * [Bug Fixes](#bug-fixes)\n  * [In Development](#in-development)\n* [Ecosystem Spotlight: Vuetify CLI v1.0.0](#ecosystem-spotlight-vuetify-cli-v100)\n* [Vuetify MCP: V4 Migration & Developer Tools](#vuetify-mcp-v4-migration--developer-tools)\n* [Product Updates](#product-updates)\n* [Vuetify0: Progress Update](#vuetify0-progress-update)\n* [February 2026 Changelog](#february-2026-changelog)\n* [What's Next](#whats-next)\n\n---\n\n## Releases\n\nFebruary was Vuetify's biggest release month ever. Four v4 betas culminated in the **stable v4.0.0 (Revisionist) release**, while v3.11.9, v3.12.0, and v3.12.1 maintained the v3 line. The CLI shipped nine releases reaching v1.0.0, Vuetify0 released v0.1.3, and the UnoCSS preset hit v0.2.0.\n\n![February Releases Banner](https://cdn.vuetifyjs.com/docs/images/blog/february-2026-update/releases.png \"February Releases Banner\")\n\n### Key Improvements\n\n* **[Vuetify 4.0.0](https://vuetifyjs.com/getting-started/release-notes/?version=v4.0.0)** stable release with CSS layers, MD3 design system, and unstyled foundations\n* **[VAvatarGroup](https://vuetifyjs.com/components/avatar-groups/)** new component for stacked avatar displays\n* **[VSelect/VAutocomplete/VCombobox](https://vuetifyjs.com/components/selects/)** `menu-header` and `menu-footer` slots\n* **[VSnackbarQueue](https://vuetifyjs.com/components/snackbar-queue/)** show multiple snackbars simultaneously\n* **[v-expand-both-transition](https://vuetifyjs.com/styles/transitions/)** new bidirectional expand transition\n* **[mdi-unocss](https://vuetifyjs.com/features/icon-fonts/)** icon set for UnoCSS integration\n\nView the complete list of changes in the [Full Changelog](#february-2026-changelog).\n\n**Details:**\n\n* [v4.0.0](https://vuetifyjs.com/getting-started/release-notes/?version=v4.0.0)\n* [v3.12.0](https://vuetifyjs.com/getting-started/release-notes/?version=v3.12.0)\n* [v3.12.1](https://vuetifyjs.com/getting-started/release-notes/?version=v3.12.1)\n* [v3.11.9](https://vuetifyjs.com/getting-started/release-notes/?version=v3.11.9)\n\n---\n\n## Vuetify 4.0.0 Stable\n\nThe stable release of **Vuetify 4.0.0 (Revisionist)** landed on February 23rd after four beta releases (beta.0 through beta.3). This is a pivotal release for the Vuetify ecosystem—not just for the features it ships, but for the architecture it establishes.\n\n<!-- MEDIA TODO: v4-launch.png\n  Ideas:\n  - Full-width announcement banner — \"Vuetify 4\" in large type with the key pillars underneath: CSS Layers / MD3 / Unstyled\n  - Side-by-side code comparison: v3 styles being overridden with !important vs v4 clean @layer override — the \"why it matters\" shot\n  - Browser DevTools screenshot showing the clean @layer stack (vuetify-base, vuetify-components, utilities) — proves the CSS layers story is real\n  - Stylized diagram showing Vuetify 4 architecture: layers cake with MD3 at the base, components in the middle, user overrides on top\n-->\n![Vuetify 4 Launch](https://cdn.vuetifyjs.com/docs/images/blog/february-2026-update/v4-launch.png \"Vuetify 4.0.0 Stable Release\")\n\n### What's in v4\n\n* **CSS Layers** — Vuetify's styles are now organized in CSS `@layer` blocks, making it trivial to override styles and coexist with utility frameworks like TailwindCSS and UnoCSS\n* **MD3 Typography & Elevation** — Full Material Design 3 type scale and shadow system\n* **Grid System Overhaul** — Modernized responsive grid with improved flexbox, RTL support, and cleaner CSS output\n* **Unstyled Foundations** — The internal architecture that makes true unstyled components possible in future releases\n\n### Migration\n\nThe upgrade path from v3 to v4 is intentionally minimal. The [upgrade guide](https://vuetifyjs.com/getting-started/upgrade-guide/) covers the handful of breaking changes, and the [Vuetify MCP server](#vuetify-mcp-v4-migration--developer-tools) provides AI-assisted migration tooling.\n\nEvery breaking change in v4 can be reverted with a drop-in snippet — upgrade now, migrate visuals at your own pace:\n\n* **[Grid System](https://vuetifyjs.com/getting-started/grid-legacy-mode/)** — CSS snippet restores v3 negative-margin grid behavior using `@layer vuetify-overrides`\n* **[Typography](https://vuetifyjs.com/getting-started/typography-migration/)** — Sass config restores full MD2 type scale with component-specific variable mappings\n* **[Elevation](https://vuetifyjs.com/getting-started/elevation-migration/)** — CSS file restores all 25 MD2 elevation levels (v4 ships MD3's 6-level system)\n* **[CSS Reset](https://vuetifyjs.com/getting-started/upgrade-guide/)** — Minimal or full reset snippets using `@layer vuetify-core.reset`\n* **[Breakpoints](https://vuetifyjs.com/getting-started/upgrade-guide/)** — JS or Sass config to restore v3 thresholds (960/1280/1920/2560)\n* **[Button text-transform](https://vuetifyjs.com/getting-started/upgrade-guide/)** — Sass variable, global default, or utility class to restore uppercase\n\nThe [vuetify-codemods](https://www.npmjs.com/package/vuetify-codemods) package automates class and attribute renames.\n\n::: tip\n\nUse the Vuetify MCP server to analyze your project: *\"Scan my project for Vuetify 3 patterns that need updating for v4.\"*\n\n:::\n\nAcross the ecosystem, v4 adoption started immediately—[Vuetify One](https://one.vuetifyjs.com/) upgraded to v4 the same week, and the CLI updated all project templates.\n\n**Details:**\n\n* [v4.0.0 Release Notes](https://vuetifyjs.com/getting-started/release-notes/?version=v4.0.0)\n* [Upgrade Guide](https://vuetifyjs.com/getting-started/upgrade-guide/)\n* [Vuetify 3 Documentation](https://v3.vuetifyjs.com/)\n* [Building with Vite and TailwindCSS](https://vuetifyjs.com/blog/building-with-vite-and-tailwindcss/)\n\n---\n\n## Framework Updates\n\n<AppFigure :src=\"vuetifylogo\" alt=\"Vuetify logo\" width=\"200\" height=\"auto\" class=\"mx-auto mt-4\" title=\"Vuetify Logo\" />\n\n<br>\n\nFebruary's 39 merged PRs delivered new components, significant feature additions, and targeted bug fixes across both the v3 and v4 branches.\n\n### New Features\n\n**[VAvatarGroup](https://vuetifyjs.com/components/avatar-groups/)**\n\nA new component for displaying stacked avatar collections with overlap, max count, and a \"+N\" indicator for overflow. Pairs with the new `badge` prop on VAvatar for status indicators.\n\n<!-- MEDIA TODO: avatar-group.png\n  Ideas:\n  - Live screenshot from the docs playground showing 5-6 avatars overlapping with the \"+3\" overflow chip\n  - Show two variants side-by-side: one with photo avatars, one with icon/initial avatars — demonstrates flexibility\n  - Include the VAvatar badge prop in the shot — a couple avatars with green \"online\" dots to show both features at once\n  - Dark and light theme split if possible — the component looks good on both\n-->\n![VAvatarGroup](https://cdn.vuetifyjs.com/docs/images/blog/february-2026-update/avatar-group.png \"VAvatarGroup Component\")\n\n**[VSnackbarQueue](https://vuetifyjs.com/components/snackbar-queue/)** — Show multiple snackbars simultaneously instead of replacing one at a time ([#22605](https://github.com/vuetifyjs/vuetify/pull/22605))\n\n**[VToolbar](https://vuetifyjs.com/components/toolbars/)** — New `location` prop for bottom-positioned toolbars ([#22608](https://github.com/vuetifyjs/vuetify/pull/22608))\n\n**[VImg](https://vuetifyjs.com/components/images/)** — `image-class` prop for styling the inner `<img>` element, plus `width=\"fit-content\"` support ([#22622](https://github.com/vuetifyjs/vuetify/pull/22622), [#21414](https://github.com/vuetifyjs/vuetify/pull/21414))\n\n**[VDataTable](https://vuetifyjs.com/components/data-tables/)** — `page-by` prop for page size control ([#22580](https://github.com/vuetifyjs/vuetify/pull/22580))\n\n**[VSelect/VAutocomplete/VCombobox](https://vuetifyjs.com/components/selects/)** — `menu-header` and `menu-footer` slots for custom dropdown content ([#22414](https://github.com/vuetifyjs/vuetify/pull/22414))\n\n**[VSlider](https://vuetifyjs.com/components/sliders/)** — Show thumb value on hover ([#22412](https://github.com/vuetifyjs/vuetify/pull/22412))\n\n**[VOtpInput](https://vuetifyjs.com/components/otp-input/)** — `masked` prop to hide or show entered text ([#20950](https://github.com/vuetifyjs/vuetify/pull/20950))\n\n**[VProgressCircular](https://vuetifyjs.com/components/progress-circular/)** — `reveal` prop for animated entry ([#22502](https://github.com/vuetifyjs/vuetify/pull/22502))\n\n**[VRow](https://vuetifyjs.com/api/v-row/)** — Smaller density steps for finer layout control ([#22574](https://github.com/vuetifyjs/vuetify/pull/22574))\n\n**v-expand-both-transition** — New transition that expands in both width and height ([#22570](https://github.com/vuetifyjs/vuetify/pull/22570))\n\n**color utilities** — Strip `text-*` and `bg-*` prefixes for dynamic utility class support ([#17569](https://github.com/vuetifyjs/vuetify/pull/17569))\n\n**mdi-unocss icon set** — Native UnoCSS icon support ([#22117](https://github.com/vuetifyjs/vuetify/pull/22117))\n\n**Details:**\n\n* [VAvatarGroup PR#22495](https://github.com/vuetifyjs/vuetify/pull/22495)\n* [VAvatar badge PR#22496](https://github.com/vuetifyjs/vuetify/pull/22496)\n* [VSnackbarQueue PR#22605](https://github.com/vuetifyjs/vuetify/pull/22605)\n* [VToolbar location PR#22608](https://github.com/vuetifyjs/vuetify/pull/22608)\n* [VImg image-class PR#22622](https://github.com/vuetifyjs/vuetify/pull/22622)\n\n### Bug Fixes\n\n**VSnackbar** — Opaque background for transparent variants ([#22646](https://github.com/vuetifyjs/vuetify/pull/22646))\n\n**VTab** — Correct text colors with `inset` without `slider-color` ([#22614](https://github.com/vuetifyjs/vuetify/pull/22614))\n\n**VDateInput** — Prevent page scroll when opening years view ([#22613](https://github.com/vuetifyjs/vuetify/pull/22613))\n\n**VTimePicker** — Enforce allowed values and range in inputs ([#22578](https://github.com/vuetifyjs/vuetify/pull/22578))\n\n**VColorPicker** — Avoid undefined alpha in RGB/HSL output ([#22582](https://github.com/vuetifyjs/vuetify/pull/22582))\n\n**VSelect** — Fix screenreader navigation to select options ([#22602](https://github.com/vuetifyjs/vuetify/pull/22602))\n\n**VTreeview** — Indent lines with `prepend-gap`, correct ARIA roles and attributes ([#22589](https://github.com/vuetifyjs/vuetify/pull/22589), [#22577](https://github.com/vuetifyjs/vuetify/pull/22577))\n\n**VCard** — Accept height when used within a dialog ([#22594](https://github.com/vuetifyjs/vuetify/pull/22594))\n\n**VDataTable** — Sort icon persists after removing sort ([#22595](https://github.com/vuetifyjs/vuetify/pull/22595))\n\n**router** — Ensure reactivity for `to` attribute in useLink ([#20994](https://github.com/vuetifyjs/vuetify/pull/20994))\n\n**styles** — Utilities override responsive typography correctly ([#22573](https://github.com/vuetifyjs/vuetify/pull/22573))\n\n**Details:**\n\n* [VSelect a11y PR#22602](https://github.com/vuetifyjs/vuetify/pull/22602)\n* [VTreeview ARIA PR#22577](https://github.com/vuetifyjs/vuetify/pull/22577)\n* [VTreeview indent PR#22589](https://github.com/vuetifyjs/vuetify/pull/22589)\n\n### In Development\n\nSeveral features opened in February are expected in upcoming releases:\n\n#### VMorphingIcon\n\nA new component for animated icon transitions—morphing between two icons using SVG path animation for polished state changes.\n\n#### Theme Page Transitions\n\nOptional built-in page transitions that leverage the View Transitions API, bringing smooth animated route changes without custom code.\n\n#### Hover Elevation\n\nA new `hover-elevation` prop and CSS utilities for elevation changes on hover—a common Material Design pattern now built in.\n\n**Details:**\n\n* [VMorphingIcon PR#22639](https://github.com/vuetifyjs/vuetify/pull/22639)\n* [Theme transitions PR#22623](https://github.com/vuetifyjs/vuetify/pull/22623)\n* [Hover elevation PR#22621](https://github.com/vuetifyjs/vuetify/pull/22621)\n\n---\n\n## Ecosystem Spotlight: Vuetify CLI v1.0.0\n\n<AppFigure :src=\"clilogo\" alt=\"Vuetify CLI Logo\" width=\"200\" height=\"auto\" class=\"mx-auto mt-4\" title=\"Vuetify CLI Logo\" />\n\n<br>\n\nThe Vuetify CLI reached its **first stable release** on February 23rd—shipping alongside Vuetify 4. With **42 commits** and 9 releases (v0.0.14 through v1.0.3), [Andrei Elkin](https://github.com/AndreyYolkin) transformed the CLI from an early beta into a production-ready tool.\n\n### What's New in v1.0.0\n\n**Project Presets** — Create projects with predefined configurations. The first preset is **TailwindCSS**—scaffolding a complete Vuetify 4 + Tailwind project with CSS layers configured correctly out of the box.\n\n**Vuetify 4 Templates** — All project templates updated for v4, with version selection removed now that v4 is stable.\n\n**i18n Support** — CLI prompts now support fallback locales for internationalized project scaffolding.\n\n### Getting Started\n\n::: tabs\n\n```bash [pnpm]\npnpm add -g @vuetify/cli\n```\n\n```bash [npm]\nnpm install -g @vuetify/cli\n```\n\n```bash [yarn]\nyarn global add @vuetify/cli\n```\n\n```bash [bun]\nbun add -g @vuetify/cli\n```\n\n:::\n\n**Details:**\n\n* [Vuetify CLI GitHub Repository](https://github.com/vuetifyjs/cli)\n* [v1.0.0 Release](https://github.com/vuetifyjs/cli/releases/tag/v1.0.0)\n\n---\n\n## Vuetify MCP: V4 Migration & Developer Tools\n\n<AppFigure :src=\"mcplogo\" alt=\"Vuetify MCP logo\" width=\"200\" height=\"auto\" class=\"mx-auto mt-4\" title=\"Vuetify MCP Logo\" />\n\n<br>\n\nThe MCP server received 9 commits in February, adding new developer tooling and improving v0 integration.\n\n### What's New\n\n**V4 Migration Tools** — Two tools launched alongside the v4 beta cycle provide AI-assisted upgrade guidance:\n\n* **`get_upgrade_guide`** — Fetches the full v3 → v4 upgrade guide with step-by-step migration instructions and revert snippets\n* **`get_v4_breaking_changes`** — Returns detailed migration guidance for all 13 categories of breaking changes (styles, grid, typography, elevation, theme, display, v-btn, v-snackbar, v-select, v-date-picker, v-form, v-img, nested), with optional category filtering\n\n**`create_bug_report` Tool** — Generate a pre-filled link to the Vuetify issue tracker with the correct repository and label pre-selected.\n\n**`get_vuetify0_skill` Tool** — Provides AI assistants with v0 composable documentation and usage patterns, enabling better code generation for headless components.\n\n**v0 Fixes** — Corrected composable names and missing exports in the v0 documentation, and fixed GitHub URL branch references.\n\n**CLI Integration** — [Andrei Elkin](https://github.com/AndreyYolkin) opened a PR for detecting running IDE instances and supporting multi-selection during MCP setup.\n\n### Setup\n\nInstall with the Vuetify CLI:\n\n::: tabs\n\n```bash [pnpm]\npnpm dlx @vuetify/cli add mcp\n```\n\n```bash [npm]\nnpx @vuetify/cli add mcp\n```\n\n```bash [yarn]\nyarn dlx @vuetify/cli add mcp\n```\n\n```bash [bun]\nbunx @vuetify/cli add mcp\n```\n\n:::\n\nOr configure manually:\n\n```json\n{\n  \"mcpServers\": {\n    \"vuetify\": {\n      \"url\": \"https://mcp.vuetifyjs.com/mcp\"\n    }\n  }\n}\n```\n\n**Details:**\n\n* [Vuetify MCP GitHub Repository](https://github.com/vuetifyjs/mcp)\n* [create_bug_report commit](https://github.com/vuetifyjs/mcp/commit/47d4dafc4fc6fb13dad705d32f802beec92ffefd)\n* [get_vuetify0_skill commit](https://github.com/vuetifyjs/mcp/commit/d58a7abbcdb73a087e982ce8a8d3d27331064e52)\n\n---\n\n## Product Updates\n\n### Vuetify One\n\nVuetify One completed a **monorepo conversion**, extracting `@vuetify/auth` as a standalone package with 7 iterative releases (v0.1.1 through v0.1.8). The app upgraded to **Vuetify 4** on release day, and a new [v3.vuetifyjs.com](https://v3.vuetifyjs.com/) site identifier was added for versioned documentation hosting.\n\n**Details:**\n\n* [Vuetify One](https://one.vuetifyjs.com/)\n* [v3.0.2 Release](https://github.com/vuetifyjs/one/releases/tag/v3.0.2)\n* [@vuetify/auth@0.1.8](https://github.com/vuetifyjs/one/releases/tag/%40vuetify/auth%400.1.8)\n\n### Vuetify Bin\n\n[Henry Aviles](https://github.com/Haviles04) shipped the **team dashboard** feature across 5 merged PRs—enabling team bin management, role-based permissions, and team switching.\n\n**Details:**\n\n* [Vuetify Bin](https://bin.vuetifyjs.com/)\n\n### Vuetify Snips\n\n[Kael](https://github.com/KaelWD) set up **visual regression testing** for Snips, and [J-Sek](https://github.com/J-Sek) fixed import and TypeScript issues for Vuetify Play compatibility.\n\n### UnoCSS Preset\n\nThe [unocss-preset-vuetify](https://github.com/vuetifyjs/unocss-preset-vuetify) reached **v0.2.0** with theme variants, built-in MD2/MD3 elevation presets, and separated base typography layers.\n\n---\n\n## Vuetify0: Progress Update\n\n<AppFigure :src=\"zerologo\" alt=\"Vuetify0 logo\" width=\"200\" height=\"auto\" class=\"mx-auto mt-4\" title=\"Vuetify0 Logo\" />\n\n<br>\n\nFebruary was Vuetify0's highest-commit month with **152 commits** and **10 merged PRs**, releasing **v0.1.3**. The focus shifted toward data-heavy composables and overlay management, building the foundation for reconstructing Vuetify's internals on v0's headless layer.\n\n<!-- MEDIA TODO: v0.png\n  Ideas:\n  - Screenshot of the v0 docs site showing the new createDataTable composable page — TypeScript types visible in the API reference\n  - IDE screenshot showing createDataTable usage with full autocompletion — sorting, filtering, pagination props all typed\n  - Diagram of the v0 composable tree: createDataTable composed from createGroup + createFilter + createPagination + createSort — shows the composable-composition story\n  - The Breadcrumbs compound component tree (Root > List > Item > Link > Divider > Ellipsis) rendered in the docs with ARIA attributes visible in DevTools\n  - Before/after: Vuetify VDataTable source vs v0 createDataTable — shows the refactor direction\n-->\n![Vuetify0 Progress](https://cdn.vuetifyjs.com/docs/images/blog/february-2026-update/v0.png \"Vuetify0 February Progress\")\n\n### New Composables & Components\n\n* **[createDataTable](https://0.vuetifyjs.com/composables/data/create-data-table/)** — Headless data table composable with sorting, filtering, pagination, and selection built in. The foundation for Vuetify's VDataTable refactor.\n\n* **[createNested](https://0.vuetifyjs.com/composables/selection/create-nested/)** — Gained active state management for hierarchical tree structures, enabling treeview, file browser, and nested navigation patterns with `activate()`, `deactivate()`, and `activeIds` tracking.\n\n* **[useStack](https://0.vuetifyjs.com/composables/plugins/use-stack/)** — Overlay z-index management plugin for coordinating dialogs, menus, and drawers. Ensures correct stacking order without manual z-index management.\n\n* **[Breadcrumbs](https://0.vuetifyjs.com/components/navigation/breadcrumbs/)** — Composable and component for accessible breadcrumb navigation with automatic ARIA attributes.\n\n### useDate Fixes\n\n[J-Sek](https://github.com/J-Sek) landed two important fixes—symmetrical date diffs and a corrected `getWeek` implementation ported from Vuetify core.\n\n### Coming Next\n\nDevelopment is accelerating with several new components and composables in active PRs:\n\n* **[Treeview](https://github.com/vuetifyjs/0/pull/144)** — Full tree component built on createNested\n* **[Slider](https://github.com/vuetifyjs/0/pull/143)** — New component and composable\n* **[Splitter](https://github.com/vuetifyjs/0/pull/145)** — Root, Panel, and Handle components for resizable pane layouts\n* **[useNotifications](https://github.com/vuetifyjs/0/pull/146)** — Notification lifecycle management with adapters\n* **[createModel](https://github.com/vuetifyjs/0/pull/148)** — Selection state layer between registry and selection\n* **[createRegistry](https://github.com/vuetifyjs/0/pull/149)** — `move()` method for reordering registered items\n* **[useRules](https://github.com/vuetifyjs/0/pull/140)** — Validation composable with Zod and Yup adapters\n\nThe [interactive playground](https://0.vuetifyjs.com/playground) is now live for experimenting with v0 composables.\n\n::: info\n\nWith v4 stable, the Vuetify → Vuetify0 refactor has begun. Core Vuetify components are being rebuilt on top of v0's headless composable layer—the path to Vuetify 5.\n\n:::\n\n**Details:**\n\n* [Vuetify0 Documentation](https://0.vuetifyjs.com/)\n* [createDataTable PR#138](https://github.com/vuetifyjs/0/pull/138)\n* [createNested PR#137](https://github.com/vuetifyjs/0/pull/137)\n* [Breadcrumbs PR#136](https://github.com/vuetifyjs/0/pull/136)\n* [createStack PR#129](https://github.com/vuetifyjs/0/pull/129)\n* [v0.1.3 Release Notes](https://github.com/vuetifyjs/0/releases/tag/v0.1.3)\n\n---\n\n## February 2026 Changelog\n\nThe following section provides an overview of the changes made in February 2026, including new features, bug fixes, and enhancements across the Vuetify framework.\n\n**Key Improvements:**\n\n* New components: VAvatarGroup, v-expand-both-transition\n* Select components: menu-header/footer slots, screenreader fixes\n* VDataTable: page-by prop, sort icon persistence fix\n* VTreeview: ARIA roles, indent line improvements\n* Multiple VTimePicker, VDateInput, and VColorPicker fixes\n* Dynamic color utility class support\n\n**Expand** this section to see the detailed changelog for February 2026:\n\n<details>\n<summary>February 2026 Full Changelog</summary>\n\n### v3.11.9\n\n**:wrench: Bug Fixes**\n\n* **VSnackbar:** opaque background for transparent variants ([#22646](https://github.com/vuetifyjs/vuetify/issues/22646)) ([Timur000101](https://github.com/Timur000101))\n* **VTab:** correct text colors when using inset without slider-color ([#22614](https://github.com/vuetifyjs/vuetify/issues/22614)) ([J-Sek](https://github.com/J-Sek))\n* **VDateInput:** don't scroll the page when opening years view ([#22613](https://github.com/vuetifyjs/vuetify/issues/22613)) ([Tzahile](https://github.com/Tzahile))\n* **VTimePicker:** enforce allowed values and range in inputs ([#22578](https://github.com/vuetifyjs/vuetify/issues/22578)) ([J-Sek](https://github.com/J-Sek))\n* **VColorPicker:** avoid undefined alpha in rgb/hsl output ([#22582](https://github.com/vuetifyjs/vuetify/issues/22582)) ([TheSanjBot](https://github.com/TheSanjBot))\n* **VTable:** apply $table-header-font-size to th elements ([#22598](https://github.com/vuetifyjs/vuetify/issues/22598)) ([nemanjamalesija](https://github.com/nemanjamalesija))\n* **VDataTable:** sort icon persists after removing sort via click ([#22595](https://github.com/vuetifyjs/vuetify/issues/22595)) ([nemanjamalesija](https://github.com/nemanjamalesija))\n* **VCard:** accept height when used within a dialog ([#22594](https://github.com/vuetifyjs/vuetify/issues/22594)) ([J-Sek](https://github.com/J-Sek))\n* **VSelect:** pass listProps density to VCheckboxBtn in multiple ([#22512](https://github.com/vuetifyjs/vuetify/issues/22512)) ([johnleider](https://github.com/johnleider))\n* **VField:** fixed incorrect type define ([#22618](https://github.com/vuetifyjs/vuetify/issues/22618)) ([ZacharyBear](https://github.com/ZacharyBear))\n* **styles:** utilities should override responsive typography ([#22573](https://github.com/vuetifyjs/vuetify/issues/22573)) ([J-Sek](https://github.com/J-Sek))\n* **router:** ensure reactivity for 'to' attribute in useLink ([#20994](https://github.com/vuetifyjs/vuetify/issues/20994)) ([rbgmulmb](https://github.com/rbgmulmb))\n\n---\n\n### v3.12.0\n\n**:rocket: Features**\n\n* **VAvatarGroup:** add new component ([#22495](https://github.com/vuetifyjs/vuetify/issues/22495)) ([J-Sek](https://github.com/J-Sek))\n* **VAvatar:** add badge prop + dot-size for VBadge ([#22496](https://github.com/vuetifyjs/vuetify/issues/22496)) ([J-Sek](https://github.com/J-Sek))\n* **VSnackbarQueue:** show multiple snackbars ([#22605](https://github.com/vuetifyjs/vuetify/issues/22605)) ([J-Sek](https://github.com/J-Sek))\n* **VToolbar:** add location prop ([#22608](https://github.com/vuetifyjs/vuetify/issues/22608)) ([J-Sek](https://github.com/J-Sek))\n* **VImg:** add image-class prop ([#22622](https://github.com/vuetifyjs/vuetify/issues/22622)) ([J-Sek](https://github.com/J-Sek))\n* **VImg:** support width=\"fit-content\" ([#21414](https://github.com/vuetifyjs/vuetify/issues/21414)) ([eesayas](https://github.com/eesayas))\n* **VDataTable:** add page-by prop ([#22580](https://github.com/vuetifyjs/vuetify/issues/22580)) ([J-Sek](https://github.com/J-Sek))\n* **VSelect/VAutocomplete/VCombobox:** add menu-header and menu-footer slots ([#22414](https://github.com/vuetifyjs/vuetify/issues/22414)) ([Haviles04](https://github.com/Haviles04))\n* **VSlider:** show thumb slider value on hover ([#22412](https://github.com/vuetifyjs/vuetify/issues/22412)) ([brandonpham13](https://github.com/brandonpham13))\n* **VOtpInput:** add masked prop ([#20950](https://github.com/vuetifyjs/vuetify/issues/20950)) ([ankusharoraa](https://github.com/ankusharoraa))\n* **VProgressCircular:** add reveal prop ([#22502](https://github.com/vuetifyjs/vuetify/issues/22502)) ([J-Sek](https://github.com/J-Sek))\n* **VRow:** smaller density steps ([#22574](https://github.com/vuetifyjs/vuetify/issues/22574)) ([J-Sek](https://github.com/J-Sek))\n* **VCol:** syntax for overriding row size ([#22572](https://github.com/vuetifyjs/vuetify/issues/22572)) ([J-Sek](https://github.com/J-Sek))\n* **transitions:** add v-expand-both-transition ([#22570](https://github.com/vuetifyjs/vuetify/issues/22570)) ([J-Sek](https://github.com/J-Sek))\n* **color:** strip text-*/bg-* for dynamic utility classes ([#17569](https://github.com/vuetifyjs/vuetify/issues/17569)) ([cgodo](https://github.com/cgodo))\n* **icon-set:** add mdi-unocss icon set ([#22117](https://github.com/vuetifyjs/vuetify/issues/22117)) ([userquin](https://github.com/userquin))\n* **VProgressLinear:** split buffer and indeterminate ([#22663](https://github.com/vuetifyjs/vuetify/issues/22663)) ([J-Sek](https://github.com/J-Sek))\n\n**:wrench: Bug Fixes**\n\n* **VSelect:** fix screenreader navigation to select options ([#22602](https://github.com/vuetifyjs/vuetify/issues/22602)) ([ikushum](https://github.com/ikushum))\n* **VTreeview:** indent lines with prepend-gap ([#22589](https://github.com/vuetifyjs/vuetify/issues/22589)) ([J-Sek](https://github.com/J-Sek))\n* **VTreeview:** add correct roles and aria attributes ([#22577](https://github.com/vuetifyjs/vuetify/issues/22577)) ([mjung2605](https://github.com/mjung2605))\n\n---\n\n### v3.12.1\n\n**:wrench: Bug Fixes**\n\n* **docs:** add overflow-hidden to FAQ expansion panels ([#22660](https://github.com/vuetifyjs/vuetify/issues/22660)) ([Haviles04](https://github.com/Haviles04))\n\n---\n\n### v4.0.0\n\n**:rocket: Features**\n\n* All features from v3.12.0 included in the v4 stable release\n* **CSS Layers:** styles organized in `@layer` blocks for clean utility framework coexistence\n* **MD3 Typography:** Material Design 3 type scale from v4.0.0-beta.0\n* **MD3 Elevation:** updated elevation levels matching MD3 specifications from v4.0.0-beta.0\n* **Grid System Overhaul:** modernized responsive grid from v4.0.0-beta.0\n\n</details>\n\n---\n\n## What's Next{ .mt-4 }\n\nWith v4 stable, the focus shifts to two fronts. First, **v4.1** will land the features currently in development—VMorphingIcon, theme page transitions, and hover elevation. VFileUpload's VInput integration and VCommandPalette's `closeOnSelect` and `before-select` events have already landed, along with Nuxt and UnoCSS presets for the CLI.\n\nSecond, the **Vuetify → Vuetify0 refactor** is now [underway](https://github.com/vuetifyjs/vuetify/pull/22672). Core Vuetify components are being rebuilt on v0's headless composable layer—starting with data table, tree, and form primitives. This is the path to **Vuetify 5**, where the full component library and the headless meta-framework share one unified architecture.\n\nVuetify is and always will be free and open source. If your team relies on the framework, consider supporting continued development through [Vuetify One](https://one.vuetifyjs.com/) or [GitHub Sponsors](https://github.com/sponsors/johnleider). Every contribution helps us ship features like v4, the CLI, and Vuetify0 faster.\n\nThank you for being part of the Vuetify community. See you in March!\n\n---\n\n*Stay connected with Vuetify updates through our [GitHub repository](https://github.com/vuetifyjs/vuetify), [Discord community](https://discord.gg/vuetify), and follow [@vuetifyjs](https://twitter.com/vuetifyjs) for the latest announcements. The best is yet to come!*\n"
  },
  {
    "path": "packages/docs/src/pages/en/blog/index.md",
    "content": "---\nlayout: blog\nmeta:\n  title: Vuetify — Blog\n  description: The Vuetify blog is a place where we share the latest news, updates, and stories about Vuetify. Stay up to date with the latest developments in the Vuetify ecosystem.\n  keywords: vuetify, blog, news, updates, stories, ecosystem\n---\n\n<br>\n\n# From the blog\n\nLatest news, updates, and stories about Vuetify.\n\n<PromotedEntry />\n\n---\n\n<br>\n\n## February 2026 Update\n\n🖊️ John Leider • 📅 March 9th, 2026\n\nFebruary marks Vuetify's most significant milestone—the stable release of **Vuetify 4.0.0** with CSS layers, MD3 design system, and unstyled component foundations. The Vuetify CLI hit v1.0.0, VAvatarGroup shipped as a new component, and Vuetify0 gained createDataTable and Breadcrumbs composables across 390 commits and 68 merged PRs... { .text-medium-emphasis }\n\n[Read More](/blog/february-2026-update/) { .text-end }\n\n## Vuetify Project baseline with Vite and TailwindCSS\n\n🖊️ Jacek Czarniecki • 📅 February 16th, 2026\n\nEver wondered what does it really take to make Vuetify project play in harmony with TailwindCSS? This article is about to lay it out in a consise step-by-step guide. With CSS layers enabled by default in Vuetify v4, the two frameworks coexist smoothly while sharing aligned breakpoints, theme colors, and custom fonts. We cover disabling Vuetify's built-in utilities in favor of Tailwind's, resolving conflicting classes and more. { .text-medium-emphasis }\n\n[Read More](/blog/building-with-vite-and-tailwindcss/) { .text-end }\n\n## January 2026 Update\n\n🖊️ John Leider • 📅 February 11th, 2026\n\nJanuary delivered Vuetify 4.0.0-beta.0 with MD3 typography and elevation systems, VCommandPalette in labs, grid system overhaul, and the Vuetify CLI reaching 100 commits with analyze command and tab completion. Vuetify0 hit v0.1.0 with Tabs, Radio, and Checkbox components, while Snips gained 11 new snippets from J-Sek... { .text-medium-emphasis }\n\n[Read More](/blog/january-2026-update/) { .text-end }\n\n## December 2025 Update\n\n🖊️ John Leider • 📅 January 12th, 2026\n\nDecember was our most productive month of 2025 with 522 commits across 16 repositories. The month delivered Vuetify 4.0.0-alpha.0 with CSS layers, six v3.11.x patches, the Vuetify CLI public release, Google OAuth for Vuetify One, PWA support across all ecosystem products, and 6 Vuetify0 releases with new composables including usePagination, useClickOutside, and useVirtual... { .text-medium-emphasis }\n\n[Read More](/blog/december-2025-update/) { .text-end }\n\n## Vuetify Project baseline with Nuxt and UnoCSS\n\n🖊️ Jacek Czarniecki • 📅 December 22th, 2025\n\nLet's explore a lean, production‑ready setup for Nuxt application that combines Vuetify 3 with UnoCSS. By disabling Vuetify’s default CSS bundles (basic colors and utility classes) and generating only the styles actually used, the resulting CSS footprint shrinks dramatically. We will ensure the project foundation works with themes, typography, and breakpoints without compromises. { .text-medium-emphasis }\n\n[Read More](/blog/building-with-nuxt-and-unocss/) { .text-end }\n\n## November 2025 Update\n\n🖊️ John Leider • 📅 December 10th, 2025\n\nNovember delivered Vuetify v3.11.0 (Harbinger) with VCalendar and VHotkey promoted from labs, new VTimePicker input variant, VDatePicker MD3 improvements, and significant CLI progress. J-Sek contributed an impressive 14 PRs while the v0 project hit 109 commits across 5 releases... { .text-medium-emphasis }\n\n[Read More](/blog/november-2025-update/) { .text-end }\n\n## October 2025 Update\n\n🖊️ John Leider • 📅 November 11th, 2025\n\nOctober focused on refinement and reliability, delivering critical accessibility improvements with enhanced focus trap functionality, optimized VDataTable performance for large datasets, and refined components across the board. The month also saw the launch of Vuetify Link, our new URL shortening service, and significant updates to the Vuetify MCP server with HTTP transport support. We made substantial progress on v0 composables, laying the groundwork for Vuetify 4.0... { .text-medium-emphasis }\n\n[Read More](/blog/october-2025-update/) { .text-end }\n\n## September 2025 Update\n\n🖊️ John Leider • 📅 October 12th, 2025\n\nSeptember marks significant progress as we assemble the building blocks for Vuetify's next phase. From revolutionary design-to-development workflows with our new Figma UI Kit to foundational v0 composables, September has been about connecting the pieces that will define the future of Vue development. This update includes the release of v3.10.0 (Argo), updated Figma UI Kit, new Vuetify0 composables, and over 60 bug fixes and features... { .text-medium-emphasis }\n\n[Read More](/blog/september-2025-update/) { .text-end }\n\n## August 2025 Update\n\n🖊️ John Leider • 📅 September 9th, 2025\n\nAugust marks a pivotal moment in Vuetify's evolution as we prepare to release the pre-alpha of Vuetify0 (v0), launch our redesigned issues page, and continue delivering powerful components and improvements. This month brings exciting developments including the \"Mastering Vuetify Theming\" webinar recap, VEditor final testing phase, free premium themes for personal use, and significant framework updates with 87 merged pull requests... { .text-medium-emphasis }\n\n[Read More](/blog/august-2025-update/) { .text-end }\n\n## July 2025 Update\n\n🖊️ John Leider • 📅 August 6th, 2025\n\nJuly was a month of significant advancements in the Vuetify ecosystem, highlighted by the release of v3.9.0 (Zealot) and the promotion of VTreeview and VTimePicker from labs to core components. This update also includes a focus on component stability, bug fixes, and developer experience improvements, with subsequent patches up to v3.9.3... { .text-medium-emphasis }\n\n[Read More](/blog/july-2025-update/) { .text-end }\n\n## June 2025 Update\n\n🖊️ John Leider • 📅 July 7th, 2025\n\nJune delivered substantial progress on VHotkey component, VCommandPalette development, component stability improvements, and developer experience enhancements across the Vuetify ecosystem. Discover the completion of VHotkey and useHotkey composable, new components in development like VMaskInput and VEditor, and exciting ecosystem updates including documentation improvements and Vuetify Studio enhancements... { .text-medium-emphasis }\n\n[Read More](/blog/june-2025-update/) { .text-end }\n\n---\n\n## May 2025 Update\n\n🖊️ John Leider • 📅 June 6th, 2025\n\nThis month brings exciting advancements across the Vuetify ecosystem, with major strides in AI integration, component refinements, and developer experience. Discover the official release of @vuetify/mcp (Model Context Protocol), substantial improvements to VDateInput and VNumberInput components, and the introduction of the new VColorInput Labs component... { .text-medium-emphasis }\n\n[Read More](/blog/may-2025-update/) { .text-end }\n\n---\n\n## April 2025 Update\n\n🖊️ John Leider • 📅 May 1st, 2025\n\nApril delivered tangible progress on MCP, the new theming engine, component refinements, docs, ESLint v4, and tooling across the Vuetify ecosystem. Discover how these updates enhance your development experience and prepare Vuetify for the future... { .text-medium-emphasis }\n\n[Read More](/blog/april-2025-update/) { .text-end }\n\n---\n\n## Announcing Vuetify v3.8\n\n🖊️ John Leider • 📅 April 8th, 2025\n\nVuetify v3.8 is here! Discover the latest features, improvements, and bug fixes in this minor release, including new components and form input enhancements. This release is packed with new features, improvements, and bug fixes, and contains no breaking changes... { .text-medium-emphasis }\n\n---\n\n[Read More](/blog/announcing-vuetify-3.8/) { .text-end }\n\n## Vuetify HeroDevs Partnership\n\n🖊️ Taylor Corbett • 📅 March 28th, 2025\n\nVuetify is excited to announce a partnership with HeroDevs to provide extended long-term support for Vuetify 2 users through Vue 2 NES + Essentials. For teams that haven't yet migrated to Vuetify 3, this solution is designed to keep applications secure and up to date without requiring an immediate migration, addressing security vulnerabilities, compliance issues, and compatibility challenges... { .text-medium-emphasis }\n\n[Read More](/blog/vuetify-herodevs-partnership/) { .text-end }\n\n---\n\n## State of the Union 2024 - Post Mortem\n\n🖊️ John Leider • 📅 March 19th, 2025\n\nA lot has changed since the 2024 State of the Union. In this post, I want to share the journey we've been on, the challenges we've faced, and the incredible team that's come together to shape Vuetify's future. From nearly losing it all to finding renewed purpose and energy, this is a story of resilience, community, and a shared vision for what Vuetify can become... { .text-medium-emphasis }\n\n[Read More](/blog/state-of-the-union-2024-post-mortem/) { .text-end }\n\n---\n\n## Building a Basic Nuxt Application with Vuetify\n\n🖊️ Eric Sarrion • 📅 February 21st, 2025\n\nDiscover how to craft a polished Nuxt application with Vuetify in this detailed guide. Leverage Vue.js and Nuxt’s streamlined framework to build a basic app featuring a toolbar, navigation menu, and multiple pages. Ideal for developers of all levels looking to simplify their workflow with automatic imports and reusable components... { .text-medium-emphasis }\n\n[Read More](/blog/building-a-basic-nuxt-application-with-vuetify/) { .text-end }\n\n---\n\n## State of the Union 2024\n\n🖊️ John Leider • 📅 September 8th, 2024\n\nIt's been a long road to get where we are today, and looking back, I can’t help but feel proud of how far Vuetify has come. From humble beginnings to now surpassing Vuetify 2’s usage, the journey has been anything but easy, but we’ve always had our community to lean on. Today, I want to take some time to reflect on our past, acknowledge our wins and challenges, and share where we're headed... { .text-medium-emphasis }\n\n[Read More](/blog/state-of-the-union-2024/) { .text-end }\n\n---\n"
  },
  {
    "path": "packages/docs/src/pages/en/blog/january-2026-update.md",
    "content": "---\nlayout: blog\nmeta:\n  title: January 2026 Update\n  description: January delivered Vuetify 4.0.0-beta.0, MD3 typography and elevation levels, VCommandPalette labs release, grid system overhaul, and Vuetify0 hitting v0.1.0 with 21 merged PRs including Tabs, Radio, and Checkbox components.\n  keywords: Vuetify January 2026, v4.0.0-beta.0, VCommandPalette, MD3 typography, grid system, Vuetify0, CLI\n---\n\n<script setup>\n  import { computed } from 'vue'\n  import { useTheme } from 'vuetify'\n\n  const theme = useTheme()\n\n  const clilogo = computed(() => {\n    return `https://cdn.vuetifyjs.com/docs/images/one/logos/vcli-logo-${theme.current.value.dark ? 'dark' : 'light'}.png`\n  })\n  const mcplogo = computed(() => {\n    return `https://cdn.vuetifyjs.com/docs/images/one/logos/vmcp-logo-${theme.current.value.dark ? 'dark' : 'light'}.png`\n  })\n  const zerologo = computed(() => {\n    return `https://cdn.vuetifyjs.com/docs/images/one/logos/vzero-logo-${theme.current.value.dark ? 'dark' : 'light'}.png`\n  })\n  const vuetifylogo = computed(() => {\n    return `https://cdn.vuetifyjs.com/docs/images/one/logos/vuetify-logo-${theme.current.value.dark ? 'dark' : 'light'}.png`\n  })\n  const snipslogo = computed(() => {\n    return `https://cdn.vuetifyjs.com/docs/images/one/logos/vsnips-logo-${theme.current.value.dark ? 'dark' : 'light'}.png`\n  })\n</script>\n\n# January 2026 Update\n\nWelcome to the January 2026 Vuetify update! The new year kicks off with **Vuetify 4.0.0-beta.0**—the first beta of our next major version featuring MD3 typography, elevation levels, and a complete grid system overhaul. **VCommandPalette** lands in labs, and **Vuetify0** hits the v0.1.0 milestone with new Tabs, Radio, and Checkbox components.\n\n![Hero image for January update](https://cdn.vuetifyjs.com/docs/images/blog/january-2026-update/january-hero.png \"January hero image\"){ height=112 }\n\n🖊️ John Leider • 📅 February 11th, 2026\n\n<PromotedEntry />\n\n---\n\n## A Strong Start to 2026\n\nJanuary delivered steady progress across all Vuetify projects. With **661 commits** across 12 active repositories and **49 merged PRs**, the team maintained momentum from December's productive close. The release of v4.0.0-beta.0 brings MD3 typography and elevation system migrations, preparing Vuetify 4 for stable release. [J-Sek](https://github.com/J-Sek) continued his exceptional contribution streak with 5 merged PRs to the main framework plus 11 to Snips, while [Andrei Elkin](https://github.com/AndreyYolkin) drove the grid system overhaul and led CLI development with 75 commits.\n\n---\n\n## Table of Contents\n\n* [Releases](#releases)\n  * [Key Improvements](#key-improvements)\n* [Vuetify 4 Beta](#vuetify-4-beta)\n* [Framework Updates](#framework-updates)\n  * [New Features](#new-features)\n  * [Bug Fixes](#bug-fixes)\n  * [In Development](#in-development)\n* [Ecosystem Spotlight: Vuetify Snips](#ecosystem-spotlight-vuetify-snips)\n* [Vuetify CLI: Rapid Development](#vuetify-cli-rapid-development)\n* [Vuetify MCP: V4 Migration Tools](#vuetify-mcp-v4-migration-tools)\n* [Product Updates](#product-updates)\n* [Vuetify0: Progress Update](#vuetify0-progress-update)\n* [January 2026 Changelog](#january-2026-changelog)\n* [What's Next](#whats-next)\n\n---\n\n## Releases\n\nJanuary delivered three Vuetify releases—two v3.11.x patches maintaining stability and the landmark **v4.0.0-beta.0** advancing the next major version. The MCP server shipped five releases (v0.4.4 through v0.5.0) with v4 migration tooling, and Vuetify One saw eight releases with Open Collective integration.\n\n![January Releases Banner](https://cdn.vuetifyjs.com/docs/images/blog/january-2026-update/releases.png \"January Releases Banner\")\n\n### Key Improvements\n\n* **[VCommandPalette](https://next.vuetifyjs.com/components/command-palettes/)** new labs component for command-driven navigation\n* **[VDataTable](/components/data-tables/)** `sort-icon` prop for custom sort indicators\n* **MD3 Typography** migration to Material Design 3 type system\n* **MD3 Elevation** updated elevation levels matching MD3 specifications\n* **Grid System Overhaul** modernized responsive grid implementation\n* **[v-intersect](/directives/intersect/)** re-mount on prop updates for dynamic behavior\n\nView the complete list of changes in the [Full Changelog](#january-2026-changelog)\n\n**Details:**\n\n* [v3.11.7](https://vuetifyjs.com/getting-started/release-notes/?version=v3.11.7)\n* [v3.11.8](https://vuetifyjs.com/getting-started/release-notes/?version=v3.11.8)\n* [v4.0.0-beta.0](https://vuetifyjs.com/getting-started/release-notes/?version=v4.0.0-beta.0)\n\n---\n\n## Vuetify 4 Beta\n\nThe first beta of **Vuetify 4.0** landed on January 30th, building on December's alpha with significant style system migrations. This release brings Material Design 3 alignment for typography and elevation, plus a modernized grid system.\n\n![Vuetify 4 Beta](https://cdn.vuetifyjs.com/docs/images/blog/january-2026-update/releases-beta.png \"Vuetify 4 Beta\")\n\n### What's New in v4.0.0-beta.0\n\n* **MD3 Typography** — Migrates to Material Design 3's type scale while preserving Sass customization. Updated font sizes and line heights for better hierarchy and readability.\n* **MD3 Elevation** — Elevation levels now match MD3 specifications with smoother shadow progressions and better depth perception across light and dark themes.\n* **Grid System Overhaul** — The responsive grid has been completely modernized with improved flexbox implementation, better RTL support, and cleaner CSS output. [VCol](/api/v-col/) gains syntax for overriding row size.\n\n**Component Updates**:\n\n* **[VDataTable](/components/data-tables/)**: New `sort-icon` prop allows custom sort indicators\n* **[v-intersect](/directives/intersect/)**: Now re-mounts when props update for dynamic threshold changes\n* **nested**: Mark individual nodes as detached for independent selection behavior\n\n::: info\n\nv4.0.0-beta.0 is for testing and feedback only. Production applications should continue using v3.11.x until v4 reaches stable release.\n\n:::\n\n**Details:**\n\n* [v4.0.0-beta.0 Release Notes](https://vuetifyjs.com/getting-started/release-notes/?version=v4.0.0-beta.0)\n* [Migration Guide](https://next.vuetifyjs.com/getting-started/upgrade-guide/)\n* [Remaining Issues](https://github.com/vuetifyjs/vuetify/milestone/62)\n\n---\n\n## Framework Updates\n\n<AppFigure :src=\"vuetifylogo\" alt=\"Vuetify logo\" width=\"200\" height=\"auto\" class=\"mx-auto mt-4\" title=\"Vuetify Logo\" />\n\n<br>\n\nJanuary's framework work balanced v4 development with v3 maintenance. The team merged 14 PRs addressing new features, accessibility, and bug fixes.\n\n### New Features\n\n**[VCommandPalette](/labs/command-palette/)**\n\nThe highly anticipated command palette component lands in labs! VCommandPalette provides a keyboard-driven interface for searching commands, navigation, and actions. It's built on the same patterns used by VS Code, Figma, and other modern applications.\n\n<video width=\"100%\" loop controls class=\"mb-4\">\n  <source src=\"https://cdn.vuetifyjs.com/docs/images/blog/january-2026-update/command-palette.mp4\" type=\"video/mp4\"></source>\n</video>\n\n**[VDataTable](/components/data-tables/) Sort Icon**\n\nA new `sort-icon` prop allows customizing the sort indicator in table headers, enabling consistent iconography with your design system.\n\n**[VField](/api/v-field/) Label Improvements**\n\nVField now ensures only one label element renders at a time, fixing edge cases with floating labels and improving screen reader compatibility.\n\n**Details:**\n\n* [VCommandPalette PR#22403](https://github.com/vuetifyjs/vuetify/pull/22403)\n* [VDataTable sort-icon PR#22521](https://github.com/vuetifyjs/vuetify/pull/22521)\n* [VField label PR#22542](https://github.com/vuetifyjs/vuetify/pull/22542)\n\n### Bug Fixes\n\n**[VAutocomplete](/components/autocompletes/)** Avoid no-items being selectable\n\n**[VInput](/api/v-input/)** Use direction prop only where needed\n\n**[VNumberInput](/components/number-inputs/)** Prevent stepper hover overflow when rounded\n\n**Details:**\n\n* [VAutocomplete PR#22509](https://github.com/vuetifyjs/vuetify/pull/22509)\n* [VInput direction PR#22519](https://github.com/vuetifyjs/vuetify/pull/22519)\n* [VNumberInput PR#22492](https://github.com/vuetifyjs/vuetify/pull/22492)\n\n### In Development\n\nSeveral exciting features are in active development and expected in upcoming releases:\n\n#### VHeatmap\n\nA new visualization component for displaying data density and patterns. Ideal for activity calendars, contribution graphs, and heat distribution displays.\n\n![VHeatmap Preview](https://cdn.vuetifyjs.com/docs/images/blog/january-2026-update/heatmap-preview.png \"VHeatmap Preview\")\n\n#### VMonthPicker\n\nA dedicated month selection component complementing VDatePicker for use cases requiring only month/year selection.\n\n#### VMaskInput Multiple Masks\n\nEnhanced mask input supporting multiple and dynamic mask resolution for complex input patterns like phone numbers with variable country codes.\n\n**Details:**\n\n* [VHeatmap PR#22535](https://github.com/vuetifyjs/vuetify/pull/22535)\n* [VMonthPicker PR#22534](https://github.com/vuetifyjs/vuetify/pull/22534)\n* [VMaskInput PR#22501](https://github.com/vuetifyjs/vuetify/pull/22501)\n\n---\n\n## Ecosystem Spotlight: Vuetify Snips\n\n<AppFigure :src=\"snipslogo\" alt=\"Vuetify Snips logo\" width=\"200\" height=\"auto\" class=\"mx-auto mt-4\" title=\"Vuetify Snips Logo\" />\n\n<br>\n\n[Vuetify Snips](https://snips.vuetifyjs.com/) had an exceptional January with **11 merged PRs**—all from [J-Sek](https://github.com/J-Sek)—adding new snippet categories and improving existing templates.\n\n### New Snippets\n\n![Vuetify Snips Pickers](https://cdn.vuetifyjs.com/docs/images/blog/january-2026-update/snips-pickers.png \"Vuetify Snips Pickers\")\n\n**Pickers**: 6 new picker snippets covering date ranges, time selection, and combined datetime patterns\n\n**Pagination**: New pagination templates demonstrating various layouts and styles\n\n**Buttons**: Additional button variations and loading state patterns\n\n**Charts**: New visualization snippets using Vuetify's chart components\n\n### Improvements\n\n* Improved accessibility for radio group snippets\n* Fixed TypeScript compatibility for Chat snippets in Vuetify Play\n* Updated Vuetify version across all snippets\n\n**Details:**\n\n* [Vuetify Snips](https://snips.vuetifyjs.com/)\n* [Pickers PR#70](https://github.com/vuetifyjs/snips/pull/70)\n* [Pagination PR#83](https://github.com/vuetifyjs/snips/pull/83)\n* [Charts PR#63](https://github.com/vuetifyjs/snips/pull/63)\n\n---\n\n## Vuetify CLI: Rapid Development\n\n<AppFigure :src=\"clilogo\" alt=\"Vuetify CLI Logo\" width=\"200\" height=\"auto\" class=\"mx-auto mt-4\" title=\"Vuetify CLI Logo\" />\n\n<br>\n\nThe Vuetify CLI saw intensive development in January with **97 commits** and 31 releases (v0.0.8 through v0.0.13-beta.9), bringing major new capabilities for project management and development workflows. [Andrei Elkin](https://github.com/AndreyYolkin) drove the majority of CLI development with 75 commits.\n\n### New Features{ #new-cli-features }\n\n**Analyze Command**: `vuetify analyze` detects Vuetify usage patterns in your project, helping identify optimization opportunities and migration paths.\n\n<video width=\"100%\" loop controls class=\"mb-4\">\n  <source src=\"https://cdn.vuetifyjs.com/docs/images/blog/january-2026-update/cli-analyze.mp4\" type=\"video/mp4\"></source>\n</video>\n\n**MCP Integration**: Built-in MCP server configuration with `vuetify add mcp` now supports ruler configuration for AI-assisted development.\n\n**Tab Completion**: Shell tab completion for commands and project arguments, powered by @bomb.sh/tab.\n\n**Localization**: Internationalized prompts for version selection during project scaffolding.\n\n### Getting Started\n\n::: tabs\n\n```bash [pnpm]\npnpm add -g @vuetify/cli\n```\n\n```bash [npm]\nnpm install -g @vuetify/cli\n```\n\n```bash [yarn]\nyarn global add @vuetify/cli\n```\n\n```bash [bun]\nbun add -g @vuetify/cli\n```\n\n:::\n\n**Details:**\n\n* [Vuetify CLI GitHub Repository](https://github.com/vuetifyjs/cli)\n* [v0.0.13 Release](https://github.com/vuetifyjs/cli/releases/tag/v0.0.13)\n\n---\n\n## Vuetify MCP: V4 Migration Tools\n\n<AppFigure :src=\"mcplogo\" alt=\"Vuetify MCP logo\" width=\"200\" height=\"auto\" class=\"mx-auto mt-4\" title=\"Vuetify MCP Logo\" />\n\n<br>\n\nThe Vuetify MCP server shipped four releases in January (v0.4.4 through v0.5.0), with the headline feature being **V4 migration tooling**.\n\n### What's New\n\n![Vuetify MCP Migration](https://cdn.vuetifyjs.com/docs/images/blog/january-2026-update/mcp-migration.png \"Vuetify MCP Migration Workflow\")\n\n**V3 to V4 Upgrade Guide**: New tool providing comprehensive migration guidance for upgrading from Vuetify 3 to Vuetify 4.\n\n**Breaking Changes Reference**: Detailed documentation of all v4 breaking changes with migration examples.\n\n**Vuetify0 Sync**: Updated composable and component documentation synchronized with the v0 repository.\n\n::: tip AI Migration Prompt\n\nTry asking your AI assistant: *\"Use the Vuetify MCP server to analyze my project and generate a migration plan from Vuetify 3 to Vuetify 4.\"*\n\n:::\n\n### Getting Started{ #getting-started-cli }\n\nInstall with the Vuetify CLI:\n\n::: tabs\n\n```bash [pnpm]\npnpm dlx @vuetify/cli add mcp\n```\n\n```bash [npm]\nnpx @vuetify/cli add mcp\n```\n\n```bash [yarn]\nyarn dlx @vuetify/cli add mcp\n```\n\n```bash [bun]\nbunx @vuetify/cli add mcp\n```\n\n:::\n\nOr configure manually:\n\n```json\n{\n  \"mcpServers\": {\n    \"vuetify\": {\n      \"url\": \"https://mcp.vuetifyjs.com/mcp\"\n    }\n  }\n}\n```\n\n**Details:**\n\n* [Vuetify MCP GitHub Repository](https://github.com/vuetifyjs/mcp)\n* [v0.5.0 Release Notes](https://github.com/vuetifyjs/mcp/releases/tag/v0.5.0)\n* [Model Context Protocol Documentation](https://modelcontextprotocol.io/)\n\n---\n\n## Product Updates\n\n### Vuetify One\n\nVuetify One shipped **8 releases** in January (v2.11.0 through v2.13.2), with the highlight being **Open Collective integration**—backers on OpenCollective now receive Vuetify One benefits automatically. Other improvements include banner priority sorting, store function additions, and ecosystem link fixes.\n\n**Details:**\n\n* [Vuetify One](https://one.vuetifyjs.com/)\n\n### Other Products\n\n**Vuetify Play** received 6 commits with quality-of-life improvements. **Vuetify Bin** and **Vuetify Link** each saw minor updates, and **Vuetify Issues Reporter** gained 5 commits improving triage workflows.\n\n---\n\n## Vuetify0: Progress Update\n\n<AppFigure :src=\"zerologo\" alt=\"Vuetify0 logo\" width=\"200\" height=\"auto\" class=\"mx-auto mt-4\" title=\"Vuetify0 Logo\" />\n\n<br>\n\nJanuary marked a significant milestone for Vuetify0 with the **v0.1.0 release**—the first minor version signaling API stability. With **464 commits**, **21 merged PRs**, and 7 releases (v0.0.22 through v0.1.2), the headless meta-framework gained three new components and substantial internal improvements.\n\n![Vuetify0 Progress](https://cdn.vuetifyjs.com/docs/images/blog/january-2026-update/v0.png \"Vuetify0 Progress\")\n\n### New Components\n\n**[Tabs](https://0.vuetifyjs.com/components/disclosure/tabs/)** — A fully accessible tab interface with keyboard navigation, ARIA attributes, and flexible styling. Supports both horizontal and vertical orientations with lazy rendering options.\n\n```html\n<script lang=\"ts\" setup>\n  import { Tabs } from '@vuetify/v0'\n\n  const selected = ref('profile')\n</script>\n\n<template>\n  <Tabs.Root v-model=\"selected\">\n    <Tabs.List label=\"Account settings\">\n      <Tabs.Item value=\"profile\">Profile</Tabs.Item>\n      <Tabs.Item value=\"password\">Password</Tabs.Item>\n      <Tabs.Item value=\"billing\" disabled>Billing</Tabs.Item>\n    </Tabs.List>\n\n    <Tabs.Panel value=\"profile\">Profile content</Tabs.Panel>\n    <Tabs.Panel value=\"password\">Password content</Tabs.Panel>\n    <Tabs.Panel value=\"billing\">Billing content</Tabs.Panel>\n  </Tabs.Root>\n</template>\n```\n\n**[Radio](https://0.vuetifyjs.com/components/forms/radio/)** — Accessible radio button groups with proper fieldset/legend semantics, keyboard navigation, and focus management.\n\n```html\n<script lang=\"ts\" setup>\n  import { Radio } from '@vuetify/v0'\n\n  const selected = ref<string>()\n</script>\n\n<template>\n  <Radio.Group v-model=\"selected\">\n    <label>\n      <Radio.Root value=\"a\">\n        <Radio.Indicator>●</Radio.Indicator>\n      </Radio.Root>\n      Option A\n    </label>\n    <label>\n      <Radio.Root value=\"b\">\n        <Radio.Indicator>●</Radio.Indicator>\n      </Radio.Root>\n      Option B\n    </label>\n  </Radio.Group>\n</template>\n```\n\n**[Checkbox](https://0.vuetifyjs.com/components/forms/checkbox/)** — Standalone checkbox with indeterminate state support, proper labeling, and native form integration.\n\n```html\n<script lang=\"ts\" setup>\n  import { Checkbox } from '@vuetify/v0'\n\n  const agreed = ref(false)\n</script>\n\n<template>\n  <label>\n    <Checkbox.Root v-model=\"agreed\">\n      <Checkbox.Indicator>✓</Checkbox.Indicator>\n    </Checkbox.Root>\n    I agree to the terms\n  </label>\n</template>\n```\n\n### New Composables\n\n**[useLazy](https://0.vuetifyjs.com/composables/system/use-lazy/)** — Deferred rendering based on visibility. Content renders only when its container enters the viewport, ideal for performance optimization in long pages.\n\n**[useDate](https://0.vuetifyjs.com/composables/plugins/use-date/)** — Date manipulation utilities with locale support, formatting, and comparison functions.\n\n**[useHotkey](https://0.vuetifyjs.com/composables/system/use-hotkey/)** — Keyboard shortcut management ported from Vuetify 3, enabling consistent hotkey handling across applications.\n\n**[createNested](https://0.vuetifyjs.com/composables/selection/create-nested/)** — Hierarchical tree management for building treeview, file browser, and nested list components.\n\n### Internal Improvements\n\n**useFeatures Adapters**: New adapter system allows customizing feature behavior without modifying core composables.\n\n**Theme Style Injection**: Migrated to adoptedStyleSheets for better performance and Shadow DOM support.\n\n**Web Types Generation**: Automatic generation of web-types for IDE support with prop documentation and type hints.\n\n::: info\n\nVuetify0 v0.1.x signals API stability for existing composables. Breaking changes will follow semver conventions going forward.\n\n:::\n\n**Details:**\n\n* [Vuetify0 Documentation](https://0.vuetifyjs.com/)\n* [Vuetify0 Roadmap](https://0.vuetifyjs.com/roadmap)\n* [Tabs Component](https://0.vuetifyjs.com/components/disclosure/tabs/)\n* [Radio Component](https://0.vuetifyjs.com/components/forms/radio/)\n* [Checkbox Component](https://0.vuetifyjs.com/components/forms/checkbox/)\n* [v0.1.0 Release Notes](https://0.vuetifyjs.com/releases/?version=v0.1.0)\n\n---\n\n## January 2026 Changelog\n\nThe following section provides an overview of the changes made in January 2026, including new features, bug fixes, and enhancements across the Vuetify framework.\n\n**Key Improvements:**\n\n* MD3 typography and elevation system migrations\n* VCommandPalette labs component\n* Grid system modernization\n* VDataTable sort-icon customization\n* v-intersect dynamic prop updates\n* Numerous accessibility and form fixes\n\n**Expand** this section to see the detailed changelog for January 2026:\n\n<details>\n\n### v3.11.7\n\n**:wrench: Bug Fixes**\n\n* **VAutocomplete:** avoid no-items being selectable ([#22509](https://github.com/vuetifyjs/vuetify/issues/22509)) ([36f679c](https://github.com/vuetifyjs/vuetify/commit/36f679ccef))\n* **VInput:** Use direction prop only where needed ([#22519](https://github.com/vuetifyjs/vuetify/issues/22519)) ([1eca6f8](https://github.com/vuetifyjs/vuetify/commit/1eca6f8fad))\n* **VNumberInput:** prevent inner button overflow when rounded ([#22492](https://github.com/vuetifyjs/vuetify/issues/22492)) ([942ddcc](https://github.com/vuetifyjs/vuetify/commit/942ddcccc8))\n* **VBreadcrumbs:** drop redundant `item-props` prop ([901061b](https://github.com/vuetifyjs/vuetify/commit/901061b7fb))\n* **VTabs:** correct slider width with inset and vertical ([0201b64](https://github.com/vuetifyjs/vuetify/commit/0201b641c4))\n\n---\n\n### v3.11.8\n\n**:wrench: Bug Fixes**\n\n* **VColorPicker:** prevent glitch hiding canvas on resize ([f4e3172](https://github.com/vuetifyjs/vuetify/commit/f4e31724e3))\n* **VListItem:** avoid overlay blinking when deactivating ([d11c6a6](https://github.com/vuetifyjs/vuetify/commit/d11c6a69ec))\n* **VField:** Use only one for label at a time ([#22542](https://github.com/vuetifyjs/vuetify/issues/22542)) ([4c0c9fc](https://github.com/vuetifyjs/vuetify/commit/4c0c9fc08a))\n\n---\n\n### v4.0.0-beta.0\n\n**:rocket: Features**\n\n* **typography:** migrate to MD3 typography ([#22557](https://github.com/vuetifyjs/vuetify/issues/22557)) ([311daf4](https://github.com/vuetifyjs/vuetify/commit/311daf433a))\n* **elevation:** MD3 elevation levels ([#22461](https://github.com/vuetifyjs/vuetify/issues/22461)) ([dfce695](https://github.com/vuetifyjs/vuetify/commit/dfce695f8e))\n* **VCol/VRow:** grid system overhaul ([#21500](https://github.com/vuetifyjs/vuetify/issues/21500)) ([f6d24a9](https://github.com/vuetifyjs/vuetify/commit/f6d24a9234))\n* **VDataTable:** add `sort-icon` prop ([#22521](https://github.com/vuetifyjs/vuetify/issues/22521)) ([3bdf0ea](https://github.com/vuetifyjs/vuetify/commit/3bdf0ead33))\n* **v-intersect:** re-mount on prop updates ([#22556](https://github.com/vuetifyjs/vuetify/issues/22556)) ([6262290](https://github.com/vuetifyjs/vuetify/commit/6262290d24))\n\n**:test_tube: Labs**\n\n* **VCommandPalette:** add new command palette component ([#22403](https://github.com/vuetifyjs/vuetify/issues/22403)) ([2d4d0df](https://github.com/vuetifyjs/vuetify/commit/2d4d0df64f))\n\n</details>\n\n---\n\n## What's Next{ .mt-4 }\n\n**Vuetify 4.0 launches February 23rd.** The final beta releases are landing now, incorporating community feedback on the new typography, elevation, and grid systems. This is a pivotal Vuetify release—bringing CSS layers, a DX overhaul, and minimal migration effort. The [v3 → v4 MCP migration tools](#vuetify-mcp-v4-migration-tools) make an already straightforward upgrade even easier. Importantly, v4 includes the infrastructure changes that make **unstyled components possible**—the foundation for true styling freedom in future releases.\n\nThe tailwind/unocss support landing in v4 is exciting, but it's a stepping stone. The real transformation comes next: **full unstyled capability** where you control every aspect of styling while keeping Vuetify's component logic and accessibility. V4's architecture—combined with the work happening in [Vuetify0](https://0.vuetifyjs.com/roadmap)—sets the stage for this future.\n\nVCommandPalette will receive refinements based on labs feedback, and we're expanding the component's integration patterns for common use cases. VHeatmap and VMonthPicker are on track for labs release.\n\nStarting February 24th, we begin the **Vuetify → Vuetify0 refactor**—rebuilding Vuetify's internals on top of v0's headless composable layer. This is the path to **Vuetify 5**, where the full component library and the headless meta-framework become one unified architecture, unlocking complete styling control without sacrificing the features you rely on.\n\nThank you for being part of the Vuetify community. See you in February!\n\n---\n\n*Stay connected with Vuetify updates through our [GitHub repository](https://github.com/vuetifyjs/vuetify), [Discord community](https://discord.gg/vuetify), and follow [@vuetifyjs](https://twitter.com/vuetifyjs) for the latest announcements. The best is yet to come!*\n"
  },
  {
    "path": "packages/docs/src/pages/en/blog/july-2025-update.md",
    "content": "---\nlayout: blog\nmeta:\n  title: July 2025 Update\n  description: July delivered substantial progress on collaborative development, component enhancements, developer experience improvements, and ecosystem tools across the Vuetify ecosystem.\n  keywords: Vuetify July 2025, Vuetify Migrations Webinar, Vuetify0, VCommandPalette, VEditor, Framework Czar, Vuetify Bin\n---\n\n<script setup>\n  import { useTheme } from 'vuetify'\n  import AboutTeamMember from '@/components/about/TeamMember.vue'\n\n  const theme = useTheme()\n  const teams = useTeamMembersStore()\n\n  const jacek = computed(() => teams.members.find(member => member.github === 'J-Sek'))\n  const zerologo = computed(() => {\n    return `https://cdn.vuetifyjs.com/docs/images/logos/v0-logo-${theme.current.value.dark ? 'dark' : 'light'}.png`\n  })\n</script>\n\n# July 2025 Update\n\nThis month showcases the power of collaborative development as our team and community work together to enhance Vuetify's ecosystem.\n\n![Hero image for July release notes](https://vuetifyjs.b-cdn.net/docs/images/blog/july-2025-update/july-hero.png \"July release notes hero image\"){ height=112 }\n\n---\n\n🖊️ John Leider • 📅 August 6th, 2025\n\n<PromotedEntry />\n\n---\n\n## New Beginnings\n\nJuly exemplified what makes Vuetify special: a dedicated team working alongside an engaged community to build something greater than the sum of its parts. From bug fixes to revolutionary new components, from documentation improvements to ecosystem tools—every contribution matters. This month brings exciting advancements across the Vuetify ecosystem, with major strides in collaborative features, component refinements, and enhanced developer experience.\n\n::: success\n\nCool example of the month: [VChatList](https://play.vuetifyjs.com/playgrounds/spDtrg) by [Ishan](https://github.com/ikushum)\n\n:::\n\n---\n\n## Table of Contents\n\n* [Releases](#releases)\n* [The future of Vuetify](#the-future-of-vuetify)\n* [\"Decoding Vuetify Migrations\" Webinar Recap](#webinar-recap)\n* [Ecosystem Spotlight: Vuetify Bin](#ecosystem-spotlight-vuetify-bin)\n* [Framework Updates](#framework-updates)\n* [July 2025 Changelog](#july-2025-changelog)\n* [What's Next](#whats-next)\n\n---\n\n## Releases\n\nJuly featured the release of [v3.9.0 (Zealot)](/getting-started/release-notes/?version=v3.9.0) on July 8th, promoting [VTreeview](/components/treeview/) and [VTimePicker](/components/time-pickers/) from labs to the core framework; along with subsequent patches up to v3.9.3 on July 29th, focusing on component stability, bug fixes, and developer experience improvements. View the complete list of changes in the [Full Changelog](#july-2025-changelog).\n\n**Details:**\n\n* [v3.9.0](https://vuetifyjs.com/getting-started/release-notes/?version=v3.9.0)\n* [v3.9.1](https://vuetifyjs.com/getting-started/release-notes/?version=v3.9.1)\n* [v3.9.2](https://vuetifyjs.com/getting-started/release-notes/?version=v3.9.2)\n* [v3.9.3](https://vuetifyjs.com/getting-started/release-notes/?version=v3.9.3)\n\n## The future of Vuetify\n\nOver the past decade, I've had the unique opportunity to work closely with hundreds of developers and meet thousands more on a project that I love. Through community support and consistent dedication, that opportunity has continued to thrive and support our efforts—I cannot thank everyone enough for your trust over the years. The last time I wrote about the future of Vuetify was back in [2017](https://github.com/vuetifyjs/vuetify/issues/2240), when this whole thing was just getting started. We're **8 years**, **15 thousand commits**, and **45 million downloads** later, and I can confidently say that Vuetify has become a staple in the Vue ecosystem; that's pretty cool!\n\nWe went through some [organizational](https://vuetifyjs.com/blog/state-of-the-union-2024-post-mortem/) changes earlier this year after facing funding [challenges](https://vuetifyjs.com/blog/state-of-the-union-2024/) in 2024. We're now in August, and I personally consider the effort an ongoing success. The new members assimilated quickly and immediately started making strides across all parts of the ecosystem. This new structure has been a *game changer*, and has finally allowed me to contemplate the future of Vuetify in a way that I haven't been able to in a very long time.\n\nLast [month](https://vuetifyjs.com/blog/june-2025-update/), I revealed some information regarding a new project I've been working on called [Vuetify0](https://github.com/vuetifyjs/0). It is a **meta framework** for building Vue UI libraries with the express goal of abstracting the Vuetify core into a set of publicly available composables.\n\n![Image of Vuetify composition progress](https://cdn.vuetifyjs.com/docs/images/blog/july-2025-update/evolution.png \"Vuetify composition progress\"){ height=588 }\n\n* **Vuetify0**: Meta framework for building framework agnostic UI libraries\n* **Vuetify Paper**: Styleless components that are prop configured—no CSS required\n* **Vuetify**: Marries Vuetify0, Vuetify Paper, and Vuetify's defaults system\n\nI plan to give my first public talk about it at **VueConf Toronto** later this year, and I'm excited to see what everyone thinks.\n\nIn order to have the focus necessary to execute on the above propositions *and* continue to push Vuetify forward, I'm introducing a new position to the organization: the **Framework Czar**. Think of it as the *Lead Maintainer* of the core framework. I will still be involved in the day-to-day operations, but will be less focused on tasks involving the actual management of the [vuetifyjs/vuetify](https://github.com/vuetifyjs/vuetify) repository and more focused on the future of Vuetify as a whole. This includes the Vuetify0 project, Vuetify Paper, and the broader Vuetify ecosystem.\n\nToday I'm excited to announce that **Jacek Czarniecki** will be taking the torch as the first Framework Czar of Vuetify. He is a long-time member of the Vuetify community, contributing to the framework and helping others with their projects. He officially joined the team last November and has since demonstrated a keen sense of detail and a deep understanding of how to build beautiful UI.\n\n<br>\n\n<AboutTeamMember v-if=\"jacek\" v-bind=\"{ member: jacek }\" />\n\n<br>\n\nJacek is a seasoned developer with experience honed in corporate environments and battle-tested through independent projects. He stands out as a true \"maker,\" delivering tangible results while others get bogged down in scheduling meetings about future meetings. We're all very excited to have him in this role, and I look forward to seeing how he shapes the next chapter of the framework.\n\nThank you once again to everyone who has supported Vuetify over the years. I hope you are as excited as I am about the future of this project and the direction we are heading in. Let us know what you think about the changes in the comments below, or on our [Discord](https://community.vuetifyjs.com/).\n\n---\n\n## \"Decoding Vuetify Migrations\" Webinar Recap{ #webinar-recap}\n\nLast week we hosted our monthly webinar, this time focusing on **Vuetify 2 to 3 migrations**. We had a fantastic turnout and talked with the community about the most common migration issues, how to approach them, and the tools available to help. We answered questions about the migration process, shared tips and tricks, and provided insights into the most common pitfalls developers face when upgrading their projects.\n\nBelow are a few key points we noticed most users struggled with during the migration process:\n\n### ESLint Plugin\n\nThe [Vuetify ESLint plugin](https://github.com/vuetifyjs/eslint-plugin-vuetify) is a powerful tool that helps developers identify and fix Vuetify-specific issues in their code. It provides rules for common migration issues, such as deprecated components, incorrect prop usage, and more. The plugin is designed to be used during your upgrade process and will *drastically* reduce the time it takes to migrate your project.\n\n```bash\npnpm install eslint-plugin-vuetify --save-dev\n```\n\n```js\n// eslint.config.js\nimport vue from 'eslint-plugin-vue'\nimport vuetify from 'eslint-plugin-vuetify'\n\nexport default [\n  ...vue.configs['flat/base'],\n  ...vuetify.configs['flat/base'],\n]\n```\n\nFor more information on how to set up and use this plugin, check out the [vuetifyjs/eslint-plugin-vuetify](https://github.com/vuetifyjs/eslint-plugin-vuetify) repository.\n\n### Theme Changes\n\nThe most common migration issue we see? **Theme configuration**. V3's theme system is more powerful but requires a different approach:\n\n```js\n// V2 Approach (Won't work in V3)\ntheme: {\n  themes: {\n    light: {\n      primary: '#1976D2',\n    },\n  },\n}\n\n// V3 Approach (Correct)\ntheme: {\n  themes: {\n    light: {\n      colors: {  // Note the 'colors' wrapper!\n        primary: '#1976D2',\n      },\n    },\n  },\n}\n```\n\n---\n\nWe are looking forward to our next webinar this month. Make sure to sign up, and if you have suggestions for topics, let us know in the comments or on our [Discord](https://community.vuetifyjs.com).\n\n## Ecosystem Spotlight: Vuetify Bin\n\nEvery month, we highlight one tool from the Vuetify ecosystem. This month, we're featuring **Vuetify Bin**—our answer to sharing and debugging Vuetify code snippets.\n\n### What is Vuetify Bin?\n\n[Vuetify Bin](https://bin.vuetifyjs.com/) is our official pastebin/gist alternative for saving and managing snippets of code. Since code is compressed into the URL, you can easily bookmark and share your snippets with others—*free forever*.\n\n![Image of Vuetify Bin](https://vuetifyjs.b-cdn.net/docs/images/blog/july-2025-update/vbin1234.png \"Vuetify Bin interface\"){ height=300 }\n\n::: info\nIf you're part of the **Vuetify One** subscription, you can save your snippets with a unique URL. [More Info](https://vuetifyjs.com/?one=subscribe)\n:::\n\n## Framework Updates\n\nWe've made significant progress on several key components and features this month. The team merged **95 pull requests** in July alone, primarily focusing on component enhancements, bug fixes, and developer experience improvements. Key highlights include:\n\n**VCommandPalette** has moved from concept to reality. This keyboard-first navigation component brings the power of command palettes (think **VS Code** or **Raycast**) to web applications. Early prototypes show seamless integration with Vuetify's existing keyboard navigation, making power-user features accessible to all developers.\n\n<video width=\"100%\" height=\"auto\" loop controls>\n  <source src=\"https://cdn.vuetifyjs.com/docs/images/blog/july-2025-update/vcommand-palette.mp4\" type=\"video/mp4\"></source>\n</video>\n\n**VEditor** reached a significant milestone with the completion of heading formatting (h1-h6) and substantial progress on alignment controls. This rich text editor is becoming the *go-to solution* for content management within Vuetify applications.\n\n<video width=\"100%\" height=\"auto\" loop controls>\n  <source src=\"https://cdn.vuetifyjs.com/docs/images/blog/july-2025-update/veditor.m4v\" type=\"video/mp4\"></source>\n</video>\n\n**VVideo** officially entered Labs with the release of [v3.9.3](https://vuetifyjs.com/getting-started/release-notes/?version=v3.9.3). This component provides a flexible and powerful way to embed videos in Vuetify applications, supporting various formats and configurations.\n\n<video width=\"100%\" height=\"auto\" loop controls>\n  <source src=\"https://vuetifyjs.b-cdn.net/docs/images/blog/june-2025-update/vvideo.mp4\" type=\"video/mp4\"></source>\n</video>\n\n**Details:**\n\n* [VCommandPalette PR#21534](https://github.com/vuetifyjs/vuetify/pull/21534)\n* [VEditor PR#21653](https://github.com/vuetifyjs/vuetify/pull/21653)\n* [VVideo PR#21460](https://github.com/vuetifyjs/vuetify/pull/21460)\n\n## July 2025 Changelog\n\nThe following section provides an overview of the changes made in July 2025, including new features, bug fixes, and enhancements across the Vuetify framework.\n\n**Key Improvements:**\n\n* **VProgressLinear** [#21744](https://github.com/vuetifyjs/vuetify/pull/21744): Added chunk separation capability for creating segmented progress indicators—perfect for multi-step forms and wizards *(Merged July 15)*\n* **VDatePicker** [#21760](https://github.com/vuetifyjs/vuetify/pull/21760): Restored the accidentally removed `first-day-of-year` prop after community feedback *(Draft as of July 24)*\n* **VMaskInput** [#21719](https://github.com/vuetifyjs/vuetify/pull/21719): Fixed validation value handling, ensuring masks work correctly with form validation\n* **VField** [#21706](https://github.com/vuetifyjs/vuetify/pull/21706): Enhanced label accessibility for improved screen reader support\n* **VDateInput** [#21684](https://github.com/vuetifyjs/vuetify/pull/21684): Added proper TypeScript definitions to the `displayFormat` function\n* **Input components** [#21703](https://github.com/vuetifyjs/vuetify/pull/21703): Fixed `aria-describedby` attributes when using `hide-details`\n\nExpand this section to see the detailed changelog for July 2025.\n\n<details >\n\n### 🏅 Component promotions\n\nThe following components have been promoted to the core framework from labs:\n\n* [VTreeview](https://vuetifyjs.com/components/treeview/)\n* [VTimePicker](https://vuetifyjs.com/components/time-pickers/)\n\n### :rocket: Features\n\n* **date:** add StringDateAdapter ([#21174](https://github.com/vuetifyjs/vuetify/issues/21174)) ([7fe9152](https://github.com/vuetifyjs/vuetify/commit/7fe91520fb9ab3ae58d4f7eeba6c0a7b431e6198)), closes [#20967](https://github.com/vuetifyjs/vuetify/issues/20967)\n* **date:** export VuetifyDateAdapter ([#21252](https://github.com/vuetifyjs/vuetify/issues/21252)) ([1a98d03](https://github.com/vuetifyjs/vuetify/commit/1a98d030a7b9547d519b1491e14e97f3e554ee6e)), closes [#19904](https://github.com/vuetifyjs/vuetify/issues/19904)\n* **ripple:** use key names instead of codes ([7ecec03](https://github.com/vuetifyjs/vuetify/commit/7ecec03fb50267507928c6de6751dee16540ea7f))\n* **theme:** add change, toggle, and cycle functions ([#21224](https://github.com/vuetifyjs/vuetify/issues/21224)) ([3570254](https://github.com/vuetifyjs/vuetify/commit/357025485c7e8ac8dbc254a9fb37a3360e8c8d79))\n* **theme:** add new option 'unimportant' to generate classes without `!important` ([3190331](https://github.com/vuetifyjs/vuetify/commit/3190331e70f42b7fdf4d7ee04f662b15eefde026))\n* **theme:** add new theme 'system' ([#21244](https://github.com/vuetifyjs/vuetify/issues/21244)) ([8393a41](https://github.com/vuetifyjs/vuetify/commit/8393a41287d34dba56cb2140bcc1aa44de62ffcb))\n* **transition:** expose create transition functions ([#21352](https://github.com/vuetifyjs/vuetify/issues/21352)) ([79f36aa](https://github.com/vuetifyjs/vuetify/commit/79f36aa042284471c7a7cb248721de884e4ef329)), closes [#16050](https://github.com/vuetifyjs/vuetify/issues/16050)\n* **types:** emit GlobalDirectives ([136dfdf](https://github.com/vuetifyjs/vuetify/commit/136dfdf99380063ed20ca8d0672e1e450faf5431)), closes [#21475](https://github.com/vuetifyjs/vuetify/issues/21475)\n* **useHotkey:** add new composable for making hotkey bindings ([#21598](https://github.com/vuetifyjs/vuetify/issues/21598)) ([99c721c](https://github.com/vuetifyjs/vuetify/commit/99c721c381e47b403429c7de194306013c0ec679))\n* **VAlert:** better aligment with prepend icon ([#20700](https://github.com/vuetifyjs/vuetify/issues/20700)) ([5231b95](https://github.com/vuetifyjs/vuetify/commit/5231b956c39477e913648dcbaef4030c284b1ece)), closes [#20636](https://github.com/vuetifyjs/vuetify/issues/20636)\n* **VBadge:** add width and height props ([#21509](https://github.com/vuetifyjs/vuetify/issues/21509)) ([b87f179](https://github.com/vuetifyjs/vuetify/commit/b87f17933b31cf63289ffccdd78eda3682decc07)), closes [#20837](https://github.com/vuetifyjs/vuetify/issues/20837)\n* **VBtnGroup:** add `direction=\"vertical\"` ([#17878](https://github.com/vuetifyjs/vuetify/issues/17878)) ([5f39b85](https://github.com/vuetifyjs/vuetify/commit/5f39b8586e99c4529da9ef71576c048e711757e8)), closes [#17492](https://github.com/vuetifyjs/vuetify/issues/17492)\n* **VCombobox:** scroll to first item on search result ([#21255](https://github.com/vuetifyjs/vuetify/issues/21255)) ([57bb5ad](https://github.com/vuetifyjs/vuetify/commit/57bb5adb426372ca6af48b961a5b3533efa7d703)), closes [#20572](https://github.com/vuetifyjs/vuetify/issues/#20572)\n* **VDataTable:** support `fixed: 'end'` in headers ([#21665](https://github.com/vuetifyjs/vuetify/issues/21665)) ([415c267](https://github.com/vuetifyjs/vuetify/commit/415c267d057ad49334d9801c4fdb0c6aa9dcdcd1)), closes [#20020](https://github.com/vuetifyjs/vuetify/issues/20020) [#21153](https://github.com/vuetifyjs/vuetify/issues/21153)\n* **VDatePicker:** add `weekday-format` prop ([#21290](https://github.com/vuetifyjs/vuetify/issues/21290)) ([b13b15c](https://github.com/vuetifyjs/vuetify/commit/b13b15c865252f43f09ef590feeaeaac6a49bc1b))\n* **VDatePicker:** expose slots from underlying components ([#21532](https://github.com/vuetifyjs/vuetify/issues/21532)) ([1e351a2](https://github.com/vuetifyjs/vuetify/commit/1e351a2015db61564c3432662e4fc7700dff3a84)), closes [#20236](https://github.com/vuetifyjs/vuetify/issues/20236)\n* **VInfiniteScroll:** add reset method ([#20637](https://github.com/vuetifyjs/vuetify/issues/20637)) ([2e5bc43](https://github.com/vuetifyjs/vuetify/commit/2e5bc4330bf7409870516b818dcdd8bb0f36d0d5)), closes [#20308](https://github.com/vuetifyjs/vuetify/issues/20308) [#19935](https://github.com/vuetifyjs/vuetify/issues/19935)\n* **VKbd:** update default styling, add configurable options ([8ea20d9](https://github.com/vuetifyjs/vuetify/commit/8ea20d9fccaca572465d31af780f460d03f489db))\n* **VNumberInput:** custom decimal separator ([#21489](https://github.com/vuetifyjs/vuetify/issues/21489)) ([534c1e7](https://github.com/vuetifyjs/vuetify/commit/534c1e72363dadfee213f0360272c29d308b28af)), closes [#20254](https://github.com/vuetifyjs/vuetify/issues/20254)\n* **VNumberInput:** more flexible precision display ([#21315](https://github.com/vuetifyjs/vuetify/issues/21315)) ([d5779cd](https://github.com/vuetifyjs/vuetify/commit/d5779cd8529c6589d215569453733700b095ffe9)), closes [#21306](https://github.com/vuetifyjs/vuetify/issues/21306)\n* **VOtpInput:** allow to keep focus on paste ([#21356](https://github.com/vuetifyjs/vuetify/issues/21356)) ([cb8015d](https://github.com/vuetifyjs/vuetify/commit/cb8015daad38b7d9c6853e1053d78ab148574804)), closes [#21275](https://github.com/vuetifyjs/vuetify/issues/21275)\n* **VOverlay:** align scrim color with MD3 ([#21219](https://github.com/vuetifyjs/vuetify/issues/21219)) ([29d22a6](https://github.com/vuetifyjs/vuetify/commit/29d22a6737fa7e68bdd49c522a5b36dca3cabe11)), closes [#20244](https://github.com/vuetifyjs/vuetify/issues/20244)\n* **VSelect/VAutoComplete/VCombobox:** add `item-type` prop ([eaa4d15](https://github.com/vuetifyjs/vuetify/commit/eaa4d15caac1b66868a6af42e52b22cf2279821b)), closes [#21666](https://github.com/vuetifyjs/vuetify/issues/21666)\n* **VSelect:** add `no-auto-scroll` prop ([#21254](https://github.com/vuetifyjs/vuetify/issues/21254)) ([1e0f1c1](https://github.com/vuetifyjs/vuetify/commit/1e0f1c1a527deb5256844e4663d6931840736968)), closes [#20237](https://github.com/vuetifyjs/vuetify/issues/20237)\n* **VSelect:** support divider and subheader in items ([#21348](https://github.com/vuetifyjs/vuetify/issues/21348)) ([0953ed2](https://github.com/vuetifyjs/vuetify/commit/0953ed22c81c1c8d51505a2e35e222af1880698a)), closes [#5014](https://github.com/vuetifyjs/vuetify/issues/5014) [#15721](https://github.com/vuetifyjs/vuetify/issues/15721)\n* **VSlideGroup:** add content class to VSlideGroup props ([#21431](https://github.com/vuetifyjs/vuetify/issues/21431)) ([935351c](https://github.com/vuetifyjs/vuetify/commit/935351cc0e80c2327701a071eeeff15f1a128310)), , closes [#20853](https://github.com/vuetifyjs/vuetify/issues/20853)\n* **VSlider:** expose focus method ([#21575](https://github.com/vuetifyjs/vuetify/issues/21575)) ([6790e1e](https://github.com/vuetifyjs/vuetify/commit/6790e1ebfa820506f92a68f4c9055a2a36413b4b)), closes [#17602](https://github.com/vuetifyjs/vuetify/issues/17602)\n* **VTable:** add striped prop ([#19735](https://github.com/vuetifyjs/vuetify/issues/19735)) ([35b3304](https://github.com/vuetifyjs/vuetify/commit/35b3304a18bdb39df3431b71eef52cdef11130c9)), closes [#17505](https://github.com/vuetifyjs/vuetify/issues/17505)\n* **VTextarea:** add update:rows event ([#21226](https://github.com/vuetifyjs/vuetify/issues/21226)) ([e72d4d3](https://github.com/vuetifyjs/vuetify/commit/e72d4d30088ef47d5abf2e4533cc62c8ee91f823)), closes [#21133](https://github.com/vuetifyjs/vuetify/issues/21133)\n* **VTimePicker:** promote from labs ([7ce2cd6](https://github.com/vuetifyjs/vuetify/commit/7ce2cd68cb40d8de9c2135bdf33c9be9140d22c3))\n* **VTimePicker:** remove ampmInTitle prop ([#21595](https://github.com/vuetifyjs/vuetify/issues/21595)) ([e32796a](https://github.com/vuetifyjs/vuetify/commit/e32796a114711f2b30d3401abea11bfd8b8c2460)), closes [#19637](https://github.com/vuetifyjs/vuetify/issues/19637) [#19957](https://github.com/vuetifyjs/vuetify/issues/19957)\n* **VToolbar:** allow for explicit `:extension=\"false\"` ([#21264](https://github.com/vuetifyjs/vuetify/issues/21264)) ([092e64a](https://github.com/vuetifyjs/vuetify/commit/092e64a10aa6e1b476e0e7fddaf01d1bb1df3793)), closes [#7317](https://github.com/vuetifyjs/vuetify/issues/7317)\n* **VTreeview:** add `indent-lines` prop ([#21675](https://github.com/vuetifyjs/vuetify/issues/21675)) ([501e016](https://github.com/vuetifyjs/vuetify/commit/501e01641f226b54d80176c9e5a20baa4dd7df43)), closes [#11506](https://github.com/vuetifyjs/vuetify/issues/11506)\n* **VTreeview:** expose depth, path, index in slots ([#19833](https://github.com/vuetifyjs/vuetify/issues/19833)) ([bd908af](https://github.com/vuetifyjs/vuetify/commit/bd908afc7e335904c2fb35aa73541d8c04a9fcfb)), closes [#13863](https://github.com/vuetifyjs/vuetify/issues/13863)\n* **VTreeview:** promote from labs ([b610813](https://github.com/vuetifyjs/vuetify/commit/b6108138fdbfb2cc157a29602817708676a23491))\n* **VTreeview:** support `item-type` ([#21709](https://github.com/vuetifyjs/vuetify/issues/21709)) ([877f323](https://github.com/vuetifyjs/vuetify/commit/877f3232698147dee01effc57b2a9770d2ed0e39))\n* **VVirtualScroll:** support fractional scroll index ([#20407](https://github.com/vuetifyjs/vuetify/issues/20407)) ([adad9e2](https://github.com/vuetifyjs/vuetify/commit/adad9e2629fffa52b0abbb7d18297a5c0078074f))\n* **VWindow:** add `vertical-arrows` prop ([#21587](https://github.com/vuetifyjs/vuetify/issues/21587)) ([663b9a8](https://github.com/vuetifyjs/vuetify/commit/663b9a83ee602200adae115500594d462ddfff16))\n\n### :wrench: Bug Fixes\n\n* **date:** align `fullDate` format with documentation and other adapters ([#21668](https://github.com/vuetifyjs/vuetify/issues/21668)) ([c856da3](https://github.com/vuetifyjs/vuetify/commit/c856da3c4d5b0ac6a8c2ac5f8312debc3009fae4)), closes [#21667](https://github.com/vuetifyjs/vuetify/issues/21667)\n* **input:** handle aria-describedby with hide-details ([#21703](https://github.com/vuetifyjs/vuetify/issues/21703)) ([543f932](https://github.com/vuetifyjs/vuetify/commit/543f932622f1de44a215c71fbe8d52af3edea1bd)), closes [#17012](https://github.com/vuetifyjs/vuetify/issues/17012) [#19794](https://github.com/vuetifyjs/vuetify/issues/19794)\n* **inputs:** expose missing validation methods ([be64296](https://github.com/vuetifyjs/vuetify/commit/be6429615af6e0e9e0aad7ef21bfe7a1403229ec)), closes [#19934](https://github.com/vuetifyjs/vuetify/issues/19934)\n* **theme:** ability to restore \"system\" ([#21821](https://github.com/vuetifyjs/vuetify/issues/21821)) ([45077be](https://github.com/vuetifyjs/vuetify/commit/45077be13c220a4abeac161d16f5f406d7e1fb2e)), closes [#21819](https://github.com/vuetifyjs/vuetify/issues/21819)\n* **types:** don't use primitive object wrappers ([32007ed](https://github.com/vuetifyjs/vuetify/commit/32007ed2d34f9a131eb73faeb7629c0ff515f7b2))\n* **virtual:** skip items update if height has not been checked ([#21442](https://github.com/vuetifyjs/vuetify/issues/21442)) ([2e55ed3](https://github.com/vuetifyjs/vuetify/commit/2e55ed3d30daf6ea19660fb8168ea45fca0e9b1d)), closes [#18806](https://github.com/vuetifyjs/vuetify/issues/18806)\n* **VAutocomplete, VCombobox:** space key should not select ([#21311](https://github.com/vuetifyjs/vuetify/issues/21311)) ([f9288ad](https://github.com/vuetifyjs/vuetify/commit/f9288ad7dbfb3547d36e036932e653270eb9ff08)), closes [#20728](https://github.com/vuetifyjs/vuetify/issues/20728)\n* **VChipGroup:** don't select items with a value by index ([#21742](https://github.com/vuetifyjs/vuetify/issues/21742)) ([72cd412](https://github.com/vuetifyjs/vuetify/commit/72cd412ac7a794cc7fbb18918928c4e819827449)), closes [#20129](https://github.com/vuetifyjs/vuetify/issues/20129)\n* **VColorPicker:** keep sliders visible when inputs are hidden ([#21803](https://github.com/vuetifyjs/vuetify/issues/21803)) ([215bfd8](https://github.com/vuetifyjs/vuetify/commit/215bfd866e8c6f606620d8f88c8b1fd4dfe7ab15)), closes [#21801](https://github.com/vuetifyjs/vuetify/issues/21801)\n* **VCombobox:** select all values from pasted text ([#21840](https://github.com/vuetifyjs/vuetify/issues/21840)) ([408a95d](https://github.com/vuetifyjs/vuetify/commit/408a95d7b4c39649546f8098af7a6afd663f777c)), closes [#21838](https://github.com/vuetifyjs/vuetify/issues/21838)\n* **VDataTable:** continue sorting if dates are identical ([a9d0c56](https://github.com/vuetifyjs/vuetify/commit/a9d0c560d77392c803fd0c27b4748b82591dd0e0)), closes [#21650](https://github.com/vuetifyjs/vuetify/issues/21650)\n* **VDataTable:** don't pass slots to VSelect in mobile view ([#21572](https://github.com/vuetifyjs/vuetify/issues/21572)) ([6e61468](https://github.com/vuetifyjs/vuetify/commit/6e6146814462ec56a40bd439b6641630f6e057a3)), closes [#19873](https://github.com/vuetifyjs/vuetify/issues/19873)\n* **VDataTable:** only tab focus sortable columns ([27aaaf4](https://github.com/vuetifyjs/vuetify/commit/27aaaf41246aaaf3bed977c74d0b962daf0a5662)), closes [#20899](https://github.com/vuetifyjs/vuetify/issues/20899)\n* **VDatePicker:** add aria-labels for improved accessibility ([#21635](https://github.com/vuetifyjs/vuetify/issues/21635)) ([5e3fc2b](https://github.com/vuetifyjs/vuetify/commit/5e3fc2b4baf9df2939bdaca84cec28f3bf41633b)), closes [#20696](https://github.com/vuetifyjs/vuetify/issues/20696)\n* **VDatePicker:** avoid infinite loop when first day is out of range ([#21649](https://github.com/vuetifyjs/vuetify/issues/21649)) ([a330d75](https://github.com/vuetifyjs/vuetify/commit/a330d75ef091046c96aae3451bed5f29a66b5d3b))\n* **VDatePicker:** correct week labels ([#21648](https://github.com/vuetifyjs/vuetify/issues/21648)) ([b46e60c](https://github.com/vuetifyjs/vuetify/commit/b46e60c5eba21438c4ecd412ec99f67ebbb24dac)), closes [#21645](https://github.com/vuetifyjs/vuetify/issues/21645) [#21332](https://github.com/vuetifyjs/vuetify/issues/21332)\n* **VDatePicker:** format month to always have 2 digits ([#21686](https://github.com/vuetifyjs/vuetify/issues/21686)) ([f529212](https://github.com/vuetifyjs/vuetify/commit/f529212faffbde85299023b1eb0f4fa344e87df7)), closes [#21681](https://github.com/vuetifyjs/vuetify/issues/21681)\n* **VDatePicker:** improved date comparison with `min` constraint ([#21398](https://github.com/vuetifyjs/vuetify/issues/21398)) ([421a6f6](https://github.com/vuetifyjs/vuetify/commit/421a6f68557e617e0e24b9e525a4cebd841c4f2c)), closes [#21380](https://github.com/vuetifyjs/vuetify/issues/21380)\n* **VDatePicker:** round font-size from 13.6 to 14px ([#21590](https://github.com/vuetifyjs/vuetify/issues/21590)) ([d81a4a0](https://github.com/vuetifyjs/vuetify/commit/d81a4a0cf81353c96f6c5557d8c9be77df7a5836))\n* **VField:** fix label accessibility ([#21706](https://github.com/vuetifyjs/vuetify/issues/21706)) ([85abd80](https://github.com/vuetifyjs/vuetify/commit/85abd8078a2cba159b1cc3caa323519b3b29dec6))\n* **VFileInput:** avoid text overflow with long file names ([#21748](https://github.com/vuetifyjs/vuetify/issues/21748)) ([389a260](https://github.com/vuetifyjs/vuetify/commit/389a260a334d2b9fa1cd717d04904c0b60abe755)), closes [#21707](https://github.com/vuetifyjs/vuetify/issues/21707)\n* **VFileUploadItem:** accept `title` slot ([#21769](https://github.com/vuetifyjs/vuetify/issues/21769)) ([fe85aa0](https://github.com/vuetifyjs/vuetify/commit/fe85aa0ecb4efa17f499beccea27710ad3bea164))\n* **VFileUploadItem:** apply classes, styles as props ([#21752](https://github.com/vuetifyjs/vuetify/issues/21752)) ([d6050f0](https://github.com/vuetifyjs/vuetify/commit/d6050f051ac36cadef5cb6ae1e8995875d2b4bfe)), closes [#21740](https://github.com/vuetifyjs/vuetify/issues/21740)\n* **VList:** ignore invalid itemType values ([4bae0bc](https://github.com/vuetifyjs/vuetify/commit/4bae0bcfba724d90eafda96801ed597558e30885)), closes [#21728](https://github.com/vuetifyjs/vuetify/issues/21728)\n* **VList:** merge classes from itemProps ([5423fbf](https://github.com/vuetifyjs/vuetify/commit/5423fbf18ca6d27ac560529cdd20310aee6d2d32))\n* **VListItem:** keyboard navigation when list contains checkboxes ([#21701](https://github.com/vuetifyjs/vuetify/issues/21701)) ([f500c5b](https://github.com/vuetifyjs/vuetify/commit/f500c5bad5d0da31d8ebec0447cd4b68f91bcbbd)), closes [#21516](https://github.com/vuetifyjs/vuetify/issues/21516)\n* **VMenu:** let persistent menus coexist with regular ones ([#21449](https://github.com/vuetifyjs/vuetify/issues/21449)) ([30ac0fc](https://github.com/vuetifyjs/vuetify/commit/30ac0fcdd491d0eba970d383023d183aafcef491)), closes [#20976](https://github.com/vuetifyjs/vuetify/issues/20976)\n* **VNumberInput:** keep cursor position when typing decimal values ([acc30fb](https://github.com/vuetifyjs/vuetify/commit/acc30fbfa5cd8295f341c545bd4adc5629b14bd6))\n* **VNumberInput:** only trim zeros from the end ([ab2d941](https://github.com/vuetifyjs/vuetify/commit/ab2d941c02a2b5f0c976269c277471a808f251ca)), closes [#21828](https://github.com/vuetifyjs/vuetify/issues/21828)\n* **VOtpInput:** only autofocus if autofocus prop is set ([79bcb27](https://github.com/vuetifyjs/vuetify/commit/79bcb27d8b6006ac9e50787b8e771f46b402e315))\n* **VOverlay:** properly detect location flipping loop ([07db6b2](https://github.com/vuetifyjs/vuetify/commit/07db6b2fdda106325fff514f603b861ae788fee4)), closes [#21564](https://github.com/vuetifyjs/vuetify/issues/21564) [#21551](https://github.com/vuetifyjs/vuetify/issues/21551)\n* **VOverlay:** trigger scrollStrategy when target is a point ([1146171](https://github.com/vuetifyjs/vuetify/commit/114617141a73271f07c108b91829186f3ec36291))\n* **VProgressLinear:** accept pointer events unless `clickable` is used ([#21691](https://github.com/vuetifyjs/vuetify/issues/21691)) ([a6b1136](https://github.com/vuetifyjs/vuetify/commit/a6b1136243f70bf868c438f8d9e6be9b18a492e3)), closes [#21690](https://github.com/vuetifyjs/vuetify/issues/21690)\n* **VRipple:** support touch simulators ([#20776](https://github.com/vuetifyjs/vuetify/issues/20776)) ([9fa2870](https://github.com/vuetifyjs/vuetify/commit/9fa2870eeaf073489f3de790defe3e94a3746788))\n* **VSelect:** don't open menu on its own when items change ([#21247](https://github.com/vuetifyjs/vuetify/issues/21247)) ([339bd45](https://github.com/vuetifyjs/vuetify/commit/339bd45a1fd75b8d51dafcc1d0b270f07c985ee0)), closes [#21205](https://github.com/vuetifyjs/vuetify/issues/21205)\n* **VSelectionControl:** correctly pass ripple options to directive ([#21713](https://github.com/vuetifyjs/vuetify/issues/21713)) ([87a8a3e](https://github.com/vuetifyjs/vuetify/commit/87a8a3ef0edb14d43179442c1727cf5b3d86edab)), closes [#21208](https://github.com/vuetifyjs/vuetify/issues/21208)\n* **VSelects:** avoid error with `null` items ([#21660](https://github.com/vuetifyjs/vuetify/issues/21660)) ([dd98067](https://github.com/vuetifyjs/vuetify/commit/dd98067d8fb2ac46c5cd7f23d630777b61129797))\n* **VSlider:** correctly apply `thumb-color` ([#21833](https://github.com/vuetifyjs/vuetify/issues/21833)) ([b207522](https://github.com/vuetifyjs/vuetify/commit/b207522f5767f11edf56d4c4f0fad0b8dd8fcbb7)), closes [#21832](https://github.com/vuetifyjs/vuetify/issues/21832)\n* **VTextField:** avoid infinite focus loop ([#21628](https://github.com/vuetifyjs/vuetify/issues/21628)) ([efaaa5d](https://github.com/vuetifyjs/vuetify/commit/efaaa5d4f02e886b3e0c46e1f9dd9eed1cdf2e88)), closes [#21626](https://github.com/vuetifyjs/vuetify/issues/21626)\n* **VTextField:** don't try to re-focus input on focus ([#21722](https://github.com/vuetifyjs/vuetify/issues/21722)) ([14c88df](https://github.com/vuetifyjs/vuetify/commit/14c88df44eff939e176f8c01cc4350d2be0d81c5)), closes [#21716](https://github.com/vuetifyjs/vuetify/issues/21716) [#21626](https://github.com/vuetifyjs/vuetify/issues/21626) [#21717](https://github.com/vuetifyjs/vuetify/issues/21717)\n* **VTimePicker:** auto width ([#21613](https://github.com/vuetifyjs/vuetify/issues/21613)) ([5d1ceab](https://github.com/vuetifyjs/vuetify/commit/5d1ceab3e519974cdde29f7e7610ffb5972ac6a7))\n* **VTreeview:** activatable implies openOnClick=false ([c0b7d7b](https://github.com/vuetifyjs/vuetify/commit/c0b7d7b518727f8d43e4463dd3e69edfa4c43d73))\n* **VTreeview:** don't display expanded items as activated ([683dc86](https://github.com/vuetifyjs/vuetify/commit/683dc863d1e8736ac8bda93f58f2b8cc8fa819b4)), closes [#21721](https://github.com/vuetifyjs/vuetify/issues/21721) [#21724](https://github.com/vuetifyjs/vuetify/issues/21724)\n* **VTreeview:** don't select disabled children with parent ([#20962](https://github.com/vuetifyjs/vuetify/issues/20962)) ([0772bc1](https://github.com/vuetifyjs/vuetify/commit/0772bc11c10cd55ca1dd186a64819337b38bc3fd)), closes [#20386](https://github.com/vuetifyjs/vuetify/issues/20386)\n* **VTreeview:** hide extended lines when fluid ([#21798](https://github.com/vuetifyjs/vuetify/issues/21798)) ([5728b2b](https://github.com/vuetifyjs/vuetify/commit/5728b2b2fc9a1e608bb395cc077f5640261a57ea)), closes [#21794](https://github.com/vuetifyjs/vuetify/issues/21794)\n* **VTreeview:** modelValue reactivity ([6daf53d](https://github.com/vuetifyjs/vuetify/commit/6daf53ddbd7f66155f1e1cce870968153fc2b1df))\n* **VTreeview:** prevent checkbox deselection when mandatory ([431af5f](https://github.com/vuetifyjs/vuetify/commit/431af5fa7df28d98d7bb76f88a1803ec98a62719)), closes [#21614](https://github.com/vuetifyjs/vuetify/issues/21614)\n* **VTreeview:** restore reactivity with computed items ([107dd0c](https://github.com/vuetifyjs/vuetify/commit/107dd0c6822a5f029e302627f040a43a82bebb58)), closes [#20900](https://github.com/vuetifyjs/vuetify/issues/20900)\n* **VTreeview:** select trunk nodes on click when openOnClick=false ([e6a1710](https://github.com/vuetifyjs/vuetify/commit/e6a1710296ea0cb67d6877a9c587766b5565f90d)), closes [#21599](https://github.com/vuetifyjs/vuetify/issues/21599)\n* **VTreeview:** set active state from router ([#21644](https://github.com/vuetifyjs/vuetify/issues/21644)) ([01c7a4f](https://github.com/vuetifyjs/vuetify/commit/01c7a4f8a0af4b62eda99bcd7eac56ef452e22d8))\n\n### :microscope: Code Refactoring\n\n* **layout:** consoleWarn instead of error for missing layout items ([34b53f1](https://github.com/vuetifyjs/vuetify/commit/34b53f10b5ae1b218721b32d51c757adecf343f7))\n* **theme:** add internal methods for testing tailwind integration ([abfdb77](https://github.com/vuetifyjs/vuetify/commit/abfdb777e0e00d4a1798f52d7e4c118e7409fcb9))\n\n### :test_tube: Labs\n\n* **VCalendar:** slot day-event not available ([#21558](https://github.com/vuetifyjs/vuetify/issues/21558)) ([d743051](https://github.com/vuetifyjs/vuetify/commit/d743051c3fc2ba99c77b49e2fa99f9925af50eb6)), closes [#21341](https://github.com/vuetifyjs/vuetify/issues/21341)\n* **VCalendar:** use adapter for day element key ([#21689](https://github.com/vuetifyjs/vuetify/issues/21689)) ([428f460](https://github.com/vuetifyjs/vuetify/commit/428f4602b54b6ecbfcc37cd2edf61703ae49712e)), closes [#21688](https://github.com/vuetifyjs/vuetify/issues/21688)\n* **VColorInput:** ensure cancel action closes menu ([#21664](https://github.com/vuetifyjs/vuetify/issues/21664)) ([7822179](https://github.com/vuetifyjs/vuetify/commit/7822179df9d61dec98179ddcb70346d949305412)), closes [#21655](https://github.com/vuetifyjs/vuetify/issues/21655)\n* **VDateInput:** align generic model type with VDatePicker ([#21764](https://github.com/vuetifyjs/vuetify/issues/21764)) ([0cfca46](https://github.com/vuetifyjs/vuetify/commit/0cfca46b2da04c9b98e7a56788f9e648f31b6c3e)), closes [#21751](https://github.com/vuetifyjs/vuetify/issues/21751) [#21753](https://github.com/vuetifyjs/vuetify/issues/21753)\n* **VDateInput:** assign type to displayFormat function ([#21684](https://github.com/vuetifyjs/vuetify/issues/21684)) ([4446ebf](https://github.com/vuetifyjs/vuetify/commit/4446ebff30e96f1d7629bafa0c8b8bad8f473307)), closes [#21683](https://github.com/vuetifyjs/vuetify/issues/21683)\n* **VDateInput:** avoid time values in the field ([#21694](https://github.com/vuetifyjs/vuetify/issues/21694)) ([d4efd48](https://github.com/vuetifyjs/vuetify/commit/d4efd487d384f94a263d2af9b8abc5dbb8381134))\n* **VHotkey:** add new component ([#21598](https://github.com/vuetifyjs/vuetify/issues/21598)) ([99c721c](https://github.com/vuetifyjs/vuetify/commit/99c721c381e47b403429c7de194306013c0ec679))\n* **VIconBtn:** add button type ([#21638](https://github.com/vuetifyjs/vuetify/issues/21638)) ([dd1db74](https://github.com/vuetifyjs/vuetify/commit/dd1db749edd8df351727c01eeca67a1bb7fb8fb6)), closes [#21634](https://github.com/vuetifyjs/vuetify/issues/21634)\n* **VMaskInput:** create new component ([#21519](https://github.com/vuetifyjs/vuetify/issues/21519)) ([117443a](https://github.com/vuetifyjs/vuetify/commit/117443afbe676d5d31ab20b4a549cb7405994493))\n* **VMaskInput:** send unmasked value to rules ([#21719](https://github.com/vuetifyjs/vuetify/issues/21719)) ([64943b3](https://github.com/vuetifyjs/vuetify/commit/64943b30c4a84ddfaa565f9b2d62285450aa128b))\n* **VPie:** create new component ([#21176](https://github.com/vuetifyjs/vuetify/issues/21176)) ([5f0ebca](https://github.com/vuetifyjs/vuetify/commit/5f0ebca99b830f2cdce234b5f45529a1553c66ef))\n* **VStepperVertical:** correct avatar alignment ([#21797](https://github.com/vuetifyjs/vuetify/issues/21797)) ([6292149](https://github.com/vuetifyjs/vuetify/commit/6292149811091210af7005bbaf7de37aea66b69a)), closes [#21792](https://github.com/vuetifyjs/vuetify/issues/21792)\n* **VStepperVertical:** fix next/prev-text props ([#21360](https://github.com/vuetifyjs/vuetify/issues/21360)) ([11986c6](https://github.com/vuetifyjs/vuetify/commit/11986c6e2ac351c38194cd3a8c74f6e03f58e3cf)), closes [#21358](https://github.com/vuetifyjs/vuetify/issues/21358)\n* **VVideo:** create new component ([#21460](https://github.com/vuetifyjs/vuetify/issues/21460)) ([936eba2](https://github.com/vuetifyjs/vuetify/commit/936eba2ef278137d650b00acf0425116ec8237eb)), closes [#5592](https://github.com/vuetifyjs/vuetify/issues/5592)\n\n</details>\n\n---\n\n## What's Next\n\nNext month promises to be an exciting one as we continue building momentum from July's achievements. Here's what's on the horizon:\n\n### Community Roadmap Voting\n\nOver the next few weeks, we'll be launching our community voting system where you can directly influence Vuetify's development priorities. This democratic approach ensures that the features you need most get the attention they deserve.\n\n### Vuetify0 Alpha Release\n\nWe're targeting **late August** for the first alpha release of Vuetify0. This milestone will include:\n\n* Core composable abstractions\n* Initial documentation and examples\n\n### Labs Component Stabilization\n\nAugust is dedicated to refining our Labs components based on community feedback:\n\n* **VCommandPalette**: Finalizing keyboard navigation patterns\n* **VEditor**: Completing table and list formatting features\n* **VCalendar**: Addressing performance optimizations and accessibility improvements\n* **VMaskInput**: Expanding validation integration\n\nThank you for your continued support, feedback, and contributions that make all of this possible! See you next month.\n\n---\n\n*Stay connected with Vuetify updates through our [GitHub repository](https://github.com/vuetifyjs/vuetify), [Discord community](https://discord.gg/eXubxyJ), and upcoming webinar series announcements.*\n"
  },
  {
    "path": "packages/docs/src/pages/en/blog/june-2025-update.md",
    "content": "---\nlayout: blog\nmeta:\n  title: June 2025 Update\n  description: June delivered substantial progress on VHotkey component, VCommandPalette development, component stability improvements, and developer experience enhancements across the Vuetify ecosystem.\n  keywords: Vuetify June 2025, VHotkey, VCommandPalette, Vuetify 0, component stability, developer experience\n---\n\n<script setup>\n  import { useTheme } from 'vuetify'\n\n  const theme = useTheme()\n\n  const zerologo = computed(() => {\n    return `https://cdn.vuetifyjs.com/docs/images/logos/v0-logo-${theme.current.value.dark ? 'dark' : 'light'}.png`\n  })\n</script>\n\n# June 2025 Update\n\nThis month is packed full of exciting updates and progress across the Vuetify ecosystem.\n\n---\n\n🖊️ John Leider • 📅 July 7th, 2025\n\n<PromotedEntry />\n\n---\n\n## Powering Forward\n\nJune delivered substantial progress on developer experience enhancements, component stability improvements, and platform ecosystem expansion. Our team focused on shipping major new composables, refining core components, and strengthening the development workflow with significant updates to hotkey management, command palette functionality, and comprehensive bug fixes across the framework.\n\nWe also hosted an engaging Q&A session with [me](https://github.com/johnleider/), where our community shared their questions and valuable insights. We were thrilled to connect directly with our users and gather feedback that will help shape the future direction of the framework. Don't worry if you missed this session, we have exciting webinars planned for the coming months as well!\n\n::: success\n\nCool example of the month: [VBites](https://play.vuetifyjs.com/playgrounds/7Ksitg) by [Jacek](https://github.com/J-Sek)\n\n:::\n\n---\n\n## Table of Contents\n\n* [Releases](#releases)\n* [Spotlight: Vuetify Studio](#spotlight-vuetify-studio)\n* [Framework](#framework)\n  * [VHotkey Component and useHotkey Composable](#vhotkey-component-and-usehotkey-composable)\n  * [New Component Development](#new-component-development)\n* [Ecosystem Updates](#ecosystem-updates)\n  * [Vuetify Documentation](#vuetify-documentation)\n  * [Vuetify One](#vuetify-one)\n  * [Vuetify Bin](#vuetify-bin)\n* [Q&A and Upcoming Webinars](#qa-and-upcoming-webinars)\n* [Sneak Peek: Vuetify 0](#sneak-peek-vuetify-0)\n* [June 2025 Changelog](#june-2025-changelog)\n* [What's Next](#whats-next)\n\n---\n\n## Releases\n\nJune continued our steady release cadence with several updates addressing bugs and introducing enhancements. These releases focused on component stability and developer experience improvements. View the complete list of changes in the [Full Changelog](#june-2025-changelog).\n\n![Hero image for June release notes](https://vuetifyjs.b-cdn.net/docs/images/blog/june-2025-update/june-2025-hero-asdfasdf.png \"June release notes hero image\"){ height=200 }\n\n**Details:**\n\n* [v3.8.8](https://vuetifyjs.com/en/getting-started/release-notes/?version=3.8.8)\n* [v3.8.9](https://vuetifyjs.com/en/getting-started/release-notes/?version=3.8.9)\n* [v3.8.10](https://vuetifyjs.com/en/getting-started/release-notes/?version=3.8.10)\n* [v3.8.11](https://vuetifyjs.com/en/getting-started/release-notes/?version=3.8.11)\n* [v3.9.0-beta.0](https://vuetifyjs.com/en/getting-started/release-notes/?version=3.9.0-beta.0)\n* [v3.9.0-beta.1](https://vuetifyjs.com/en/getting-started/release-notes/?version=3.9.0-beta.1)\n\n---\n\n## Spotlight: Vuetify Studio\n\n**Did you know?** [Vuetify Studio](https://studio.vuetifyjs.com/) is our comprehensive development platform that often goes unnoticed by the broader community. Studio provides a complete ecosystem for Vuetify development, including:\n\n* **Interactive Component Playground**: Test and experiment with components in real-time\n* **Code Generation Tools**: Quickly prototype layouts and component configurations\n* **Collaborative Development**: Share and iterate on designs with team members\n* **Integration Testing**: Validate component behavior across different scenarios\n\n<video width=\"100%\" height=\"auto\" autoplay loop controls>\n  <source src=\"https://vuetifyjs.b-cdn.net/docs/images/blog/june-2025-update/vstudio-june-2025.mp4\" type=\"video/mp4\"></source>\n</video>\n\nWe're continuously expanding Studio's capabilities to support modern development workflows, and we encourage the community to explore how Studio can accelerate your Vuetify development process.\n\n**Details:**\n\n* [Vuetify Studio](https://studio.vuetifyjs.com/)\n\n## Framework\n\nThere are multiple new components in development with some of that functionality reaching Labs this month. Below are some of the highlights.\n\n### VHotkey Component and useHotkey Composable\n\nThis month marked a significant milestone with the completion and pre-release of our [VHotkey component](https://dev.vuetifyjs.com/en/components/hotkeys/) and `useHotkey` composable system. After extensive development and iteration, these tools are now available in Labs for testing and feedback as we work toward their stable release.\n\n**VHotkey Component Features:**\n\n* **Inline Mode**: Use the component inline with text and it automatically inherits font size and baseline styling\n* **New Variants**: Introduction of the Combined Variant that displays hotkeys in a Chip with Label format\n* **Consolidated Parser**: VHotkey and useHotkey now share the same parsing logic and key alias mapping for consistent behavior\n* **Platform Awareness**: New `platform` prop allows forcing the component to display Mac vs PC hotkey conventions\n* **Enhanced Customization**: Added `prefix` and `postfix` props for better integration flexibility\n\n![Hero image for VHotkey component](https://vuetifyjs.b-cdn.net/docs/images/blog/june-2025-update/hotkeys.png \"VHotkey component hero image\"){ height=220 }\n\n**useHotkey Composable Features:**\n\n* **Dynamic Options**: Options accept `maybeRefs`, enabling dynamic hotkey configuration changes\n* **Shared Logic**: Unified codebase with VHotkey component ensures consistency\n* **Comprehensive Documentation**: Detailed examples and usage patterns available\n\nThis functionality serves as a critical building block for the upcoming VCommandPalette component, providing developers with robust keyboard shortcut management that works seamlessly across different platforms and use cases. While currently in Labs, we encourage the community to test these components and provide feedback as we work toward their stable release.\n\n**Details:**\n\n* [VHotkey Component Documentation](https://dev.vuetifyjs.com/en/components/hotkeys/)\n* [useHotkey Composable Documentation](https://dev.vuetifyjs.com/en/features/hotkey/)\n\n### New Component Development\n\nWe have several new components in development that we are confident will enhance the Vuetify ecosystem and provide additional functionality for developers.\n\n**VMaskInput**: After vanishing in v2, masking is back in the library with enhanced input capabilities and new features.\n\n![Hero gif for VMaskInput component](https://vuetifyjs.b-cdn.net/docs/images/blog/june-2025-update/vmaskinput.gif \"VMaskInput component hero gif\"){ height=280 }\n\n**VEditor**: Early development phase for a new editor component, expanding Vuetify's content creation capabilities.\n\n![Hero image for VEditor component](https://vuetifyjs.b-cdn.net/docs/images/blog/june-2025-update/veditor.png \"VEditor component hero image\"){ height=220 }\n\n**VVideo**: Documentation improvements, Sass variable extraction, and volume component refinement.\n\n<video width=\"100%\" height=\"auto\" autoplay loop controls>\n  <source src=\"https://vuetifyjs.b-cdn.net/docs/images/blog/june-2025-update/vvideo.mp4\" type=\"video/mp4\"></source>\n</video>\n\n**VCommandPalette**: Ongoing development for a powerful command palette component, designed to enhance user interaction and streamline application workflows.{ height=150 }\n\n![Hero image for VCommandPalette component](https://vuetifyjs.b-cdn.net/docs/images/blog/june-2025-update/vcommandpalette.png \"VCommandPalette component hero image\"){ height=370 }\n\n**Details:**\n\n* [VMaskInput P.R.](https://github.com/vuetifyjs/vuetify/pull/21519)\n* [VEditor P.R.](https://dev.vuetifyjs.com/en/components/editor/)\n* [VVideo P.R.](https://github.com/vuetifyjs/vuetify/pull/21460)\n\n## Ecosystem Updates\n\nMultiple advancements were made across the Vuetify ecosystem to improve developer experience and platform capabilities.\n\n### Vuetify Documentation\n\n[Vuetify One subscribers](https://vuetifyjs.com/en/?one=subscribe) can now copy documentation pages as Markdown. This feature allows you to easily extract and reuse documentation content in your projects, enhancing collaboration and knowledge sharing within teams.\n\n![Vuetify documentation copy page as markdown](https://vuetifyjs.b-cdn.net/docs/images/blog/june-2025-update/copy-page-as-markdown.png \"Vuetify documentation copy page as markdown\"){ height=220 }\n\nAll users can now save favorite search results in the Vuetify documentation. Just press `ctrl+k` or `cmd+k` to open the search bar, type your query, and click the star icon next to the search result you want to save. This feature allows you to quickly access frequently used documentation pages, improving your workflow and efficiency.\n\n![Vuetify documentation search favorites](https://vuetifyjs.b-cdn.net/docs/images/blog/june-2025-update/docs-favorites.png \"Vuetify documentation search favorites\"){ height=300 }\n\n**Details:**\n\n* [Copy as Markdown Commit](https://github.com/vuetifyjs/vuetify/commit/dfd8eea1ebd28e6fde702c19b15a33af3620daa4)\n* [Save Search Favorites Commit](https://github.com/vuetifyjs/vuetify/commit/14d5e63f2760db84257f324cfa298a8ce9905903)\n\n### Vuetify One\n\nUpdated default interface to include links to various Vuetify ecosystem sites, making it easier for users to navigate and access resources.\n\n![Vuetify One Platform interface](https://vuetifyjs.b-cdn.net/docs/images/blog/june-2025-update/one-quicklinks.png \"Vuetify One Platform interface\"){ height=300 }\n\n### Vuetify Bin\n\nBins now support **locking**. This new functionality prevents unwanted changes to shared code examples, ensuring that your collaborative work remains intact and consistent.\n\n![Vuetify Bin locking functionality](https://vuetifyjs.b-cdn.net/docs/images/blog/june-2025-update/lock-bin.png \"Vuetify Bin locking functionality\"){ height=250 }\n\nThis feature will soon propagate to the [Vuetify Playground](https://play.vuetifyjs.com/) as well as [Vuetify Studio](https://studio.vuetifyjs.com/).\n\nIt's also now possible to access Bins saved while having an active Vuetify One subscription.\n\n**Details:**\n\n* [Vuetify Bin](https://bin.vuetifyjs.com/)\n\n## Q&A and Upcoming Webinars\n\nJune featured successful community Q&A sessions that provided direct interaction between our core team and the developer community. The feedback and engagement we received were invaluable in shaping our development priorities and understanding real-world usage patterns.\n\n**Missed the Q&A Sessions?** Don't worry! We're planning a comprehensive webinar series launching in July. If you have valuable feedback, suggestions, or questions you'd like to see addressed, keep an eye out for our upcoming webinar announcements. These sessions will provide deep dives into Vuetify best practices, new feature demonstrations, and direct access to core team expertise.\n\nWe encourage community members to [share their input](https://community.vuetifyjs.com/) and help us make these educational sessions as valuable as possible for everyone.\n\n## Sneak Peek: Vuetify 0\n\n<AppFigure :src=\"zerologo\" alt=\"Vuetify 0 logo\" width=\"300\" height=\"auto\" class=\"mx-auto pa-4\" title=\"Vuetify 0 Logo\" />\n\nWe're excited to share an early glimpse into **Vuetify 0** (internally known as v0), our upcoming entry into the unstyled component and composable ecosystem. Building on our experience with Vuetify's component library, we're developing a new approach that delivers the same functionality and developer experience without built-in styling.\n\n**What This Means**: While unstyled components are certainly part of this initiative, Vuetify 0 represents something much more significant - we're publicly releasing our internal composables and framework building tooling. This includes the foundational utilities, patterns, and architectural components that power Vuetify itself, giving developers access to the same building blocks we use internally to create robust UI frameworks:\n\n```ts\nimport { useGroup } from '@vuetify/0'\nimport type { GroupItem, GroupTicket, GroupContext, GroupOptions } from '@vuetify/0'\n\ninterface StepItem extends GroupItem {\n  title: string\n  description?: string\n}\n\ninterface StepTicket extends GroupTicket {\n  step: number\n}\n\ninterface StepOptions extends Omit<GroupOptions, 'multiple'> {}\n\ninterface StepContext extends GroupContext {\n  first: () => void\n  last: () => void\n  next: () => void\n  prev: () => void\n  step: (count: number) => void\n}\n\nconst options: StepOptions = {\n  itemKey: 'step',\n  itemValue: 'value',\n}\n\nexport function useStep<T extends StepContext> (\n  namespace: string,\n  options?: StepOptions,\n) {\n  const [\n    useGroupContext,\n    provideGroupContext,\n    group,\n  ] = useGroup<T>(namespace, options)\n\n  function first () { ... }\n  function last () { ... }\n  function next () { ... }\n  function prev () { ... }\n  function step (count: number) { ... }\n\n  const context = {\n    ...group,\n    first,\n    last,\n    next\n    prev,\n    step,\n  } as T\n\n  return [\n    useGroupContext,\n    provideGroupContext,\n    context,\n  ]\n}\n```\n\nThis project is in early development as we explore the best path forward for providing developers with powerful, accessible, and feature-complete building blocks for custom implementations. We're taking time to ensure we deliver genuine value while maintaining the quality standards you expect from Vuetify.\n\nWe'll share more details as development progresses and look forward to community feedback on this new direction.\n\n## June 2025 Changelog\n\nExpand this section to see the detailed changelog for June 2025, including bug fixes and enhancements.\n\n<details open>\n\n### :rocket: Features\n\n* **VDatePicker:** Disable months and years if not allowed ([#21466](https://github.com/vuetifyjs/vuetify/issues/21466))\n\n### :wrench: Bug Fixes\n\n* **date:** Keep `createDateRange` internal ([#21531](https://github.com/vuetifyjs/vuetify/issues/21531))\n* **date:** Week number for DST ([#21378](https://github.com/vuetifyjs/vuetify/issues/21378))\n* **icons:** Add missing aliases in presets ([#21521](https://github.com/vuetifyjs/vuetify/issues/21521))\n* **VBtn:** Allow text values for letter-spacing Sass variable ([#21602](https://github.com/vuetifyjs/vuetify/issues/21602))\n* **VBtn:** Correct letter-spacing compensation for RTL ([#21574](https://github.com/vuetifyjs/vuetify/issues/21574))\n* **VBtnToggle:** Buttons should be accessible despite overflow ([#21577](https://github.com/vuetifyjs/vuetify/issues/21577))\n* **VCarousel:** Avoid missing progress bar ([#21586](https://github.com/vuetifyjs/vuetify/issues/21586))\n* **VChip:** Disable close button of disabled chip ([#21512](https://github.com/vuetifyjs/vuetify/issues/21512))\n* **VDataTable:** Add missing ARIA label on footer text ([#21508](https://github.com/vuetifyjs/vuetify/issues/21508))\n* **VDataTable:** Columns are not keyboard-accessible ([#20939](https://github.com/vuetifyjs/vuetify/issues/20939))\n* **VDataTableColumn:** On tab focus also show sortable icon ([#21540](https://github.com/vuetifyjs/vuetify/issues/21540))\n* **VDatePicker:** Completely hide days not in weekdays array ([#21624](https://github.com/vuetifyjs/vuetify/issues/21624))\n* **VDatePicker:** Fix autoscroll ([#21556](https://github.com/vuetifyjs/vuetify/issues/21556))\n* **VDatePicker:** Reactive month and year ([#21563](https://github.com/vuetifyjs/vuetify/issues/21563))\n* **VFileInput, VFileUpload:** Handle folders drop ([#21495](https://github.com/vuetifyjs/vuetify/issues/21495))\n* **VList:** Set item value to item if primitive ([#21596](https://github.com/vuetifyjs/vuetify/issues/21596))\n* **VListGroup:** Use item value in ID with return-object ([#20595](https://github.com/vuetifyjs/vuetify/issues/20595))\n* **VNumberInput:** Fix endless increment ([#21610](https://github.com/vuetifyjs/vuetify/issues/21610))\n* **VNumberInput:** Focus after click handler executed ([#21217](https://github.com/vuetifyjs/vuetify/issues/21217))\n* **VOtpInput:** Autofocus on intersect ([#21582](https://github.com/vuetifyjs/vuetify/issues/21582))\n* **VOtpInput:** Trim clipboard text and update focus on finish ([#21342](https://github.com/vuetifyjs/vuetify/issues/21342))\n* **VSelect, VAutocomplete, VCombobox:** Open menu on icon click ([#21617](https://github.com/vuetifyjs/vuetify/issues/21617))\n* **VSelect:** Camelize props only for custom use ([#21544](https://github.com/vuetifyjs/vuetify/issues/21544))\n* **VSelect:** Convert all `itemProps` keys to camelCase ([#21518](https://github.com/vuetifyjs/vuetify/issues/21518))\n* **VSelect:** Reuse compact chip label style ([#21517](https://github.com/vuetifyjs/vuetify/issues/21517))\n* **VSlider:** Apply color to slider label ([#21538](https://github.com/vuetifyjs/vuetify/issues/21538))\n* **VSlider:** Correct step rounding for max value ([#21434](https://github.com/vuetifyjs/vuetify/issues/21434))\n* **VSpeedDial:** Avoid position glitch when reopening menu ([#21451](https://github.com/vuetifyjs/vuetify/issues/21451))\n* **VTabs:** Deselect tab when route is no longer active ([#21569](https://github.com/vuetifyjs/vuetify/issues/21569))\n* **VTextField:** Change order of events for checking input focus state ([#21136](https://github.com/vuetifyjs/vuetify/issues/21136))\n* **VWindow, VTabs:** Don't override cursor in VWindowItem ([#21138](https://github.com/vuetifyjs/vuetify/issues/21138))\n\n### :microscope: Code Refactoring\n\n* **VNumberInput:** Replace touch-action with pointercancel ([#21436](https://github.com/vuetifyjs/vuetify/issues/21436))\n\n### :test_tube: Labs\n\n* **VDateInput:** Use common date range parser ([#21450](https://github.com/vuetifyjs/vuetify/issues/21450))\n* **VFileUpload:** File name not passed correctly ([#21541](https://github.com/vuetifyjs/vuetify/issues/21541))\n* **VTimePicker:** Value not changing on wheel ([#21549](https://github.com/vuetifyjs/vuetify/issues/21549))\n* **VTreeview:** Avoid inaccessible items when overflow ([#21443](https://github.com/vuetifyjs/vuetify/issues/21443))\n* **VTreeview:** Stop click bubbling up on expand icon ([#21083](https://github.com/vuetifyjs/vuetify/issues/21083))\n\n</details>\n\n---\n\n## What's Next\n\nJuly will focus on finalizing the `VCommandPalette` Labs release, expanding `VMaskInput` and `VEditor` component development, and continuing our documentation excellence initiative. We're also actively working on enhanced MCP integration features that allow you to create and access existing Vuetify Bin, Playground, Studio files; in addition to new Studio platform capabilities.\n\nThe team remains committed to delivering stable, performant components while expanding Vuetify's ecosystem to support modern development patterns. Our focus on developer experience, community feedback integration, and systematic improvement processes continues to drive meaningful progress each month.\n\nWe appreciate the community's continued engagement, feedback, and contributions that make these improvements possible. Keep building amazing applications with Vuetify, and don't forget to explore [Vuetify Studio](https://studio.vuetifyjs.com/) for an enhanced development experience.\n\n---\n\n*Stay connected with Vuetify updates through our [GitHub repository](https://github.com/vuetifyjs/vuetify), [Discord community](https://discord.gg/eXubxyJ), and upcoming webinar series announcements.*\n"
  },
  {
    "path": "packages/docs/src/pages/en/blog/may-2025-update.md",
    "content": "---\nlayout: blog\nmeta:\n  title: May 2025 Update\n  description: May delivered significant progress on MCP, VDateInput enhancements, VNumberInput improvements, and ecosystem-wide improvements across Vuetify.\n  keywords: Vuetify May 2025, Model Context Protocol, VDateInput, VNumberInput, Vuetify ecosystem\n---\n\n<script setup>\n  import { useTheme } from 'vuetify'\n\n  const theme = useTheme()\n\n  const mcpLogo = computed(() => {\n    return `https://cdn.vuetifyjs.com/docs/images/logos/vmcp-logo-${theme.current.value.dark ? 'dark' : 'light'}.png`\n  })\n</script>\n\n# May 2025 Update\n\nThis month brings exciting advancements across the Vuetify ecosystem, with major strides in AI integration, component refinements, and developer experience.\n\n---\n\n🖊️ John Leider • 📅 June 6th, 2025\n\n<PromotedEntry />\n\n---\n\n## Expanding Horizons\n\nMay 2025 has been a month of significant progress for Vuetify, with key developments that enhance the framework's capabilities and developer experience. From the official release of [Vuetify MCP](https://github.com/vuetifyjs/mcp) (Model Context Protocol) to substantial improvements in core components like [VDateInput](https://vuetifyjs.com/components/date-inputs/); this month has set the stage for exciting future innovations.\n\n::: success\n\nCool example of the month: [VTreeview File structure](https://play.vuetifyjs.com/playgrounds/AbH9-w) by [Jacek](https://github.com/J-Sek)\n\n:::\n\n---\n\n## Table of Contents\n\n- [Releases](#releases)\n- [Official @vuetify/mcp Release](#official-vuetifymcp-release)\n  - [MCP Vuetify API Keys](#mcp-vuetify-api-keys)\n- [Framework](#framework)\n  - [VDateInput Enhancements](#vdateinput-enhancements)\n  - [VNumberInput](#vnumberinput)\n  - [New Labs Component: VColorInput](#new-labs-component-vcolorinput)\n- [Ecosystem updates](#ecosystem-updates)\n  <!-- - [Vuetify Documentation](#vuetify-documentation) -->\n  - [Vuetify Bin](#vuetify-bin)\n  - [Vuetify Issues Next in Testing](#vuetify-issues-next-in-testing)\n  - [Vuetify Play Enhancements](#vuetify-play-enhancements)\n  - [Vuetify ESLint Config](#vuetify-eslint-config)\n- [May 2025 Changelog](#may-2025-changelog)\n- [What's Next](#whats-next)\n\n---\n\n## Releases\n\nMay continued our steady release cadence with several patch updates addressing bugs and introducing minor enhancements. These releases focused on stability and performance improvements, ensuring that Vuetify remains a reliable foundation for your applications.\n\n![Hero image for latest release notes](https://vuetifyjs.b-cdn.net/docs/images/blog/may-2025-update/may-2025-release-note.png \"Latest release notes hero image\")\n\n**Details:**\n\n- [v3.8.4](https://vuetifyjs.com/getting-started/release-notes/?version=v3.8.4)\n- [v3.8.5](https://vuetifyjs.com/getting-started/release-notes/?version=v3.8.5)\n- [v3.8.6](https://vuetifyjs.com/getting-started/release-notes/?version=v3.8.6)\n- [v3.8.7](https://vuetifyjs.com/getting-started/release-notes/?version=v3.8.7)\n\n## Official @vuetify/mcp Release\n\nAfter months of development and anticipation, we're excited to announce that **@vuetify/mcp** is officially publicly available!\n\n<AppFigure :src=\"mcpLogo\" alt=\"MCP logo\" width=\"300\" height=\"auto\" class=\"mx-auto\" title=\"Vuetify MCP Logo\" />\n\nThis implementation of the [Model Context Protocol](https://modelcontextprotocol.io/introduction) represents a fundamental shift in how developers can interact with Vuetify through AI-powered tools. Now you can provide up-to-date context for features, components, and best practices directly to AI applications, enhancing the accuracy and relevance of AI-generated code.\n\nThe Model Context Protocol (MCP) standardizes how applications provide context to LLMs, functioning like a \"USB-C port for AI applications.\"\n\nSetting up MCP is as simple as running the following in your terminal:\n\n```bash\nnpx -y @vuetify/mcp config\n```\n\nThis single command configures MCP for your development environment, giving AI tools instant access to up-to-date Vuetify context.\n\nOur implementation ensures that AI tools have access to the most up-to-date Vuetify documentation, components, and best practices, eliminating the frustration of outdated or incorrect AI-generated code.\n\nRecent additions to @vuetify/mcp include:\n\n- Improved installation process (one command installation) using `npx -y @vuetify/mcp config`\n- New tools for accessing release notes, directives, frequently asked questions, and more\n- Up next: Application upgrade between major versions\n\n<video width=\"100%\" height=\"auto\" autoplay loop controls>\n  <source src=\"https://vuetifyjs.b-cdn.net/docs/images/blog/may-2025-update/may-2025-%40vuetify-mcp.mp4\" type=\"video/mp4\"></source>\n</video>\n\nThis release marks just the beginning of our MCP journey. We're actively working on expanding its capabilities and integrations, with a focus on making Vuetify development more intuitive and efficient than ever before.\n\n### MCP Vuetify API Keys\n\nLater in June, we'll be introducing a new API key system for MCP managed through Vuetify One. We will be rolling out special **primer** prompts that super charge how agents interact with Vuetify MCP for our Vuetify One subscribers.\n\n**Details:**\n\n- [@vuetify/mcp GitHub repository](https://github.com/vuetifyjs/mcp)\n- [Model Context Protocol documentation](https://modelcontextprotocol.io/introduction)\n\n## Framework\n\nWe continue to make improvements to the core framework, focusing on resolving bugs, iterating on Labs components, and preparing for the next minor release, v3.9.0, which is scheduled for June 2025. Here are a few highlights:\n\n### VDateInput Enhancements\n\nMay brought substantial improvements to several core components, with VDateInput receiving particular attention. The component now features enhanced parsing capabilities, improved validation, and more flexible configuration options. The spotlight for this month is on the [VDateInput](https://vuetifyjs.com/components/date-inputs/).\n\n<video width=\"100%\" height=\"auto\" autoplay loop controls>\n  <source src=\"https://vuetifyjs.b-cdn.net/docs/images/blog/may-2025-update/may-2025-date-input.mp4\" type=\"video/mp4\"></source>\n</video>\n\nFor details on other changes, please check the [May 2025 Changelog](#may-2025-changelog).\n\n**Details:**\n\n- [VDateInput input-format PR #21221](https://github.com/vuetifyjs/vuetify/pull/21221)\n- [VDateInput menu v-model PR #21298](https://github.com/vuetifyjs/vuetify/pull/21298)\n- [VDateInput validationValue PR #21408](https://github.com/vuetifyjs/vuetify/pull/21408)\n- [VDateInput common parser PR #21450](https://github.com/vuetifyjs/vuetify/pull/21450)\n- [VDateInput disable months/years PR #21466](https://github.com/vuetifyjs/vuetify/pull/21466)\n\n### VNumberInput\n\nThis month also saw multiple updates to the [VNumberInput](https://vuetifyjs.com/components/number-inputs/) component, including:\n\n- Improved append inner icon alignment\n- Enhanced touch pointer capture on controls\n- Better extraction of numbers from pasted text\n\n<video width=\"100%\" height=\"auto\" autoplay loop controls>\n  <source src=\"https://vuetifyjs.b-cdn.net/docs/images/blog/may-2025-update/may-2025-number-input.mp4\" type=\"video/mp4\"></source>\n</video>\n\n**Details:**\n\n- [VNumberInput inner spacing PR #21389](https://github.com/vuetifyjs/vuetify/pull/21389)\n- [VNumberInput touch pointer capture PR #21436](https://github.com/vuetifyjs/vuetify/pull/21436)\n- [VNumberInput paste text extraction PR #21263](https://github.com/vuetifyjs/vuetify/pull/21263)\n\n### New Labs Component: VColorInput\n\nThis month also saw the introduction of a new [VColorInput](https://vuetifyjs.com/components/color-inputs/) component in the Labs section. This component provides an intuitive interface for color selection and input, featuring integration with color pickers and text-based hex input. As a Labs component, VColorInput is available for testing and feedback as we refine its API and functionality.\n\nBasic usage is simple:\n\n```html\n<template>\n  <v-color-input v-model=\"color\" label=\"Pick a color\" />\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const color = shallowRef('#1976D2')\n</script>\n```\n\n<video width=\"100%\" height=\"auto\" autoplay loop controls>\n  <source src=\"https://vuetifyjs.b-cdn.net/docs/images/blog/may-2025-update/may-2025-color-input.mp4\" type=\"video/mp4\"></source>\n</video>\n\nThe component supports both picker and text input modes, making it flexible for different use cases.\n\n**Details:**\n\n- [VColorInput introduction PR #20623](https://github.com/vuetifyjs/vuetify/pull/20623)\n\n## Ecosystem updates\n\nThe broader Vuetify ecosystem saw significant advancements in May, with improvements in developer tooling and infrastructure. These updates collectively enhance the developer experience and set the stage for future innovations.\n\n<!--\n### Vuetify Documentation\n\nYou can now save your favorite search results in the Vuetify documentation. Just press `ctrl+k` or `cmd+k` to open the search bar, type your query, and click the star icon next to the search result you want to save. This feature allows you to quickly access frequently used documentation pages, improving your workflow and efficiency.\n\n![Vuetify documentation search favorites](https://cdn.vuetifyjs.com/docs/images/blog/may-2025-update/docs-search-favorites.png \"Vuetify documentation search favorites\"){ height=300 }\n-->\n\n### Vuetify Bin\n\nYou can now choose a language for your code snippets in Vuetify Bin, improving syntax highlighting and code organization. This enhancement makes it easier to share and collaborate on code examples with proper language-specific formatting.\n\n<video width=\"100%\" height=\"auto\" autoplay loop controls>\n  <source src=\"https://vuetifyjs.b-cdn.net/docs/images/blog/may-2025-update/may-2025-vbin.mp4\" type=\"video/mp4\"></source>\n</video>\n\n### Vuetify Play Enhancements\n\nVuetify Play continues to evolve with new features and improvements that make it an even more powerful tool for exploring and experimenting with Vuetify components.\n\n<video width=\"100%\" height=\"auto\" autoplay loop controls>\n  <source src=\"https://vuetifyjs.b-cdn.net/docs/images/blog/may-2025-update/may-2025-vplay.mp4\" type=\"video/mp4\"></source>\n</video>\n\nKey enhancements to Vuetify Play include:\n\n- Added New File Explorer\n- Added Export-to-Vite functionality\n\nThese improvements make Vuetify Play more versatile and user-friendly, enabling developers to more effectively explore, test, and share Vuetify components and configurations.\n\n**Details:** [Vuetify Play](https://play.vuetifyjs.com/)\n\n### Vuetify Issues Next in Testing\n\nWe've published the new issue generator for testing, providing a new interface for creating and managing GitHub issues. Please drop us a line in [Discord](https://community.vuetifyjs.com/) if you have any feedback or suggestions.\n\n**Details:** [Issues-next deployment](https://issues-next.vuetifyjs.com/)\n\n### Vuetify ESLint Config\n\nv4.0.0 of the Vuetify ESLint config is now available, providing updated linting rules and configurations that align with the latest Vuetify standards and best practices. This major version includes improved TypeScript support and enhanced component-specific rules. The config is automatically included when [Creating a new project](https://vuetify.new/) and is recommended for all Vuetify projects.\n\n**Key improvements:**\n\n- Enhanced TypeScript integration\n- Updated component-specific linting rules\n- Better compatibility with modern JavaScript standards\n- Improved accessibility checks\n\n## May 2025 Changelog\n\nExpand this section to see the detailed changelog for May 2025, including bug fixes and enhancements.\n\n<details open>\n\n### 🛠️ Bug Fixes\n\n- **VAutocomplete:** Re-evaluate dirty on external change [#21344](https://github.com/vuetifyjs/vuetify/issues/21344)\n- **VBottomNavigation:** Set inline margin to auto [#21357](https://github.com/vuetifyjs/vuetify/issues/21357)\n- **VDataTable:** Shift-click toggles only selectable rows [#21334](https://github.com/vuetifyjs/vuetify/issues/21334)\n- **VDataTableServer/Virtual:** Add generic headers type [#21327](https://github.com/vuetifyjs/vuetify/issues/21327)\n- **VDialog:** Focus on open only with scrim or retainFocus [#21343](https://github.com/vuetifyjs/vuetify/issues/21343)\n- **VField:** Prevent tab focus on clear icon [#19528](https://github.com/vuetifyjs/vuetify/issues/19528)\n- **VFileInput/VFileUpload:** Fix drop not calling change function [#21182](https://github.com/vuetifyjs/vuetify/issues/21182)\n- **VMenu:** Position relative to `visualViewport` when not zoomed [#21462](https://github.com/vuetifyjs/vuetify/issues/21462)\n- **VNumberInput:** Adjust inner spacing [#21389](https://github.com/vuetifyjs/vuetify/issues/21389)\n- **VNumberInput:** Capture touch pointer on controls [#21436](https://github.com/vuetifyjs/vuetify/issues/21436)\n- **VNumberInput:** Extract number from pasted text [#21263](https://github.com/vuetifyjs/vuetify/issues/21263)\n- **VOverlay:** Validate target positioning [#21350](https://github.com/vuetifyjs/vuetify/issues/21350)\n- **VPagination:** Adapt button width for large values [#21139](https://github.com/vuetifyjs/vuetify/issues/21139)\n- **VSelect:** Keyboard match multiple items with same prefix [#21419](https://github.com/vuetifyjs/vuetify/issues/21419)\n- **VSelect:** Prevent selection on lookup in multiple mode [#21418](https://github.com/vuetifyjs/vuetify/issues/21418)\n- **VSnackbarQueue:** Prevent infinite recursion in message type [#21410](https://github.com/vuetifyjs/vuetify/issues/21410)\n- **VTable:** Remove border radius with top/bottom [#21320](https://github.com/vuetifyjs/vuetify/issues/21320) [#21321](https://github.com/vuetifyjs/vuetify/issues/21321)\n- **VTextField:** Reset field on clear [#21310](https://github.com/vuetifyjs/vuetify/issues/21310)\n- **VTooltip:** Disable transition when set to false [#21268](https://github.com/vuetifyjs/vuetify/issues/21268)\n\n### 🧪 Labs\n\n- **validation:** Resolve global rules [#21267](https://github.com/vuetifyjs/vuetify/issues/21267)\n- **VColorInput:** Introduced new component [#20623](https://github.com/vuetifyjs/vuetify/issues/20623)\n- **VDateInput:** Accept value on hidden picker [#21273](https://github.com/vuetifyjs/vuetify/issues/21273)\n- **VDateInput:** Add `input-format` prop [#21221](https://github.com/vuetifyjs/vuetify/issues/21221)\n- **VDateInput:** Add `update-on` prop [#21249](https://github.com/vuetifyjs/vuetify/issues/21249)\n- **VDateInput:** Expose menu as `v-model` [#21298](https://github.com/vuetifyjs/vuetify/issues/21298)\n- **VDateInput:** Reset model to \\[] when multiple [#21299](https://github.com/vuetifyjs/vuetify/issues/21299)\n- **VDateInput:** Sync placeholder and locale [#21409](https://github.com/vuetifyjs/vuetify/issues/21409)\n- **VDateInput:** Validation sync with `modelValue` [#21408](https://github.com/vuetifyjs/vuetify/issues/21408)\n- **VTimePicker:** Fix SSR hydration mismatch [#21355](https://github.com/vuetifyjs/vuetify/issues/21355)\n\n### 🔄 Reverts\n\n- Revert fix for **VAutocomplete** dirty state change [#21392](https://github.com/vuetifyjs/vuetify/issues/21392)\n\n### 🧩 Code Refactoring\n\n- Resolve directives directly [#21413](https://github.com/vuetifyjs/vuetify/issues/21413)\n- Use `clamp()` utility function [commit](https://github.com/vuetifyjs/vuetify/commit/6784ba7aae029c3e25dd92197c5b5d19feb43430)\n\n</details>\n\n---\n\n## What's Next\n\nJune is all about shipping. MCP gets API keys and primer prompts, v3.9.0 lands with the features we've been building, and we'll start showing off more of the new theming work in the release blog post coming next week. VDateInput will likely graduate from Labs soon, and we've got some performance improvements in the pipeline that I'm excited about.\n\nUntil next month!\n"
  },
  {
    "path": "packages/docs/src/pages/en/blog/november-2025-update.md",
    "content": "---\nlayout: blog\nmeta:\n  title: November 2025 Update\n  description: November delivered Vuetify v3.11.0 with VCalendar and VHotkey promoted from labs, new VTimePicker input variant, VDatePicker MD3 improvements, and significant CLI progress.\n  keywords: Vuetify November 2025, v3.11.0 Harbinger, VCalendar, VHotkey, VTimePicker, VDatePicker MD3\n---\n\n<script setup>\n  import { useTheme } from 'vuetify'\n\n  const theme = useTheme()\n  const mcplogo = computed(() => {\n    return `https://cdn.vuetifyjs.com/docs/images/one/logos/vmcp-logo-${theme.current.value.dark ? 'dark' : 'light'}.png`\n  })\n  const zerologo = computed(() => {\n    return `https://cdn.vuetifyjs.com/docs/images/one/logos/vzero-logo-${theme.current.value.dark ? 'dark' : 'light'}.png`\n  })\n  const vuetifylogo = computed(() => {\n    return `https://cdn.vuetifyjs.com/docs/images/one/logos/vuetify-logo-${theme.current.value.dark ? 'dark' : 'light'}.png`\n  })\n</script>\n\n# November 2025 Update\n\nWelcome to the November 2025 Vuetify update! This month marks a major milestone with the release of **v3.11.0 (Harbinger)**, promoting VCalendar and VHotkey from labs to core, introducing the new VTimePicker input variant, and aligning VDatePicker with Material Design 3 specifications.\n\n![Hero image for November update](https://cdn.vuetifyjs.com/docs/images/blog/november-2025-update/november-hero.png \"November hero image\")\n\n🖊️ John Leider • 📅 December 10th, 2025\n\n<PromotedEntry />\n\n---\n\n## The Harbinger Arrives\n\nNovember was a landmark month for the framework. We shipped **v3.11.0 (Harbinger)** with two components graduating from labs—VCalendar and VHotkey—alongside significant enhancements to date and time pickers that bring them in line with Material Design 3. The **VTimePicker input variant** and **VDatePicker control alignment** represent months of refinement work finally landing in a stable release. Beyond the framework, we made substantial progress on the **Vuetify CLI** with 37 commits laying the groundwork for v0 tooling. J-Sek continued his incredible contribution streak, authoring 14 PRs to the main framework and adding 7+ new templates to Snips. The ecosystem is firing on all cylinders.\n\n::: success\n\nCool example of the month: [v0 Expansion Panel in VPlay](https://vtfy.link/i5LxmQ) by [johnleider](https://github.com/johnleider)\n\n:::\n\n---\n\n## Table of Contents\n\n* [Releases](#releases)\n  * [Key Improvements](#key-improvements)\n* [Ecosystem Spotlight: Vuetify CLI](#ecosystem-spotlight-vuetify-cli)\n* [Framework Updates](#framework-updates)\n  * [Date & Time Picker Enhancements](#date-time-picker-enhancements)\n  * [Component Refinements](#component-refinements)\n  * [In Development](#in-development)\n* [Vuetify MCP: Continued Evolution](#vuetify-mcp-continued-evolution)\n* [Vuetify0: Progress Update](#vuetify0-progress-update)\n* [November 2025 Changelog](#november-2025-changelog)\n* [What's Next](#whats-next)\n\n---\n\n## Releases\n\nNovember delivered seven releases culminating in **v3.11.0 (Harbinger)**, our most feature-rich release since v3.10. Two components graduated from labs to core, and we shipped significant enhancements across date/time pickers, tabs, and overlay components.\n\n![November Releases Banner](https://cdn.vuetifyjs.com/docs/images/blog/november-2025-update/releases.png \"November Releases Banner\")\n\n### Key Improvements\n\n* **VCalendar** and **VHotkey** promoted from labs to core components\n* New **VTimePicker input variant** for inline time entry without the dial interface\n* **VDatePicker MD3 alignment** with updated control variants matching Material Design 3 specifications\n* **VTabs inset prop** for subtle tab designs in dense layouts\n* **VTextarea max-height prop** for controlled textarea growth\n* **VSelect auto-select-first** for automatic first-item highlighting\n* Theme **layers option** for advanced CSS cascade control\n\nView the complete list of changes in the [Full Changelog](#november-2025-changelog)\n\n**Details:**\n\n* [v3.10.9](https://vuetifyjs.com/getting-started/release-notes/?version=v3.10.9)\n* [v3.10.10](https://vuetifyjs.com/getting-started/release-notes/?version=v3.10.10)\n* [v3.10.11](https://vuetifyjs.com/getting-started/release-notes/?version=v3.10.11)\n* [v3.10.12](https://vuetifyjs.com/getting-started/release-notes/?version=v3.10.12)\n* [v3.11.0](https://vuetifyjs.com/getting-started/release-notes/?version=v3.11.0)\n\n---\n\n## Ecosystem Spotlight: Vuetify CLI\n\nNovember saw intensive development on the **Vuetify CLI**, with 37 commits laying the foundation for v0 tooling and developer workflows. While not yet released, this work represents a significant investment in the developer experience for Vuetify 4.0 and beyond.\n\nThe CLI will provide streamlined project scaffolding, component generation, and integration with the broader Vuetify ecosystem including v0 composables and the MCP server. More details coming as we approach the initial release.\n\n**Also this month:**\n\n* **Vuetify Bin** received real-time collaboration features\n* **Vuetify Snips** added 7+ new templates across pricing, buttons, feedback cards, and chat components\n* **Vuetify Play** and **Studio** improved user preference persistence\n\n**Details:**\n\n* [Vuetify Bin](https://bin.vuetifyjs.com/)\n* [Vuetify Snips](https://snips.vuetifyjs.com/)\n* [Vuetify Play](https://play.vuetifyjs.com/)\n\n---\n\n## Framework Updates\n\n<AppFigure :src=\"vuetifylogo\" alt=\"Vuetify logo\" width=\"200\" height=\"auto\" class=\"mx-auto my-4\" title=\"Vuetify Logo\" />\n\nNovember's framework work centered on date/time picker improvements and component polish. J-Sek delivered an outstanding 14 PRs, driving many of the enhancements below.\n\n### Date & Time Picker Enhancements\n\nThe date and time picker components received significant attention this month, bringing them closer to Material Design 3 specifications and adding long-requested features.\n\n**VTimePicker Input Variant**\n\nA new input variant allows users to type time values directly without using the dial interface—perfect for power users and keyboard-first workflows.\n\n![VTimePicker Input Variant](https://cdn.vuetifyjs.com/docs/images/blog/november-2025-update/vtimepicker-input.png \"VTimePicker Input Variant\")\n\n**VDatePicker MD3 Controls**\n\nControl variants have been aligned with Material Design 3, providing a more polished and consistent appearance.\n\n<!-- replace height with auto before releasing -->\n<video width=\"100%\" height=\"300\" loop controls class=\"mb-4\">\n  <source src=\"https://cdn.vuetifyjs.com/docs/images/blog/november-2025-update/vdatepicker-md3.mp4\" type=\"video/mp4\"></source>\n</video>\n\n**Details:**\n\n* [VTimePicker input variant PR#21601](https://github.com/vuetifyjs/vuetify/pull/21601)\n* [VDatePicker MD3 alignment PR#21589](https://github.com/vuetifyjs/vuetify/pull/21589)\n* [VDatePicker landscape mode PR#22305](https://github.com/vuetifyjs/vuetify/pull/22305)\n* [VDateInput min/max fix PR#22295](https://github.com/vuetifyjs/vuetify/pull/22295)\n\n### Component Refinements\n\n**Navigation & Layout**\n\n* **VTabs**: New `inset` prop for subtle tab designs, plus slider transition improvements\n* **VOverlay**: Added `viewport-margin` prop for better positioning control\n* **VNavigationDrawer**: New `retain-focus` prop to control focus behavior\n\n<!-- replace height with auto before releasing -->\n<video width=\"100%\" height=\"300\" loop controls class=\"mb-4\">\n  <source src=\"https://cdn.vuetifyjs.com/docs/images/blog/november-2025-update/vtabs-slider.mp4\" type=\"video/mp4\"></source>\n</video>\n\n**Form Components**\n\n* **VTextarea**: Added `max-height` prop for controlled growth\n* **VSelect**: New `auto-select-first` prop and improved chip itemProps handling\n* **VCombobox**: Create new items when pasting with line breaks\n\n**Data & Display**\n\n* **VTreeview**: Significant performance improvements for large trees\n* **VList**: New `prepend-gap` and `indent` props for flexible spacing\n* **VBreadcrumbs**: Props and width can now be passed to items\n\n**Theming**\n\n* New `layers` option for advanced CSS cascade control\n\n**Details:**\n\n* [VTabs inset PR#22221](https://github.com/vuetifyjs/vuetify/pull/22221)\n* [VTabs slider transition PR#19556](https://github.com/vuetifyjs/vuetify/pull/19556)\n* [VOverlay viewport-margin PR#22243](https://github.com/vuetifyjs/vuetify/pull/22243)\n* [VNavigationDrawer retain-focus PR#22106](https://github.com/vuetifyjs/vuetify/pull/22106)\n* [VTextarea max-height PR#22286](https://github.com/vuetifyjs/vuetify/pull/22286)\n* [VSelect auto-select-first PR#22312](https://github.com/vuetifyjs/vuetify/pull/22312)\n* [VCombobox line breaks PR#22304](https://github.com/vuetifyjs/vuetify/pull/22304)\n* [VTreeview performance PR#22255](https://github.com/vuetifyjs/vuetify/pull/22255)\n* [VList prepend-gap/indent PR#20616](https://github.com/vuetifyjs/vuetify/pull/20616)\n* [VBreadcrumbs props PR#22213](https://github.com/vuetifyjs/vuetify/pull/22213)\n* [Theme layers PR#22215](https://github.com/vuetifyjs/vuetify/pull/22215)\n\n---\n\n## Vuetify MCP: Continued Evolution\n\n<AppFigure :src=\"mcplogo\" alt=\"Vuetify MCP logo\" width=\"200\" height=\"auto\" class=\"mx-auto my-4\" title=\"Vuetify MCP Logo\" />\n\nNovember brought four releases to the Vuetify MCP server (v0.2.0 through v0.2.3), continuing to refine the AI-powered development experience.\n\n### What's New\n\n**Stability Improvements**: Multiple releases focused on reliability and edge case handling for the HTTP transport introduced in October.\n\n**Documentation Enhancements**: Improved tool descriptions and response formatting for better AI assistant integration.\n\n### Getting Started\n\nTo use the hosted MCP server with Claude Desktop or other MCP clients:\n\n```json\n{\n  \"mcpServers\": {\n    \"vuetify\": {\n      \"url\": \"https://mcp.vuetifyjs.com/mcp\"\n    }\n  }\n}\n```\n\n**Details:**\n\n* [Vuetify MCP GitHub Repository](https://github.com/vuetifyjs/mcp)\n* [Model Context Protocol Documentation](https://modelcontextprotocol.io/)\n\n---\n\n## Vuetify0: Progress Update\n\n<AppFigure :src=\"zerologo\" alt=\"Vuetify0 logo\" width=\"200\" height=\"auto\" class=\"mx-auto my-4\" title=\"Vuetify0 Logo\" />\n\nNovember was our most active month yet for Vuetify0, with 109 commits and 5 releases (v0.0.10 through v0.0.14). The focus was on performance optimization and type safety improvements.\n\n![Vuetify0 Type Safety](https://cdn.vuetifyjs.com/docs/images/blog/november-2025-update/v0.png \"Vuetify0 Type Safety\")\n\n**Performance Optimizations**\n\nWe implemented deferred reindexing for registry unregister operations, significantly improving performance when components mount and unmount rapidly.\n\n**Type Safety Improvements**\n\nThe `RegistryTicket.value` is now generic, providing better type inference and IntelliSense support when working with registered items.\n\n```ts\nimport { useRegistry } from '@vuetify/v0'\nimport type { RegistryTicket } from '@vuetify/v0'\n\ninterface User {\n  name: string\n  email: string\n}\n\n// Value type flows through the registry\nconst registry = useRegistry<RegistryTicket<User>>()\n\nconst ticket = registry.register({\n  id: 'user-1',\n  value: { name: 'John', email: 'john@vuetifyjs.com' }\n})\n\n// ticket.value is typed as User\nconsole.log(ticket.value.name) // ✓ TypeScript knows this is a string\n```\n\nDecember will focus on expanding the component library and preparing integration paths with the main Vuetify framework.\n\n**Details:**\n\n* [Vuetify0 Documentation](https://0.vuetifyjs.com/)\n* [Performance optimization PR#48](https://github.com/vuetifyjs/0/pull/48)\n* [Type safety PR#53](https://github.com/vuetifyjs/0/pull/53)\n\n---\n\n## November 2025 Changelog\n\nThe following section provides an overview of the changes made in November 2025, including new features, bug fixes, and enhancements across the Vuetify framework.\n\n**Key Improvements:**\n\n* VCalendar and VHotkey promoted from labs to core\n* VTimePicker input variant for direct time entry\n* VDatePicker MD3 control alignment\n* VTabs inset prop and slider transitions\n* VTreeview performance optimizations for large trees\n* Theme layers option for CSS cascade control\n\n**Expand** this section to see the detailed changelog for November 2025:\n\n<details>\n\n### :rocket: Features\n\n* **flex:** add justify-items utilities ([#22346](https://github.com/vuetifyjs/vuetify/issues/22346)) ([pgalhardo](https://github.com/pgalhardo))\n* **VBreadcrumbs:** pass props and width to items ([#22213](https://github.com/vuetifyjs/vuetify/issues/22213)) ([J-Sek](https://github.com/J-Sek))\n* **VCombobox:** create new items when pasting with line breaks ([#22304](https://github.com/vuetifyjs/vuetify/issues/22304)) ([ikushum](https://github.com/ikushum))\n* **VDatePicker:** align control variants with MD3 ([#21589](https://github.com/vuetifyjs/vuetify/issues/21589)) ([J-Sek](https://github.com/J-Sek))\n* **VList:** add `prepend-gap` and `indent` props ([#20616](https://github.com/vuetifyjs/vuetify/issues/20616)) ([yuwu9145](https://github.com/yuwu9145))\n* **VNavigationDrawer, VOverlay:** add `retain-focus` prop ([#22106](https://github.com/vuetifyjs/vuetify/issues/22106)) ([J-Sek](https://github.com/J-Sek))\n* **VOverlay:** add `viewport-margin` prop ([#22243](https://github.com/vuetifyjs/vuetify/issues/22243)) ([J-Sek](https://github.com/J-Sek))\n* **VSelect:** add `auto-select-first` prop ([#22312](https://github.com/vuetifyjs/vuetify/issues/22312)) ([J-Sek](https://github.com/J-Sek))\n* **VSelect:** apply compatible itemProps to chips ([#22339](https://github.com/vuetifyjs/vuetify/issues/22339)) ([KaelWD](https://github.com/KaelWD))\n* **VStepper:** add new item-props prop ([#20651](https://github.com/vuetifyjs/vuetify/issues/20651)) ([johnleider](https://github.com/johnleider))\n* **VTabs:** add `inset` prop ([#22221](https://github.com/vuetifyjs/vuetify/issues/22221)) ([J-Sek](https://github.com/J-Sek))\n* **VTabs:** add new prop, slider transition ([#19556](https://github.com/vuetifyjs/vuetify/issues/19556)) ([johnleider](https://github.com/johnleider))\n* **VTextarea:** add `max-height` prop ([#22286](https://github.com/vuetifyjs/vuetify/issues/22286)) ([J-Sek](https://github.com/J-Sek))\n* **VTimePicker:** input variant ([#21601](https://github.com/vuetifyjs/vuetify/issues/21601)) ([J-Sek](https://github.com/J-Sek))\n* **theme:** add layers option ([#22215](https://github.com/vuetifyjs/vuetify/issues/22215)) ([Niki2k1](https://github.com/Niki2k1))\n* **typography:** add font-weight semibold helper class ([#20586](https://github.com/vuetifyjs/vuetify/issues/20586)) ([FraCata00](https://github.com/FraCata00))\n\n### :wrench: Bug Fixes\n\n* **v-tooltip:** prevent showing empty tooltip ([#22347](https://github.com/vuetifyjs/vuetify/issues/22347)) ([Haviles04](https://github.com/Haviles04))\n* **VAvatar:** update background variable to use RGB format ([#22310](https://github.com/vuetifyjs/vuetify/issues/22310)) ([juanjcardona13](https://github.com/juanjcardona13))\n* **VBtnToggle:** remove semicolon from Sass ([#22293](https://github.com/vuetifyjs/vuetify/issues/22293)) ([methompson](https://github.com/methompson))\n* **VBtnToggle:** render selected in forced-colors mode ([#22279](https://github.com/vuetifyjs/vuetify/issues/22279)) ([06b](https://github.com/06b))\n* **VCalendar:** calculate week numbers using current locale ([#22341](https://github.com/vuetifyjs/vuetify/issues/22341)) ([J-Sek](https://github.com/J-Sek))\n* **VCalendar:** correct interval and event offset with custom firstTime ([#22343](https://github.com/vuetifyjs/vuetify/issues/22343)) ([KaelWD](https://github.com/KaelWD))\n* **VCalendar:** day button font size and no active state ([#22336](https://github.com/vuetifyjs/vuetify/issues/22336)) ([J-Sek](https://github.com/J-Sek))\n* **VDateInput:** min/max with built-in adapter ([#22295](https://github.com/vuetifyjs/vuetify/issues/22295)) ([J-Sek](https://github.com/J-Sek))\n* **VDatePicker:** support landscape mode ([#22305](https://github.com/vuetifyjs/vuetify/issues/22305)) ([ikushum](https://github.com/ikushum))\n* **VField:** hide progress border in forced-colors mode ([#22316](https://github.com/vuetifyjs/vuetify/issues/22316)) ([06b](https://github.com/06b))\n* **VField:** remove details prop from makeVFieldProps ([#22268](https://github.com/vuetifyjs/vuetify/issues/22268)) ([pgalhardo](https://github.com/pgalhardo))\n* **VHotkey:** inline alignment, sizing consistency, slash separator ([#22321](https://github.com/vuetifyjs/vuetify/issues/22321)) ([J-Sek](https://github.com/J-Sek))\n* **VInfiniteScroll:** hide side element when empty ([#21749](https://github.com/vuetifyjs/vuetify/issues/21749)) ([J-Sek](https://github.com/J-Sek))\n* **VList:** correct styles for spacing with `nav` prop ([#22254](https://github.com/vuetifyjs/vuetify/issues/22254)) ([J-Sek](https://github.com/J-Sek))\n* **VMaskInput:** Fixes error when mask input is cleared ([#22176](https://github.com/vuetifyjs/vuetify/issues/22176)) ([ikushum](https://github.com/ikushum))\n* **VRating:** correct keyboard controls ([#22314](https://github.com/vuetifyjs/vuetify/issues/22314)) ([J-Sek](https://github.com/J-Sek))\n* **VSelect:** Use hidden select for native form submissions ([#22330](https://github.com/vuetifyjs/vuetify/issues/22330)) ([ikushum](https://github.com/ikushum))\n* **VTab:** render selected in forced-colors mode ([#22271](https://github.com/vuetifyjs/vuetify/issues/22271)) ([06b](https://github.com/06b))\n* **VTreeview:** faster interactions with large trees ([#22255](https://github.com/vuetifyjs/vuetify/issues/22255)) ([J-Sek](https://github.com/J-Sek))\n\n### :test_tube: Labs\n\n* **VCalendar:** promoted to core component\n* **VHotkey:** promoted to core component\n\n</details>\n\n## What's Next{ .mt-4 }\n\nDecember will see continued refinement of v3.11.x as we stabilize the new features and address community feedback. Work on VCommandPalette progresses toward an initial labs release, and we're expanding the v0 library with additional headless primitives.\n\nThe Vuetify CLI is approaching its first public release, which will streamline project setup and component generation for both Vuetify 3 and the upcoming v0-based workflows. We're also planning end-of-year webinars covering the v3.11 release highlights and a preview of what's coming in 2026.\n\nThank you for being part of the Vuetify community. See you in December!\n\n---\n\n*Stay connected with Vuetify updates through our [GitHub repository](https://github.com/vuetifyjs/vuetify), [Discord community](https://discord.gg/vuetify), and follow [@vuetifyjs](https://twitter.com/vuetifyjs) for the latest announcements. The best is yet to come!*\n"
  },
  {
    "path": "packages/docs/src/pages/en/blog/october-2025-update.md",
    "content": "---\nlayout: blog\nmeta:\n  title: October 2025 Update\n  description: October focused on refinement, delivering focus trap improvements, component enhancements, and v0 composables progress for v3.11 and v4.0.\n  keywords: Vuetify October 2025, v3.11 LTS, Focus trap, Component enhancements, v0 composables, v4.0\n---\n\n<script setup>\n  import { useTheme } from 'vuetify'\n\n  const theme = useTheme()\n  const linklogo = computed(() => {\n    return `https://cdn.vuetifyjs.com/docs/images/one/logos/vlink-logo-${theme.current.value.dark ? 'dark' : 'light'}.svg`\n  })\n  const mcplogo = computed(() => {\n    return `https://cdn.vuetifyjs.com/docs/images/one/logos/vmcp-logo-${theme.current.value.dark ? 'dark' : 'light'}.svg`\n  })\n  const zerologo = computed(() => {\n    return `https://cdn.vuetifyjs.com/docs/images/one/logos/vzero-logo-${theme.current.value.dark ? 'dark' : 'light'}.svg`\n  })\n  const vuetifylogo = computed(() => {\n    return `https://cdn.vuetifyjs.com/docs/images/one/logos/vuetify-logo-${theme.current.value.dark ? 'dark' : 'light'}.png`\n  })\n</script>\n\n# October 2025 Update\n\nWelcome to the October 2025 Vuetify update! This month, our team focused on refinement and reliability, delivering significant **focus trap improvements** across multiple components and advancing key features in development.\n\n![Hero image for October update](https://cdn.vuetifyjs.com/docs/images/blog/october-2025-update/october-hero.png \"October hero image\"){ height=112 }\n\n🖊️ John Leider • 📅 November 11th, 2025\n\n<PromotedEntry />\n\n---\n\n## Moving along\n\nOctober's development cycle focused on polish and developer experience. We delivered critical accessibility improvements with enhanced focus trap functionality, optimized VDataTable performance for large datasets, and refined components across the board. The month also saw the launch of **Vuetify Link**, our new URL shortening service, and significant updates to the **Vuetify MCP server** with HTTP transport support, making it easier than ever to integrate Vuetify's documentation and API intelligence into AI-powered development workflows. We also made substantial progress on our **v0 composables**, laying the groundwork for the upcoming Vuetify 4.0 release.\n\n::: success\n\nCool example of the month: [VTreeview footer](https://play.vuetifyjs.com/playgrounds/foNl1A) by [J-Sek](https://github.com/J-Sek)\n\n:::\n\n---\n\n## Table of Contents\n\n* [Releases](#releases)\n  * [Key Improvements](#key-improvements)\n* [Ecosystem Spotlight: Vuetify Link](#ecosystem-spotlight-vuetify-link)\n* [Framework Updates](#framework-updates)\n  * [Focus Trap Enhancements](#focus-trap-enhancements)\n  * [Component Refinements](#component-refinements)\n  * [In Development](#in-development)\n* [Vuetify MCP: HTTP Transport Support](#vuetify-mcp-http-transport-support)\n* [Vuetify0: Progress Update](#vuetify0-progress-update)\n* [October 2025 Changelog](#october-2025-changelog)\n* [What's Next](#whats-next)\n\n---\n\n## Releases\n\nOctober delivered five releases focused on stability, performance, and accessibility. We merged numerous bug fixes across components, improved focus trap behavior, enhanced form field handling, and optimized performance for large data sets.\n\n![October Releases Banner](https://cdn.vuetifyjs.com/docs/images/blog/october-2025-update/releases.png \"October Releases Banner\")\n\n### Key Improvements\n\n* Enhanced focus trap functionality across VDialog and VMenu with better invisible/inert element handling\n* Performance optimizations for VDataTable with select-all improvements and reduced lag in large datasets\n* Multiple VMenu fixes improving keyboard navigation, scroll behavior, and ARIA attributes\n* VCombobox and VAutocomplete refinements with consistent transitions and better open/close behavior\n* Accessibility improvements with forced-colors mode support for multiple components\n* Labs components updates including VCalendar, VDateInput, and VMaskInput enhancements\n\nView the complete list of changes in the [Full Changelog](#october-2025-changelog)\n\n**Details:**\n\n* [v3.10.4](https://vuetifyjs.com/getting-started/release-notes/?version=v3.10.4)\n* [v3.10.5](https://vuetifyjs.com/getting-started/release-notes/?version=v3.10.5)\n* [v3.10.6](https://vuetifyjs.com/getting-started/release-notes/?version=v3.10.6)\n* [v3.10.7](https://vuetifyjs.com/getting-started/release-notes/?version=v3.10.7)\n* [v3.10.8](https://vuetifyjs.com/getting-started/release-notes/?version=v3.10.8)\n\n---\n\n## Ecosystem Spotlight: Vuetify Link\n\n<AppFigure :src=\"linklogo\" alt=\"Vuetify Link logo\" width=\"200\" height=\"auto\" class=\"mx-auto my-4\" title=\"Vuetify Link Logo\" />\n\nSharing code examples and playground demos is fundamental to how our community learns and collaborates. **Vuetify Link** is now live—a URL shortening service purpose-built for the Vuetify ecosystem. It makes sharing your playgrounds, reporting issues with reproducible examples, and showcasing your latest components effortless.\n\n<video width=\"100%\" height=\"auto\" loop controls class=\"mb-4\">\n  <source src=\"https://cdn.vuetifyjs.com/docs/images/blog/october-2025-update/vuetify-link.mp4\" type=\"video/mp4\"></source>\n</video>\n\nCreating links is free for everyone. Vuetify One users get additional features such as redirect timer, password protection, and custom slug generation.\n\n**Details:**\n\n* [Vuetify Link](https://link.vuetifyjs.com/)\n\n---\n\n## Framework Updates\n\n<AppFigure :src=\"vuetifylogo\" alt=\"Vuetify logo\" width=\"200\" height=\"auto\" class=\"mx-auto my-4\" title=\"Vuetify Logo\" />\n\nOctober was all about refinement and reliability. Our team focused on enhancing existing components with new features and improving the overall developer experience across the framework.\n\n### Focus Trap Enhancements\n\nWe've made significant improvements to focus trap functionality across components, ensuring better keyboard navigation and accessibility compliance. These enhancements improve the experience for users relying on keyboard navigation and assistive technologies.\n\n**Details:**\n\n* [PR#22105](https://github.com/vuetifyjs/vuetify/pull/22105)\n* [PR#22044](https://github.com/vuetifyjs/vuetify/pull/22044)\n\n### Component Refinements\n\nThe team has been working diligently to enhance component reliability and functionality:\n\n**Navigation & Selection**\n\n* **VTreeview & VList**: Improved node selection reliability for more predictable behavior in complex tree structures\n* **VBreadcrumbs**: Added `item-props` support to enable text truncation for long breadcrumb items\n\n**Form Components**\n\n* **VAutocomplete & VCombobox**: Refined menu transitions and resolved edge-case issues\n* **VMenu**: Various fixes improving stability and user experience\n\n**Data & Display**\n\n* **VTreeview**: New footer slot plus minor bug fixes\n* **VDataTable**: Multi-sort enhancements for more powerful data manipulation\n\n**Details:**\n\n* [VTreeview PR#22130](https://github.com/vuetifyjs/vuetify/pull/22130)\n* [VBreadcrumbs PR#22213](https://github.com/vuetifyjs/vuetify/pull/22213)\n* [VAutocomplete/VCombobox PR#22144](https://github.com/vuetifyjs/vuetify/pull/22144)\n* [VMenu PR#22242](https://github.com/vuetifyjs/vuetify/pull/22242)\n* [VMenu PR#22240](https://github.com/vuetifyjs/vuetify/pull/22240)\n* [VDataTable PR#22133](https://github.com/vuetifyjs/vuetify/pull/22133)\n\n### In Development\n\nWe have multiple new features and components in active development that are continuing to make progress:\n\n#### VCommandPalette\n\n**VCommandPalette Development**: Work continues on scoping and developing this highly-requested component. Command-driven interfaces are perfect for power users and keyboard-first workflows, and we're excited to bring this pattern to Vuetify applications.\n\n![VCommandPalette Component](https://cdn.vuetifyjs.com/docs/images/blog/october-2025-update/vcommandpalette.png \"VCommandPalette Component\")\n\n#### VTabs Enhancements\n\nWe're working on a new **inset variant** for `VTabs`. This variant provides a more subtle tab design that works beautifully in dense layouts and secondary navigation contexts.\n\n<video width=\"100%\" height=\"auto\" loop controls class=\"mb-4\">\n  <source src=\"https://cdn.vuetifyjs.com/docs/images/blog/october-2025-update/inset-tabs.mp4\" type=\"video/mp4\"></source>\n</video>\n\n**Details:**\n\n* [VCommandPalette PR#22217](https://github.com/vuetifyjs/vuetify/pull/22217)\n* [VList a11y PR#21444](https://github.com/vuetifyjs/vuetify/pull/21444)\n* [VTabs inset variant PR#22221](https://github.com/vuetifyjs/vuetify/pull/22221)\n\n---\n\n## Vuetify MCP: HTTP Transport Support\n\n<AppFigure :src=\"mcplogo\" alt=\"Vuetify MCP logo\" width=\"200\" height=\"auto\" class=\"mx-auto my-4\" title=\"Vuetify MCP Logo\" />\n\nOctober brought significant updates to the **Vuetify MCP (Model Context Protocol) server**, expanding how developers can integrate Vuetify's comprehensive documentation and API intelligence into AI-powered coding assistants like Claude Code, Cline, and other MCP-compatible tools.\n\n### What's New\n\n**HTTP Transport Support**: The Vuetify MCP server now supports HTTP transport in addition to the standard stdio transport. This makes it easier to deploy and connect to the server across different environments and use cases.\n\n**Official Hosted Server**: We've launched an official hosted MCP server at **[https://mcp.vuetifyjs.com](https://mcp.vuetifyjs.com)**, allowing you to access Vuetify's documentation, component APIs, installation guides, and feature documentation without running a local server.\n\n### Getting Started\n\nTo use the hosted MCP server with Claude Desktop or other MCP clients, add the following to your MCP configuration:\n\n```json\n{\n  \"mcpServers\": {\n    \"vuetify\": {\n      \"url\": \"https://mcp.vuetifyjs.com/mcp\"\n    }\n  }\n}\n```\n\nThe Vuetify MCP server provides AI assistants with direct access to:\n\n* **Component APIs**: Detailed prop, slot, and event documentation for all Vuetify components\n* **Directive APIs**: Complete directive documentation including v-ripple, v-scroll, and more\n* **Installation Guides**: Platform-specific setup instructions for Vite, Nuxt, Laravel, and others\n* **Feature Guides**: In-depth documentation on theming, internationalization, accessibility, and more\n* **Release Notes**: Version-specific changelogs and migration information\n* **FAQ**: Frequently asked questions and common solutions\n\nThis integration enables your AI coding assistant to provide accurate, up-to-date Vuetify guidance directly within your development workflow.\n\n**Details:**\n\n* [Vuetify MCP GitHub Repository](https://github.com/vuetifyjs/mcp)\n* [HTTP Transport Commit](https://github.com/vuetifyjs/mcp/commit/66a3802951294f7610562d949dbdd51db879d50a)\n* [Model Context Protocol Documentation](https://modelcontextprotocol.io/)\n\n---\n\n## Vuetify0: Progress Update\n\n<AppFigure :src=\"zerologo\" alt=\"Vuetify0 logo\" width=\"200\" height=\"auto\" class=\"mx-auto my-4\" title=\"Vuetify0 Logo\" />\n\nOctober was all about testing and iteration and we covered a lot of ground. All composables received a tuning pass to improve type safety and Intellisense support:\n\n![TypeScript Intellisense](https://cdn.vuetifyjs.com/docs/images/blog/october-2025-update/v0.png \"Vuetify0 TypeScript Intellisense\")\n\nAll composables now follow consistent naming conventions and patterns and we are now beginning to iterate on the component variations of each composable (where applicable). These components will marry various composables together to provide full-featured UI elements built on the v0 foundation.\n\nWe've also started to add interactive examples to the documentation site to showcase usage patterns and best practices. One component that received a lot of work last month was the **ExpansionPanel** which is now available as of the [v0.0.10](https://github.com/vuetifyjs/0/releases/tag/v0.0.10) release.\n\n```html\n<script lang=\"ts\" setup>\n  import { ExpansionPanel } from '@vuetify/v0'\n</script>\n\n<template>\n  <ExpansionPanel.Root>\n    <ExpansionPanel.Item>\n      <ExpansionPanel.Activator>\n        Click me\n      </ExpansionPanel.Activator>\n\n      <ExpansionPanel.Content>\n        Hello from the expansion panel content!\n      </ExpansionPanel.Content>\n    </ExpansionPanel.Item>\n  </ExpansionPanel.Root>\n</template>\n```\n\nNovember will focus on continuing to build out components based on the v0 composables, along with additional documentation and examples as we prepare for Vuetify integration.\n\n**Details:**\n\n* [Vuetify0 Documentation](https://0.vuetifyjs.com/)\n* [ExpansionPanel](https://0.vuetifyjs.com/components/expansion-panel/)\n\n---\n\n## October 2025 Changelog\n\nThe following section provides an overview of the changes made in October 2025, including new features, bug fixes, and enhancements across the Vuetify framework.\n\n**Key Improvements:**\n\n* Focus trap enhancements: Better keyboard navigation, invisible/inert element handling, and aria-owns support\n* Performance optimizations: Select-all optimization in VDataTable, reduced lag with large datasets\n* Form field reliability: Fixed duplicated emits, improved validation rules, better field control refs\n* Component polish: VMenu scroll/focus fixes, VCombobox/VAutocomplete transition improvements, VDatePicker range fixes\n* Accessibility: Forced-colors mode support for VBadge, VListItem, VSkeletonLoader, and VIconBtn\n* Labs updates: VCalendar scrolling fixes, VMaskInput inheritance, VDateInput min/max support\n\n**Expand** this section to see the detailed changelog for October 2025:\n\n<details>\n\n### :rocket: Features\n\n* **locationStrategies:** support CSS zoom ([#21878](https://github.com/vuetifyjs/vuetify/issues/21878)) ([32242a3](https://github.com/vuetifyjs/vuetify/commit/32242a353b1313b35f18bfc7c0ac7a72ed2196bb)), closes [#20719](https://github.com/vuetifyjs/vuetify/issues/20719)\n* **VCombobox:** add `always-filter` prop ([#22093](https://github.com/vuetifyjs/vuetify/issues/22093)) ([8853f4d](https://github.com/vuetifyjs/vuetify/commit/8853f4da7a6600af3587dcc54f18e5b06a2d1ff9)), closes [#22060](https://github.com/vuetifyjs/vuetify/issues/22060)\n\n### :wrench: Bug Fixes\n\n* catch querySelector errors in focusableChildren() ([ae2af38](https://github.com/vuetifyjs/vuetify/commit/ae2af38f982dc83c662bfa84ce7189c4c08ff16b)), closes [#22238](https://github.com/vuetifyjs/vuetify/issues/22238)\n* **group:** avoid errors when comparing recursive items ([#22246](https://github.com/vuetifyjs/vuetify/issues/22246)) ([8ac9c67](https://github.com/vuetifyjs/vuetify/commit/8ac9c67a50653147b9d1003546a45cfea206aab3)), closes [#19322](https://github.com/vuetifyjs/vuetify/issues/19322)\n* **nested:** avoid console warnings when updating items order ([#21987](https://github.com/vuetifyjs/vuetify/issues/21987)) ([1dac082](https://github.com/vuetifyjs/vuetify/commit/1dac0826eea90668bf760ea8c43a01a092c6f28e)), closes [#20934](https://github.com/vuetifyjs/vuetify/issues/20934)\n* **nested:** selection should react to items changes ([#22236](https://github.com/vuetifyjs/vuetify/issues/22236)) ([6bcdbea](https://github.com/vuetifyjs/vuetify/commit/6bcdbea3800c03bdf3ae736969c423bcd7e54672)), closes [#21733](https://github.com/vuetifyjs/vuetify/issues/21733)\n* **validation:** 'number' rule should accept 0 and empty string ([#22204](https://github.com/vuetifyjs/vuetify/issues/22204)) ([1b52724](https://github.com/vuetifyjs/vuetify/commit/1b52724dfeb17c6fb6dd6e50002dec33994ecd51)), closes [#22192](https://github.com/vuetifyjs/vuetify/issues/22192)\n* **validation:** correct translation template arguments ([#22146](https://github.com/vuetifyjs/vuetify/issues/22146)) ([a8e17c9](https://github.com/vuetifyjs/vuetify/commit/a8e17c9966c6333d30c092b3c931ab6afff2b03a))\n* **VBadge:** background highlight in forced-colors mode ([#22148](https://github.com/vuetifyjs/vuetify/issues/22148)) ([65f6bb7](https://github.com/vuetifyjs/vuetify/commit/65f6bb708b6cdc72c4a0e2828ef3d917f2a78559))\n* **VBtn:** set group state for non-router links ([4eeb514](https://github.com/vuetifyjs/vuetify/commit/4eeb514c675b2eeef16f994cac7d37fe1a516b65)), closes [#22085](https://github.com/vuetifyjs/vuetify/issues/22085)\n* **VChipGroup:** disable auto-scroll to the last selected ([360203a](https://github.com/vuetifyjs/vuetify/commit/360203aa3e97d84d2aea76f46a6a2062b7a7b879)), closes [#22223](https://github.com/vuetifyjs/vuetify/issues/22223)\n* **VChipGroup:** support `center-active` ([#22050](https://github.com/vuetifyjs/vuetify/issues/22050)) ([4a95697](https://github.com/vuetifyjs/vuetify/commit/4a95697c58665ed53b7c23ab6864318b59a371e9)), closes [#22046](https://github.com/vuetifyjs/vuetify/issues/22046)\n* **VCombobox:** open menu when `chips` and typing after clear ([d200f22](https://github.com/vuetifyjs/vuetify/commit/d200f227a12ba14aeb5b0a0ce0fd77ce95da52dc))\n* **VCombobox:** show full list on reopen unless `always-filter` is used ([83d0073](https://github.com/vuetifyjs/vuetify/commit/83d00737566fd1df7d043d97d6c93dde5237162e))\n* **VCombobox, VAutocomplete:** avoid glitches when opening with click ([9a1dd83](https://github.com/vuetifyjs/vuetify/commit/9a1dd8363ff59d91257236b126cb5d89c92ebb61)), closes [#22228](https://github.com/vuetifyjs/vuetify/issues/22228)\n* **VAutocomplete/VCombobox:** consistent open/close transition ([#22144](https://github.com/vuetifyjs/vuetify/issues/22144)) ([96f6479](https://github.com/vuetifyjs/vuetify/commit/96f6479d2aa82bcf8f75de51c9dce557fba981bd))\n* **VConfirmEdit:** deeply unwrap refs before cloning values ([a507171](https://github.com/vuetifyjs/vuetify/commit/a507171d25b0d41a4be0d74095ac69afbc413922)), closes [#22232](https://github.com/vuetifyjs/vuetify/issues/22232)\n* **VDataTable:** avoid lag when selecting rows in large tables ([#22163](https://github.com/vuetifyjs/vuetify/issues/22163)) ([92f8a3c](https://github.com/vuetifyjs/vuetify/commit/92f8a3c5c75e84ab79377e9c26a74576f36e6bbc)), closes [#21767](https://github.com/vuetifyjs/vuetify/issues/21767)\n* **VDataTable:** optimize select-all performance ([#22252](https://github.com/vuetifyjs/vuetify/issues/22252)) ([2ad1a38](https://github.com/vuetifyjs/vuetify/commit/2ad1a385a06d94405aa3497b079498f08c870e83)), closes [#19447](https://github.com/vuetifyjs/vuetify/issues/19447)\n* **VDatePicker:** correct range for `allowed-dates` ([#22167](https://github.com/vuetifyjs/vuetify/issues/22167)) ([e678f0e](https://github.com/vuetifyjs/vuetify/commit/e678f0e0d6c45018c611785d932c51db4068a8ef)), closes [#22160](https://github.com/vuetifyjs/vuetify/issues/22160)\n* **VDatePicker:** correct range selection for Luxon adapter ([20b2bf4](https://github.com/vuetifyjs/vuetify/commit/20b2bf425353f6a4d5edf6f1c63d5c35b0ecd165)), closes [#22262](https://github.com/vuetifyjs/vuetify/issues/22262)\n* **VDatePicker:** return correct range for DST ([#22187](https://github.com/vuetifyjs/vuetify/issues/22187)) ([a3ddcf1](https://github.com/vuetifyjs/vuetify/commit/a3ddcf16cca785abcfbc1a922c6e44f6e2acc576)), closes [#22186](https://github.com/vuetifyjs/vuetify/issues/22186)\n* **VDialog:** fix focus trap when tabbing forward ([#22101](https://github.com/vuetifyjs/vuetify/issues/22101)) ([50a150b](https://github.com/vuetifyjs/vuetify/commit/50a150bf0eb8abf6129958e6b11355a1315bfb5b)), closes [#21945](https://github.com/vuetifyjs/vuetify/issues/21945)\n* **VDialog:** focus trap should ignore invisible and inert elements ([#22105](https://github.com/vuetifyjs/vuetify/issues/22105)) ([adf3f91](https://github.com/vuetifyjs/vuetify/commit/adf3f919c6fa1efd6aacde0686a0fb5d5dc0e0bb)), closes [#18400](https://github.com/vuetifyjs/vuetify/issues/18400)\n* **VDivider:** inherit color in colored containers ([bb54a7d](https://github.com/vuetifyjs/vuetify/commit/bb54a7ded40156e24b670c83e826caca1740b74a))\n* **VField:** missing `controlRef` assignment ([#22171](https://github.com/vuetifyjs/vuetify/issues/22171)) ([b89f568](https://github.com/vuetifyjs/vuetify/commit/b89f56819302649463482ce2776557e371b9ec75)), closes [#22034](https://github.com/vuetifyjs/vuetify/issues/22034)\n* **VFileInput, VFileUpload:** avoid invalid `accept` when not defined ([e6c39bc](https://github.com/vuetifyjs/vuetify/commit/e6c39bcbeb750ce4b1a5da91edb4a940dcc4fd38)), closes [#22131](https://github.com/vuetifyjs/vuetify/issues/22131)\n* **VKbd:** use `$body-font-family` as default ([3f61102](https://github.com/vuetifyjs/vuetify/commit/3f6110237d3a0fb5e65dae6358dc4d04d11e7338))\n* **VListItem:** correct role when item is a link ([#22137](https://github.com/vuetifyjs/vuetify/issues/22137)) ([80e154b](https://github.com/vuetifyjs/vuetify/commit/80e154b8c295458b9ced262b3e20403fe07376c3)), closes [#22086](https://github.com/vuetifyjs/vuetify/issues/22086)\n* **VListItem:** respect link & canvas colors in forced-colors mode ([#22032](https://github.com/vuetifyjs/vuetify/issues/22032)) ([84a7bff](https://github.com/vuetifyjs/vuetify/commit/84a7bffc9d721c2bc2deca6b93c6d08e4e77f534))\n* **VMenu:** add aria-owns to activator ([#22240](https://github.com/vuetifyjs/vuetify/issues/22240)) ([975a18c](https://github.com/vuetifyjs/vuetify/commit/975a18cc2dd4ef197a6ab6ca49f81788f9b4f638)), closes [#22226](https://github.com/vuetifyjs/vuetify/issues/22226)\n* **VMenu:** avoid scrolling to the off-screen menu ([#22044](https://github.com/vuetifyjs/vuetify/issues/22044)) ([d1dafff](https://github.com/vuetifyjs/vuetify/commit/d1dafffd729590f1c873da20fb6b09f6d53c38e4)), closes [#21775](https://github.com/vuetifyjs/vuetify/issues/21775) [#20569](https://github.com/vuetifyjs/vuetify/issues/20569) [#21015](https://github.com/vuetifyjs/vuetify/issues/21015) [#16819](https://github.com/vuetifyjs/vuetify/issues/16819)\n* **VMenu:** ignore focus on root element ([fe1214f](https://github.com/vuetifyjs/vuetify/commit/fe1214fb1cbfe021b7db50e88ea091b4ef39e707)), closes [#22263](https://github.com/vuetifyjs/vuetify/issues/22263)\n* **VMenu:** keep open with keyboard and open-delay=\"0\" ([#22242](https://github.com/vuetifyjs/vuetify/issues/22242)) ([8e810e5](https://github.com/vuetifyjs/vuetify/commit/8e810e54b12c58a525bf2efb149f0f03a3769448)), closes [#21591](https://github.com/vuetifyjs/vuetify/issues/21591)\n* **VNumberInput:** align stacked controls in underlined variant ([#22185](https://github.com/vuetifyjs/vuetify/issues/22185)) ([e10ffea](https://github.com/vuetifyjs/vuetify/commit/e10ffea80e6cedbdfbf14912f7587aaabd221779)), closes [#22184](https://github.com/vuetifyjs/vuetify/issues/22184)\n* **VNumberInput:** allow typing negative decimal values with a comma separator ([#22199](https://github.com/vuetifyjs/vuetify/issues/22199)) ([f0fec8f](https://github.com/vuetifyjs/vuetify/commit/f0fec8fb39ec5bbc82bd02c70a17bdc1d1746995)), closes [#22183](https://github.com/vuetifyjs/vuetify/issues/22183)\n* **VNumberInput:** emit pasted value without waiting for blur ([6034a73](https://github.com/vuetifyjs/vuetify/commit/6034a73a09c649140af726dbd7dbc13a7871a245)), closes [#22182](https://github.com/vuetifyjs/vuetify/issues/22182)\n* **VOverlay:** `stick-to-target` content visible until target overflows ([#22233](https://github.com/vuetifyjs/vuetify/issues/22233)) ([0e1dff0](https://github.com/vuetifyjs/vuetify/commit/0e1dff0be1cbcc05985bd6f50c58e70ccc0ceea8)), closes [#22055](https://github.com/vuetifyjs/vuetify/issues/22055)\n* **VProgressCircular:** hide overflow to avoid height changes ([#22245](https://github.com/vuetifyjs/vuetify/issues/22245)) ([d5cfb7b](https://github.com/vuetifyjs/vuetify/commit/d5cfb7bf14cbafe57a4043a6427d21ab21d84a45)), closes [#22244](https://github.com/vuetifyjs/vuetify/issues/22244)\n* **VRangeSlider:** inherit readonly/disabled from form ([d071e24](https://github.com/vuetifyjs/vuetify/commit/d071e241c82fca7c65405174623014989f2d3985)), closes [#22054](https://github.com/vuetifyjs/vuetify/issues/22054)\n* **VSelect:** item checkbox gets out of sync ([#22181](https://github.com/vuetifyjs/vuetify/issues/22181)) ([f257802](https://github.com/vuetifyjs/vuetify/commit/f2578024e948ff24faea7275b3d0d808e0afa02e))\n* **VSkeletonLoader:** accept scoped styles ([#22201](https://github.com/vuetifyjs/vuetify/issues/22201)) ([c20031b](https://github.com/vuetifyjs/vuetify/commit/c20031be5347d17286acadf29d12d5edddc6bcb3)), closes [#22198](https://github.com/vuetifyjs/vuetify/issues/22198)\n* **VSkeletonLoader:** render background in forced-colors mode ([#22216](https://github.com/vuetifyjs/vuetify/issues/22216)) ([26e0b6d](https://github.com/vuetifyjs/vuetify/commit/26e0b6d623bcc154cc14db4958c2c3204c0dff0a))\n* **VSlider:** prevent thumb movement when disabled mid-interaction ([#22257](https://github.com/vuetifyjs/vuetify/issues/22257)) ([4506459](https://github.com/vuetifyjs/vuetify/commit/45064595260f6644e09fdfc9712547fc321e83e6)), closes [#22248](https://github.com/vuetifyjs/vuetify/issues/22248)\n* **VTabs:** correct link state in Nuxt app ([7068ce1](https://github.com/vuetifyjs/vuetify/commit/7068ce141ee11dc70d237960ea78480cf97922c6)), closes [#22188](https://github.com/vuetifyjs/vuetify/issues/22188)\n* **VTextarea:** mask should not clip scrollbar ([#22001](https://github.com/vuetifyjs/vuetify/issues/22001)) ([e8e7234](https://github.com/vuetifyjs/vuetify/commit/e8e72349a985d1ede8a4c8500114e237f1cd742d)), closes [#21283](https://github.com/vuetifyjs/vuetify/issues/21283)\n* **VTextField:** keep counter in one line ([78e053f](https://github.com/vuetifyjs/vuetify/commit/78e053f58375b07c1a636e70fdb733dda447a99e)), closes [#19620](https://github.com/vuetifyjs/vuetify/issues/19620)\n* **VTextField, VCombobox:** avoid duplicated emits on clear ([#22219](https://github.com/vuetifyjs/vuetify/issues/22219)) ([3e92de3](https://github.com/vuetifyjs/vuetify/commit/3e92de31a3d1df808710606c687f114e81df08cc)), closes [#21417](https://github.com/vuetifyjs/vuetify/issues/21417)\n* **VTreeview:** pass `indent-lines` to `header` slot ([8e964c7](https://github.com/vuetifyjs/vuetify/commit/8e964c72d00600f29202bee782eb11bb571627ad))\n* **VVirtualScroll:** scroll to last element ([#22166](https://github.com/vuetifyjs/vuetify/issues/22166)) ([1cc009f](https://github.com/vuetifyjs/vuetify/commit/1cc009f3f1387c2530d044c9bd3b6a12fdc18f1d)), closes [#20931](https://github.com/vuetifyjs/vuetify/issues/20931)\n* **VWindow:** fix exception due to missing scrollable parent in unit test ([7b122b7](https://github.com/vuetifyjs/vuetify/commit/7b122b735428e736808177cb84a39a5bb3f9b7f1))\n* **VWindow:** Maintain scroll position on window change ([#22191](https://github.com/vuetifyjs/vuetify/issues/22191)) ([fb7d36b](https://github.com/vuetifyjs/vuetify/commit/fb7d36bf66bfc67adb607c7ac0f222c9181251b8))\n\n### :arrows_counterclockwise: Reverts\n\n* Revert \"fix(VOverlay): ignore mouseenter events from touch devices\" ([d448e0e](https://github.com/vuetifyjs/vuetify/commit/d448e0eb4f958967cea632e6af2140a8847f860e)), closes [#17640](https://github.com/vuetifyjs/vuetify/issues/17640) [#22237](https://github.com/vuetifyjs/vuetify/issues/22237)\n\n### :test_tube: Labs\n\n* **VCalendar:** avoid selecting day button ([da4f99a](https://github.com/vuetifyjs/vuetify/commit/da4f99a5f35af7e664d7a5e0d100aeb43b07ddac)), closes [#22141](https://github.com/vuetifyjs/vuetify/issues/22141)\n* **VCalendar:** import directives ([1c7896d](https://github.com/vuetifyjs/vuetify/commit/1c7896dc96abbf45f58d819663fa87ec00ae7127)), closes [#22122](https://github.com/vuetifyjs/vuetify/issues/22122)\n* **VCalendar:** use scrollAreaRef from base ([#22253](https://github.com/vuetifyjs/vuetify/issues/22253)) ([16dc1d2](https://github.com/vuetifyjs/vuetify/commit/16dc1d290f5759bb1d5a6f495aae4641fc60d125)), closes [#22251](https://github.com/vuetifyjs/vuetify/issues/22251)\n* **VColorInput:** avoid VField, VInput props leaking to VPicker ([14b74d1](https://github.com/vuetifyjs/vuetify/commit/14b74d15557371baafefa8479a9ad77b00ada6af))\n* **VDateInput:** apply min/max to text input ([#22196](https://github.com/vuetifyjs/vuetify/issues/22196)) ([201e6d2](https://github.com/vuetifyjs/vuetify/commit/201e6d27f884ac6077bc8c2cef14eb12a1a28c45)), closes [#22179](https://github.com/vuetifyjs/vuetify/issues/22179)\n* **VDateInput:** avoid `color` prop leaking to VPicker ([6bddea1](https://github.com/vuetifyjs/vuetify/commit/6bddea14a7e22e6eea804a6cf8f0fb0dd807b793))\n* **VDateInput:** avoid VField, VInput props leaking to VPicker ([253e75e](https://github.com/vuetifyjs/vuetify/commit/253e75e4894fa40e069b4032dfe3bab22aa05d48))\n* **VIconBtn:** render interaction highlights in forced-colors mode ([#22211](https://github.com/vuetifyjs/vuetify/issues/22211)) ([37bd57d](https://github.com/vuetifyjs/vuetify/commit/37bd57d7400d716830ddbe0ced85754e2cd334f5))\n* **VMaskInput:** handle null value when clearing input ([#22175](https://github.com/vuetifyjs/vuetify/issues/22175)) ([46e3a84](https://github.com/vuetifyjs/vuetify/commit/46e3a84b582aa0c8f7e8aba4e00be3b1a6f7bddd)), closes [#22174](https://github.com/vuetifyjs/vuetify/issues/22174)\n* **VMaskInput:** inherit class and style ([#22247](https://github.com/vuetifyjs/vuetify/issues/22247)) ([01f5e6f](https://github.com/vuetifyjs/vuetify/commit/01f5e6f29d83d3e4c477eb1cfe92262b8186150e))\n* **VPie:** consistent avatar size in tooltip ([6cefd46](https://github.com/vuetifyjs/vuetify/commit/6cefd4663ba1c6dfee02eea3a35ae76e0793b44e))\n\n</details>\n\n## What's Next{ .mt-4 }\n\nNovember brings us closer to the Vuetify v3.11 release as we continue stabilizing the framework and polishing components. Work continues on v0 composables with expanded documentation and integration testing, while in-development features like VCommandPalette and the VTabs inset variant move toward completion.\n\nThe Vuetify MCP server will continue evolving based on community feedback, and we're exploring additional AI-powered developer tools to streamline the Vuetify development experience. As always, your bug reports, feature requests, and community contributions drive our roadmap forward.\n\nThank you for being part of the Vuetify community. See you in November!\n\n---\n\n*Stay connected with Vuetify updates through our [GitHub repository](https://github.com/vuetifyjs/vuetify), [Discord community](https://discord.gg/vuetify), and follow [@vuetifyjs](https://twitter.com/vuetifyjs) for the latest announcements. The best is yet to come!*\n"
  },
  {
    "path": "packages/docs/src/pages/en/blog/september-2025-update.md",
    "content": "---\nlayout: blog\nmeta:\n  title: September 2025 Update\n  description: September marks significant progress as we assemble the building blocks for Vuetify's next phase. From revolutionary design-to-development workflows with our new Figma UI Kit to foundational v0 composables, September has been about connecting the pieces that will define the future of Vue development.\n  keywords: Vuetify September 2025, Figma UI Kit, Vuetify0\n---\n\n<script setup>\n  import { useTheme } from 'vuetify'\n\n  const theme = useTheme()\n  const linklogo = computed(() => {\n    return `https://cdn.vuetifyjs.com/docs/images/one/logos/vlink-logo-${theme.current.value.dark ? 'dark' : 'light'}.svg`\n  })\n  const zerologo = computed(() => {\n    return `https://cdn.vuetifyjs.com/docs/images/one/logos/vzero-logo-${theme.current.value.dark ? 'dark' : 'light'}.svg`\n  })\n</script>\n\n# September 2025 Update\n\nWelcome to our September update! This month marks significant progress as we assemble the building blocks for Vuetify's next phase. From revolutionary design-to-development workflows with our new Figma UI Kit to foundational v0 composables, September has been about connecting the pieces that will define the future of Vue development.\n\n![Hero image for September update](https://cdn.vuetifyjs.com/docs/images/blog/september-2025-update/september-hero.png \"September hero image\"){ height=112 }\n\n🖊️ John Leider • 📅 October 12th, 2025\n\n<PromotedEntry />\n\n---\n\n## Assembling the Future\n\nI've been heads-down on Vuetify0 composables this month, and it's starting to click. The Figma UI Kit update is great, the framework improvements are solid, but what keeps me up at night is making sure these v0 composables feel *right*. We're not just building features—we're establishing patterns that thousands of developers will use. Get the abstraction wrong and you've created more problems than you solved. Get it right and complex stuff like permissions and feature flags just works.\n\nHaving Jacek take over as Framework Czar has been huge. I can focus on these bigger architectural questions while he keeps the core framework moving forward. The team shipped over 60 bug fixes and features in the month of September, and we're maintaining that pace. Between the Figma Kit, the v0 work, and everything else happening in the ecosystem, things are coming together.\n\n::: success\n\nCool example of the month: [Gradient VProgressLinear](https://play.vuetifyjs.com/playgrounds/AIVKig) by [J-Sek](https://github.com/J-Sek)\n\n:::\n\n---\n\n## Table of Contents\n\n* [Releases](#releases)\n  * [Key Improvements](#key-improvements)\n* [Updated Official Figma UI Kit](#updated-official-figma-ui-kit)\n  * [What's Included](#whats-included)\n  * [Why This Matters](#why-this-matters)\n  * [Pro Version Available](#pro-version-available)\n* [September Webinar Recap: Performance Crisis](#september-webinar-recap-performance-crisis)\n  * [Next Event: v0 Live Coding with John](#next-event-v0-live-coding-with-john)\n* [Vuetify0: Composables Taking Shape](#vuetify0-composables-taking-shape)\n  * [New Composables This Month](#new-composables-this-month)\n* [Framework & Security Updates](#framework-security-updates)\n  * [Build System Modernization](#build-system-modernization)\n* [Ecosystem Spotlight: Vuetify Link](#ecosystem-spotlight-vuetify-link)\n  * [Key Features](#key-features)\n* [September 2025 Changelog](#september-2025-changelog)\n* [The Pieces Come Together](#the-pieces-come-together)\n\n---\n\n## Releases\n\nSeptember focused on stabilization and quality improvements across the Vuetify 3 series, including iterating to the next minor version with [v3.10.0 (Argo)](/getting-started/release-notes/?version=v3.10.0). We've addressed numerous bugs, enhanced accessibility, and refined component behaviors to ensure a robust experience for developers and users alike.\n\n![September Releases Banner](https://cdn.vuetifyjs.com/docs/images/blog/september-2025-update/v310_release.png \"September Releases Banner\")\n\n### Key Improvements\n\n* A direct [VCalendar](/components/calendars) port from Vuetify 2, bringing back familiar calendar functionalities with modern enhancements.\n* Added support for `prefers-reduced-motion` to respect user accessibility settings\n* Added multiple new slots for [VTreeview](/components/treeview) and [VDataTable](/components/data-tables/introduction/) for greater customization\n\nView the complete list of changes in the [Full Changelog](#september-2025-changelog)\n\n**Details:**\n\n* [v3.9.7](https://vuetifyjs.com/getting-started/release-notes/?version=v3.9.7)\n* [v3.10.0](https://vuetifyjs.com/getting-started/release-notes/?version=v3.10.0)\n* [v3.10.1](https://vuetifyjs.com/getting-started/release-notes/?version=v3.10.1)\n* [v3.10.2](https://vuetifyjs.com/getting-started/release-notes/?version=v3.10.2)\n* [v3.10.3](https://vuetifyjs.com/getting-started/release-notes/?version=v3.10.3)\n\n## Updated Official Figma UI Kit\n\nWe're thrilled to announce the release of our **[updated Vuetify 3 UI Kit for Figma](https://store.vuetifyjs.com/products/vuetify-ui-kit-figma)**! This comprehensive design system brings Vuetify's Material Design implementation directly to your design workflow, completely free.\n\n![Vuetify Figma UI Kit Update](https://cdn.vuetifyjs.com/docs/images/blog/september-2025-update/figma.png \"Vuetify Figma UI Kit Update\")\n\n### What's Included\n\n* **Complete Component Library**: Every Vuetify 3 component meticulously recreated in Figma\n* **Material Design 3 Foundation**: Built on the latest Material Design specifications\n* **Design Tokens**: Consistent spacing, typography, and color systems\n* **Responsive Variants**: Components optimized for all screen sizes\n* **Dark Mode Support**: Full theme switching capabilities\n* **Auto-Layout**: Modern Figma features for flexible, maintainable designs\n\n### Why This Matters\n\nThis free UI kit bridges the gap between design and development, ensuring pixel-perfect implementations and faster handoffs. Designers can now work with the exact same components developers use, eliminating interpretation errors and accelerating the design-to-code process.\n\n### Pro Version Available\n\nDesign faster with 1:1 Vuetify components, production-ready variants and style controls (colors, densities, radius and states) that adapt to any brand. Choose the version that best fits your workflow.\n\n#### Why PRO\n\n* ✅ 150+ components with 1:1 names and structure with Vuetify\n* ✅ All variants (elevated, flat, tonal, outlined, text, plain…) and complete states\n* ✅ Advanced foundations: 7 color roles, densities, radius, borders (color/width/opacity)\n* ✅ +4 modes by variables to scale brands and themes\n* ✅ Updates synchronized with the library and direct support\n\n**Ideal for:**\n\n* Teams & Startups — Faster delivery, total consistency and less rework\n* Freelancers — Winning proposals and clean handoff with devs\n* Design Systems — Variables, tokens and real theme scalability\n* Dev Teams — 1:1 parity with Vuetify components to implement without friction.\n\n#### Comparison Table\n\n| Feature | PRO | FREE |\n|---------|-----|------|\n| **Foundations** | Includes complete **Material Design Colors** | Does not include MD color palette |\n| **Themes** | Light / Dark (+ extra modes by variables) | Light / Dark |\n| **Color Roles** | Default, Primary, Secondary, Custom, Error, Warning, Info, Success | Default, Primary, Secondary, Custom, Error, Warning, Info, Success |\n| **States** | Enabled, Disabled, Active/Focus, Hover | Enabled, Disabled |\n| **Sizes** | Default, Small, X/Small, Large, X/Large | Default, Small, Large |\n| **Density** | Default, Comfortable, Compact | Only Default |\n| **Border Color** | Current + Primary, Secondary, Error, Warning, Info, Success | Only Current |\n| **Border Width** | default, 0, xs (thin), sm, md, lg, xl | default, 0 |\n| **Border Opacity** | default, 0, 25, 50, 75, 100 | Not available |\n| **Border Radius** | default, square, xs, sm, md, lg, xl, pill, circle | default, square, pill, circle |\n| **Error State** | Full support | Basic inputs |\n| **Others** | Individual color control in `VField` | No individual control |\n| **Components** | All components | Missing components |\n| **Variants** | All variants | Only elevated • flat • outlined |\n| **Variants in Inputs** | All variants | Only filled • outlined |\n| **Updates & Support** | Synchronized with library + support | Not guaranteed • no support |\n| **Modes by variables** | 4+ modes | 4 or less |\n\n**Details:**\n\n* [Free Figma UI Kit](https://store.vuetifyjs.com/products/vuetify-ui-kit-figma)\n* [Go PRO](https://store.vuetifyjs.com/products/official-vuetify-3-ui-kit-for-figma)\n\n## September Webinar Recap: Performance Crisis\n\nThank you to everyone who joined our September performance optimization webinar. We had an engaging Q&A session with the community discussing bundle size reduction strategies. Some highlights and key takeaways:\n\n* Disable [unused CSS utilities](/features/sass-variables/#disabling-utility-classes) with SASS variables\n* Use [vite-plugin-vuetify](/features/treeshaking/) for automatic treeshaking and code splitting\n* Reduce page load time with [VLazy](/components/lazy/)\n* Use [VVirtualScroll](/components/virtual-scroll/) for expensive lists\n\nNever miss another event by joining our [Discord Community](https://community.vuetifyjs.com/) and following us on [X](https://x.com/vuetifyjs)!.\n\n### Next Event: v0 Live Coding with John\n\n**Wednesday, October 29th**: Join John for an exclusive live coding session where he'll build a complete application using Vuetify0 from scratch!\n\n#### What to Expect\n\n* **Real-time Development**: Watch as John tackles real-world challenges\n* **Composables in Action**: See how usePermissions, useFeatures, and other v0 composables work together\n* **Architecture Decisions**: Learn the reasoning behind v0's design patterns\n* **Live Q&A**: Get your questions answered as we code\n* **Early Access Insights**: First detailed look at v0's developer experience\n\nThis will be a true live demo, so expect some surprises and spontaneous problem-solving. Whether you're a seasoned Vue developer or just curious about v0, this session will provide valuable insights into building modern applications with v0 composables.\n\n**Details**:\n\n* Date: Wednesday, October 29th\n* Start Time: 9:00 AM CST\n* [See what Vuetify0 is all about](https://discord.gg/vuetify-340160225338195969?event=1426220686162268311)\n\n## Vuetify0: Composables Taking Shape\n\n<AppFigure :src=\"zerologo\" alt=\"Vuetify0 logo\" width=\"200\" height=\"auto\" class=\"mx-auto\" title=\"Vuetify0 Logo\" />\n\nSeptember saw intensive development on v0's composable foundation. The team has been deep in the codebase, introducing critical composables and ensuring code quality across the board.\n\n### New Composables This Month\n\n* **usePermissions**: A composable for managing RBAC permissions:\n\n```ts { resource=\"src/main.ts\" }\nimport { createApp } from 'vue'\nimport { createPermissionsPlugin } from '@vuetify/0'\n\nconst app = createApp()\n\napp.use(\n  createPermissionsPlugin({\n    permissions: {\n      super: [\n        ['create', 'Post'],\n        ['read', 'Post'],\n        ['update', 'Post'],\n        ['delete', 'Post'],\n        ['use', 'Dev'],\n      ],\n      editor: [\n        ['create', 'Post'],\n        ['read', 'Post'],\n        ['update', 'Post']\n      ],\n    },\n  })\n)\n\napp.mount('#app')\n```\n\n```html { resource=\"src/components/SomeComponent.vue\" }\n<script lang=\"ts\" setup>\n  import { usePermissions } from '@vuetify/0'\n  import { useAuth } from 'your-auth-provider'\n\n  const { user } = useAuth()\n  const { can } = usePermissions()\n</script>\n\n<template>\n  <div v-if=\"can(user.role, 'create', 'Post')\">\n    <button>Create Post</button>\n  </div>\n\n  <div v-if=\"can(user.role, 'delete', 'Post')\">\n    <button>Delete Post</button>\n  </div>\n</template>\n```\n\n* **useFeatures**: A composable for managing available features and feature flags w/ variants support.\n\n```ts { resource=\"src/main.ts\" }\nimport { createApp } from 'vue'\nimport { createFeaturesPlugin } from '@vuetify/0'\n\nconst app = createApp()\n\napp.use(\n  createFeaturesPlugin({\n    features: {\n      comments: true,\n      dev: false,\n      search: {\n        $value: true,\n        $variation: 'v2',\n        $description: 'The new and improved search experience',\n      },\n    },\n  })\n)\n\napp.mount('#app')\n```\n\n```html { resource=\"src/components/SomeComponent.vue\" }\n<script lang=\"ts\" setup>\n  import { useFeatures } from '@vuetify/0'\n\n  const features = useFeatures()\n  const dev = features.get('dev')!\n  const search = features.get('search')!\n</script>\n\n<template>\n  <button @click=\"dev.toggle()\">Toggle Dev</button>\n\n  <input\n    v-if=\"dev.value && features.variation('search') === 'v2'\"\n    placeholder=\"Search v2\"\n  />\n\n  <input v-else placeholder=\"Search v1\" />\n</template>\n```\n\n* **useTimeline**: A composable for sequence management with undo/redo support.\n\n```html { resource=\"src/components/SomeComponent.vue\" }\n<script lang=\"ts\" setup>\n  import { useTimeline } from '@vuetify/0'\n\n  const timeline = useTimeline({ size: 5 })\n\n  timeline.register({ id: 1, value: 'foo' })\n  timeline.register({ id: 2, value: 'bar' })\n  timeline.register({ id: 3, value: 'baz' })\n\n  console.log(timeline.size) // 3\n\n  timeline.undo()\n  timeline.undo()\n\n  console.log(timeline.values()) // ['foo']\n\n  timeline.redo()\n\n  console.log(timeline.values()) // ['foo', 'bar']\n</script>\n```\n\n::: info\n\nSee all available composables on the [Vuetify0 documentation site](https://0.vuetifyjs.com/composables/).\n\n:::\n\n**Details:**\n\n* [usePermissions Documentation](https://0.vuetifyjs.com/composables/plugins/use-permissions/)\n* [useFeatures Documentation](https://0.vuetifyjs.com/composables/plugins/use-features/)\n* [useTimeline Documentation](https://0.vuetifyjs.com/composables/registration/use-timeline/)\n\n## Framework & Security Updates\n\nWith all the buzz around security vulnerabilities in the NPM ecosystem, we've prioritized enhancing our build and publishing processes to ensure the highest level of security for our users.\n\n### Build System Modernization\n\nThis month brought significant improvements to our build infrastructure in Vuetify and across the ecosystem. Key updates include:\n\n* **Vite 7 Support**: Full migration completed with improved build performance\n* **Vue-TSC 3**: Updated TypeScript tooling for better type checking\n* **Trusted Publishing**: Enhanced security for all package releases with the pnpm's **minimumReleaseAge** setting\n* **TSGO:** Replaced our TSC usage with TSGO for faster builds and better DX\n\n**Details:**\n\n* [Commit: af9a9bf](https://github.com/vuetifyjs/vuetify/commit/af9a9bfc63fa44721f89076431fbe004e70d7c1c)\n* [Commit: c78f8aa](https://github.com/vuetifyjs/vuetify/commit/c78f8aa066164f6ee5f2e1f106ed121963faffe5)\n\n## Ecosystem Spotlight: Vuetify Link\n\n<AppFigure :src=\"linklogo\" alt=\"Vuetify Link logo\" width=\"200\" height=\"auto\" class=\"mx-auto\" title=\"Vuetify Link Logo\" />\n\nVuetify Link is a new service that simplifies the process of creating and managing custom short links for your projects. The initial idea came from the need to share Vuetify Bins/Playgrounds/Studios without necessarily wanting to save them to your dashboard. Since these services all compress their data into the URL, it can often times be very long and cumbersome to share. It also enables us to continue to bolster the value proposition for **Vuetify One** subscribers with advanced options while making the core functionality of creating shortlinks free for everyone.\n\n### Key Features\n\n* **Custom Slugs**: Create memorable and branded short links\n* **Link Management**: Edit, delete, and track your links from a simple dashboard\n* **Analytics**: Monitor link performance with detailed statistics\n* **Free & Pro Plans**: Basic link shortening is free, with advanced features available for Vuetify One subscribers\n\n![Vuetify Link Landing Screenshot](https://vuetifyjs.b-cdn.net/docs/images/blog/september-2025-update/vlink_banner.png \"Vuetify Link Landing\")\n\nWe anticipate launching this new service **this month!** Stay tuned for the official release announcement with all the details.\n\n## September 2025 Changelog\n\nThe following section provides an overview of the changes made in September 2025, including new features, bug fixes, and enhancements across the Vuetify framework.\n\n**Key Improvements:**\n\n* Introduced `spaced` prop for VBtn to enhance button spacing options.\n* Added `truncate-length` prop to VFileInput for better filename management.\n* Implemented `stick-to-target` prop in VOverlay for improved overlay positioning.\n* Enhanced accessibility with `aria-controls` and `aria-expanded` in VSelects.\n* Re-converted `VCalendar` based off of Vuetify 2 implementation.\n\n**Expand** this section to see the detailed changelog for September 2025:\n\n<details>\n\n### :rocket: Features\n\n* **filter:** keep dividers and subheaders ([#21822](https://github.com/vuetifyjs/vuetify/issues/21822)) ([18ac731](https://github.com/vuetifyjs/vuetify/commit/18ac7319a04df9645861977b723173c376655c2f)), closes [#7424](https://github.com/vuetifyjs/vuetify/issues/7424)\n* **framework:** respect prefers-reduced-motion ([#21530](https://github.com/vuetifyjs/vuetify/issues/21530)) ([01c9e91](https://github.com/vuetifyjs/vuetify/commit/01c9e9115898118535865197660dd7399ae1626c)), closes [#19622](https://github.com/vuetifyjs/vuetify/issues/19622)\n* **VBtn:** add `spaced` prop ([#21663](https://github.com/vuetifyjs/vuetify/issues/21663)) ([819605c](https://github.com/vuetifyjs/vuetify/commit/819605c6b4606bf45d33ea9c431c4e97a1bbd3b7)), closes [#21652](https://github.com/vuetifyjs/vuetify/issues/21652)\n* **VCard:** allow semantic HTML tags for content parts ([#21943](https://github.com/vuetifyjs/vuetify/issues/21943)) ([5f8abb6](https://github.com/vuetifyjs/vuetify/commit/5f8abb6c5cece7fea660a7f4811e3c0108a4f402))\n* **VColorPicker:** add `hide-eye-dropper` prop ([be452a5](https://github.com/vuetifyjs/vuetify/commit/be452a547f7efeb773fa8173695c6463137281a0)), closes [#19154](https://github.com/vuetifyjs/vuetify/issues/19154) [#19150](https://github.com/vuetifyjs/vuetify/issues/19150)\n* **VColorPicker:** customizable eyeDropper icon ([#21656](https://github.com/vuetifyjs/vuetify/issues/21656)) ([71377a6](https://github.com/vuetifyjs/vuetify/commit/71377a69079ccdb258ead9dcee2bcd355d6ce6d3)), closes [#21406](https://github.com/vuetifyjs/vuetify/issues/21406)\n* **VDataIterator:** add filtered items count to slot data ([#18641](https://github.com/vuetifyjs/vuetify/issues/18641)) ([7d51302](https://github.com/vuetifyjs/vuetify/commit/7d51302c8e609b78854934586dafef41ba188428))\n* **VDataTable:** customizable expand/collapse icons ([#21698](https://github.com/vuetifyjs/vuetify/issues/21698)) ([1636f63](https://github.com/vuetifyjs/vuetify/commit/1636f632027255bdbc33a989ce667f9c9b352793))\n* **VDataTable:** re-introduce `group-summary` slot ([#21802](https://github.com/vuetifyjs/vuetify/issues/21802)) ([a19cd87](https://github.com/vuetifyjs/vuetify/commit/a19cd8778ac21e9c050649d570e726ac11fa0008)), closes [#21800](https://github.com/vuetifyjs/vuetify/issues/21800)\n* **VDatePicker:** re-introduce `first-day-of-year` prop ([#21760](https://github.com/vuetifyjs/vuetify/issues/21760)) ([af74f62](https://github.com/vuetifyjs/vuetify/commit/af74f62a1d57a63bcad835a4a2aded2ff03b419c)), closes [#20270](https://github.com/vuetifyjs/vuetify/issues/20270)\n* **VFileInput:** add `truncate-length` prop ([#17972](https://github.com/vuetifyjs/vuetify/issues/17972)) ([28ef26c](https://github.com/vuetifyjs/vuetify/commit/28ef26c59b5e1991c469adbd567f305d88bac904)), closes [#17635](https://github.com/vuetifyjs/vuetify/issues/17635)\n* **VFileUpload, VFileInput:** add `filter-by-type` prop ([#21576](https://github.com/vuetifyjs/vuetify/issues/21576)) ([1b78b06](https://github.com/vuetifyjs/vuetify/commit/1b78b06a40470186c83c88f95ec00ba71d36171d)), closes [#21150](https://github.com/vuetifyjs/vuetify/issues/21150)\n* **VOverlay:** add `stick-to-target` prop ([#21704](https://github.com/vuetifyjs/vuetify/issues/21704)) ([8552779](https://github.com/vuetifyjs/vuetify/commit/855277993131333d57359dadbf1511532a98cc68)), closes [#19856](https://github.com/vuetifyjs/vuetify/issues/19856) [#19732](https://github.com/vuetifyjs/vuetify/issues/19732) [#17125](https://github.com/vuetifyjs/vuetify/issues/17125)\n* **VProgressLinear:** ability to separate chunks ([#21744](https://github.com/vuetifyjs/vuetify/issues/21744)) ([4c66aa0](https://github.com/vuetifyjs/vuetify/commit/4c66aa0bda8763d31a5d61a1eff77e873cd4b4c1))\n* **VTextField, VTextarea:** add `autocomplete` prop ([#21359](https://github.com/vuetifyjs/vuetify/issues/21359)) ([d94c003](https://github.com/vuetifyjs/vuetify/commit/d94c00309e6e744e267275cc179bbdfc61fdd848)), closes [#21353](https://github.com/vuetifyjs/vuetify/issues/21353)\n* **VTimePicker:** add `period` prop ([#21823](https://github.com/vuetifyjs/vuetify/issues/21823)) ([8df7685](https://github.com/vuetifyjs/vuetify/commit/8df76851aff28dcfc8b73eee18d5613557aafce8)), closes [#15405](https://github.com/vuetifyjs/vuetify/issues/15405)\n* **VTreeview:** add `header` slot ([fc86d05](https://github.com/vuetifyjs/vuetify/commit/fc86d05d0b72fb27ebc6bd2017d8684a3aa148a9))\n* **VTreeview:** add `toggle` slot ([#21018](https://github.com/vuetifyjs/vuetify/issues/21018)) ([4ec13f2](https://github.com/vuetifyjs/vuetify/commit/4ec13f2841839d482ee38c9e7f0d72dc006d4090)), closes [#20307](https://github.com/vuetifyjs/vuetify/issues/20307)\n* **VWindow, VCarousel:** add `crossfade` and `transition-duration` ([#21850](https://github.com/vuetifyjs/vuetify/issues/21850)) ([15a5c96](https://github.com/vuetifyjs/vuetify/commit/15a5c96933db148d568a88855d6ba3df53815001))\n\n### :wrench: Bug Fixes\n\n* **framework:** don't use multi-line :not() ([a15edec](https://github.com/vuetifyjs/vuetify/commit/a15edecc8313d13158d62776d4532eb9cc2e583a)), closes [#21995](https://github.com/vuetifyjs/vuetify/issues/21995)\n* **goto:** always check for window.matchMedia support ([7d11a39](https://github.com/vuetifyjs/vuetify/commit/7d11a39d16262c867bcd1d760dee05758b95a398)), closes [#22059](https://github.com/vuetifyjs/vuetify/issues/22059)\n* **group:** support `null` values ([#21743](https://github.com/vuetifyjs/vuetify/issues/21743)) ([facd4af](https://github.com/vuetifyjs/vuetify/commit/facd4af2e90a80c80c512b8a2df46cd6d48be5e2)), closes [#20550](https://github.com/vuetifyjs/vuetify/issues/20550)\n* **nested:** detect and warn about multiple `null` values ([#21940](https://github.com/vuetifyjs/vuetify/issues/21940)) ([0960aa6](https://github.com/vuetifyjs/vuetify/commit/0960aa607835c63950976c570b880feb3f3ae358)), closes [#21815](https://github.com/vuetifyjs/vuetify/issues/21815)\n* **rounded:** prioritize `tile` prop (like in v2) ([6b13382](https://github.com/vuetifyjs/vuetify/commit/6b13382f7784dfa47b0def7b7a80d184063bf392)), closes [#21844](https://github.com/vuetifyjs/vuetify/issues/21844)\n* **selects:** open menu when items is mutated not just replaced ([#22067](https://github.com/vuetifyjs/vuetify/issues/22067)) ([a3f8b17](https://github.com/vuetifyjs/vuetify/commit/a3f8b17e66c1e12a14c80376b0ad7ad7c42cd4cd)), closes [#22066](https://github.com/vuetifyjs/vuetify/issues/22066)\n* **v-touch:** set event handlers on root components ([#21997](https://github.com/vuetifyjs/vuetify/issues/21997)) ([1da3451](https://github.com/vuetifyjs/vuetify/commit/1da3451724ca97de6a95082c0a39736ef89a4906)), closes [#21768](https://github.com/vuetifyjs/vuetify/issues/21768)\n* **VAlert:** use outline instead of background in forced-colors mode ([#21946](https://github.com/vuetifyjs/vuetify/issues/21946)) ([7560323](https://github.com/vuetifyjs/vuetify/commit/7560323d9d33a9d71d2975ab25537cc7bfe493ec))\n* **VAutocomplete:** restore placeholder on blur ([#22114](https://github.com/vuetifyjs/vuetify/issues/22114)) ([d0ebeec](https://github.com/vuetifyjs/vuetify/commit/d0ebeec88485e3579967e073b0f17136cfd84eac)), closes [#21762](https://github.com/vuetifyjs/vuetify/issues/21762)\n* **VBtn, VChip:** correct link active state after navigation cancellation ([#21651](https://github.com/vuetifyjs/vuetify/issues/21651)) ([bce7046](https://github.com/vuetifyjs/vuetify/commit/bce70460ea7e7c9243c5bbe7e0c384202a2c402f)), closes [#21594](https://github.com/vuetifyjs/vuetify/issues/21594)\n* **VBtn:** add aria-disabled and tabindex to disabled links ([#22082](https://github.com/vuetifyjs/vuetify/issues/22082)) ([6e92383](https://github.com/vuetifyjs/vuetify/commit/6e92383726ee33cbb20cfa1e8c44e7d6f089a7fa)), closes [#22061](https://github.com/vuetifyjs/vuetify/issues/22061)\n* **VBtn:** don't set group state on link click ([e292171](https://github.com/vuetifyjs/vuetify/commit/e292171a593020b3eeb02cf8fa377cca8f48235a)), closes [#21594](https://github.com/vuetifyjs/vuetify/issues/21594)\n* **VBtn:** set group state for non-router links ([6bb3fce](https://github.com/vuetifyjs/vuetify/commit/6bb3fce6a165da8cd895ceba66690af3ab7422ef)), closes [#22085](https://github.com/vuetifyjs/vuetify/issues/22085)\n* **VCard:** render border in forced-colors mode ([#21968](https://github.com/vuetifyjs/vuetify/issues/21968)) ([b30d5c8](https://github.com/vuetifyjs/vuetify/commit/b30d5c851947cb214927b7e6bd9288de9d4b15fa))\n* **VChip:** correct opacity for plain variant ([#22005](https://github.com/vuetifyjs/vuetify/issues/22005)) ([48d20f3](https://github.com/vuetifyjs/vuetify/commit/48d20f3095b3b103c791b759dbbf28a751b374f5))\n* **VChip:** render border in forced-colors mode ([#21970](https://github.com/vuetifyjs/vuetify/issues/21970)) ([59aeadc](https://github.com/vuetifyjs/vuetify/commit/59aeadc4337bd3273eebb31cb220728cf0aadac3))\n* **VChipGroup:** render selected in forced-colors mode ([#21973](https://github.com/vuetifyjs/vuetify/issues/21973)) ([997dd56](https://github.com/vuetifyjs/vuetify/commit/997dd5668fe71994e11b4a406ea472697591ac6a))\n* **VCombobox:** filter matching items when opening first time ([#21901](https://github.com/vuetifyjs/vuetify/issues/21901)) ([eeb9d14](https://github.com/vuetifyjs/vuetify/commit/eeb9d145be9f8fb0984ab8a82fc0b561c530cb17)), closes [#21900](https://github.com/vuetifyjs/vuetify/issues/21900)\n* **VCombobox:** unstable menu state while typing ([#22045](https://github.com/vuetifyjs/vuetify/issues/22045)) ([3983af9](https://github.com/vuetifyjs/vuetify/commit/3983af946d49e9eab6c523777510871aa0b5d563))\n* **VDataTable:** allow filters on all columns ([#21876](https://github.com/vuetifyjs/vuetify/issues/21876)) ([af20234](https://github.com/vuetifyjs/vuetify/commit/af20234e3642ff0cff82f546390eca7412c594d0))\n* **VDataTable:** correct alignment of checkboxes ([402257d](https://github.com/vuetifyjs/vuetify/commit/402257d8490a43bb888203ddbb57b82773ad3c0b))\n* **VDataTable:** expand rows when items are plain array ([#22109](https://github.com/vuetifyjs/vuetify/issues/22109)) ([d8b5c4a](https://github.com/vuetifyjs/vuetify/commit/d8b5c4ad009cb27a0dcee6a0c0ee8d3a0a3dd939)), closes [#22080](https://github.com/vuetifyjs/vuetify/issues/22080)\n* **VDataTable:** more flexible alignment with grouping ([#21862](https://github.com/vuetifyjs/vuetify/issues/21862)) ([6d802d3](https://github.com/vuetifyjs/vuetify/commit/6d802d3c8e87752f601414141ce0ee843592535f)), closes [#17863](https://github.com/vuetifyjs/vuetify/issues/17863)\n* **VDataTable:** should allow expanding rows when `return-object` is true ([#21128](https://github.com/vuetifyjs/vuetify/issues/21128)) ([a586965](https://github.com/vuetifyjs/vuetify/commit/a586965cf351aa34e632fe753c43ffd6e9304e4d)), closes [#21096](https://github.com/vuetifyjs/vuetify/issues/21096)\n* **VList, VTreeview:** avoid locked active state when navigating ([#21725](https://github.com/vuetifyjs/vuetify/issues/21725)) ([bdbe15a](https://github.com/vuetifyjs/vuetify/commit/bdbe15ae1a6882dbfa48f620752eba9f26578d3b))\n* **VList:** outline and selection in forced-colors mode ([#21958](https://github.com/vuetifyjs/vuetify/issues/21958)) ([a8eac52](https://github.com/vuetifyjs/vuetify/commit/a8eac52195d894b5a6f3f3c1a93de4f59a2dba7a))\n* **VList:** use proper accessibility attributes ([#21444](https://github.com/vuetifyjs/vuetify/issues/21444)) ([9b2541e](https://github.com/vuetifyjs/vuetify/commit/9b2541e1085dd69295a23fd501d44dc51730638e)), closes [#20978](https://github.com/vuetifyjs/vuetify/issues/20978)\n* **VListGroup:** fit the navigation drawer rail ([2ebc7fa](https://github.com/vuetifyjs/vuetify/commit/2ebc7fa5b4b395337faadf4a8dfbf09edac6b247)), closes [#22047](https://github.com/vuetifyjs/vuetify/issues/22047)\n* **VListItem:** fix `rounded` prop ([9ec5a0d](https://github.com/vuetifyjs/vuetify/commit/9ec5a0d624dceb659f746d11263bb53298f2bdc5)), closes [#22015](https://github.com/vuetifyjs/vuetify/issues/22015)\n* **VMenu, VTooltip:** default to `stick-to-target` false ([263ca4b](https://github.com/vuetifyjs/vuetify/commit/263ca4b9eee3b1f4acc201d255a88ea1c2c222d4)), closes [#22055](https://github.com/vuetifyjs/vuetify/issues/22055)\n* **VNumberInput:** accept external changes when focused ([#21827](https://github.com/vuetifyjs/vuetify/issues/21827)) ([d0340e7](https://github.com/vuetifyjs/vuetify/commit/d0340e7ea0925dc9995a299cd61b6b91de30e239)), closes [#21735](https://github.com/vuetifyjs/vuetify/issues/21735) [#21804](https://github.com/vuetifyjs/vuetify/issues/21804)\n* **VNumberInput:** ignore custom `type` ([c535f1a](https://github.com/vuetifyjs/vuetify/commit/c535f1a17ba2fa15ae182dc0aeeef8df985b0d91)), closes [#22110](https://github.com/vuetifyjs/vuetify/issues/22110)\n* **VOtpInput:** focus next field when correcting values ([#21781](https://github.com/vuetifyjs/vuetify/issues/21781)) ([fc91e6d](https://github.com/vuetifyjs/vuetify/commit/fc91e6d7ee632437fb376b8169a88c593e436716)), closes [#21680](https://github.com/vuetifyjs/vuetify/issues/21680)\n* **VProgressLinear:** ensure visibility when using custom colors ([#21949](https://github.com/vuetifyjs/vuetify/issues/21949)) ([e3fdb53](https://github.com/vuetifyjs/vuetify/commit/e3fdb53a1fe5bb332ad981012cfdf8cab79faa1a))\n* **VSelects:** add `aria-controls` and `aria-expanded` ([#22025](https://github.com/vuetifyjs/vuetify/issues/22025)) ([a5abe89](https://github.com/vuetifyjs/vuetify/commit/a5abe893d7d3c9f93d69f60ece5a93185f74bb9a)), closes [#22017](https://github.com/vuetifyjs/vuetify/issues/22017)\n* **VSelects/VCombobox/VAutocomplete:** use rounding from Sass variable ([d3e56de](https://github.com/vuetifyjs/vuetify/commit/d3e56def269205bb84cd26a0c8c24e433045f71a)), closes [#21956](https://github.com/vuetifyjs/vuetify/issues/21956)\n* **VSkeletonLoader:** no wrapper for content ([#21637](https://github.com/vuetifyjs/vuetify/issues/21637)) ([17ae110](https://github.com/vuetifyjs/vuetify/commit/17ae11093e0ff21a0d0d16aa4559bedf86615236)), closes [#21286](https://github.com/vuetifyjs/vuetify/issues/21286)\n* **VSlideGroup:** correct hasNext after resize ([#21124](https://github.com/vuetifyjs/vuetify/issues/21124)) ([0633aef](https://github.com/vuetifyjs/vuetify/commit/0633aef52540f5e9853e25d0ef2ad94e134fe8b2)), closes [#21115](https://github.com/vuetifyjs/vuetify/issues/21115)\n* **VSlider:** respect disabled and readonly from form ([0bbf362](https://github.com/vuetifyjs/vuetify/commit/0bbf3623ae0a66743ead2b23fb7a0dc197a035f2)), closes [#22054](https://github.com/vuetifyjs/vuetify/issues/22054)\n* **VSnackbar:** render border in forced-colors mode ([#21977](https://github.com/vuetifyjs/vuetify/issues/21977)) ([a2249c2](https://github.com/vuetifyjs/vuetify/commit/a2249c24aaed5cce0cc926993829c405b5d11296))\n* **VTimeline:** render lines in forced-colors mode ([#21974](https://github.com/vuetifyjs/vuetify/issues/21974)) ([dc7417c](https://github.com/vuetifyjs/vuetify/commit/dc7417c60c95b34b2f8375eb2269955d846427d9))\n* **VTreeview:** indent lines should support RTL ([1733666](https://github.com/vuetifyjs/vuetify/commit/1733666d5364819b78605185c00deeeef3f2f2a4)), closes [#21952](https://github.com/vuetifyjs/vuetify/issues/21952)\n* **VTreeview:** match type of update:opened with VList ([#22092](https://github.com/vuetifyjs/vuetify/issues/22092)) ([8924b4d](https://github.com/vuetifyjs/vuetify/commit/8924b4d4230cba102f3293fca0fa4c569909eb3c)), closes [#22091](https://github.com/vuetifyjs/vuetify/issues/22091)\n* **VTreeview:** support prepend icon and avatar ([#21813](https://github.com/vuetifyjs/vuetify/issues/21813)) ([478230a](https://github.com/vuetifyjs/vuetify/commit/478230abcdc0fb156523cc9edd4d5f10eea3e069)), closes [#21812](https://github.com/vuetifyjs/vuetify/issues/21812)\n* **VWindow:** override `transition-duration` to respect user preference ([27fe364](https://github.com/vuetifyjs/vuetify/commit/27fe36478ae161b7758a08c8dd4b70e7068a8f06))\n\n### :test_tube: Labs\n\n* **mask:** create useMask composable ([#21736](https://github.com/vuetifyjs/vuetify/issues/21736)) ([a687f7a](https://github.com/vuetifyjs/vuetify/commit/a687f7a38f4377421f47660564fe7f02d6e0231c))\n* **VCalendar:** correct effective weekdays determination ([#22042](https://github.com/vuetifyjs/vuetify/issues/22042)) ([54e6674](https://github.com/vuetifyjs/vuetify/commit/54e667426d5ddefbab951d240511cfc74afa0233))\n* **VCalendar:** directly port from v2 ([#21910](https://github.com/vuetifyjs/vuetify/issues/21910)) ([2e6f72b](https://github.com/vuetifyjs/vuetify/commit/2e6f72baf3a8337dee76e321ed5e18910159c5f6)), closes [#19065](https://github.com/vuetifyjs/vuetify/issues/19065) [#20098](https://github.com/vuetifyjs/vuetify/issues/20098) [#20947](https://github.com/vuetifyjs/vuetify/issues/20947) [#20970](https://github.com/vuetifyjs/vuetify/issues/20970) [#21379](https://github.com/vuetifyjs/vuetify/issues/21379) [#21783](https://github.com/vuetifyjs/vuetify/issues/21783) [#21964](https://github.com/vuetifyjs/vuetify/issues/21964) [#22016](https://github.com/vuetifyjs/vuetify/issues/22016) [#22018](https://github.com/vuetifyjs/vuetify/issues/22018)\n* **VCalendar:** fix click:date event error ([97d3a3e](https://github.com/vuetifyjs/vuetify/commit/97d3a3eed1add2b3957bb65916ebf234e9bf8e67)), closes [#22079](https://github.com/vuetifyjs/vuetify/issues/22079)\n* **VCalendar:** prevent month view event duplication ([977a7e2](https://github.com/vuetifyjs/vuetify/commit/977a7e2a2e400092723e44024c23a2f56947ac77)), closes [#22062](https://github.com/vuetifyjs/vuetify/issues/22062)\n* **VCalendar:** translate eventMoreText ([e41e091](https://github.com/vuetifyjs/vuetify/commit/e41e091f10a13aa55b14b567272412391617ff1a)), closes [#22062](https://github.com/vuetifyjs/vuetify/issues/22062)\n* **VCalendar:** use camelCase event names ([8b2fae3](https://github.com/vuetifyjs/vuetify/commit/8b2fae3428d2228660c8c8d80721da5bb9a9db6d)), closes [#22063](https://github.com/vuetifyjs/vuetify/issues/22063)\n* **VDateInput:** pass-through picker slots ([#21975](https://github.com/vuetifyjs/vuetify/issues/21975)) ([d91dad0](https://github.com/vuetifyjs/vuetify/commit/d91dad08751717ca2097932774485a939e2d9ca7))\n* **VMaskInput:** fix caret position while editing ([#21925](https://github.com/vuetifyjs/vuetify/issues/21925)) ([27dc68c](https://github.com/vuetifyjs/vuetify/commit/27dc68caec935395fdd0d713e106db06f7e00404)), closes [#21776](https://github.com/vuetifyjs/vuetify/issues/21776)\n* **VPicker:** add `hide-title` prop ([#21657](https://github.com/vuetifyjs/vuetify/issues/21657)) ([8d7eac3](https://github.com/vuetifyjs/vuetify/commit/8d7eac3dcd80387e4d3118f1660d7fb25251f66a)), closes [#21545](https://github.com/vuetifyjs/vuetify/issues/21545)\n* **VVideo:** avoid interaction conflicts with VOverlay ([10a1821](https://github.com/vuetifyjs/vuetify/commit/10a18215226793f2832a5b68ebec52241f8db2c7)), closes [#21962](https://github.com/vuetifyjs/vuetify/issues/21962)\n* **VVideo:** background variant should fill the container ([b766424](https://github.com/vuetifyjs/vuetify/commit/b76642493c7144df3573e6bedf4a62c7ea5c94e7))\n\n### :arrows_counterclockwise: Reverts\n\n* Revert \"fix(VSelect): use selected text instead of value (#21902)\" ([95dea2c](https://github.com/vuetifyjs/vuetify/commit/95dea2c3934d58fbebb50cde6314f19e8305cb1d)), closes [#22006](https://github.com/vuetifyjs/vuetify/issues/22006)\n* Revert \"fix(VBtn, VChip): correct link active state after navigation cancellation (#21651)\" ([ab28070](https://github.com/vuetifyjs/vuetify/commit/ab28070a432a15ab8ae0aeba8faa0ab0cb0b4d38)), closes [#22072](https://github.com/vuetifyjs/vuetify/issues/22072) [#22065](https://github.com/vuetifyjs/vuetify/issues/22065)\n* Revert \"fix(VCombobox): filter matching items when opening first time\" ([44002f6](https://github.com/vuetifyjs/vuetify/commit/44002f65364c524953a955479cd5badb3d926cf9)), closes [#22077](https://github.com/vuetifyjs/vuetify/issues/22077)\n\n</details>\n\n## The Pieces Come Together{ .mt-4 }\n\nThis month has been busy. We shipped a complete Figma UI Kit update, built out critical composables for v0, hardened our build infrastructure, and continued the steady march of bug fixes and improvements across the framework. Each piece matters, but what matters more is how they fit together—designers working from the same components developers implement, composables that solve real auth and feature flag problems, tools that make sharing work easier.\n\nOctober brings our v0 live coding webinar where I'll build something real and show you what these composables actually look like in practice. We'll keep stabilizing Labs components and working through the community roadmap. As always, thanks for the bug reports, PRs, and Discord help. See you next month.\n\n---\n\n*The Vuetify Team*\n"
  },
  {
    "path": "packages/docs/src/pages/en/blog/state-of-the-union-2024-post-mortem.md",
    "content": "---\nlayout: blog\nmeta:\n  title: State of the Union 2024 Post Mortem\n  description: An update about where we are currently post 2024 State of the Union\n  keywords: vuetify, blog, updates, state of the union\n---\n\n# State of the Union 2024 Post Mortem\n\n---\n\n🖊️ John Leider • 📅 March 19th, 2025\n\n<PromotedEntry />\n\n---\n\nLast year, I stood at a crossroads. Balancing the weight of family, a new job, and Vuetify, I realized something had to change. I underestimated how heavy it had become to carry Vuetify forward with dwindling support from the team. I took on a job at Optikka, hoping it would bring stability, but it left me with little energy to dedicate to the framework. I left the [State of the Union](/blog/state-of-the-union-2024) on a positive note, knowing that there would be challenges ahead, but I was hopeful that we would be able to overcome them.\n\nI had this naive hope Kael could run with Vuetify while I got my bearings, but it's not that kind of machine—it doesn't coast. When he couldn't make it move, it was like a gut check: had we just blown it for everyone who's stuck with us? This isn't just a project—it's who I am, and watching it stall hurt. I'd been drifting in a haze, probably for months, maybe more, wrestling stuff I didn't name until now. These new team members? They're not here to patch a leak. They're the shove I needed to remember why I started, why Vuetify's still worth every ounce we've got.\n\n## The Shift\n\nIn December, I knew I had to breathe life back into Vuetify. That meant confronting my mistakes—acknowledging that I hadn't done enough to keep the core team motivated and moving; I had been stuck in an era of thinking that wasn't working anymore. For seven years, I searched for team members the same way, expecting different results. Finding team members organically works in the beginning when hype is high, but when the hype dies down, you need to be more proactive.\n\nI needed to change my approach. I needed to find people who were as passionate about Vuetify as I was, but also willing to step up and take ownership. { .blockquote .border-s-lg }\n\nSo I posted a job listing, hoping to find that one person who could inject fresh energy into Vuetify. The response was crazy—over 130 applications poured in (at least I think it's a lot), each one a reminder of how much this community still cares. But as I sifted through them, I kept hitting a wall: one person couldn't carry it all, not anymore. By Day 2, a new question started nagging at me: What if instead of hiring one person, I brought on multiple contributors in focused roles?\n\nThat's where it shifted. Some of the sharpest candidates weren't after a full-time gig—many only wanted to give five hours a week. What if we shared the load, each person bringing their strengths? I floated it to them, and their excitement lit up the conversations.\n\nOn Day 3, everything clicked, and the enthusiasm for what we could accomplish as a team became undeniable. And when I started seeing how well these individuals fit into key areas of the framework—from NUXT, to component development, documentation, scaffolding, and tooling—it just started making sense.\n\n## Meet the Seven New Core Team Members\n\nThis isn't some random lineup—it's a crew of passionate coders stepping up to shape Vuetify's future. Together, they'll tackle everything from components to docs to ecosystem tools, adding over 50 years of combined Vuetify experience. Here's who they are:\n\n- **Shubham Patlani (Technical Lead)** - Leading the team with nearly a decade of experience, Shubham will be at the helm, managing and organizing core team efforts.\n- **Isaias Briones** - Focused on Documentation and the Calendar component.\n- **Henry Aviles** - Focused on the Vuetify API, [Vuetify One](https://one.vuetifyjs.com/), and Vuetify MCP.\n- **Ishan Subedi** - Focused on all things dates, GitHub issues, and pull requests.\n- **Andrei Elkin** - Focused on [Nuxt integration](https://github.com/vuetifyjs/vuetify-loader), [Vuetify Create](https://github.com/vuetifyjs/create), and [Vuetify Loader](https://github.com/vuetifyjs/vuetify-loader).\n- **JC Puno** - Focused on [Nuxt integration](https://github.com/vuetifyjs/vuetify-loader) and SSR support.\n- **Abdelouahed Oumoussa** - Focused on [Vuetify Play](https://play.vuetifyjs.com/), [Vuetify Bin](https://bin.vuetifyjs.com/), [Vuetify Awesome](https://github.com/vuetifyjs/awesome), [Issues Generator](https://issues.vuetifyjs.com/), and implementing ecosystem features.\n\nThese Vuetify heavy hitters are joining the existing ranks of core team members, including myself, Kael, and a few others. We're not just adding bodies—we're stacking the team with talent that's ready to dig in and carry this framework forward together.\n\n## Investing in the Future\n\nHow do we pay for this dream team? Glad you asked. The Open Collective's got $6,800 coming in monthly, and we're sitting on just over $16,000. With the new hires, that's six months before we're back to bartering with coffee. So, I threw in $5,000 of my own—call it a nudge to see if anyone's paying attention.\n\n![Donation to Vuetify Open Collective](https://vuetifyjs.b-cdn.net/docs/images/blog/state-of-the-union-2024-post-mortem/donation.png \"Donation to Vuetify Open Collective\"){ height=300 }\n\nIf 30 companies matched me, we'd fund Vuetify for years. You're rolling your eyes, I can feel it—but picture this: you hit that [Open Collective link](https://opencollective.com/vuetify), and suddenly we're not just a team, we're a movement. I've seen this [community rally before](https://github.com/vuetifyjs/vuetify/issues/2240).\n\n## Closing: The Road Ahead\n\nI can't thank this community enough—for sticking with us, for believing in Vuetify even when I faltered. We've lost some along the way, and I own that, but now it's time to build smarter, together. With this team and your support, we'll hit the precision this next chapter demands. How incredible could that be?\n\nIf this stirs you, join us on [Discord](https://community.vuetifyjs.com) or pitch in directly. Companies using Vuetify, let's shape its future together. This has always been about us—all of us—and it still is.\n"
  },
  {
    "path": "packages/docs/src/pages/en/blog/state-of-the-union-2024.md",
    "content": "---\nlayout: blog\nmeta:\n  title: Vuetify — State of the Union 2024\n  description: Reflecting on the journey and looking ahead for 2025\n  keywords: vuetify, blog, news, updates, stories, ecosystem, state of the union\n---\n\n<script setup>\n  import AboutTeamMember from '@/components/about/TeamMember.vue'\n  import { VSparkline } from 'vuetify'\n\n  const teams = useTeamMembersStore()\n  const kael = computed(() => teams.members.find(member => member.github === 'KaelWD'))\n</script>\n\n# State of the Union 2024\n\n---\n\n🖊️ John Leider • 📅 September 8th, 2024\n\n<PromotedEntry />\n\n---\n\n## Introduction\n\nIt's been a long road to get where we are today, and looking back, I can’t help but feel proud of how far Vuetify has come. From humble beginnings to now surpassing Vuetify 2’s usage, the journey has been anything but easy, but we’ve always had our community to lean on. Today, I want to take some time to reflect on our past, acknowledge our wins and challenges, and share where we're headed.\n\n## Looking Back – The Journey So Far\n\nFirst, I'd like to reflect on what we've been up to for the past year. Since November 2023, we’ve hit some incredible milestones. This includes the release of `v-data-table`, and over 10 other new and old components. Each of these components was designed with developer feedback in mind, making the framework more flexible and feature-complete. We’ve also made significant progress on our ecosystem tools, with Vuetify One, Vuetify Bin, Vuetify Playground, and Vuetify Snips all seeing major updates.\n\n![Image of 4 releases banner](https://vuetifyjs.b-cdn.net/docs/images/blog/state-of-the-union-2024/releases.png \"Release banners\")\n\n- [**v3.4 (Blackguard)**](/getting-started/release-notes/?version=v3.4.0) in November 2023 brought 8 new components:\n  - [`v-bottom-sheet`](/components/bottom-sheets/)\n  - [`v-data-iterator`](/components/data-iterators/)\n  - [`v-data-table`](/components/data-tables/introduction/)\n  - [`v-date-picker`](/components/date-pickers/)\n  - [`v-infinite-scroll`](/components/infinite-scroller/)\n  - [`v-otp-input`](/components/otp-input/)\n  - [`v-skeleton-loader`](/components/skeleton-loaders/)\n  - [`v-stepper`](/components/steppers/)\n- [**v3.5 (Polaris)**](/getting-started/release-notes/?version=v3.5.0) in January 2024 was a maintenance cycle for bug fixes and performance improvements. This release focused heavily on refining existing components, ensuring performance remained high across all devices.\n- [**v3.6 (Nebula)**](/getting-started/release-notes/?version=v3.6.0) in April 2024 brought 5 new components:\n  - [`v-fab`](/components/floating-action-buttons/)\n  - [`v-empty-state`](/components/empty-states/)\n  - [`v-sparkline`](/components/sparklines/)\n  - [`v-speed-dial`](/components/speed-dials/)\n  - [`v-confirm-edit`](/components/confirm-edit/)\n\n- [**v3.7 (Odyssey)**](/getting-started/release-notes/?version=v3.7.0) in August 2024 improved sub `v-menu` support and added new input validation options, making form handling more intuitive and robust.\n\n---\n\nIn addition, we've made significant progress on our ecosystem tools:\n\n![Image of all ecosystem logos](https://vuetifyjs.b-cdn.net/docs/images/blog/state-of-the-union-2024/ecosystem.png \"Ecosystem logos\")\n\n- [**Vuetify One**](/blog/state-of-the-union-2024/?one=subscribe) (January 2024) unified our tools for authentication and state management across the entire Vuetify ecosystem.\n- [**Vuetify Bin**](https://bin.vuetifyjs.com/) (March 2024) was launched as a simple and easy pastebin alternative.\n- [**Vuetify Playground**](https://play.vuetifyjs.com/) (March 2024) was updated to support saving remote playgrounds for easy sharing with the Vuetify One subscription.\n- [**Vuetify Snips**](https://snips.vuetifyjs.com/) (April 2024) became our first stand-alone product, showcasing advanced Vuetify examples to help fund ongoing development.\n- **Vuetify Issues** (On Deck) is a rebuild of our existing [issues website](https://issues.vuetifyjs.com/), with a focus on improving the user experience and making it easier to find solutions to common problems.\n\nI'm _extremely_ proud of the team and all that we've been able to accomplish during this time. One of our toughest challenges has been developer churn, where several components were started by one developer and finished by another. But through these transitions, we've continued pushing forward with the support of our amazing community.\n\nA huge win has been the financial support through Open Collective and GitHub Sponsors, with over **$8,000** per month on both platforms. This funding ensures that Vuetify development will continue at full speed.\n\nPlease give a shoutout to our [sponsors and backers](/introduction/sponsors-and-backers/) for their ongoing support. 🎉\n\n## Current State – Where We Are Now\n\nToday, Vuetify is in an exciting place. While we are still recovering from a tough financial **drought**, things are looking up. Thanks to generous contributions from companies like [Abacus](https://www.abacus.ch/), [Route4Me](https://route4me.com/), and [Teamwork](https://teamwork.com), the framework is now back at full speed.\n\nWith that being said, those who followed my post earlier back in [June](https://x.com/zeroskillz/status/1803081840669937724) will know that I've been seeking employment in lieu of the financial situation. During this time, I connected with a company named Optikka. Their entire platform is built on Vue / Vuetify and they were gracious enough to offer me a Senior Developer position. I've been with them for a little over a month now and it's been an amazing experience. I've been able to bring my knowledge of Vuetify to the team and help them build out their platform.\n\nWith that in mind, I have taken a step back to analyze my role in Vuetify and decided to pass creative and engineering control of the framework over to [Kael](https://github.com/kaelwd). The recent events forced my focus to shift to higher-level tasks, ensuring we never encounter a funding crisis like we did, while still fostering creativity within the team. I'll remain an active contributor, but my role will be different moving forward.\n\n<AboutTeamMember v-if=\"kael\" v-bind=\"{ member: kael }\" class=\"mb-4\" />\n\nKael is a Senior Developer who has been with Vuetify since the beginning. He has a deep understanding of the framework and has been instrumental in shaping its direction. He is responsible for a lot of the cool technology in Vuetify and he still has a lot more in the tank. I have full confidence in his ability to lead the team and continue pushing Vuetify forward.\n\n### Growth 🚀\n\nOur user base continues to grow, with Vuetify 3 usage officially surpassing Vuetify 2. The demand for the new features and improved performance has been immense, and it’s been amazing to watch our community evolve. The team remains as dedicated as ever to bringing you the best possible UI framework.\n\n![Graph showing weekly download statistics for Vuetify 0, 1, 2 and 3](https://vuetifyjs.b-cdn.net/docs/images/blog/state-of-the-union-2024/downloads.png \"Vuetify download statistics\")\n\n### Ongoing Success 📈\n\nA key recent success story is [**Vuetify Snips**](https://snips.vuetifyjs.com/). It’s quickly become a popular resource for developers looking for premade snippets, supercharging their workflow and easing adoption of Vuetify 3. It's also a beneficial way to support the framework. All sales from Snips go directly back into Vuetify development.\n\n### Roadmap Updates 🛣️\n\nWe have an updated roadmap for the remainder of the year, and I encourage everyone to check it out on the [Vuetify Roadmap](https://vuetifyjs.com/introduction/roadmap). There's a lot in store, and we’re excited to keep pushing the framework forward. 🎯\n\n## Looking Ahead – The Future\n\nLooking ahead, we're focused on making Vuetify even easier to customize. One exciting change will be the splitting out of our CSS utilities from the core framework, which will pave the way for 3rd party integration with other tools such as Tailwind. We want Vuetify to be as flexible as possible, giving developers the ability to choose the tools that work best for their needs, which is why we plan to expand the functionality of blueprints by moving core styling from SASS variables to CSS variables, making them easily configurable through the Vuetify config.\n\nAs always, the community will be at the heart of Vuetify’s future. [Contributions](/getting-started/contributing/) and [funding](/introduction/sponsors-and-backers/) will be instrumental as we continue to expand the ecosystem. We’re always looking for code contributions, so if you're interested in learning how to help with the framework, feel free to reach out to me!\n\nAnd of course, our [Discord community](https://community.vuetifyjs.com) is always buzzing with activity. If you're looking to engage with fellow developers, troubleshoot issues, or just hang out, we'd love to see you there! 💬\n\n## Personal Reflections\n\nBuilding Vuetify full-time has been nothing short of a blessing. I’ve always loved the challenge of creating UI components, and it’s something I look forward to continuing. Working in Open Source comes with its ups and downs, and one major lesson I’ve learned is this: if you want to do Open Source full-time, you need to build something that can generate revenue.\n\nIt’s the key to sustaining yourself during those inevitable moments when excitement fades and donations slow. For me, it's always been about providing the absolute most value for free without gating functionality behind a paywall. I feel that Snips strikes a perfect balance between the two, and I'm excited to see where it goes.\n\nLooking back, I’ve learned some critical lessons that I’d pass on to anyone considering building or contributing to an open-source project:\n\n1. **Sustainability is key**: Passion alone isn’t enough. You need to think about how to generate income to keep the project going long-term, whether through sponsorships, paid products, or other creative avenues.\n2. **Community is your foundation**: Open Source lives and dies by its community. Engage with your users, listen to their feedback, and be open to contributions. Vuetify wouldn’t be where it is today without the incredible people supporting it.\n3. **Set clear goals**: It’s easy to get caught up in features or get sidetracked by shiny new things. Having a clear roadmap, with both short and long-term goals, helps keep development focused and moving forward, even during challenging times.\n4. **Developer retention is a challenge**: Open-source projects often suffer from turnover, especially when contributors are volunteers. Ensuring smooth transitions, proper documentation, and a welcoming environment can help mitigate some of this churn.\n\nVuetify has changed me in more ways than one. It’s helped me grow not just as a developer but as a leader. I’ve learned the importance of perseverance, the value of community, and how crucial it is to always plan for the long term. I’m excited to see where Vuetify goes from here, and I’m grateful to have been part of this journey.\n\n## Conclusion\n\nAs we look to the future, I want to thank every single one of you who has been part of this experiment, whether as a user, contributor, or supporter. The road ahead is bright, and with your help, we’re going to continue bringing high quality features to enhance your Vuetify development experience.\n\nThis is just the first of many blog posts to come. Stay tuned for future updates, tutorials, community highlights, and much more. We’re just getting started. 🔥\n"
  },
  {
    "path": "packages/docs/src/pages/en/blog/vuetify-herodevs-partnership.md",
    "content": "---\nlayout: blog\nmeta:\n  title: Vuetify HeroDevs Partnership\n  description: Vuetify partners with HeroDevs to provide extended long-term support for Vuetify 2 users through Vue 2 NES + Essentials, ensuring security and compliance.\n  keywords: Vuetify, HeroDevs, Vue 2 NES, long-term support, security, compliance, Vuetify 2, partnership\n---\n\n# Vuetify HeroDevs Partnership\n\n---\n\n🖊️ Taylor Corbett • 📅 March 28th, 2025\n\n<PromotedEntry />\n\n---\n\n## Vuetify Partners with HeroDevs to Provide Long-Term Support for Vuetify 2\n\nVuetify is excited to announce a partnership with HeroDevs to provide extended long-term support for Vuetify 2 users through **Vue 2 NES + Essentials**, a secure drop-in replacement.\n\n[Vuetify 2 reached end-of-life (EOL) on January 23, 2025](/introduction/long-term-support/), meaning it no longer receives official updates. Applications still relying on Vuetify 2 are now at risk of security vulnerabilities, compliance issues, and compatibility challenges.\n\nFor teams that haven’t yet migrated to Vuetify 3, whether due to project constraints, long-term maintenance needs, or regulatory requirements, HeroDevs offers Vue 2 NES + Essentials—a solution designed to keep applications secure and up to date without requiring an immediate migration.\n\n“I am glad to partner with HeroDevs to give Vuetify 2 users and teams a secure solution. I know that HeroDevs teams are reactive and well-trained, giving us more focus on the future of Vuetify.”\n<br><span class=\"text-body-small font-weight-bold\">— John Leider, Creator of Vuetify</span> { .blockquote .border-s-lg }\n\n### Why This Partnership Matters\n\nVuetify 2 has been widely adopted across industries, helping developers build high-quality, responsive applications. While many teams have transitioned to Vuetify 3, not all applications can be migrated immediately. Some businesses require long-term stability, regulatory compliance, or compatibility with existing systems, making an immediate upgrade difficult.\n\nWith **HeroDevs' Vue 2 NES + Essentials**, organizations can continue using Vuetify 2 while receiving:\n\n- ✅ **Security patches** for known vulnerabilities\n- ✅ **Compliance updates** to meet regulatory standards\n- ✅ **Compatibility fixes** to maintain stability in modern environments\n\n### Supporting the Vuetify Community\n\nWhile Vuetify is focused on the future with Vuetify 3 and beyond, we recognize the importance of providing a secure option for teams that still rely on Vuetify 2. Partnering with HeroDevs ensures that these users have a reliable, long-term solution to keep their applications secure.\n\nFor more information on **Vue 2 NES + Essentials**, visit [HeroDevs.com](https://www.herodevs.com/blog-posts/vuetify-2-end-of-life-ensuring-continued-support-with-herodevs-never-ending-support?utm_source=partnership&utm_medium=coblog&utm_campaign=Vuetify2&utm_id=vuetify+partnership) to learn how to keep your Vuetify 2 application secure and current.\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/alerts.md",
    "content": "---\nmeta:\n  nav: Alerts\n  title: Alert component\n  description: The v-alert component is used to convey information to the user. Designed to stand out, the alerts come in four contextual styles.\n  keywords: v-alert, alerts, vue alert component, vuetify alert component\nrelated:\n  - /components/buttons/\n  - /components/icons/\n  - /components/snackbars/\nfeatures:\n  figma: true\n  github: /components/VAlert/\n  label: 'C: VAlert'\n  report: true\n---\n\n# Alerts\n\nThe `v-alert` component is used to convey important information to the user through the use of contextual types, icons, and colors.\n\n<PageFeatures />\n\n## Usage\n\nAn alert is a [v-sheet](/components/sheets/) that specializes in getting the user's attention. While similar to [v-banner](/components/banners/) in functionality, `v-alert` is typically inline with content and used multiple times throughout an application.\n\n<ExamplesUsage name=\"v-alert\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-alert](/api/v-alert/) | Primary Component |\n| [v-alert-title](/api/v-alert-title/) | Sub-component used to display the `v-alert` title. Wraps the `#title` slot |\n\n## Anatomy\n\nThe recommended placement of elements inside of `v-alert` is:\n\n* Place a `v-icon` on the far left\n* Place `v-alert-title` to the right of the contextual icon\n* Place textual content below the title\n* Place closing actions to the far right\n\n![Alert Anatomy](https://cdn.vuetifyjs.com/docs/images/components-temp/v-alert/v-alert-anatomy.png)\n\n| Element / Area | Description |\n| - | - |\n| 1. Container | The Alert container holds all `v-alert` components |\n| 2. Icon | An icon that correlates to the contextual state of the alert; **success, info, warning, error** |\n| 3. Title | A heading with increased font-size |\n| 4. Text | A content area for displaying text and other inline elements |\n| 5. Close Icon (optional) | Used to hide the `v-alert` component |\n\n<ApiInline hide-links />\n\n## Guide\n\nThe `v-alert` component is a callout element designed to attract the attention of a user. Unlike [v-banner](/components/banners/), the `v-alert` component is intended to be used and re-used throughout your application. An alert's color is derived from its **type** property which corresponds to your application's contextual [theme colors](/features/theme/#custom-theme-colors) and [iconfont aliases](/features/icon-fonts/#creating-a-custom-icon-set).\n\n### Props\n\nIn addition to the standard [v-sheet](/components/sheets/) properties such as elevation, dimension, and border-radius, the `v-alert` component supports **v-model**, **variants**, and **density**.\n\n#### Content\n\nThe `v-alert` component supports simple content using the **title** and **text** props. This approach is best for strings that do not need custom styling.\n\nThe following code snippet is an example of a basic `v-alert` component only containing text:\n\n```html\n<v-alert text=\"Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus...\"></v-alert>\n```\n\nAdding a title is as easy as defining its value. The next example adds a string title to accompany the content text:\n\n<ExamplesExample file=\"v-alert/prop-content\" />\n\nNotice how the alert does not have a color or icon. This is defined using the **type** property.\n\n#### Type\n\nAlerts have 4 contextual states: **success**, **info**, **warning**, and **error**. Each state has a default _color_ and _icon_ associated with it. When a **type** is not provided, the `v-alert` component defaults to a greyish background.\n\nWith a basic alert rendered, add your choice of contextual type. The following example puts the `v-alert` component in a success state:\n\n<ExamplesExample file=\"v-alert/prop-type\" />\n\n##### Type reference\n\n| Type | Color | Icon alias | Icon |\n| - | - | - | :---: |\n| Success | **success** { .text-success } | $success | <v-icon icon=\"$success\" /> |\n| Info | **info** { .text-info } | $info | <v-icon icon=\"$info\" /> |\n| Warning | **warning** { .text-warning } | $warning | <v-icon icon=\"$warning\" /> |\n| Error | **error** { .text-error } | $error | <v-icon icon=\"$error\" /> |\n\n#### Color and icon\n\nThe **type** property acts as a shorthand for a **color** and **icon** combination, you can use both props individually to achieve the same effect. The following example produces the same result as using **type=\"success\"** by defining a custom color and using the icon lookup table to get the globally defined success icon:\n\n```html\n<v-alert\n  color=\"success\"\n  icon=\"$success\"\n  title=\"Alert title\"\n  text=\"Lorem ipsum dolor sit amet consectetur adipisicing elit. Commodi, ratione debitis quis est labore voluptatibus...\"\n></v-alert>\n```\n\n#### Density\n\nThe `v-alert` component has the ability to reduce its height in intervals using the density prop. This is useful when you need to reduce the vertical space a component needs. The following example reduces the vertical space by using **density=\"compact\"**:\n\n<ExamplesExample file=\"v-alert/prop-density\" />\n\nThe **density** prop supports 3 levels of component height; **default**, **comfortable**, and **compact**.\n\n#### Variants\n\nThe `v-alert` has 6 style variants, **elevated**, **flat**, **tonal**, **outlined**, **text**, and **plain**. By default, the `v-alert` component is **flat**; which means that it has a solid background and no box-shadow (elevation). The following example modifies the overall styling of the alert with a custom variant:\n\n<ExamplesExample file=\"v-alert/prop-variant\" />\n\n#### Closable\n\nThe **closable** prop adds a [v-icon](/components/icons) on the far right, after the main content. This control hides the `v-alert` when clicked, setting it's internal model to **false**. Manually control the visibility of the alert by binding **v-model** or using **model-value**. The following example uses a dynamic model that shows and hides the `v-alert` component:\n\n<ExamplesExample file=\"v-alert/prop-closable\" />\n\nThe close icon automatically applies a default `aria-label` and is configurable by using the **close-label** prop or changing **close** value in your locale.\n\n::: info\n  For more information on how to global modify your locale settings, navigate to the [Internationalization page](/features/internationalization).\n:::\n\n## Additional Examples\n\nThe following is a collection of `v-alert` examples that demonstrate how different the properties work in an application.\n\n### Border color\n\nThe **border-color** prop removes the alert background in order to accent the **border** prop. If a **type** is set, it will use the type's default color. If no **color** or **type** is set, the color will default to the inverted color of the applied theme (black for light and white/gray for dark).\n\n<ExamplesExample file=\"v-alert/prop-border-color\" />\n\n### Icon\n\nThe **icon** prop allows you to add an icon to the beginning of the alert component. If a **type** is provided, this will override the default type icon. Additionally, setting the **icon** prop to _false_ will remove the icon altogether.\n\n<ExamplesExample file=\"v-alert/prop-icon\" />\n\n### Outlined\n\nThe **outlined** prop inverts the style of an alert, inheriting the currently applied **color**, applying it to the text and border, and making its background transparent.\n\n<ExamplesExample file=\"v-alert/prop-outlined\" />\n\n## Accessibility\n\nBy default, `v-alert` components are assigned the [WAI-ARIA](https://www.w3.org/WAI/standards-guidelines/aria/) role of [**alert**](https://www.w3.org/TR/wai-aria/#alert) which denotes that the alert \\\"is a live region with important and usually time-sensitive information.\\\" When using the **closable** prop, the close icon will receive a corresponding `aria-label`. This value can be modified by changing either the **close-label** prop or globally through customizing the [Internationalization](/features/internationalization)'s default value for the _close_ property.\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/all.md",
    "content": "---\nmeta:\n  nav: All Components\n  title: All Vuetify Components\n  description: Browse all of the available Vuetify components or group by category.\n  keywords: components, all components, all Vuetify components\n---\n\n# Components\n\nVuetify Components are interactive building blocks for creating user interfaces.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## Containment\n\nContainment components wrap other components and provide additional functionality. They are typically used to provide a consistent layout or styling.\n\n<v-row>\n\n<ComponentsListItem name=\"Button component\" src=\"buttons\">\n\n  The button component allows users to take actions or make choices with a single tap\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Card components\" src=\"cards\">\n\n  The card component is a versatile and enhanced sheet of paper that provides a simple interface for headings, text, images, and actions\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"List components\" src=\"lists\">\n\n  The list component is a display interface for items\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Chip component\" src=\"chips\">\n\n  Chips are useful for displaying small pieces of information\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Divider components\" src=\"dividers\">\n\n  Dividers are used to separate content into distinct sections or groups\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Expansion panel components\"  src=\"expansion-panels\">\n\n  Expansion panels are used to reveal additional content in a compact manner\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Menu component\" src=\"menus\">\n\n  The menu component is used to display a list of actions that the user can make\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Dialog component\" src=\"dialogs\">\n\n  The dialog component informs a user about a specific task and may contain critical information\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Bottom sheet component\" src=\"bottom-sheets\">\n\n  The bottom sheet component elevates content from the bottom of the screen\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Overlay component\" src=\"overlays\">\n\n  The overlay component is used to display a custom scrim that sits on top of the application\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Toolbar components\" src=\"toolbars\">\n\n  Toolbars are used to label a content area and / or display a list of actions that the user can make\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Tooltip component\" src=\"tooltips\">\n\n  Tooltips provide additional information about an element when the user hovers over it\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Sheet component\" src=\"sheets\">\n\n  The sheet component is a simple piece of paper that can be used to style and customize a block of content\n\n</ComponentsListItem>\n\n</v-row>\n\n----\n\n## Navigation\n\nNavigation components are used to navigate between different views or pages.\n\n<v-row>\n\n<ComponentsListItem name=\"App bars\"  src=\"app-bars\">\n\n  The app bar is used for top level navigation items and current page actions\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"FABs\" src=\"floating-action-buttons\">\n\n  The floating action button is used for a promoted actions within an application\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Navigation drawers\"  src=\"navigation-drawers\">\n\n  Navigation drawers contain primary application navigation links\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Pagination component\" src=\"paginations\">\n\n  The Pagination component is used to separate long sets of data\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Bottom navigation\"  src=\"bottom-navigation\">\n\n  The bottom navigation component is used for displaying navigation links on mobile\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Breadcrumbs components\" src=\"breadcrumbs\">\n\n  Breadcrumbs are navigational helpers for router pages\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Footer component\" src=\"footers\">\n\n  The footer component is a simple navigation area with inner site links\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Speed dials\" src=\"speed-dials\">\n\n  The speed dial component is a floating action button that can reveal additional actions when clicked\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"System bar\"  src=\"system-bars\">\n\n  The system bar component shows application information with iconography, time, and more\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Tabs components\" src=\"tabs\">\n\n  Tabs are used to organize content into different sections that can be viewed independently\n\n</ComponentsListItem>\n\n</v-row>\n\n----\n\n## Form inputs and controls\n\nForm components are used to collect user input in a variety of ways.\n\n<v-row>\n\n<ComponentsListItem name=\"Autocomplete component\" src=\"autocompletes\">\n\n  Autocompletes are used to provide suggestions to the user as they type into a field\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Combobox components\" src=\"combobox\">\n\n  The combobox component is used to select a value from a list of options with the ability to enter a custom value\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Text field\"  src=\"text-fields\">\n\n  The text field component accepts textual input from users and is a replacement for the native text input element\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Checkbox components\" src=\"checkboxes\">\n\n  The checkbox component is a replacement for the native input checkbox\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Switch components\" src=\"switches\">\n\n  The switch component is an alternately styled checkbox\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Radio button\"  src=\"radio-buttons\">\n\n  The radio component is a replacement for its native counterpart\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"File input\"  src=\"file-inputs\">\n\n  The file input component is used to select files from the user's device and is a replacement for the native file input element\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Form component\" src=\"forms\">\n\n  The form component is used to wrap form elements and provide a consistent styling and a single source for validation\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Inputs component\" src=\"inputs\">\n\n  Create custom inputs that can be used with the v-model directive\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Number input component\" src=\"number-inputs\" labs>\n\n  The number input component is used for collecting numerical data from the user\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"OTP Input component\" src=\"otp-input\" >\n\n  The OTP input component is used for MFA authentication via input field\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Select component\" src=\"selects\">\n\n  The select component is used to select a value from a list of options and is a replacement for the native select element\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Slider component\" src=\"sliders\">\n\n  Sliders are used to select a value from a range of values by moving a slider thumb and are a replacement for the native input range element\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Range slider\"  src=\"range-sliders\">\n\n  Range sliders are regular sliders with the ability to select in a range\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Textarea component\" src=\"textareas\">\n\n  The textarea component is a replacement for the native textarea element\n\n</ComponentsListItem>\n\n</v-row>\n\n----\n\n## Layouts\n\nLayout components are used to create responsive layouts.\n\n<v-row>\n\n<ComponentsListItem name=\"grids\" src=\"grids\">\n\n  The grid component is used to create responsive layouts\n\n</ComponentsListItem>\n\n</v-row>\n\n----\n\n## Selection\n\nThese components allow a user to select one or multiple items from a list of options.\n\n<v-row>\n\n<ComponentsListItem name=\"Carousel component\" src=\"carousels\">\n\n  Carousels are used to display multiple forms of visual content\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Button group\" src=\"button-groups\">\n\n  Button groups are used to select between multiple options using the button component\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Chip group\" src=\"chip-groups\">\n\n  Chip group is a wrapper component that makes chips interactive and allows them to be selected\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Window components\" src=\"windows\">\n\n  The window component is used to display a block of content based upon a model\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Stepper components\" src=\"steppers\">\n\n  The stepper component is a linear progress control used to break lengthy forms into smaller logical sections\n\n</ComponentsListItem>\n\n</v-row>\n\n----\n\n## Data and display\n\nThese components are used to display data and information in a variety of ways.\n\n<v-row>\n\n<ComponentsListItem name=\"Confirm edit component\" src=\"confirm-edit\">\n\n  The confirm edit component is used to confirm changes to data\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Data iterator component\" src=\"data-iterators\">\n\n  The data iterator component provides an easy interface for paginating and sorting data\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Data table component\"  src=\"data-tables/basics\">\n\n  Data tables are used to display large amounts of data in a small amount of space\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Infinite scroll component\"  src=\"infinite-scroller\">\n\n  The Infinite scroll component is a container that loads more items when scrolling\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Server-side table component\"  src=\"data-tables/server-side-tables\">\n\n  Server side data tables are intended to be used with a server side data source\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Sparkline component\" src=\"sparklines\">\n\n  The sparkline component creates beautiful and expressive simple graphs for displaying numerical data\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Virtual Data table component\"  src=\"data-tables/virtual-tables\">\n\n  The virtual data table component is used to display very large subsets of data\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Table component\" src=\"tables\">\n\n  The table component is a barebones table for manually displaying data and is a replacement for the native table element\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Virtual scroll component\"  src=\"virtual-scroller\">\n\n  The virtual scroller component makes it possible to render large amounts of data without sacrificing performance\n\n</ComponentsListItem>\n\n</v-row>\n\n----\n\n## Feedback\n\nThese components are used to provide feedback to the user within content, over content, or in response to user actions.\n\n<v-row>\n\n<ComponentsListItem name=\"Alert component\" src=\"alerts\">\n\n  Alerts convey important information to the user\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Badge component\" src=\"badges\">\n\n  Badges superscript or subscript an avatar-like icon or text onto content.\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Banner component\" src=\"banners\">\n\n  Banners are used to communicate important information to the user\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Empty state component\" src=\"empty-states\">\n\n  The empty state component is used to indicate that a page or area on a page has no content.\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Skeleton loader component\" src=\"skeleton-loaders\">\n\n  Displays a content, enhancing perceived performance during data-fetching & rendering\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Snackbar component\" src=\"snackbars\">\n\n  The snackbar component is used to display a message to the user that hovers over existing content\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Rating component\" src=\"ratings\">\n\n  Ratings are useful for collecting user feedback\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Timeline components\" src=\"timelines\">\n\n  Timeline components are used to display a list of events in chronological order\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Hover component\" src=\"hover\">\n\n  The hover component is a wrapper component that allows you to react to hover events\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Progress circular component\"  src=\"progress-circular\">\n\n  Circular progress's are a visual indicator of numerical data in a circle\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Progress linear component\"  src=\"progress-linear\">\n\n  The linear progress component is used to display numerical data in a horizontal line\n\n</ComponentsListItem>\n\n</v-row>\n\n----\n\n## Images and icons\n\nThis subset of components are used to display media in a variety of ways.\n\n<v-row>\n\n<ComponentsListItem name=\"Aspect ratios component\"  src=\"aspect-ratios\">\n\n  The aspect ratio component enforces a defined ratio\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Avatar component\" src=\"avatars\">\n\n  Avatars are used in numerous components to display avatars and profile pictures\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Icon component\" src=\"icons\">\n\n  The icon component is an reusable component that can be used to display icons\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Image component\" src=\"images\">\n\n  The image component provides a flexible interface for displaying images\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Parallax component\" src=\"parallax\">\n\n  Creates a 3d effect that makes an image appear to move slower than the foreground\n\n</ComponentsListItem>\n\n</v-row>\n\n----\n\n## Pickers\n\nThese components are used to select a value from a specifically styled set of options.\n\n<v-row>\n\n<ComponentsListItem name=\"Color picker component\"  src=\"color-pickers\">\n\n  The color picker component is used to select a color from a palette\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Date picker component\" src=\"date-pickers\">\n\n  The date picker component is used to select a single date from a calendar month / year.\n\n</ComponentsListItem>\n\n</v-row>\n\n----\n\n## Providers\n\n<v-row>\n\n<ComponentsListItem name=\"Defaults provider component\"  src=\"defaults-providers\">\n\n  The defaults provider component is used to set default values for all components within a template\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Locale provider component\"  src=\"locale-providers\">\n\n  The locale provider component allows you to change the language of all components within its slot\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"Theme provider component\"  src=\"theme-providers\">\n\n  The theme provider component allows you to change the theme of all children components\n\n</ComponentsListItem>\n\n</v-row>\n\n----\n\n## Miscellaneous\n\nThese components don't fit into a traditional category and are used for a variety of purposes.\n\n<v-row>\n\n<ComponentsListItem name=\"Lazy component\" src=\"lazy\">\n\n  The lazy component is a wrapper component that prevents the rendering of its child components until it is visible in the viewport\n\n</ComponentsListItem>\n\n<ComponentsListItem name=\"No-ssr component\"  src=\"no-ssr\">\n\n  This component is used to prevent the rendering of its child components on the server\n\n</ComponentsListItem>\n\n</v-row>\n\n::: info\n  This page is under **design** construction and will be updated with the missing images over time.\n:::\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/app-bars.md",
    "content": "---\nmeta:\n  nav: App bars\n  title: App-bar component\n  description: The app bar component is a supercharged toolbar with advanced scrolling techniques and application layout support.\n  keywords: app bars, vuetify app bar component, vue app bar component\nrelated:\n  - /components/buttons/\n  - /components/icons/\n  - /components/toolbars/\nfeatures:\n  figma: true\n  label: 'C: VAppBar'\n  report: true\n  github: /components/VAppBar/\n  spec: https://m2.material.io/components/app-bars-top\n---\n\n<script setup>\n  import PropScrollBehavior from '@/examples/v-app-bar/prop-scroll-behavior.vue'\n</script>\n\n# App bars\n\nThe `v-app-bar` component is pivotal to any graphical user interface (GUI), as it generally is the primary source of site navigation.\n\n<PageFeatures />\n\n## Usage\n\nThe `v-app-bar` component is used for application-wide actions and information.\n\n<ExamplesUsage name=\"v-app-bar\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-app-bar](/api/v-app-bar/) | Primary Component |\n| [v-app-bar-nav-icon](/api/v-app-bar-nav-icon/) | A customized [v-btn](/components/buttons/) component that uses a default *icon* value of **$menu** |\n| [v-app-bar-title](/api/v-app-bar-title/) | An extension of `v-toolbar-title` that is used for scrolling techniques |\n\n<ApiInline hide-links />\n\n::: tip\n\nThe app-bar component works great in conjunction with a [v-navigation-drawer](/components/navigation-drawers) for providing site navigation in your application.\n\n:::\n\n## Anatomy\n\nThe recommended placement of elements inside of `v-app-bar` is:\n\n- Place `v-app-bar-nav-icon` or other navigation items on the far left\n- Place `v-app-bar-title` to the right of navigation\n- Place contextual actions to the right of navigation\n- Place overflow actions to the far right\n\n![App Bar Anatomy](https://cdn.vuetifyjs.com/docs/images/components-temp/v-app-bar/v-app-bar-anatomy.png)\n\n| Element / Area | Description |\n| - | - |\n| 1. Container | The App Bar container holds all `v-app-bar` components |\n| 2. App Bar Icon (optional) | A styled icon button component created that is often used to control the state of a `v-navigation drawer` |\n| 3. Title (optional) | A heading with increased **font-size** |\n| 4. Action items (optional) | Used to highlight certain actions not in the overflow menu |\n| 5. Overflow menu (optional) | Place less often used action items into a hidden menu |\n\n::: warning\n\nWhen a `v-btn` with the `icon` prop is used inside of `v-toolbar` and `v-app-bar` they will automatically have their size increased and negative margin applied to ensure proper spacing according to the Material Design Specification. If you choose to wrap your buttons in any container, such as a `div`, you will need to apply negative margin to that container in order to properly align them.\n\n:::\n\n## Examples\n\nThe following are a collection of examples that demonstrate more advanced and real world use of the `v-app-bar` component.\n\n### Props\n\nThe `v-app-bar` component has a variety of props that allow you to customize its look and feel, density, scroll behavior, and more.\n\n#### Scroll behavior\n\nAvailable values:\n\n- **hide**: The default slot area will shift up and hide as the user scrolls down. The extension slot remains visible.\n- **fully-hide**: The entire app bar will hide as the user scrolls down.\n- **collapse**: Shrink horizontally to a small bar in one corner.\n- **elevate**: Add a drop shadow to the app bar when scrolling. Ignores `scroll-threshold`, will always be applied with any amount of scrolling.\n- **fade-image**: Fade out the image as the user scrolls down.\n- **inverted**: Has no effect on its own, but will reverse the behavior when combined with any other option.\n\nThe `scroll-threshold` prop is used to determine how far the user must scroll down (in pixels) before the behavior is applied.\n\nA scroll listener is added to `window` by default, but can be changed to a custom element using the `scroll-target` prop.\n\n<prop-scroll-behavior />\n\n#### Density\n\nYou can make **app-bar** dense. A dense app bar has lower height than regular one.\n\n<ExamplesExample file=\"v-app-bar/prop-density\" />\n\n#### Images\n\n`v-app-bar` can contain background images. You can set source via the `image` prop. If you need to customize the `v-img` properties, the app-bar provides you with an **image** slot.\n\n<ExamplesExample file=\"v-app-bar/prop-image\" />\n\n#### Prominent\n\nAn `v-app-bar` with the `density=\"prominent\"` prop can be used for longer titles, to house imagery, or to provide a stronger presence to the top app bar.\n\n<ExamplesExample file=\"v-app-bar/prop-prominent\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/application.md",
    "content": "---\nmeta:\n  title: Application\n  description: Vuetify comes equipped with a default markup that makes it easy to create layouts (boilerplate) for any Vue application.\n  keywords: default layout, vuetify default markup, vuetify default layout\nrelated:\n  - /features/theme/\n  - /components/app-bars/\n  - /components/navigation-drawers/\nfeatures:\n  report: true\n---\n\n# Application\n\nThe `v-app` component is an optional feature that serves as the root layout component as well as providing an easy way to control the theme used at the root level.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-app](/api/v-app/) | Primary Component |\n| [v-main](/api/v-main/) | Content area |\n\n<ApiInline hide-links />\n\n## Guide\n\nIn Vuetify, the `v-app` component is a convenient way to dynamically modify your application's current theme and provide an entry point for your layouts. When an application is mounted, each layout child registers itself with the closest layout parent and is then automatically placed in your window.\n\n::: info\n  More information on how to interact with the root sizing and styling is on the [Application](/features/application-layout/) page.\n:::\n\nWhen placing your application level components, the order matters. Elements are stacked based on when they register and are rendered in the DOM after the first **nextTick** (to account for suspense). Layouts utilize [suspense](https://vuejs.org/guide/built-ins/suspense) to allow all layout components to register before rendering the initial layout.\n\nThe following example demonstrates how the `v-app-bar` component takes priority over `v-navigation-drawer` because of its rendering order:\n\n<ExamplesExample file=\"application/app-bar-drawer\" open preview  />\n\nIf we swap `v-app-bar` and `v-navigation-drawer`, the registration order changes and the layout system layers the two components differently.\n\n<ExamplesExample file=\"application/drawer-app-bar\" open preview  />\n\n## Theme\n\nThe `v-app` component makes it easy to enable one of your application defined themes. By default, Vuetify comes with 2 themes, **light** and **dark**. Each one is a collection of various colors used to style each individual component. Because `v-app` acts as an interface for [theme](/features/theme/) functionality, you have the ability to change it dynamically within your template.\n\nThe following example demonstrates how to use the **theme** prop to toggle the theme from dark to light.\n\n<ExamplesExample file=\"application/theme\" open preview />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/aspect-ratios.md",
    "content": "---\nmeta:\n  title: Aspect ratios\n  description: The responsive component is used as a wrapper component to force custom aspect ratios for its children.\n  keywords: ratio, responsive, aspect ratios\nrelated:\n  - /components/cards/\n  - /components/sheets/\n  - /components/images/\nfeatures:\n  github: /components/VAspectRatio/\n  label: 'C: VAspectRatio'\n  report: true\n---\n\n# Aspect ratios\n\nThe `v-responsive` component can be used to fix any section to a specific aspect ratio\n\n<PageFeatures />\n\n## Usage\n\nSpecify a custom aspect-ratio\n\n<ExamplesUsage name=\"v-responsive\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-responsive](/api/v-responsive/) | Primary component |\n\n<ApiInline hide-links />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/autocompletes.md",
    "content": "---\nmeta:\n  nav: Autocompletes\n  title: Autocomplete component\n  description: The autocomplete component provides type-ahead autocomplete functionality and provides a list of available options.\n  keywords: autocomplete, vuetify autocomplete component, vue autocomplete component\nrelated:\n  - /components/combobox/\n  - /components/forms/\n  - /components/selects/\nfeatures:\n  figma: true\n  label: 'C: VAutocomplete'\n  report: true\n  github: /components/VAutocomplete/\n  spec: https://m2.material.io/components/text-fields\n---\n\n# Autocompletes\n\nThe `v-autocomplete` component offers simple and flexible type-ahead functionality. This is useful when searching large sets of data or even dynamically requesting information from an API.\n\n<PageFeatures />\n\n## Usage\n\nThe autocomplete component extends `v-select` and adds the ability to filter items.\n\n<ExamplesUsage name=\"v-autocomplete\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-autocomplete](/api/v-autocomplete/) | Primary Component |\n| [v-combobox](/api/v-combobox/) | A select component that allows for filtering and custom values |\n| [v-select](/api/v-select/) | A replacement for the HTML <select></select> |\n\n<ApiInline hide-links />\n\n## Caveats\n\n::: error\n\nWhen using objects for the **items** prop, you must associate **item-title** and **item-value** with existing properties on your objects. These values are defaulted to **title** and **value** and can be changed.\n\n:::\n\n## Examples\n\nBelow is a collection of simple to complex examples.\n\n### Props\n\n#### Density\n\nYou can use `density` prop to adjust vertical spacing within the component.\n\n<ExamplesExample file=\"v-autocomplete/prop-density\" />\n\n#### Filter\n\nThe `custom-filter` prop can be used to filter each individual item with custom logic. In this example we filter items by name.\n\n<ExamplesExample file=\"v-autocomplete/prop-filter\" />\n\n#### Filter keys\n\nWhen user is typing in the field to narrow the list of options, the input text is matched against the `title`. With `filter-keys` you can specify which properties should be used instead. Properties of original objects passed to `items` need to be accessed via the `raw.*` path, as `filter-keys` index the root level of `InternalItem`.\n\n<ExamplesExample file=\"v-autocomplete/prop-filter-keys\" />\n\n#### Subheaders and dividers\n\nThe `items` prop recognizes special type of `divider` and `subheader`. Those items will be excluded when using filter and can be further customized with dedicated slots.\n\n<ExamplesExample file=\"v-autocomplete/prop-items\" />\n\n::: tip\n\nThe **v-autocomplete** component updates the search model on focus/blur events. Focus sets search to the current model (if available), and blur clears it.\n\nUnlike **v-combobox**, it doesn't keep unlisted values. To prevent unnecessary API requests when querying, ensure that search is not empty and/or doesn't match the current model.\n\n:::\n\n### Slots\n\n#### Item and selection\n\nWith the power of slots, you can customize the visual output of the select. In this example we add a profile picture for both the chips and list items.\n\n<ExamplesExample file=\"v-autocomplete/slot-item-and-selection\" />\n\nWhen customizing v-autocomplete items with the #item slot, make sure to forward the slot props using v-bind=\"props\".\nThis is required for virtual scrolling to work properly — without it, only part of your items may be displayed.\n\n<ExamplesExample file=\"v-autocomplete/slot-item-and-vbind-props\" />\n\n#### Menu footer\n\nThe **menu-footer** slot allows you to add custom content at the bottom of the dropdown menu, such as action buttons for clearing the selection or closing the menu.\n\n<ExamplesExample file=\"v-autocomplete/slot-menu-footer\" />\n\n### Misc\n\n#### Asynchronous items\n\nSometimes you need to load data externally based upon a search query. Simply bind to the `search` prop with the **v-model** and watch for the changes to the reactive variable. Make sure to apply debounce and avoid race conditions.\n\n<ExamplesExample file=\"v-autocomplete/misc-asynchronous-items\" />\n\n#### State selector\n\nUsing a combination of `v-autocomplete` slots and transitions, you can create a stylish toggleable autocomplete field such as this state selector.\n\n<ExamplesExample file=\"v-autocomplete/misc-state-selector\" />\n\n#### New tab\n\nThe **auto-select-first** property highlights the first result when searching, allowing you to press <v-kbd>tab</v-kbd> or <v-kbd>enter</v-kbd> to quickly select it.\n\n<ExamplesExample file=\"v-autocomplete/misc-new-tab\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/avatar-groups.md",
    "content": "---\nemphasized: true\nmeta:\n  nav: Avatar groups\n  title: Avatar group component\n  description: The avatar group component combines multiple avatars into a stacked or inline group display.\n  keywords: avatar groups, vuetify avatar group component, vue avatar group component\nrelated:\n  - /components/avatars/\n  - /components/chip-groups/\n  - /components/lists/\nfeatures:\n  github: /labs/VAvatarGroup/\n  label: 'C: VAvatarGroup'\n  report: true\n---\n\n# Avatar groups\n\nThe `v-avatar-group` component is used to display a collection of avatars in a stacked or grouped layout, commonly used for showing collaborators, team members, or user lists.\n\n<PageFeatures />\n\n## Installation\n\nLabs components require manual import and registration with the Vuetify instance.\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { VAvatarGroup } from 'vuetify/labs/VAvatarGroup'\n\nexport default createVuetify({\n  components: {\n    VAvatarGroup,\n  },\n})\n```\n\n## Usage\n\nAvatar groups stack avatars together with overlapping edges. Use the **items** prop to render avatars from an array, or nest `v-avatar` components directly.\n\n<ExamplesUsage name=\"v-avatar-group\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-avatar-group](/api/v-avatar-group/) | Primary component |\n| [v-avatar](/api/v-avatar/) | Sub-component used to display individual avatars |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n#### Items\n\nUse the **items** prop to render avatars from an array. Strings are treated as image URLs, objects are passed as props to `v-avatar`.\n\n<ExamplesExample file=\"v-avatar-group/prop-items\" />\n\n#### Size and Gap\n\nUse the **size** prop to control avatar dimensions and the **gap** prop to adjust the overlap between avatars.\n\n<ExamplesExample file=\"v-avatar-group/prop-size\" />\n\n#### Reverse\n\nThe **reverse** prop displays avatars in reverse stacking order. When rendering individual avatars (instead of passing `items`), use `toReversed` to counter flexbox visual order.\n\n<ExamplesExample file=\"v-avatar-group/prop-reverse\" />\n\n#### Vertical\n\nUse the **vertical** prop to stack avatars vertically instead of horizontally.\n\n<ExamplesExample file=\"v-avatar-group/prop-vertical\" />\n\n### Slots\n\n#### Overflow\n\nUse the **overflow** slot to customize or replace the last item when using the **limit** prop.\n\n<ExamplesExample file=\"v-avatar-group/slot-overflow\" />\n\n### Misc\n\n#### Hoverable\n\nGroups of avatars can be customized further with slots and **hoverable** prop for subtle interactions.\n\n<ExamplesExample file=\"v-avatar-group/misc-hoverable\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/avatars.md",
    "content": "---\nmeta:\n  nav: Avatars\n  title: Avatar component\n  description: The avatar component is used to control the size and border radius of an image. It can be used with numerous components to provide better visual context.\n  keywords: avatars, vuetify avatar component, vue avatar component\nrelated:\n  - /components/badges/\n  - /components/icons/\n  - /components/lists/\nfeatures:\n  figma: true\n  github: /components/VAvatar/\n  label: 'C: VAvatar'\n  report: true\n---\n\n# Avatars\n\nThe `v-avatar` component is typically used to display circular user profile pictures. This component will allow you to dynamically size and add a border radius of responsive images, icons, and text.  When **rounded** prop set to `0` will display an avatar without border radius.\n\n<PageFeatures />\n\n## Usage\n\nAvatars in their simplest form display content within a circular container.\n\n<ExamplesUsage name=\"v-avatar\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-avatar](/api/v-avatar/) | Primary Component |\n\n## Anatomy\n\nThe recommended placement of elements inside of `v-avatar` is:\n\n* Place a [v-img](/components/images/) or [v-icon](/components/icons/) component within the default *slot*\n* Place textual content within the default *slot*\n\n![Avatar Anatomy](https://cdn.vuetifyjs.com/docs/images/components-temp/v-avatar/v-avatar-anatomy.png)\n\n| Element / Area | Description |\n| - | - |\n| 1. Container | The Avatar container that typically holds a [v-icon](/components/icons/) or [v-img](/components/images/) component |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n#### Size\n\nThe `size` prop allows you to change the height and width of the avatar.\n\n<ExamplesExample file=\"v-avatar/prop-size\" />\n\n#### Badge\n\nThe `badge` prop wraps the avatar in a [v-badge](/components/badges/) to display a status indicator. Set it to `true` for a default dot badge, a color string, or an object of VBadge props for full customization. Use the **badge** slot to render custom content inside the badge.\n\n<ExamplesExample file=\"v-avatar/prop-badge\" />\n\n#### Tile\n\nThe `rounded` prop can be used to remove the border radius from v-avatar leaving you with a simple square avatar.\n\n<ExamplesExample file=\"v-avatar/prop-tile\" />\n\n### Slots\n\n#### Default\n\nThe `v-avatar` default slot allows you to render content such as `v-icon` components, images, or text. Mix and match these with other props to create something unique.\n\n<ExamplesExample file=\"v-avatar/slot-default\" />\n\n<PromotedPromoted />\n\n### Misc\n\n#### Advanced usage\n\nCombining an avatar with other components allows you to build beautiful user interfaces right out of the box.\n\n<ExamplesExample file=\"v-avatar/misc-advanced\" />\n\nAnother example combining avatar with menu.\n\n<ExamplesExample file=\"v-avatar/misc-avatar-menu\" />\n\n#### Profile Card\n\nUsing the **rounded** prop value `0`, we can create a sleek hard-lined profile card.\n\n<ExamplesExample file=\"v-avatar/misc-profile-card\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/badges.md",
    "content": "---\nmeta:\n  nav: Badges\n  title: Badge component\n  description: The badge component is a small status descriptor for elements. This typically contains a small number or short set of characters.\n  keywords: badges, vuetify badge component, vue badge component\nrelated:\n  - /components/avatars/\n  - /components/icons/\n  - /components/toolbars/\nfeatures:\n  github: /components/VBadge/\n  label: 'C: VBadge'\n  report: true\n---\n\n# Badges\n\nThe `v-badge` component superscripts or subscripts an avatar-like icon or text onto content to highlight information to a user or to just draw attention to a specific element. Content within the badge usually contains numbers or icons.\n\n<PageFeatures />\n\n## Usage\n\nBadges in their simplest form display to the upper right of the content that it wraps and requires the badge slot.\n\n<ExamplesUsage name=\"v-badge\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-badge](/api/v-badge/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n#### Dot\n\nThe **dot** property removes badge's content and reduces its overall size. This is useful when you need to draw a user's attention subtly.\n\n<ExamplesExample file=\"v-badge/prop-dot\" />\n\n#### Inline\n\nInline badges can be placed anywhere with content and can render without a *default* slot.\n\n<ExamplesExample file=\"v-badge/prop-inline\" />\n\n#### Content\n\nFor simple text, use the **content** property to display a *value* on the badge.\n\n<ExamplesExample file=\"v-badge/prop-content\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/banners.md",
    "content": "---\nmeta:\n  nav: Banners\n  title: Banner component\n  description: The banner component displays an important and concise message for a user to address. It can also indicate actions that the user can take.\n  keywords: banners, vuetify banner component, vue banner component\nrelated:\n  - /components/alerts/\n  - /components/icons/\n  - /components/snackbars/\nfeatures:\n  figma: true\n  github: /components/VBanner/\n  label: 'C: VBanner'\n  report: true\n  spec: https://m2.material.io/components/banners\n---\n\n# Banners\n\nThe `v-banner` component is used as a middle-interrupting message to the user with one to two actions.\n\n<PageFeatures />\n\n## Usage\n\nBanners come in two variations **single-line** and **multi-line** (implicit). These can have icons and actions that you can use with your message.\n\n<ExamplesUsage name=\"v-banner\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-banner](/api/v-banner/) | Primary Component |\n| [v-banner-text](/api/v-banner-text/) | Sub-component used to display the `v-banner` subtitle. Wraps the `#text` slot |\n| [v-banner-actions](/api/v-banner-actions/) | Sub-component that modifies the default styling of [v-btn](/components/buttons/). Wraps the `#actions` slot |\n\n<ApiInline hide-links />\n\n## Anatomy\n\nThe recommended placement of elements inside of `v-banner` is:\n\n* Place a `v-banner-avatar` or `v-banner-icon` on the far left\n* Place `v-banner-text` to the right of any visual content\n* Place `v-banner-actions` to the far right of textual content, offset bottom\n\n![Banner Anatomy](https://cdn.vuetifyjs.com/docs/images/components-temp/v-banner/v-banner-anatomy.png)\n\n| Element / Area | Description |\n| - | - |\n| 1. Container | The Banner container holds all `v-banner` components |\n| 2. Avatar / Icon (optional) | Leading media content intended to improve visual context |\n| 3. Text | A content area for displaying text and other inline elements |\n| 4. Actions (optional) | A content area that typically contains one or more [v-btn](/components/buttons) components |\n\n## Examples\n\n### Props\n\n#### Lines\n\nThe prop **lines** can be used to specify how the displayed text should be handled based on its length.\n\n<ExamplesExample file=\"v-banner/prop-lines\" />\n\n#### Sticky\n\nYou can optionally turn on the **sticky** prop to ensure that the content is pinned to the top of the screen.\n\n<ExamplesExample file=\"v-banner/prop-sticky\" />\n\n### Slots\n\n#### Actions\n\nBanners may have one or two text buttons that don't stand out that much.\n\n<ExamplesExample file=\"v-banner/slot-actions\" />\n\n#### Icon\n\nThe icon slot allows you to explicitly control the content and functionality within it.\n\n<ExamplesExample file=\"v-banner/slot-icon\" />\n\n#### Prepend\n\nThe prepend slot allows you to explicitly control the content and functionality within it. Icons also help to emphasize a banner's message.\n\n<ExamplesExample file=\"v-banner/slot-prepend\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/bottom-navigation.md",
    "content": "---\nmeta:\n  nav: Bottom navigation\n  title: Bottom navigation component\n  description: The bottom navigation component is used for mobile devices and acts as the primary navigation for your application.\n  keywords: bottom navigation, vuetify bottom navigation component, vue bottom navigation component\nrelated:\n  - /components/buttons/\n  - /components/icons/\n  - /components/tabs/\nfeatures:\n  figma: true\n  label: 'C: VBottomNavigation'\n  report: true\n  github: /components/VBottomNavigation/\n  spec: https://m2.material.io/components/bottom-navigation\n---\n\n# Bottom navigation\n\nThe `v-bottom-navigation` component is an alternative to the sidebar. It is primarily used for mobile applications and comes in three variants, **icons** and **text**, and **shift**.\n\n<PageFeatures />\n\n## Usage\n\nWhile `v-bottom navigation` is meant to be used with [vue-router](https://router.vuejs.org/), you can also programmatically control the active state of the buttons by using the **value** property. A button is given a default value of its _index_ with `v-bottom-navigation`.\n\n<ExamplesUsage name=\"v-bottom-navigation\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-bottom-navigation](/api/v-bottom-navigation/) | Primary Component |\n| [v-btn](/api/v-btn/) | Sub-component used for modifying the `v-bottom-navigation` state |\n\n<ApiInline hide-links />\n\n::: info\n\nFor styles to apply properly when using the **shift** prop, `v-btn` text is **required** to be wrapped in a `span` tag.\n\n:::\n\n## Examples\n\n### Props\n\n#### Color\n\nThe **color** prop applies a color to the background of the bottom navigation. We recommend using the **light** and **dark** props to properly contrast text color.\n\n<ExamplesExample file=\"v-bottom-navigation/prop-color\" />\n\n#### Grow\n\nUsing the **grow** property forces [v-btn](/components/buttons/) components to _fill_ all available space. Buttons have a maximum width of **168px** per the [Bottom Navigation MD specification](https://material.io/components/bottom-navigation#specs).\n\n<ExamplesExample file=\"v-bottom-navigation/prop-grow\" />\n\n<!-- TODO: Fix this example when scrolling techniques is implemented\n#### Hide on scroll\n\nThe `v-bottom-navigation` component hides when *scrolling up* when using the **hide-on-scroll** property. This is similar to the [scrolling techniques](https://material.io/archive/guidelines/patterns/scrolling-techniques.html) that are supported in [v-app-bar](/components/app-bars/). In the following example, scroll *up and down* to see this behavior.\n\n<ExamplesExample file=\"v-bottom-navigation/prop-hide-on-scroll\" />\n-->\n\n#### Horizontal\n\nAdjust the style of buttons and icons by using the **horizontal** prop. This positions button text *inline* with the provided [v-icon](/components/icons/).\n\n<ExamplesExample file=\"v-bottom-navigation/prop-horizontal\" />\n\n<!-- TODO: Fix this example when scrolling techniques is implemented\n#### Scroll threshold\n\nModify the **scroll-threshold** property to increase the distance a user must scroll before the `v-bottom-navigation` is hidden.\n\n<ExamplesExample file=\"v-bottom-navigation/prop-scroll-threshold\" />\n-->\n\n#### Shift\n\nThe **shift** prop hides button text when not active. This provides an alternative visual style to the `v-bottom-navigation` component.\n\n::: info\n  For this to work, `v-btn` text is **required** to be wrapped in a `span` tag.\n:::\n\n<ExamplesExample file=\"v-bottom-navigation/prop-shift\" />\n\n#### Toggle\n\nSince `v-bottom-navigation` supports v-model, use the **active** prop to control the display state.\n\n<ExamplesExample file=\"v-bottom-navigation/prop-toggle\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/bottom-sheets.md",
    "content": "---\nmeta:\n  nav: Bottom sheets\n  title: Bottom sheet component\n  description: The bottom sheet component is used for elevating content above other elements in a dialog style fashion.\n  keywords: bottom sheets, vuetify bottom sheet component, vue bottom sheet component\nrelated:\n  - /components/dialogs/\n  - /components/lists/\n  - /components/menus/\nfeatures:\n  label: 'C: VBottomSheet'\n  github: /components/VBottomSheet/\n  report: true\n  spec: https://m2.material.io/components/sheets-bottom\n---\n\n# Bottom sheets\n\nThe bottom sheet is a modified `v-dialog` that slides from the bottom of the screen, similar to a `v-bottom-navigation`.\n\n<PageFeatures />\n\n## Usage\n\nWhereas a bottom navigation component is for buttons and specific application level actions, a bottom sheet is meant to contain anything.\n\n<ExamplesUsage name=\"v-bottom-sheet\" />\n\n<PromotedEntry />\n\n## API\n\n| Component                                        | Description       |\n|--------------------------------------------------|-------------------|\n| [v-bottom-sheet](/api/v-bottom-sheet/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Anatomy\n\nThe recommended components to use inside of a `v-bottom-sheet` are:\n\n* [v-card](/components/cards/)\n* [v-list](/components/lists/)\n* [v-sheet](/components/sheets/)\n\n![Bottom Sheet Anatomy](https://cdn.vuetifyjs.com/docs/images/components/v-bottom-sheet/v-bottom-sheet-anatomy.png)\n\n| Element / Area | Description                                                              |\n|----------------|--------------------------------------------------------------------------|\n| 1. Container   | The bottom sheet is a dialog that animates from the bottom of the screen |\n\n## Guide\n\nThe `v-bottom-sheet` component is a modified [v-dialog](/components/dialogs/) that slides from the bottom of the screen. It is used for elevating content above other elements in a dialog style fashion. The bottom sheet can be controlled using the `v-model` prop or through the `activator` slot.\n\nThe following code snippet is an example of a basic `v-bottom-sheet` component:\n\n```html\n<v-bottom-sheet>\n  <v-card\n    title=\"Bottom Sheet\"\n    text=\"Lorem ipsum dolor sit amet consectetur, adipisicing elit. Ut, eos? Nulla aspernatur odio rem, culpa voluptatibus eius debitis.\"\n  ></v-card>\n</v-bottom-sheet>\n```\n\n### Props\n\nThe `v-bottom-sheet` component has access to all of the props available in [v-dialog](/api/v-dialog/).\n\n#### Model\n\nThe **v-model** (or **model-value**) controls the visibility of the bottom sheet:\n\n<ExamplesExample file=\"v-bottom-sheet/prop-model\" />\n\nThis also works in tandem with the [activator](/api/v-bottom-sheet/#slots-activator) slot.\n\n#### Inset\n\nWith the **inset** prop, reduce the maximum width of the content area on desktop to 70%. This can be further reduced manually using the **width** prop.\n\n<ExamplesExample file=\"v-bottom-sheet/prop-inset\" />\n\n### Slots\n\nThe `v-bottom-sheet` component has access to all of the slots available in [v-dialog](/api/v-dialog#slots).\n\n![Bottom Sheet Slots](https://cdn.vuetifyjs.com/docs/images/components/v-bottom-sheet/v-bottom-sheet-slots.png)\n\n| Slot         | Description                                         |\n|--------------|-----------------------------------------------------|\n| 1. Default   | The default slot                                    |\n| 2. Activator | The activator slot is used to open the bottom sheet |\n\n::: info\n\nThe **activator** slot is not required when using the **v-model** prop.\n\n:::\n\n### Examples\n\nThe following are a collection of examples that demonstrate more advanced and real world use of the `v-bottom-sheet` component.\n\n#### Music Player\n\nUsing a inset bottom sheet, you can make practical components such as this simple music player.\n\n<ExamplesExample file=\"v-bottom-sheet/misc-player\" />\n\n#### Open In List\n\nBy combining a functional list into a bottom sheet, you can create a simple 'open in' component.\n\n<ExamplesExample file=\"v-bottom-sheet/misc-open-in-list\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/breadcrumbs.md",
    "content": "---\nmeta:\n  nav: Breadcrumbs\n  title: Breadcrumbs component\n  description: The breadcrumbs component is a navigational helper for pages. It can accept a Material Icons icon or characters as a divider.\n  keywords: breadcrumbs, vuetify breadcrumbs component, vue breadcrumbs component, v-breadcrumbs component\nrelated:\n  - /components/buttons/\n  - /components/navigation-drawers/\n  - /components/icons/\nfeatures:\n  figma: true\n  label: 'C: VBreadcrumbs'\n  report: true\n  github: /components/VBreadcrumbs/\n---\n\n# Breadcrumbs\n\nThe `v-breadcrumbs` component is used as a navigational helper and hierarchy for pages.\n\n<PageFeatures />\n\n## Usage\n\nBy default, breadcrumbs use a text divider. This can be any string.\n\n<ExamplesUsage name=\"v-breadcrumbs\" />\n\n<PromotedEntry />\n\n::: tip\n\nUse [slots](/api/v-breadcrumbs/#slots) for more control of the breadcrumbs, either utilizing `v-breadcrumbs-item` or other custom markup.\n\n:::\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-breadcrumbs](/api/v-breadcrumbs/) | Primary Component |\n| [v-breadcrumbs-item](/api/v-breadcrumbs-item/) | Sub-component used for each breadcrumb |\n| [v-breadcrumbs-divider](/api/v-breadcrumbs-divider/) | Sub-component used for dividing breadcrumbs |\n\n<ApiInline hide-links />\n\n::: info\n  By default `v-breadcrumbs` will disable all crumbs up to the current page in a nested paths. You can prevent this behavior by using `exact: true` on each applicable breadcrumb in the `items` array.\n:::\n\n## Examples\n\n### Props\n\n#### Divider\n\nBreadcrumbs separator can be set using `divider` property.\n\n<ExamplesExample file=\"v-breadcrumbs/prop-divider\" />\n\n### Slots\n\n#### Prepend\n\nPrepend content with the `prepend` slot.\n\n<ExamplesExample file=\"v-breadcrumbs/slot-prepend\" />\n\n#### Dividers\n\nTo customize the divider, use the `divider` slot.\n\n<ExamplesExample file=\"v-breadcrumbs/slot-icon-dividers\" />\n\n#### Title\n\nYou can use the `title` slot to customize each breadcrumb title.\n\n<ExamplesExample file=\"v-breadcrumbs/slot-title\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/button-groups.md",
    "content": "---\nmeta:\n  nav: Button toggles\n  title: Button toggle component\n  description: The button toggle component allows you to combine a series of selectable buttons together in a single element.\n  keywords: button groups, vuetify button group component, vue button group component\nrelated:\n  - /components/buttons/\n  - /components/icons/\n  - /components/toolbars/\nfeatures:\n  github: /components/VBtnToggle/\n  label: 'C: VBtnToggle'\n  report: true\n  spec: https://m2.material.io/components/buttons#toggle-button\n---\n\n# Button toggles\n\nThe `v-btn-toggle` component is a simple wrapper for `v-item-group` built specifically to work with `v-btn`.\n\n<PageFeatures />\n\n## Usage\n\nToggle buttons allow you to create a styled group of buttons that can be selected or toggled under a single **v-model**.\n\n<ExamplesExample file=\"v-btn-toggle/usage\" />\n\n<PromotedEntry />\n\n## API\n\n| Component                          | Description |\n|------------------------------------| - |\n| [v-btn-toggle](/api/v-btn-toggle/) | Primary component |\n| [v-btn](/api/v-btn/)               | Sub-component used for modifying the `v-btn-toggle` state |\n| [v-btn-group](/api/v-btn-group/)   | A stateless version of `v-btn-toggle` |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n#### Divided\n\nYou can add a visual divider between buttons with the **divided** prop.\n\n<ExamplesExample file=\"v-btn-toggle/prop-divided\" />\n\n#### Variant\n\nYou can switch the button variant by using **variant** prop on `v-btn-toggle`.\n\n<ExamplesExample file=\"v-btn-toggle/prop-variant\" />\n\n#### Mandatory\n\nA `v-btn-toggle` with the **mandatory** prop will always have a value.\n\n<ExamplesExample file=\"v-btn-toggle/prop-mandatory\" />\n\n#### Multiple\n\nA `v-btn-toggle` with the **multiple** prop will allow a user to select multiple return values as an array.\n\n<ExamplesExample file=\"v-btn-toggle/prop-multiple\" />\n\n#### Rounded\n\nYou can control the border radius with the **rounded** prop.\n\n<ExamplesExample file=\"v-btn-toggle/prop-rounded\" />\n\n### Misc\n\n<!-- #### Toolbar\n\nEasily integrate customized button solutions with a `v-toolbar`\n\n<ExamplesExample file=\"v-btn-toggle/misc-toolbar\" /> -->\n\n#### WYSIWYG\n\nGroup similar actions and design your own WYSIWYG component.\n\n<ExamplesExample file=\"v-btn-toggle/misc-wysiwyg\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/buttons.md",
    "content": "---\nmeta:\n  nav: Buttons\n  title: Button component\n  description: The button component communicates actions that a user can take and are typically placed in dialogs, forms, cards and toolbars.\n  keywords: buttons, vuetify button component, vue button component\nrelated:\n  - /components/button-groups/\n  - /components/icons/\n  - /components/cards/\nfeatures:\n  figma: true\n  github: /components/VBtn/\n  label: 'C: VBtn'\n  report: true\n  spec: https://m2.material.io/components/buttons\n---\n\n# Buttons\n\nThe `v-btn` component replaces the standard html button with a material design theme and a multitude of options. Any color helper class can be used to alter the background or text color.\n\n<PageFeatures />\n\n## Usage\n\nButtons in their simplest form contain uppercase text, a slight elevation, hover effect, and a ripple effect on click.\n\n<ExamplesUsage name=\"v-btn\" />\n\n<VoPromotionsCardVuetify slug=\"vuetify-snips\" class=\"mb-4\" />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-btn](/api/v-btn/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Anatomy\n\nThe recommended placement of elements inside of `v-btn` is:\n\n* Place text in the center\n* Place visual content around container text\n\n![Button Anatomy](https://cdn.vuetifyjs.com/docs/images/components/v-btn/v-btn-anatomy.png)\n\n| Element / Area | Description |\n| - | - |\n| 1. Container | In addition to text, the Button container typically holds a [v-icon](/components/icons/) component |\n| 2. Icon (optional) | Leading media content intended to improve visual context |\n| 3. Text | A content area for displaying text and other inline elements |\n\n## Guide\n\nThe `v-btn` component is commonly used throughout Vuetify and is a staple for any application. It is used for everything from navigation to form submission; and can be styled in a multitude of ways.\n\nThe following code snippet is an example of a basic `v-btn` component only containing text:\n\n```html\n<v-btn>Button</v-btn>\n```\n\n### Props\n\nA wide array of props can be employed to modify the `v-btn` component's look and functionality. Props like **prepend-icon** and **append-icon** offer a straightforward approach to incorporate positioned icons, whereas **block** and **stacked** props are utilized to manage the component's form.\n\n#### Density\n\nThe **density** prop is used to control the vertical space that the button takes up.\n\n<ExamplesExample file=\"v-btn/prop-density\" />\n\n#### Size\n\nThe **size** property is used to control the size of the button and scales with density. The default size is **undefined** which essentially translates to **medium**.\n\n<ExamplesExample file=\"v-btn/prop-size\" />\n\n#### Block\n\nBlock buttons extend the full available width of their container. This is useful for creating buttons that span the full width of a card or dialog.\n\n<ExamplesExample file=\"v-btn/prop-block\" />\n\n::: info\nBlock applies **width: 100%** which can cause overflow issues inside a flex container.\n:::\n\n#### Rounded\n\nUse the **rounded** prop to control the border radius of a button.\n\n<ExamplesExample file=\"v-btn/prop-rounded\" />\n\n#### Elevation\n\nThe **elevation** property provides up to 24 levels of shadow depth. By default, buttons rest at 2dp.\n\n<ExamplesExample file=\"v-btn/prop-elevation\" />\n\n#### Ripple\n\nThe **ripple** property determines whether the [v-ripple](/directives/ripple/) directive is used.\n\n<ExamplesExample file=\"v-btn/prop-ripple\" />\n\n#### Variants\n\nThe **variant** prop gives you easy access to several different button styles. Available variants are: **elevated**(default), **flat**, **tonal**, **outlined**, **text**, and **plain**.\n\n| Value        | Example                                                  | Description                                                     |\n|--------------|----------------------------------------------------------|-----------------------------------------------------------------|\n| **elevated** | <v-btn color=\"primary\" variant=\"elevated\">Button</v-btn> | Elevates the button with a shadow                               |\n| **flat**     | <v-btn color=\"primary\" variant=\"flat\">Button</v-btn>     | Removes button shadow                                           |\n| **tonal**    | <v-btn color=\"primary\" variant=\"tonal\">Button</v-btn>    | Background color is a lowered opacity of the current text color |\n| **outlined** | <v-btn color=\"primary\" variant=\"outlined\">Button</v-btn> | Applies a thin border with the current text color               |\n| **text**     | <v-btn color=\"primary\" variant=\"text\">Button</v-btn>     | Removes the background and removes shadow                       |\n| **plain**    | <v-btn color=\"primary\" variant=\"plain\">Button</v-btn>    | Removes the background and lowers the opacity until hovered     |\n\n#### Icon\n\nIcons can be used for the primary content of a button. They are commonly used in the [v-toolbar](/components/toolbars/) and [v-app-bar](/components/app-bars/) components.\n\n<ExamplesExample file=\"v-btn/prop-icon\" />\n\n#### Loaders\n\nUsing the loading prop, you can notify a user that there is processing taking place. The default behavior is to use a `v-progress-circular` component but this can be customized with the **loader** slot.\n\n<ExamplesExample file=\"v-btn/prop-loaders\" />\n\n#### Inside of bars\n\nA common use-case is to use the `v-btn` with the **icon** property within a [v-toolbar](/components/toolbars/) or [v-app-bar](/components/app-bars/) component.\n\n<ExamplesExample file=\"v-btn/misc-toolbar\" />\n\n### Slots\n\nThe `v-btn` component provides slots that enable you to customize content created by its props or to add additional content.\n\n![Button Anatomy](https://cdn.vuetifyjs.com/docs/images/components/v-btn/v-btn-slots.png)\n\n| Slot | Description |\n| - | - |\n| 1. Default | The default slot |\n| 2. Prepend | Content area before the default slot |\n| 3. Append | Content area after the default slot |\n| 4. Loader | Content area shown when **loading** is set to `true` |\n\nSlots give you greater control to customize the content of the `v-btn` component while still taking advantage of the easy-to-use props.\n\n#### Icon color\n\nWhen you use the **prepend-icon** and **append-icon** props in conjunction with the corresponding slot, **prepend** or **append**, you are able to place a [v-icon](/components/icons/) that automatically injects the designated icon.\n\n<ExamplesExample file=\"v-btn/slot-prepend-append\" />\n\n#### Spaced\n\nBy default icons stick to the button content, but you can space them out with `spaced` prop.\n\n<ExamplesExample file=\"v-btn/prop-spaced\" />\n\n#### Custom loader\n\nThe **loader** slot allows you to customize the loading indicator. In this example we use a [v-progress-linear](/components/progress-linear/) component to create a loading bar that spans the full width of the button.\n\n<ExamplesExample file=\"v-btn/slot-loader\" />\n\n<VoPromotionsCardVuetify class=\"mb-4\" />\n\n## Examples\n\nThe following are a collection of examples that demonstrate more advanced and real world use of the `v-btn` component.\n\n### Discord event\n\nIn this example we utilize multiple different button variants and styles to create a copy of the Discord event card.\n\n<ExamplesExample file=\"v-btn/misc-discord-event\" hide-invert />\n\n### Survey group\n\nIn addition to [Button groups](/components/button-groups/), the `v-btn` component cant hook into a [v-item-group](/components/item-groups/) using a special symbol. In the next example we create a group of buttons that are used to select a survey answer and add custom **active** state styling.\n\n<ExamplesExample file=\"v-btn/misc-group-survey\" hide-invert />\n\n### Tax form confirmation\n\nThis example utilizes the [v-text-field](/components/text-fields/) component to collect data from the user and the **loading** prop of `v-btn` when submitting the form.\n\n<ExamplesExample file=\"v-btn/misc-tax-form\" />\n\n### Dialog action\n\nButtons are often used to trigger actions within a [v-dialog](/components/dialogs/). In this example we use the **outlined** variant and the **color** prop to create a button that is visually distinct from the other buttons.\n\n<ExamplesExample file=\"v-btn/misc-dialog-action\" />\n\n### Cookie settings\n\nIn this example we use a [v-banner](/components/banners/) component to display a custom cookie consent banner. Clicking the \"Manage Cookies\" button will prompt a [v-dialog](/components/dialogs/) component.\n\n<ExamplesExample file=\"v-btn/misc-cookie-settings\" />\n\n### Readonly buttons\n\nIn this example, we change the properties of the `v-btn` based upon a \"subscription\" state. When the user is subscribed, we want to disable interaction with the button, but not change its appearance; which is what occurs when using the **disabled** property.\n\n<ExamplesExample file=\"v-btn/misc-readonly\" />\n\n## Global Configuration\n\nModify the default values and set a default style for all `v-btn` components using the [Global configuration](/features/global-configuration/). This helps keep your application consistent and allows you to change it in the future with minimal effort.\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createVuetify } from 'vuetifyjs'\n\nexport default createVuetify({\n  defaults: {\n    VBtn: {\n      color: 'primary',\n      variant: 'outlined',\n      rounded: true,\n    },\n  },\n})\n```\n\n## Aliasing\n\nUtilize the [component aliasing](/features/aliasing/) feature to generate virtual components derived from the v-btn component. This proves valuable when dealing with numerous button variations within design specifications or when developing a custom library based on Vuetify.\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createVuetify } from 'vuetifyjs'\nimport { VBtn } from 'vuetifyjs/components'\n\nexport createVuetify({\n  aliases: {\n    VBtnSecondary: VBtn,\n    VBtnTertiary: VBtn,\n  },\n  defaults: {\n    VBtn: {\n      color: 'primary',\n      variant: 'text',\n    },\n    VBtnSecondary: {\n      color: 'secondary',\n      variant: 'flat',\n    },\n    VBtnTertiary: {\n      rounded: true,\n      variant: 'plain',\n    },\n  },\n})\n```\n\n## SASS Variables\n\nMake fine tuned changes by modifying the `v-btn` [SASS variables](/features/sass-variables). This is useful when you want to change the default button height or padding.\n\n```scss { resource=\"src/settings.scss\" }\n@use 'vuetify/settings' with (\n  $button-banner-actions-padding: 16px,\n  $button-height: 32px,\n);\n```\n\nSome of these values can be modified using the [Global configuration](/features/global-configuration/) as well and will take precedence over the SASS variables. For example, the **height** prop can be used to change the default button height without modifying the SASS variables.\n\n## Defaults Side Effects\n\nThere are instances where a set of default properties are injected or custom styling is applied to the `v-btn`. This can be for a variety of reasons, but the most common are:\n\n* to match a design specification\n* to provide a better visual appearance based upon context\n* to avoid creating proprietary components; e.g. `v-bottom-navigation-btn` and `v-card-btn`\n\n### Banners\n\nThe `v-banner-actions` component applies the **text** variant and **slim** prop, reducing button x-axis padding to **8px**.\n\n| Documentation | API |\n| - | - |\n| [Banners](/components/banners/) | [v-banner-actions](/api/v-banner-actions/) |\n\n<ExamplesExample file=\"v-btn/defaults-banner-actions\" />\n\nThe following properties are modified when used within a `v-banner-actions` component:\n\n| Property | Value |\n| - | - |\n| **color** | provided by `v-banner-actions` |\n| **density** | provided by `v-banner-actions` |\n| **slim** | `true` |\n| **variant** | `text` |\n\n### Bottom navigation\n\nThe `v-bottom-navigation` component **scopes** out all previously provided defaults and applies its own. This is to avoid changes made to `v-btn` in the [Global configuration](/features/global-configuration/). Buttons automatically register with `v-bottom-navigation`'s' group and will update the **model** when clicked.\n\n| Documentation | API |\n| - | - |\n| [Bottom navigation](/components/bottom-navigation/) | [v-bottom-navigation](/api/v-bottom-navigation/) |\n\n<ExamplesExample file=\"v-btn/defaults-bottom-navigation\" />\n\nThe following properties are modified when used within a `v-bottom-navigation` component:\n\n| Property | Value |\n| - | - |\n| **color** | provided by `v-bottom-navigation` |\n| **density** | provided by `v-bottom-navigation` |\n| **stacked** | `true` when **mode** is `shift` |\n| **variant** | `text` |\n\n### Button groups\n\nThe `v-btn-group` component makes multiple changes to the `v-btn` component.\n\n| Documentation | API |\n| - | - |\n| [Button groups](/components/button-groups/) | [v-btn-group](/api/v-btn-group/) |\n\n<ExamplesExample file=\"v-btn/defaults-btn-group\" />\n\nThe following properties are modified when used within a `v-btn-group` component:\n\n| Property | Value |\n| - | - |\n| **color** | provided by `v-btn-group` |\n| **height** | `auto` |\n| **density** | provided by `v-btn-group` |\n| **flat** | `true` |\n| **variant** | provided by `v-btn-group` |\n\n### Cards\n\nThe `v-card-actions` component applies the **text** variant and **slim** prop, reducing button x-axis padding to **8px**, and applies a start margin for all siblings. This is to ensure the text from the button lines up with the text and title of the card and that there is space between its actions.\n\n| Documentation | API |\n| - | - |\n| [Cards](/components/cards/) | [v-card-actions](/api/v-card-actions/) |\n\n<ExamplesExample file=\"v-btn/defaults-card-actions\" />\n\nThe following properties are modified when used within a `v-card-actions` component:\n\n| Property | Value |\n| - | - |\n| **slim** | `true` |\n| **variant** | `text` |\n\n### Snackbars\n\nThe `v-snackbar` component applies the **text** variant, **slim** prop, and removes ripples from all `v-btn` components.\n\n| Documentation | API |\n| - | - |\n| [Snackbars](/components/snackbars/) | [v-snackbar](/api/v-snackbar/) |\n\n<ExamplesExample file=\"v-btn/defaults-snackbar\" />\n\nThe following properties are modified when used within the **actions** slot of the `v-snackbar` component:\n\n| Property | Value |\n| - | - |\n| **slim** | `true` |\n| **ripple** | `false` |\n| **variant** | `text` |\n\n### Toolbars and AppBars\n\nThe `v-toolbar` component applies the **text** variant to all `v-btn` components. In addition, the [v-toolbar-items](/api/v-toolbar-items/) component is used to create a grouping of buttons that fill the height of the toolbar.\n\n| Documentation | API |\n| - | - |\n| [Toolbars](/components/toolbars/) | [v-toolbar](/api/v-toolbar/)  |\n\n<ExamplesExample file=\"v-btn/defaults-toolbar\" />\n\n::: info\n\nThe [v-app-bar](/components/app-bars/) component uses [v-toolbar](/components/toolbars/) internally. When applying global defaults, you must target the `v-toolbar` component.\n\n:::\n\n```js { resource=\"src/plugins/vuetify.js\" }\nexport default createVuetify({\n  defaults: {\n    VToolbar: {\n      VBtn: { variant: 'flat' },\n    },\n  },\n})\n```\n\nThe following properties are modified when used within a `v-toolbar` or `v-toolbar-items` component:\n\n| Property | Value |\n| - | - |\n| **height** | provided by `v-toolbar-items` |\n| **variant** | `text` |\n\n<VoPromotionsCardVuetify class=\"mb-4\" />\n\n## Accessibility\n\nThe `v-btn` component is an extension of the native `button` element and supports all of the same accessibility features.\n\n### ARIA Attributes\n\nBy default, the `v-btn` component includes relevant [WAI-ARIA](https://www.w3.org/WAI/standards-guidelines/aria/) attributes to enhance accessibility. The component is automatically assigned the `type=\"button\"` attribute, which indicates its purpose as a button to assistive technologies.\n\n### Keyboard Navigation\n\nThe `v-btn` component is natively focusable and responds to keyboard events, such as pressing the <v-kbd>Enter</v-kbd> or <v-kbd>Space</v-kbd> key to trigger the button's action. This ensures that users can navigate and interact with your application using just the keyboard.\n\n### Accessible Labels\n\nWhen using a [v-icon](/components/icons/) within the `v-btn` component (e.g., with the **icon** prop), it is essential to provide a text alternative for screen reader users. You can add an `aria-label` attribute with a descriptive label to ensure that the button's purpose is clear to all users.\n\n```html\n<v-btn\n  aria-label=\"Refresh\"\n  icon=\"mdi-refresh\"\n></v-btn>\n```\n\n### Touch Target Size\n\nMake sure your buttons have an adequate touch target size, especially on touch devices. A larger touch target can improve the usability of your buttons for users with motor impairments or those using small screens. You can use **large** or **x-large** values for the size prop to increase the button size:\n\n```html\n<v-btn size=\"large\">\n  Large Button\n</v-btn>\n\n<v-btn size=\"x-large\">\n  Extra Large Button\n</v-btn>\n```\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/calendars.md",
    "content": "---\nmeta:\n  nav: Calendars\n  title: Calendar component\n  description: The calendar component is a clean and simple adaptation to the popular Google Calendar application.\n  keywords: calendars, vuetify calendar component, vue calendar component\nrelated:\n  - /components/date-pickers\n  - /components/time-pickers\n  - /components/cards\nfeatures:\n  github: /components/VCalendar/\n  label: 'C: VCalendar'\n  report: true\n---\n\n# Calendars\n\nThe `v-calendar` component is used to display information in a daily, weekly, monthly, or category view. The daily view has slots for all day or timed elements, and the weekly and monthly view has a slot for each day. The category view has a slot for each category in the day and timed sections based on the categories given or the categories in the given events. Optionally you can pass in an array of events and they will be rendered over the appropriate days and times.\n\n<PageFeatures />\n\n## Usage\n\nA calendar has a type and a value which determines what type of calendar is shown over what span of time. This shows the bare minimum configuration, an array of events with **name**, **start** and **end** properties. **end** is optional, it defaults to the **start**. If the **start** has a time it's considered a timed event and will be shown accordingly in the day views. An event can span multiple days and will be rendered accordingly.\n\n<ExamplesExample file=\"v-calendar/usage\" />\n\n<PromotedEntry />\n\n## API\n\n| Component                      | Description |\n|--------------------------------| - |\n| [v-calendar](/api/v-calendar/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n#### Type category\n\nThis is an example of an event calendar with a **type** of `category` that allows you to compare two schedules side-by-side.\n\n<ExamplesExample file=\"v-calendar/prop-type-category\" />\n\n#### Type day\n\nThis is an example of calendar with content in each interval slot and a **type** of `day`.\n\n<ExamplesExample file=\"v-calendar/prop-type-day\" />\n\n#### Type week\n\nThis is an example of an event calendar with all-day and timed events with a **type** of `week`.\n\n<ExamplesExample file=\"v-calendar/prop-type-week\" />\n\n### Events\n\n#### Click\n\nThis is an example of a planner with additional event handlers and external components controlling the display of the calendar.\n\n<ExamplesExample file=\"v-calendar/event-click\" />\n\n### Slots\n\n#### Day\n\nSlots allow you to define the content for each day, time interval for the daily views, and various labels.\n\n<ExamplesExample file=\"v-calendar/slot-day\" />\n\n#### Day body\n\nUsing the `day-body` slot you can customize the calendar content for the day. In this example we added a line for the current time.\n\n<ExamplesExample file=\"v-calendar/slot-day-body\" />\n\n### Misc\n\n#### Drag and drop\n\nThis is an example of an event calendar where you can drag events, extend their length, and create events.\n\n<ExamplesExample file=\"v-calendar/misc-drag-and-drop\" />\n\n<backmatter />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/cards.md",
    "content": "---\nmeta:\n  nav: Cards\n  title: Card component\n  description: The v-card component is a versatile and enhanced sheet of paper that provides a simple interface for headings, text, images, and actions.\n  keywords: cards, vuetify card component, vue card component, v-card\nrelated:\n  - /components/buttons\n  - /components/images\n  - /styles/text-and-typography\nfeatures:\n  figma: true\n  label: 'C: VCard'\n  github: /components/VCard/\n  report: true\n  spec: https://m2.material.io/components/cards\n---\n\n# Cards\n\n The `v-card` component is a versatile and enhanced version of [v-sheet](/components/sheets/) that provides a simple interface for headings, text, images, icons, and more.\n\n<PageFeatures />\n\n## Usage\n\nThe `v-card` component is a stylish way to wrap different types of content; such as tables, images, or user actions.\n\n<ExamplesUsage name=\"v-card\" />\n\n<VoPromotionsCardVuetify slug=\"vuetify-snips\" class=\"mb-4\" />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-card](/api/v-card/) | Primary Component |\n| [v-card-item](/api/v-card-item/) | Sub-component used to wrap the Card's `v-card-title` and `v-card-subtitle` components. |\n| [v-card-title](/api/v-card-title/) | Sub-component used to display the Card's title. Wraps the `#title` slot |\n| [v-card-subtitle](/api/v-card-subtitle/) | Sub-component used to display the Card's subtitle. Wraps the `#subtitle` slot. |\n| [v-card-text](/api/v-card-text/) | Sub-component used to display the Card's text. Wraps the `#text` slot. |\n| [v-card-actions](/api/v-card-actions/) | Sub-component that modifies the default styling of [v-btn](/components/buttons/). Wraps the `#actions` slot |\n\n<ApiInline hide-links />\n\n## Anatomy\n\nThe recommended placement of elements inside of `v-card` is:\n\n* Place `v-card-title`, `v-card-subtitle` or other title text on top\n* Place `v-card-text` and other forms of media below the card header\n* Place `v-card-actions` after card content\n\n![Card Anatomy](https://cdn.vuetifyjs.com/docs/images/components-temp/v-card/v-card-anatomy.png)\n\n| Element / Area | Description |\n| - | - |\n| 1. Container | The Card container holds all `v-card` components. Composed of 3 major parts: `v-card-item`, `v-card-text`, and `v-card-actions` |\n| 2. Title (optional) | A heading with increased **font-size** |\n| 3. Subtitle (optional) | A subheading with a lower emphasis text color |\n| 4. Text (optional) | A content area with a lower emphasis text color |\n| 5. Actions (optional) | A content area that typically contains one or more [v-btn](/components/buttons) components |\n\n## Guide\n\nThe `v-card` component is a versatile and enhanced sheet of paper that provides a simple interface for headings, text, images, and actions. It is a content container that is the most common way to present information.\n\n### Basics\n\nThere are three ways you can populate a `v-card` with content. The first one is by using props, the second one is by slots, and the third one is by manually using the `v-card-*` components.\n\n<ExamplesExample file=\"v-card/basics-content\" />\n\nProps give you an easy interface to display text-only content. They can also be used to easily render images and icons. Use slots if you need to render more complex content. If you need full control over the content, use markup.\n\n### Combined\n\nIn some cases it is possible to combine the different options, like the example below where props, slots and markup have all been used.\n\n<ExamplesExample file=\"v-card/basics-combine\" />\n\n::: info\n\nIn general slots take precedence over props. So if you provide both **text** prop and use **text** slot, then only the slot content will be rendered.\n\n:::\n\n### Props\n\nThe `v-card` component has a variety of props that allow you to customize its appearance and behavior.\n\n#### Variants\n\nThe **variant** prop gives you easy access to several different card styles. Available variants are: **elevated**(default), **flat**, **tonal**, **outlined**, **text**, and **plain**.\n\n| Value        | Description                                                 |\n|--------------|-------------------------------------------------------------|\n| **elevated** | Elevates the card with a shadow                             |\n| **flat**     | Removes card shadow and border                              |\n| **tonal**    | Background color is a lowered opacity of the color          |\n| **outlined** | Applies a thin border and card has zero elevation           |\n| **text**     | Removes the background and removes shadow                   |\n| **plain**    | Removes the background and lowers the opacity until hovered |\n\n<ExamplesExample file=\"v-card/prop-variant\" />\n\n<VoPromotionsCardVuetify class=\"mb-4\" />\n\n#### Color\n\nCards can be colored by using any of the builtin colors and contextual names using the **color** prop.\n\n<ExamplesExample file=\"v-card/prop-color\" />\n\n#### Elevation\n\nThe **elevation** property provides up to 24 levels of shadow depth. By default, cards rest at 2dp.\n\n<ExamplesExample file=\"v-card/prop-elevation\" />\n\n#### Hover\n\nWhen using the **hover** prop, the cards will increase its elevation when the mouse is hovered over them.\n\n<ExamplesExample file=\"v-card/prop-hover\" />\n\n#### Href\n\nThe card becomes an anchor with the **href** prop.\n\n<ExamplesExample file=\"v-card/prop-href\" />\n\n#### Link\n\nAdd the **link** prop for the same style without adding an anchor.\n\n<ExamplesExample file=\"v-card/prop-link\" />\n\n#### Disabled\n\nThe **disabled** prop can be added in order to prevent a user from interacting with the card.\n\n<ExamplesExample file=\"v-card/prop-disabled\" />\n\n#### Image\n\nApply a specific background image to the Card.\n\n<ExamplesExample file=\"v-card/prop-image\" />\n\n::: tip\n\n`v-card` does not allow its content to overflow outside the card by default. It also establishes a z-index stacking context, which prevents its content from displaying on top of elements outside the `v-card`, even when it sets a higher z-index value. To override this default behavior, apply the following usage: `<v-card style=\"overflow: initial; z-index: initial\">`.\n\n:::\n\n### Slots\n\nThe `v-card` component provides slots that enable you to customize content created by its props or to add additional content.\n\nSlots give you greater control to customize the content of the `v-card` component while still taking advantage of the easy-to-use props.\n\n#### Avatar and icon\n\nYou can use the **prepend-avatar**, **append-avatar**, **prepend-icon** and **append-icon** props or the **prepend** and **append** slots to place a [v-icon](/components/icons/) that automatically injects the designated icon.\n\n<ExamplesExample file=\"v-card/slot-prepend-append\" />\n\n## Examples\n\nThe following are a collection of examples that demonstrate more advanced and real world use of the `v-card` component.\n\n### Card Reveal\n\nUsing [v-expand-transition](/api/v-expand-transition/) and a `@click` event you can have a card that reveals more information once the button is clicked, activating the hidden card to be revealed.\n\n<ExamplesExample file=\"v-card/misc-card-reveal\" />\n\n### Content wrapping\n\nThe `v-card` component is useful for wrapping content.\n\n<ExamplesExample file=\"v-card/misc-content-wrapping\" />\n\n### Custom actions\n\nWith a simple conditional, you can easily add supplementary text that is hidden until opened.\n\n<ExamplesExample file=\"v-card/misc-custom-actions\" />\n\n<VoPromotionsCardVuetify class=\"mb-4\" />\n\n### Grids\n\nUsing [grids](/components/grids/), you can create beautiful layouts.\n\n<ExamplesExample file=\"v-card/misc-grids\" />\n\n### Horizontal cards\n\nYou can also play with the card layout using [layout flex](/styles/flex/).\n\n<ExamplesExample file=\"v-card/misc-horizontal-cards\" />\n\n### Information card\n\nCards are entry points to more detailed information. To keep things concise, ensure to limit the number of actions the user can take.\n\n<ExamplesExample file=\"v-card/misc-information-card\" />\n\n### Media with text\n\nUsing the layout system, we can add custom text anywhere within the background.\n\n<ExamplesExample file=\"v-card/misc-media-with-text\" />\n\n### Twitter card\n\nThe `v-card` component has multiple children components that help you build complex examples without having to worry about spacing. This example is comprised of the `v-card-title`, `v-card-text` and `v-card-actions` components.\n\n<ExamplesExample file=\"v-card/misc-twitter-card\" />\n\n### Weather card\n\nUsing [v-list-items](/components/lists) and a [v-slider](/components/sliders), we are able to create a unique weather card. The list components ensure that we have consistent spacing and functionality while the slider component allows us to provide a useful interface of selection to the user.\n\n<ExamplesExample file=\"v-card/misc-weather-card\" />\n\n### Loading\n\nUse an indeterminate [v-progress-linear](/components/progress-linear) to indicate a loading state.\n\n<ExamplesExample file=\"v-card/prop-loading\" />\n\n### Earnings goal\n\nThis example utilizes slots to customize the appearance of the different content areas.\n\n<ExamplesExample file=\"v-card/misc-earnings-goal\" />\n\n### Funding card\n\nUtilize a combination of Card properties and utility classes to create a unique funding card.\n\n<ExamplesExample file=\"v-card/misc-shopify-funding\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/carousels.md",
    "content": "---\nmeta:\n  nav: Carousels\n  title: Carousel component\n  description: The carousel component is used to cycle through visual content such as images or slides of text.\n  keywords: carousels, vuetify carousel component, vue carousel component\nrelated:\n  - /components/parallax/\n  - /components/images/\n  - /components/windows/\nfeatures:\n  github: /components/VCarousel/\n  label: 'C: VCarousel'\n  report: true\n---\n\n# Carousels\n\nThe `v-carousel` component is used to display large numbers of visual content on a rotating timer.\n\n<PageFeatures />\n\n## Usage\n\nThe `v-carousel` component expands upon `v-window` by providing additional features targeted at displaying images.\n\n<ExamplesUsage name=\"v-carousel\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-carousel](/api/v-carousel/) | Primary component |\n| [v-carousel-item](/api/v-carousel-item/) | Sub-component used for displaying the `v-carousel` state |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n#### Custom delimiters\n\nUse any available icon as your carousel's slide delimiter.\n\n<ExamplesExample file=\"v-carousel/prop-custom-icons\" />\n\n#### Custom transition\n\nThe `v-carousel-item` component can have its **transition/reverse-transition** changed.\n\n::: info\nCrossfade transition using `crossfade` prop requires **3.10.0**.\n:::\n\n<ExamplesExample file=\"v-carousel/prop-custom-transition\" />\n\n#### Cycle\n\nWith the **cycle** prop you can have your slides automatically transition to the next available every 6s (default).\n\n<ExamplesExample file=\"v-carousel/prop-cycle\" />\n\n#### Hide controls\n\nYou can hide the carousel navigation controls with `:show-arrows=\"false\"`. Or you can make them only appear on hover with `show-arrows=\"hover\"`.\n\n<ExamplesExample file=\"v-carousel/prop-hide-controls\" />\n\n#### Customized arrows\n\nArrows can be customized by using **prev** and **next** slots.\n\n<ExamplesExample file=\"v-carousel/slots-next-prev\" />\n\n#### Hide delimiters\n\nYou can hide the bottom controls with **hide-delimiters** prop.\n\n<ExamplesExample file=\"v-carousel/prop-hide-delimiters\" />\n\n#### Progress\n\nYou can show a linear progress bar with the **progress** prop. It will indicate how far into the cycle the carousel currently is.\n\n<ExamplesExample file=\"v-carousel/prop-progress\" />\n\n#### Model\n\nYou can control carousel with **v-model**.\n\n<ExamplesExample file=\"v-carousel/prop-model\" />\n\n### Misc\n\n#### Vertical with overlay content\n\nCarousel can be augmented with additional content simply by placing VOverlay next to it.\n\n<ExamplesExample file=\"v-carousel/misc-vertical\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/checkboxes.md",
    "content": "---\nmeta:\n  nav: Checkboxes\n  title: Checkbox component\n  description: The checkbox component permits users to select between two values.\n  keywords: checkbox, checkbox component, vuetify checkbox component, vue checkbox component\nrelated:\n  - /components/switches\n  - /components/forms\n  - /components/text-fields\nfeatures:\n  label: 'C: VCheckbox'\n  report: true\n  github: /components/VCheckbox/\n  spec: https://m2.material.io/components/checkboxes\n---\n\n# Checkboxes\n\nThe `v-checkbox` component provides users the ability to choose between two distinct values. These are very similar to a switch and can be used in complex forms and checklists.\n\n<PageFeatures />\n\n## Usage\n\nA `v-checkbox` in its simplest form provides a toggle between 2 values.\n\n<ExamplesUsage name=\"v-checkbox\" />\n\n<PromotedEntry />\n\n::: tip\n\nA simpler version, [`v-checkbox-btn`](/components/data-tables/basics/#simple-checkbox) is used primarily as a lightweight alternative in data-table components to select rows or display inline boolean data.\n\n:::\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-checkbox](/api/v-checkbox/) | Primary component |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n#### Colors\n\nCheckboxes can be colored by using any of the builtin colors and contextual names using the **color** prop.\n\n<ExamplesExample file=\"v-checkbox/prop-colors\" />\n\n#### Model as array\n\nMultiple `v-checkbox`'s can share the same **v-model** by using an array.\n\n<ExamplesExample file=\"v-checkbox/prop-model-as-array\" />\n\n#### Model as boolean\n\nA single `v-checkbox` will have a boolean value as its **value**.\n\n<ExamplesExample file=\"v-checkbox/prop-model-as-boolean\" />\n\n#### States\n\n`v-checkbox` can have different states such as **default**, **disabled**, and **indeterminate**.\n\n<ExamplesExample file=\"v-checkbox/prop-states\" />\n\n### Slots\n\n#### Label slot\n\nCheckbox labels can be defined in `label` slot - that will allow to use HTML content.\n\n<ExamplesExample file=\"v-checkbox/slot-label\" />\n\n### Misc\n\n#### Inline text-field\n\nIf you need to place checkboxes in line with other components, you can use the `v-checkbox-btn` component.\n\nThis component renders just checkbox, without the trapping of a form input such as validation, a label, and messages.\n\n<ExamplesExample file=\"v-checkbox/misc-inline-textfield\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/chip-groups.md",
    "content": "---\nmeta:\n  nav: Chip groups\n  title: Chip group component\n  description: The chip group component combines numerous selectable chips into single or multiple lines.\n  keywords: chip groups, vuetify chip group component, vue chip group component\nrelated:\n  - /components/chips/\n  - /components/slide-groups/\n  - /components/item-groups/\nfeatures:\n  github: /components/VChipGroup/\n  label: 'C: VChipGroup'\n  report: true\n  spec: https://m2.material.io/components/chips#choice-chips\n---\n\n# Chip groups\n\nThe `v-chip-group` supercharges the `v-chip` component by providing groupable functionality. It is used for creating groups of selections using chips.\n\n<PageFeatures />\n\n## Usage\n\nChip groups make it easy for users to select filtering options for more complex implementations. By default `v-chip-group` will overflow to the right but can be changed to a **column** only mode.\n\n<ExamplesUsage name=\"v-chip-group\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-chip-group](/api/v-chip-group/) | Primary component |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n#### Column\n\nChip groups with **column** prop can wrap their chips.\n\n<ExamplesExample file=\"v-chip-group/prop-column\" />\n\n#### Filter results\n\nEasily create chip groups that provide additional feedback with the **filter** prop. This creates an alternative visual style that communicates to the user that the chip is selected.\n\n<ExamplesExample file=\"v-chip-group/prop-filter\" />\n\n#### Mandatory\n\nChip groups with **mandatory** prop must always have a value selected.\n\n<ExamplesExample file=\"v-chip-group/prop-mandatory\" />\n\n#### Multiple\n\nChip groups with **multiple** prop can have many values selected.\n\n<ExamplesExample file=\"v-chip-group/prop-multiple\" />\n\n### Misc\n\n#### Product card\n\nThe `v-chip` component can have an explicit value used for its model. This gets passed to the `v-chip-group` component and is useful for when you don't want to use the chips index as their values.\n\n<ExamplesExample file=\"v-chip-group/misc-product-card\" />\n\n#### Toothbrush card\n\nChip groups allow the creation of custom interfaces that perform the same actions as an item group or radio controls, but are stylistically different.\n\n<ExamplesExample file=\"v-chip-group/misc-toothbrush-card\" />\n\n#### Reddit style categories\n\nUse a combination of utility classes and emojis to create a Reddit-style category selection.\n\n<ExamplesExample file=\"v-chip-group/misc-reddit-categories\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/chips.md",
    "content": "---\nmeta:\n  nav: Chips\n  title: Chip component\n  description: The chip component allows a user to enter information, make selections, filter content or trigger actions.\n  keywords: chips, vuetify chip component, vue chip component\nrelated:\n  - /components/avatars\n  - /components/icons\n  - /components/selects\nfeatures:\n  figma: true\n  github: /components/VChip/\n  label: 'C: VChip'\n  report: true\n  spec: https://m2.material.io/components/chips\n---\n\n# Chips\n\nThe `v-chip` component is used to convey small pieces of information. Using the `close` property, the chip becomes interactive, allowing user interaction. This component is used by the [v-chip-group](/components/chip-groups) for advanced selection options.\n\n<PageFeatures />\n\n## Usage\n\nChips come in the following variations: closeable, filter, outlined, pill. The default slot of `v-chip` will also accept avatars and icons alongside text.\n\n<ExamplesUsage name=\"v-chip\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-chip](/api/v-chip/) | Primary component |\n\n<ApiInline hide-links />\n\n## Guide\n\nThe `v-chip` component is used to convey small pieces of information. Using the `close` property, the chip becomes interactive, allowing user interaction. This component is used by the [v-chip-group](/components/chip-groups) for advanced selection options.\n\n### Props\n\nSimilar to other components such as [v-btn](/components/buttons/) and [v-list](/components/lists/), the `v-chip` component has a large selection of props for customizing the appearance.\n\n#### Closable\n\nClosable chips can be controlled with a v-model. You can also listen to the `click:close` event if you want to know when a chip has been closed.\n\n<ExamplesExample file=\"v-chip/prop-closable\" />\n\n#### Color and variants\n\nAny color from the Material Design palette can be used to change a chips color.\n\n<ExamplesExample file=\"v-chip/prop-colored\" />\n\nThe **variant** prop gives you easy access to several different button styles. Available variants are: **elevated**, **flat**, **tonal** (default), **outlined**, **text**, and **plain**.\n\n| Value        | Example                                                  | Description                                                     |\n|--------------|----------------------------------------------------------|-----------------------------------------------------------------|\n| **elevated** | <v-chip color=\"primary\" variant=\"elevated\">Chip</v-chip> | Elevates the chip with a shadow                               |\n| **flat**     | <v-chip color=\"primary\" variant=\"flat\">Chip</v-chip>     | Removes chip shadow                                           |\n| **tonal**    | <v-chip color=\"primary\" variant=\"tonal\">Chip</v-chip>    | Background color is a lowered opacity of the current text color |\n| **outlined** | <v-chip color=\"primary\" variant=\"outlined\">Chip</v-chip> | Applies a thin border with the current text color               |\n| **text**     | <v-chip color=\"primary\" variant=\"text\">Chip</v-chip>     | Removes the background and removes shadow                       |\n| **plain**    | <v-chip color=\"primary\" variant=\"plain\">Chip</v-chip>    | Removes the background and lowers the opacity until hovered     |\n\n#### Size and density\n\nChips can have various sizes from `x-small` to `x-large`. `density` is used to adjust the vertical spacing without affecting width or font size.\n\n<ExamplesExample file=\"v-chip/prop-sizes\" />\n\n#### Draggable\n\n`draggable` `v-chip` component can be dragged by mouse.\n\n<ExamplesExample file=\"v-chip/prop-draggable\" />\n\n#### Label\n\nLabel chips use the `v-card` border-radius.\n\n<ExamplesExample file=\"v-chip/prop-label\" />\n\n#### No ripple\n\n`v-chip` can be rendered without ripple if `ripple` prop is set to `false`.\n\n<ExamplesExample file=\"v-chip/prop-no-ripple\" />\n\n#### Outlined\n\nOutlined chips inherit their border color from the current text color.\n\n<ExamplesExample file=\"v-chip/prop-outlined\" />\n\n### Slots\n\n#### Icon\n\nChips can use text or any icon available in the Material Icons font library.\n\n<ExamplesExample file=\"v-chip/slot-icon\" />\n\n## Examples\n\nThe following are a collection of examples that demonstrate more advanced and real world use of the `v-chip` component.\n\n### Action chips\n\nChips can be used as actionable items. Provided with a _click_ event, the chip becomes interactive and can invoke methods.\n\n<ExamplesExample file=\"v-chip/event-action-chips\" />\n\n#### Custom list\n\nIn this example we opt to use a customized list instead of [v-autocomplete](/components/autocompletes). This allows us to always display the options available while still providing the same functionality of search and selection.\n\n<ExamplesExample file=\"v-chip/misc-custom-list\" />\n\n#### Expandable\n\nChips can be combined with `v-menu` to enable a specific set of actions for a chip.\n\n<ExamplesExample file=\"v-chip/misc-expandable\" />\n\n#### Filtering\n\nChips are great for providing supplementary actions to a particular task. In this instance, we are searching a list of items and collecting a subset of information to display available keywords.\n\n<ExamplesExample file=\"v-chip/misc-filtering\" />\n\n#### In selects\n\nSelects can use chips to display the selected data. Try adding your own tags below.\n\n<ExamplesExample file=\"v-chip/misc-in-selects\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/color-inputs.md",
    "content": "---\nmeta:\n  nav: Color inputs\n  title: Color input component\n  description: The color input is a specialized input that provides a clean interface for selecting colors.\n  keywords: color input, color picker, color field\nrelated:\n  - /components/color-pickers/\n  - /components/text-fields/\n  - /components/menus/\nfeatures:\n  label: 'C: VColorInput'\n  report: true\n  github: /labs/VColorInput/\n---\n\n# Color inputs\n\nThe `v-color-input` component combines a text field with a color picker..\n\n<PageFeatures />\n\n## Installation\n\nLabs components require a manual import and installation of the component.\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { VColorInput } from 'vuetify/labs/VColorInput'\n\nexport default createVuetify({\n  components: {\n    VColorInput,\n  },\n})\n```\n\n## Usage\n\nAt its core, the `v-color-input` component is a basic container that extends [v-text-field](/components/text-fields).\n\n<ExamplesUsage name=\"v-color-input\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-color-input](/api/v-color-input/) | Primary component |\n| [v-color-picker](/api/v-color-picker/) | Color picker component |\n| [v-text-field](/api/v-text-field/) | Text field component |\n\n<ApiInline hide-links />\n\n## Guide\n\nThe `v-color-input` component provides a clean interface for selecting colors.\n\n### Props\n\nThe `v-color-input` component extends the [v-text-field](/components/text-fields/) and [v-color-picker](/components/color-pickers/) component; and supports all of their props.\n\n#### Pip location\n\nYou can move the pip icon within the input by utilizing the `pip-location` or hide it entirely with `hide-pip`.\n\n<ExamplesExample file=\"v-color-input/prop-pip-location\" />\n\n#### Color Pip\n\nThe `color-pip` is a boolean that determines whether the pip icon color matches the selected color.\n\n<ExamplesExample file=\"v-color-input/prop-color-pip\" />\n\n#### Pip variant\n\nThe `pip-variant` lets you further customize the pip icon.\n\n<ExamplesExample file=\"v-color-input/prop-pip-variant\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/color-pickers.md",
    "content": "---\nmeta:\n  nav: Color pickers\n  title: Color picker component\n  description: The color picker component allows users to select a from pre-defined or custom colors using a variety of different inputs and formats.\n  keywords: color pickers, vuetify color picker component, vue color picker component\nrelated:\n  - /components/menus/\n  - /styles/colors/\n  - /features/theme/\nfeatures:\n  github: /components/VColorPicker/\n  label: 'C: VColorPicker'\n  report: true\n---\n\n# Color pickers\n\nThe `v-color-picker` allows you to select a color using a variety of input methods.\n\n<PageFeatures />\n\n## Usage\n\n<ExamplesUsage name=\"v-color-picker\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-color-picker](/api/v-color-picker/) | Primary component |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n#### Customizing the look of the picker\n\nThere are a number of props available to help you customize the component by hiding or showing the various parts of the picker. You can independently hide the canvas, the sliders, and the inputs. You can also show a collection of swatches.\n\n<ExamplesExample file=\"v-color-picker/prop-canvas\" />\n\n#### Elevation\n\nAdjust the elevation of the `v-color-picker` component using the **elevation** or **flat** prop. The **flat** is equivalent to setting **elevation** to 0.\n\n<ExamplesExample file=\"v-color-picker/prop-elevation\" />\n\n#### Mode\n\nYou can specify which input modes are available to your users with the `modes` prop. If you only set a single mode, then the mode toggle will automatically be hidden. You can also control the current mode with the `mode` v-model.\n\n<ExamplesExample file=\"v-color-picker/prop-mode\" />\n\n#### Model\n\nThe `v-color-picker` uses the `v-model` prop to control the color displayed. It supports hex strings such as **#FF00FF** and **#FF00FF00**, and objects representing **RGBA**, **HSLA** and **HSVA** values. The component will try to emit the color in the same format that was provided. If the value is null or an unsupported format, then the `v-color-picker` will default to emitting hex colors.\n\n<ExamplesExample file=\"v-color-picker/prop-model\" />\n\n#### Swatches\n\nUsing the `show-swatches` prop you can display an array of color swatches that users can pick from. It is also possible to customize what colors are shown using the `swatches` prop. This prop accepts a two-dimensional array, where the first dimension defines a column, and second dimension defines the swatches from top to bottom by providing rgba hex strings. You can also set the max height of the swatches section with the `swatches-max-height` prop.\n\n<ExamplesExample file=\"v-color-picker/prop-swatches\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/combobox.md",
    "content": "---\nmeta:\n  nav: Combobox\n  title: Combobox component\n  description: The combobox component provides type-ahead autocomplete functionality and allows users to provide a custom values beyond the provided list of options.\n  keywords: combobox, vuetify combobox component, vue combobox component\nrelated:\n  - /components/autocompletes/\n  - /components/forms/\n  - /components/selects/\nfeatures:\n  figma: true\n  label: 'C: VCombobox'\n  report: true\n  github: /components/VCombobox/\n  spec: https://m2.material.io/components/text-fields\n---\n\n# Combobox\n\nThe `v-combobox` component is a [v-text-field](/components/text-fields) that allows the user to select values from a provided **items** array, or to enter their own value. Created items will be returned as strings.\n\n<PageFeatures />\n\n## Usage\n\nWith Combobox, you can allow a user to create new values that may not be present in a provided items list.\n\n<ExamplesUsage name=\"v-combobox\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-combobox](/api/v-combobox/) | Primary component |\n| [v-autocomplete](/api/v-autocomplete/) | A select component that allows for advanced filtering |\n| [v-select](/api/v-select/) | A replacement for the HTML <select></select> |\n\n<ApiInline hide-links />\n\n## Caveats\n\n::: error\n  As the Combobox allows user input, it **always** returns the full value provided to it (for example a list of Objects will always return an Object when selected). This is because there's no way to tell if a value is supposed to be user input or an object lookup [GitHub Issue](https://github.com/vuetifyjs/vuetify/issues/5479)\n\n  This also means that a typed string will not select an item the same way clicking on it would, you may want to set `auto-select-first=\"exact\"` when using object items.\n:::\n\n## Examples\n\n### Props\n\n#### Density\n\nYou can use `density` prop to adjust vertical spacing within the component.\n\n<ExamplesExample file=\"v-combobox/prop-density\" />\n\n#### Placeholder\n\nUse the **placeholder** prop to give users additional context about the expected values in the combobox. The placeholder will only appear when no items are selected.\n\n::: info\n  Use the **persistent-placeholder** prop to force the **placeholder** to be visible, even when the input is not focused.\n:::\n\n<ExamplesExample file=\"v-combobox/prop-placeholder\" />\n\n#### Multiple combobox\n\nPreviously known as **tags** - user is allowed to enter more than one value.\n\n<ExamplesExample file=\"v-combobox/prop-multiple\" />\n\n### Slots\n\n#### No data\n\nIn this example we utilize a custom **no-data** slot to provide context to the user when searching / creating items.\n\n<ExamplesExample file=\"v-combobox/slot-no-data\" />\n\n#### Menu header\n\nThe **menu-header** slot allows you to add custom content at the top of the dropdown menu, such as tabs to filter items by category.\n\n<ExamplesExample file=\"v-combobox/slot-menu-header\" />\n\n#### Custom chips\n\nWhen working with custom chip slots, it’s recommended to use `v-bind=\"props\"` to pass event handler `@mousedown.stop`. This helps prevent unintentionally opening the dropdown.\n\n<ExamplesExample file=\"v-combobox/slot-custom-chip\" />\n\n### Misc\n\n#### Advanced custom options\n\nThe `v-combobox` improves upon the added functionality from `v-select` and `v-autocomplete`. This provides you with an expansive interface to create truly customized implementations. This example takes advantage of some more advanced features such as a custom **filter** algorithm, inline list editing and dynamic input items.\n\n<ExamplesExample file=\"v-combobox/misc-advanced\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/command-palettes.md",
    "content": "---\nemphasized: true\nmeta:\n  nav: Command Palettes\n  title: Command Palette component\n  description: A keyboard-driven command palette component that provides a searchable dialog interface for executing commands and actions.\n  keywords: command palette, keyboard shortcuts, vuetify command palette component, vue command palette component\nrelated:\n  - /components/dialogs/\n  - /components/hotkeys/\n  - /components/lists/\nfeatures:\n  github: /labs/VCommandPalette/\n  label: 'C: VCommandPalette'\n  report: true\n---\n\n# Command Palettes\n\nThe `v-command-palette` component provides a keyboard-driven command interface that allows users to quickly search and execute commands. It's commonly used for quick navigation, command execution, and power-user workflows.\n\n<PageFeatures />\n\n::: success\nThis feature was introduced in v4.0, is a labs component and is available for testing and feedback.\n:::\n\n## Installation\n\nLabs components require manual import and registration with the Vuetify instance.\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { VCommandPalette } from 'vuetify/labs/VCommandPalette'\n\nexport default createVuetify({\n  components: {\n    VCommandPalette,\n  },\n})\n```\n\n## Usage\n\nThe command palette displays a searchable list of commands in a dialog. Users can type to filter items and press Enter or click to execute commands.\n\n<ExamplesUsage name=\"v-command-palette\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-command-palette](/api/v-command-palette/) | Primary Component |\n| [v-dialog](/api/v-dialog/) | Base Component |\n\n<ApiInline hide-links />\n\n## Examples\n\nBelow is a collection of simple to complex examples.\n\n### Props\n\n#### Items\n\nThe **items** prop accepts an array of command palette items. Items support action items (interactive commands), subheaders (section labels), and dividers (visual separators).\n\n<ExamplesExample file=\"v-command-palette/prop-items\" />\n\n#### Hotkey\n\nUse the **hotkey** prop to register a global keyboard shortcut that toggles the command palette. Individual items can also have their own **hotkey** property for quick access.\n\n<ExamplesExample file=\"v-command-palette/prop-hotkey\" />\n\n#### Controlled close behavior\n\nBy default, selecting an actionable item closes the palette. Use **close-on-select** to disable that behavior, or handle **@before-select** and call **preventDefault()** to keep the palette open for external drill-in flows.\n\n<ExamplesExample file=\"v-command-palette/prop-close-on-select\" />\n\n### Slots\n\nThe command palette provides several slots for customizing the display of items and other elements.\n\n#### Item prepend\n\nUse the **#item.prepend** slot to customize the prepend area of each item. This slot receives the current **item** and **index** as slot props.\n\n<ExamplesExample file=\"v-command-palette/slot-item-prepend\" />\n\n#### Item append\n\nSimilarly **#item.append** slot and allows you to include supplemental information (replaces hotkey).\n\n<ExamplesExample file=\"v-command-palette/slot-item-append\" />\n\n### Filtering\n\nThe search input automatically filters items based on their **title** and **subtitle** properties. Use **v-model:search** to control or monitor the search query. The **filter-keys** prop can customize which item properties are searched.\n\nThe **placeholder** prop customizes the search input's placeholder text, while **no-data-text** customizes the message shown when no items match the search query.\n\n### Keyboard navigation\n\nThe command palette supports full keyboard navigation:\n\n- **Arrow Up/Down**: Navigate through commands\n- **Enter**: Execute the selected command\n- **Escape**: Close the palette\n- **Typing**: Filters commands by title and subtitle\n- **Per-item hotkeys**: Execute specific commands directly (when palette is open)\n\n## Accessibility\n\nThe `v-command-palette` component follows accessibility best practices:\n\n- Uses semantic ARIA roles (`listbox` for the list, `option` for items)\n- Provides descriptive labels for screen readers\n- Implements `aria-activedescendant` for proper focus announcement\n- Maintains focus within the dialog while open\n- Returns focus to the previously focused element on close\n- Supports full keyboard navigation without mouse interaction\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/confirm-edit.md",
    "content": "---\nmeta:\n  nav: Confirm Edit\n  title: Confirm Edit\n  description: The confirm edit component is used to allow the user to verify their changes before they are committed. This is useful when you want to prevent accidental changes or to allow the user to cancel their changes.\n  keywords: v-confirm-edit, confirm edit, vuetify confirm edit, vuetify confirm edit component, vuetify confirm edit examples\nrelated:\n  - /components/avatars/\n  - /components/icons/\n  - /components/toolbars/\nfeatures:\n  github: /components/VConfirmEdit/\n  label: 'C: VConfirmEdit'\n  report: true\n---\n\n# Confirm edit\n\nThe `v-confirm-edit` component is used to allow the user to verify their changes before they are committed.\n\n<PageFeatures />\n\n## Usage\n\n<ExamplesUsage name=\"v-confirm-edit\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-confirm-edit](/api/v-confirm-edit/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Guide\n\nThe `v-confirm-edit` component is an intuitive way to capture a model's changes before they are committed. This is useful when you want to prevent accidental changes or to allow the user to cancel their changes.\n\n### Pickers\n\nIt's easy to integrate pickers into the `v-confirm-edit` component. This allows you to provide a more user-friendly experience when selecting dates, times, or colors.\n\n<ExamplesExample file=\"v-confirm-edit/misc-date-picker\" />\n\n### Disable actions\n\nYou can control the disabled state of action buttons using **disabled** prop by either passing an array to disable targeted actions or a boolean value to disable all actions. If the **disabled** prop is not provided, the component will use internal logic to determine the disabled state.\n\n<ExamplesExample file=\"v-confirm-edit/misc-disable-actions\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/data-iterators.md",
    "content": "---\nmeta:\n  nav: Data iterators\n  title: Data iterator component\n  description: The data iterator component is used for filter and displaying data including sorting, searching, pagination, and selection.\n  keywords: data iterators, vuetify data iterator component, vue data iterator component\nrelated:\n  - /components/data-tables/basics/\n  - /components/tables/\n  - /components/toolbars/\nfeatures:\n  github: /components/VDataIterator/\n  label: 'C: VDataIterator'\n  report: true\n---\n\n# Data iterators\n\nThe `v-data-iterator` component is used for displaying arbitrary data, and shares a majority of its functionality with the `v-data-table` component. Features include sorting, searching, pagination, and selection.\n\n<PageFeatures />\n\n## Usage\n\nThe `v-data-iterator` allows you to customize exactly how to display your data. In this example we are using a grid with cards.\n\n<ExamplesUsage name=\"v-data-iterator\" />\n\n<PromotedEntry />\n\n## API\n\n| Component                                | Description       |\n|------------------------------------------|-------------------|\n| [v-data-iterator](/api/v-data-iterator/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Anatomy\n\nThe recommended placement of elements inside of a `v-data-iterator` are:\n\n* Place a [v-toolbar](/components/toolbars/) or similar component above the main content\n* Place content after the header\n* Place a [v-pagination](/components/paginations/) below the main content\n\n![Data iterator Anatomy](https://cdn.vuetifyjs.com/docs/images/components/v-data-iterator/v-data-iterator-anatomy.png){ height=392 }\n\n| Element / Area | Description |\n| - | - |\n| 1. Header (optional) | The header is used to display a title and actions |\n| 2. Container | The container is the root element of the component |\n| 3. Footer (optional) | The footer is used to display pagination |\n\n## Guide\n\nThe `v-data-iterator` component is used for displaying data, and shares a majority of its functionality with the `v-data-table` component. Features include sorting, searching, pagination, and selection.\n\nThe following code snippet is an example of a basic `v-data-iterator` component:\n\n```html\n<v-data-iterator :items=\"[1, 2, 3, 4, 5]\">\n  <template v-slot:default=\"{ items }\">\n    <v-list-item\n      v-for=\"(item, i) in items\"\n      :key=\"i\"\n      :title=\"`Item ${i}`\"\n    ></v-list-item>\n  </template>\n</v-data-iterator>\n```\n\n## Examples\n\nThe following are a collection of examples that demonstrate more advanced and real world use of the `v-data-iterator` component.\n\n### Slots\n\nThe `v-data-iterator` component has 4 main slots\n\n#### Default\n\nThe `v-data-iterator` has internal state for both selection and expansion, just like `v-data-table`. In this example we use the methods `isExpanded` and `toggleExpand` available on the default slot.\n\n<ExamplesExample file=\"v-data-iterator/slot-default\" />\n\n#### Header and footer\n\nThe `v-data-iterator` has both a **header** and **footer** slot for adding extra content.\n\n<ExamplesExample file=\"v-data-iterator/slot-header-and-footer\" />\n\n#### Controllable props\n\nSorting, filters and pagination can be controlled externally by using the individual props\n\n<ExamplesExample file=\"v-data-iterator/misc-filter\" />\n\n#### Loader props\n\nLoader can be used to change loader on \"loading\" prop\n\n<ExamplesExample file=\"v-data-iterator/slot-loader\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/data-tables/basics.md",
    "content": "---\nmeta:\n  nav: Basics\n  title: Data table component\n  description: The data table component is used for displaying tabular data in a way that is easy for users to scan. It includes sorting, searching, pagination and selection.\n  keywords: data tables, vuetify data table component, vue data table component\nrelated:\n  - /components/paginations/\n  - /components/tables/\n  - /components/lists/\nfeatures:\n  github: /components/VDataTable/\n  label: 'C: VDataTable'\n  report: true\n  spec: https://m2.material.io/components/data-tables\n---\n\n# Data tables\n\nThe `v-data-table` component is used for displaying tabular data. Features include sorting, searching, pagination, grouping, and row selection.\n\n<PageFeatures />\n\n## Usage\n\nThe standard data table presumes that the entire data set is available locally. Sorting, pagination, and filtering is supported and done internally by the component itself.\n\n<ExamplesUsage name=\"v-data-table\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-data-table](/api/v-data-table/) | Primary Component |\n| [v-data-table-headers](/api/v-data-table-headers/) | Functional Component used to display Data-table headers |\n| [v-data-table-footer](/api/v-data-table-footer/) | Functional Component used to display Data-table footers |\n| [v-data-table-row](/api/v-data-table-row/) | Functional Component used to display a single row of a data-table |\n| [v-data-table-rows](/api/v-data-table-rows/) | Functional Component used to display all of the rows in a data-table |\n| [v-checkbox-btn](/api/v-checkbox-btn/) | Reusable lightweight [v-checkbox](/components/checkboxes) |\n\n<ApiInline hide-links />\n\n### Server side tables\n\nThis variant of the data table is meant to be used for very large datasets, where it would be inefficient to load all the data into the client. It supports sorting, filtering, pagination, and selection like a standard data table, but all the logic must be handled externally by your backend or database.\n\n| Component | Description |\n| - | - |\n| [v-data-table-server](/api/v-data-table-server/) | Primary Component |\n\nFind more information and examples on the [Server side tables](/components/data-tables/server-side-tables) page.\n\n<ExamplesExample file=\"v-data-table/server\" />\n\n### Virtual tables\n\nThe virtual variant of the data table relies, like the standard variant, on all data being available locally. But unlike the standard variant it uses virtualization to only render a small portion of the rows. This makes it well suited for displaying large data sets. It supports client-side sorting and filtering, but not pagination.\n\n| Component | Description |\n| - | - |\n| [v-data-table-virtual](/api/v-data-table-virtual/) | Primary Component |\n\nFind more information and examples on the [Virtual tables](/components/data-tables/virtual-tables) page.\n\n<ExamplesExample file=\"v-data-table/virtual\" />\n\n## Guide\n\nThe `v-data-table` component is a simple and powerful table manipulation component. It is perfect for showing large amounts of tabular data.\n\n### Items\n\nTable items can be objects with almost any shape or number of properties. The only requirement is some form of unique identifier if row selection is being utilized.\n\n### Headers\n\nThe headers array is the core of the table. It defines which properties to display, their associated labels, how they should be sorted, and what they should look like.\n<br>\nAll properties are optional, but at least one of **title**, **value**, or **key** should be present to display more than just an empty column:\n\n```js\nconst headers = [\n  { title: 'No data, just a label' },\n  { key: 'quantity' },\n  { value: 'price' },\n]\n```\n\nWithout any headers defined, the table will use all the keys of the first item as headers.\n\nHeaders can also be a tree structure with a **children** property to create multi-row header labels with rowspan and colspan calculated automatically.\n<br>\nLeaf nodes (objects without **children**) will be used as columns for each item.\n<br>\nBranch nodes (objects with **children**) support all the same sorting and filtering options as leaf nodes, but cannot be used as columns.\n\n<ExamplesExample file=\"v-data-table/headers-multiple\" />\n\n#### Keys and values\n\nThe **key** property is used to identify the column in slots, events, filters, and sort functions. It will default to the **value** property if **value** is a string.\n<br>\n**value** maps the column to a property in the items array. If **value** is not defined it will default to **key**, so key and value are interchangeable in most cases. The exception to this is reserved keys like `data-table-select` and `data-table-expand` which must be defined as **key** to work properly.\n<br>\n**key** and **value** both support dot notation to access properties of nested objects, and **value** can also be a function to combine multiple properties or do other custom formatting. If **value** is not a string then **key** must be defined.\n\n```js\nconst items = [\n  {\n    id: 1,\n    name: {\n      first: 'John',\n      last: 'Doe',\n    },\n  },\n]\n\nconst headers = [\n  { title: 'First Name', value: 'name.first' },\n  { title: 'Last Name', key: 'name.last' },\n  {\n    title: 'Full Name',\n    key: 'fullName',\n    value: item => `${item.name.first} ${item.name.last}`,\n  },\n]\n```\n\n#### Sorting, filtering, pagination\n\nSee [Data and display](/components/data-tables/data-and-display).\n\n#### Customization\n\nOther options are available for setting **width**, **align**, **fixed**, or pass custom props to the header element with **headerProps** and row cells with **cellProps**.\n\n### Props\n\nThere is no shortage of properties available for customizing various aspects of the Data table components.\n\n#### Density\n\nUsing the **density** prop you are able to give your data tables an alternate style.\n\n<ExamplesExample file=\"v-data-table/prop-dense\" />\n\n<!-- #### Footer props\n\nThe `v-data-table` renders a default footer using the `v-data-footer` component. You can pass props to this component using **footer-props**.\n\n<ExamplesExample file=\"v-data-table/prop-footer-props\" /> -->\n\n#### Hide default header and footer\n\nYou can apply the **hide-default-header** and **hide-default-footer** props to remove the default header and footer respectively.\n\n<ExamplesExample file=\"v-data-table/prop-hide-header-footer\" />\n\n#### Sort icons\n\nYou can customize sorting icons using dedicated props as well as control default opacity and spacing with Sass variables.\n\n<ExamplesExample file=\"v-data-table/prop-sort-icon\" />\n\n#### Selection\n\nThe **show-select** prop will render a checkbox in the default header to toggle all rows, and a checkbox for each row.\n\nFor more information and examples, see the [selection examples](/components/data-tables/data-and-display/#selection-examples) page.\n\n<ExamplesExample file=\"v-data-table/prop-row-selection\" />\n\n#### Simple checkbox\n\nWhen wanting to use a checkbox component inside of a slot template in your data tables, use the `v-checkbox-btn` component rather than the `v-checkbox` component.\n\n<ExamplesExample file=\"v-data-table/slot-simple-checkbox\" />\n\n#### Group by\n\nThe **group-by** prop makes it possible to group rows by one or more attributes.\n\n<ExamplesExample file=\"v-data-table/prop-grouping\" />\n\n### Slots\n\n#### Header slot\n\nYou can use the dynamic slots `header.<key>` to customize only certain columns. `<key>` corresponds to the **key** property in the items found in the **headers** prop.\n\n::: info\nThere are two built-in slots for customizing both the select (`header.data-table-select`) and expand (`header.data-table-expand`) columns when using **show-select** and **show-expand** props respectively.\n:::\n\n<ExamplesExample file=\"v-data-table/slot-header\" />\n\n#### Headers slot\n\nYou can also override all the internal headers by using the `headers` slot. Remember that you will have to re-implement any internal functionality like sorting.\n\n<ExamplesExample file=\"v-data-table/slot-headers\" />\n\n#### Item slot\n\nNormally you would use the `item.<key>` slots to render custom markup in specific columns. If you instead need more control over the entire row, you can use the `item` slot.\n\n<ExamplesExample file=\"v-data-table/slot-item\" />\n\n#### Item key slot\n\nYou can use the dynamic slots `item.<key>` to customize only certain columns. `<key>` is the name of the **key** property in header items sent to **headers**. So to customize the calories column we're using the `item.calories` slot.\n\n<ExamplesExample file=\"v-data-table/slot-item-key\" />\n\n#### Group header slot\n\nWhen using the **group-by** prop, you can customize the group header with the `group-header` slot. Example below makes the whole row clickable.\n\n<ExamplesExample file=\"v-data-table/slot-group-header\" />\n\n#### Group summary slot\n\nBy default grouping with **group-by** shows only the header slot. When you define `group-summary` slot, additional summary row will appear below the group rows.\n\n<ExamplesExample file=\"v-data-table/slot-group-summary\" />\n\n#### Loading slot\n\nThe `loading` slot allows you to customize your table's display state when fetching data. In this example we utilize the [v-skeleton-loader](/components/skeleton-loaders) component to display a loading animation.\n\n<ExamplesExample file=\"v-data-table/slot-loading\" />\n\n### Misc\n\n#### Select All\n\nThe example below shows how to use the `@keydown` event to quickly select all rows in the data table using the `Ctrl+A` or `Cmd+A` keyboard shortcut. To begin using the shortcut, click anywhere inside the table first.\n\n<ExamplesExample file=\"v-data-table/misc-select-all\" />\n\n## Examples\n\nThe following are a collection of examples that demonstrate more advanced and real world use of the `v-data-table` component.\n\n### CRUD Actions\n\n`v-data-table` with CRUD actions using a `v-dialog` component for editing each row\n\n<ExamplesExample file=\"v-data-table/misc-crud\" />\n\n### Expandable rows\n\nThe **show-expand** prop will render an expand icon on each row. You can customize this with the `item.data-table-expand` slot. The position of this slot can be changed by adding a column with `key: 'data-table-expand'` to the headers array.\n\nYou can override the rows expand icon via the `item.data-table-expand` slot. To call upon the expand functionality, pass the slots provided `internalItem` to the `toggleExpand` function and add it to a click handler to perform the expand functionality. You can also check the current state of the rows expansion by passing the `internalItem` to the `isExpanded` function.\n\nJust like selection, row items require a unique property on each item for expansion to work. The default is `id`, but you can use the **item-value** prop to specify a different item property.\n\n<ExamplesExample file=\"v-data-table/misc-expand\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/data-tables/data-and-display.md",
    "content": "---\nmeta:\n  nav: Data and Display\n  title: Data table - Data and Display\n  description: The data table component is used for displaying tabular data in a way that is easy for users to scan. It includes sorting, searching, pagination and selection.\n  keywords: data tables, vuetify data table component, vue data table component\nrelated:\n  - /components/data-tables/basics/\n  - /components/paginations/\n  - /components/tables/\nfeatures:\n  github: /components/VDataTable/\n  label: 'C: VDataTable'\n  report: true\n---\n\n# Data and Display\n\nData table filtering is a key feature that allows users to quickly find the data they are looking for.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## Filtering examples\n\nThese examples demonstrate various ways that you can utilize the **search** prop to filter results.\n\n### Search\n\nThe data table exposes a **search** prop that allows you to filter your data.\n\n<ExamplesExample file=\"v-data-table/prop-search\" />\n\n### Filter Keys\n\nYou can easily select only the column you want to filter on by using the **filter-keys** prop. This prop accepts an array of keys from the table items that will be used for filtering. You may also choose to disable columns from filtering by setting the **filter** property to `false` on the header item(s). In the example below the we only filter on the `name` column.\n\n<ExamplesExample file=\"v-data-table/prop-filter-keys\" />\n\n### Custom filter\n\nYou can override the default filtering used with the **search** prop by supplying a function to the **custom-filter** prop. You can see the signature of the function below.\n\n```ts\n(value: string, query: string, item?: any) => boolean | number | [number, number] | [number, number][]\n```\n\nAdditionally, you may apply customize the filtering on a per column basis by setting custom function to the **filter** property on the header item(s). In the example below, the custom filter will only match inputs that are in completely in upper case.\n\n<ExamplesExample file=\"v-data-table/prop-custom-filter\" />\n\n## Pagination examples\n\nPagination is used to split up large amounts of data into smaller chunks.\n\n### External pagination\n\nPagination can be controlled externally by using the individual props, or by using the **options** prop. Remember to use **v-model**, so you fully control the state.\n\n<ExamplesExample file=\"v-data-table/misc-external-paginate\" />\n\n## Selection examples\n\nSelection allows you to select/deselect rows and retrieve information about which rows have been selected.\n\n### Item value\n\nFor the selection feature to work, the data table must be able to differentiate each row in the data set. This is done using the **item-value** prop. It designates a property on the item that should contain a unique value. By default the property it looks for is `id`.\n\nYou can also supply a function, if for example the unique value needs to be a composite of several properties. The function receives each item as its first argument.\n\n<ExamplesExample file=\"v-data-table/prop-item-value\" />\n\n### Selected values\n\nThe current selection of the data-table can be accessed through the **v-model** prop. The array will consist of the unique values found in the property you set using the **item-value** prop (or the value returned by the function you passed). You can use **return-object** prop if you want the array to consist of the actual objects instead.\n\n<ExamplesExample file=\"v-data-table/prop-return-object\" />\n\n<PromotedEntry />\n\n### Selectable rows\n\nUse the **item-selectable** prop to designate a property on your items that controls if the item should be selectable or not.\n\n<ExamplesExample file=\"v-data-table/prop-item-selectable\" />\n\n### Custom select column\n\nUse the **item.data-table-select** slot alongside `v-checkbox-btn` to customize the checkbox used for row selection. You can also use the **header.data-table-select** slot to customize the select-all checkbox in the header of the column.\n\n<ExamplesExample file=\"v-data-table/slot-item-data-table-select\" />\n\n### Select strategies\n\nData-tables support three different select strategies.\n\n|Strategy|Description|\n|-|-|\n|`'single'`|Only a single row can be selected. The select all checkbox in the header is not shown|\n|`'page'`|Multiple rows can be selected. Clicking on the select all checkbox in the header selects all (selectable) rows on the current page|\n|`'all'`|Multiple rows can be selected. Clicking on the select all checkbox in the header selects all (selectable) rows in the entire data set|\n\n<ExamplesExample file=\"v-data-table/prop-select-strategy\" />\n\n## Sorting examples\n\nData tables can sort rows by a column value.\n\n<PromotedEntry />\n\n### Basic sorting\n\nThe sorting of your table can be controlled by the **sort-by** prop. This prop takes an array of objects, where each object has a **key** and **order** property, describing how the table is to be sorted.\n\nThe **key** corresponds to a column defined in the **headers** array, and **order** is either the string `'asc'` or `'desc'` indicating the order in which the items are sorted.\n\nUnless you are using the **multi-sort** prop seen below, this array will almost always just have a single object in it.\n\n<ExamplesExample file=\"v-data-table/prop-sort-by\" />\n\n### Multi sort\n\nUsing the **multi-sort** prop will allow user to sort on multiple columns at the same time. You can specify whether new columns should be added first or last to the **sort-by** array. By specifying optional **modifier** key, you can support both modes.\n\n<ExamplesExample file=\"v-data-table/prop-multi-sort\" />\n\n### Sort by raw\n\nUsing a *sortRaw* key in your headers object gives you access to all values on the item. This is useful if you want to sort by a value that is not displayed in the table or a combination of multiple values.\n\n<ExamplesExample file=\"v-data-table/prop-headers-sort-raw\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/data-tables/introduction.md",
    "content": "---\nmeta:\n  nav: Introduction\n  title: Data table - Introduction\n  description: The data table component is used for displaying tabular data in a way that is easy for users to scan. It includes sorting, searching, pagination and selection.\n  keywords: data tables, vuetify data table component, vue data table component\nrelated:\n  - /components/paginations/\n  - /components/selects/\n  - /components/data-tables/basics/\n---\n\n# Data table - Introduction\n\nThe data table component is used for displaying tabular data in a way that is easy for users to scan. It includes sorting, searching, pagination and selection.\n\n<PromotedEntry />\n\n## Components\n\nBefore diving into the guides and examples, let's take a moment to understand the core components available for data tables. These are variations optimized for different scenarios.\n\n| Component                                                    | Use-case                                                                            |\n|--------------------------------------------------------------|-------------------------------------------------------------------------------------|\n| [Data tables](/components/data-tables/basics/)               | The base functionality data table, used for paginating, filtering and sorting data. |\n| [Server tables](/components/data-tables/server-side-tables/) | Adds new events and properties used for displaying data from a server               |\n| [Virtual tables](/components/data-tables/virtual-tables/)    | A version of the data table that has built in row virtualization features           |\n\n## API\n\n| Component                                          | Description                                                 |\n|----------------------------------------------------|-------------------------------------------------------------|\n| [v-data-table](/api/v-data-table/)                 | Primary Component                                           |\n| [v-data-table-server](/api/v-data-table-server/)   | Specialized Data-table for displaying results from a server |\n| [v-data-table-virtual](/api/v-data-table-virtual/) | Data-table with built in row virtualization                 |\n| [v-data-table-footer](/api/v-data-table-footer/)   | Functional Component used to display Data-table footer     |\n| [v-checkbox-btn](/api/v-checkbox-btn/)             | Reusable lightweight [v-checkbox](/components/checkboxes)   |\n\n<ApiInline hide-links />\n\n## Guides\n\nExplore data table pages that provide detailed explanations and code samples for various functionalities and use cases.\n\n| Guide                                                         | Description                                                |\n|---------------------------------------------------------------|------------------------------------------------------------|\n| [Basics](/components/data-tables/basics/)                     | Understand the fundamental building blocks of Data Tables. |\n| [Data and Display](/components/data-tables/data-and-display/) | Learn how to manipulate and display data effectively.      |\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/data-tables/server-side-tables.md",
    "content": "---\nmeta:\n  nav: Server side tables\n  title: Data table - Server side tables\n  description: The data table component is used for displaying tabular data in a way that is easy for users to scan. It includes sorting, searching, pagination and selection.\n  keywords: data tables, vuetify data table component, vue data table component\nrelated:\n  - /components/data-tables/basics/\n  - /components/data-tables/virtual-tables/\n  - /components/tables/\nfeatures:\n  github: /components/VDataTable/VDataTableServer.tsx\n  label: 'C: VDataTableServer'\n  report: true\n---\n\n# Data table - Server side tables\n\nServer-side Data tables are used for showing data coming from an API.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-data-table-server](/api/v-data-table-server/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Server-side paginate and sort\n\nTo use data from an API, listen to the **@update:options** event to know when to fetch new data. Use the **loading** prop to display a progress bar while fetching the data.\n\n<ExamplesExample file=\"v-data-table/misc-server-side-paginate-and-sort\" />\n\n### Server-side search\n\nIf you need to support search functionality, use the **search** prop to let the table know when new search input is available. Since the table does not actually do any filtering on its own, the **search** input does not need to be the actual value being searched for. In this example we have multiple values searchable, so we just make sure to set **search** to _anything_ when we need to fetch new data.\n\n<ExamplesExample file=\"v-data-table/server-search\" />\n\n### Loading\n\nYou can use the **loading** prop to indicate that data in the table is currently loading. If there is no data in the table, a loading message will also be displayed. This message can be customized using the **loading-text** prop or the `loading` slot.\n\n<ExamplesExample file=\"v-data-table/prop-loading\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/data-tables/virtual-tables.md",
    "content": "---\nmeta:\n  nav: Virtual tables\n  title: Data table - Virtual tables\n  description: The data table component is used for displaying tabular data in a way that is easy for users to scan. It includes sorting, searching, pagination and selection.\n  keywords: data tables, vuetify data table component, vue data table component\nrelated:\n  - /components/data-tables/basics/\n  - /components/data-tables/server-side-tables/\n  - /components/tables/\nfeatures:\n  github: /components/VDataTable/VDataTableVirtual.tsx\n  label: 'C: VDataTableVirtual'\n  report: true\n---\n\n# Data table - Virtual tables\n\nThe v-data-table-virtual component relies on all data being available locally. But unlike the standard data-table it uses virtualization to only render a small portion of the rows. This makes it well suited for displaying large data sets. It supports sorting and filtering, but not pagination.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-data-table-virtual](/api/v-data-table-virtual/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Basic example\n\n<ExamplesExample file=\"v-data-table/virtual\" />\n\nWhen customizing rows with the `#item` slot, you must bind the provided `itemRef` to your `<tr>`. This ensures that the virtual scroller can correctly measure and recycle rows.\n\n<ExamplesExample file=\"v-data-table/virtual-custom\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/date-inputs.md",
    "content": "---\nmeta:\n  nav: Date inputs\n  title: Date input component\n  description: The date input is a specialized input that provides a clean interface for selecting dates, showing detailed selection information.\n  keywords: date input, date picker, date field\nrelated:\n  - /components/date-pickers/\n  - /components/text-fields/\n  - /components/menus/\nfeatures:\n  label: 'C: VDateInput'\n  report: true\n  github: /labs/VDateInput/\n---\n\n# Date inputs\n\nThe `v-date-input` component combines a text field with a date picker. It is meant to be a direct replacement for a standard date input.\n\n<PageFeatures />\n\n## Installation\n\nLabs components require manual import and registration with the Vuetify instance.\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { VDateInput } from 'vuetify/labs/VDateInput'\n\nexport default createVuetify({\n  components: {\n    VDateInput,\n  },\n})\n```\n\n## Usage\n\nAt its core, the `v-date-input` component is a basic container that extends [v-text-field](/components/text-fields).\n\n<ExamplesUsage name=\"v-date-input\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-date-input](/api/v-date-input/) | Primary component |\n| [v-date-picker](/api/v-date-picker/) | Date picker component |\n| [v-text-field](/api/v-text-field/) | Text field component |\n\n<ApiInline hide-links />\n\n## Guide\n\nThe `v-date-input` component is a replacement for the standard date input. It provides a clean interface for selecting dates and shows detailed selection information.\n\n::: tip\n\nUse the built in parseISO and toISO methods available as part of the [date composable](/features/dates/) to format and parse the date input. Internally, `v-date-input` transforms the model into a plain JS Date object.\n\n:::\n\n### Props\n\nThe `v-date-input` component extends the [v-text-field](/components/text-fields/) and [v-date-picker](/components/date-pickers/) component; and supports all of their props.\n\n#### Model\n\nThe default model value is a Date object, but is displayed as formatted text in the input..\n\n<ExamplesExample file=\"v-date-input/prop-model\" />\n\n#### Multiple\n\nUsing the **multiple** prop, the default model value is an empty array.\n\n<ExamplesExample file=\"v-date-input/prop-multiple\" />\n\n#### Range\n\nUsing the multiple prop with a value of **range**, select 2 dates to select them and all the dates between them.\n\n<ExamplesExample file=\"v-date-input/prop-multiple-range\" />\n\n::: tip\n\nOn mobile devices, when the menu is open, clicking the input a second time will enable editing mode.\n\n:::\n\n#### Calendar icon\n\nYou can move the calendar icon within the input or entirely by utilizing the **prepend-icon** and **prepend-inner-icon** properties.\n\n<ExamplesExample file=\"v-date-input/prop-prepend-icon\" />\n\n#### Input format\n\nYou can use the **input-format** prop to change the displayed format of the date in the input. This will make the field expect the same format when typing and pasting values.\n\n<ExamplesExample file=\"v-date-input/prop-input-format\" />\n\n## Examples\n\nThe following are a collection of examples that demonstrate more advanced and real world use of the `v-date-input` component.\n\n### Passenger\n\nIn this example, the `v-date-input` component is used to select a date of birth.\n\n<ExamplesExample file=\"v-date-input/misc-passenger\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/date-pickers-month.md",
    "content": "---\ndisabled: true\nmeta:\n  title: Month picker component\n  description: The month picker component is a stand-alone interface that allows the selection of month or both month and year.\n  keywords: month pickers, vuetify month picker component, vue month picker component\nrelated:\n  - /components/date-pickers/\n  - /components/menus/\n  - /components/time-pickers/\n---\n\n# Date pickers - month\n\n`v-date-picker` can be used as a standalone month picker component.\n\n<PromotedEntry />\n\n## Usage\n\nMonth pickers come in two orientation variations, portrait **(default)** and landscape.\n\n<ExamplesExample file=\"v-date-picker-month/usage\" />\n\n## API\n\n<ApiInline />\n\n## Caveats\n\n::: warning\n  `v-date-picker` accepts ISO 8601 **date** strings (*YYYY-MM-DD*). For more information regarding ISO 8601 and other standards, visit the official ISO (International Organization for Standardization) [International Standards](https://www.iso.org/standards.html) page.\n:::\n\n## Examples\n\n### Props\n\n#### Allowed months\n\nYou can specify allowed months using arrays, objects or functions.\n\n<ExamplesExample file=\"v-date-picker-month/prop-allowed-months\" />\n\n#### Colors\n\nMonth picker colors can be set using the **color** and **header-color** props. If **header-color** prop is not provided header will use the `color` prop value.\n\n<ExamplesExample file=\"v-date-picker-month/prop-colors\" />\n\n#### Icons\n\nYou can override the default icons used in the picker.\n\n<ExamplesExample file=\"v-date-picker-month/prop-icons\" />\n\n#### Multiple\n\nMonth pickers can now select multiple months with the **multiple** prop. If using **multiple** then the month picker expects its model to be an array.\n\n<ExamplesExample file=\"v-date-picker-month/prop-multiple\" />\n\n#### Readonly\n\nSelecting new date could be disabled by adding **readonly** prop.\n\n<ExamplesExample file=\"v-date-picker-month/prop-readonly\" />\n\n#### Show current\n\nBy default the current month is displayed using outlined button - **show-current** prop allows you to remove the border or select different month to be displayed as the current one.\n\n<ExamplesExample file=\"v-date-picker-month/prop-show-current\" />\n\n#### Width\n\nYou can specify allowed the picker's width or make it full width.\n\n<ExamplesExample file=\"v-date-picker-month/prop-width\" />\n\n### Misc\n\n#### Dialog and menu\n\nWhen integrating a picker into a `v-text-field`, it is recommended to use the **readonly** prop. This will prevent mobile keyboards from triggering. To save vertical space, you can also hide the picker title.\n\nPickers expose a slot that allow you to hook into save and cancel functionality. This will maintain an old value which can be replaced if the user cancels.\n\n<ExamplesExample file=\"v-date-picker-month/misc-dialog-and-menu\" />\n\n#### Internationalization\n\nThe month picker supports internationalization through the JavaScript Date object. Specify a BCP 47 language tag using the **locale** prop.\n\n<ExamplesExample file=\"v-date-picker-month/misc-internationalization\" />\n\n#### Orientation\n\nMonth pickers come in two orientation variations, portrait **(default)** and landscape.\n\n<ExamplesExample file=\"v-date-picker-month/misc-orientation\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/date-pickers.md",
    "content": "---\nmeta:\n  title: Date pickers\n  description: The date picker component is a stand-alone interface that allows the selection of a date, month and year.\n  keywords: date pickers, vuetify date picker component, vue date picker component\nrelated:\n  - /components/buttons/\n  - /features/dates/\n  - /components/text-fields/\nfeatures:\n  github: /components/VDatePicker/\n  label: 'C: VDatePicker'\n  report: true\n  spec: https://m2.material.io/components/date-pickers\n---\n\n# Date pickers\n\n`v-date-picker` is a fully featured date selection component that lets users select a date.\n\n<PageFeatures />\n\n## Usage\n\nDate pickers come in two orientation variations, portrait **(default)** and landscape. By default they are emitting `input` event when the day (for date picker) or month (for month picker), but with **reactive** prop they can update the model even after clicking year/month.\n\n<ExamplesUsage name=\"v-date-picker\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-date-picker](/api/v-date-picker/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Guide\n\nThe `v-date-picker` component is a stand-alone interface that allows the selection of a date, month and year. This component is built using the [Date composable](/features/dates/).\n\nAll date components support the [date-io](https://github.com/dmtrKovalenko/date-io) abstraction layer for date management. By default they will use a built-in adapter that uses the native Date object, but it is possible to use any of the date-io adapters. See the [dates](/features/dates/) page for more information.\n\n```js\nimport DayJsAdapter from '@date-io/dayjs'\n\ncreateVuetify({\n  date: {\n    adapter: DayJsAdapter,\n  },\n})\n```\n\n### Props\n\nThe `v-date-picker` component supports multiple props for configuring dates that can be selected, date formats, translations and more.\n\n#### Elevation\n\nThe `v-date-picker` component supports elevation up to a maximum value of 5. For more information on elevations, visit the official [Material Design elevations](https://m3.material.io/styles/elevation) page.\n\n<ExamplesExample file=\"v-date-picker/prop-elevation\" />\n\n#### Width\n\nYou can specify the picker's width or make it full width.\n\n<ExamplesExample file=\"v-date-picker/prop-width\" />\n\n#### Show sibling months\n\nBy default days from previous and next months are not visible. They can be displayed using the **show-adjacent-months** prop.\n\n<ExamplesExample file=\"v-date-picker/prop-show-adjacent-months\" />\n\n#### Colors\n\nDate picker colors can be set using the **color** props.\n\n<ExamplesExample file=\"v-date-picker/prop-colors\" />\n\n#### Allowed dates\n\nSpecify allowed dates using objects or functions. When using objects, accepts a date string in the format of YYYY-MM-DD. When using functions, accepts a date object as a parameter and should return a boolean.\n\n<ExamplesExample file=\"v-date-picker/prop-allowed-dates\" />\n\n#### Landscape\n\nUsing `landscape` moves header to the side. You can customize it further using custom width and date format.\n\n<ExamplesExample file=\"v-date-picker/prop-landscape\" />\n\n#### Date events\n\nYou can specify events using arrays, objects or functions. To change the default color of the event use **event-color** prop. Your **events** function or object can return an array of colors (material or css) in case you want to display multiple event indicators.\n\n<ExamplesExample file=\"v-date-picker/prop-events\" />\n\n### Slots\n\n#### Controls\n\nReplace main controls to adapt behavior and/or visual appearance beyond CSS styling.\n\n<ExamplesExample file=\"v-date-picker/slots-controls\" />\n\n### Internationalization\n\nVuetify components can localize date formats by utilizing the [i18n](/features/internationalization) feature. This determines the appropriate locale for date display. When the default date adapter is in use, localization is managed automatically.\n\nFor those not using the default date adapter, you need to create a mapping between the i18n locale string and your chosen date library's locale. This can be done in the Vuetify options as shown below:\n\n```js\nimport DateFnsAdapter from '@date-io/date-fns'\nimport enUS from 'date-fns/locale/en-US'\nimport svSE from 'date-fns/locale/sv'\n\ncreateVuetify({\n  date: {\n    adapter: DateFnsAdapter,\n    locale: {\n      en: enUS,\n      sv: svSE,\n    },\n  },\n})\n```\n\n### Parsing dates\n\nIt's recommended that you use the [Date composable](/features/dates/) for parsing and formatting when working with string dates. The following example uses the parseISO function to convert a string date to a Date object.\n\n```js\nimport { useDate } from 'vuetify'\n\nconst adapter = useDate()\nconst date = '2023-11-30'\n\nconsole.log(new Date(date)) // Wed Nov 29 2023 18:00:00 GMT-0600\nconsole.log(adapter.parseISO(date)) // Thu Nov 30 2023 00:00:00 GMT-0600\n```\n\nUsing this function ensures that the date is parsed correctly regardless of the user's timezone.\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/defaults-providers.md",
    "content": "---\nmeta:\n  nav: Defaults providers\n  title: Defaults provider component\n  description: The defaults provider allows you to provide specific default prop values to components in a section of your application\n  keywords: defaults provider, vuetify defaults provider component, vue defaults provider component\nrelated:\n  - /features/aliasing/\n  - /features/blueprints/\n  - /features/global-configuration/\nfeatures:\n  github: /components/VDefaultsProvider/\n  label: 'C: VDefaultsProvider'\n  report: true\n---\n\n# Defaults providers\n\nThe defaults provider allows you to provide specific default prop values to components in a section of your application\n\n<PageFeatures />\n\n## Usage\n\nThe `v-defaults-provider` component is used to provide default props to components within its scope. It hooks into the [Global configuration](/features/global-configuration/) feature and makes it easy to assign multiple properties at once or scope out all incoming changes to any children.\n\n<ExamplesUsage name=\"v-defaults-provider\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-defaults-provider](/api/v-defaults-provider/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Defaults\n\nThe `v-defaults-provider` expects a prop **defaults** which looks the same as the **defaults** object that you can pass to `createVuetify` when creating your application.\n\n<ExamplesExample file=\"v-defaults-provider/prop-defaults\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/dialogs.md",
    "content": "---\nmeta:\n  nav: Dialogs\n  title: Dialog component\n  description: The dialog component informs a user about a specific task and may contain critical information or require the user to take a specific action.\n  keywords: dialogs, vuetify dialog component, vue dialog component\nrelated:\n  - /components/buttons\n  - /components/cards\n  - /components/menus\nfeatures:\n  github: /components/VDialog/\n  label: 'C: VDialog'\n  report: true\n  spec: https://m2.material.io/components/dialogs\n---\n\n# Dialogs\n\nThe `v-dialog` component inform users about a specific task and may contain critical information, require decisions, or involve multiple tasks. Use dialogs sparingly because they are interruptive.\n\n<PageFeatures />\n\n## Usage\n\nIn this basic example we use the **activator** slot to render a button that is used to open the dialog. When using the **activator** slot it is important that you bind the **props** object from the slot (using `v-bind`) to the element that will activate the dialog. See the examples below for more ways of activating a dialog.\n\n<ExamplesUsage name=\"v-dialog\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-dialog](/api/v-dialog/) | Primary component |\n| [v-overlay](/api/v-overlay/) | Extended component |\n\n<ApiInline hide-links />\n\n## Anatomy\n\nThe recommended components to use inside of a `v-dialog` are:\n\n* [v-card](/components/cards/)\n* [v-list](/components/lists/)\n* [v-sheet](/components/sheets/)\n\n![Dialog Anatomy](https://cdn.vuetifyjs.com/docs/images/components/v-dialog/v-dialog-anatomy.png)\n\n| Element / Area | Description                                                              |\n| - | - |\n| 1. Container | The dialog's content that animates from the activator |\n| 2. Activator | The element that activates the dialog |\n\n## Guide\n\nThe `v-dialog` component is used to inform users about a specific task and may contain critical information, require decisions, or involve multiple tasks. They are controlled by a **v-model** and/or an activator.\n\n### Props\n\nThe `v-dialog` component extends [v-overlay](/components/overlays/) and has access to all of its props.\n\n#### v-model\n\nYou can also trigger a dialog by simply updating the v-model, without using either **activator** slot or prop. In this case, the dialog will not appear to be activated by any specific element, and will simply appear in the middle of the screen.\n\n<ExamplesExample file=\"v-dialog/prop-model\" />\n\n#### Persistent\n\nPersistent dialogs are not dismissed when touching outside or pressing the **esc** key.\n\n<ExamplesExample file=\"v-dialog/prop-persistent\" />\n\n#### Transitions\n\nYou can make the dialog appear from the top or the bottom.\n\n<ExamplesExample file=\"v-dialog/prop-transitions\" />\n\n#### Nesting\n\nDialogs can be nested: you can open one dialog from another.\n\n<ExamplesExample file=\"v-dialog/misc-nesting\" />\n\n#### Overflowed\n\nModals that do not fit within the available window space will scroll the container.\n\n<ExamplesExample file=\"v-dialog/misc-overflowed\" />\n\n### Slots\n\nThe `v-dialog` component has 2 slots, **activator** and **default**. The **activator** slot is used to designate an element that will activate the dialog. The **default** slot provides an **isActive** ref which is tied to the current state of the dialog.\n\n#### Default\n\n<ExamplesExample file=\"v-dialog/slot-default\" />\n\n#### Activator\n\nIn addition using the **activator** slot, we can instead use the **activator** prop to activate a dialog. By placing the dialog component inside the button, and setting the **activator** prop value to **\"parent\"** we can designate the parent (button) as the activator.\n\n<ExamplesExample file=\"v-dialog/prop-activator\" />\n\n## Examples\n\nThe following are a collection of examples that demonstrate more advanced and real world use of the `v-dialog` component.\n\n### Scrollable\n\nExample of a dialog with scrollable content.\n\n<ExamplesExample file=\"v-dialog/prop-scrollable\" />\n\n### Form\n\nA simple example of a form in a dialog.\n\n<ExamplesExample file=\"v-dialog/misc-form\" />\n\n### Loader\n\nThe `v-dialog` component makes it easy to create a customized loading experience for your application.\n\n<ExamplesExample file=\"v-dialog/misc-loader\" />\n\n### Fullscreen\n\nDue to limited space, full-screen dialogs may be more appropriate for mobile devices than dialogs used on devices with larger screens.\n\n<ExamplesExample file=\"v-dialog/prop-fullscreen\" />\n\n### Invite dialog\n\nThis example demonstrates a dialog that is used to invite users to a group.\n\n<ExamplesExample file=\"v-dialog/misc-invite-dialog\" />\n\n### Data Table\n\nThe **activator** prop allows you to use just one instance of the `v-dialog` component. For example, a row in a `v-data-table` can trigger the same dialog.\n\n<ExamplesExample file=\"v-dialog/misc-data-table\"/>\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/dividers.md",
    "content": "---\nmeta:\n  nav: Dividers\n  title: Divider component\n  description: The divider component is a thin line commonly used to separate groups of content in lists or layouts.\n  keywords: dividers, vuetify divider component, vue divider component\nrelated:\n  - /components/lists\n  - /components/navigation-drawers\n  - /components/toolbars\nfeatures:\n  github: /components/VDivider/\n  label: 'C: VDivider'\n  report: true\n  spec: https://m2.material.io/components/dividers\n---\n\n# Dividers\n\nThe `v-divider` component is used to separate sections of lists or layouts.\n\n<PageFeatures />\n\n## Usage\n\nDividers in their simplest form display a horizontal line.\n\n<ExamplesUsage name=\"v-divider\" />\n\n::: info\n\nThis example uses the **border-opacity** utility class and is not available when **$utilities** is set to **false**. More information regarding utility classes is located on the [SASS variables page](features/sass-variables/#basic-usage).\n\n:::\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-divider](/api/v-divider/) | The divider component. |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n#### Inset\n\nInset dividers are moved 72px to the right. This will cause them to line up with list items.\n\n<ExamplesExample file=\"v-divider/prop-inset\" />\n\n#### Gradient\n\nEasily enable fading effect with **gradient** prop for a modern look.\n\n<ExamplesExample file=\"v-divider/prop-gradient\" />\n\n#### Vertical\n\nVertical dividers give you more tools for unique layouts.\n\n<ExamplesExample file=\"v-divider/prop-vertical\" />\n\n### Slots\n\n#### Default\n\nWhen you pass any content to be placed in between dividers simply by utilizing the default slot.\n\n<ExamplesExample file=\"v-divider/slot-default\" />\n\n### Misc\n\n#### Portrait View\n\nCreate custom cards to fit any use-case.\n\n<ExamplesExample file=\"v-divider/misc-portrait-view\" />\n\n#### Subheaders\n\nDividers and subheaders can help break up content and can optionally line up with one another by using the same `inset` prop.\n\n<ExamplesExample file=\"v-divider/misc-subheaders\" />\n\n## Accessibility\n\nBy default, `v-divider` components are assigned the [WAI-ARIA](https://www.w3.org/WAI/standards-guidelines/aria/) role of [**separator**](https://www.w3.org/TR/wai-aria/#separator) which denotes that the divider \"separates and distinguishes sections of content or groups of menu items.\" However, sometimes a divider is just a way to make an interface look nice. In those cases, the role of [**presentation**](https://www.w3.org/TR/wai-aria/#presentation) should be used which denotes \"an element whose implicit native role semantics will not be mapped to the accessibility API.\" To override the default **separator** role in a `v-divider`, simply add a `role=\"presentation\"` prop to your component. In addition, `v-divider` components have an `aria-orientation=\"horizontal\"`. If `vertical=\"true\"`, then `aria-orientation=\"vertical\"` will be set automatically as well. If `role=\"presentation\"`, `aria-orientation=\"undefined\"`, its default value.\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/empty-states.md",
    "content": "---\nmeta:\n  title: Empty states\n  description: The empty state component is used to indicate that a list is empty or that no search results were found.\n  keywords: empty state, no results, no data, no items, no content, no records, no information, no search results\nrelated:\n  - /components/buttons/\n  - /components/icons/\n  - /components/avatars/\nfeatures:\n  report: true\n  spec: https://m2.material.io/design/communication/empty-states.html\n  label: 'C: VEmptyState'\n  github: '/components/VEmptyState/'\n---\n\n# Empty states\n\nThe `v-empty-state` component is used to indicate that a list is empty or that no search results were found.\n\n<PageFeatures />\n\n## Usage\n\nA basic empty state is composed of a title and a description. It can also include an icon and a button.\n\n<ExamplesUsage name=\"v-empty-state\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-empty-state](/api/v-empty-state/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Guide\n\nThe `v-empty-state` component is used to indicate that a page or list is empty or that no search results were found. It can be used in a variety of contexts, such as a list of items, a search results page, or a page with no content.\n\n### Props\n\nThe `v-empty-state` component has a multitude of props that allow you to customize its appearance and behavior.\n\n#### Content\n\nThere are three main properties for configuring text content, **title**, **subtitle**, and **text**.\n\n<ExamplesExample file=\"v-empty-state/prop-content\" />\n\n#### Media\n\nAdd an icon or image to the empty state to help convey its purpose.\n\n<ExamplesExample file=\"v-empty-state/prop-media\" />\n\n#### Actions\n\nAdd a button to the empty state to help users take action.\n\n<ExamplesExample file=\"v-empty-state/prop-actions\" />\n\n### Slots\n\nThe `v-empty-state` component has numerous slots that make it easy to customize the default behavior.\n\n| Slot | Description |\n| - | - |\n| 1. Default | The default slot |\n| 2. Media | The media slot is for images or icons |\n| 3. Title | The main title slot |\n| 4. Subtitle | The subtitle slot |\n| 5. Text | The text slot |\n| 6. Actions | The actions slot |\n\n#### Default\n\nThe default slot is positioned between **text** and **actions**.\n\n<ExamplesExample file=\"v-empty-state/slot-default\" />\n\n#### Title\n\nIt's simple to customize the font-sizing of the title using utility classes.\n\n<ExamplesExample file=\"v-empty-state/slot-title\" />\n\n#### Custom Actions\n\nBy default, only 1 action is displayed through configuration. To add more options, utilize the **actions** slot.\n\n<ExamplesExample file=\"v-empty-state/slot-actions\" />\n\n## Examples\n\nThe following are a collection of examples that demonstrate more advanced and real world use of the `v-empty-state` component.\n\n### Astro dog\n\nThis example demonstrates how to use the `v-empty-state` component to create a fun and engaging empty state.\n\n<ExamplesExample file=\"v-empty-state/misc-astro-dog\" />\n\n### Astro cat\n\nThis example utilizes components such as [v-tabs](/components/tabs/) and [v-window](/components/windows/) to create a more complex empty state.\n\n<ExamplesExample file=\"v-empty-state/misc-astro-cat\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/expansion-panels.md",
    "content": "---\nmeta:\n  nav: Expansion panels\n  title: Expansion panel component\n  description: The expansion panel component is a lightweight container that hides information behind expandable and contractable containers.\n  keywords: expansion panels, vuetify expansion panel component, vue expansion panel component\nrelated:\n  - /components/cards/\n  - /components/data-tables/basics/\n  - /components/lists/\nfeatures:\n  github: /components/VExpansionPanel/\n  label: 'C: VExpansionPanels'\n  report: true\n  spec: https://m1.material.io/components/expansion-panels.html\n---\n\n# Expansion panels\n\nThe `v-expansion-panel` component is useful for reducing vertical space with large amounts of information. The default functionality of the component is to only display one expansion-panel body at a time; however, with the `multiple` property, the expansion-panel can remain open until explicitly closed.\n\n<PageFeatures />\n\n## Usage\n\nExpansion panels in their simplest form display a list of expandable items. You can either declare the markup explicitly, or use the **title** and **text** props.\n\n<ExamplesUsage name=\"v-expansion-panels\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-expansion-panels](/api/v-expansion-panels/) | Primary component |\n| [v-expansion-panel](/api/v-expansion-panel/) | Sub-component that wraps `v-expansion-panel-text` and `v-expansion-panel-title` |\n| [v-expansion-panel-title](/api/v-expansion-panel-title/) | Sub-component used to display the Expansion Panel's title. Wraps the `#title` slot |\n| [v-expansion-panel-text](/api/v-expansion-panel-text/) | Sub-component used to display the Expanion Panel's text. Wraps the `#text` slot |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n#### Variant\n\nThere are four different variants of the expansion-panel. Accordion expansion-panels have no margins around the currently active panel. Inset expansion-panels become smaller when activated, while poput expansion-panels become larger.\n\n<ExamplesExample file=\"v-expansion-panels/prop-variant\" />\n\n#### Disabled\n\nBoth the expansion-panel and its content can be disabled using the **disabled** prop.\n\n<ExamplesExample file=\"v-expansion-panels/prop-disabled\" />\n\n<!-- #### Focusable\n\nThe expansion-panel headers can be made focusable with the prop **focusable**.\n\n<ExamplesExample file=\"v-expansion-panels/prop-focusable\" /> -->\n\n#### Model\n\nExpansion panels can be controlled externally by using the **v-model**. You will need to set a **value** on each panel, so that you can refer to them outside the component. If the **multiple** prop is set, then the **v-model** value will be an array.\n\n<ExamplesExample file=\"v-expansion-panels/prop-model\" />\n\n#### Readonly\n\n**readonly** prop does the same thing as **disabled**, but it doesn't touch styles.\n\n<ExamplesExample file=\"v-expansion-panels/prop-readonly\" />\n\n### Misc\n\n#### Advanced\n\nThe expansion panel component provides a rich playground to build truly advanced implementations. Here we take advantage of slots in the `v-expansion-panel-title` component to react to the state of being open or closed by fading content in and out.\n\n<ExamplesExample file=\"v-expansion-panels/misc-advanced\" />\n\n#### Custom icon\n\nExpand action icon can be customized with **expand-icon** prop or the `actions` slot.\n\n<ExamplesExample file=\"v-expansion-panels/misc-custom-icons\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/explorer/[...name].md",
    "content": "---\nbackmatter: false\nfluid: true\nmeta:\n  nav: API Explorer\n  title: API Explorer\n  description: Explore the Vuetify API\n  keywords: vuetify api explorer\n---\n\n# API Explorer\n\nQuickly search the Vuetify API for components, directives, and composables\n\n----\n\n<PromotedEntry />\n\n<DocExplorer />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/file-inputs.md",
    "content": "---\nmeta:\n  nav: File inputs\n  title: File input component\n  description: The file input component is a specialized input that provides a clean interface for selecting files, showing detailed selection information and upload progress.\n  keywords: file input, file upload, file field\nrelated:\n  - /components/text-fields/\n  - /components/forms/\n  - /components/icons/\nfeatures:\n  label: 'C: VFileInput'\n  report: true\n  github: /components/VFileInput/\n---\n\n# File inputs\n\nThe `v-file-input` component is a specialized input that provides a clean interface for selecting files, showing detailed selection information and upload progress. It is meant to be a direct replacement for a standard file input.\n\n<PageFeatures />\n\n## Usage\n\nAt its core, `v-file-input` is built on the same [VField](/components/text-fields) and VInput primitives as [v-text-field](/components/text-fields), giving it a consistent look and feel without directly extending it.\n\n<ExamplesUsage name=\"v-file-input\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-file-input](/api/v-file-input/) | Primary component |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n#### Accept\n\n`v-file-input` component can accept only specific media formats/file types if you want. For more information, checkout the documentation on the [accept attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept).\n\n<ExamplesExample file=\"v-file-input/prop-accept\" />\n\n#### Chips\n\nA selected file can be displayed as a [chip](/components/chips). When using the **chips** and **multiple** props, each chip will be displayed (as opposed to the file count).\n\n<ExamplesExample file=\"v-file-input/prop-chips\" />\n\n#### Counter\n\nWhen using the **show-size** property along with **counter**, the total number of files and size will be displayed under the input.\n\n<ExamplesExample file=\"v-file-input/prop-counter\" />\n\n#### Density\n\nYou can reduces the file input height with the **density** prop.\n\n<ExamplesExample file=\"v-file-input/prop-dense\" />\n\n#### Multiple\n\nThe `v-file-input` can contain multiple files at the same time when using the **multiple** prop.\n\n<ExamplesExample file=\"v-file-input/prop-multiple\" />\n\n#### Prepend icon\n\nThe `v-file-input` has a default **prepend-icon** that can be set on the component or adjusted globally. More information on changing global components can be found on the [customizing icons page](/features/icon-fonts).\n\n<ExamplesExample file=\"v-file-input/prop-prepend-icon\" />\n\n#### Show size\n\nThe displayed size of the selected file(s) can be configured with the **show-size** property. Display sizes can be either _1024_ (the default used when providing **true**) or _1000_.\n\n<ExamplesExample file=\"v-file-input/prop-show-size\" />\n\n#### Validation\n\nSimilar to other inputs, you can use the **rules** prop to create your own custom validation parameters. If **multiple** props is set, the`value` passed in the validation functions will be an array.\n\n<ExamplesExample file=\"v-file-input/prop-validation\" />\n\n### Slots\n\n#### Selection\n\nUsing the `selection` slot, you can customize the appearance of your input selections. This is typically done with [chips](/components/chips), however any component or markup can be used.\n\n<ExamplesExample file=\"v-file-input/slot-selection\" />\n\n### Misc\n\n#### Complex selection slot\n\nThe flexibility of the selection slot allows you accommodate complex use-cases. In this example we show the first 2 selections as chips while adding a number indicator for the remaining amount.\n\n<ExamplesExample file=\"v-file-input/misc-complex-selection\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/file-upload.md",
    "content": "---\nemphasized: true\nmeta:\n  title: File upload\n  description: The file upload component is a drag and drop area for uploading files.\n  keywords: file uploading, file upload, file drag and drop, file drop area, file dropzone, file upload component\nrelated:\n  - /components/buttons/\n  - /components/file-inputs/\n  - /components/sheets/\nfeatures:\n  report: true\n  label: 'C: VFileUpload'\n  github: '/labs/VFileUpload/'\n---\n\n# File upload\n\n<PageFeatures />\n\n## Installation\n\nLabs components require manual import and registration with the Vuetify instance.\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport {\n  VFileUpload,\n  VFileUploadDropzone,\n  VFileUploadItem,\n  VFileUploadList,\n} from 'vuetify/labs/VFileUpload'\n\nexport default createVuetify({\n  components: {\n    VFileUpload,\n    VFileUploadDropzone,\n    VFileUploadItem,\n    VFileUploadList,\n  },\n})\n```\n\n## Usage\n\nThe `v-file-upload` component is a drag and drop area for uploading files. It can be customized with slots and has support for density and multiple styles.\n\n<ExamplesUsage name=\"v-file-upload\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-file-upload](/api/v-file-upload/) | Primary Component |\n| [v-file-upload-dropzone](/api/v-file-upload-dropzone/) | Dropzone Component |\n| [v-file-upload-item](/api/v-file-upload-item/) | Item Component |\n| [v-file-upload-list](/api/v-file-upload-list/) | List Component |\n| [v-file-input](/api/v-file-input/) | File input component |\n\n<ApiInline hide-links />\n\n## Guide\n\nThe v-file-upload component is a more visual counterpart to the [v-file-input](/components/file-inputs/) component. It provides a drag and drop area for files, and can be customized with slots.\n\n### Props\n\nUtilize various properties to customize the look and feel of the `v-file-upload` component.\n\n#### Content\n\nUse the **browse-text**, **divider-text**, **icon**, **title**, or **subtitle** props to customize the text displayed in the component.\n\n<ExamplesExample file=\"v-file-upload/prop-content\" />\n\n#### Inset file list\n\nThe **inset-file-list** prop renders the file list inside the dropzone instead of below it.\n\n<ExamplesExample file=\"v-file-upload/prop-inset-file-list\" />\n\n#### Scrim\n\nThe **scrim** property allows you to set a colored scrim when hovering over the component with files.\n\n<ExamplesExample file=\"v-file-upload/prop-scrim\" />\n\n### Slots\n\nThe `v-file-upload` component has several slots that can be used to customize the component.\n\n#### Item\n\nThe **item** slot is used to customize the appearance of the file item.\n\n<ExamplesExample file=\"v-file-upload/slot-item\" />\n\n### Misc\n\n#### List\n\nUse `v-file-upload-list` with the **default** slot to compose `v-file-upload-item` components directly. The slot provides `files` and `onClickRemove` for wiring up removal.\n\n<ExamplesExample file=\"v-file-upload/misc-list\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/floating-action-buttons.md",
    "content": "---\nmeta:\n  nav: Floating Action Buttons\n  title: FAB component\n  description: The floating action button (or FAB) component is a promoted action that is elevated above the UI or attached to an element such as a card.\n  keywords: floating action button, fab, vuetify fab component, vue fab component\nrelated:\n  - /components/buttons/\n  - /components/icons/\n  - /styles/transitions/\nfeatures:\n  report: true\n  label: 'C: VFab'\n  github: /components/VFab/\n  spec: https://m2.material.io/components/buttons-floating-action-button\n---\n\n# Floating Action Buttons\n\nThe `v-fab` component can be used as a floating action button. This provides an application with a main point of action.\n\n<PageFeatures />\n\n## Usage\n\nFloating action buttons can be attached to material to signify a promoted action in your application. The default size will be used in most cases, whereas the `small` variant can be used to maintain continuity with similar sized elements.\n\n<ExamplesUsage name=\"v-fab\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-fab](/api/v-fab/) | Primary Component |\n\n<ApiInline hide-links />\n\n<!-- ## Guide\n\nThe `v-fab` component is used to indicate a promoted action in your application. It can be used in a variety of contexts, such as a page with no content, a list of items, or a search results page.\n\n### Props\n\nThe `v-fab` component has a multitude of props that allow you to customize its appearance and behavior. -->\n\n## Examples\n\nThe following are a collection of examples that demonstrate more advanced and real world use of the `v-fab` component.\n\n### Display animation\n\nWhen displaying for the first time, a floating action button should animate onto the screen. Here we use the `v-fab-transition` with v-show. You can also use any custom transition provided by Vuetify or your own.\n\n<ExamplesExample file=\"v-fab/misc-display-animation\" />\n\n### Lateral screens\n\nWhen changing the default action of your button, it is recommended that you display a transition to signify a change. We do this by binding the `key` prop to a piece of data that can properly signal a change in action to the Vue transition system.\n\n<ExamplesExample file=\"v-fab/misc-lateral-screens\" />\n\n### Small variant\n\nFor better visual appeal, we use a small button to match our list avatars.\n\n<ExamplesExample file=\"v-fab/misc-small\" />\n\n### Speed dial\n\nThe speed-dial component has a very robust api for customizing your FAB experience exactly how you want.\n\n<ExamplesExample file=\"v-fab/misc-speed-dial\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/footers.md",
    "content": "---\nmeta:\n  nav: Footers\n  title: Footer component\n  description: The footer component provides a container for displaying additional navigation information about a site.\n  keywords: footers, vuetify footer component, vue footer component\nrelated:\n  - /components/grids\n  - /components/buttons\n  - /components/toolbars\nfeatures:\n  figma: true\n  label: 'C: VFooter'\n  report: true\n  github: /components/VFooter/\n---\n\n# Footers\n\nThe `v-footer` component is used for displaying general information that a user might want to access from any page within your site.\n\n<PageFeatures />\n\n## Usage\n\nThe `v-footer` component in its simplest form is a container.\n\n<ExamplesUsage name=\"v-footer\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-footer](/api/v-footer/) | The footer component. |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Misc\n\n#### Company Footer\n\nThe footer component as a basic company footer with links.\n\n<ExamplesExample file=\"v-footer/misc-company-footer\" />\n\n#### Indigo Footer\n\nThe footer component with Indigo background color and social media icons and button.\n\n<ExamplesExample file=\"v-footer/misc-indigo-footer\" />\n\n#### Teal Footer\n\nThe footer component with a Teal color header and columns and rows of links.\n\n<ExamplesExample file=\"v-footer/misc-teal-footer\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/forms.md",
    "content": "---\nmeta:\n  nav: Forms\n  title: Form component\n  description: The form component provides a wrapper that makes it easy to process and control validation states of input components.\n  keywords: forms, vuetify form component, vue form component, form validation\nrelated:\n  - /components/selects/\n  - /components/switches/\n  - /components/text-fields/\nfeatures:\n  label: 'C: VForm'\n  report: true\n  github: /components/VForm/\n---\n\n# Forms\n\nVuetify offers a simple built-in form validation system based on functions as rules, making it easy for developers to get set up quickly.\n\n<PageFeatures />\n\n## Usage\n\nThe `v-form` component makes it easy to add validation to form inputs. All input components have a **rules** prop that can be used to specify conditions in which the input is either *valid* or *invalid*.\n\n::: tip\n\nIf you prefer using a 3rd party validation plugin, we provide [examples](#vee-validate) further down the page for integrating both [Vee-validate](https://github.com/baianat/Vee-validate) and [vuelidate](https://github.com/vuelidate/vuelidate) validation libraries.\n\n:::\n\nWhenever the value of an input is changed, each rule receives a new value and is re-evaluated. If a rule returns `false` or a `string`, validation has failed and the `string` value is presented as an error message.\n\n<ExamplesExample file=\"v-form/usage\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-form](/api/v-form/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Rules\n\nRules allow you to apply custom validation on all form components. These are validated sequentially, and components display a *maximum* of 1 error at a time; so make sure you order your rules accordingly.\n\nThe most basic of rules is a simple function that checks if an input has a value or not; i.e. it makes it a required input.\n\n<ExamplesExample file=\"v-form/rules-required\" />\n\nHowever, you can make rules as complicated as needed, even allowing for asynchronous input validation. In the example below, the input is checked against a fake API service that takes some time to respond. Wait for the `submit` event promise to resolve and see the validation in action.\n\n<ExamplesExample file=\"v-form/rules-async\" />\n\nThe submit event is a combination of a native `SubmitEvent` with a promise, so it can be `await`ed or used with `.then()` to get the result of the validation.\n<br>\nThis also demonstrates the **validate-on** prop, which tells the `v-form` component when validation should happen. Here we set it to `'submit lazy'` so that we only call the API service when the button is clicked.\n\n## Validation state\n\nWhen rules run is controlled with the **validate-on** prop which accepts a string containing `input`, `blur`, `submit`, `invalid-input`, `eager`, or `lazy`.\n<br>\n`input`, `blur`, `submit`, and `eager` set when a validation error can first be displayed to the user, while `lazy` disables validation on mount (useful for async rules).\n<br>\nBy default, all inputs run their validation rules when mounted but do not display errors to the user. Adding `eager` will display errors immediately, or `lazy` to disable this.\n<br>\n`eager` and `lazy` can be combined with other options but not each other, and both imply `input` on their own.\n<br>\n`invalid-input` behaves the same as `blur` unless the field is invalid, then it will run on input instead until validation passes again.\n\n| `validate-on=` | `\"input\"` | `\"blur\"` | `\"submit\"` | `\"invalid-input\"` |   `\"eager\"`   | `\"lazy\"` |\n|----------------|:---------:|:--------:|:----------:|:-----------------:|:-------------:|:--------:|\n| On mount       |     ✅     |    ✅     |     ✅      |         ✅         | ✅<sup>†</sup> |    ❌     |\n| On input       |     ✅     |    ❌     |     ❌      |         ‡         |       *       |    *     |\n| On blur        |     ✅     |    ✅     |     ❌      |         ✅         |       *       |    *     |\n| On submit      |     ✅     |    ✅     |     ✅      |         ✅         |       ✅       |    ✅     |\n\n<p class=\"text-body-small\">\n* Uses the behavior of whatever it's combined with, the same as on=\"input\" by default.\n<br>\n† Displays errors immediately on mount or reset.\n<br>\n‡ Only if the validation failed previously.\n</p>\n\nThe form's current validation status is accessed using `v-model` or the submit event. It can be in one of three states:\n\n- `true`: All inputs with validation rules have been successfully validated.\n- `false`: At least one input has failed validation either by interaction or manual validation.\n- `null`: At least one input has failed validation without interaction or has not been validated yet due to `lazy` validation.\n\nThis allows you to either check for any validation failure with `!valid`, or only errors that are displayed to the user with `valid === false`{.text-no-wrap}.\n\n## Examples\n\n### Props\n\n#### Disabled\n\nYou can easily disable all input components in a `v-form` by setting the **disabled** prop.\n\n<ExamplesExample file=\"v-form/prop-disabled\" />\n\n#### Fast fail\n\nWhen the **fast-fail** prop is set, validation will short-circuit after the first invalid input is found. This can be useful if some of your rules are computationally heavy and can take a long time. In this example, notice how when the submit button is clicked, the second input does not show validation errors even though it does not satisfy the rules.\n\n<ExamplesExample file=\"v-form/prop-fast-fail\" />\n\n### Misc\n\n#### Exposed properties\n\nThe `v-form` component has a number of exposed properties that can be accessed by setting a **ref** on the component. A ref allows us to access internal methods on a component. You can find all of them on the API page, but some of the more commonly used ones are `validate()`, `reset()`, and `resetValidation()`.\n\nThe difference between `reset()` and `resetValidation()` is that the former resets both input values and validation state, while the latter only resets validation state.\n\n<ExamplesExample file=\"v-form/misc-exposed\" />\n\n#### Vee-validate\n\n**vee-validate** documentation can be found [here](https://vee-validate.logaretm.com/v4/).\n\n<ExamplesExample file=\"v-form/misc-vee-validate\" />\n\n#### Vuelidate\n\n**vuelidate** documentation can be found [here](https://vuelidate-next.netlify.app/).\n\n<ExamplesExample file=\"v-form/misc-vuelidate\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/grids.md",
    "content": "---\nmeta:\n  nav: Grids\n  title: Grid system\n  description: Vuetify supports the 12 point Material Design grid for laying out and controlling breakpoints for your application.\n  keywords: grids, vuetify grid component, layout component, flex component\nrelated:\n  - /styles/flex\n  - /features/display-and-platform/\n  - /styles/display\nfeatures:\n  github: /components/VGrid/\n  label: 'C: VGrid'\n  report: true\n  spec: https://m2.material.io/design/layout/responsive-layout-grid\n---\n\n# Grid system\n\nVuetify comes with a 12 point grid system built using flexbox.\n\nThe grid is used to create specific layouts within an application's content.  It contains 5 types of media breakpoints that are used for targeting specific screen sizes or orientations: **xs**, **sm**, **md**, **lg** and **xl**. These breakpoints are defined below in the Viewport Breakpoints table and can be modified by customizing the [Breakpoint service](/features/display-and-platform).\n\n<PageFeatures />\n\n## Usage\n\nThe Vuetify grid is heavily inspired by the [Bootstrap grid](https://getbootstrap.com/docs/4.0/layout/grid/). It is implemented by using a series of containers, rows, and columns to layout and align content. If you are new to flexbox, read the [CSS Tricks flexbox guide](https://css-tricks.com/snippets/css/a-guide-to-flexbox/#flexbox-background) for background, terminology, guidelines, and code snippets.\n\n<ExamplesExample file=\"grid/usage\" />\n\n<FeaturesBreakpointsTable />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-container](/api/v-container/) | The container component. |\n| [v-row](/api/v-row/) | Sub-component used to create rows. |\n| [v-col](/api/v-col/) | Sub-component used to create columns. |\n| [v-spacer](/api/v-spacer/) | A component often used in grid scenarios. |\n\n<ApiInline hide-links />\n\n## Sub-components\n\n### v-container\n\n`v-container` provides the ability to center and horizontally pad your site's contents. You can also use the **fluid** prop to fully extend the container across all viewport and device sizes. Maintains previous 1.x functionality in which props are passed through as classes on `v-container` allowing for the application of helper classes (such as `ma-#`/`pa-#`/`fill-height`) to easily be applied.\n\n### v-col\n\n`v-col` is a content holder that must be a direct child of `v-row`. This is the 2.x replacement for `v-flex` in 1.x.\n\n### v-row\n\n`v-row` is a wrapper component for `v-col`. It utilizes flex properties to control the layout and flow of its inner columns. It uses a standard gutter of **24px**. This can be modified using the **density** prop - use **comfortable** for reduced gutters or **compact** to remove them completely. This is the 2.x replacement for `v-layout` in 1.x.\n\n### v-spacer\n\n`v-spacer` is a basic yet versatile spacing component used to distribute remaining width in-between a parents child components. When placing a single `v-spacer` before or after the child components, the components will push to the right and left of its container. When more than one `v-spacer`'s are used between multiple components, the remaining width is evenly distributed between each spacer.\n\n## Helper Classes\n\nThe class `fill-height` applies `height: 100%` to an element. When applied to `v-container` it will also set `align-items: center`.\n\n## Caveats\n\n::: info\n  Breakpoints based props on grid components work in an `andUp` fashion. With this in mind the **xs** breakpoint is assumed and has been removed from the props context. This applies to **offset** and single breakpoint props on `v-col`\n\n- The **xs** prop does not exist on `v-col`. The equivalent to this is the **cols** prop\n:::\n\n## Examples\n\n### Props\n\n#### Size\n\nThe **size** prop on `v-row` defines the number of columns for the columns placed directly within. The example below sets it to 5 instead of 12.\n\n#### Align\n\nChange the vertical alignment of flex items and their parents using the **align** and **align-self** utility classes.\n\n<ExamplesExample file=\"grid/prop-align\" />\n\n#### Breakpoint sizing\n\nColumns will automatically take up an equal amount of space within their parent container. This can be modified using the **cols** prop. You can also utilize the **sm**, **md**, **lg**, and **xl** props to further define how the column will be sized in different viewport sizes.\n\n<ExamplesExample file=\"grid/prop-breakpoint-sizing\" />\n<ExamplesExample file=\"grid/prop-size\" />\n\n#### Justify\n\nChange the horizontal alignment of flex items using the **justify** utility classes.\n\n<ExamplesExample file=\"grid/prop-justify\" />\n\n#### No gutters\n\nYou can remove the negative margins from `v-row` and the padding from its direct `v-col` children using the **density** property.\n\n<ExamplesExample file=\"grid/prop-density-compact\" />\n\n#### Offset\n\nOffsets are useful for compensating for elements that may not be visible yet, or to control the position of content. Just as with breakpoints, you can set an offset for any available sizes. This allows you to fine tune your application layout precisely to your needs.\n\n<ExamplesExample file=\"grid/prop-offset\" />\n\n#### Offset breakpoint\n\nOffset can also be applied on a per breakpoint basis.\n\n<ExamplesExample file=\"grid/prop-offset-breakpoint\" />\n\n#### Order\n\nYou can control the ordering of grid items. As with offsets, you can set different orders for different sizes using the **order** utility classes. Design specialized screen layouts that accommodate to any application.\n\n<ExamplesExample file=\"grid/prop-order\" />\n\n#### Order first and last\n\nYou can also designate explicitly **first** or **last** using the **order-first** and **order-last** utility classes.\n\n<ExamplesExample file=\"grid/prop-order-first-and-last\" />\n\n### Misc\n\n#### Column wrapping\n\nWhen more than 12 columns are placed within a given row (that is not using the `.flex-nowrap` utility class), each group of extra columns will wrap onto a new line.\n\nIn the example below, the first and second **v-col** components are a total of 13 columns wide, which means the second **v-col** gets wrapped to a new line.\n\n<ExamplesExample file=\"grid/misc-column-wrapping\" />\n\n#### Equal width columns\n\nYou can break equal width columns into multiple lines using **v-responsive**.\n\n<ExamplesExample file=\"grid/misc-equal-width-columns\" />\n\n#### Grow and Shrink\n\nBy default, flex components will automatically fill the available space in a row or column. They will also shrink relative to the rest of the flex items in the flex container when a specific size is not designated. You can define the column width of the `v-col` by using the **cols** prop and providing a value from **1 to 12**.\n\n<ExamplesExample file=\"grid/misc-grow-and-shrink\" />\n\n#### Margin helpers\n\nUsing the [auto margin helper utilities](/styles/flex#auto-margins) you can force sibling columns away from each other.\n\n<ExamplesExample file=\"grid/misc-margin-helpers\" />\n\n#### Nested grid\n\nGrids can be nested, similar to other frameworks, in order to achieve very custom layouts.\n\n<ExamplesExample file=\"grid/misc-nested-grid\" />\n\n#### One column width\n\nWhen using the auto-layout, you can define the width of only one column and still have its siblings to automatically resize around it.\n\n<ExamplesExample file=\"grid/misc-one-column-width\" />\n\n#### Row and column breakpoints\n\nDynamically change your layout based upon resolution. Resize your screen and watch the row layout change on sm, md, and lg breakpoints.\n\n<ExamplesExample file=\"grid/misc-row-and-column-breakpoints\" />\n\n#### Size overrides\n\nThe `v-col` component can override the row's **size** using a fraction syntax like `cols=\"2/5\"`. This means the column takes 2 parts of a 5-column grid. You can also use responsive props like **md** and **lg** or **offset** with the same syntax.\n\n<ExamplesExample file=\"grid/misc-size-overrides\" />\n\n#### Spacers\n\nThe `v-spacer` component is useful when you want to fill available space or make space between two components.\n\n<ExamplesExample file=\"grid/misc-spacer\" />\n\n<!-- #### Unique layouts\n\nThe power and flexibility of the Vuetify grid system allows you to create amazing user interfaces.\n\n<ExamplesExample file=\"grid/misc-unique-layouts\" /> -->\n\n<!-- #### Variable content width\n\nAssigning breakpoint width for columns can be configured to resize based upon the nature width of their content.\n\n<ExamplesExample file=\"grid/misc-variable-content\" /> -->\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/hotkeys.md",
    "content": "---\nmeta:\n  nav: Hotkeys\n  title: Hotkey component\n  description: The hotkey component displays keyboard shortcuts in a visually consistent and platform-aware manner.\n  keywords: hotkeys, keyboard shortcuts, vuetify hotkey component, vue hotkey component\nrelated:\n  - /components/buttons/\n  - /components/icons/\n  - /components/toolbars/\nfeatures:\n  github: /components/VHotkey/\n  label: 'C: VHotkey'\n  report: true\n---\n\n# Hotkeys\n\nThe `v-hotkey` component renders keyboard shortcuts in a visually consistent and accessible way. It handles complex key combination parsing, platform-specific differences (Mac vs PC), and provides multiple display modes for different design needs.\n\n<PageFeatures />\n\n## Usage\n\nHotkeys display keyboard shortcuts with proper styling and platform awareness. The component automatically handles platform differences like showing <v-kbd>⌘</v-kbd> on Mac and <v-kbd>Ctrl</v-kbd> on PC.\n\n<ExamplesUsage name=\"v-hotkey\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-hotkey](/api/v-hotkey/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Guide\n\nThe `v-hotkey` component is designed to display keyboard shortcuts consistently across your application. It's commonly used in command palettes, help documentation, tooltips, and anywhere you need to show keyboard shortcuts to users.\n\n::: info\nThe `v-hotkey` component serves solely as a visual tool for displaying keyboard shortcuts. It does not generate or manage keyboard shortcuts itself. To implement functional keyboard shortcuts, utilize the [useHotkey](/features/hotkey/) composable.\n:::\n\n### Props\n\nThe component provides several props to customize how keyboard shortcuts are displayed and parsed. This component is designed to work seamlessly across different platforms, automatically adjusting key representations based on the user's operating system.\n\n#### Keys\n\nThe **keys** prop accepts a string representing keyboard shortcuts in various formats. See [Hotkeys](/features/hotkey/#key-combination-syntax) for detailed parsing rules.\n\n<ExamplesExample file=\"v-hotkey/prop-keys\" />\n\n#### Display modes\n\nThe **display-mode** prop controls how keys are visually represented. Choose from **icon** (default), **symbol**, or **text** modes:\n\n<ExamplesExample file=\"v-hotkey/prop-display-mode\" />\n\n#### Platform awareness\n\nThe component automatically detects the user's platform and adjusts key representations accordingly:\n\n<ExamplesExample file=\"v-hotkey/prop-platform-aware\" />\n\n#### Custom key mapping\n\n::: info\nIt is recommended to set the **key-map** prop at the application level via global component defaults rather than per-instance for consistency.\n:::\n\nUse the **key-map** prop to customize how specific keys are displayed. You can import and modify the exported `hotkeyMap` to create custom configurations:\n\n```typescript\nimport { hotkeyMap } from 'vuetify/labs/VHotkey'\n\nconst customKeyMap = {\n  ...hotkeyMap,\n  ctrl: {\n    default: { text: 'Control', icon: '$ctrl' },\n    mac: { symbol: '⌃', icon: '$ctrl', text: 'Control' }\n  }\n}\n```\n\n<ExamplesExample file=\"v-hotkey/prop-key-map\" />\n\n#### Inline display\n\nThe **inline** prop optimizes the component for integration within text content, documentation, and flowing paragraphs. This mode applies specialized styling for seamless text flow and improved readability:\n\n<ExamplesExample file=\"v-hotkey/prop-inline\" />\n\n**Layout considerations:** When using multiple inline hotkeys within the same paragraph, consider increasing the `line-height` of the containing text to provide adequate vertical spacing. This prevents visual overlap when hotkey components wrap to new lines, ensuring clean separation and improved readability.\n\n## Accessibility\n\nThe `v-hotkey` component is designed with accessibility in mind. It uses semantic HTML elements and ARIA attributes to ensure that screen readers can interpret the displayed keyboard shortcuts correctly.\n\n### ARIA attributes\n\nThe component uses the `aria-label` attribute to provide a clear description of the keyboard shortcut. This is automatically generated based on the current keys.\n\n```html\n<v-hotkey keys=\"ctrl+s\" />\n```\n\nwill generate the following HTML:\n\n```html\n<div class=\"v-hotkey\" role=\"img\" aria-label=\"Keyboard shortcut: Ctrl plus S\">\n  <span class=\"v-hotkey__combination\">\n    <div class=\"v-kbd v-hotkey__key\" aria-hidden=\"true\">Ctrl</div>\n    <span class=\"v-hotkey__divider\" aria-hidden=\"true\">+</span>\n    <div class=\"v-kbd v-hotkey__key\" aria-hidden=\"true\">S</div>\n  </span>\n</div>\n```\n\n::: info\nThe HTML structure varies by variant. Standard variants use individual `VKbd` components, while the `contained` variant uses nested `<kbd>` elements within a single wrapper.\n:::\n\nKey accessibility features:\n\n- **Screen reader support**: Uses `role=\"img\"` with descriptive `aria-label`\n- **Visual elements hidden**: Individual keys and separators use `aria-hidden=\"true\"`\n- **Sequence notation**: Dash separators display as \"then\" for screen readers (e.g., `ctrl+k-p` becomes \"Ctrl plus K then P\")\n- **Tooltips**: Icon and symbol modes include `title` attributes for enhanced usability\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/hover.md",
    "content": "---\nmeta:\n  nav: Hover\n  title: Hover component\n  description: The hover component makes it easy respond when the user hover events by wrapping selectable content.\n  keywords: hover, vuetify hover component, vue hover component\nrelated:\n  - /components/cards/\n  - /components/images/\n  - /components/tooltips/\nfeatures:\n  github: /components/VHover/\n  label: 'C: VHover'\n  report: true\n---\n\n# Hover\n\nThe `v-hover` component provides a simple interface for handling hover states for any component.\n\n<PageFeatures />\n\n## Usage\n\n `v-hover` is a renderless component that uses the default slot to provide scoped access to its internal model; as well as mouse event listeners to modify it. To explicitly control the internal state, use the **model-value** property.\n\n<ExamplesUsage name=\"v-hover\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-hover](/api/v-hover/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n#### Disabled\n\nThe **disabled** prop disables the hover functionality.\n\n<ExamplesExample file=\"v-hover/prop-disabled\" />\n\n#### Open and close delay\n\nDelay `v-hover` events by using **open-delay** and **close-delay** props in combination or separately.\n\n<ExamplesExample file=\"v-hover/prop-open-and-close-delay\" />\n\n### Misc\n\n#### Hover list\n\n`v-hover` can be used in combination with `v-for` to make a single item stand out when the user interacts with the list.\n\n<ExamplesExample file=\"v-hover/misc-hover-list\" />\n\n#### Transition\n\nCreate highly customized components that respond to user interaction.\n\n<ExamplesExample file=\"v-hover/misc-transition\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/icon-buttons.md",
    "content": "---\nmeta:\n  nav: Icon buttons\n  title: Icon button component\n  description: The icon component is compatible with multiple common icon fonts such as Material Design Icons, Font Awesome and more.\n  keywords: icons, vuetify icon component, vue icon component\nrelated:\n  - /features/icon-fonts/\n  - /components/buttons/\n  - /components/floating-action-buttons/\nfeatures:\n  github: /labs/VIconBtn/\n  label: 'C: VIconBtn'\n  report: true\n  spec: https://m3.material.io/components/icon-buttons/\n---\n\n# Icon Buttons\n\nThe `v-icon-btn` component is a lightweight button component for iconography.\n\n<PageFeatures />\n\n## Installation\n\nLabs components require manual import and registration with the Vuetify instance.\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { VIconBtn } from 'vuetify/labs/VIconBtn'\n\nexport default createVuetify({\n  components: {\n    VIconBtn,\n  },\n})\n```\n\n## Usage\n\n<ExamplesUsage name=\"v-icon-btn\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-icon-btn](/api/v-icon-btn/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Anatomy\n\nThe recommended placement of elements inside of `v-icon-btn` is:\n\n* Place icon or text in the center\n\n| Element / Area | Description |\n| - | - |\n| 1. Container | The container element that holds the icon and text |\n\n## Guide\n\nThe `v-icon-btn` component is a lightweight reusable button that displays icons and text in various states.\n\n### Using with vue-router\n\nThe `v-icon-btn` component does not have built in support for vue-router. The following example demonstrates how to use the `v-icon-btn` component with the `router-link` component:\n\n```html\n<template>\n  <RouterLink v-slot=\"{ navigate, isActive }\" to=\"/page1\" custom>\n    <v-icon-btn\n      :active=\"isActive\"\n      color=\"primary\"\n      icon=\"$vuetify\"\n      tag=\"a\"\n      @click=\"navigate\"\n    />\n  </RouterLink>\n</template>\n```\n\n### Props\n\nThe `v-icon-btn` supports various stylistic props to customize the appearance of the button and its icon.\n\n#### Active\n\nThe **active** prop is used to control the active state of the button and should be used in conjunction with the **active-color** prop.\n\n<ExamplesExample file=\"v-icon-btn/prop-active\" />\n\n#### Opacity\n\nThe **opacity** prop is used to control the opacity of the internal icon.\n\n<ExamplesExample file=\"v-icon-btn/prop-opacity\" />\n\n#### Rotate\n\nThe **rotate** prop is used to control the rotation of the internal icon. This is useful when creating dropdowns or other components that need to toggle visibility.\n\n<ExamplesExample file=\"v-icon-btn/prop-rotate\" />\n\n### Examples\n\nThe following are a collection of examples that demonstrate more advanced and real world use of the `v-icon-btn` component.\n\n#### Dialog\n\nThe `v-icon-btn` component is perfect for closing dialogs or other components.\n\n<ExamplesExample file=\"v-icon-btn/misc-dialog\" />\n\n#### Video controls\n\nThe following example demonstrates how flexible the `v-icon-btn` component is by replicating the Google Meet video controls.\n\n<ExamplesExample file=\"v-icon-btn/misc-video-controls\" />\n\n#### Markdown editor\n\nThe following example is a simple markdown editor that demonstrates how to use the `v-icon-btn` component to create a toolbar.\n\n<ExamplesExample file=\"v-icon-btn/misc-markdown-editor\" />\n\n#### Datatable actions\n\nThe `v-icon-btn` component is perfect for datatable actions.\n\n<ExamplesExample file=\"v-icon-btn/misc-table-actions\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/icons.md",
    "content": "---\nmeta:\n  nav: Icons\n  title: Icon component\n  description: The icon component is compatible with multiple common icon fonts such as Material Design Icons, Font Awesome and more.\n  keywords: icons, vuetify icon component, vue icon component\nrelated:\n  - /features/icon-fonts/\n  - /components/buttons/\n  - /components/cards/\nassets:\n  - https://use.fontawesome.com/releases/v5.0.13/css/all.css\n  - https://fonts.googleapis.com/icon?family=Material+Icons\nfeatures:\n  figma: true\n  github: /components/VIcon/\n  label: 'C: VIcon'\n  report: true\n  spec: https://m2.material.io/design/iconography/system-icons.html\n---\n\n# Icons\n\nThe `v-icon` component provides a large set of glyphs to provide context to various aspects of your application. For a list of all available icons, visit the official [Material Design Icons](https://pictogrammers.com/library/mdi/) page. To use any of these icons simply use the `mdi-` prefix followed by the icon name.\n\n<PageFeatures />\n\n## Usage\n\nIcons come in two themes (light and dark), and five different sizes (x-small, small, medium (default), large, and x-large).\n\n<ExamplesUsage name=\"v-icon\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-icon](/api/v-icon/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n#### Color\n\nUsing color helpers you can change the color of an icon from the standard dark and light themes.\n\n<ExamplesExample file=\"v-icon/prop-color\" />\n\n<!-- ### Events\n\n#### Click\n\nBinding any click event to `v-icon` will automatically change the cursor to a pointer.\n\n<ExamplesExample file=\"v-icon/event-click\" /> -->\n\n### Misc\n\n#### Buttons\n\nIcons can be used inside of buttons to add emphasis to the action.\n\n<ExamplesExample file=\"v-icon/misc-buttons\" />\n\n#### Font Awesome\n\n[Font Awesome](https://fontawesome.com/icons/) is also supported. Simply use the `fa-` prefixed icon name. Please note that you still need to include the Font Awesome icons in your project. For more information on how to install it, please navigate to the [installation page](/features/icon-fonts#install-font-awesome-5-icons)\n\n::: info\n  Note that this example is using an icon set prefix, because the default icon set in the documentation is `mdi`. You can read more about using multiple icon sets [here](/features/icon-fonts/#multiple-icon-sets)\n:::\n\n<ExamplesExample file=\"v-icon/misc-font-awesome\" />\n\n#### Material Design\n\n[Material Design](https://fonts.google.com/icons) is also supported. For more information on how to install it please [navigate here](/features/icon-fonts#install-material-icons)\n\n::: info\n  Note that this example is using an icon set prefix, because the default icon set in the documentation is `mdi`. You can read more about using multiple icon sets [here](/features/icon-fonts/#multiple-icon-sets)\n:::\n\n<ExamplesExample file=\"v-icon/misc-md\" />\n\n#### MDI SVG\n\nYou can manually import only the icons you use when using the [@mdi/js](https://www.npmjs.com/package/@mdi/js) package. Read more about using them [here](/features/icon-fonts#material-design-icons-js-svg).\n\n::: info\n  Note that this example is using an icon set prefix, because the default icon set in the documentation is `mdi`. You can read more about using multiple icon sets [here](/features/icon-fonts/#multiple-icon-sets)\n:::\n\n<ExamplesExample file=\"v-icon/misc-mdi-svg\" />\n\n## Accessibility\n\nIcons can convey all sorts of meaningful information, so it’s important that they reach the largest amount of people possible. There are two use cases you’ll want to consider:\n\n- **Decorative Icons** are only being used for visual or branding reinforcement. If they were removed from the page, users would still understand and be able to use your page.\n\n- **Semantic Icons** are ones that you’re using to convey meaning, rather than just pure decoration. This includes icons without text next to them used as interactive controls — buttons, form elements, toggles, etc.\n\n::: error\n  WAI-ARIA Authoring Practices 1.1 notes that `aria-hidden=\"false\"` currently [behaves inconsistently across browsers](https://www.w3.org/TR/wai-aria-1.1/#aria-hidden).\n:::\n\n::: info\n  WIP: Our team will change to the component to not render `aria-hidden=\"false\"` when you pass a label  prop.\n:::\n\n### Decorative Font Icons\n\nIf your icons are purely decorative, you’ll need to manually add an attribute to each of your icons so they’re accessible.`aria-hidden`(automatically by vuetify)\n\n### Semantic Font Icons\n\nIf your icons have semantic meaning, you need to provide a text alternative inside a (or similar) element. Also include appropriate CSS to visually hide the element while keeping it accessible to assistive technologies.\n\n```html\n<v-icon aria-hidden=\"false\">\n  mdi-account\n</v-icon>\n```\n\n### Decorative SVG Icons\n\nIf your icons are purely decorative, you’ll need to manually add an attribute to each of your icons so they’re accessible.`aria-hidden`(automatically by vuetify)\n\n### Semantic SVG Icons\n\nApply accessibility attributes to the [v-icon](/components/icons/) component, such as `role=\"img\"`, to give it a semantic meaning.\n\n```html { resource=\"Component.vue\" }\n<v-icon aria-label=\"My Account\" role=\"img\" aria-hidden=\"false\">\n  mdiAccount\n</v-icon>\n\n<script setup>\nimport { mdiAccount } from \"@mdi/js\";\n\nconst icons = { mdiAccount }\n</script>\n```\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/images.md",
    "content": "---\nmeta:\n  nav: Images\n  title: Image component\n  description: The image component provides a flexible interface for displaying different types of images.\n  keywords: images, vuetify image component, vue image component\nrelated:\n  - /components/grids\n  - /components/aspect-ratios\n  - /components/parallax\nfeatures:\n  github: /components/VImg/\n  label: 'C: VImg'\n  report: true\n---\n\n# Images\n\nThe `v-img` component is packed with features to support rich media. Combined with the [vuetify-loader](https://github.com/vuetifyjs/vuetify-loader), you can add dynamic progressive images to provide a better user experience.\n\n<PageFeatures />\n\n## Usage\n\n`v-img` component is used to display a responsive image with lazy-load and placeholder.\n\n<ExamplesUsage name=\"v-img\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-img](/api/v-img/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Caveats\n\n::: warning\n  The **lazy-src** property has no effect unless either **height** or **aspect-ratio** are provided. This is because\n  the image container needs a non-zero height in order for the temporary image to be shown.\n:::\n\n## Examples\n\n### Props\n\n#### Cover\n\nIf the provided aspect ratio doesn't match that of the actual image, the default behavior is to fill as much space as possible without cropping. To fill the entire available space use the `cover` prop.\n\n<ExamplesExample file=\"v-img/prop-cover\" />\n\n#### Rounded\n\nUse the **rounded** prop to control the border radius of the image container.\n\n<ExamplesExample file=\"v-img/prop-rounded\" />\n\n#### Height\n\n`v-img` will automatically grow to the size of its `src`, preserving the correct aspect ratio. You can limit this with the `height` and `max-height` props.\n\n<ExamplesExample file=\"v-img/prop-max-height\" />\n\n#### Image class\n\nThe `image-class` prop allows you to apply CSS classes directly to the inner `<img>` element. This is useful for adding hover effects or styles that should target the image itself rather than the container.\n\n<ExamplesExample file=\"v-img/prop-image-class\" />\n\n#### Gradient\n\nThe `gradient` prop can be used to apply a simple gradient overlay to the image. More complex gradients should be written as a class on the content slot instead.\n\n<ExamplesExample file=\"v-img/prop-gradient\" />\n\n### Slots\n\n#### Placeholder\n\n`v-img` has a special `placeholder` slot for placeholder to display while image's loading. Note: the example below has bad src which won't load for you to see placeholder.\n\n<ExamplesExample file=\"v-img/slot-placeholder\" />\n\n#### Error\n\n`v-img` has an `error` slot that can be used to display alternative content if an error occurs while loading your source image. A common use for this slot is to load a fallback image if your original image is not available.\n\n<ExamplesExample file=\"v-img/slot-error\" />\n\n### Misc\n\n#### Future image formats\n\nBy default `v-img` will render a basic `<img>` element. If you want to use `.webp` images with a fallback for older browsers, you can pass a list of `<source>` elements to the `sources` slot:\n\n```html\n<v-img src=\"image.jpeg\">\n  <template #sources>\n    <source srcset=\"image.webp\">\n  </template>\n</v-img>\n```\n\nThis will behave similarly to:\n\n```html\n<picture>\n  <source srcset=\"image.webp\">\n  <img src=\"image.jpeg\">\n</picture>\n```\n\n`srcset` and `media` attributes can also be used for art direction or alternate sizes, see [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture) for more.\n\n#### Grid\n\nYou can use `v-img` to make, for example, a picture gallery.\n\n<ExamplesExample file=\"v-img/misc-grid\" />\n\n#### Complex Grid Layout\n\nBuild a more complex picture gallery layout using `flex-box` classes.\n\n<ExamplesExample file=\"v-img/complex-grid\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/infinite-scroller.md",
    "content": "---\nmeta:\n  nav: Infinite scrollers\n  title: Infinite scroller component\n  description: The Infinite scroll component is a container that loads more items when scrolling. It is useful when you need to display an unknown but large number of items.\n  keywords: infinite scroll, vuetify infinite scroll component, vue infinite scroll component, v-infinite-scroll component\nrelated:\n  - /components/lists/\n  - /components/data-tables/basics/\n  - /components/data-iterators/\nfeatures:\n  github: /components/VInfiniteScroll/\n  label: 'C: VInfiniteScroll'\n  report: true\n---\n\n# Infinite scrollers\n\nThe `v-infinite-scroll` component displays a potentially infinite list, by loading more items of the list when scrolling. It supports either vertical or horizontal scrolling.\n\n<PageFeatures />\n\n## Usage\n\nWhen scrolling towards the bottom, new items will be rendered either automatically, or manually with the click of a button.\n\n<ExamplesUsage name=\"v-infinite-scroll\" />\n\nA **load** event will be emitted when the component needs to load more content. The argument passed is an object with two properties.\n\n- `side` tells you on which side new content should be added, either at the `'start'` or `'end'`. The return value of the function is a string that describes if the new content was loaded successfully or not.\n- `done` is a callback function that should be called when the loading of new content is done. It takes a single parameter `status` that describes if the load was successful or not. See the table below for the possible values.\n\n|Status|Description|\n|------|-----------|\n|`'ok'`|Content was added successfully|\n|`'error'`|Something went wrong when adding content. This will display the `error` slot|\n|`'empty'`|There is no more content to fetch. This will display the `empty` slot|\n|`'loading'`|Content is currently loading. This will display a message that the content is loading. This status is only set internally by the component and should not be used with the **done** function|\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-infinite-scroll](/api/v-infinite-scroll/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Anatomy\n\nThe `v-infinite-scroll` works with any content in its default slot.\n\n![Infinite scroll Anatomy](https://cdn.vuetifyjs.com/docs/images/components/v-infinite-scroll/v-infinite-scroll-anatomy.png)\n\n| Element / Area | Description                                                              |\n|----------------|-----------------------------------------|\n| 1. Container   | The infinite scroller content container |\n| 2. Loader      | The loader content area                 |\n\n## Guide\n\nThe `v-infinite-scroll` component is a container that allows you to react to a user reaching the end of the content area. It is useful when you need to display an unknown but large number of items, and you don't want to load them all at once.\n\n### Props\n\nThe `v-infinite-scroll` component has several props that can be used to customize its behavior.\n\n#### Mode\n\nThe default behavior of the component is to try to load more content automatically when the scrollbar gets close to the end. However, a manual mode is also supported, where the user needs to do some interaction to load the content. By default this is a button, but it can be customized with a [slot](#load-more)\n\n<ExamplesExample file=\"v-infinite-scroll/prop-mode\" />\n\n#### Direction\n\nThe `v-infinite-scroll` component can be used with either vertical or horizontal scrolling.\n\n<ExamplesExample file=\"v-infinite-scroll/prop-direction\" />\n\n#### Side\n\nBy default, the `v-infinite-scroll` component assumes that new content will appear at the end of existing content. But it also supports content being added to the start and appearing both at the beginning and the end.\n\nWhen using the **start** side for content, the scrollbar will start at the bottom of the content.\n\n<ExamplesExample file=\"v-infinite-scroll/prop-side-start\" />\n\nWhen using **both** sides for content, the scrollbar will start in the middle of the content.\n\n<ExamplesExample file=\"v-infinite-scroll/prop-side-both\" />\n\n#### Color\n\nThe default load more button and loading spinner can be colored with the **color** prop.\n\n<ExamplesExample file=\"v-infinite-scroll/prop-color\" />\n\n### Slots\n\nThe `v-infinite-scroll` component exposes several slots that allow you to further customize its behaviour.\n\n![Infinite scroll Slots](https://cdn.vuetifyjs.com/docs/images/components/v-infinite-scroll/v-infinite-scroll-slots.png)\n\n| Element / Area | Description |\n| - | - |\n| 1. Container | The default slot |\n| 2. Load-more | The slot shown when the mode is set to `manual` and the status is not `loading` |\n| 3. Loading | The slot is shown when the mode is set to `manual` and status is `loading` |\n| 4. Empty | The slot shown when the status is `empty` |\n| 5. Error | The slot is shown when the status is `error` |\n\n#### Loading\n\nYou can customize the loading message with the **loading** slot.\n\n<ExamplesExample file=\"v-infinite-scroll/slot-loading\" />\n\n#### Load more\n\nWhen using **manual** mode you can customize the action required to load more content with the **load-more** slot.\n\n<ExamplesExample file=\"v-infinite-scroll/slot-load-more\" />\n\n#### Empty\n\nYou can customize the empty message with the **empty** slot.\n\n<ExamplesExample file=\"v-infinite-scroll/slot-empty\" />\n\n#### Error\n\nThe **error** slot is shown if the status `'error'` is returned from the `done` callback.\n\n<ExamplesExample file=\"v-infinite-scroll/slot-error\" />\n\n### Misc\n\n#### Exposed properties\n\nThe `v-infinite-scroll` component exposes the `reset()` method, allowing to programatically reset the status to the default after reaching the `empty` state. This makes it possible for load to be called again.\nAn optional 'side' parameter can also be provided to the method for cases where only one of the two sides needs to be reset.\n\n<ExamplesExample file=\"v-infinite-scroll/misc-reset\" />\n\n### Examples\n\nThe following is a collection of examples that demonstrate more advanced and real-world use of the `v-infinite-scroll` component.\n\n#### Virtualized infinite scroller\n\nIf the items in your infinite list are of a uniform size, you can quite easily virtualize the list to only render a small number of items regardless of how far you scroll in either direction.\n\n<ExamplesExample file=\"v-infinite-scroll/misc-virtual\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/inputs.md",
    "content": "---\nmeta:\n  nav: Custom inputs\n  title: Input component\n  description: The input component is the baseline functionality for all of Vuetify's form components and provides a baseline for custom implementations.\n  keywords: inputs, vuetify input component, vue input component\nrelated:\n  - /components/forms/\n  - /components/selects/\n  - /components/text-fields/\nfeatures:\n  label: 'C: VInput'\n  report: true\n  github: /components/VInput/\n---\n\n# Inputs\n\nThe `v-input` component gives you a baseline to create your own custom inputs. It consists of a prepend/append slot, messages, and a default slot.\n\n<PageFeatures />\n\n## Usage\n\n`v-input` has 4 main areas. The prepended slot, the appended slot, the default slot, and messages. These make up the core logic shared between all form components.\n\n<ExamplesExample file=\"v-input/usage\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-input](/api/v-input/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Caveats\n\n::: warning\n\nThe `v-input` component is used as a wrapper for all of the Vuetify form controls. It does **NOT** inherit attributes as they are expected to be passed down to inner inputs.\n\n:::\n\n## Examples\n\n### Props\n\n#### Error\n\nAs any validatable Vuetify component, `v-input` can be set to error state using **error** prop, messages can be added using **error-messages** prop. You can determine error messages count to show using **error-count** property.\n\n#### Error count\n\nYou can add multiple errors to `v-input` using **error-count** property.\n\n<ExamplesExample file=\"v-input/prop-error-count\" />\n\n<ExamplesExample file=\"v-input/prop-error\" />\n\n#### Hide details\n\nWhen the **hide-details** prop is set to `auto` messages will be rendered only if there's a message (hint, error message etc) to display.\n\n<ExamplesExample file=\"v-input/prop-hide-details\" />\n\n#### Hint\n\n`v-input` can have **hint** which can tell user how to use the input (when focused). **persistent-hint** prop makes the hint visible always if no `error-messages` are displayed.\n\n<ExamplesExample file=\"v-input/prop-hint\" />\n\n#### Loading\n\n`v-input` has **loading** state which can be used, e.g. for data loading indication. Note: `v-text-field` is used just for example.\n\n<ExamplesExample file=\"v-input/prop-loading\" />\n\n#### Rules\n\nYou can add custom validation rules to `v-input`, add them as functions returning `true`/error message. Note: `v-text-field` is used just for example.\n\n<ExamplesExample file=\"v-input/prop-rules\" />\n\n### Events\n\n#### Slot clicks\n\n`v-input` can have `click:append` and `click:prepend` events for its slots. Note: `v-text-field` is used just for example.\n\n<ExamplesExample file=\"v-input/event-slot-clicks\" />\n\n### Slots\n\n#### Append and prepend\n\n`v-input` has `append` and `prepend` slots. You can place custom icons in them.\n\n<ExamplesExample file=\"v-input/slot-append-and-prepend\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/item-groups.md",
    "content": "---\nmeta:\n  nav: Item groups\n  title: Item group component\n  description: The item group components provides the ability to create a group of selectable items out of any component.\n  keywords: item groups, vuetify item group component, vue item group component\nrelated:\n  - /components/button-groups\n  - /components/carousels\n  - /components/tabs\nfeatures:\n  github: /components/VItemGroup/\n  label: 'C: VItemGroup'\n  report: true\n---\n\n# Item groups\n\nThe `v-item-group` provides the ability to create a group of selectable items out of any component. This is the baseline functionality for components such as `v-tabs` and `v-carousel`.\n\n<PageFeatures />\n\n## Usage\n\nThe core usage of the `v-item-group` is to create groups of anything that should be controlled by a **model**.\n\n<!-- <ExamplesExample file=\"v-item-group/usage\" /> -->\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-item-group](/api/v-item-group/) | The item group component. |\n| [v-item](/api/v-item/) | Sub-component used for modifying the `v-item-group` state |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n#### Selected class\n\nThe **selected-class** prop allows you to designate a CSS class applied to _selected_ items.\n\n<ExamplesExample file=\"v-item-group/prop-selected-class\" />\n\n#### Mandatory\n\n**mandatory** item groups must have at least 1 item selected.\n\n<ExamplesExample file=\"v-item-group/prop-mandatory\" />\n\n#### Multiple\n\nItem groups can have **multiple** items selected.\n\n<ExamplesExample file=\"v-item-group/prop-multiple\" />\n\n### Misc\n\n#### Selection\n\nIcons can be used as toggle buttons when they allow selection, or deselection, of a single choice, such as marking an item as a favorite.\n\n<ExamplesExample file=\"v-item-group/misc-selection\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/lazy.md",
    "content": "---\nmeta:\n  nav: Lazy\n  title: Lazy component\n  description: The lazy component allows you to dynamically render content based upon the user's viewport.\n  keywords: lazy loading\nrelated:\n  - /components/badges/\n  - /components/icons/\n  - /components/lists/\nfeatures:\n  github: /components/VLazy/\n  label: 'C: VLazy'\n  report: true\n---\n\n# Lazy\n\nThe `v-lazy` component is used to dynamically load components based upon an elements visibility.\n\n<PageFeatures />\n\n## Usage\n\nThe `v-lazy` component by default will not render its contents until it has been intersected. Scroll down and watch the element render as you go past it.\n\n<ExamplesUsage name=\"v-lazy\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-lazy](/api/v-lazy/) | Primary Component |\n\n<ApiInline hide-links />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/lists.md",
    "content": "---\nmeta:\n  nav: Lists\n  title: List component\n  description: The list component is a continuous group of text, images and icons that may contain primary or supplemental actions.\n  keywords: lists, vuetify list component, vue list component\nrelated:\n  - /components/item-groups/\n  - /components/avatars/\n  - /components/sheets/\nfeatures:\n  figma: true\n  github: /components/VList/\n  label: 'C: VList'\n  report: true\n  spec: https://m2.material.io/components/lists\n---\n\n# Lists\n\nThe `v-list` component is used to display information. It can contain an avatar, content, actions, subheaders and much more. Lists present content in a way that makes it easy to identify a specific item in a collection. They provide a consistent styling for organizing groups of text and images.\n\n<PageFeatures />\n\n## Usage\n\nLists come in three main variations. **single-line** (default), **two-line** and **three-line**. The line declaration specifies the minimum height of the item and can also be controlled from `v-list` with the same prop.\n\n<ExamplesUsage name=\"v-list\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-list](/api/v-list/) | Primary Component |\n| [v-list-group](/api/v-list-group/) | Sub-component used to display or hide groups of items |\n| [v-list-subheader](/api/v-list-subheader/) | Sub-component used to separate groups of items |\n| [v-list-item](/api/v-list-item/) | Sub-component used to display a single item or modify the `v-list` state |\n| [v-list-item-title](/api/v-list-item-title/) | Sub-component used to display the title of a list item. Wraps the `#title` slot |\n| [v-list-item-subtitle](/api/v-list-item-subtitle/) | Sub-component used to display the subtitle of a list item. Wraps the `#subtitle` slot |\n| [v-list-item-action](/api/v-list-item-action/) | Sub-component used to display [v-checkbox](/components/checkboxes/) or [v-switch](/components/switches/) |\n| [v-list-img](/api/v-list-img/) | Sub-component that is used to wrap a the [v-img](/components/images/) component |\n| [v-list-item-media](/api/v-list-item-media/) | Sub-component that is used to wrap a the [v-img](/components/images/) component |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n#### Items\n\nLists can either be created by markup using the many sub-components that are available, or by using the **items** prop.\n\n<ExamplesExample file=\"v-list/prop-items\" />\n\nTo customize which properties will be used for the title and value of each item, use the **item-title** and **item-value** props.\n\n<ExamplesExample file=\"v-list/prop-items-custom\" />\n\nIf you need to render subheaders or dividers, add an item with a **type** property. Which property to use can be customized using the **item-type** prop.\n\n<ExamplesExample file=\"v-list/prop-items-type\" />\n\nTo customize individual items, you can use the **item-props** prop. It defaults to looking for a **props** property on the items. The value should be an object, and if found it will be spread on the **v-list-item** component.\n\nIf **item-props** is set to **true** then the whole item will be spread.\n\n<ExamplesExample file=\"v-list/prop-items-prop\" />\n\n#### Density\n\n`v-list` supports the **density** property.\n\n<ExamplesExample file=\"v-list/prop-density\" />\n\n<PromotedPromoted slug=\"vuetify-lux-admin-pro\" />\n\n#### Disabled\n\nYou cannot interact with disabled `v-list`.\n\n<ExamplesExample file=\"v-list/prop-disabled\" />\n\n#### Variant\n\n`v-list` supports the **variant** prop.\n\n<ExamplesExample file=\"v-list/prop-variant\" />\n\n#### Nav\n\nLists can receive an alternative **nav** styling that reduces the width `v-list-item` takes up as well as adding a border radius.\n\n<ExamplesExample file=\"v-list/prop-nav\" />\n\n#### Rounded\n\nYou can make `v-list` items rounded.\n\n<ExamplesExample file=\"v-list/prop-rounded\" />\n\n#### Shaped\n\nShaped lists have rounded borders on one side of the `v-list-item`.\n\n<ExamplesExample file=\"v-list/prop-shaped\" />\n\n#### Sub group\n\nUsing the `v-list-group` component you can create sub-groups of items.\n\n<ExamplesExample file=\"v-list/prop-sub-group\" />\n\n#### Three line\n\nFor three line lists, the subtitle will clamp vertically at 2 lines and then ellipsis. This feature uses [line-clamp](https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-line-clamp) and is not supported in all browsers.\n\n<ExamplesExample file=\"v-list/prop-three-line\" />\n\n#### Two lines and subheader\n\nLists can contain subheaders, dividers, and can contain 1 or more lines. The subtitle will overflow with ellipsis if it extends past one line.\n\n<ExamplesExample file=\"v-list/prop-two-line-and-subheader\" />\n\n### Misc\n\n#### Action and item groups\n\nA **three-line** list with actions. Utilizing **select-strategy**, easily connect actions to your tiles.\n\n<ExamplesExample file=\"v-list/misc-actions\" />\n\n#### Action with text\n\nA list can contain additional meta information within an action.\n\n<ExamplesExample file=\"v-list/misc-action-stack\" />\n\n#### Card list\n\nA list can be combined with a card.\n\n<ExamplesExample file=\"v-list/misc-card-list\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/locale-providers.md",
    "content": "---\nmeta:\n  nav: Locale providers\n  title: Locale provider component\n  description: The locale provider allows you to modify the application's current language scoped within a template\n  keywords: locale provider, vuetify locale provider component, vue locale provider component\nrelated:\n  - /features/internationalization/\n  - /features/global-configuration/\n  - /getting-started/browser-support/\nfeatures:\n  github: /components/VLocaleProvider/\n  label: 'C: VLocaleProvider'\n  report: true\n---\n\n# Locale providers\n\nThe locale provider allows you to provide specific default prop values to components in a section of your application\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-locale-provider](/api/v-locale-provider/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Locale\n\nThe `v-locale-provider` expects a prop **locale** which looks the same as the **locale** object that you can pass to `createVuetify` when creating your application.\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/mask-inputs.md",
    "content": "---\nmeta:\n  nav: Mask inputs\n  title: Mask input component\n  description: The mask input component is a input component for masking input values.\n  keywords: mask, vuetify mask input, vue mask input\nfeatures:\n  label: 'C: VMaskInput'\n  report: true\n  github: /labs/VMaskInput/\n---\n\n# Mask Inputs\n\nThe `v-mask-input` component allows you to enforce a format on user input according to specific patterns. This is particularly useful for fields like phone numbers, credit cards, dates, and other formatted data.\n\n<PageFeatures />\n\n## Installation\n\nLabs components require manual import and registration with the Vuetify instance.\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { VMaskInput } from 'vuetify/labs/VMaskInput'\n\nexport default createVuetify({\n  components: {\n    VMaskInput,\n  },\n})\n```\n\n## Usage\n\nAt its core, the `v-mask-input` is a wrapper around [v-text-field](/components/text-fields).\n\n<ExamplesUsage name=\"v-mask-input\" />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-mask-input](/api/v-mask-input/) | Primary Component |\n| [useMask](/api/use-mask/) | Masking composable |\n\n<ApiInline hide-links />\n\n### Guide\n\nMasks are created using a combination of special tokens that define the allowed characters and their formatting. Each token represents a specific type of character input.\n\n### Available Tokens\n\n| Token | Description |\n|-------|-------------|\n| # | Any digit |\n| A | Any capital letter |\n| a | Any small letter |\n| N | Any capital alphanumeric character |\n| n | Any small alphanumeric character |\n| X | Any special symbol (-!$%^&*()_+ &#124;~=`{}[]:\";'<>?,./\\) or space |\n\n### Built-in Masks\n\nVuetify includes several pre-configured masks for common use cases:\n\n| Name | Pattern | Example |\n|------------|------------|---------|\n| credit-card | #### - #### - #### - #### | 1234 - 5678 - 9012 - 3456 |\n| date | ##/##/#### | 12/31/2024 |\n| date-time | ##/##/#### ##:## | 12/31/2024 23:59 |\n| iso-date | ####-##-## | 2024-12-31 |\n| iso-date-time | ####-##-## ##:## | 2024-12-31 23:59 |\n| phone | (###) ### - #### | (123) 456 - 7890 |\n| social | ###-##-#### | 123-45-6789 |\n| time | ##:## | 23:59 |\n| time-with-seconds | ##:##:## | 23:59:59 |\n\n### useMask composable\n\nThe `useMask` composable provides a set of methods for working with masks.\n\n```js\n  import { useMask } from 'vuetify'\n\n  const mask = useMask({ mask: '####-####' })\n\n  mask.mask('12345678') // 1234-5678\n  mask.unmask('1234-5678') // 12345678\n  mask.isValid('abc') // false\n  mask.isValid('1234') // true\n  mask.isComplete('1234') // false\n  mask.isComplete('1234-5678') // true\n```\n\n### Examples\n\n#### Using Built in Masks\n\nYou can use the built-in masks by simply referencing their name. This is an example of a **phone** mask.\n\n<ExamplesExample file=\"v-mask-input/phone\" />\n\n#### Using Custom Masks\n\nYou can create custom masks using the available tokens. This will create a mask that accepts 3 letters followed by 3 numbers (e.g., \"ABC-123\").\n\n<ExamplesExample file=\"v-mask-input/custom-mask\" />\n\n#### Using Custom Tokens\n\nYou can also define custom tokens for more specific input requirements:\n\n<ExamplesExample file=\"v-mask-input/custom-token\" />\n\n#### IP Address\n\nThis example shows how to create a mask for IP addresses with validation:\n\n<ExamplesExample file=\"v-mask-input/ip-address\" />\n\n#### Credit Card Form\n\nA complete credit card form example with validation:\n\n<ExamplesExample file=\"v-mask-input/credit-card-form\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/menus.md",
    "content": "---\nmeta:\n  nav: Menus\n  title: Menu component\n  description: The menu component exposes a dropdown of potential selections or actions that the user can make.\n  keywords: menus, vuetify menu component, vue menu component\nrelated:\n  - /components/dialogs/\n  - /components/tooltips/\n  - /styles/transitions/\nfeatures:\n  github: /components/VMenu/\n  label: 'C: VMenu'\n  report: true\n  spec: https://m2.material.io/components/menus\n---\n\n# Menus\n\nThe `v-menu` component shows a menu at the position of the element used to activate it.\n\n<PageFeatures />\n\n## Usage\n\nThere are three main ways that menus can be defined in markup.\n\nThe first one is by using the **activator** slot. Don't forget to bind the slot **props** to the activating element.\n\nThe second one is by using the **activator** prop with value `parent`. This will turn the parent element of the menu into the activator.\n\nThe third one is to supply a CSS selector string to **activator** prop. This allows you to place the menu and its activator in separate parts of the markup.\n\n<ExamplesExample file=\"v-menu/usage\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-menu](/api/v-menu/) | Primary Component |\n| [v-btn](/api/v-btn/) | Sub-component often used for the `v-menu` activator |\n| [v-list-item](/api/v-list-item/) | Sub-component often used for the `v-menu` content |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n<!-- #### Absolute\n\nMenus can also be placed absolutely on top of the activator element using the **absolute** prop. Try clicking anywhere on the image.\n\n<ExamplesExample file=\"v-menu/prop-absolute\" />\n\n#### Absolute without activator\n\nMenus can also be used without an activator by using **absolute** together with the props **position-x** and **position-y**. Try right-clicking anywhere on the image.\n\n<ExamplesExample file=\"v-menu/prop-absolute-without-activator\" /> -->\n\n<!-- #### Close on click\n\nMenu can be closed when lost focus.\n\n<ExamplesExample file=\"v-menu/prop-close-on-click\" />\n\n#### Close on content click\n\nYou can configure whether `v-menu` should be closed when its content is clicked.\n\n<ExamplesExample file=\"v-menu/prop-close-on-content-click\" /> -->\n\n<!-- #### Disabled\n\nYou can disable the menu. Disabled menus can't be opened.\n\n<ExamplesExample file=\"v-menu/prop-disabled\" /> -->\n\n#### Location\n\nMenu can be offset relative to the activator by using the **location** prop. Read more about **location** [here](/components/overlays/#location).\n\n<ExamplesExample file=\"v-menu/prop-location\" />\n\n#### Open on hover\n\nMenus can be accessed using hover instead of clicking with the **open-on-hover** prop.\n\n<ExamplesExample file=\"v-menu/prop-open-on-hover\" />\n\n#### Nested menus\n\nMenus with other menus inside them will not close until their children are closed. The **submenu** prop changes keyboard behaviour to open and close with left/right arrow keys instead of up/down.\n\n<ExamplesExample file=\"v-menu/prop-submenu\" />\n\n#### Positioning Menus with Coordinates\n\n`v-menu` can be positioned relative to a DOM element or explicit `[x, y]` coordinates.\n\n* The most common use case is to pass an **event target element**. This allows the menu to anchor itself to the element that was clicked.\n* You can also use `[x, y]` screen coordinates, though this is less common and typically used for context menus.\n* `:offset` is used to shift the menu position relative to its anchor, not to define an absolute position.\n* Any DOM event with `clientX` and `clientY` can be used (e.g. `click`, `contextmenu`).\n\n<ExamplesExample file=\"v-menu/prop-positioningmenu\" />\n\n### Slots\n\n#### Activator and tooltip\n\nWith the new `v-slot` syntax, nested activators such as those seen with a `v-menu` and `v-tooltip` attached to the same activator button, need a particular setup in order to function correctly.\n\n::: info\n  This same syntax is used for other nested activators such as `v-dialog` with `v-tooltip`\n:::\n\n<ExamplesExample file=\"v-menu/slot-activator-and-tooltip\" />\n\n### Misc\n\n#### Transitions\n\nVuetify comes with [several standard transitions](/styles/transitions#api) that you can use. You can also create your own and pass it as the transition argument. For an example of how the stock transitions are constructed, visit [here](https://github.com/vuetifyjs/vuetify/blob/master/packages/vuetify/src/util/helpers.ts).\n\n<ExamplesExample file=\"v-menu/misc-transition\" />\n\n#### Popover menu\n\nA menu can be configured to be static when opened, allowing it to function as a popover. This can be useful when there are multiple interactive items within the menu contents.\n\n<ExamplesExample file=\"v-menu/misc-popover\" />\n\n#### Use In components\n\nMenus can be placed within almost any component.\n\n<ExamplesExample file=\"v-menu/misc-use-in-components\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/navigation-drawers.md",
    "content": "---\nmeta:\n  nav: Navigation drawers\n  title: Navigation drawer component\n  description: The navigation drawer component contains internal navigation links for an application and can be permanently on-screen or controlled programmatically.\n  keywords: navigation drawer, vuetify navigation drawer component, vue navigation drawer component\nrelated:\n  - /components/lists/\n  - /components/icons/\n  - /getting-started/wireframes/\nfeatures:\n  label: \"C: VNavigationDrawer\"\n  report: true\n  github: /components/VNavigationDrawer/\n  spec: https://m2.material.io/components/navigation-drawer\n---\n\n# Navigation drawers\n\nThe `v-navigation-drawer` component is what your users will utilize to navigate through the application.\n\n<PageFeatures />\n\n## Usage\n\nThe navigation drawer is primarily used to house links to the pages in your application and is pre-configured to work with or without **vue-router** right out the box. Using `null` as the starting value for its **v-model** will initialize the drawer as closed on mobile and as open on desktop. It is common to pair drawers with the [v-list](/components/lists) component using the **nav** property. You can learn more by exploring [application layout](/features/application-layout) examples.\n\n<ExamplesUsage name=\"v-navigation-drawer\" />\n\n<PromotedEntry />\n\n::: tip\n\nFor the purpose of display, some examples are wrapped in a `v-card` element. Within your application you will generally place the `v-navigation-drawer` as a direct child of\n`v-app`.\n\n:::\n\n```html { resource=\"src/App.vue\" }\n<template>\n  <v-app>\n    <v-navigation-drawer />\n  </v-app>\n</template>\n```\n\n## API\n\n| Component                                        | Description                               |\n| ------------------------------------------------ | ----------------------------------------- |\n| [v-navigation-drawer](/api/v-navigation-drawer/) | Primary Component                         |\n| [v-list-item](/api/v-list-item/)                 | Component used to create navigation links |\n\n<ApiInline hide-links />\n\n## Caveats\n\n::: info\nThe **expand-on-hover** prop does not alter the content area of **v-main**. To have content area respond to **expand-on-hover**, bind **v-model:rail** to a data prop.\n:::\n\n## Examples\n\n### Props\n\n#### Bottom drawer\n\nUsing the **bottom** prop, we are able to relocate our drawer on mobile devices to come from the bottom of the screen. This is an alternative style and only activates once the **mobile-breakpoint** is met.\n\n<ExamplesExample file=\"v-navigation-drawer/prop-bottom-drawer\" />\n\n#### Expand on hover\n\nPlaces the component in **rail** mode and expands once hovered. This **does not** alter the content area of **v-main**. The width can be controlled with the **rail-width** property.\n\n<ExamplesExample file=\"v-navigation-drawer/prop-expand-on-hover\" />\n\n#### Background images\n\nApply a custom background to your drawer via the **image** prop. If you need to customize it further, you can use the `image` slot and render your own `v-img`.\n\n<ExamplesExample file=\"v-navigation-drawer/prop-images\" />\n\n#### Rail variant\n\nWhen using the **rail** prop, the drawer will shrink (default 56px) and hide everything inside of `v-list` except the first element.\n\n<ExamplesExample file=\"v-navigation-drawer/prop-rail-variant\" />\n\n#### Floating\n\nBy default, a navigation drawer has a 1px right border that separates it from content. In this example we want to detach the drawer from the left side and let it float on its own. The **floating** property removes the right border (or left if using **position** prop).\n\n<ExamplesExample file=\"v-navigation-drawer/prop-permanent-and-floating\" />\n\n#### Location\n\nNavigation drawers can also be positioned on the opposite side of your application (or an element) using the **location** prop. This is useful for creating a side-sheet with auxiliary information that may not have any navigation links.\n\n<ExamplesExample file=\"v-navigation-drawer/prop-right\" />\n\n#### Temporary\n\nA temporary drawer sits above its application and uses a scrim (overlay) to darken the background. This drawer behavior is mimicked by default when on mobile. Clicking outside of the drawer will cause it to close.\n\n<ExamplesExample file=\"v-navigation-drawer/prop-temporary\" />\n\n### Misc\n\n#### Colored drawer\n\nNavigation drawers can be customized to fit any application's design. Here we apply a custom background color and an appended content area using the **append** slot.\n\n<ExamplesExample file=\"v-navigation-drawer/misc-colored\" />\n\n#### Multiple drawers\n\nIn this example we define two navigation-drawers, one using **rail** and one without.\n\n<ExamplesExample file=\"v-navigation-drawer/misc-combined\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/no-ssr.md",
    "content": "---\nmeta:\n  title: No SSR\n  description: The No SSR component is a simple component that doesn't get rendered on the server, but only on the client.\n  keywords: nossr, vuetify no ssr component, vue no ssr component\nfeatures:\n  github: /components/VNoSsr/\n  label: 'C: VNoSsr'\n  report: true\n---\n\n# No SSR\n\nThe `v-no-ssr` component is a simple wrapper that allows a developer to designate what a server-side renderer should not render, but leave to the client.\n\n<PageFeatures />\n\n## Usage\n\nThe `v-no-ssr` component prevents its content from rendering on the server side.\n\n```html\n<template>\n  <v-no-ssr>\n    <!-- Everything inside will only render on the Client -->\n    <v-sheet>\n      Lorem ipsum dolor sit amet consectetur adipisicing elit. Alias vitae minus, incidunt laboriosam amet doloribus officiis?\n    </v-sheet>\n  </v-no-ssr>\n</template>\n```\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-no-ssr](/api/v-no-ssr/) | Primary Component |\n\n<ApiInline hide-links />\n\n<PromotedEntry />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/number-inputs.md",
    "content": "---\nmeta:\n  title: Number inputs\n  description: The number input component provides a clean interface for entering numeric values with increment and decrement controls.\n  keywords: Number, vuetify number input component, vue number component\nrelated:\n  - /components/inputs/\n  - /components/text-fields/\n  - /components/forms/\nfeatures:\n  label: 'C: VNumberInput'\n  github: /components/VNumberInput/\n  report: true\n---\n\n# Number inputs\n\nThe VNumberInput extends the standard HTML number-type input, ensuring style consistency across browsers as a replacement for `<input type=\"number\">`\n\n<page-features />\n\n## Usage\n\nHere we display a list of settings that could be applied within an application.\n\n<ExamplesUsage name=\"v-number-input\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-number-input](/api/v-number-input/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Caveats\n\n::: warning\n**v-number-input** is designed for simple numeric input usage. It has limitations with very long integers and highly precise decimal arithmetic due to JavaScript number precision issues:\n\n- For integers, **v-model** is restricted within [Number.MIN_SAFE_INTEGER](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MIN_SAFE_INTEGER) and [Number.MAX_SAFE_INTEGER](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER) to ensure precision is not lost.\n\n- To cope with JavaScript floating-point issues (e.g. 0.1 + 0.2 === 0.30000000000000004), Vuetify's internal logic uses **toFixed()** with the maximum number of decimal places between v-model and step. If accurate arbitrary-precision decimal arithmetic is required, consider working with strings using [decimal.js](https://github.com/MikeMcl/decimal.js) and  [v-text-field](/components/text-fields) instead.\n:::\n\n## Guide\n\nThe `v-number-input` component is built upon the `v-field` and `v-input` components. It is used as a replacement for `<input type=\"number\">`, accepting numeric values from the user.\n\n### Props\n\nThe `v-number-input` component has support for most of `v-field`'s props and is follows the same design patterns as other inputs.\n\n#### Control-variant\n\nThe `control-variant` prop offers an easy way to customize steppers button layout. The following values are valid options: **default**, **stacked**, **split** and **hidden**.\n\n<ExamplesExample file=\"v-number-input/prop-control-variant\" />\n\n#### Reverse\n\nThe `reverse` prop automatically changes the stepper buttons' position to the opposite side for both the default and stacked control variants.\n\n<ExamplesExample file=\"v-number-input/prop-reverse\" />\n\n#### Hide-input\n\nThe `hide-input` prop hides the input field, allowing only the stepper buttons to be visible. These stepper buttons follow a stacked control-variant layout.\n\n<ExamplesExample file=\"v-number-input/prop-hide-input\" />\n\n#### Inset\n\nThe `inset` prop adjusts the style of the stepper buttons by reducing the size of the button dividers.\n\n<ExamplesExample file=\"v-number-input/prop-inset\" />\n\n#### Min/Max\n\nThe `min` and `max` props specify the minimum and maximum values accepted by v-number-input, behaving identically to the native min and max attributes for `<input type=\"number\">`.\n\n<ExamplesExample file=\"v-number-input/prop-min-max\" />\n\n#### Step\n\nThe `step` prop behaves the same as the `step` attribute in the `<input type=\"number\">`, it defines the incremental steps for adjusting the numeric value.\n\n<ExamplesExample file=\"v-number-input/prop-step\" />\n\n#### Precision\n\nThe `precision` prop enforces strict precision. It is expected to be an integer value in range between `0` and `15`. Input will prevent user from typing or pasting an invalid value.\n\n<ExamplesExample file=\"v-number-input/prop-precision\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/otp-input.md",
    "content": "---\nmeta:\n  title: OTP Input\n  description: The OTP input component is used for MFA authentication via input field.\n  keywords: OTP, MFA, vuetify OTP input component, vue OTP component\nrelated:\n  - /components/inputs/\n  - /components/text-fields/\n  - /components/forms/\nfeatures:\n  label: 'C: VOtpInput'\n  github: /components/VOtpInput/\n  report: true\n---\n\n# OTP Input\n\nThe OTP input is used for MFA procedure of authenticating users by a one-time password.\n\n<PageFeatures />\n\n## Usage\n\nHere we display a list of settings that could be applied within an application.\n\n<ExamplesUsage name=\"v-otp-input\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-otp-input](/api/v-otp-input/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Anatomy\n\nThe `v-otp-input` component is a collection of [v-field](/api/v-field/) components that combine to create a single input.\n\n![Otp input Anatomy](https://cdn.vuetifyjs.com/docs/images/components/v-otp-input/v-otp-input-anatomy.png \"OTP input Anatomy\")\n\n| Element / Area | Description |\n| - | - |\n| 1. Container | The OTP input container holds a number of `v-field` components  |\n| 2. Field | The `v-field` component is used to create a single input field |\n\n## Guide\n\nThe `v-otp-input` component is a collection of `v-field` components that combine to create a single input. It is used to validate a one-time password (OTP) that is sent to the user via email or SMS.\n\nThe following code snippet is an example of a basic `v-otp-input` component.\n\n```html\n<v-otp-input></v-otp-input>\n```\n\n### Props\n\nThe `v-otp-input` component has support for most of `v-field`'s props and is follows the same design patterns as other inputs.\n\n#### Length\n\nThe `length` prop determines the number of `v-field` components that are rendered. The default value is `6`.\n\n<ExamplesExample file=\"v-otp-input/prop-length\" />\n\n#### Focus-all\n\nThe `autofocus` prop automatically focuses the first element in the `v-otp-input` component.\n\n<ExamplesExample file=\"v-otp-input/prop-focus-all\" />\n\n#### Error\n\nThe `error` prop puts the `v-otp-input` into an error state. This is useful for displaying validation errors.\n\n<ExamplesExample file=\"v-otp-input/prop-error\" />\n\n#### Variants\n\nThe `v-otp-input` component supports the same variants as `v-field`, `v-text-field` and other inputs.\n\n<ExamplesExample file=\"v-otp-input/prop-variant\" />\n\n#### Masked\n\nUsing `masked` prop you can hide the entered characters. It is similar to a `type=\"password\"`, but makes it possible to also restrict characters to digits with `type=\"number\"`.\n\n<ExamplesExample file=\"v-otp-input/prop-masked\" />\n\n#### Loader\n\nThe `loader` prop displays a loader when the `v-otp-input` component is in a loading state. When complete, emits a `finish` event.\n\n<ExamplesExample file=\"v-otp-input/prop-loader\" />\n\n## Examples\n\nThe following are a collection of examples that demonstrate more advanced and real world use of the `v-otp-input` component.\n\n### Card variants\n\nThe following example is a detailed example of a `v-otp-input` component used within a card.\n\n<ExamplesExample file=\"v-otp-input/misc-card\" />\n\n### Mobile text\n\nThe following example is a detailed example of a `v-otp-input` component used with mobile text.\n\n<ExamplesExample file=\"v-otp-input/misc-mobile\" />\n\n### Verify account\n\nThe following example is a detailed example of a `v-otp-input` component used to verify a user's account.\n\n<ExamplesExample file=\"v-otp-input/misc-verify\" />\n\n### Divider\n\nThe following example is a detailed example of a `v-otp-input` component used with a divider.\n\n<ExamplesExample file=\"v-otp-input/misc-divider\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/overflow-btns.md",
    "content": "---\ndisabled: true\nmeta:\n  title: Overflow button component\n  description: The overflow button component creates an interface for a select that contains additional features and functionality.\n  keywords: overflow buttons, vuetify overflow button component, vue overflow button component\nrelated:\n  - /components/forms/\n  - /components/selects/\n---\n\n# Overflow buttons\n\n`v-overflow-btn` is used to give the user the ability to select items from the list. It has 3 variations: `editable`, `overflow` and `segmented`\n\n<PromotedEntry />\n\n## Usage\n\n`v-overflow-btn` is used for creating selection lists\n\n<ExamplesUsage name=\"v-overflow-btn\" />\n\n## API\n\n<ApiInline />\n\n## Examples\n\n### Props\n\n#### Counter\n\nYou can add a counter to `v-overflow-btn` to control the max char count\n\n<ExamplesExample file=\"v-overflow-btn/prop-counter\" />\n\n#### Dense\n\nYou can use `dense` prop to reduce overflow button height and lower max height of list items.\n\n<ExamplesExample file=\"v-overflow-btn/prop-dense\" />\n\n#### Disabled\n\n`v-overflow-btn` can be disabled in order to prevent a user from interacting with it\n\n<ExamplesExample file=\"v-overflow-btn/prop-disabled\" />\n\n#### Editable\n\n`editable` `v-overflow-btn` can be directly edited, just as `v-text-field`\n\n<ExamplesExample file=\"v-overflow-btn/prop-editable\" />\n\n#### Filled\n\nText fields can be used with an alternative box design.\n\n<ExamplesExample file=\"v-overflow-btn/prop-filled\" />\n\n#### Hint\n\nYou can add a hint for the user using the `hint` property\n\n<ExamplesExample file=\"v-overflow-btn/prop-hint\" />\n\n#### Loading\n\n`v-overflow-btn` can have `loading` state with a linear progress bar under them\n\n<ExamplesExample file=\"v-overflow-btn/prop-loading\" />\n\n#### Menu props\n\nYou can set underlying `v-menu` props using `menu-props` property\n\n<ExamplesExample file=\"v-overflow-btn/prop-menu-props\" />\n\n#### Readonly\n\n`v-overflow-btn` can be put into `readonly` mode, it'll become inactive but won't change the color\n\n<ExamplesExample file=\"v-overflow-btn/prop-readonly\" />\n\n#### Segmented\n\n`segmented` `v-overflow-btn` has and additional divider between the content and the icon\n\n<ExamplesExample file=\"v-overflow-btn/prop-segmented\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/overlays.md",
    "content": "---\nmeta:\n  nav: Overlays\n  title: Overlay component\n  description: The overlay component makes it easy to create a scrim over components or your entire application.\n  keywords: overlays, vuetify overlay component, vue overlay component\nrelated:\n  - /components/dialogs/\n  - /components/menus/\n  - /components/tooltips/\nfeatures:\n  github: /components/VOverlay/\n  label: 'C: VOverlay'\n  report: true\n---\n\n# Overlays\n\n`v-overlay` is the base for components that float over the rest of the page, such as `v-menu` and `v-dialog`. It can also be used on its own and comes with everything you need to create a custom popover component.\n\n<PageFeatures />\n\n## Usage\n\nIn its simplest form, the `v-overlay` component will add a dimmed layer over your application.\n\n<ExamplesExample file=\"v-overlay/usage\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-overlay](/api/v-overlay/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Activator\n\nOverlays can be opened with v-model, or by clicking or hovering on an activator element. An activator is mandatory for the connected locationLocation strategy. The activator element (if present) will also be used by some transitions to slide or scale from the activator's location instead of the middle of the screen.\n\nRelated props:\n\n- `activator`\n- `activatorProps`\n- `openOnClick`\n- `openOnHover`\n- `openOnFocus`\n- `closeDelay`\n- `openDelay`\n\n### Activator prop\n\nThe simplest way of providing an activator. Can be a CSS selector to pass to `document.querySelector()`, a component instance, or a HTMLElement. The string `\"parent\"` is also accepted to automatically bind to the parent element.\n\n```html\n<v-overlay activator=\"#id\" />\n<v-overlay activator=\".class\" />\n<v-overlay :activator=\"elementRef\" />\n<v-btn>\n  <v-overlay activator=\"parent\" />\n</v-btn>\n```\n\n### Activator slot\n\nFor more manual control, the slot can be used instead. `props` is an object containing all the relevant ARIA attributes and event handlers, and must be applied to the target element with `v-bind` for the component to work correctly.\n\n```html\n<v-overlay>\n  <template #activator=\"{ isActive, props }\">\n    <v-btn v-bind=\"props\">Overlay is {{ isActive ? 'open' : 'closed' }}</v-btn>\n  </template>\n</v-overlay>\n```\n\n## Location Strategies\n\n### Static (default)\n\n`location-strategy=\"static\"`\n\nOverlay content is absolutely positioned to the center of its container by default.\n\n### Connected\n\n`location-strategy=\"connected\"`\n\nThe connected strategy is used by [v-menu](/components/menus) and [v-tooltip](/components/tooltips) to attach the overlay content to an activator element.\n\n`location` selects a point on the activator, and `origin` a point on the overlay content. The content element will be positioned so the two points overlap.\n\n<ExamplesExample file=\"v-overlay/connected-playground\" />\n\n## Scroll Strategies\n\n### Block (default)\n\n`scroll-strategy=\"block\"`\n\nScrolling is blocked while the overlay is active, and the scrollbar is hidden. If `contained` is also set, scrolling will only be blocked up to the overlay's [`offsetParent`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetParent).\n\n<ExamplesExample file=\"v-overlay/scroll-block\" />\n\n### Close\n\n`scroll-strategy=\"close\"`\n\nScrolling when the overlay is active will de-activate it.\n\n<ExamplesExample file=\"v-overlay/scroll-close\" />\n\n### Reposition\n\n`scroll-strategy=\"reposition\"`\n\nWhen using the `connected` location strategy, this scroll strategy will reposition the overlay element to always respect the activator location.\n\n<ExamplesExample file=\"v-overlay/scroll-reposition\" />\n\n### None\n\n`scroll-strategy=\"none\"`\n\nNo scroll strategy is used.\n\n<ExamplesExample file=\"v-overlay/scroll-none\" />\n\n## Examples\n\n### Props\n\n#### Contained\n\nA **contained** overlay is positioned absolutely and contained inside its parent element.\n\n::: info\n  Note: The parent element must have position: relative.\n:::\n\n<ExamplesExample file=\"v-overlay/prop-contained\" />\n\n### Misc\n\n#### Advanced\n\nUsing the [v-hover](/components/hover), we are able to add a nice scrim over the information card with additional actions the user can take.\n\n<ExamplesExample file=\"v-overlay/misc-advanced\" />\n\n#### Loader\n\nUsing the `v-overlay` as a background, add a progress component to easily create a custom loader.\n\n<ExamplesExample file=\"v-overlay/misc-loader\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/paginations.md",
    "content": "---\nmeta:\n  nav: Pagination\n  title: Pagination component\n  description: The pagination component is used to separate long sets of data so that it is easier for a user to consume information.\n  keywords: pagination, vuetify pagination component, vue pagination component\nrelated:\n  - /components/data-tables/basics/\n  - /components/tables/\nfeatures:\n  figma: true\n  label: 'C: VPagination'\n  report: true\n  github: /components/VPagination/\n---\n\n# Pagination\n\nThe `v-pagination` component is used to separate long sets of data so that it is easier for a user to consume information.\n\n<PageFeatures />\n\n## Usage\n\nPagination by default displays the number of pages based on the set **length** prop, with **prev** and **next** buttons surrounding to help you navigate. Depending on the length provided, the pagination component will automatically scale. To maintain the current page, simply supply a **v-model** attribute.\n\n<ExamplesUsage name=\"v-pagination\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-pagination](/api/v-pagination/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n#### Rounded\n\nThe **rounded** prop allows you to render pagination buttons with alternative styles.\n\n<ExamplesExample file=\"v-pagination/prop-rounded\" />\n\n#### Disabled\n\nPagination items can be manually deactivated using the **disabled** prop.\n\n<ExamplesExample file=\"v-pagination/prop-disabled\" />\n\n#### Icons\n\nPrevious and next page icons can be customized with the **prev-icon** and **next-icon** props.\n\n<ExamplesExample file=\"v-pagination/prop-icons\" />\n\n#### Length\n\nUsing the **length** prop you can set the length of `v-pagination`, if the number of page buttons exceeds the parent container, it will truncate the list.\n\n<ExamplesExample file=\"v-pagination/prop-length\" />\n\n#### Total visible\n\nYou can also manually set the maximum number of visible page buttons with the **total-visible** prop.\n\n<ExamplesExample file=\"v-pagination/prop-total-visible\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/parallax.md",
    "content": "---\nmeta:\n  nav: Parallax\n  title: Parallax component\n  description: The parallax component creates a 3d effect that makes an image appear to scroll slower than the window.\n  keywords: parallax, vuetify parallax component, vue parallax component\nrelated:\n  - /components/aspect-ratios/\n  - /components/cards/\n  - /components/images/\nfeatures:\n  github: /components/VParallax/\n  label: 'C: VParallax'\n  report: true\n---\n\n# Parallax\n\nThe `v-parallax` component creates a 3d effect that makes an image appear to scroll slower than the window.\n\n<PageFeatures />\n\n## Usage\n\nA parallax causes a shift in a background image when the user scrolls the page.\n\n<ExamplesExample file=\"v-parallax/usage\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-parallax](/api/v-parallax/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Misc\n\n#### Content\n\nYou can also place any content inside of the parallax. This allows you to use the parallax as a hero image.\n\n<ExamplesExample file=\"v-parallax/misc-content\" />\n\n#### Welcome\n\nYou can use it as a welcome section or as a portfolio hero section.\n\n<ExamplesExample file=\"v-parallax/misc-welcome\" />\n\n#### Custom height\n\nYou can specify a custom height on a parallax. Keep in mind this can break the parallax if your image is not sized properly\n\n<ExamplesExample file=\"v-parallax/misc-custom-height\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/pie-charts.md",
    "content": "---\nmeta:\n  nav: Pie charts\n  title: Pie chart component\n  description: The pie/donut chart component is versatile and fully customizable.\n  keywords: vuetify pie component, vue pie component, chart, pie, donut\nfeatures:\n  github: /labs/VPie/\n  label: 'C: VPie'\n  report: true\n---\n\n# Pie Chart\n\nThe `v-pie` component is design to display either pie or a donut chart with integrated tooltips and legend.\n\n<PageFeatures />\n\n## Installation\n\nLabs components require manual import and registration with the Vuetify instance.\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { VPie } from 'vuetify/labs/VPie'\n\nexport default createVuetify({\n  components: {\n    VPie,\n  },\n})\n```\n\n## Usage\n\n<ExamplesUsage name=\"v-pie\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-pie](/api/v-pie/) | Primary Component |\n| [v-pie-segment](/api/v-pie-segment/) | Sub-component used to display a single segment |\n| [v-pie-tooltip](/api/v-pie-tooltip/) | Chart tooltip component based on `v-list-item` |\n\n<ApiInline hide-links />\n\n## Guide\n\n`v-pie` does not have any opinionated way to use. You may start by providing an array of items (data) and then customize, hide or replace elements to make it behave as you wish to fit your project.\n\nThere are some notable features that are not common in other Vuetify components:\n\n- each item is expected to have a `key` field (name can be changed with `item-key`)\n- `tooltip` accept object and lets you customize transition, offset and the text. Notably, the `titleFormat` and `subtitleFormat` can be functions or simple string templates that support `[title]` and `[value]` macros.\n- `animations` prop lets you control duration and easing\n\n### Props\n\nThe `v-pie` supports various stylistic props to customize the appearance and hover transitions.\n\n#### Size\n\nCharts are more like drawings then regular HTML elements and their size needs to be controlled externally. `hover-scale` will reserve some space to enlarge segments on hover.\n\n<ExamplesExample file=\"v-pie/prop-size\" />\n\n#### Palette\n\nColors can be conveniently passed to a dedicated `palette` prop.\n\n<ExamplesExample file=\"v-pie/prop-palette\" />\n\n#### Legend position\n\nThe legend can be moved to any side or hidden entirely. With little effort you can also control legend's and tooltip's text.\n\n<ExamplesExample file=\"v-pie/prop-legend\" />\n\n#### Item text overrides\n\nSingle item representation can be easily customized with string templates.\n\n<ExamplesExample file=\"v-pie/prop-formats\" />\n\n### Examples\n\nThe following are a collection of examples that demonstrate some more advanced capabilities of `v-pie` component.\n\n#### Custom Legend\n\nLegend does not need to be a list of chips. You can fully override it to match the expected design.\n\n<ExamplesExample file=\"v-pie/misc-custom-legend\" />\n\n#### Overlay patterns\n\nThe following example demonstrates how to provide overlay patterns to support users with vision impairments.\n\n<ExamplesExample file=\"v-pie/misc-patterns\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/progress-circular.md",
    "content": "---\nmeta:\n  nav: Progress circular\n  title: Progress circular component\n  description: The progress circular component is useful for displaying a visual indicator of numerical data in a circle.\n  keywords: progress circular, vuetify progress circular component, vue progress circular component, circular progress\nrelated:\n  - /components/cards/\n  - /components/progress-linear/\n  - /components/lists/\nfeatures:\n  github: /components/VProgressCircular/\n  label: 'C: VProgressCircular'\n  report: true\n  spec: https://m2.material.io/components/progress-indicators\n---\n\n# Progress circular\n\nThe `v-progress-circular` component is used to convey data circularly to users. It also can be put into an indeterminate state to portray loading.\n\n<PageFeatures />\n\n## Usage\n\nIn its simplest form, v-progress-circular displays a circular progress bar. Use the value prop to control the progress.\n\n<ExamplesUsage name=\"v-progress-circular\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-progress-circular](/api/v-progress-circular/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n#### Color\n\nAlternate colors can be applied to `v-progress-circular` using the `color` prop.\n\n<ExamplesExample file=\"v-progress-circular/prop-color\" />\n\n#### Indeterminate\n\nUsing the `indeterminate` prop, a `v-progress-circular` continues to animate indefinitely.\n\n<ExamplesExample file=\"v-progress-circular/prop-indeterminate\" />\n\n#### Reveal\n\nThe `reveal` prop animates the progress circle from 0 to its model value when the component mounts.\n\n<ExamplesExample file=\"v-progress-circular/prop-reveal\" />\n\n#### Rotate\n\nThe `rotate` prop gives you the ability to customize the `v-progress-circular`'s origin.\n\n<ExamplesExample file=\"v-progress-circular/prop-rotate\" />\n\n#### Size and Width\n\nThe `size` and `width` props allow you to easily alter the size and width of the `v-progress-circular` component.\n\n<ExamplesExample file=\"v-progress-circular/prop-size-and-width\" />\n\n### Slots\n\n#### Default\n\n`default` slot can be used to replace the text inside the loader.\n\n<ExamplesExample file=\"v-progress-circular/prop-slot-default\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/progress-linear.md",
    "content": "---\nmeta:\n  nav: Progress linear\n  title: Progress linear component\n  description: The progress-linear component is useful for displaying a visual indicator of numerical data in a straight line.\n  keywords: progress linear, vuetify progress linear component, vue progress linear component, linear progress\nrelated:\n  - /components/cards/\n  - /components/progress-circular/\n  - /components/lists/\nfeatures:\n  figma: true\n  github: /components/VProgressLinear/\n  label: 'C: VProgressLinear'\n  report: true\n  spec: https://m2.material.io/components/progress-indicators\n---\n\n# Progress linear\n\nThe `v-progress-linear` component is used to convey data visually to users. It supports both indeterminate amounts, such as loading or processing, and finite amounts of progress (including separate buffer values).\n\n<PageFeatures />\n\n## Usage\n\nIn its simplest form, `v-progress-linear` displays a horizontal progress bar. Use the **value** prop to control the progress.\n\n<ExamplesUsage name=\"v-progress-linear\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-progress-linear](/api/v-progress-linear/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n#### Buffering\n\nThe primary value is controlled by **v-model**, whereas the buffer is controlled by the **buffer-value** prop.\n\n<ExamplesExample file=\"v-progress-linear/prop-buffer-value\" />\n\n#### Chunks\n\nThe component can be split into chunks using `chunk-count` or `chunk-width`. Visible progress is snapped to the last filled chunk.\n\n<ExamplesExample file=\"v-progress-linear/prop-chunks\" />\n\n#### Colors\n\nYou can set the colors of the progress bar using the props **color** and **bg-color**.\n\n<ExamplesExample file=\"v-progress-linear/prop-colors\" />\n\n#### Indeterminate\n\nUsing the **indeterminate** prop, `v-progress-linear` continuously animates.\n\n<ExamplesExample file=\"v-progress-linear/prop-indeterminate\" />\n\n#### Reversed\n\nDisplays reversed progress. The component also has RTL support, such that a progress bar in right-to-left mode with **reverse** prop enabled will display left-to-right.\n\n<ExamplesExample file=\"v-progress-linear/prop-reverse\" />\n\n#### Rounded\n\nThe **rounded** prop is used to apply a border radius to the `v-progress-linear` component.\n\n<ExamplesExample file=\"v-progress-linear/prop-rounded\" />\n\n::: info\n  Use the **rounded-bar** property to add a border-radius to the inner edges of value bar. By default, the value bar's border-radius is equal to the default _border-radius_ of your application unless a different value is provided by the **rounded** prop or SASS variable.\n:::\n\n#### Stream\n\nThe **stream** property works with **buffer-value** to convey to the user that there is some action taking place.\n\n<ExamplesExample file=\"v-progress-linear/prop-stream\" />\n\n#### Striped\n\nThis applies a striped background over the value portion of the `v-progress-linear`. This prop has no effect when using **indeterminate**.\n\n<ExamplesExample file=\"v-progress-linear/prop-striped\" />\n\n### Slots\n\n#### Default\n\nThe `v-progress-linear` component will be responsive to user input when using **v-model**. You can use the default slot or bind a local model to display inside of the progress. If you are looking for advanced features on a linear type component, check out [v-slider](/components/sliders).\n\n<ExamplesExample file=\"v-progress-linear/slot-default\" />\n\n### Misc\n\n#### Determinate\n\nThe progress linear component can have a determinate state modified by **v-model**.\n\n<ExamplesExample file=\"v-progress-linear/misc-determinate\" />\n\n#### File loader\n\nThe `v-progress-linear` component is good for communicating to the user that they are waiting for a response.\n\n<ExamplesExample file=\"v-progress-linear/misc-file-loader\" />\n\n#### Toolbar loader\n\nUsing the **absolute** prop we are able to position the `v-progress-linear` component at the bottom of the `v-toolbar`. We also use the **active** prop which allows us to control the visibility of the progress.\n\n<ExamplesExample file=\"v-progress-linear/misc-toolbar-loader\" />\n\n#### Buffer color and opacity\n\nThe buffer color and opacity can be controlled using the **buffer-color** and **buffer-opacity** props. This enables you to make multi colored progress bars.\n\n<ExamplesExample file=\"v-progress-linear/misc-buffer-color\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/progress.md",
    "content": "---\nemphasized: true\nmeta:\n  nav: Progress\n  title: Progress component\n  description: A unified progress indicator component that supports both linear and circular variants with labels and accessible value formatting.\n  keywords: progress, progress bar, loading, vuetify progress component\nrelated:\n  - /components/progress-linear/\n  - /components/progress-circular/\nfeatures:\n  github: /labs/VProgress/\n  label: 'C: VProgress'\n  report: true\n---\n\n# Progress\n\nThe `v-progress` component is a unified wrapper for linear and circular progress indicators with built-in label and accessible value formatting.\n\n<PageFeatures />\n\n::: warning\n\nThis feature requires [v4.0.3](/getting-started/release-notes/?version=v4.0.3)\n\n:::\n\n## Installation\n\nLabs components require manual import and registration with the Vuetify instance.\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { VProgress } from 'vuetify/labs/VProgress'\n\nexport default createVuetify({\n  components: {\n    VProgress,\n  },\n})\n```\n\n## Usage\n\n<ExamplesUsage name=\"v-progress\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-progress](/api/v-progress/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Guide\n\nThe `v-progress` component combines `v-progress-linear` and `v-progress-circular` into a single component with a `type` prop, while adding label support and accessible value formatting.\n\n### Props\n\n#### Label\n\nThe **label** prop displays text alongside the progress indicator. Use the **label-position** prop to control placement.\n\n<ExamplesExample file=\"v-progress/prop-label\" />\n\n#### Value format\n\nThe **value-format** prop formats the `aria-valuetext` for screen readers. Use `[value]`, `[max]`, or `[percent]` as placeholders in strings, or pass a function for custom formatting.\n\n<ExamplesExample file=\"v-progress/prop-value-format\" />\n\n### Slots\n\n#### Label and value\n\nUse the **#label** and **#value** slots to fully customize the content displayed alongside the progress indicator. Both slots receive `value`, `max`, `percent`, and `formattedValue` as scoped props.\n\n<ExamplesExample file=\"v-progress/slot-label-and-value\" />\n\n### Misc\n\n#### Card loader\n\nUse the **#default** slot to replace the built-in progress indicator with your own. The slot exposes `percent` and other scoped props for custom rendering.\n\n<ExamplesExample file=\"v-progress/misc-card-loader\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/pull-to-refresh.md",
    "content": "---\nmeta:\n  title: Pull To Refresh\n  description: The PullToRefresh allows users to update content with a simple downward swipe on their screen.\n  keywords: Pull to refresh, vuetify Pull to refresh component, vue pull to refresh component\nfeatures:\n  label: 'C: VPullToRefresh'\n  github: /components/VPullToRefresh/\n  report: true\n---\n\n# Pull To Refresh\n\nThe PullToRefresh allows users to update content with a simple downward swipe on their screen. Works for Mobile and Desktop.\n\n<PageFeatures />\n\n## Installation\n\nLabs components require manual import and registration with the Vuetify instance.\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { VPullToRefresh } from 'vuetify/labs/VPullToRefresh'\n\nexport default createVuetify({\n  components: {\n    VPullToRefresh,\n  },\n})\n```\n\n## Usage\n\nDrag the list downward to activate the pull-to-refresh feature.\n\n<ExamplesExample file=\"v-pull-to-refresh/usage\" />\n\n::: tip\n\nPull down functionality is available as soon as its immediate scrollable parent has scrolled to the top.\n\n:::\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-pull-to-refresh](/api/v-pull-to-refresh/) | Primary Component |\n\n<ApiInline hide-links />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/radio-buttons.md",
    "content": "---\nmeta:\n  nav: Radio buttons\n  title: Radio button component\n  description: A radio button allows the user to choose only one of a set of options using a radio group.\n  keywords: radio groups, radio buttons, vuetify radio group component, vuetify radio component, vue radio component, vue radio group component\nrelated:\n  - /components/button-groups/\n  - /components/forms/\n  - /components/checkboxes/\nfeatures:\n  label: 'C: VRadio'\n  report: true\n  github: /components/VRadio/\n  spec: https://m2.material.io/components/radio-buttons\n---\n\n# Radio buttons\n\nThe `v-radio` component is a simple radio button. When combined with  the `v-radio-group` component you can provide grouping functionality to allow users to select from a predefined set of options.\n\n<PageFeatures />\n\n## Usage\n\nAlthough `v-radio` can be used on its own, it is best used in conjunction with `v-radio-group`.\n\n<ExamplesUsage name=\"v-radio-group\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-radio-group](/api/v-radio-group/) | Primary Component |\n| [v-radio](/api/v-radio/) | Sub-component used for modifying the `v-radio-group` state |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n#### Model (group)\n\nUsing the **v-model** (or **model-value**) you can access and control the selected radio button defined by the set **value** on the child `v-radio` components.\n\n<ExamplesExample file=\"v-radio-group/prop-model-group\" />\n\n::: info\n  If you are using integer values with **model-value**, you will need to use `:value` to set the value of the child `v-radio` otherwise it will be evaluated as a string.\n:::\n\n#### Model (radio)\n\nThe **v-model** (or **model-value**) you can access and control the value of a single radio button. The `true`/`false` values can be independently defined using the **true-value** and **false-value** props.\n\n<ExamplesExample file=\"v-radio-group/prop-model-radio\" />\n\n#### Colors\n\nRadios can be colored by using any of the builtin colors and contextual names using the **color** prop.\n\n<ExamplesExample file=\"v-radio-group/prop-colors\" />\n\n#### Direction\n\nRadio-groups can be presented either as a row or a column, using their respective props. The default is as a column.\n\n<ExamplesExample file=\"v-radio-group/prop-direction\" />\n\n### Slots\n\n#### Label\n\nRadio Group labels can be defined in `label` slot - that will allow to use HTML content.\n\n<ExamplesExample file=\"v-radio-group/slot-label\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/range-sliders.md",
    "content": "---\nmeta:\n  nav: Range sliders\n  title: Range Slider component\n  description: The range slider component is a better visualization of the number input. It is used for gathering a range of numerical user data.\n  keywords: sliders, range, vuetify slider component, vuetify range slider component, vue slider component\nrelated:\n  - /components/forms/\n  - /components/selects/\n  - /components/sliders/\nfeatures:\n  label: 'C: VRangeSlider'\n  report: true\n  github: /components/VRangeSlider/\n  spec: https://m2.material.io/components/sliders\n---\n\n# Range Sliders\n\nThe `v-range-slider` component complements the `v-slider` component nicely when you are in need of representing a range of values.\n\n<PageFeatures />\n\n## Usage\n\nSliders reflect a range of values along a bar, from which users may select a single value. They are ideal for adjusting settings such as volume, brightness, or applying image filters.\n\n<ExamplesUsage name=\"v-range-slider\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-range-slider](/api/v-range-slider/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n#### Strict\n\nWith the **strict** prop applied, the thumbs of the range slider are not allowed to cross over each other.\n\n<ExamplesExample file=\"v-range-slider/prop-strict\" />\n\n#### Disabled\n\nYou cannot interact with **disabled** sliders.\n\n<ExamplesExample file=\"v-range-slider/prop-disabled\" />\n\n#### Min and max\n\nYou can set **min** and **max** values of sliders.\n\n<ExamplesExample file=\"v-range-slider/prop-min-and-max\" />\n\n#### Step\n\n`v-range-slider` can have steps other than 1. This can be helpful for some applications where you need to adjust values with more or less accuracy.\n\n<ExamplesExample file=\"v-range-slider/prop-step\" />\n\n#### Vertical sliders\n\nYou can use the **vertical** prop to switch sliders to a vertical orientation.\nIf you need to change the height of a vertical slider, be aware that `v-range-slider` is not a simple HTML element. This means plain CSS on the component will not affect the correct internal element. Instead, you must use a **deep selector**.\n\n<ExamplesExample file=\"v-range-slider/prop-vertical\" />\n\n::: tip\n\nThe `:deep()` pseudo-class allows scoped styles to affect child components, which is why it works for resizing the slider.\nSee the official Vue documentation for more details: [Scoped CSS and :deep selectors](https://vuejs.org/api/sfc-css-features.html#scoped-css)\n\n:::\n\n### Slots\n\n#### Thumb label\n\nUsing the **tick-labels** prop along with the `thumb-label` slot, you can create a very customized solution.\n\n<ExamplesExample file=\"v-range-slider/slot-thumb-label\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/ratings.md",
    "content": "---\nmeta:\n  nav: Ratings\n  title: Rating component\n  description: The star rating component is a specialized widget for collecting user feedback via ratings.\n  keywords: star ratings, vuetify star rating component, vue star rating component, rating component\nrelated:\n  - /components/cards\n  - /components/icons\n  - /components/lists\nfeatures:\n  github: /components/VRating/\n  label: 'C: VRating'\n  report: true\n---\n\n# Ratings\n\nThe `v-rating` component is a specialized but important piece in building user widgets. Collecting user feedback via ratings is a simple analytic that can provide a lot of feedback to your product or application.\n\n<PageFeatures />\n\n## Usage\n\nThe `v-rating` component provides a simple interface for gathering user feedback.\n\n<ExamplesUsage name=\"v-rating\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-rating](/api/v-rating/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n#### Color\n\nThe `v-rating` component can be colored as you want, you can set both selected and not selected colors.\n\n<ExamplesExample file=\"v-rating/prop-color\" />\n\n#### Density\n\nControl the space occupied by `v-rating` items using the **density** prop.\n\n<ExamplesExample file=\"v-rating/prop-density\" />\n\n#### Clearable\n\nClicking on a current rating value can reset the rating by using **clearable** prop.\n\n<ExamplesExample file=\"v-rating/prop-clearable\" />\n\n#### Readonly\n\nFor ratings that are not meant to be changed you can use **readonly** prop.\n\n<ExamplesExample file=\"v-rating/prop-readonly\" />\n\n#### Hover effect\n\nWhen using the **hover** prop, the rating icons will become a solid color and slightly increase its scale when the mouse is hovered over them.\n\n<ExamplesExample file=\"v-rating/prop-hover\" />\n\n#### Labels\n\nThe `v-rating` component can display labels above or below each item.\n\n<ExamplesExample file=\"v-rating/prop-item-labels\" />\n\n#### Icons\n\nYou can use custom icons.\n\n<ExamplesExample file=\"v-rating/prop-icons\" />\n\n#### Length\n\nChange the number of items by modifying the the **length** prop.\n\n<ExamplesExample file=\"v-rating/prop-length\" />\n\n#### Half increments\n\nThe **half-increments** prop increases the granularity of the ratings, allow for `.5` values as well.\n\n<ExamplesExample file=\"v-rating/prop-half-increments\" />\n\n#### Size\n\nUtilize the same sizing classes available in `v-icon` or provide your own with the **size** prop.\n\n<ExamplesExample file=\"v-rating/prop-size\" />\n\n#### Aria Label\n\nProvide a label to assistive technologies for each item.\n\n<ExamplesExample file=\"v-rating/prop-icon-label\" />\n\n### Slots\n\n#### Item slot\n\nSlots enable advanced customization possibilities and provide you with more freedom in how you display the rating.\n\n<ExamplesExample file=\"v-rating/slot-item\" />\n\n#### Custom labels slot\n\nAny arbitrary content could be displayed for labels in **item-label** slot.\n\n<ExamplesExample file=\"v-rating/slot-item-label\" />\n\n### Misc\n\n<!-- #### Advanced usage\n\nThe `v-rating` component fits right in with existing components. Build truly complex examples with rich features and beautiful designs.\n\n<ExamplesExample file=\"v-rating/misc-advanced\" /> -->\n\n#### Card ratings\n\nThe rating component pairs well with products allowing you to gather and display customer feedback.\n\n<ExamplesExample file=\"v-rating/misc-card\" />\n\n<ExamplesExample file=\"v-rating/misc-card-overview\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/selects.md",
    "content": "---\nmeta:\n  nav: Selects\n  title: Select component\n  description: The select component provides a list of options that a user can make selections from.\n  keywords: selects, vuetify select component, vue select component\nrelated:\n  - /components/autocompletes/\n  - /components/combobox/\n  - /components/forms/\nfeatures:\n  label: 'C: VSelect'\n  report: true\n  github: /components/VSelect/\n  spec: https://m2.material.io/components/text-fields\n---\n\n# Selects\n\nSelect fields components are used for collecting user provided information from a list of options.\n\n<PageFeatures />\n\n## Usage\n\n<ExamplesUsage name=\"v-select\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-select](/api/v-select/) | Primary Component |\n| [v-autocomplete](/api/v-autocomplete/) | A select component that allows for advanced filtering |\n| [v-combobox](/api/v-combobox/) | A select component that allows for filtering and custom values |\n\n<ApiInline hide-links />\n\n## Caveats\n\n::: error\n\nWhen using objects for the **items** prop, you must associate **item-title** and **item-value** with existing properties on your objects. These values are defaulted to **title** and **value** and can be changed.\n\n:::\n\n## Guide\n\nThe `v-select` component is meant to be a direct replacement for a standard `<select>` element. It is commonly used with [v-form](/components/forms/) and other inputs & controls.\n\n### Props\n\nAll form inputs have a massive API that make it super easy to configure everything just the way you want it.\n\n#### Density\n\nYou can use **density** prop to adjust vertical spacing within the component.\n\n<ExamplesExample file=\"v-select/prop-dense\" />\n\n#### Multiple\n\nThe **multiple** prop allows for multiple selections.\n\n<ExamplesExample file=\"v-select/prop-multiple\" />\n\n#### Chips\n\nDisplay selected items as chips with the **chips** prop.\n\n<ExamplesExample file=\"v-select/prop-chips\" />\n\n#### Readonly\n\nYou can use the **readonly** prop on `v-select` which will prevent a user from changing its value.\n\n<ExamplesExample file=\"v-select/prop-readonly\" />\n\n#### Disabled\n\nApplying the **disabled** prop to a `v-select` will prevent a user from interacting with the component.\n\n<ExamplesExample file=\"v-select/prop-disabled\" />\n\n#### Custom title and value\n\nYou can specify the specific properties within your items array that correspond to the title and value fields. By default, this is **title** and **value**. In this example we also use the **return-object** prop which will return the entire object of the selected item on selection.\n\n<ExamplesExample file=\"v-select/prop-custom-title-and-value\" />\n\nWhen customizing items with the `item` slot, you should disable the default `title` prop rendering to avoid duplicate text.\nYou can do this by setting `:title=\"null\"` on `v-list-item`.\n\n<ExamplesExample file=\"v-select/prop-avoid-duplicate-text\" />\n\n#### Menu props\n\nCustom props can be passed directly to `v-menu` using **menu-props** prop. In this example a scrim as added to the select and the menu closes when you scroll.\n\n<ExamplesExample file=\"v-select/prop-menu-props\" />\n\n#### List props\n\nCustom props can be passed directly to `v-list` using **list-props** prop. In this example a background color is added to the list.\n\n<ExamplesExample file=\"v-select/prop-list-props\" />\n\n#### Custom item props\n\n`item-title` and `item-value` are provided for convenience, and additional props can be passed to list items either through the **item** slot (see below) or with the **itemProps** prop.\nSimilar to title and value, it has a default value of `\"props\"`, which will pass everything in the `props` key of each item object to the list item.\n\n```js\nconst items = [\n  {\n    title: 'John',\n    props: { subtitle: 'Engineering' },\n  },\n]\n```\n\n`:item-props=\"true\"` will use the entire item object as props. This overrides `item-title` and `item-value`.\n\n```js\nconst items = [\n  {\n    title: 'John',\n    subtitle: 'Engineering',\n  },\n]\n```\n\nOr a custom transform function can be passed to `itemProps` to generate the props for each item.\n\n<ExamplesExample file=\"v-select/prop-item-props\" />\n\nSee the [VListItem API](/api/v-list-item/) for a list of available props.\n\n### Slots\n\nThe `v-select` component offers slots that make it easy to customize the output of certain parts of the component. This includes the **prepend** and **append** slots, the **selection** slot, and the **no-data** slot.\n\n#### Item\n\nThe item slot is used to change how items are rendered in the list. It provides `item`, an [InternalItem](/api/v-select/#slots-item) object containing the transformed item-title and item-value; and `props`, an object containing the props and events that would normally be bound to the list item.\n\n<ExamplesExample file=\"v-select/slot-item\" />\n\n#### Append and prepend item\n\nThe `v-select` component can be optionally expanded with prepended and appended items. This is perfect for customized **select-all** functionality.\n\n<ExamplesExample file=\"v-select/slot-append-and-prepend-item\" />\n\n#### Selection\n\nThe **selection** slot can be used to customize the way selected values are shown in the input. This is great when you don't want the selection to occupy multiple lines.\n\n<ExamplesExample file=\"v-select/slot-selection\" />\n\n#### Menu header and footer\n\nThe **menu-header** and **menu-footer** slots allow you to add custom content at the top and bottom of the dropdown menu. This is useful for adding search fields, action buttons, or any other controls.\n\n<ExamplesExample file=\"v-select/slot-menu-header-and-footer\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/sheets.md",
    "content": "---\nmeta:\n  nav: Sheets\n  title: Sheet component\n  description: The sheet component is the baseline for many Material Design implementations used in Vuetify.\n  keywords: sheets, vuetify sheet component, vue sheet component, paper, material design paper, material design sheets\nrelated:\n  - /components/cards\n  - /components/grids\n  - /styles/elevation\nfeatures:\n  github: /components/VSheet/\n  label: 'C: VSheet'\n  report: true\n  spec: https://m2.material.io/design/environment/elevation.html\n---\n\n# Sheets\n\nThe `v-sheet` component is a transformable piece of _paper_ that provides a basic foundation for Vuetify features.\n\n<PageFeatures />\n\n## Usage\n\nThe sheet component has support for elevation, rounded corners, color, and more. It can be used as a container for other components or as a standalone.\n\n<ExamplesUsage name=\"v-sheet\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-sheet](/api/v-sheet/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Anatomy\n\nThe `v-sheet` component contains only a default slot.\n\n![Sheet Anatomy](https://cdn.vuetifyjs.com/docs/images/components/v-sheet/v-sheet-anatomy.png)\n\n| Element / Area | Description |\n| - | - |\n| 1. Container | The main content area |\n\n## Guide\n\nOften when building out a user interface, you will need to create a container for content and other custom components. The `v-sheet` component is a great way to do this. It provides a baseline for elevation, rounded corners, and color.\n\n### Props\n\nSome of the standard props that can be applied to the `v-sheet` component are listed below.\n\n#### Elevation\n\nThe `v-sheet` component accepts a custom elevation between **0** and **5** (0 is default). The _elevation_ property modifies the `box-shadow` property.\n\n<ExamplesExample file=\"v-sheet/prop-elevation\" />\n\n#### Rounded\n\nThe **rounded** prop adds a default `border-radius` of _4px_. By default, the `v-sheet` component has no border-radius. Customize the radius's size and location by providing a custom rounded value; e.g. a rounded value of _tr-xl l-pill_ equates to _rounded-tr-xl rounded-l-pill_. Additional information is on the [Border Radius](/styles/border-radius/) page.\n\n<ExamplesExample file=\"v-sheet/prop-rounded\" />\n\n#### Color\n\nSheets and components based on them can have different sizes and colors.\n\nThe `v-sheet` component accepts custom [Material Design Color](/styles/colors/) values such as `warning`, `amber darken-3`, and `deep-purple accent` — as well as _rgb_, _rgba_, and _hexadecimal_ values.\n\n<ExamplesExample file=\"v-sheet/prop-color\" />\n\n## Examples\n\nThe following are a collection of examples that demonstrate more advanced and real world use of the `v-sheet` component.\n\n### Congratulations\n\nThis example uses a sheet component to create a banner congratulating users for signing up for the Vuetify community.\n\n<ExamplesExample file=\"v-sheet/misc-congratulations\" />\n\n### Reconcile Notification\n\nThe following example uses a sheet component to create a banner that notifies users that the account balance has been reconciled.\n\n<ExamplesExample file=\"v-sheet/misc-reconcile\" />\n\n### Privacy Policy\n\nCreating a Privacy Policy notification is a great use case for the `v-sheet` component.\n\n<ExamplesExample file=\"v-sheet/misc-privacy-policy\" />\n\n### Referral program\n\nEven for simple use-cases, the `v-sheet` component is versatile makes it easy to contain content and other components.\n\n<ExamplesExample file=\"v-sheet/misc-referral-program\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/skeleton-loaders.md",
    "content": "---\nmeta:\n  nav: Skeleton loaders\n  title: Skeleton loader component\n  description:  The skeleton loader component provides a placeholder loading state for when content is being fetched from a server or loaded asynchronously. It can be used in a variety of contexts, including cards, lists, and tables.\n  keywords: skeleton loaders, vuetify skeleton loader component, vue skeleton loader\nrelated:\n  - /components/cards/\n  - /components/progress-circular/\n  - /components/buttons/\nfeatures:\n  figma: true\n  label: 'C: VSkeletonLoader'\n  github: /components/VSkeletonLoader/\n  report: true\n---\n\n# Skeleton loaders\n\nSkeleton loaders provide a simple way to display loading placeholders in your application.\n\n<PageFeatures />\n\n## Usage\n\nThe `v-skeleton-loader` component provides a user with a visual indicator that content is coming / loading. This is better received than traditional full-screen loaders.\n\n<ExamplesUsage name=\"v-skeleton-loader\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-skeleton-loader](/api/v-skeleton-loader/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Anatomy\n\nThe `v-skeleton-loader` has a default slot that is rendered when the component is not in a loading state.\n\n![Skeleton loader Anatomy](https://cdn.vuetifyjs.com/docs/images/components-temp/v-skeleton-loader/v-skeleton-loader-anatomy.png)\n\n| Element / Area | Description |\n| - | - |\n| 1. Container | The container is the root element of the component. |\n\n## Guide\n\nThe `v-skeleton-loader` component can be used in a variety of contexts, including cards, lists, and tables. It can be used to create a placeholder loading state for when content is being fetched from a server or loaded asynchronously.\n\nThe following code snippet is an example of a basic `v-skeleton-loader` component. When no **type** property is provided, the component will default to an **image** type.\n\n```html\n<v-skeleton-loader></v-skeleton-loader>\n```\n\n### Props\n\nThe `v-skeleton-loader` component has a small API mainly used to configure the root and item height.\n\n#### Type\n\nThe **type** property is used to define the type of skeleton loader. Types can be combined to create more complex skeletons. For example, the **card** type is a combination of the **image** and **heading** types.\n\n<ExamplesExample file=\"v-skeleton-loader/prop-type\" />\n\nThe following built-in types are available:\n\n| Type | Composition |\n| - | - |\n| **actions** | button@2 |\n| **article** | heading, paragraph |\n| **avatar** | avatar |\n| **button** | button |\n| **card** | image, heading |\n| **card-avatar** | image, list-item-avatar |\n| **chip** | chip |\n| **date-picker** | list-item, heading, divider, date-picker-options, date-picker-days, actions |\n| **date-picker-options** | text, avatar@2 |\n| **date-picker-days** | avatar@28 |\n| **divider** | divider |\n| **heading** | heading |\n| **image** | image |\n| **list-item** | text |\n| **list-item-avatar** | avatar, text |\n| **list-item-two-line** | sentences |\n| **list-item-avatar-two-line** | avatar, sentences |\n| **list-item-three-line** | paragraph |\n| **list-item-avatar-three-line** | avatar, paragraph |\n| **ossein** | ossein |\n| **paragraph** | text@3 |\n| **sentences** | text@2 |\n| **subtitle** | text |\n| **table** | table-heading, table-thead, table-tbody, table-tfoot |\n| **table-heading** | heading, text |\n| **table-thead** | heading@6 |\n| **table-tbody** | table-row-divider@6 |\n| **table-row-divider** | table-row, divider |\n| **table-row** | text@6 |\n| **table-tfoot** | text@2, avatar@2 |\n| **text** | text |\n\n#### Loading\n\nA skeleton loader is considered to be in a loading state if one of the following conditions are met:\n\n* The default slot is not used\n* The **loading** property is set to **true**\n\nIf either condition is met, the skeleton loader returns the type structure in place of the default slot and applies dimensions values; e.g. **height**, **width**, **min-height**, etc. If the condition is not met, the default slot is returned.\n\n<ExamplesExample file=\"v-skeleton-loader/prop-loading\" />\n\n#### Elevation\n\nThe **elevation** property makes it easy to match the elevation of the skeleton loader to the content it is replacing.\n\n<ExamplesExample file=\"v-skeleton-loader/prop-elevation\" />\n\n#### Boilerplate\n\nThe `v-skeleton-loader` can be used as boilerplate designs when creating mockups. Mix and match various pre-defined options or create your own unique implementations. In this example, we use a custom **data** property to apply the same props to multiple `v-skeleton-loader`'s at once.\n\n<ExamplesExample file=\"v-skeleton-loader/prop-boilerplate\" />\n\n## Examples\n\nThe following are a collection of examples that demonstrate more advanced and real world use of the `v-skeleton-loader` component.\n\n### Ice-cream suggestions\n\nThe following example demonstrates how the `v-skeleton-loader` component can be used to create a placeholder loading state for when content is being fetched from a server or loaded asynchronously.\n\n<ExamplesExample file=\"v-skeleton-loader/misc-ice-cream\" />\n\n## SASS Variables\n\nMake fine tuned changes by modifying the `v-skeleton-loader` [SASS variables](/features/sass-variables). This is useful when you want to change the default button height or padding.\n\n```scss { resource=\"src/settings.scss\" }\n@use 'vuetify/settings' with (\n  $skeleton-loader-gutter: 24px,\n  $skeleton-loader-button-width: 80px,\n);\n```\n\nFor a list of all available SASS variables, navigate to the [v-skeleton-loader](/api/v-skeleton-loader/#sass) API page.\n\n## Accessibility\n\nBy default, the `v-skeleton-loader` component is assigned a [WAI-ARIA](https://www.w3.org/WAI/standards-guidelines/aria/) role of [**alert**](https://www.w3.org/TR/wai-aria/#alert). We augment this role with three aria properties. An [**aria-busy**](https://www.w3.org/TR/wai-aria-1.0/states_and_properties#aria-busy) value of **true** denotes that a widget is missing required owned elements. An [**aria-live**](https://www.w3.org/TR/wai-aria-1.1/#aria-live) value of **polite** sets the screen reader's priority of live regions. And finally, [**aria-label**](https://www.w3.org/TR/WCAG20-TECHS/ARIA6.html), which is used to provide a human readable description of the element.\n\n### Configuring the aria-label\n\nConfigure the default text used in the `v-skeleton-loader` component in the locale options. The following example demonstrates how to update the **loading-text** property:\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createVuetify } from 'vuetify'\n\nexport default createVuetify({\n  locale: {\n    messages: {\n      loading: 'Loading content...',\n    },\n  },\n})\n```\n\nNavigate to the [Internationalization (i18n)](/features/internationalization/) page for more information on how to configure the locale options.\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/slide-groups.md",
    "content": "---\nmeta:\n  nav: Slide groups\n  title: Slide group component\n  description: The slide group component is similar to item groups in that you can make selectable content out of elements but does so in a single line fashion.\n  keywords: slide groups, slideable groups, vuetify slide group component, vue slide group component\nrelated:\n  - /components/icons/\n  - /components/carousels/\n  - /components/tabs/\nfeatures:\n  github: /components/VSlideGroup/\n  label: 'C: VSlideGroup'\n  report: true\n---\n\n# Slide groups\n\nThe `v-slide-group` component is used to display pseudo paginated information. It uses [v-item-group](/components/item-groups) at its core and provides a baseline for components such as [v-tabs](/components/tabs) and [v-chip-group](/components/chip-groups).\n\n<PageFeatures />\n\n## Usage\n\nSimilar to the [v-window](/components/windows) component, `v-slide-group` lets items to take up as much space as needed, allowing the user to move horizontally through the provided information.\n\n<ExamplesExample file=\"v-slide-group/usage\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-slide-group](/api/v-slide-group/) | Primary Component |\n| [v-slide-group-item](/api/v-slide-group-item/) | Sub-component used for modifying the `v-slide-group` state |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n#### Selected class\n\n**selected-class** prop allows you to pass a class to customize the active items.\n\n<ExamplesExample file=\"v-slide-group/prop-active-class\" />\n\n#### Center active\n\nUsing the **center-active** prop will make the active item always centered.\n\n<ExamplesExample file=\"v-slide-group/prop-center-active\" />\n\n#### Custom icons\n\nYou can add your custom pagination icons instead of arrows using the **next-icon** and **prev-icon** props.\n\n<ExamplesExample file=\"v-slide-group/prop-custom-icons\" />\n\n### Mandatory\n\nthe **mandatory** prop will make the slide group require at least 1 item must be selected.\n\n<ExamplesExample file=\"v-slide-group/prop-mandatory\" />\n\n#### Multiple\n\nYou can select multiple items by setting the **multiple** prop.\n\n<ExamplesExample file=\"v-slide-group/prop-multiple\" />\n\n### Misc\n\n#### Pseudo Carousel\n\nCustomize the slide group to creatively display information on sheets. Using the selection, we can display auxiliary information easily for the user.\n\n<ExamplesExample file=\"v-slide-group/misc-pseudo-carousel\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/sliders.md",
    "content": "---\nmeta:\n  nav: Sliders\n  title: Slider component\n  description: The slider component can be used as an alternative visualization instead of a number input.\n  keywords: sliders, vuetify slider component, vue slider component\nrelated:\n  - /components/forms/\n  - /components/selects/\n  - /components/range-sliders/\nfeatures:\n  label: 'C: VSlider'\n  report: true\n  github: /components/VSlider/\n  spec: https://m2.material.io/components/sliders\n---\n\n# Sliders\n\nThe `v-slider` component can be used as an alternative visualization instead of a number input.\n\n<PageFeatures />\n\n## Usage\n\nSliders reflect a range of values along a track, from which users may select a single value. They are ideal for adjusting settings such as volume, brightness, or applying image filters.\n\n<ExamplesUsage name=\"v-slider\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-slider](/api/v-slider/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n#### Colors\n\nYou can set the colors of the slider using the props **color**, **track-color** and **thumb-color**.\n\n<ExamplesExample file=\"v-slider/prop-colors\" />\n\n#### Disabled\n\nYou cannot interact with **disabled** sliders.\n\n<ExamplesExample file=\"v-slider/prop-disabled\" />\n\n#### Step\n\nUsing the **step** prop you can control the precision of the slider, and how much it should move each step.\n\n<ExamplesExample file=\"v-slider/prop-step\" />\n\n#### Icons\n\nYou can add icons to the slider with the **append-icon** and **prepend-icon** props. With `@click:append` and `@click:prepend` you can trigger a callback function when click the icon.\n\n<ExamplesExample file=\"v-slider/prop-icons\" />\n\n#### Min and max\n\nYou can set **min** and **max** values of sliders.\n\n<ExamplesExample file=\"v-slider/prop-min-and-max\" />\n\n#### Readonly\n\nYou cannot interact with **readonly** sliders, but they look as ordinary ones.\n\n<ExamplesExample file=\"v-slider/prop-readonly\" />\n\n#### Thumb\n\nYou can display a thumb label while sliding or always with the **thumb-label** prop . It can have a custom color by setting **thumb-color** prop and a custom size with the **thumb-size** prop.\n\n<ExamplesExample file=\"v-slider/prop-thumb\" />\n\n#### Ticks\n\nTick marks represent predetermined values to which the user can move the slider.\n\n<ExamplesExample file=\"v-slider/prop-ticks\" />\n\n<!-- #### Validation\n\nVuetify includes simple validation through the **rules** prop. The prop accepts a mixed array of types `function`, `boolean` and `string`. When the input value changes, each element in the array will be validated. Functions pass the current v-model as an argument and must return either `true` / `false` or a `string` containing an error message.\n\n<ExamplesExample file=\"v-slider/prop-validation\" /> -->\n\n#### Vertical sliders\n\nYou can use the **direction** prop to switch sliders to a vertical orientation. If you need to change the height of the slider, use css.\n\n<ExamplesExample file=\"v-slider/prop-vertical\" />\n\n### Slots\n\n#### Append and prepend\n\nUse slots such as `append` and `prepend` to easily customize the `v-slider` to fit any situation.\n\n<ExamplesExample file=\"v-slider/slot-append-and-prepend\" />\n\n#### Append text field\n\nSliders can be combined with other components in its `append` slot, such as `v-text-field`, to add additional functionality to the component.\n\n<ExamplesExample file=\"v-slider/slot-append-text-field\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/snackbar-queue.md",
    "content": "---\nemphasized: true\nmeta:\n  nav: Snackbar Queue\n  title: Snackbar Queue component\n  description: test\n  keywords: test\nrelated:\n  - /components/buttons/\n  - /components/snackbars/\n  - /components/defaults-providers/\nfeatures:\n  github: /components/VSnackbarQueue/\n  label: 'C: VSnackbarQueue'\n  report: true\n  spec: https://m3.material.io/components/snackbar\n---\n\n# Snackbar Queue\n\nThe `v-snackbar-queue` component is used to display a sequence of messages to the user.\n\n<PageFeatures />\n\n## Usage\n\nMessages are passed as an array of strings to `v-model`, when a message is displayed it will be removed from the start of the array.\n\n<ExamplesUsage name=\"v-snackbar-queue\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-snackbar-queue](/api/v-snackbar-queue/) | Primary Component |\n| [v-snackbar](/api/v-snackbar/) | The actual Snackbar Component |\n\n<ApiInline hide-links />\n\n## Examples\n\n::: info\nSome examples below use the **contained** prop and direct **z-index** values to keep snackbars scoped within the example preview. In a real application you typically don't need either — snackbars render in the application overlay by default.\n:::\n\n### Props\n\n#### Total visible\n\nThe **total-visible** prop controls how many snackbars are shown simultaneously, stacked vertically with automatic offset. The **display-strategy** prop determines what happens when the queue exceeds this limit: `\"hold\"` (default) pauses the queue until a visible slot opens, while `\"overflow\"` immediately shows new messages and dismisses the oldest ones. Enable the **collapsed** prop to visually compress the stack into a single snackbar with a counter badge.\n\n<ExamplesExample file=\"v-snackbar-queue/prop-total-visible\" />\n\n#### Transition\n\nUse the **transition** prop to change the enter/leave animation. If you pass CSS-based animation with suffix `*-auto` (e.g. `\"slide-auto\"`, `\"scroll-auto\"`) the effective transition will be location-aware. To present it more clearly, the example below uses custom \"bouncy-slide\" transition.\n\n<ExamplesExample file=\"v-snackbar-queue/prop-transition\" />\n\n### Misc\n\n#### Promise\n\nMessages can include a **promise** property along with **success** and **error** callbacks. The snackbar shows a loading state until the promise resolves or rejects, then updates accordingly.\n\n<ExamplesExample file=\"v-snackbar-queue/misc-promise\" />\n\n### Additional props\n\nSnackbar props can be set either on the queue to apply to all messages:\n\n```html\n<v-snackbar-queue timeout=\"2000\" color=\"error\" />\n```\n\nOr individual messages as objects:\n\n```js\nqueue.push({\n  text: text.value,\n  timeout: 2000,\n  color: 'error',\n})\n```\n\n### Global state\n\nYou can use pinia or vuex to display messages from any component:\n\n```js { resource=\"stores/messages.js\" }\nexport const useMessagesStore = defineStore('messages', () => {\n  const queue = ref([])\n  function add (message) {\n    queue.push(message)\n  }\n\n  return { queue, add }\n})\n```\n\n```html { resource=\"App.vue\" }\n<template>\n  <v-app>\n    <router-view></router-view>\n\n    <v-snackbar-queue v-model=\"messages.queue\"></v-snackbar-queue>\n  </v-app>\n</template>\n\n<script setup>\n  const messages = useMessagesStore()\n</script>\n```\n\n```html { resource=\"pages/error.vue\" }\n<script setup>\n  const messages = useMessagesStore()\n\n  function onError (err) {\n    messages.add({ text: err.message, color: 'error' })\n  }\n</script>\n```\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/snackbars.md",
    "content": "---\nemphasized: true\nmeta:\n  nav: Snackbars\n  title: Snackbar component\n  description: The snackbar component informs user of a process that your application has performed is will perform. It can be temporary and often contains actions. Timer will stop when user hovers over the snackbar.\n  keywords: snackbars, vuetify snackbar component, vue snackbar component\nrelated:\n  - /components/buttons/\n  - /styles/colors/\n  - /components/forms/\nfeatures:\n  github: /components/VSnackbar/\n  label: 'C: VSnackbar'\n  report: true\n  spec: https://m3.material.io/components/snackbar\n---\n\n# Snackbars\n\nThe `v-snackbar` component is used to display a quick message to a user. Snackbars support positioning, removal delay, and callbacks.\n\n<PageFeatures />\n\n## Usage\n\na `v-snackbar` in its simplest form displays a temporary and closable notification to the user.\n\n<ExamplesExample file=\"v-snackbar/usage\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-snackbar](/api/v-snackbar/) | Primary Component |\n| [v-btn](/api/v-btn/) | Sub-component typically used for actions |\n\n<ApiInline hide-links />\n\n## Examples\n\n::: info\nSome examples below use the **contained** prop to keep snackbars scoped within the example preview. In a real application you typically don't need it — snackbars render in the application overlay by default.\n:::\n\n### Props\n\n#### Timeout\n\nThe **timeout** property lets you customize the delay before the `v-snackbar` is hidden.\n\n<ExamplesExample file=\"v-snackbar/prop-timeout\" />\n\n#### Variants\n\nUse the **variant** and **rounded** prop to apply distinct look and shape to the snackbar. Transparent variants such as `tonal` and `outlined` render with a surface background to remain legible against the page.\n\n<ExamplesExample file=\"v-snackbar/prop-variants\" />\n\n#### Prepend icon\n\nThe **prepend-icon** prop adds an icon to the start of the snackbar.\n\n<ExamplesExample file=\"v-snackbar/prop-prepend-icon\" />\n\n#### Prepend avatar\n\nThe **prepend-avatar** prop adds an avatar image to the start of the snackbar.\n\n<ExamplesExample file=\"v-snackbar/prop-prepend-avatar\" />\n\n#### Loading\n\nThe **loading** prop displays a circular progress indicator in the prepend area, useful for indicating an ongoing process.\n\n<ExamplesExample file=\"v-snackbar/prop-loading\" />\n\n#### Timer position\n\nThe **timer** prop accepts `'top'` or `'bottom'` to control where the progress bar is rendered. Use **timer-color** to change its color and **reverse-timer** to invert the direction.\n\n<ExamplesExample file=\"v-snackbar/prop-timer-position\" />\n\n#### Vertical\n\nThe **vertical** property allows you to stack the content of your `v-snackbar`.\n\n<ExamplesExample file=\"v-snackbar/prop-vertical\" />\n\n### Slots\n\n#### Header\n\nThe **header** slot renders content above the snackbar wrapper, useful for metadata like a provider name or timestamp.\n\n<ExamplesExample file=\"v-snackbar/slot-header\" />\n\n#### Prepend\n\nThe **prepend** slot overrides the default prepend area, allowing you to customize the content beyond what is possible with simple props.\n\n<ExamplesExample file=\"v-snackbar/slot-prepend\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/sparklines.md",
    "content": "---\nmeta:\n  title: Sparklines\n  description: The sparkline component creates beautiful and expressive simple graphs for displaying numerical data.\n  keywords: sparklines, vuetify sparkline component, vue sparkline component, sparkline, graph, chart, line\nrelated:\n  - /components/cards/\n  - /components/sheets/\n  - /components/expansion-panels/\nfeatures:\n  github: /components/VSparkline/\n  label: 'C: VSparkline'\n  report: true\n---\n\n# Sparklines\n\nThe sparkline component can be used to create simple graphs, like GitHub's contribution chart.\n\n<PageFeatures />\n\n## Usage\n\nA sparkline is a tiny chart that provides a visual representation of data. The sparkline component comes in 2 variations, **trend** (default) and **bar**. Each supports a multitude of options for customizing the look and feel of the sparkline.\n\n<ExamplesExample file=\"v-sparkline/usage\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-sparkline](/api/v-sparkline/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n#### Fill\n\nYou can create a `v-sparkline` with fill using the `fill` property.\n\n<ExamplesExample file=\"v-sparkline/prop-fill\" />\n\n### Misc\n\n#### Custom labels\n\nBy providing a **label** slot, we are able to modify the displayed content by adding a dollar sign ($). This slot is **_exclusively_** for text content. For more information on the svg `<text>` element, [navigate here](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/text).\n\n<ExamplesExample file=\"v-sparkline/misc-custom-labels\" />\n\n#### Dashboard card\n\nThe `v-sparkline` component pairs nicely with `v-card` and `v-sheet` to create customized information cards, perfect for admin dashboards. Here we use custom labels to provide additional context for the sparkline.\n\n<ExamplesExample file=\"v-sparkline/misc-dashboard-card\" />\n\n#### Heart rate\n\nFor concise information, a complete chart might be overkill. Using a trend line with gradient provides enough detail for the user without showing too much information.\n\n<ExamplesExample file=\"v-sparkline/misc-heart-rate\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/speed-dials.md",
    "content": "---\nmeta:\n  nav: Speed Dials\n  title: Speed Dial component\n  description: The speed dial component is a floating action button that can reveal additional actions when clicked.\n  keywords: speed dial, fab, vuetify speed dial component, vue speed dial component\nrelated:\n  - /components/buttons/\n  - /components/icons/\n  - /styles/transitions/\nfeatures:\n  report: true\n  github: /components/VSpeedDial/\n  label: 'C: VSpeedDial'\n---\n\n# Speed Dials\n\nThe `v-speed-dial` component can be used as a floating action button that can reveal additional actions when clicked.\n\n<PageFeatures />\n\n## Usage\n\nSpeed dials can be attached to material to signify a promoted action in your application. The default size will be used in most cases, whereas the `small` variant can be used to maintain continuity with similar sized elements.\n\n<ExamplesUsage name=\"v-speed-dial\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-speed-dial](/api/v-speed-dial/) | Primary Component |\n\n<ApiInline hide-links />\n\n### Guide\n\nComing soon.\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/steppers.md",
    "content": "---\nmeta:\n  nav: Steppers\n  title: Stepper component\n  description: The stepper component provides a linear progression process for gathering and displaying information to a user, similar to a form wizard.\n  keywords: steppers, vuetify stepper component, vue stepper component\nrelated:\n  - /components/tabs/\n  - /components/item-groups/\n  - /components/windows/\nfeatures:\n  figma: true\n  github: /components/VStepper/\n  label: 'C: VStepper'\n  report: true\n  spec: https://m1.material.io/components/steppers.html\n---\n\n# Steppers\n\nThe `v-stepper` component displays progress through numbered steps.\n\n<PageFeatures />\n\n## Usage\n\nA stepper can be used for a multitude of scenarios, including shopping carts, record creation and more.\n\n<ExamplesUsage name=\"v-stepper\" />\n\n<PromotedEntry />\n\n::: warning\n\nDue to the massive differences in display and functionality between horizontal and vertical steppers, the **vertical** property is moving to a new component [v-stepper-vertical](/components/vertical-steppers/).\n\n:::\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-stepper](/api/v-stepper/) | Primary Component |\n| [v-stepper-actions](/api/v-stepper-actions/) | Actions for stepper |\n| [v-stepper-header](/api/v-stepper-header/) | Container for stepper items |\n| [v-stepper-item](/api/v-stepper-item/) | Primary Component |\n| [v-stepper-window](/api/v-stepper-window/) | Window container for stepper window items |\n| [v-stepper-window-item](/api/v-stepper-window-item/) | Items for stepper window |\n\n<ApiInline hide-links />\n\n## Anatomy\n\nThe recommended placement of elements inside of `v-stepper` is:\n\n* Place `v-stepper-header` on top\n* Place `v-stepper-window` or other forms of content below the stepper header\n* Place `v-stepper-actions` after the stepper window\n\n![Pending graphic](https://cdn.vuetifyjs.com/docs/images/components/v-stepper/v-stepper-anatomy.png \"Stepper Anatomy\")\n\n| Element / Area | Description |\n| - | - |\n| 1. Container | The Stepper container holds all `v-stepper` components and is composed of 3 major parts: `v-stepper-header`, `v-stepper-window`, and `v-stepper-actions`. |\n| 2. Header | The header is the container for the `v-stepper-item` components. |\n| 3. Window | The window is the container for the `v-stepper-window-item` components. |\n| 4. Actions (optional) | A content area that typically contains one or more [v-btn](/components/buttons) components |\n\n## Guide\n\nThe `v-stepper` component provides a linear progression process for gathering and displaying information to a user, similar to a form wizard.\n\n### Props\n\nThe `v-stepper` component has multiple props to customize its visual appearance and functionality.\n\n#### Non editable steps\n\nA basic stepper has non-editable steps that force a user to move linearly through your process.\n\n<ExamplesExample file=\"v-stepper/misc-non-editable\" />\n\n#### Editable steps\n\nAn editable step can be selected by a user at any point and will navigate them to that step.\n\n<ExamplesExample file=\"v-stepper/misc-editable\" />\n\n#### Alternate label\n\nSteppers also have an alternative label style which places the title under the step itself.\n\n<ExamplesExample file=\"v-stepper/prop-alternate-label\" />\n\n#### Linear steppers\n\nLinear steppers will always move a user through your defined path.\n\n<ExamplesExample file=\"v-stepper/misc-linear\" />\n\n#### Optional steps\n\nAn optional step can be called out with sub-text.\n\n<ExamplesExample file=\"v-stepper/misc-optional\" />\n\n#### Items\n\nThe stepper component accepts an array of items similar to other components such as [v-list](/components/lists/) and [v-select](/components/selects/).\n\n<ExamplesExample file=\"v-stepper/misc-horizontal\" />\n\n::: warning\n\nIf no value is provided, the stepper will assign a value based off of its index + 1\n\n:::\n\n#### Mobile\n\nUse the **mobile** prop to hide the title and subtitle of the `v-stepper-item` component.\n\n<ExamplesExample file=\"v-stepper/prop-mobile\" />\n\n#### Errors\n\nAn error state can be displayed to notify the user of some action that must be taken.\n\n<ExamplesExample file=\"v-stepper/misc-error\" />\n\n#### Dynamic steps\n\nSteppers can have their steps dynamically added or removed. If a currently active step is removed, be sure to account for this by changing the applied model.\n\n<ExamplesExample file=\"v-stepper/misc-dynamic\" />\n\n#### Alternative label with errors\n\nThe error state can also be applied to the alternative label style.\n\n<ExamplesExample file=\"v-stepper/misc-alternate-error\" />\n\n#### Non linear\n\nNon-linear steppers allow the user to move through your process in whatever way they choose.\n\n<ExamplesExample file=\"v-stepper/prop-non-linear\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/switches.md",
    "content": "---\nmeta:\n  nav: Switches\n  title: Switch component\n  description: The switch component is a simple and eloquent toggle used to select between two values.\n  keywords: switch, switch component, vuetify switch component, vue switch component\nrelated:\n  - /components/checkboxes/\n  - /components/forms/\n  - /components/radio-buttons/\nfeatures:\n  label: 'C: VSwitch'\n  report: true\n  github: /components/VSwitch/\n  spec: https://m2.material.io/components/switches\n---\n\n# Switches\n\nThe `v-switch` component provides users the ability to choose between two distinct values. These are very similar to a toggle, or on/off switch, though aesthetically different than a checkbox.\n\n<PageFeatures />\n\n## Usage\n\nA `v-switch` in its simplest form provides a toggle between 2 values.\n\n<ExamplesUsage name=\"v-switch\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-switch](/api/v-switch/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n#### Colors\n\nSwitches can be colored by using any of the builtin colors and contextual names using the **color** prop.\n\n<ExamplesExample file=\"v-switch/prop-colors\" />\n\n<!-- #### Flat\n\nYou can make switch render without elevation of thumb using **flat** property.\n\n<ExamplesExample file=\"v-switch/prop-flat\" /> -->\n\n#### Inset\n\nYou can make switch render in inset mode.\n\n<ExamplesExample file=\"v-switch/prop-inset\" />\n\n#### Model as array\n\nMultiple `v-switch`'s can share the same **v-model** by using an array.\n\n<ExamplesExample file=\"v-switch/prop-model-as-array\" />\n\n#### Custom true/false values\n\nThe switch can use custom values for its v-model, using the props **true-value** and **false-value**.\n\n<ExamplesExample file=\"v-switch/prop-custom-values\" />\n\n#### States\n\n`v-switch` can have different states such as **default**, **disabled**, and **loading**.\n\n<ExamplesExample file=\"v-switch/prop-states\" />\n\n### Slots\n\n#### Label\n\nIf you need to render a switch label with more complex markup than plain text, you can use the **label** slot.\n\n<ExamplesExample file=\"v-switch/slot-label\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/system-bars.md",
    "content": "---\nmeta:\n  nav: System bars\n  title: System-bar component\n  description: The system bar component creates an android style status bar that rests on the very top of your application.\n  keywords: system bars, vuetify system bar component, vue system bar component, android status bar, status bar\nrelated:\n  - /components/buttons/\n  - /components/toolbars/\n  - /components/tabs/\nfeatures:\n  figma: true\n  label: 'C: VSystemBar'\n  report: true\n  github: /components/VSystemBar/\n---\n\n# System bars\n\nThe `v-system-bar` component can be used for displaying statuses to the user. It looks like the Android system bar and can contain icons, spacers, and some text.\n\n<PageFeatures />\n\n## Usage\n\n`v-system-bar` in its simplest form displays a small container with default theme.\n\n<ExamplesUsage name=\"v-system-bar\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-system-bar](/api/v-system-bar/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Anatomy\n\nThe recommended placement of elements inside of `v-system-bar` is:\n\n* Place informational icons to the right\n* Place time or other textual information to the far right\n\n![System Bar Anatomy](https://cdn.vuetifyjs.com/docs/images/components-temp/v-system-bar/v-system-bar-anatomy.png)\n\n| Element / Area | Description |\n| - | - |\n| 1. Container | The System Bar container has a default slot with content justified right |\n| 2. Icon items (optional) | Used to convey information through the use of icons |\n| 3. Text (optional) | Textual content that is typically used to show time |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n#### Color\n\nYou can optionally change the color of the `v-system-bar` by using the `color` prop.\n\n<ExamplesExample file=\"v-system-bar/prop-color\" />\n\n#### Window\n\nA window bar with window controls and status info.\n\n<ExamplesExample file=\"v-system-bar/prop-window\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/tables.md",
    "content": "---\nmeta:\n  nav: Tables\n  title: Table\n  description: The table component is a lightweight wrapper around the table element that provides a Material Design feel without all the baggage.\n  keywords: table, simple table, vuetify table component, vue simple table component, table component\nrelated:\n  - /components/data-tables/basics/\n  - /components/lists/\nfeatures:\n  github: /components/VTable/\n  label: 'C: VTable'\n  report: true\n  spec: https://m2.material.io/components/data-tables\n---\n\n# Tables\n\nThe simpler of the table components is `v-table`, a basic wrapper component for the HTML `<table>` element. In addition, regular table elements such as `<thead>`, `<tbody>`, `<tr>`, and `<td>` work by default.\n\n::: info\nMore advanced tables such as [v-data-table](/components/data-tables/basics/) are available.\n:::\n\n<PageFeatures />\n\n## Usage\n\n<ExamplesExample file=\"v-table/usage\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-table](/api/v-table/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n#### Theme\n\nUse **theme** prop to switch table to another theme.\n\n<ExamplesExample file=\"v-table/prop-dark\" />\n\n#### Density\n\nYou can show a dense version of the table by using the **density** prop.\n\n<ExamplesExample file=\"v-table/prop-dense\" />\n\n#### Height\n\nUse the **height** prop to set the height of the table.\n\n<ExamplesExample file=\"v-table/prop-height\" />\n\n#### Fixed header\n\nUse the **fixed-header** prop together with the **height** prop to fix the header to the top of the table.\n\n<ExamplesExample file=\"v-table/prop-fixed-header\" />\n\n#### Striped\n\nBy applying the **striped** prop, you can have a background applied to either the **even** or **odd** rows of the table. Color can be further adjusted using sass variables.\n\n<ExamplesExample file=\"v-table/prop-striped\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/tabs.md",
    "content": "---\nmeta:\n  nav: Tabs\n  title: Tabs component\n  description: The tabs component provides a way to organize and navigate between groups of content that are related at the same level of hierarchy.\n  keywords: tabs, vuetify tabs component, vue tabs component\nrelated:\n  - /components/icons/\n  - /components/toolbars/\n  - /components/windows/\nfeatures:\n  figma: true\n  label: 'C: VTabs'\n  report: true\n  github: /components/VTabs/\n  spec: https://m2.material.io/components/tabs\n---\n\n# Tabs\n\nThe `v-tabs` component is used for hiding content behind a selectable item. This can also be used as a pseudo-navigation for a page, where the tabs are links and the tab-items are the content.\n\n<PageFeatures />\n\n## Usage\n\nThe `v-tabs` component is a styled extension of [v-slide-group](/components/slide-groups). It provides an easy to use interface for organizing content into separate sections.\n\n<ExamplesUsage name=\"v-tabs\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-tabs](/api/v-tabs/) | Primary Component |\n| [v-tab](/api/v-tab/) | Sub-component used for modifying the `v-tabs` state |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n#### Align tabs\n\nThe **align-tabs** prop will align tabs to the `start`, `center`, or `end` of its container.\n\n<ExamplesExample file=\"v-tabs/prop-align-tabs-center\" />\n\n<ExamplesExample file=\"v-tabs/prop-align-tabs-end\" />\n\n#### Align tabs with title\n\nMake `v-tabs` line up with the `v-toolbar-title` component by setting the **align-tabs** prop to `title` (`v-app-bar-nav-icon` or `v-btn` must be used in `v-toolbar`).\n\n<ExamplesExample file=\"v-tabs/prop-align-tabs-title\" />\n\n#### Center active\n\nThe **center-active** prop will make the active tab always centered.\n\n<ExamplesExample file=\"v-tabs/prop-center-active\" />\n\n#### Custom icons\n\n**prev-icon** and **next-icon** can be used for applying custom pagination icons.\n\n<ExamplesExample file=\"v-tabs/prop-icons\" />\n\n#### Fixed tabs\n\nThe **fixed-tabs** prop forces `v-tab` items to take up all available space up to 300px width, and centers them.\n\n<ExamplesExample file=\"v-tabs/prop-fixed-tabs\" />\n\n#### Grow\n\nThe **grow** prop will make the tab items take up all available space with no limit.\n\n<ExamplesExample file=\"v-tabs/prop-grow\" />\n\n#### Stacked\n\nUsing **stacked** increases the `v-tabs` height to 72px to allow for both icons and text to be displayed.\n\n<ExamplesExample file=\"v-tabs/prop-stacked\" />\n\n#### Slider Transition\n\nWith **slider-transition** you can change default animation of the slider so it better fits with the app design.\n\n<ExamplesExample file=\"v-tabs/prop-slider-transition\" />\n\n#### Pagination\n\nIf the tab items overflow their container, pagination controls will appear on desktop. For mobile devices, arrows will only display with the **show-arrows** prop.\n\n<ExamplesExample file=\"v-tabs/misc-pagination\" />\n\n#### Vertical tabs\n\nThe **direction** prop allows for `v-tab` components to stack vertically.\n\n<ExamplesExample file=\"v-tabs/prop-direction\" />\n\n#### Spaced\n\nVertical tabs can be customized with **spaced** prop to move the text away from the icon.\n\n<ExamplesExample file=\"v-tabs/prop-spaced\" />\n\n### Misc\n\n#### Content\n\nIt is common to put `v-tabs` inside the **extension** slot of `v-toolbar`.\n\n<ExamplesExample file=\"v-tabs/misc-content\" />\n\n#### Mobile tabs\n\nOn mobile you can use `v-tab` items with just icons to conserve space.\n\n<ExamplesExample file=\"v-tabs/misc-mobile\" />\n\n#### Dynamic Tabs\n\nTabs can be dynamically added and removed. In this example when we add a new tab, we automatically change our model to match. As we add more tabs and overflow the container, the selected item will be automatically scrolled into view. Remove all `v-tab` items and the slider will disappear.\n\n<ExamplesExample file=\"v-tabs/misc-dynamic\" />\n\n#### Overflow to menu\n\nYou can use a menu to hold additional tabs, swapping them out on the fly.\n\n<ExamplesExample file=\"v-tabs/misc-overflow-to-menu\" />\n\n### Slots\n\n#### Tab and window items\n\nUse the **tab** and **item** slots with the **items** prop to reduce the markup required to build tabs.\n\n<ExamplesExample file=\"v-tabs/slot-tabs\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/text-fields.md",
    "content": "---\nmeta:\n  nav: Text fields\n  title: Text field component\n  description: The text field component accepts textual input from users.\n  keywords: text fields, vuetify text field component, vue text field component\nrelated:\n  - /components/textareas/\n  - /components/selects/\n  - /components/forms/\nfeatures:\n  label: 'C: VTextField'\n  report: true\n  github: /components/VTextField/\n  spec: https://m2.material.io/components/text-fields\n---\n\n# Text fields\n\nText field components are used for collecting user provided information.\n\n<PageFeatures />\n\n## Usage\n\nA simple text field with placeholder and/or label.\n\n<ExamplesUsage name=\"v-text-field\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-text-field](/api/v-text-field/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Anatomy\n\nThe recommended placement of elements inside of `v-text-field` is:\n\n* Place a `v-icon` at the start of the input or label\n* Place label after prepended content\n\n![Text-field Anatomy](https://cdn.vuetifyjs.com/docs/images/components-temp/v-text-field/v-text-field-anatomy.png)\n\n| Element / Area | Description |\n| - | - |\n| 1. Container | The Text field container contains the `v-input` and `v-field` components |\n| 2. Prepend icon | A custom icon that is located before `v-field` |\n| 3. Prepend-inner icon | A custom icon that is located at the start of `v-field` |\n| 4. Label | A content area for displaying text to users that correlates to the input |\n| 5. Append-inner icon | A custom icon that is located at the end of `v-field` component |\n| 6. Append icon | A custom icon that is located after `v-field` component |\n\n## Guide\n\nThe `v-text-field` component is a versatile `<input type=\"text\">` field which combines both the `v-input` and `v-field` components into a single offering. It is a commonly used element that provides the baseline for other form inputs; such as [v-select](/components/selects/), [v-autocomplete](/components/autocompletes/), [v-combobox](/components/combobox/). In this guide you learn the basic fundamentals of `v-text-field` and how its various properties interact with each other.\n\n### Props\n\nThe `v-text-field` component has an massive API with numerous options to modify the display, functionality, or style of your inputs. Many of the configurable options are also available through [slots](#slots).\n\n#### Labeling\n\nThe **label** prop displays custom text for identifying an input's purpose. The following code snippet is an example of a basic `v-text-field` component:\n\n```html\n<v-text-field label=\"First name\"></v-text-field>\n```\n\nUsing this baseline makes it easy to put together quick mock implementations of your interface without needing to hook up any functional logic.\n\nThe following code snippet is an example of a simple form for for collecting a user's **First** name:\n\n<ExamplesExample file=\"v-text-field/prop-label\" />\n\n#### Placeholders\n\nSometimes a label alone doesn't convey enough information and you need to expose more. For those use-cases, use the **placeholder** property with or without the [label](#labeling) or [hint](#hint) properties.\n\nIn the following snippet, we improve the user experience of a `v-text-field` that is capturing an email address:\n\n```html\n<v-text-field\n  label=\"Email address\"\n  placeholder=\"johndoe@gmail.com\"\n  type=\"email\"\n></v-text-field>\n```\n\nWhen the user focuses the input, the placeholder fades in as the label translates up. The added visual element improves the user experience when using multiple field inputs.\n\n<ExamplesExample file=\"v-text-field/prop-placeholder\" />\n\n::: info\n  Use the **persistent-placeholder** prop to force the **placeholder** to be visible, even when the input is not focused.\n:::\n\n#### Hints & messages\n\nThe **label** and **placeholder** props are useful for providing context to the input but are typically concise. For longer textual information, all Vuetify inputs contain a **details** section that is used to provide **hints**, regular **messages**, and **error-messages**. In the following example watch the custom hint message display when you focus the input:\n\n<ExamplesExample file=\"v-text-field/prop-messages\" open />\n\nIf you want to make the hint visible at all times, use the **persistent-hint** property. The following example demonstrates how to force a **hint** to show in the input's details:\n\n```html\n<v-text-field\n  hint=\"Enter your password to access this website\"\n  label=\"Password\"\n  persistent-hint\n  type=\"input\"\n></v-text-field>\n```\n\nIn addition to **persistent-hint**, there are 3 other properties that support a persistent state:\n\n* **persistent-clear** - always show the input clear icon when a **value** is present\n* **persistent-counter** - always show input character length element\n* **persistent-placeholder** - always show placeholder, causes label to automatically elevate\n\n#### Clearable\n\nThe **clearable** prop appends an inner [v-icon](/components/icons/) that clears the `v-text-field` when clicked. When an input is cleared, it resets the current `v-text-field` value. The following example displays an interactive icon when the mouse hovers over the input:\n\n<ExamplesExample file=\"v-text-field/prop-clearable\" open />\n\nNote that **readonly** will not remove the clear icon, to prevent readonly inputs from being cleared you should also disable **clearable**.\n\nSometimes you may need to perform an action when the user clears an input. By using a custom [Vue Event Handler](https://vuejs.org/guide/essentials/event-handling.html), you can bind a custom function that is invoked whenever the `v-text-field` is cleared by the user. The following example demonstrates how to use a a custom event handler to invoke the **onClear** method:\n\n```html { resource=\"Component.vue\" }\n<template>\n  <v-text-field\n    clearable\n    label=\"Last name\"\n    placeholder=\"Doe\"\n    persistent-clear\n    @click:clear=\"onClear\"\n  ></v-text-field>\n</template>\n\n<script setup>\n  onClear () {\n    alert('User cleared the input')\n  }\n</script>\n```\n\nYou can see more supported events on the `v-text-field` [API page](/api/v-text-field/#events).\n\n#### Validation & rules\n\nWhen working with inputs you often need to validate the user's input in some manner; i.e. Email, Password. Use the **rules** property to invoke custom functions based upon the `v-text-field`'s state. It accepts an array of **functions** that return either `true` or a `string`. In the following example, enter a value into the field and then clear it:\n\n<ExamplesExample file=\"v-text-field/prop-rules\" open />\n\n#### Forms\n\nGroup multiple `v-text-field` components and other functionality within a `v-form` component; for a more detailed look at forms, please visit the [v-form](/components/forms/) page. Forms are useful for validating more than 1 input and make it easy to interact with the state of many fields at once. The following example combines multiple `v-text-field` components to create a login form:\n\n<ExamplesExample file=\"v-text-field/misc-guide\" />\n\n### Examples\n\nThe following is a collection of `v-text-field` examples that demonstrate how different the properties work in an application.\n\n#### Custom colors\n\nThe **color** prop provides an easy way to change the color of textual content; label, prefix, suffix, etc. This color is applied as long as `v-text-field` is focused.\n\n<ExamplesExample file=\"v-text-field/prop-custom-colors\" />\n\n#### Density\n\nThe **density** prop decreases the height of the text field based upon 1 of 3 levels of density; **default**, **comfortable**, and **compact**.\n\n<ExamplesExample file=\"v-text-field/prop-dense\" />\n\n#### Disabled and readonly\n\nThe state of a text field can be changed by providing the **disabled** or **readonly** props.\n\n<ExamplesExample file=\"v-text-field/prop-disabled-and-readonly\" />\n\n#### Hide details\n\nWhen **hide-details** is set to `auto` messages will be rendered only if there's a message (hint, error message, counter value etc) to display.\n\n<ExamplesExample file=\"v-text-field/prop-hide-details\" />\n\n#### Hint\n\nThe **hint** property on text fields adds the provided string beneath the text field. Using **persistent-hint** keeps the hint visible when the text field is not focused.\n\n<ExamplesExample file=\"v-text-field/prop-hint\" />\n\n#### Icons\n\nYou can add icons to the text field with **prepend-icon**, **append-icon** and **append-inner-icon** props.\n\n<ExamplesExample file=\"v-text-field/prop-icon\" />\n\n#### Prefixes and suffixes\n\nThe **prefix** and **suffix** properties allows you to prepend and append inline non-modifiable text next to the text field.\n\n<ExamplesExample file=\"v-text-field/prop-prefixes-and-suffixes\" />\n\n#### Validation\n\nVuetify includes simple validation through the **rules** prop. The prop accepts a mixed array of types `function`, `boolean` and `string`. When the input value changes, each element in the array will be validated. Functions pass the current v-model as an argument and must return either `true` / `false` or a `string` containing an error message.\n\n<ExamplesExample file=\"v-text-field/prop-validation\" />\n\n#### Variant\n\nThe **variant** prop provides an easy way to customize the style of your text field. The following values are valid options: **solo**, **filled**, **outlined**, **plain**, and **underlined**.\n\n<ExamplesExample file=\"v-text-field/prop-variant\" />\n\n#### Focused\n\nThe **focused** prop that sets the initial focus state of the component. It is a model prop, which handles 2 way binding with `focused` and `@update:focused`. This means its value sets the initial state but will be updated internally by focus/blur events.\nIf you want to override this behavior (e.g., keep the input always focused), you can bind an empty `@update:focused` handler.\n\n<ExamplesExample file=\"v-text-field/prop-focused\" />\n\n### Events\n\n#### Icon events\n\n`click:prepend`, `click:append`, `click:append-inner`, and `click:clear` are emitted when you click on the respective icon. Note that these events will not be fired if the slot is used instead.\n\n<ExamplesExample file=\"v-text-field/event-icons\" />\n\n### Slots\n\nSlots allow you to customize the display of many `v-text-field` properties to modify what Vuetify does by default. The following slots are available on the `v-text-field` component:\n\n| Slot name | Description |\n| - | - |\n| 1. prepend | Provided by `v-input`, positioned before the input field |\n| 2. prepend-inner | Provided by `v-field`, positioned at the start of the input field |\n| 3. label | The form input label |\n| 4. append-inner | Provided by `v-field`, positioned at the end of the input field |\n| 5. append | Provided by `v-input`, positioned after the input field |\n| 6. details | Used for displaying **messages**, **hint**, **error-messages**, and more |\n\nThe following example uses the **label**, **prepend**, and **prepend-inner** slots and adds custom elements to the `v-text-field`\n\n```html { resource=\"Component.vue\" }\n<template>\n  <v-text-field v-model=\"model\">\n    <template v-slot:label>\n      <span>Type something...</span>\n    </template>\n\n    <template v-slot:prepend>\n      <v-icon\n        :color=\"model ? 'primary' : undefined\"\n        icon=\"$vuetify\"\n      />\n    </template>\n\n    <template v-slot:append-inner>\n      <v-icon\n        v-if=\"model\"\n        icon=\"mdi-check-circle\"\n      />\n    </template>\n\n    <template #details>\n      <v-spacer />\n\n      See our <a href=\"#\">Terms and Service</a>\n    </template>\n  </v-text-field>\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const model = shallowRef('')\n</script>\n```\n\n<PromotedPromoted />\n\n#### Icon slots\n\nInstead of using `prepend`/`append`/`append-inner` icons you can use slots to extend input's functionality.\n\n<ExamplesExample file=\"v-text-field/slot-icons\" />\n\n#### Label\n\nText field label can be defined in `label` slot - that will allow to use HTML content\n\n<ExamplesExample file=\"v-text-field/slot-label\" />\n\n#### Progress\n\nYou can display a progress bar instead of the bottom line. You can use the default indeterminate progress having same color as the text field or designate a custom one using the `progress` slot\n\n<ExamplesExample file=\"v-text-field/slot-progress\" />\n\n### Misc\n\n#### Custom validation\n\nWhile the built in `v-form` or 3rd party plugin such as [vuelidate](https://github.com/monterail/vuelidate) or [vee-validation](https://github.com/logaretm/vee-validate) can help streamline your validation process, you can choose to simply control it yourself.\n\n<ExamplesExample file=\"v-text-field/misc-custom-validation\" />\n\n#### Full width with counter\n\nFull width text fields allow you to create boundless inputs. In this example, we use a `v-divider` to separate the fields.\n\n<ExamplesExample file=\"v-text-field/misc-full-width-with-counter\" />\n\n#### Password input\n\nUsing the HTML input **type** [password](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/password) can be used with an appended icon and callback to control the visibility.\n\n<ExamplesExample file=\"v-text-field/misc-password\" />\n\n#### Login Form\n\nIn this example we use a combination of prepend and append icon to create a custom login form.\n\n<ExamplesExample file=\"v-text-field/misc-login-form\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/textareas.md",
    "content": "---\nmeta:\n  nav: Textareas\n  title: Textarea component\n  description: The textarea component is a text field that accepts lengthy textual input from users.\n  keywords: textareas, vuetify textarea component, vue textarea component\nrelated:\n  - /components/forms/\n  - /components/selects/\n  - /components/text-fields/\nfeatures:\n  label: 'C: VTextarea'\n  report: true\n  github: /components/VTextarea/\n  spec: https://m2.material.io/components/text-fields#input-types\n---\n\n# Textareas\n\nTextarea components are used for collecting large amounts of textual data.\n\n<PageFeatures />\n\n## Usage\n\n`v-textarea` in its simplest form is a multi-line text-field, useful for larger amounts of text.\n\n<ExamplesUsage name=\"v-textarea\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-textarea](/api/v-textarea/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n#### Auto grow\n\nWhen using the `auto-grow` prop, textarea's will automatically increase in size when the contained text exceeds its size.\n\n<ExamplesExample file=\"v-textarea/prop-auto-grow\" />\n\n#### Background color\n\nThe `bg-color` and `color` props give you more control over styling `v-textarea`'s.\n\n<ExamplesExample file=\"v-textarea/prop-background-color\" />\n\n#### Browser autocomplete\n\nThe `autocomplete` prop gives you the option to enable the browser to predict user input.\n\n<ExamplesExample file=\"v-textarea/prop-browser-autocomplete\" />\n\n#### Clearable\n\nYou can clear the text from a `v-textarea` by using the `clearable` prop, and customize the icon used with the `clearable-icon` prop.\n\n<ExamplesExample file=\"v-textarea/prop-clearable\" />\n\n#### Counter\n\nThe `counter` prop informs the user of a character limit for the `v-textarea`.\n\n<ExamplesExample file=\"v-textarea/prop-counter\" />\n\n#### Icons\n\nThe `append-icon` and `prepend-icon` props help add context to `v-textarea`.\n\n<ExamplesExample file=\"v-textarea/prop-icons\" />\n\n#### No resize\n\n`v-textarea`'s have the option to remain the same size regardless of their content's size, using the `no-resize` prop.\n\n<ExamplesExample file=\"v-textarea/prop-no-resize\" />\n\n#### Rows\n\nThe `rows` prop allows you to define how many rows the textarea has, when combined with the `row-height` prop you can further customize your rows by defining their height.\n\n<ExamplesExample file=\"v-textarea/prop-rows\" />\n\n### Misc\n\n#### Signup form\n\nUtilizing alternative input styles, you can create amazing interfaces that are easy to build and easy to use.\n\n<ExamplesExample file=\"v-textarea/misc-signup-form\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/theme-providers.md",
    "content": "---\nmeta:\n  nav: Theme providers\n  title: Theme provider component\n  description: The theme provider allows you to style a section of your application in a different theme from the default\n  keywords: theme provider, vuetify theme provider component, vue theme provider component\nrelated:\n  - /features/theme/\n  - /styles/colors/\n  - /features/application-layout/\nfeatures:\n  github: /components/VThemeProvider/\n  label: 'C: VThemeProvider'\n  report: true\n---\n\n# Theme providers\n\nThe theme provider allows you to style a section of your application in a different theme from the default\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-theme-provider](/api/v-theme-provider/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Background\n\nBy default, `v-theme-provider` is a renderless component that allows you to change the applied theme for all of its children. When using the **with-background** prop, the `v-theme-provider` wraps its children in an element and applies the selected theme's background color to it.\n\n<ExamplesExample file=\"v-theme-provider/prop-with-background\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/time-pickers.md",
    "content": "---\nmeta:\n  nav: Time pickers\n  title: Time picker component\n  description: The time picker component is a stand-alone interface that allows the selection of hours and minutes in AM/PM and 24hr formats.\n  keywords: time pickers, vuetify time picker component, vue time picker component\nrelated:\n  - /components/buttons/\n  - /components/date-pickers/\n  - /components/text-fields/\n---\n\n# Time pickers\n\nThe `v-time-picker` is stand-alone component that can be utilized in many existing Vuetify components. It offers the user a visual representation for selecting the time.\n\n<PageFeatures />\n\n## Usage\n\nTime pickers have the light theme enabled by default.\n\n<ExamplesUsage name=\"v-time-picker\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-time-picker](/api/v-time-picker/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n#### Allowed times\n\nYou can specify allowed times using arrays, objects, and functions. You can also specify time step/precision/interval - e.g. 10 minutes.\n\n<ExamplesExample file=\"v-time-picker/prop-allowed-times\" />\n\n#### Colors\n\nTime picker colors can be set using the `color` prop.\n\n<ExamplesExample file=\"v-time-picker/prop-color\" />\n\n#### Disabled\n\nYou can't interact with disabled picker.\n\n<ExamplesExample file=\"v-time-picker/prop-disabled\" />\n\n#### Elevation\n\nEmphasize the `v-time-picker` component by providing an **elevation** from 0 to 5. Elevation modifies the `box-shadow` css property.\n\n<ExamplesExample file=\"v-time-picker/prop-elevation\" />\n\n#### Format\n\nA time picker can be switched to 24hr format. Note that the `format` prop defines only the way the picker is displayed, picker's value (model) is always in 24hr format.\n\n<ExamplesExample file=\"v-time-picker/prop-format\" />\n\n#### No header\n\nYou can remove picker's header.\n\n<ExamplesExample file=\"v-time-picker/prop-hide-header\" />\n\n#### Range\n\nThis is an example of joining pickers together using `min` and `max` prop.\n\n<ExamplesExample file=\"v-time-picker/prop-range\" />\n\n#### Read-only\n\nRead-only picker behaves same as disabled one, but looks like default one.\n\n<ExamplesExample file=\"v-time-picker/prop-readonly\" />\n\n#### Scrollable\n\nYou can edit time picker's value using mouse wheel.\n\n<ExamplesExample file=\"v-time-picker/prop-scrollable\" />\n\n#### Use seconds\n\nTime picker can have seconds input.\n\n<ExamplesExample file=\"v-time-picker/prop-use-seconds\" />\n\n### Misc\n\n#### Dialog and menu\n\nDue to the flexibility of pickers, you can really dial in the experience exactly how you want it.\n\n<ExamplesExample file=\"v-time-picker/misc-dialog-and-menu\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/timelines.md",
    "content": "---\nmeta:\n  nav: Timelines\n  title: Timeline component\n  description: The timeline component is used to display chronological information either vertically or horizontally.\n  keywords: timelines, vuetify timeline component, vue timeline component\nrelated:\n  - /components/cards/\n  - /components/icons/\n  - /components/grids/\nfeatures:\n  github: /components/VTimeline/\n  label: 'C: VTimeline'\n  report: true\n---\n\n# Timelines\n\nThe `v-timeline` is useful for stylistically displaying chronological information.\n\n<PageFeatures />\n\n<!--\n## Usage\n\n`v-timeline`s in their simplest form display a vertical timeline that should contain at least one `v-timeline-item`.\n\n<ExamplesExample file=\"v-timeline/usage\" />\n-->\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-timeline](/api/v-timeline/) | Primary Component |\n| [v-timeline-item](/api/v-timeline-item/) | Sub-component used to display a single timeline item |\n\n<ApiInline hide-links />\n\n<!-- ## Sub-components\n\n### v-timeline-item\n\nv-timeline-item description -->\n\n## Examples\n\n### Props\n\n#### Direction\n\nSwitch between a horizontal and vertical timeline in real-time using the **direction** prop.\n\n<ExamplesExample file=\"v-timeline/prop-direction\" />\n\n#### Side\n\nUse the **side** property to force all items to one side of the timeline.\n\n<ExamplesExample file=\"v-timeline/prop-single-side\" />\n\n#### Alignment\n\nBy default, `v-timeline-item` content is vertically aligned `center`. The **align** prop also supports `top` alignment.\n\n<ExamplesExample file=\"v-timeline/prop-align\" />\n\n#### Dot color\n\nColored dots create visual breakpoints that make your timelines easier for users to read.\n\n<ExamplesExample file=\"v-timeline/prop-color\" />\n\n#### Icon dots\n\nUse icons within the `v-timeline-item` dot to provide additional context.\n\n<ExamplesExample file=\"v-timeline/prop-icon-dots\" />\n\n<!-- #### Mirror\n\nYou can mirror the placement of the timeline items by using the **mirror** prop.\n\n<ExamplesExample file=\"v-timeline/prop-mirror\" /> -->\n\n#### Size\n\nThe **size** prop allows you to customize the size of each dot.\n\n<ExamplesExample file=\"v-timeline/prop-size\" />\n\n#### Truncated line\n\nTruncate the start, end or both ends of the timeline center line by using the **truncate-line** prop.\n\n<ExamplesExample file=\"v-timeline/prop-truncate-line\" />\n\n#### Line inset\n\nModify the inset of dividing lines by specifying a custom amount using the **line-inset** prop.\n\n<ExamplesExample file=\"v-timeline/prop-line-inset\" />\n\n### Slots\n\n#### Icon\n\nInsert avatars into dots with use of the `icon` slot and `v-avatar`.\n\n<ExamplesExample file=\"v-timeline/slot-icon\" />\n\n#### Opposite\n\nThe **opposite** slot provides an additional layer of customization within your timelines.\n\n<ExamplesExample file=\"v-timeline/slot-opposite\" />\n\n<!--\n#### Timeline item default\n\nIf you place a `v-card` inside of a `v-timeline-item`, a caret will appear on the side of the card.\n\n<ExamplesExample file=\"v-timeline/slot-timeline-item-default\" />\n-->\n\n### Misc\n\n#### Advanced\n\n<ExamplesExample file=\"v-timeline/misc-advanced\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/toolbars.md",
    "content": "---\nmeta:\n  nav: Toolbars\n  title: Toolbar component\n  description: The toolbar component sits above the content that it affects and provides an area for labeling and additional actions.\n  keywords: toolbars, vuetify toolbar component, vue toolbar component\nrelated:\n  - /components/navigation-drawers/\n  - /components/cards/\n  - /components/app-bars/\nfeatures:\n  github: /components/VToolbar/\n  label: 'C: VToolbar'\n  report: true\n  spec: https://m1.material.io/components/toolbars.html\n---\n\n# Toolbars\n\nThe `v-toolbar` component is pivotal to any graphical user interface (GUI), as it generally is the primary source of site navigation.\n\n<PageFeatures />\n\n## Usage\n\n<ExamplesUsage name=\"v-toolbar\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-toolbar](/api/v-toolbar/) | Primary Component |\n| [v-toolbar-items](/api/v-toolbar-items/) | Sub-component used to modify the styling of [v-btn](/components/buttons) |\n| [v-toolbar-title](/api/v-toolbar-title/) | Sub-component used to display the title of the toolbar |\n| [v-btn](/api/v-btn/) | Sub-component commonly used in `v-toolbar` |\n\n<ApiInline hide-links />\n\n## Caveats\n\n::: warning\n\nWhen `v-btn`s with the **icon** prop are used inside of `v-toolbar` and `v-app-bar` they will automatically have their size increased and negative margin applied to ensure proper spacing according to the Material Design Specification. If you choose to wrap your buttons in any container, such as a `div`, you will need to apply negative margin to that container in order to properly align them.\n\n:::\n\n## Guide\n\nA toolbar is a flexible container that can be used in a number of ways. By default, the toolbar is 64px high on desktop and 56px high on mobile. There are a number of helper components available to use with the toolbar. The `v-toolbar-title` is used for displaying a title and `v-toolbar-items` allow [v-btn](/components/buttons) to extend full height.\n\n### Props\n\nThe toolbar has a number of props that can be used to modify its appearance and behavior.\n\n#### Dense toolbars\n\nDense toolbars reduce their height to _48px_.\n\n<ExamplesExample file=\"v-toolbar/prop-dense\" />\n\n#### Collapse\n\nToolbars can be collapsed to save screen space.\n\n<ExamplesExample file=\"v-toolbar/prop-collapse\" />\n\n#### Background\n\nToolbars can display a background as opposed to a solid color using the **src** prop. This can be modified further by using the **img** slot and providing your own [v-img](/components/images) component. Backgrounds can be faded using a [v-app-bar](/components/app-bars#prominent-w-scroll-shrink-and-image)\n\n<ExamplesExample file=\"v-toolbar/prop-background\" />\n\n#### Location\n\nYou can use **location** prop to control how the toolbar is positioned within a relative container. It can also be used with **position-fixed** class instead of **absolute** prop.\n\n<ExamplesExample file=\"v-toolbar/prop-location\" />\n\n#### Extended\n\nToolbars can be extended without using the `extension` slot.\n\n<ExamplesExample file=\"v-toolbar/prop-extended\" />\n\n#### Extension height\n\nThe extension's height can be customized.\n\n<ExamplesExample file=\"v-toolbar/prop-extension-height\" />\n\n### Slots\n\nThe toolbar has a number of slots that can be used to customize its content.\n\n#### Extension\n\nThe `extension` slot can be used to add additional content to the toolbar.\n\n<ExamplesExample file=\"v-toolbar/slot-extension\" />\n\n## Examples\n\nThe following are a collection of examples that demonstrate more advanced and real world use of the `v-toolbar` component.\n\n### Contextual action bar\n\nIt is possible to update the appearance of a toolbar in response to changes in app state. In this example, the color and content of the toolbar changes in response to user selections in the `v-select`.\n\n<ExamplesExample file=\"v-toolbar/misc-contextual-action-bar\" />\n\n### Flexible and card toolbar\n\nIn this example we offset our card onto the extended content area of a toolbar using the **extended** prop.\n\n<ExamplesExample file=\"v-toolbar/misc-flexible-and-card\" />\n\n### Floating with search\n\nA floating toolbar is turned into an inline element that only takes up as much space as needed. This is particularly useful when placing toolbars over content.\n\n<ExamplesExample file=\"v-toolbar/prop-floating-with-search\" />\n\n### Tooltips and Speed Dial\n\nToolbar elements can include menus (like Speed Dial) and tooltips to help users understand the action intent when buttons show only icons to keep interface minimalistic.\n\n<ExamplesExample file=\"v-toolbar/misc-tooltips-and-speed-dial\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/tooltips.md",
    "content": "---\nmeta:\n  nav: Tooltips\n  title: Tooltip component\n  description: The tooltip component displays textual information regarding the element it is attached to.\n  keywords: tooltips, vuetify tooltip component, vue tooltip component\nrelated:\n  - /components/overlays/\n  - /components/icons/\n  - /components/menus/\nfeatures:\n  github: /components/VTooltip/\n  label: 'C: VTooltip'\n  report: true\n  spec: https://m2.material.io/components/tooltips\n---\n\n# Tooltips\n\nThe `v-tooltip` component is useful for conveying information when a user hovers over an element. You can also programmatically control the display of tooltips through a `v-model`. When activated, tooltips display a text label identifying an element, such as a description of its function.\n\n<PageFeatures />\n\n## Usage\n\nTooltips can wrap any element.\n\n<ExamplesUsage name=\"v-tooltip\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-tooltip](/api/v-tooltip/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n#### Interactive\n\nThe **interactive** prop prevents the tooltip from closing during mouse interactions. For example, if the tooltip contains text that users might want to click or copy.\n\n<ExamplesExample file=\"v-tooltip/prop-interactive\" />\n\n#### Location\n\nUse the **location** prop to specify on which side of the element the tooltip should show. Read more about **location** [here](/components/overlays/#location).\n\n<ExamplesExample file=\"v-tooltip/prop-location\" />\n\n<!-- TODO: not supported\n#### Color\n\nTooltip color can be set with the `color` prop.\n\n<ExamplesExample file=\"v-tooltip/prop-color\" />\n-->\n\n#### Open on Click\n\nThe **open-on-click** prop allows tooltip to open when the activator is clicked. Useful for touch devices or when manual triggering is preferred.\n\n<ExamplesExample file=\"v-tooltip/prop-open-on-click\"/>\n\n#### Visibility\n\nTooltip visibility can be programmatically changed using `v-model`.\n\n<ExamplesExample file=\"v-tooltip/prop-visibility\" />\n\n### Misc\n\n#### Tooltip at cursor\n\nTooltip can appear where the cursor is by setting the **target** prop to `cursor`. This is currently only available with **open-on-click**.\n\n<ExamplesExample file=\"v-tooltip/misc-at-cursor\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/treeview.md",
    "content": "---\nmeta:\n  nav: Treeview\n  title: Treeview component\n  description: The treeview component is a user interface that is used to represent hierarchical data in a tree structure.\n  keywords: treeview, vuetify treeview component, vue treeview component\nrelated:\n  - /components/lists/\n  - /components/timelines/\n  - /components/autocompletes/\nfeatures:\n  label: 'C: VTreeview'\n  report: true\n---\n\n# Treeview\n\nThe `v-treeview` component is useful for displaying large amounts of nested data.\n\n<PageFeatures />\n\n## Usage\n\nA basic example of the treeview component.\n\n<ExamplesExample file=\"v-treeview/usage\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-treeview](/api/v-treeview/) | Primary Component |\n| [v-treeview-item](/api/v-treeview-item/) | Sub-component used to display a single treeview node |\n| [v-treeview-group](/api/v-treeview-group/) | Sub-component used to display a single treeview node's children |\n\n<ApiInline hide-links />\n\n::: info\n\nThere is a [bug](https://github.com/vuejs/babel-plugin-jsx/issues/712) related to how [babel-plugin-jsx](https://github.com/vuejs/babel-plugin-jsx) renders templates that degrades VTreeview performance. We are tracking the issue [here](https://github.com/vuetifyjs/vuetify/issues/19919).\n\n:::\n\n## Guide\n\nThe `v-treeview` component is useful for displaying large amounts of nested data. It is a tree structure that can be expanded and collapsed, allowing users to navigate through the hierarchy of items.\n\nIt is built on top of the [v-list](/components/lists/) component, which provides the basic structure and functionality for displaying lists of items. The `v-treeview` component extends this functionality by adding support for hierarchical data, allowing users to expand and collapse items to reveal or hide their children.\n\n### Props\n\nThe `v-treeview` component has several props that allow you to customize its appearance and behavior.\n\n#### Activatable\n\nTreeview nodes can be activated by clicking on them.\n\n<ExamplesExample file=\"v-treeview/prop-activatable\" />\n\n#### Color\n\nYou can control the text and background color of the active treeview node.\n\n<ExamplesExample file=\"v-treeview/prop-color\" />\n\n#### Density\n\nDense mode provides more compact layout with decreased heights of the items.\n\n<ExamplesExample file=\"v-treeview/prop-dense\" />\n\n#### Items registration\n\nWhen working with large trees it is recommended to include `items-registration=\"props\"` to ensure faster loading and interactions.\n\n<ExamplesExample file=\"v-treeview/prop-items-registration\" />\n\n<!-- #### Hoverable\n\nTreeview nodes can have a hover effect.\n\n<ExamplesExample file=\"v-treeview/prop-hoverable\" /> -->\n\n#### Item props\n\nIf **item-props** is set to `true` then the whole item will be spread. In the following example, the disabled prop defined in each item will disable the item accordingly.\n\n<ExamplesExample file=\"v-treeview/prop-item-props\" />\n\n#### Open all\n\nTreeview nodes can be pre-opened on page load.\n\n<ExamplesExample file=\"v-treeview/prop-open-all\" />\n\n<!-- #### Rounded\n\nYou can make treeview nodes rounded.\n\n<ExamplesExample file=\"v-treeview/prop-rounded\" /> -->\n\n#### Fluid\n\nThe **fluid** prop removes the extra indentation used to line up children. This is useful when you want to reduce the horizontal space used by the treeview.\n\n<ExamplesExample file=\"v-treeview/prop-fluid\" />\n\n#### Selected color\n\nYou can control the color of the selected node checkbox.\n\n<ExamplesExample file=\"v-treeview/prop-selected-color\" />\n\n#### Selection type\n\nTreeview supports several selection modes:\n\n- **leaf** (default): Limits selection to items without children.\n- **independent**: Lets you select any node, with no parent-child linkage at all.\n- **classic**: Selecting a parent selects all descendants, and parent nodes show as selected only when all their descendants are selected. Only leaf nodes are added to the model.\n\nClassic has two variants that are displayed the same way but with slightly different v-model behavior:\n\n- **branch**: Any parent node with at least one selected descendant is also added to the model.\n- **trunk**: If all children are selected only the parent node is added to the model.\n\n<ExamplesExample file=\"v-treeview/prop-selection-type\" />\n\n#### Load children\n\nYou can dynamically load child data by supplying a _Promise_ callback to the **load-children** prop. This callback will be executed the first time a user tries to expand an item that has a children property that is an empty array.\n\n<ExamplesExample file=\"v-treeview/prop-load-children\" />\n\n### Slots\n\nThe `v-treeview` component has several slots that allow you to customize the appearance and behavior of its items.\n\n#### Append and prepend\n\nUsing the the **prepend** slot we are able to create an intuitive file explorer.\n\n<ExamplesExample file=\"v-treeview/slot-append-and-label\" />\n\nBoth **append**, and **prepend** slots get additional information about the item: `depth`, `path` (from indexes), `isFirst`, `isLast` and the `index` within the children list.\n\n<ExamplesExample file=\"v-treeview/slot-append-and-prepend-item\" />\n\n#### No data\n\nWhen searching within the treeview, you might want to show custom **no-data** slot to provide context or immediate action.\n\n<ExamplesExample file=\"v-treeview/slot-no-data\" />\n\n#### Title\n\nIn this example we use a custom **title** slot to apply a line-through the treeview item's text when selected.\n\n<ExamplesExample file=\"v-treeview/slot-title\" />\n\n#### Toggle\n\nHere, a custom **toggle** slot is utilized to assign a specific color and variant to the button depending on the state of the item.\n\n<ExamplesExample file=\"v-treeview/slot-toggle\" />\n\n## Examples\n\nThe following are a collection of examples that demonstrate more advanced and real world use of the `v-treeview` component.\n\n### Search and filter\n\nEasily filter your treeview by using the **search** prop. You can easily apply your custom filtering function if you need case-sensitive or fuzzy filtering by setting the **custom-filter** prop. This works similar to the [v-autocomplete](/components/autocompletes) component.\n\n<ExamplesExample file=\"v-treeview/misc-search-and-filter\" />\n\n### Selectable icons\n\nCustomize the **on**, **off** and **indeterminate** icons for your selectable tree. Combine with other advanced functionality like API loaded items.\n\n<ExamplesExample file=\"v-treeview/misc-selectable-icons\" />\n\n### Indent lines\n\nThe `v-treeview` component can be configured to show indent lines. The `indent-lines` prop controls lines visibility and the variant.\n\n<ExamplesExample file=\"v-treeview/misc-indent-lines\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/vertical-steppers.md",
    "content": "---\nmeta:\n  nav: Steppers Vertical\n  title: Vertical Stepper component\n  description: The vertical stepper component is a navigation element that guides users through a sequence of steps.\n  keywords: vertical stepper, vuetify vertical stepper component, vue vertical stepper component\nrelated:\n  - /components/buttons/\n  - /components/icons/\n  - /styles/transitions/\nfeatures:\n  report: true\n---\n\n# Vertical Steppers\n\nThe `v-stepper-vertical` component can be used as a navigation element that guides users through a sequence of steps.\n\n<PageFeatures />\n\n## Installation\n\nLabs components require manual import and registration with the Vuetify instance.\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport {\n  VStepperVertical,\n  VStepperVerticalItem,\n  VStepperVerticalActions,\n} from 'vuetify/labs/VStepperVertical'\n\nexport default createVuetify({\n  components: {\n    VStepperVertical,\n    VStepperVerticalItem,\n    VStepperVerticalActions,\n  },\n})\n```\n\n## Usage\n\nVertical steppers allow users to complete a series of actions in step order.\n\n<ExamplesUsage name=\"v-stepper-vertical\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-stepper-vertical](/api/v-stepper-vertical/) | Primary Component |\n\n<ApiInline hide-links />\n\n### Guide\n\nThe `v-stepper-vertical` is the vertical variant of the [v-stepper](/components/steppers/) component. It also extends functionality of [v-expansion-panels](/components/expansion-panels/).\n\n#### Props\n\n#### Non linear\n\nNon-linear stepper allow the user to navigate freely – skip to a desired section without forcing clicks on the action buttons within, provided **editable** prop is also present. When combined with `:mandatory=\"false\"`, allowes to collapse the section as well.\n\n<ExamplesExample file=\"v-stepper-vertical/prop-non-linear\" />\n\n#### Slots\n\nThe `v-stepper-vertical` component has several slots for customization.\n\n##### Actions\n\nCustomize the flow of your stepper by hooking into the available **prev** and **next** slots.\n\n<ExamplesExample file=\"v-stepper-vertical/slot-actions\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/videos.md",
    "content": "---\nmeta:\n  nav: Videos\n  title: Video component\n  description: The video component acts as a customizable wrapper for native video element.\n  keywords: video, player, vuetify video component, vue video component\nfeatures:\n  github: /labs/VVideo/\n  label: 'C: VVideo'\n  report: true\n---\n\n# Video\n\nThe `v-video` component is useful for background video or as a customizable player for self-hosted content.\n\n<PageFeatures />\n\n## Installation\n\nLabs components require manual import and registration with the Vuetify instance.\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { VVideo } from 'vuetify/labs/VVideo'\n\nexport default createVuetify({\n  components: {\n    VVideo,\n  },\n})\n```\n\n## Usage\n\nA basic example of the video component.\n\n<ExamplesUsage name=\"v-video\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-video](/api/v-video/) | Primary Component |\n| [v-video-controls](/api/v-video-controls/) | Sub-component used to display a video player controls |\n| [v-video-volume](/api/v-video-volume/) | Sub-component used to display a volume control |\n\n<ApiInline hide-links />\n\n::: warning\n\nThis component is only useful if you self-host videos or when you can reliably obtain direct media file URL and it is permitted by the host terms of service to use custom players.\n\n:::\n\n## Guide\n\nThe `v-video` component lets you display videos with controls that nicely fit into your app design. It comes equiped with common keyboard shortcuts, and three predefined control variants.\n\nAll attributes that are not explicitly defined in the component API (`autoplay`, `muted`, `loop`, etc.) are passed to the underlying native HTML video element.\n\n### Props\n\nThe `v-video` component has several props that allow you to customize its appearance and behavior.\n\n#### Image\n\nYou can display a cover image before the video is loaded.\n\n<ExamplesExample file=\"v-video/prop-image\" />\n\n#### Start at\n\nVideo can automatically skip to certain timestamp upon load. It can be useful to let the users continue where they stopped last time.\n\n<ExamplesExample file=\"v-video/prop-start-at\" />\n\n#### Color\n\nYou can control the icon color and background color of the controls.\n\n<ExamplesExample file=\"v-video/prop-color\" />\n\n#### Density\n\nThree density modes provide basic control over control bar height and the icon sizes.\n\n<ExamplesExample file=\"v-video/prop-density\" />\n\n#### Rounded\n\nBorder radius for the video and controls can be controled separately if you pass an array to the `rounded` prop.\n\n<ExamplesExample file=\"v-video/prop-rounded\" />\n\n### Slots\n\nThe `v-video` component has several slots that allow you to customize the appearance and behavior of its items.\n\n<!--\n#### Sources\n\nUsing the the **sources** slot you can make it possible to select different playback quality.\n\n<ExamplesExample file=\"v-video/slot-sources\" />\n-->\n\n#### Error\n\nThe `error` prop can be used to manually force the error state. This might be useful if an operation fails and you did not obtain the source URL or Blob yet. By default error state shows only an icon, but you can add more details simply using the `error` slot and trigger retry using the exposed `retry` method.\n\n<ExamplesExample file=\"v-video/slot-error\" />\n\n#### Header\n\nOptional **header** slot make it possible to put additional content on top of the video.\n\n<ExamplesExample file=\"v-video/slot-header\" />\n\n#### Append and prepend\n\n`v-video` has `append` and `prepend` slots. You can place custom controls in them.\n\n<ExamplesExample file=\"v-video/slot-append-and-prepend\" />\n\n#### Controls\n\nWhenever provided customizability is not enough, the `controls` slot lets you drop all the built-in controls and easily define your own set of actions.\n\n<ExamplesExample file=\"v-video/slot-controls\" />\n\n## Examples\n\nThe following are a collection of examples that demonstrate more advanced and real world use of the `v-video` component.\n\n### Video card\n\nProps like `floating`, `detached` and `split-time` can help you seamlesly integrate the video within card layout.\n\n<ExamplesExample file=\"v-video/misc-in-card\" />\n\n### YouTube clone\n\nEasily recreate the most familiar interface to let your users focus on the content.\n\n<ExamplesExample file=\"v-video/misc-tube\" />\n\n### Minimalistic players\n\nYou can override bottom panel to have achieve minimalistic design.\n\n<ExamplesExample file=\"v-video/misc-mini\" />\n\n<!--\n### Progress tracker\n\nTap into exposed `video` element to achieve more control and precisely track the progress.\n\n<ExamplesExample file=\"v-video/misc-progress-tracker\" />\n-->\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/virtual-scroller.md",
    "content": "---\nmeta:\n  nav: Virtual scrollers\n  title: Virtual scroll component\n  description: The Virtual scroll component is a container that renders only visible elements. It is useful when you need to display large amounts of uniform data.\n  keywords: virtual scroll, vuetify virtual scroll component, vue virtual scroll component, v-virtual-scroll component\nrelated:\n  - /components/lists/\n  - /components/data-tables/virtual-tables/\n  - /components/combobox/\nfeatures:\n  github: /components/VVirtualScroller/\n  label: 'C: VVirtualScroller'\n  report: true\n---\n\n# Virtual scrollers\n\nThe `v-virtual-scroll` component displays a virtual, _infinite_ list. It supports dynamic height and scrolling vertically and is a good alternative to pagination.\n\n<PageFeatures />\n\n## Usage\n\nThe virtual scroller displays just enough records to fill the viewport and uses the existing component, rehydrating it with new data.\n\n<ExamplesUsage name=\"v-virtual-scroll\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-virtual-scroll](/api/v-virtual-scroll/) | Primary Component |\n\n<ApiInline hide-links />\n\n## Anatomy\n\nThe `v-virtual-scroll` component contains only a default slot with no styling options. It is typically used with large collections of [v-list-item](/components/lists/)s.\n\n![Virtual scroll Anatomy](https://cdn.vuetifyjs.com/docs/images/components/v-virtual-scroll/v-virtual-scroll-anatomy.png)\n\n| Element / Area | Description |\n| - | - |\n| 1. Container | The rendered content area from the provided **items** prop |\n\n## Guide\n\nThe `v-virtual-scroll` allows you to display thousands of records on a single page without the performance hit of actually showing all of them at once. `v-virtual-scroll` is devoid of styling and pairs well with components such as [v-card](/components/cards/) to provide a better visual experience.\n\n### Props\n\nThe `v-virtual-scroll` component has a small API mainly used to configure the root and item height.\n\n#### Height\n\nThe `v-virtual-scroll` component does not have any initial height set on itself.\n\nThe following code snippet uses the **height** prop:\n\n<ExamplesExample file=\"v-virtual-scroll/prop-height\" />\n\nAnother way of making sure that the component has height is to place it inside an element with `display: flex`.\n\n<ExamplesExample file=\"v-virtual-scroll/prop-height-parent\" />\n\n#### Item Height\n\nFor lists where the item height is static and uniform for all items, it's recommended that you define a specific **item-height**. This value is used for `v-virtual-scroll`'s calculations.\n\n<ExamplesExample file=\"v-virtual-scroll/prop-item-height\" />\n\nIf your items are not of a uniform size, omit the **item-height** prop to have `v-virtual-scroll` dynamically calculate each item.\n\n<ExamplesExample file=\"v-virtual-scroll/prop-dynamic-item-height\" />\n\n#### Renderless\n\nRenderless mode does not generate DOM nodes automatically, so you must bind `itemRef` yourself for virtual scrolling to work properly.\n\n<ExamplesExample file=\"v-virtual-scroll/prop-renderless\" />\n\n### Examples\n\nThe following is a collection of `v-virtual-scroll` examples that demonstrate how different the properties work in an application.\n\n#### User Directory\n\nThe v-virtual-scroll component can render an large amount of items by rendering only what it needs to fill the scroller’s viewport.\n\n<ExamplesExample file=\"v-virtual-scroll/misc-user-directory\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/components/windows.md",
    "content": "---\nmeta:\n  nav: Windows\n  title: Window component\n  description: The window component is a wrapper container that allows transitioning between content. It serves as the baseline for tabs and carousels.\n  keywords: windows, vuetify window component, vue window component\nrelated:\n    - /components/carousels/\n    - /components/sheets/\n    - /components/tabs/\nfeatures:\n  github: /components/VWindow/\n  label: 'C: VWindow'\n  report: true\n---\n\n# Windows\n\nThe `v-window` component provides the baseline functionality for transitioning content from one pane to another. Other components such as `v-tabs`, `v-carousel` and `v-stepper` utilize this component at their core.\n\n<PageFeatures />\n\n## Usage\n\nDesigned to easily cycle through content, `v-window` provides a simple interface to create custom implementations.\n\n<ExamplesExample file=\"v-window/usage\" />\n\n<PromotedEntry />\n\n## API\n\n| Component | Description |\n| - | - |\n| [v-window](/api/v-window/) | Primary Component |\n| [v-window-item](/api/v-window-item/) | Sub-component used to display a single window item |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n#### Show arrows\n\nBy default no arrows are displayed. You can change this by adding the **show-arrows** prop. If you set the prop value to `\"hover\"`, they will only show when you mouse over the window.\n\n<ExamplesExample file=\"v-window/prop-show-arrows\" />\n\n#### Reverse\n\nThe **reverse** prop will reverse the transitions\n\n<ExamplesExample file=\"v-window/prop-reverse\" />\n\n#### Direction\n\nYou can change the transition to vertical using the **direction** prop\n\n<ExamplesExample file=\"v-window/prop-direction\" />\n\n#### Customized arrows\n\nArrows can be customized by using **prev** and **next** slots.\n\n<ExamplesExample file=\"v-window/slots-next-prev\" />\n\n### Misc\n\n#### Account creation\n\nCreate rich forms with smooth animations. `v-window` automatically tracks the current selection index to change the transition direction.\n\n<ExamplesExample file=\"v-window/misc-account-creation\" />\n\n#### Onboarding\n\n`v-window` makes it easy to create custom components such as a differently styled stepper.\n\n<ExamplesExample file=\"v-window/misc-onboarding\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/concepts/density-and-sizing.md",
    "content": "---\nmeta:\n  nav: Density and sizing\n  title: Density and sizing\n  description: Density and sizing\n  keywords: density, sizing\nrelated:\n  - /components/buttons/\n  - /components/chips/\n  - /components/lists/\n---\n\n# Density and sizing\n\nThe **size** and **density** props are used to reduce the overall space a component takes up, and sometimes font-size, height, padding, and margins.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## Guide\n\nThe **size** and **density** props are used to reduce the overall space a component takes up, and sometimes font-size, height, padding, and margins.\n\n### Size\n\nThis property reduces or increases the width and height a component takes up, as well as font-size.\n\n- x-small\n- small\n- default\n- large\n- x-large\n\n**Example**\n\nThe following example shows the size for various components:\n\n<ExamplesExample file=\"concepts/size\" preview />\n\n### Density\n\nReduces vertical padding and sometimes font size. Square/round components like icons will also reduce horizontal padding.\n\n- default\n- comfortable\n- compact\n\n**Example**\n\nThe following example shows the density for various components:\n\n<ExamplesExample file=\"concepts/density\" preview />\n\n::: warning\n\nNot all components have a default transition that animates height when changing density.\n\n:::\n\n### Combined\n\nCombine the **size** and **density** props to easily change the overall size of a component.\n\n**Example**\n\nThe following example shows the size and density for various components:\n\n<ExamplesExample file=\"concepts/density-and-size\" preview />\n"
  },
  {
    "path": "packages/docs/src/pages/en/concepts/items.md",
    "content": "---\nmeta:\n  nav: Items\n  title: Items\n  description: Items\n  keywords: items\nrelated:\n  - /components/lists/\n  - /components/selects/\n  - /components/data-tables/\n---\n\n# Items\n\nItems are the data that is displayed in a component. They can be passed as an array of objects or strings.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## Guide\n\nItem props allow you to map the properties of each item to the component's props. This allows you to customize the display of each item without having to manually extract the data.\n\n### Accessor props\n\nAccessor props are they keys to look for in each item object. They can be set to a string, array, or function.\n\n- **item-title:** The title of each item.\n- **item-value:** The value of each item.\n- **item-children:** The children of each item.\n- **item-props:** The props of each item.\n\n### String\n\nSpecify the property to use for the title when you have an array of user objects:\n\n```html\n<v-component\n  item-title=\"name\"\n  item-title=\"user.name\"\n/>\n```\n\nThis makes it easy to display nested properties without manually extracting them.\n\n### Array\n\nLookup on each item object. Like dot notation (each member is a key in the current object), but can be used if the key contains a dot.\n\n```html\n<v-component\n  :item-title=\"['name']\"\n  :item-title=\"['user', 'name']\"\n/>\n```\n\n### Function\n\nA function that returns the value to use for the title. This is useful if you need to format the value or access a property that is not a direct child of the item.\n\n```html\n<v-component\n  :item-title=\"item => item.name\"\n  :item-title=\"item => item.user.name\"\n/>\n```\n"
  },
  {
    "path": "packages/docs/src/pages/en/concepts/routing.md",
    "content": "---\nmeta:\n  nav: Routing\n  title: Routing\n  description: Routing\n  keywords: routing\nrelated:\n  - /components/buttons/\n  - /components/lists/\n  - /components/overlays/\n---\n\n# Routing\n\nRouting is the process of navigating between different views or pages in an application.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## Guide\n\n[Vue Router](https://router.vuejs.org/) is the official router for Vue. It allows you to define routes and map them to components, enabling navigation between different views in your application.\n\nThe following components have built in support for routing:\n\n- [v-breadcrumbs](/components/breadcrumbs/)\n- [v-btn](/api/v-btn/)\n- [v-card](/api/v-card/)\n- [v-chip](/api/v-chip/)\n- [v-list](/api/v-list-item/)\n\nThese components can act like a [router-link](https://router.vuejs.org/guide/advanced/extending-router-link.html) and have access to props such as **to** and **exact**:\n\n```html\n<v-btn to=\"/home\" text=\"Home\"></v-btn>\n```\n\n## Router view transitions\n\nVue Router lets you add transitions between different views. The **router-view** component is used to render the current route's component, and you can use the **transition** component to add transitions between different views.\n\n```html { resource=\"src/App.vue\" }\n<template>\n  <v-app>\n    <v-app-bar app>\n      <v-toolbar-title>My App</v-toolbar-title>\n    </v-app-bar>\n\n    <v-main>\n      <router-view v-slot=\"{ Component }\">\n        <v-fade-transition hide-on-leave>\n          <component :is=\"Component\" />\n        </v-fade-transition>\n      </router-view>\n    </v-main>\n  </v-app>\n</template>\n```\n\nVisit the [Transitions](/styles/transitions) page for more information.\n\n::: tip\n\nOverlay components can be closed with the browser back button, but this also triggers when calling `router.back()`. Use `:close-on-back=\"false\"` to disable this behavior.\n\n:::\n"
  },
  {
    "path": "packages/docs/src/pages/en/concepts/v-model.md",
    "content": "---\nmeta:\n  nav: v-model\n  title: v-model\n  description: v-model\n  keywords: v-model\nrelated:\n  - /components/lists\n  - /components/text-fields\n---\n\n# v-model\n\nv-model is a built in Vue directive that allows you to create two-way data bindings.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## Guide\n\nv-model is a directive that allows you to create two-way data bindings between a component and its parent. It is commonly used with form elements, such as input fields, checkboxes, and select boxes, to bind the value of the element to a data property in the parent component.\n\n### Binding models\n\n- **v-model:** is shorthand for **model-value** and **@update:model-value**\n- **v-model:prop:** is shorthand for binding specific properties as a model\n\nIf both prop and event are defined, the model is \"controlled\" and the prop is used as the value. If only the prop is defined, the model is \"uncontrolled\" and the prop is used as the initial value.\n\n```html\n<template>\n  <v-text-field v-model=\"foo\" />\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const foo = shallowRef('foo')\n</script>\n```\n\nIs the same as:\n\n```html\n<template>\n  <v-text-field :model-value=\"foo\" @update:model-value=\"onUpdateModel\" />\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const foo = shallowRef('foo')\n\n  function onUpdateModel (value) {\n    foo.value = value\n  }\n</script>\n```\n\nControlled models must be handled externally, if the updated value is not passed back to the prop, the component will not update. This can be useful for conditionally ignoring updates or preventing certain values from being entered.\n\nA static value can be set by defining the prop with an initial value, and defining the event with a noop function.\n\n```html\n<template>\n  <v-text-field model-value=\"Foobar\" @update:model-value=\"onUpdateModel\" />\n</template>\n\n<script setup>\n  function onUpdateModel (value) {\n    // noop\n  }\n</script>\n```\n\n### Binding specific properties\n\nSome components such as [v-list](/components/lists/) and [v-text-field](/components/text-fields/) have specific properties that can be bound as a model.\n\n```html\n<template>\n  <v-list\n    v-model:active=\"active\"\n    v-model:opened=\"opened\"\n    v-model:selected=\"selected\"\n  />\n\n  <v-text-field\n    v-model=\"model\"\n    v-model:focus=\"focus\"\n  />\n</template>\n\n<script setup>\n  import { shallowRef } from 'vue'\n\n  const active = shallowRef([])\n  const opened = shallowRef([])\n  const selected = shallowRef([1])\n  const model = shallowRef('')\n  const focus = shallowRef(false)\n</script>\n```\n"
  },
  {
    "path": "packages/docs/src/pages/en/concepts/variants.md",
    "content": "---\nmeta:\n  nav: Variants\n  title: Variants\n  description: Understanding and utilizing the variant prop in Vuetify\n  keywords: variant, Vuetify\nrelated:\n  - /components/buttons/\n  - /components/lists/\n---\n\n# Variants\n\nVariants are a powerful feature that allows you to customize the appearance and behavior of components.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## Sheet components\n\nSheet components in Vuetify offer different stylistic variants to make it easy to fit them into different design contexts. Below is a table summarizing the six available variants.\n\n| Variant    | Description                                                |\n|------------|------------------------------------------------------------|\n| `elevated` | Provides a subtle box-shadow for a depth effect.           |\n| `flat`     | No shadow or depth, lies flat against the content.         |\n| `tonal`    | Adjusts the tone of the component's background.            |\n| `outlined` | Adds a colored border around the component.                |\n| `text`     | Removes the background color and elevation.                |\n| `plain`    | No styles, offering a clean slate for customization.       |\n\n## Field components\n\nField components in Vuetify offer a comprehensive set of stylistic variants to elevate your forms and input fields. Whether you're into Material Design or love to experiment, there's a variant for every design challenge.\n\n| Variant        | Description   |\n| -------------- | ------------- |\n| `underlined`   | A Material Design 2 variant with a focus underline. |\n| `outlined`     | Adds a border that lifts the label when the field is focused. |\n| `filled`       | The input field features a filled background. |\n| `solo`         | Stands alone with subtle elevation for a distinct look. |\n| `solo-inverted`| Similar to `solo` but inverts input color when focused. |\n| `solo-filled`  | Like `solo`, but with a filled background. |\n| `plain`        | Strips away most styles for an almost blank slate. |\n"
  },
  {
    "path": "packages/docs/src/pages/en/directives/click-outside.md",
    "content": "---\nmeta:\n  nav: Click outside\n  title: Click outside directive\n  description: The v-click-outside directive calls a function when something outside of the target element is clicked on.\n  keywords: click outside, click directive, vue click directive, vuetify click directives\nrelated:\n  - /components/dialogs/\n  - /components/navigation-drawers/\n  - /directives/intersect/\n---\n\n# Click outside\n\nThe `v-click-outside` directive calls a function when something outside of the target element is clicked on. This is used internally by components like `v-menu` and `v-dialog`.\n\n<PageFeatures />\n\n## Usage\n\nThe `v-click-outside` directive allows you to provide a handler to be invoked when the user clicks outside of the target element.\n\n<ExamplesExample file=\"v-click-outside/usage\" />\n\n<PromotedEntry />\n\n## API\n\n<ApiInline />\n\n## Examples\n\n### Options\n\n#### Close conditional\n\nOptionally provide a `closeConditional` handler that returns `true` or `false`. This function determines whether the outside click function is invoked or not.\n\n<ExamplesExample file=\"v-click-outside/option-close-on-outside-click\" />\n\n#### Include\n\nOptionally provide an `include` function in the `options` object that returns an array of `HTMLElement`s. This function determines which additional elements that the click must be outside of, for the handler to be called.\n\n<ExamplesExample file=\"v-click-outside/option-include\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/directives/intersect.md",
    "content": "---\nmeta:\n  nav: Intersection observer\n  title: Intersection observer directive\n  description: The intersection observer directive utilizes the Intersection observer API. It allows you to determine when elements are visible on the screen.\n  keywords: intersect, vuetify intersect directive, intersection observer directive\nrelated:\n  - /components/cards/\n  - /components/images/\n  - /components/text-fields/\n---\n\n# Intersection observer\n\nThe `v-intersect` directive utilizes the [Intersection Observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API). It provides an easy-to-use interface for detecting when elements are visible within the user's viewport. This is also used for the [v-lazy](/components/lazy) component.\n\n<PageFeatures />\n\n## Usage\n\nScroll the window and watch the colored dot. Notice as the [v-card](/components/cards) comes into view that it changes from error to success.\n\n<ExamplesExample file=\"v-intersect/usage\" />\n\n<PromotedEntry />\n\n## API\n\n| Directive                                  | Description                         |\n|--------------------------------------------|-------------------------------------|\n| [v-intersect](/api/v-intersect-directive/) | The intersection observer directive |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Props\n\n#### Options\n\nThe `v-intersect` directive accepts options. Available options can be found in the [Intersection Observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API). Below is an example using the `threshold` option.\n\n<ExamplesExample file=\"v-intersect/prop-options\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/directives/mutate.md",
    "content": "---\nmeta:\n  nav: Mutation observer\n  title: Mutation observer directive\n  description: The mutation observer directive utilizes the Mutation observer API. It allows you to invoke a callback when targeted elements are updated.\n  keywords: mutate, vuetify mutate directive, mutation observer directive, mutation observer\nrelated:\n  - /components/sheets/\n  - /components/images/\n  - /directives/intersect/\n---\n\n# Mutation observer\n\nThe `v-mutate` directive utilizes the [Mutation Observer API](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver). It provides an easy to use interface for detecting when elements are updated.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## Usage\n\n`v-mutate` is a simple interface for the [Mutation Observer API](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) that is implemented with [Vue directives](https://v3.vuejs.org/api/directives.html). There are two main ways to alter `v-mutate`'s options; with directive modifiers using period notation, or with a custom options object. The following table contains information on the available directive modifiers:\n\n| Modifier     | Default      | Description |\n| ------------ | -----------  | ----------- |\n| `.attr`      | `true`       | The [attr](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserverInit/attributes) modifier monitors target node's attribute changes                                                       |\n| `.char`      | `true`       | The [char](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserverInit/characterData) modifier monitors changes to target node's character data (and, its descendants if `.sub` is `true`)       |\n| `.child`     | `true`       | The [child](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserverInit/childList) modifier monitors for the addition or removal of child nodes (and, its descendants if `.sub` is `true`) |\n| `.sub`       | `true`       | The [sub](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserverInit/subtree) modifier extends all monitoring to the entire subtree of target node                                        |\n| `.once`      | `undefined`  | The [once](#once) modifier invokes the user provided callback one time and disconnects the observer                                                                                                  |\n| `.immediate` | `undefined`  | The [immediate](#immediate) modifier invokes the user provided callback on _mounted_ and does not effect `.once`                                                                                     |\n\nBy default, `v-mutate` enables `.attr`, `.char`, `.child`, and `.sub` unless you manually apply one; in which case the undefined options are set to false:\n\n```html { resource=\"Component.vue\" }\n<template>\n  <div>\n    <!-- attr, char, child, and sub are true -->\n    <div v-mutate=\"...\" />\n\n    <!-- child is true, attr, char, and child are false -->\n    <div v-mutate.child=\"...\">\n  </div>\n</template>\n```\n\nIn addition to the _modifier_ syntax, the `v-mutate` directive is configurable via a custom object containing a **handler** and **options** key. The following example demonstrates how both processes achieve the same result:\n\n```html { resource=\"Component.vue\" }\n<template>\n  <div>\n    <div v-mutate=\"{\n      handler: onMutate,\n        modifiers: {\n          child: true,\n          sub: true,\n        }\n      }\"\n    />\n\n    <!-- is the same as -->\n\n    <div v-mutate.child.sub=\"onMutate\" />\n  </div>\n</template>\n\n<script setup>\n  function onMutate () {\n    //\n  }\n</script>\n```\n\n::: warning\n  When using custom options, it's recommended to use the `.sub` modifier. This extends mutation monitoring to all descendants of the target element.\n:::\n\n### Once\n\nThere may be times where your callback should only fire once. In these scenarios, use the **once** option to disconnect the observer after the first detected mutation. In the next example, we bind data value _content_ to 2 separate [v-card](/components/cards/) components and an `input`; then track the number of mutations that occur as we type:\n\n```html { resource=\"Component.vue\" }\n<template>\n  <div>\n    <input type=\"text\" v-model=\"content\">\n\n    <v-card v-mutate=\"onMutate\">{{ content }}</v-card>\n\n    <v-card v-mutate.once=\"onMutate\">{{ content }}</v-card>\n  </div>\n</template>\n\n<script setup>\n  import { onMounted, shallowRef } from 'vue'\n\n  const content = shallowRef('Foo')\n  const mutations = shallowRef(0)\n\n  onMounted(() => {\n    content.value = 'Bar'\n\n    console.log(mutations.value) // 2\n\n    setTimeout(() => {\n      content.value = 'Foobar'\n\n      console.log(mutations.value) // 3\n    }, 200)\n  })\n\n  function onMutate () {\n    mutations.value++\n  }\n</script>\n```\n\nWhen the value of content changes, both cards immediately call _onMutate_ and iterate the value of the _mutations_ data value. Because the second card is using the **once** modifier, it automatically unbinds its observer after the first change to _content_.\n\n### Immediate\n\nUnlike the [Intersection Observer API](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver), the provided callback is **not** immediately invoked when a Mutation Observer is created. Vuetify normalizes this behavior with the **immediate** option. In the following example, the `v-mutate` directive invokes the _onMutate_ method when the element is initially mounted in the DOM **and** with every mutation; based upon the provided options.\n\n```html { resource=\"Component.vue\" }\n<template>\n  <div v-mutate.immediate=\"onMutate\">...</div>\n</template>\n\n<script setup>\n  import { onMounted, shallowRef } from 'vue'\n\n  const mutations = shallowRef(0)\n\n  onMounted(() => {\n    console.log(mutations.value) // 1\n  })\n\n  function onMutate () {\n    mutations.value++\n  }\n</script>\n```\n\n::: info\n  The **immediate** callback is not counted as a mutation and does not trigger the observer to disconnect when using **once**.\n:::\n\n## API\n\n| Directive                            | Description                     |\n|--------------------------------------|---------------------------------|\n| [v-mutate](/api/v-mutate-directive/) | The mutation observer directive |\n\n<ApiInline hide-links />\n\n## Examples\n\n<ExamplesExample file=\"v-mutate/usage\" />\n\n<ExamplesExample file=\"v-mutate/option-modifiers\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/directives/resize.md",
    "content": "---\nmeta:\n  nav: Resize\n  title: Resize directive\n  description: The resize directive provides the ability to conditionally invoke functions when the screen is resized.\n  keywords: resize, vuetify resize directive, vue resize directive, window resize directive\nrelated:\n  - /features/display-and-platform/\n  - /components/grids/\n  - /styles/flex/\n---\n\n# Resize directive\n\nThe `v-resize` directive can be used for calling specific functions when the window resizes.\n\n<PageFeatures />\n\n## Usage\n\nResize your window and observe the values change..\n\n<ExamplesExample file=\"v-resize/usage\" />\n\n<PromotedEntry />\n\n## API\n\n| Directive                            | Description          |\n|--------------------------------------|----------------------|\n| [v-resize](/api/v-resize-directive/) | The resize directive |\n\n<ApiInline hide-links />\n"
  },
  {
    "path": "packages/docs/src/pages/en/directives/ripple.md",
    "content": "---\nmeta:\n  nav: Ripple\n  title: Ripple directive\n  description: The ripple directive adds touch and click feedback to any element in the form of a water ripple.\n  keywords: ripples, ink, vuetify ripple directive, vue ripple directive\nrelated:\n  - /components/buttons/\n  - /components/expansion-panels/\n  - /styles/transitions/\n---\n\n# Ripple directive\n\nThe `v-ripple` directive is used to show action from a user. It can be applied to any block level element. Numerous components come with the ripple directive built in, such as the `v-btn`, `v-tabs-item` and many more.\n\n<PageFeatures />\n\n## Usage\n\nBasic ripple functionality can be enabled just by using `v-ripple` directive on a component or an HTML element\n\n<ExamplesExample file=\"v-ripple/usage\" />\n\n<PromotedEntry />\n\n## API\n\n| Directive                            | Description          |\n|--------------------------------------|----------------------|\n| [v-ripple](/api/v-ripple-directive/) | The ripple directive |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Propagation\n\nIf multiple elements have the ripple directive applied, only the inner one will show the effect. This can also be done without having a visible ripple by using `v-ripple.stop` to prevent ripples in the outer element if the inner element is clicked on. `v-ripple.stop` will not actually stop propagation of the mousedown/touchstart events unlike other workarounds.\n\n<ExamplesExample file=\"v-ripple/stop\" />\n\n### Options\n\n#### Center\n\nWhen a `center` option is used ripple will always originate from the center of the target.\n\n<ExamplesExample file=\"v-ripple/option-center\" />\n\n### Misc\n\n#### Custom color\n\nUsing a helper class, you can change the color of the ripple.\n\n<ExamplesExample file=\"v-ripple/misc-custom-color\" />\n\n#### Ripple in components\n\nSome components provide the `ripple` prop that allows you to control the ripple effect. You can turn it off or customize the behavior by using `class` or `center` options.\n\n<ExamplesExample file=\"v-ripple/misc-ripple-in-components\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/directives/scroll.md",
    "content": "---\nmeta:\n  nav: Scroll\n  title: Scroll directive\n  description: The scroll directive gives you the ability to conditionally invoke methods when the screen or an element are scrolled.\n  keywords: scroll, vuetify scroll directive, vue scroll directive, window scroll directive\nrelated:\n  - /components/app-bars/\n  - /components/bottom-navigation/\n  - /directives/touch/\n---\n\n# Scroll directive\n\nThe `v-scroll` directive allows you to provide callbacks when the window, specified target or element itself (with `.self` modifier) is scrolled.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n<!-- ## Usage\n\nThe default behavior is to bind to the window. If no additional configuration options are needed, you can simply pass your callback function.\n\n<ExamplesExample file=\"v-scroll/usage\" /> -->\n\n## API\n\n| Directive                            | Description          |\n|--------------------------------------|----------------------|\n| [v-scroll](/api/v-scroll-directive/) | The scroll directive |\n\n<ApiInline hide-links />\n\n## Examples\n\n### Options\n\n#### Self\n\n`v-scroll` targets the `window` by default but can also watch the element it's being bound to. In the following example we use the **self** modifier, `v-scroll.self`, to watch the [`v-card`](/components/cards) element specifically. This causes the method `onScroll` to invoke as you scroll the card contents; incrementing the counter.\n\n<ExamplesExample file=\"v-scroll/option-self\" />\n\n#### Target\n\nFor a more fine tuned approach, you can designate the target to bind the scroll event listener.\n\n<ExamplesExample file=\"v-scroll/option-target\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/directives/tooltip.md",
    "content": "---\nmeta:\n  nav: Tooltip\n  title: Tooltip directive\n  description: The Tooltip directive is an easy to use implementation of VTooltip.\n  keywords: Tooltip, vuetify Tooltip directive, vue Tooltip directive, mobile Tooltip directive\nrelated:\n  - /components/navigation-drawers/\n  - /components/slide-groups/\n  - /components/windows/\nfeatures:\n  report: true\n---\n\n# Tooltip directive\n\nThe `v-tooltip` directive is a shorthand way of adding tooltips to elements in your application.\n\n<PageFeatures />\n\n## Usage\n\nThe `v-tooltip` directive makes it easy to add a tooltip to any element in your application. It is a wrapper around the `v-tooltip` component.\n\n<ExamplesUsage name=\"v-tooltip-directive\" />\n\n<PromotedEntry />\n\n## API\n\n| Directive                          | Description         |\n|------------------------------------|---------------------|\n| [v-tooltip](/api/v-tooltip-directive/) | The Tooltip directive |\n\n## Guide\n\nThe `v-tooltip` directive is a simple way to add a tooltip to any element in your application. It is a wrapper around the `v-tooltip` component.\n\n### Location\n\nLocation is set as a directive argument with the same syntax as the component's `location` prop separated by a hyphen instead of a space.\n\n<ExamplesExample file=\"v-tooltip-directive/args\" />\n\n### Tooltip text\n\nBy default the tooltip will use the target element's [`textContent`](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent#differences_from_innertext), or you can pass another string as a directive value. Remember directive values are expressions so static strings must be quoted.\n\n<ExamplesExample file=\"v-tooltip-directive/text\" />\n\n### Other props\n\nThe `v-tooltip` directive can also accept an object of [VTooltip props](/api/v-tooltip/#props) as a value (use camelCase keys).\n\n<ExamplesExample file=\"v-tooltip-directive/object-literals\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/directives/touch.md",
    "content": "---\nmeta:\n  nav: Touch\n  title: Touch directive\n  description: The touch directive provides an interface for responding to various user touch actions.\n  keywords: touch, vuetify touch directive, vue touch directive, mobile touch directive\nrelated:\n  - /components/navigation-drawers/\n  - /components/slide-groups/\n  - /components/windows/\n---\n\n# Touch directive\n\nThe `v-touch` directive allows you to capture swipe gestures and apply directional callbacks.\n\n<PageFeatures />\n\n## Usage\n\nOn a mobile device, try swiping in various directions.\n\n<ExamplesExample file=\"v-touch/usage\" />\n\n<PromotedEntry />\n\n## API\n\n| Directive                          | Description         |\n|------------------------------------|---------------------|\n| [v-touch](/api/v-touch-directive/) | The touch directive |\n\n<ApiInline hide-links />\n"
  },
  {
    "path": "packages/docs/src/pages/en/features/accessibility.md",
    "content": "---\nmeta:\n  title: Accessibility (a11y)\n  description: See examples and the advantages of having accessibility (a11y) support in Vuetify components.\n  keywords: a11y, accessibility, usability\nrelated:\n  - /features/internationalization/\n  - /components/menus/\n  - /components/lists/\nfeatures:\n  label: 'a11y'\n  report: true\n---\n\n# Accessibility (a11y)\n\nWeb accessibility **(a11y for short)**, is the inclusive practice of ensuring there are no barriers that prevent the interaction with, or access to, websites on the World Wide Web by people with disabilities. Vuetify components are built to provide keyboard interactions for all mouse-based actions and utilize HTML5 semantic elements where applicable.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## Activator slots\n\nVuetify uses activator slots for many components such as `v-menu`, `v-dialog` and more. In some instances these activator elements should have specific a11y attributes that associate them with their corresponding content. In order to achieve this, we pass down the necessary a11y options through the slots scope.\n\n```html\n<!-- Vue Template HTML Markup -->\n\n<template>\n  <v-menu>\n    <template v-slot:activator=\"{ props }\">\n      <v-btn\n        text=\"Click me\"\n        v-bind=\"props\"\n      ></v-btn>\n    </template>\n\n    <v-list>\n      <v-list-item @click=\"method\">\n        <v-list-item-title>Option 1</v-list-item-title>\n      </v-list-item>\n\n      <v-list-item disabled>\n        <v-list-item-title>Option 2</v-list-item-title>\n      </v-list-item>\n\n      <v-list-item @click=\"method\">\n        <v-list-item-title>Option 3</v-list-item-title>\n      </v-list-item>\n    </v-list>\n  </v-menu>\n</template>\n```\n\nWhen the activator element is rendered, it will now contain the bound a11y attributes:\n\n```html\n<!-- Rendered `v-btn` HTML Output -->\n\n<button\n  aria-expanded=\"false\"\n  aria-haspopup=\"true\"\n  role=\"button\"\n  type=\"button\"\n>\n  Click me\n</button>\n```\n\n## Focus management and keyboard interactions\n\nBeyond attributes, components such as `v-menu` also support interaction by pressing <kbd>↑</kbd> and <kbd>↓</kbd> for navigating between options.\n\n### v-menu\n\nWhen inside of a `v-menu`, `v-list-item` will be automatically configured to have a role of **menuitem**. Navigate to the [Menu](/components/menus) for more information on the components features.\n\n<ExamplesExample file=\"accessibility/menu\" inline />\n\n## Additional Resources\n\nWhile Vuetify attempts to make a11y as easy as possible in your application, there are times where additional information is needed. Below you can find a list of helpful resources.\n\n- [W3C Web Accessibility Initiative](https://www.w3.org/WAI/)\n- [WAI-ARIA Authoring Practices](https://www.w3.org/WAI/ARIA/apg/)\n- [The A11Y Project](https://a11yproject.com/)\"\n"
  },
  {
    "path": "packages/docs/src/pages/en/features/aliasing.md",
    "content": "---\nmeta:\n  title: Aliasing\n  description: Description\n  keywords: keywords\nrelated:\n- /features/blueprints/\n- /features/global-configuration/\n- /features/treeshaking/\nfeatures:\n  report: true\n---\n\n# Aliasing & virtual components\n\nCreate virtual components that extend built-in Vuetify components using custom aliases.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## Usage\n\nAliasing allows you to use built-in Vuetify components as a baseline for your custom implementations. To get started, import the component that you want to extend. Provide it as the value of a unique key that is used for the virtual component's name:\n\n```js { resource=\"src/plugins/vuetify.js\"}\nimport { createVuetify } from 'vuetify'\nimport { VBtn } from 'vuetify/components/VBtn'\n\nexport default createVuetify({\n  aliases: {\n    MyButton: VBtn,\n    MyButtonAlt: VBtn,\n  },\n})\n```\n\n::: info\nAlthough treeshaking is automatically applied during production builds, it is advantageous to import components by specifying their full path in development mode. For instance, using `vuetify/components/VBtn` instead of `vuetify/components` ensures that the compiler loads fewer components, thus optimizing performance.\n:::\n\n## Virtual component defaults\n\nVirtual components have access to the Vuetify [Global configuration](/features/global-configuration/). Default settings for aliases are defined the same as built-in components with no extra steps required by you. In the following example, **MyButton** uses [v-btn props](/api/v-btn/#props) to change it's default **variant**:\n\n```js { resource=\"src/plugins/vuetify.js\"}\nimport { createVuetify } from 'vuetify'\nimport { VBtn } from 'vuetify/components/VBtn'\n\nexport default createVuetify({\n  aliases: {\n    MyButton: VBtn,\n  },\n  defaults: {\n    VBtn: { variant: 'flat' },\n    MyButton: { variant: 'tonal' },\n  },\n})\n```\n\n## Nested defaults\n\nProp defaults accept component key references to apply style changes based upon component hierarchy. In the following example, [v-btn](/components/buttons/) and **MyButton** swap colors when nested within a [v-card](/components/cards/) component.\n\n```js { resource=\"src/plugins/vuetify.js\"}\nimport { createVuetify } from 'vuetify'\nimport { VBtn } from 'vuetify/components/VBtn'\n\nexport default createVuetify({\n  aliases: {\n    MyButton: VBtn,\n  },\n  defaults: {\n    MyButton: {\n      color: 'primary',\n      variant: 'tonal',\n    },\n    VBtn: {\n      color: 'secondary',\n      variant: 'flat',\n    },\n    VCard: {\n      MyButton: { color: 'secondary' },\n      VBtn: { color: 'primary' },\n    },\n  },\n})\n```\n"
  },
  {
    "path": "packages/docs/src/pages/en/features/application-layout.md",
    "content": "---\nmeta:\n  title: Application layout\n  description: Vuetify provides functionality to create complex layouts using components such as app bars and navigation drawers\n  keywords: application, layout, default layout\nrelated:\n  - /components/app-bars/\n  - /components/navigation-drawers/\n  - /components/footers/\nfeatures:\n  github: /composables/layout.ts\n  label: 'E: layout'\n  report: true\n---\n\n# Application layout\n\nVuetify features an application layout system that allows you to easily create complex website designs.\n\n<PageFeatures />\n\n<PromotedEntry />\n\nThe system is built around an outside-in principle, where each application layout component reserves space for itself in one of four directions (left, right, up, down), leaving the available free space for any subsequent layout component(s) to occupy.\n\nThe following components are compatible with the layout system:\n\n| Component | Description |\n| - | - |\n| [v-app-bar](/components/app-bars/) | A container that is used navigation, branding, search, and actions |\n| [v-system-bar](/components/system-bars/) | A system bar replaces the native phone system bar |\n| [v-navigation-drawer](/components/navigation-drawers/) | A persistent or temporary container that holds site navigation links |\n| [v-footer](/components/footers/) | A generic component used to replace the default html footer |\n| [v-bottom-navigation](/components/bottom-navigation/) | A persistent or temporary container that holds navigation links and is typically used for smaller devices |\n\nThe final part of the layout system is the **v-main** component. Inside this is where you place your page content. It will use the remaining free space on the page after all layout components have reserved their space.\n\n::: info\n\nIn the following examples, **v-app** has been replaced by **v-layout**. This is because **v-app** defaults to a minimum height of `100dvh`. In your own application you would always use **v-app** for the root layout.\n\n:::\n\n## Usage\n\nBy default, the order in which layout components will attempt to reserve space is simply the order that they appear in your markup. To illustrate this concept, see the following two examples where a single **v-app-bar** and **v-navigation-drawer** have changed places in the markup.\n\n<ExamplesExample file=\"application-layout/app-bar-first\" />\n\n<ExamplesExample file=\"application-layout/nav-drawer-first\" />\n\nAs you can see, placing the **v-app-bar** before the **v-navigation-drawer** means that it will use the full width of the screen. When it it placed after the **v-navigation-drawer**, it will only use the free space left over.\n\nSome layout components accept a **location** prop with which you can place the component in the layout. In the example below, we use two **v-navigation-drawer** components, one on each side of the application.\n\n<ExamplesExample file=\"application-layout/location\" />\n\n## Complex layouts\n\nLet's create a more complex layout to show the flexibility of the system. In the following example we have re-created the general layout of the Discord application. This example also demonstrates that layout components accept either a **width** or **height** prop, and that multiple components of the same type can be stacked in the same position.\n\n<ExamplesExample file=\"application-layout/discord\" />\n\n## Dynamic layouts and order\n\nIn most cases, it should be enough to simply place your layout components in the correct order in your markup to achieve the layout you want. There are however a couple of scenarios where this might not be possible. One of these is if you want to change the order of your layout components dynamically.\n\nTo solve this you can explicitly set the layout order by using the **order** prop. Explore the example below to see what happens when using the prop. By toggling the switch, you change the order of the app-bar to `-1`, thus putting it above the navigation-drawer in the layout ordering.\n\nAll layout components have a default order of `0`. Layout components with the same order will be ordered as they appear in the markup.\n\n<ExamplesExample file=\"application-layout/dynamic\" />\n\n## Accessing layout information\n\nThe layout system exposes a function `getLayoutItem` that allows you to get size and position information about a specific layout component in your markup. To use it, you will need to add a **name** prop to the layout component, and give it a unique value. You can either access the method by using a ref on **v-app**, or by using the **useLayout** composable.\n\n<ExamplesExample file=\"application-layout/layout-information-ref\" />\n\n::: warning\n\nYou will not be able to directly use the composable in the same component where you are rendering the **v-app** component. The call to **useLayout** must happen in a child component, so that the layout can be properly injected.\n\n:::\n\n<ExamplesExample file=\"application-layout/layout-information-composable\" />\n\nThe combined size of all layout components is also available under `layout.mainRect`. This is used internally by the **v-main** component to determine the size of the main content area.\n"
  },
  {
    "path": "packages/docs/src/pages/en/features/blueprints.md",
    "content": "---\nmeta:\n  title: Blueprints\n  description: Setup your entire application with pre-made or custom styling and designs\n  keywords: vuetify blueprints, vuetify presets, vuetify schemas\nrelated:\n  - /features/global-configuration/\n  - /features/theme/\n  - /features/display-and-platform/\nfeatures:\n  github: /blueprints/\n  report: true\n---\n\n# Blueprints\n\nVuetify blueprints are a new way to pre-configure your entire application with a completely unique design system.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## Usage\n\nBlueprints are a collection of Vuetify configuration options that assign default values for components, colors, language, and more. Open your project's `vuetify.js` file and import the desired blueprint. The follow example demonstrates how to apply the [Material Design 1](#material-design-1) preset:\n\n```js { resource=plugins/vuetify.js }\nimport { createVuetify } from 'vuetify'\nimport { md1 } from 'vuetify/blueprints'\n\nexport default createVuetify({\n  blueprint: md1,\n})\n```\n\n### White-label concept\n\nWhile Vuetify is built under the guise of Google's [Material Design](https://material.io) specification, it is still flexible enough to be used as the foundation for any design system. By default, Vuetify components have no color and are **white-label** in nature. A white-label product is a product or service produced by one company that other companies rebrand to make it appear as if they had made it.\n\n## Available blueprints\n\n| Name | Release date | Status | Resource |\n| - | - | - | - |\n| [Material Design 1](#material-design-1) | 2014 | ✅ Available | [Specification](https://m1.material.io) |\n| [Material Design 2](#material-design-2) | 2017 | ✅ Available | [Specification](https://m2.material.io) |\n| [Material Design 3](#material-design-3) | 2022 | ✅ Available | [Specification](https://m3.material.io) |\n\n::: error\n\nBlueprints require the use of utility classes to properly function.\n\n:::\n\n### Material Design 1\n\nReleased in 2014, the original Material Design specification aimed to create a visual language that combined principles and good design with technical and scientific innovation.\n\n```javascript { resource=plugins/vuetify.js }\nimport { md1 } from 'vuetify/blueprints'\n```\n\n**Preview:**\n\n<ExamplesExample preview file=\"blueprints/md1\" />\n\n### Material Design 2\n\nReleased in 2017, version 2 of Google's design specification received a massive upgrade with new components, guidelines, and improved on the principles that made the first system so successful.\n\n```javascript { resource=plugins/vuetify.js }\nimport { md2 } from 'vuetify/blueprints'\n```\n\n**Preview:**\n\n<ExamplesExample preview file=\"blueprints/md2\" />\n\n### Material Design 3\n\nMaterial Design 3 is currently in active development and represents the next chapter of Google's design system.\n\n```javascript { resource=plugins/vuetify.js }\nimport { md3 } from 'vuetify/blueprints'\n```\n\n**Preview:**\n\n<ExamplesExample preview file=\"blueprints/md3\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/features/css-utilities/overview.md",
    "content": "---\nemphasized: true\nmeta:\n  nav: Overview\n  title: CSS Utilities - Overview\n  description: Reduce your CSS bundle size and unlock modern utility-first styling by integrating TailwindCSS or UnoCSS alongside Vuetify.\n  keywords: tailwindcss, unocss, css utilities, atomic css, css layers, vuetify css, bundle optimization\nrelated:\n  - /features/css-utilities/unocss-vuetify-preset/\n  - /features/css-utilities/tailwindcss/\n  - /styles/layers/\nfeatures:\n  report: true\n---\n\n# CSS Utilities - Overview\n\nIntegrate TailwindCSS or UnoCSS with Vuetify to reduce bundle size and unlock modern utility-first styling.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## Introduction\n\nWhile integrating third-party CSS utility libraries was technically possible with Vuetify v3, it required fighting specificity battles between Vuetify's own utility classes (generated with `!important`) and the incoming utilities. CSS layers — enabled by default in Vuetify v4 — change the picture. Layers give you an explicit cascade order between groups of styles, so utility-first CSS can sit above component styles without hacks or `!important` overrides.\n\n### Why integrate a CSS utility library?\n\nVuetify ships a large set of built-in utility classes (spacing, flex, display, text, etc.) that are included in every project by default. Integrating TailwindCSS or UnoCSS lets you:\n\n- **Reduce your main CSS bundle** — disable Vuetify's built-in utilities (`$utilities: false`) and let the external library generate only the classes actually used in your templates. In practice this typically shaves 150–200 kB (unminified) off the CSS entry file.\n- **Use dynamic and responsive variants** — utilities like `hover:bg-primary`, `sm:flex`, `dark:text-white`, and container queries are not available in Vuetify's built-in utilities but come for free with TailwindCSS or UnoCSS.\n- **Adopt a widely supported convention** — the TailwindCSS class naming convention is backed by excellent IDE tooling (Tailwind IntelliSense), standardized documentation, and a large ecosystem.\n\n### Limitations\n\nVuetify's built-in color utilities (`bg-primary`, `text-error`, etc.) automatically calculate a foreground color that ensures sufficient contrast. This works because Vuetify reads theme colors at runtime and applies a contrast multiplier based on the CSS custom property `--v-theme-on-*`. The CSS function `contrast-color()` that would enable the same automatic contrast adjustment in plain CSS is not yet supported in major browsers.\n\nWhen replacing Vuetify's color utilities with TailwindCSS or UnoCSS equivalents, this automatic contrast calculation is no longer available. **You are responsible for choosing foreground colors that remain legible against the chosen background.** Use Vuetify's `--v-theme-on-*` CSS variables as your text color wherever possible, or validate contrast ratios manually.\n\n---\n\n## Creating a new project\n\nThe quickest way to start a new Vuetify project — including optional TailwindCSS or UnoCSS integration — is through the official Vuetify CLI. Install the latest version globally and run the wizard:\n\n::: tabs\n\n```bash [pnpm]\npnpm add -g @vuetify/cli\nvuetify init\n```\n\n```bash [yarn]\nyarn global add @vuetify/cli\nvuetify init\n```\n\n```bash [npm]\nnpm i -g @vuetify/cli@latest\nvuetify init\n```\n\n```bash [bun]\nbun add -g @vuetify/cli\nvuetify init\n```\n\n:::\n\nThe wizard will walk you through selecting a project name, base framework (Vite or Nuxt), desired Vuetify version, and optional integrations including TailwindCSS or UnoCSS. You end up with a ready-to-run project.\n\nHere is what each combination looks like after scaffolding (static assets and boilerplate files are omitted for brevity):\n\n::: tabs\n\n```bash [Vite + TailwindCSS]\nvite-tailwindcss/\n├── src/\n│   ├── components/\n│   │   └── HelloWorld.vue\n│   ├── plugins/\n│   │   ├── index.ts\n│   │   └── vuetify.ts              # Vuetify configuration entrypoint\n│   ├── styles/\n│   │   ├── layers.css              # cascade layer order\n│   │   ├── settings.scss           # disables Vuetify's built-in utilities\n│   │   └── tailwind.css            # breakpoints, dark/light variants\n│   ├── App.vue\n│   └── main.ts                     # loads Tailwind stylesheet\n├── index.html\n├── package.json\n└── vite.config.mts                 # registers Tailwind CSS Vite plugin\n```\n\n```bash [Vite + UnoCSS Vuetify]\nvite-unocss-vuetify/\n├── src/\n│   ├── components/\n│   │   └── HelloWorld.vue\n│   ├── plugins/\n│   │   └── vuetify.ts              # Vuetify configuration entrypoint\n│   ├── styles/\n│   │   ├── layers.css              # cascade layer order\n│   │   └── settings.scss           # disables Vuetify's built-in utilities\n│   ├── App.vue\n│   └── main.ts                     # loads UnoCSS generated styles\n├── index.html\n├── package.json\n├── uno.config.ts                   # Vuetify preset and layer mapping\n└── vite.config.mts                 # UnoCSS Vite plugin\n```\n\n```bash [Vite + UnoCSS Wind4]\nvite-unocss-wind4/\n├── src/\n│   ├── components/\n│   │   └── HelloWorld.vue\n│   ├── plugins/\n│   │   └── vuetify.ts              # Vuetify configuration entrypoint\n│   ├── styles/\n│   │   ├── layers.css              # cascade layer order\n│   │   └── settings.scss           # disables Vuetify's built-in utilities\n│   ├── theme/\n│   │   └── breakpoints.ts          # shared breakpoints for Vuetify and UnoCSS\n│   ├── App.vue\n│   └── main.ts                     # loads UnoCSS generated styles\n├── index.html\n├── package.json\n├── uno.config.ts                   # Wind4 preset, dark mode, breakpoints\n└── vite.config.mts                 # UnoCSS Vite plugin\n```\n\n```bash [Nuxt + TailwindCSS]\nnuxt-tailwindcss/\n├── app/\n│   ├── assets/\n│   │   └── styles/\n│   │       ├── layers.css          # cascade layer order\n│   │       ├── settings.scss       # disables Vuetify's built-in utilities\n│   │       └── tailwind.css        # breakpoints, dark/light variants\n│   ├── components/\n│   │   └── HelloWorld.vue\n│   ├── pages/\n│   │   └── index.vue\n│   └── app.vue\n├── nuxt.config.ts                  # modules and style load order\n└── package.json\n```\n\n```bash [Nuxt + UnoCSS Vuetify]\nnuxt-unocss-vuetify/\n├── app/\n│   ├── assets/\n│   │   └── styles/\n│   │       ├── layers.css          # cascade layer order\n│   │       └── settings.scss       # disables Vuetify's built-in utilities\n│   ├── components/\n│   │   └── HelloWorld.vue\n│   ├── pages/\n│   │   └── index.vue\n│   └── app.vue\n├── nuxt.config.ts                  # modules, style order, Vuetify preset\n└── package.json\n```\n\n```bash [Nuxt + UnoCSS Wind4]\nnuxt-unocss-wind4/\n├── app/\n│   ├── assets/\n│   │   └── styles/\n│   │       ├── layers.css          # cascade layer order\n│   │       └── settings.scss       # disables Vuetify's built-in utilities\n│   ├── components/\n│   │   └── HelloWorld.vue\n│   ├── pages/\n│   │   └── index.vue\n│   ├── theme/\n│   │   └── breakpoints.ts          # shared breakpoints for Vuetify and UnoCSS\n│   └── app.vue\n├── nuxt.config.ts                  # modules, style order, Wind4 preset\n└── package.json\n```\n\n:::\n\n## Integration with existing projects\n\n| Guide                                                                     | Description                                                           |\n|---------------------------------------------------------------------------|-----------------------------------------------------------------------|\n| [UnoCSS — Vuetify preset](/features/css-utilities/unocss-vuetify-preset/) | Use `unocss-preset-vuetify` for on-demand Vuetify-style utilities.    |\n| [UnoCSS — presetWind4](/features/css-utilities/unocss-tailwind-preset/)   | Use `@unocss/preset-wind4` for TailwindCSS v4 conventions via UnoCSS. |\n| [TailwindCSS](/features/css-utilities/tailwindcss/)                       | Integrate TailwindCSS v4 into an existing Vite or Nuxt project.       |\n"
  },
  {
    "path": "packages/docs/src/pages/en/features/css-utilities/tailwindcss.md",
    "content": "---\nemphasized: true\nmeta:\n  nav: TailwindCSS\n  title: Vuetify + TailwindCSS\n  description: Integrate TailwindCSS v4 into an existing Vuetify project using Vite or Nuxt.\n  keywords: tailwindcss, tailwindcss v4, vuetify tailwind, css layers, vite, nuxt\nrelated:\n  - /features/css-utilities/\n  - /styles/layers/\n  - /features/sass-variables/\n---\n\n# TailwindCSS\n\nIntegrate TailwindCSS v4 into an existing Vuetify project for a smaller CSS bundle, on-demand utility generation, and variants like `hover:`, `dark:`, and responsive prefixes.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n---\n\n:::: tabs\n\n```bash [npx]\n# generate working project for reference\nnpx @vuetify/cli@latest init --type=vuetify --css=tailwindcss\n```\n\n```bash [pnpm]\n# generate working project for reference\npnpx @vuetify/cli@latest init --type=vuetify --css=tailwindcss\n```\n\n```bash [yarn]\n# generate working project for reference\nyarn dlx @vuetify/cli@latest init --type=vuetify --css=tailwindcss\n```\n\n```bash [bun]\n# generate working project for reference\nbunx @vuetify/cli@latest init --type=vuetify --css=tailwindcss\n```\n\n::::\n\n## Establish CSS layer order\n\nCreate a `layers.css` file that declares the cascade layers in order. `tailwind` goes above component styles but below `vuetify-final`, where Vuetify keeps its transitions:\n\n```css\n@layer tailwind-theme;\n@layer tailwind-reset;\n\n@layer vuetify-core;\n@layer vuetify-components;\n@layer vuetify-overrides;\n@layer vuetify-utilities;\n\n@layer tailwind-utilities;\n\n@layer vuetify-final;\n```\n\nThis file must be loaded **before** any other styles. In a **Vite** project, save it as `src/styles/layers.css` and import it at the top of `src/plugins/vuetify.ts`, before `vuetify/styles`. You can find the exact configuration snippets in the sections for Vite and Nuxt below.\n\n## Setup dependencies\n\n### Vite\n\nImport the layers file at the top of `src/plugins/vuetify.ts`, before `vuetify/styles`:\n\n```ts { resource=\"src/plugins/vuetify.ts\" }\nimport '../styles/layers.css'\nimport 'vuetify/styles'\n// ...\n```\n\nInstall TailwindCSS and the Vite plugin:\n\n::: tabs\n\n```bash [pnpm]\npnpm add -D tailwindcss @tailwindcss/vite\n```\n\n```bash [yarn]\nyarn add -D tailwindcss @tailwindcss/vite\n```\n\n```bash [npm]\nnpm i -D tailwindcss @tailwindcss/vite\n```\n\n```bash [bun]\nbun add -D tailwindcss @tailwindcss/vite\n```\n\n:::\n\nRegister `tailwindcss()` as the **first** entry in `plugins` inside `vite.config.mts`:\n\n```ts { resource=\"vite.config.mts\" }\nimport tailwindcss from '@tailwindcss/vite'\n\nexport default defineConfig({\n  plugins: [\n    tailwindcss(), // must come before Vuetify\n    // ...\n  ],\n})\n```\n\nImport the TailwindCSS stylesheet (see [Configure TailwindCSS](#configure-tailwindcss)) in `src/main.ts`:\n\n```ts { resource=\"src/main.ts\" }\nimport './styles/tailwind.css'\n```\n\n### Nuxt\n\n::: tabs\n\n```bash [pnpm]\npnpm add -D tailwindcss @tailwindcss/postcss\n```\n\n```bash [yarn]\nyarn add -D tailwindcss @tailwindcss/postcss\n```\n\n```bash [npm]\nnpm i -D tailwindcss @tailwindcss/postcss\n```\n\n```bash [bun]\nbun add -D tailwindcss @tailwindcss/postcss\n```\n\n:::\n\nRegister `@tailwindcss/postcss` as a PostCSS plugin in `nuxt.config.ts`. The `css` array controls load order — `layers.css` must come first, followed by `vuetify/styles`, then `tailwind.css`. Set `disableVuetifyStyles: true` — otherwise the module injects styles automatically and the order above is ignored:\n\n```ts { resource=\"nuxt.config.ts\" }\nexport default defineNuxtConfig({\n  modules: [\n    'vuetify-nuxt-module',\n    // ...\n  ],\n\n  css: [\n    'assets/styles/layers.css',\n    'vuetify/styles',\n    'assets/styles/tailwind.css',\n  ],\n\n  postcss: {\n    plugins: {\n      '@tailwindcss/postcss': {},\n    },\n  },\n\n  vuetify: {\n    moduleOptions: {\n      disableVuetifyStyles: true,\n      styles: { configFile: 'assets/styles/settings.scss' },\n    },\n  },\n})\n```\n\n## Configure TailwindCSS\n\nCreate `tailwind.css` (in `src/styles/` for Vite or `assets/styles/` for Nuxt). Tailwind's preflight is skipped because Vuetify ships its own reset. The `@custom-variant` declarations wire `dark:` and `light:` prefixes to Vuetify's theme classes, and breakpoints are overridden to match Vuetify's defaults:\n\n```css { resource=\"tailwind.css\" }\n@import \"tailwindcss/theme\" layer(tailwind-theme);\n@import \"tailwindcss/preflight\" layer(tailwind-reset);\n@import \"tailwindcss/utilities\" layer(tailwind-utilities);\n\n/* dark/light mode — Vuetify uses .v-theme--dark/.v-theme--light instead of .dark */\n@custom-variant light (&:where(.v-theme--light, .v-theme--light *));\n@custom-variant dark  (&:where(.v-theme--dark,  .v-theme--dark  *));\n\n@theme {\n  --breakpoint-*: initial; /* reset Tailwind defaults */\n  /* keep in sync with vuetify plugin/config and settings.scss */\n  --breakpoint-xs:  0px;\n  --breakpoint-sm:  600px;\n  --breakpoint-md:  960px;\n  --breakpoint-lg:  1280px;\n  --breakpoint-xl:  1920px;\n  --breakpoint-xxl: 2560px;\n}\n\n/*\n  note: adopt and extend values from TailwindCSS\n*/\n@utility rounded-pill   { border-radius: 9999px }\n@utility rounded-circle { border-radius: 50%    }\n@utility rounded-shaped { border-radius: 24px 0 }\n\n@source inline('rounded'); /* .25rem */\n@source inline('rounded-{none,sm,md,lg,xl,2xl,3xl,full,pill,circle,shaped}');\n\n/*\n  note: adopt elevation shadows from TailwindCSS\n*/\n@utility elevation-0 { box-shadow: none }\n@utility elevation-1 { box-shadow: var(--shadow-xs) }\n@utility elevation-2 { box-shadow: var(--shadow-sm) }\n@utility elevation-3 { box-shadow: var(--shadow-md) }\n@utility elevation-4 { box-shadow: var(--shadow-xl) }\n@utility elevation-5 { box-shadow: var(--shadow-2xl) }\n\n@source inline('elevation-{0,1,2,3,4,5}');\n```\n\n## Disable Vuetify's built-in utilities\n\nTurn off Vuetify's built-in utility classes and the Material color palette — TailwindCSS will cover both from here on:\n\n```scss { resource=\"settings.scss\" }\n@use 'vuetify/settings' with (\n  $color-pack: false,\n  $utilities: false,\n);\n```\n\nAfter rebuilding you should see the CSS entry file shrink by roughly 150–200 kB (unminified).\n\n## Align breakpoints { id=\"breakpoints\" }\n\nVuetify and TailwindCSS ship different default breakpoints. Mismatched values cause `sm:` in Tailwind to fire at a different width than `sm` in `VCol` or `useDisplay()`. The `@theme` block in `tailwind.css` above already resets the Tailwind defaults — the same values need to be repeated in two more places.\n\nVuetify plugin (Vite) or `vuetifyOptions` (Nuxt):\n\n```ts\ndisplay: {\n  mobileBreakpoint: 'md',\n  thresholds: {\n    // repeated in tailwind.css and settings.scss\n    xs: 0, sm: 600, md: 960, lg: 1280, xl: 1920, xxl: 2560,\n  },\n},\n```\n\nSass variables:\n\n```scss { resource=\"settings.scss\" }\n@use 'vuetify/settings' with (\n  $color-pack: false,\n  $utilities: false,\n  $grid-breakpoints: (\n    // repeated in tailwind.css and vuetify config\n    'xs': 0,\n    'sm': 600px,\n    'md': 960px,\n    'lg': 1280px,\n    'xl': 1920px,\n    'xxl': 2560px,\n  ),\n);\n```\n\n::: tip\nIn a **Nuxt** project you can define breakpoints in a shared TypeScript file and feed them to both Vuetify and the Sass variables from a single source of truth. See the [UnoCSS presetWind4 guide](/features/css-utilities/unocss-tailwind-preset/#breakpoints) for an example of this pattern.\n:::\n\n## Dark mode { id=\"dark-mode\" }\n\nThe `@custom-variant` declarations in `tailwind.css` above rewire Tailwind's `dark:` and `light:` prefixes to Vuetify's theme selectors. Classes like `dark:bg-sky-900` and `light:text-gray-700` then toggle correctly when switching themes via `$vuetify.theme.cycle()` or programmatically.\n\n::: warning Nuxt SSR and `defaultTheme: 'system'`\n\nVuetify's `system` theme reads the browser's `prefers-color-scheme` media query at runtime. In a Nuxt project with SSR enabled (the default), this detection runs on the server where no browser preference is available, so the theme always falls back to `light`. Either add `ssr: false` to `nuxt.config.ts`, or start with a fixed default theme:\n\n```ts { resource=\"nuxt.config.ts\" }\ntheme: {\n  defaultTheme: 'dark', // or 'light' — 'system' requires ssr: false\n},\n```\n\n:::\n\n## Typography { id=\"typography\" }\n\nTailwindCSS provides its own type-scale utilities (`text-sm`, `text-base`, `text-2xl`, etc.) that work well with responsive prefixes. When adopting TailwindCSS, **migrate to this convention** rather than trying to preserve Vuetify's typography classes (`text-h1` through `text-overline` for MD2, or `text-display-large` through `text-label-small` for MD3).\n\nTailwindCSS utilities give you finer control — `text-2xl font-light tracking-tight` lets you mix size, weight, and spacing freely instead of relying on a predefined bundle. The trade-off is that your team needs to agree on which combinations to use, usually enforced through shared components or a design token system.\n\nIf you are integrating TailwindCSS into an **existing project** that already uses Vuetify's typography classes extensively, you can define `@utility` rules to keep them working during the migration. Below are drop-in snippets for both the MD2 (legacy) and MD3 (default) typography scales.\n\n<details>\n<summary>MD2 typography utilities (text-h1 … text-overline)</summary>\n\nThese match Vuetify's MD2 defaults and reference `--font-heading` / `--font-body` CSS custom properties. Define them in your global CSS or in a Sass `@use 'vuetify/settings'` block.\n\n```css { resource=\"tailwind.css\" }\n@utility text-h1 {\n  font-family: var(--font-heading, inherit);\n  font-size: 6rem;\n  font-weight: 300;\n  line-height: 1;\n  letter-spacing: -.015625em;\n  text-transform: none;\n}\n@utility text-h2 {\n  font-family: var(--font-heading, inherit);\n  font-size: 3.75rem;\n  font-weight: 300;\n  line-height: 1;\n  letter-spacing: -.0083333333em;\n  text-transform: none;\n}\n@utility text-h3 {\n  font-family: var(--font-heading, inherit);\n  font-size: 3rem;\n  font-weight: 400;\n  line-height: 1.05;\n  letter-spacing: normal;\n  text-transform: none;\n}\n@utility text-h4 {\n  font-family: var(--font-heading, inherit);\n  font-size: 2.125rem;\n  font-weight: 400;\n  line-height: 1.175;\n  letter-spacing: .0073529412em;\n  text-transform: none;\n}\n@utility text-h5 {\n  font-family: var(--font-heading, inherit);\n  font-size: 1.5rem;\n  font-weight: 400;\n  line-height: 1.333;\n  letter-spacing: normal;\n  text-transform: none;\n}\n@utility text-h6 {\n  font-family: var(--font-heading, inherit);\n  font-size: 1.25rem;\n  font-weight: 500;\n  line-height: 1.6;\n  letter-spacing: .0125em;\n  text-transform: none;\n}\n@utility text-subtitle-1 {\n  font-family: var(--font-body, inherit);\n  font-size: 1rem;\n  font-weight: 400;\n  line-height: 1.75;\n  letter-spacing: .009375em;\n  text-transform: none;\n}\n@utility text-subtitle-2 {\n  font-family: var(--font-body, inherit);\n  font-size: .875rem;\n  font-weight: 500;\n  line-height: 1.6;\n  letter-spacing: .0071428571em;\n  text-transform: none;\n}\n@utility text-body-1 {\n  font-family: var(--font-body, inherit);\n  font-size: 1rem;\n  font-weight: 400;\n  line-height: 1.5;\n  letter-spacing: .03125em;\n  text-transform: none;\n}\n@utility text-body-2 {\n  font-family: var(--font-body, inherit);\n  font-size: .875rem;\n  font-weight: 400;\n  line-height: 1.425;\n  letter-spacing: .0178571429em;\n  text-transform: none;\n}\n@utility text-button {\n  font-family: var(--font-body, inherit);\n  font-size: .875rem;\n  font-weight: 500;\n  line-height: 2.6;\n  letter-spacing: .0892857143em;\n  text-transform: uppercase;\n}\n@utility text-caption {\n  font-family: var(--font-body, inherit);\n  font-size: .75rem;\n  font-weight: 400;\n  line-height: 1.667;\n  letter-spacing: .0333333333em;\n  text-transform: none;\n}\n@utility text-overline {\n  font-family: var(--font-body, inherit);\n  font-size: .75rem;\n  font-weight: 500;\n  line-height: 2.667;\n  letter-spacing: .1666666667em;\n  text-transform: uppercase;\n}\n```\n\n</details>\n\n<details>\n<summary>MD3 typography utilities (text-display-large … text-label-small)</summary>\n\nThese match Vuetify's MD3 defaults (the current default typography scale). None of the MD3 classes use `text-transform`.\n\n```css { resource=\"tailwind.css\" }\n@utility text-display-large {\n  font-family: var(--font-heading, inherit);\n  font-size: 3.5625rem;\n  font-weight: 400;\n  line-height: 1.1228070175;\n  letter-spacing: -.0043859649em;\n}\n@utility text-display-medium {\n  font-family: var(--font-heading, inherit);\n  font-size: 2.8125rem;\n  font-weight: 400;\n  line-height: 1.1555555556;\n  letter-spacing: normal;\n}\n@utility text-display-small {\n  font-family: var(--font-heading, inherit);\n  font-size: 2.25rem;\n  font-weight: 400;\n  line-height: 1.2222222222;\n  letter-spacing: normal;\n}\n@utility text-headline-large {\n  font-family: var(--font-heading, inherit);\n  font-size: 2rem;\n  font-weight: 400;\n  line-height: 1.25;\n  letter-spacing: normal;\n}\n@utility text-headline-medium {\n  font-family: var(--font-heading, inherit);\n  font-size: 1.75rem;\n  font-weight: 400;\n  line-height: 1.2857142857;\n  letter-spacing: normal;\n}\n@utility text-headline-small {\n  font-family: var(--font-heading, inherit);\n  font-size: 1.5rem;\n  font-weight: 400;\n  line-height: 1.3333333333;\n  letter-spacing: normal;\n}\n@utility text-title-large {\n  font-family: var(--font-heading, inherit);\n  font-size: 1.375rem;\n  font-weight: 400;\n  line-height: 1.2727272727;\n  letter-spacing: normal;\n}\n@utility text-title-medium {\n  font-family: var(--font-body, inherit);\n  font-size: 1rem;\n  font-weight: 500;\n  line-height: 1.5;\n  letter-spacing: .009375em;\n}\n@utility text-title-small {\n  font-family: var(--font-body, inherit);\n  font-size: .875rem;\n  font-weight: 500;\n  line-height: 1.4285714286;\n  letter-spacing: .0071428571em;\n}\n@utility text-body-large {\n  font-family: var(--font-body, inherit);\n  font-size: 1rem;\n  font-weight: 400;\n  line-height: 1.5;\n  letter-spacing: .03125em;\n}\n@utility text-body-medium {\n  font-family: var(--font-body, inherit);\n  font-size: .875rem;\n  font-weight: 400;\n  line-height: 1.4285714286;\n  letter-spacing: .0178571429em;\n}\n@utility text-body-small {\n  font-family: var(--font-body, inherit);\n  font-size: .75rem;\n  font-weight: 400;\n  line-height: 1.3333333333;\n  letter-spacing: .0333333333em;\n}\n@utility text-label-large {\n  font-family: var(--font-body, inherit);\n  font-size: .875rem;\n  font-weight: 500;\n  line-height: 1.4285714286;\n  letter-spacing: .0071428571em;\n}\n@utility text-label-medium {\n  font-family: var(--font-body, inherit);\n  font-size: .75rem;\n  font-weight: 500;\n  line-height: 1.3333333333;\n  letter-spacing: .0416666667em;\n}\n@utility text-label-small {\n  font-family: var(--font-body, inherit);\n  font-size: .6875rem;\n  font-weight: 500;\n  line-height: 1.4545454545;\n  letter-spacing: .0454545455em;\n}\n```\n\n</details>\n\n## Theme colors { id=\"theme-colors\" }\n\nVuetify stores theme colors as raw RGB channels in CSS custom properties (e.g. `--v-theme-primary`). Wrapping them in `rgb()` inside a `@theme` block makes them available as standard Tailwind color utilities (`bg-primary`, `text-error`, etc.):\n\n```css { resource=\"tailwind.css\" }\n@theme {\n  /* ... breakpoints ... */\n  --color-background:      rgb(var(--v-theme-background));\n  --color-surface:         rgb(var(--v-theme-surface));\n  --color-surface-variant: rgb(var(--v-theme-surface-variant));\n  --color-primary:         rgb(var(--v-theme-primary));\n  --color-success:         rgb(var(--v-theme-success));\n  --color-warning:         rgb(var(--v-theme-warning));\n  --color-error:           rgb(var(--v-theme-error));\n  --color-info:            rgb(var(--v-theme-info));\n}\n\n/* safelist classes used dynamically via color=\"...\" prop */\n@source inline('bg-primary');\n@source inline('text-primary');\n@source inline('bg-success');\n@source inline('text-success');\n@source inline('bg-error');\n@source inline('text-error');\n```\n\nDisable Vuetify's own theme utility classes to avoid duplicate `bg-*` / `text-*` rules that can't be used with variants:\n\n```ts { resource=\"vuetify.ts\" }\ntheme: {\n  defaultTheme: 'light', // 'system' requires ssr: false in Nuxt\n  utilities: false, // skip .bg-primary, .text-error, etc.\n},\n```\n\n::: warning\n\nVuetify's original `bg-*` utilities automatically set a contrasting foreground color via `--v-theme-on-*`. Replacing them with TailwindCSS utilities removes this safeguard — you are responsible for choosing legible text colors. See [Limitations](/features/css-utilities/#limitations).\n\n:::\n\n## Using MD3 elevation\n\nThe elevation approach in [Configure TailwindCSS](#configure-tailwindcss) maps `elevation-*` to TailwindCSS's generic shadow tokens. If you need Vuetify's exact Material Design 3 shadow values — including the surface overlay tint that shifts with depth — replace those rules with the full MD3 definitions:\n\n<details>\n<summary>MD3 elevation utilities (elevation-0 … elevation-5)</summary>\n\n```css { resource=\"tailwind.css\" }\n@utility elevation-0 {\n  box-shadow: 0px 0px 0px 0px rgba(var(--v-shadow-color), var(--v-shadow-key-opacity, 0.3)), 0px 0px 0px 0px rgba(var(--v-shadow-color), var(--v-shadow-ambient-opacity, 0.15));\n  --v-elevation-overlay: color-mix(in srgb, var(--v-elevation-overlay-color) 0%, transparent);\n}\n@utility elevation-1 {\n  box-shadow: 0px 1px 2px 0px rgba(var(--v-shadow-color), var(--v-shadow-key-opacity, 0.3)), 0px 1px 3px 1px rgba(var(--v-shadow-color), var(--v-shadow-ambient-opacity, 0.15));\n  --v-elevation-overlay: color-mix(in srgb, var(--v-elevation-overlay-color) 2%, transparent);\n}\n@utility elevation-2 {\n  box-shadow: 0px 1px 2px 0px rgba(var(--v-shadow-color), var(--v-shadow-key-opacity, 0.3)), 0px 2px 6px 2px rgba(var(--v-shadow-color), var(--v-shadow-ambient-opacity, 0.15));\n  --v-elevation-overlay: color-mix(in srgb, var(--v-elevation-overlay-color) 4%, transparent);\n}\n@utility elevation-3 {\n  box-shadow: 0px 1px 3px 0px rgba(var(--v-shadow-color), var(--v-shadow-key-opacity, 0.3)), 0px 4px 8px 3px rgba(var(--v-shadow-color), var(--v-shadow-ambient-opacity, 0.15));\n  --v-elevation-overlay: color-mix(in srgb, var(--v-elevation-overlay-color) 6%, transparent);\n}\n@utility elevation-4 {\n  box-shadow: 0px 2px 3px 0px rgba(var(--v-shadow-color), var(--v-shadow-key-opacity, 0.3)), 0px 6px 10px 4px rgba(var(--v-shadow-color), var(--v-shadow-ambient-opacity, 0.15));\n  --v-elevation-overlay: color-mix(in srgb, var(--v-elevation-overlay-color) 8%, transparent);\n}\n@utility elevation-5 {\n  box-shadow: 0px 4px 4px 0px rgba(var(--v-shadow-color), var(--v-shadow-key-opacity, 0.3)), 0px 8px 12px 6px rgba(var(--v-shadow-color), var(--v-shadow-ambient-opacity, 0.15));\n  --v-elevation-overlay: color-mix(in srgb, var(--v-elevation-overlay-color) 10%, transparent);\n}\n@utility elevation-overlay {\n  background-image: linear-gradient(var(--v-elevation-overlay), var(--v-elevation-overlay));\n}\n```\n\n</details>\n"
  },
  {
    "path": "packages/docs/src/pages/en/features/css-utilities/unocss-tailwind-preset.md",
    "content": "---\nemphasized: true\nmeta:\n  nav: UnoCSS + presetWind4\n  title: Vuetify + UnoCSS (presetWind4)\n  description: Integrate UnoCSS with @unocss/preset-wind4 into an existing Vuetify project using Vite or Nuxt.\n  keywords: unocss, preset-wind4, tailwindcss v4, unocss tailwind, on-demand utilities, vite, nuxt\nrelated:\n  - /features/css-utilities/\n  - /features/css-utilities/unocss-vuetify-preset/\n  - /styles/layers/\n---\n\n# UnoCSS with presetWind4\n\nUse [`@unocss/preset-wind4`](https://unocss.dev/presets/wind4) for TailwindCSS v4 class names powered by UnoCSS's on-demand engine.\n\nUnlike TailwindCSS v4 directly (which requires pure CSS `@theme` declarations), everything stays in JavaScript/TypeScript — breakpoints, typography, dark mode, all in one shared config file.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n---\n\n:::: tabs\n\n```bash [npx]\n# generate working project for reference\nnpx @vuetify/cli@latest init --type=vuetify --css=unocss-wind4\n```\n\n```bash [pnpm]\n# generate working project for reference\npnpx @vuetify/cli@latest init --type=vuetify --css=unocss-wind4\n```\n\n```bash [yarn]\n# generate working project for reference\nyarn dlx @vuetify/cli@latest init --type=vuetify --css=unocss-wind4\n```\n\n```bash [bun]\n# generate working project for reference\nbunx @vuetify/cli@latest init --type=vuetify --css=unocss-wind4\n```\n\n::::\n\n## Establish CSS layer order\n\nCreate a `layers.css` file that declares the cascade layers in order. `uno` goes above component styles but below `vuetify-final`, where Vuetify keeps its transitions:\n\n```css\n@layer uno-base;\n@layer uno-theme;\n\n@layer vuetify-core;\n@layer vuetify-components;\n@layer vuetify-overrides;\n@layer vuetify-utilities;\n\n@layer uno-shortcuts;\n@layer uno-default;\n\n@layer vuetify-final;\n```\n\nThis file must be loaded **before** any other styles. In a **Vite** project, save it as `src/styles/layers.css` and import it at the top of `src/plugins/vuetify.ts`, before `vuetify/styles`.\n\n## Setup dependencies\n\n### Vite\n\nImport the layers file at the top of `src/plugins/vuetify.ts`, before `vuetify/styles`:\n\n```ts { resource=\"src/plugins/vuetify.ts\" }\nimport '../styles/layers.css'\nimport 'vuetify/styles'\n// ...\n```\n\nInstall UnoCSS and the Wind4 preset:\n\n::: tabs\n\n```bash [pnpm]\npnpm add -D unocss @unocss/preset-wind4\n```\n\n```bash [yarn]\nyarn add -D unocss @unocss/preset-wind4\n```\n\n```bash [npm]\nnpm i -D unocss @unocss/preset-wind4\n```\n\n```bash [bun]\nbun add -D unocss @unocss/preset-wind4\n```\n\n:::\n\nRegister the UnoCSS Vite plugin in `vite.config.ts` and create `uno.config.ts`:\n\n```ts { resource=\"vite.config.ts\" }\nimport UnoCSS from 'unocss/vite'\n\nexport default defineConfig({\n  plugins: [\n    UnoCSS(),\n    // ...\n  ],\n})\n```\n\n```ts { resource=\"uno.config.ts\" }\nimport { defineConfig } from 'unocss'\nimport presetWind4 from '@unocss/preset-wind4'\n\nexport default defineConfig({\n  presets: [\n    presetWind4(),\n  ],\n  outputToCssLayers: {\n    cssLayerName: (layer) => layer === 'properties' ? null : `uno-${layer}`,\n  },\n})\n```\n\nSetting `preflights.reset` to `false` skips UnoCSS's built-in reset so Vuetify's takes over.\n\nAdd the UnoCSS virtual import to your entry point:\n\n```ts { resource=\"src/main.ts\" }\nimport 'virtual:uno.css'\n```\n\n### Nuxt\n\n::: tabs\n\n```bash [pnpm]\npnpm add -D unocss @unocss/preset-wind4 @unocss/nuxt\n```\n\n```bash [yarn]\nyarn add -D unocss @unocss/preset-wind4 @unocss/nuxt\n```\n\n```bash [npm]\nnpm i -D unocss @unocss/preset-wind4 @unocss/nuxt\n```\n\n```bash [bun]\nbun add -D unocss @unocss/preset-wind4 @unocss/nuxt\n```\n\n:::\n\nRegister the module in `nuxt.config.ts`. The `css` array controls load order — `layers.css` must come first, followed by `vuetify/styles`. Set `disableVuetifyStyles: true` — otherwise the module injects styles automatically and the order above is ignored:\n\n```ts { resource=\"nuxt.config.ts\" }\nimport presetWind4 from '@unocss/preset-wind4'\n\nexport default defineNuxtConfig({\n  modules: [\n    '@unocss/nuxt',\n    'vuetify-nuxt-module',\n    // ...\n  ],\n\n  css: [\n    'assets/styles/layers.css',\n    'vuetify/styles',\n  ],\n\n  vuetify: {\n    moduleOptions: {\n      disableVuetifyStyles: true,\n      styles: { configFile: 'assets/styles/settings.scss' },\n    },\n  },\n\n  unocss: {\n    presets: [\n      presetWind4(),\n    ],\n    outputToCssLayers: {\n      cssLayerName: (layer) => layer === 'properties' ? null : `uno-${layer}`,\n    },\n  },\n})\n```\n\n## Disable Vuetify's built-in utilities\n\nTurn off Vuetify's built-in utility classes so UnoCSS handles them on demand instead. The Material color palette is not needed because `presetWind4` ships its own color palette (TailwindCSS colors).\n\n```scss [Vite]{resource=\"settings.scss\"}\n@use 'vuetify/settings' with (\n  $color-pack: false,\n  $utilities: false,\n);\n```\n\n## Light/dark mode compatibility { id=\"dark-mode\" }\n\nBy default UnoCSS generates dark-mode utilities scoped to a `.dark` class (e.g. `.dark .dark\\:bg-sky-900`). Vuetify uses `.v-theme--dark` and `.v-theme--light` instead, so the `dark:` prefix won't work out of the box.\n\nAdd the `dark` option inside `presetWind4()` to align both systems:\n\n```ts { resource=\"uno.config.ts\" }\npresetWind4({\n  preflights: {\n    reset: false,\n  },\n  dark: {\n    dark: '.v-theme--dark',\n    light: '.v-theme--light',\n  },\n}),\n```\n\nClasses like `dark:bg-sky-900` and `light:text-gray-700` are now scoped to Vuetify's theme selectors and toggle correctly via `$vuetify.theme.cycle()` or programmatically.\n\n### Custom themes\n\nTailwindCSS only supports the `light` and `dark` themes to align with `prefers-color-scheme` options. If your app registers additional custom themes and you want variant prefixes for each of them, use `createThemeVariants` from `unocss-preset-vuetify` instead:\n\n```ts { resource=\"uno.config.ts\" }\nimport { createThemeVariants } from 'unocss-preset-vuetify'\n\nexport default defineConfig({\n  // ...\n  variants: createThemeVariants(['light', 'dark', 'high-contrast']),\n})\n```\n\n## Align breakpoints { id=\"breakpoints\" }\n\nDefault breakpoints from TailwindCSS do not match Vuetify's. This mismatch can lead to confusing layout bugs when mixing responsive utilities (`sm:`, `md:`, …) with Vuetify's grid system (`v-col`, `v-row`) or `useDisplay()`.\n\nDefine breakpoints in a shared file and feed them to both Vuetify and UnoCSS:\n\n```ts { resource=\"src/theme/breakpoints.ts\" }\nimport type { DisplayThresholds } from 'vuetify'\n\n// repeated in settings.scss\nconst breakpoints: DisplayThresholds = {\n  xs: 0,\n  sm: 600,\n  md: 960,\n  lg: 1280,\n  xl: 1920,\n  xxl: 2560,\n}\n\nexport const forVuetify = breakpoints\n\nexport const forUnoCSS = Object.entries(breakpoints)\n  .reduce(\n    (o, [key, value]) => ({ ...o, [key]: `${value}px` }),\n    {} as Record<keyof DisplayThresholds, string>,\n  )\n```\n\nApply the breakpoints in your UnoCSS configuration:\n\n```ts\n// uno.config.ts (Vite) or unocss key (Nuxt)\ntheme: {\n  breakpoint: breakpoints.forUnoCSS,\n},\n```\n\nAnd in your Vuetify configuration:\n\n```ts\n// vuetify plugin (Vite) or vuetifyOptions (Nuxt)\ndisplay: {\n  mobileBreakpoint: 'md',\n  thresholds: breakpoints.forVuetify,\n},\n```\n\nFinally, keep the SCSS variables in sync:\n\n```scss { resource=\"settings.scss\" }\n@use 'vuetify/settings' with (\n  $color-pack: false,\n  $utilities: false,\n  $grid-breakpoints: (\n    // repeated in breakpoints.ts\n    'xs': 0,\n    'sm': 600px,\n    'md': 960px,\n    'lg': 1280px,\n    'xl': 1920px,\n    'xxl': 2560px,\n  ),\n);\n```\n\n## Typography\n\n`presetWind4` does not include Vuetify's typography classes (`text-h1` through `text-overline`). You can recreate them as UnoCSS **shortcuts** so they compose from native TailwindCSS utilities and gain responsive prefix support (e.g. `md:text-h3`).\n\nFirst, define custom font families in the UnoCSS theme so the `font-heading` and `font-body` utilities are available:\n\n```ts { resource=\"uno.config.ts\" }\ntheme: {\n  font: {\n    heading: \"'Your Heading Font', sans-serif\",\n    body: \"'Your Body Font', sans-serif\",\n  },\n},\n```\n\nThen point Vuetify's Sass variables at the same CSS custom properties:\n\n```scss { resource=\"settings.scss\" }\n@use 'vuetify/settings' with (\n  $heading-font-family: var(--font-heading),\n  $body-font-family: var(--font-body),\n  // ...\n);\n```\n\n<details>\n<summary>MD2 typography shortcuts (text-h1 … text-overline)</summary>\n\nAdd the `shortcuts` below to your UnoCSS configuration. The values are matched to Vuetify's MD2 typography scale:\n\n```ts { resource=\"uno.config.ts or nuxt.config.ts » unocss\" }\nshortcuts: {\n  'text-h1': '        font-heading normal-case text-[6rem]     font-[300] leading-[1]     tracking-[-.015625em]    ',\n  'text-h2': '        font-heading normal-case text-[3.75rem]  font-[300] leading-[1]     tracking-[-.0083333333em]',\n  'text-h3': '        font-heading normal-case text-[3rem]     font-[400] leading-[1.05]  tracking-[normal]        ',\n  'text-h4': '        font-heading normal-case text-[2.125rem] font-[400] leading-[1.175] tracking-[.0073529412em] ',\n  'text-h5': '        font-heading normal-case text-[1.5rem]   font-[400] leading-[1.333] tracking-[normal]        ',\n  'text-h6': '        font-heading normal-case text-[1.25rem]  font-[500] leading-[1.6]   tracking-[.0125em]       ',\n  'text-subtitle-1': 'font-body    normal-case text-[1rem]     font-[400] leading-[1.75]  tracking-[.009375em]     ',\n  'text-subtitle-2': 'font-body    normal-case text-[.875rem]  font-[500] leading-[1.6]   tracking-[.0071428571em] ',\n  'text-body-1': '    font-body    normal-case text-[1rem]     font-[400] leading-[1.5]   tracking-[.03125em]      ',\n  'text-body-2': '    font-body    normal-case text-[.875rem]  font-[400] leading-[1.425] tracking-[.0178571429em] ',\n  'text-button': '    font-body    uppercase   text-[.875rem]  font-[500] leading-[2.6]   tracking-[.0892857143em] ',\n  'text-caption': '   font-body    normal-case text-[.75rem]   font-[400] leading-[1.667] tracking-[.0333333333em] ',\n  'text-overline': '  font-body    uppercase   text-[.75rem]   font-[500] leading-[2.667] tracking-[.1666666667em] ',\n},\n```\n\nBecause these are shortcuts composed from real utilities, responsive prefixes like `sm:text-h3` work automatically.\n\n</details>\n\n<details>\n<summary>MD3 typography shortcuts (text-display-large … text-label-small)</summary>\n\nThese match Vuetify's MD3 defaults (the current default typography scale). None of the MD3 classes use `text-transform`.\n\n```ts { resource=\"uno.config.ts or nuxt.config.ts » unocss\" }\nshortcuts: {\n  'text-display-large': '  font-heading normal-case text-[3.5625rem] font-[400] leading-[1.1228] tracking-[-.0044em]',\n  'text-display-medium': ' font-heading normal-case text-[2.8125rem] font-[400] leading-[1.1556] tracking-[normal]  ',\n  'text-display-small': '  font-heading normal-case text-[2.25rem]   font-[400] leading-[1.2222] tracking-[normal]  ',\n  'text-headline-large': ' font-heading normal-case text-[2rem]      font-[400] leading-[1.25]   tracking-[normal]  ',\n  'text-headline-medium': 'font-heading normal-case text-[1.75rem]   font-[400] leading-[1.2857] tracking-[normal]  ',\n  'text-headline-small': ' font-heading normal-case text-[1.5rem]    font-[400] leading-[1.3333] tracking-[normal]  ',\n  'text-title-large': '    font-heading normal-case text-[1.375rem]  font-[400] leading-[1.2727] tracking-[normal]  ',\n  'text-title-medium': '   font-body    normal-case text-[1rem]      font-[500] leading-[1.5]    tracking-[.0094em] ',\n  'text-title-small': '    font-body    normal-case text-[.875rem]   font-[500] leading-[1.4286] tracking-[.0071em] ',\n  'text-body-large': '     font-body    normal-case text-[1rem]      font-[400] leading-[1.5]    tracking-[.0313em] ',\n  'text-body-medium': '    font-body    normal-case text-[.875rem]   font-[400] leading-[1.4286] tracking-[.0179em] ',\n  'text-body-small': '     font-body    normal-case text-[.75rem]    font-[400] leading-[1.3333] tracking-[.0333em] ',\n  'text-label-large': '    font-body    normal-case text-[.875rem]   font-[500] leading-[1.4286] tracking-[.0071em] ',\n  'text-label-medium': '   font-body    normal-case text-[.75rem]    font-[500] leading-[1.3333] tracking-[.0417em] ',\n  'text-label-small': '    font-body    normal-case text-[.6875rem]  font-[500] leading-[1.4545] tracking-[.0455em] ',\n},\n```\n\n</details>\n\n## Rounded corners\n\nVuetify's `rounded` prop generates classes like `rounded-lg` and `rounded-pill` that don't map to TailwindCSS equivalents. Define them as UnoCSS shortcuts so they work with responsive prefixes and don't need safelisting:\n\n<details>\n<summary>Rounded shortcuts (aligned with Vuetify defaults)</summary>\n\n```ts { resource=\"uno.config.ts or nuxt.config.ts » unocss\" }\nshortcuts: {\n  // typography shortcuts ...\n\n  'rounded-0': 'rounded-none',\n  'rounded-sm': 'rounded-[2px]',\n  'rounded': 'rounded-[4px]',\n  'rounded-lg': 'rounded-[8px]',\n  'rounded-xl': 'rounded-[24px]',\n  'rounded-pill': 'rounded-full',\n  'rounded-circle': 'rounded-[50%]',\n  'rounded-shaped': 'rounded-[24px_0]',\n\n  // directional variants\n  'rounded-t-0': 'rounded-t-none',\n  'rounded-t-sm': 'rounded-tl-[2px] rounded-tr-[2px]',\n  'rounded-t': 'rounded-tl-[4px] rounded-tr-[4px]',\n  'rounded-t-lg': 'rounded-tl-[8px] rounded-tr-[8px]',\n  'rounded-t-xl': 'rounded-tl-[24px] rounded-tr-[24px]',\n  'rounded-t-pill': 'rounded-tl-full rounded-tr-full',\n\n  'rounded-b-0': 'rounded-b-none',\n  'rounded-b-sm': 'rounded-bl-[2px] rounded-br-[2px]',\n  'rounded-b': 'rounded-bl-[4px] rounded-br-[4px]',\n  'rounded-b-lg': 'rounded-bl-[8px] rounded-br-[8px]',\n  'rounded-b-xl': 'rounded-bl-[24px] rounded-br-[24px]',\n  'rounded-b-pill': 'rounded-bl-full rounded-br-full',\n\n  'rounded-s-0': 'rounded-ss-none rounded-es-none',\n  'rounded-s-sm': 'rounded-ss-[2px] rounded-es-[2px]',\n  'rounded-s': 'rounded-ss-[4px] rounded-es-[4px]',\n  'rounded-s-lg': 'rounded-ss-[8px] rounded-es-[8px]',\n  'rounded-s-xl': 'rounded-ss-[24px] rounded-es-[24px]',\n  'rounded-s-pill': 'rounded-ss-full rounded-es-full',\n\n  'rounded-e-0': 'rounded-se-none rounded-ee-none',\n  'rounded-e-sm': 'rounded-se-[2px] rounded-ee-[2px]',\n  'rounded-e': 'rounded-se-[4px] rounded-ee-[4px]',\n  'rounded-e-lg': 'rounded-se-[8px] rounded-ee-[8px]',\n  'rounded-e-xl': 'rounded-se-[24px] rounded-ee-[24px]',\n  'rounded-e-pill': 'rounded-se-full rounded-ee-full',\n},\n```\n\n</details>\n\n## Elevation utilities\n\n`presetWind4` does not generate Vuetify's `elevation-*` classes. Choose one of the two approaches below depending on whether you want a TailwindCSS-native shadow scale or Vuetify's exact Material Design shadows.\n\n### Align with shadows from TailwindCSS\n\nMap each elevation level to `presetWind4`'s built-in shadow tokens, which use the same scale as TailwindCSS v4:\n\n```ts { resource=\"uno.config.ts or nuxt.config.ts » unocss\" }\nrules: [\n  ['elevation-0', { 'box-shadow': 'none' }],\n  ['elevation-1', { 'box-shadow': 'var(--shadow-xs)' }],\n  ['elevation-2', { 'box-shadow': 'var(--shadow-sm)' }],\n  ['elevation-3', { 'box-shadow': 'var(--shadow-md)' }],\n  ['elevation-4', { 'box-shadow': 'var(--shadow-xl)' }],\n  ['elevation-5', { 'box-shadow': 'var(--shadow-2xl)' }],\n],\n```\n\nMany Vuetify components include default shadows that are not aligned with TailwindCSS. You may want to extend `settings.scss` with all variables `*-elevation`.\n\n```scss { resource=\"settings.scss\" }\n@use 'vuetify/settings' with (\n  // ...\n  $alert-elevation: 0,\n  $avatar-elevation: 0,\n  $card-elevation: 0,\n  $card-hover-elevation: 0,\n  // etc.\n);\n```\n\n### Restore Vuetify elevation shadows\n\nIf you find TailwindCSS shadows do not align with the app design and wish to use Material Design shadows, the easiest way is to use `unocss-preset-vuetify` package. Make sure you install the library as dependency and import `elevationPresets` which can be translated into UnoCSS \"rules\".\n\n```ts { resource=\"uno.config.ts or nuxt.config.ts » unocss\" }\nimport { elevationPresets } from 'unocss-preset-vuetify'\n\n// ...\nrules: [\n  ...Object.entries(elevationPresets.md3)\n    .map(([level, css]) => [`elevation-${level}`, css]),\n],\n```\n\nThese rules let you control shadows with CSS variables bound to theme configuration (notably `--v-shadow-color`). You can also easily swap to `md2` for legacy 24-levels of elevation.\n\n## Safelist prop-driven classes\n\nSome Vuetify convenience props (`elevation`, `rounded`) add CSS classes at runtime. This means that these class names may never appear in your source files and if UnoCSS cannot detect them by scanning, they won't appear in the CSS bundle file. Add `safelist` entries for the ones you use:\n\n```ts\n{\n  // presets: ...\n  // outputToCssLayers: ...\n  safelist: [\n    ...Array.from({ length: 6 /* or 25 for MD2 */ }, (_, i) => `elevation-${i}`),\n    ['', '-0', '-sm', '-lg', '-xl', '-pill', '-circle', '-shaped'].map(suffix => `rounded${suffix}`),\n  ],\n}\n```\n\n<!-- TODO: cover approach to border prop after releasing ESLint plugin -->\n\n## VRow and VCol utility classes\n\nThis section is only relevant if your project uses the `justify`, `align`, or `order` props on `v-row` / `v-col` — these props were deprecated in Vuetify v4.0.0 — and migrating them to their TailwindCSS equivalents (which sometimes use different class names) is not practical for your project.\n\n`v-row` and `v-col` rely on Vuetify-specific utility classes for their `justify`, `align`, and `order` props (e.g. `justify-space-between`, `align-center`). These class names don't exist in TailwindCSS conventions and won't be generated by `presetWind4`.\n\nYou have two options:\n\n**Option A — static global styles.** Paste the required classes in a global CSS/SCSS file:\n\n```scss { resource=\"src/styles/vuetify-compat.scss\" }\n.justify-start { justify-content: flex-start }\n.justify-end { justify-content: flex-end }\n.justify-center { justify-content: center }\n.justify-space-between { justify-content: space-between }\n.justify-space-around { justify-content: space-around }\n.justify-space-evenly { justify-content: space-evenly }\n\n.align-start { align-items: flex-start }\n.align-end { align-items: flex-end }\n.align-center { align-items: center }\n.align-baseline { align-items: baseline }\n.align-stretch { align-items: stretch }\n```\n\n**Option B — keep selected Vuetify utilities.** Instead of `$utilities: false`, selectively enable only the classes `v-row` / `v-col` need:\n\n```scss { resource=\"settings.scss\" }\n@use 'vuetify/settings' with (\n  $color-pack: false,\n  $utilities: (\n    \"align-items\": (responsive: false, unimportant: (align-items)),\n    \"justify-content\": (responsive: false, unimportant: (justify-content)),\n    \"order\": (responsive: false, unimportant: (order)),\n    // all other utilities set to `false`\n  ),\n);\n```\n\n## Forward Vuetify theme colors to UnoCSS { id=\"theme-colors\" }\n\nVuetify stores theme colors as raw RGB channels in CSS custom properties (e.g. `--v-theme-primary`). Wrapping them in `rgb()` inside the UnoCSS `theme.colors` block makes them available as standard TailwindCSS-style color utilities (`bg-primary`, `text-error`, etc.):\n\n```ts { resource=\"uno.config.ts\" }\ntheme: {\n  colors: {\n    background:        'rgb(var(--v-theme-background))',\n    surface:           'rgb(var(--v-theme-surface))',\n    'surface-variant': 'rgb(var(--v-theme-surface-variant))',\n    primary:           'rgb(var(--v-theme-primary))',\n    success:           'rgb(var(--v-theme-success))',\n    warning:           'rgb(var(--v-theme-warning))',\n    error:             'rgb(var(--v-theme-error))',\n    info:              'rgb(var(--v-theme-info))',\n  },\n},\n```\n\nBecause `presetWind4` generates utilities on demand, also add `safelist` entries for any color classes that are bound dynamically via `color=\"...\"` prop:\n\n```ts\nsafelist: [\n  'bg-primary', 'text-primary',\n  'bg-success', 'text-success',\n  'bg-error',   'text-error',\n],\n```\n\n::: warning\n\nVuetify's original `bg-*` utilities automatically set a contrasting foreground color via `--v-theme-on-*`. Replacing them with UnoCSS utilities removes this safeguard — you are responsible for choosing legible text colors. See [Limitations](/features/css-utilities/#limitations).\n\n:::\n"
  },
  {
    "path": "packages/docs/src/pages/en/features/css-utilities/unocss-vuetify-preset.md",
    "content": "---\nemphasized: true\nmeta:\n  nav: UnoCSS + Vuetify preset\n  title: Vuetify + UnoCSS (Vuetify preset)\n  description: Integrate UnoCSS with the unocss-preset-vuetify into an existing Vuetify project using Vite or Nuxt.\n  keywords: unocss, unocss-preset-vuetify, vuetify preset, on-demand utilities, vite, nuxt\nrelated:\n  - /features/css-utilities/\n  - /features/css-utilities/unocss-tailwind-preset/\n  - /styles/layers/\n---\n\n# UnoCSS with Vuetify preset\n\nGenerate Vuetify's built-in utility classes on demand with `unocss-preset-vuetify`, maintained by the Vuetify team.\n\nNo class-naming convention change required — use the same Vuetify class names you already know, generated on demand instead of shipped in full.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n---\n\n:::: tabs\n\n```bash [npx]\n# generate working project for reference\nnpx @vuetify/cli@latest init --type=vuetify --css=unocss-vuetify\n```\n\n```bash [pnpm]\n# generate working project for reference\npnpx @vuetify/cli@latest init --type=vuetify --css=unocss-vuetify\n```\n\n```bash [yarn]\n# generate working project for reference\nyarn dlx @vuetify/cli@latest init --type=vuetify --css=unocss-vuetify\n```\n\n```bash [bun]\n# generate working project for reference\nbunx @vuetify/cli@latest init --type=vuetify --css=unocss-vuetify\n```\n\n::::\n\n## Establish CSS layer order\n\nCreate a `layers.css` file that declares the cascade layers in order. `uno` goes above component styles but below `vuetify-final`, where Vuetify keeps its transitions:\n\n```css\n@layer vuetify-core;\n@layer vuetify-components;\n@layer vuetify-overrides;\n@layer vuetify-utilities;\n@layer uno;\n@layer vuetify-final;\n```\n\nThis file must be loaded **before** any other styles. In a **Vite** project, save it as `src/styles/layers.css` and import it at the top of `src/plugins/vuetify.ts`, before `vuetify/styles`.\n\n## Setup dependencies\n\n### Vite\n\nImport the layers file at the top of `src/plugins/vuetify.ts`, before `vuetify/styles`:\n\n```ts { resource=\"src/plugins/vuetify.ts\" }\nimport '../styles/layers.css'\nimport 'vuetify/styles'\n// ...\n```\n\nInstall UnoCSS and the Vuetify preset:\n\n::: tabs\n\n```bash [pnpm]\npnpm add -D unocss unocss-preset-vuetify\n```\n\n```bash [yarn]\nyarn add -D unocss unocss-preset-vuetify\n```\n\n```bash [npm]\nnpm i -D unocss unocss-preset-vuetify\n```\n\n```bash [bun]\nbun add -D unocss unocss-preset-vuetify\n```\n\n:::\n\nRegister the UnoCSS Vite plugin in `vite.config.ts` and create `uno.config.ts`:\n\n```ts { resource=\"vite.config.ts\" }\nimport UnoCSS from 'unocss/vite'\n\nexport default defineConfig({\n  plugins: [\n    UnoCSS(),\n    // ...\n  ],\n})\n```\n\n```ts { resource=\"uno.config.ts\" }\nimport { defineConfig } from 'unocss'\nimport { presetVuetify } from 'unocss-preset-vuetify'\n\nexport default defineConfig({\n  presets: [\n    presetVuetify({\n      typography: 'md3',     // accepts 'md2' or custom object\n      elevation: 'md3',      // accepts 'md2' or custom object\n      font: {                // your custom fonts\n        heading: 'K2D, sans-serif',\n        body: '\"Work Sans\", sans-serif',\n      },\n    }),\n  ],\n  outputToCssLayers: {\n    cssLayerName: (layer) => layer === 'properties' ? null : `uno.${layer}`,\n  },\n})\n```\n\nAdd the UnoCSS virtual import to your entry point:\n\n```ts { resource=\"src/main.ts\" }\nimport 'virtual:uno.css'\n```\n\n### Nuxt\n\n::: tabs\n\n```bash [pnpm]\npnpm add -D unocss unocss-preset-vuetify @unocss/nuxt\n```\n\n```bash [yarn]\nyarn add -D unocss unocss-preset-vuetify @unocss/nuxt\n```\n\n```bash [npm]\nnpm i -D unocss unocss-preset-vuetify @unocss/nuxt\n```\n\n```bash [bun]\nbun add -D unocss unocss-preset-vuetify @unocss/nuxt\n```\n\n:::\n\nRegister the module in `nuxt.config.ts`. The `css` array controls load order — `layers.css` must come first, followed by `vuetify/styles`. Set `disableVuetifyStyles: true` — otherwise the module injects styles automatically and the order above is ignored:\n\n```ts { resource=\"nuxt.config.ts\" }\nimport { presetVuetify } from 'unocss-preset-vuetify'\n\nexport default defineNuxtConfig({\n  modules: [\n    '@unocss/nuxt',\n    'vuetify-nuxt-module',\n    // ...\n  ],\n\n  css: [\n    'assets/styles/layers.css',\n    'vuetify/styles',\n  ],\n\n  vuetify: {\n    moduleOptions: {\n      disableVuetifyStyles: true,\n      styles: { configFile: 'assets/styles/settings.scss' },\n    },\n    vuetifyOptions: {\n      theme: {\n        defaultTheme: 'dark', // 'system' requires ssr: false\n      },\n    },\n  },\n\n  unocss: {\n    presets: [\n      presetVuetify(),\n    ],\n    outputToCssLayers: {\n      cssLayerName: (layer) => layer === 'properties' ? null : `uno.${layer}`,\n    },\n  },\n})\n```\n\n## Disable Vuetify's built-in utilities\n\nTurn off Vuetify's built-in utility classes and the Material color palette so UnoCSS handles them on demand instead.\n\n```scss [Vite]{resource=\"settings.scss\"}\n@use 'vuetify/settings' with (\n  $color-pack: false,\n  $utilities: false,\n);\n```\n\n## How on-demand generation works\n\nUnoCSS scans your source files statically, looking for class name strings. A class like `elevation-4` in `class=\"elevation-4\"` gets picked up and its CSS is generated. The problem arises with props like **elevation**, **rounded** and **border**: when you write `<v-card elevation=\"4\">`, Vuetify's component logic converts the prop value into the class `elevation-4` internally — the string `elevation-4` never appears literally in your source, so UnoCSS won't generate it.\n\nThe `safelist` option solves this: it specifies classes (or patterns) that UnoCSS should always generate regardless of whether they appear in scanned files.\n\n## Safelist prop-driven classes\n\nAdd `safelist` entries for convenience props (e.g. `elevation` and `rounded`) that just add CSS classes. Because these class names are generated at runtime by Vuetify components, UnoCSS cannot detect them by scanning source files.\n\n```ts { resource=\"uno.config.ts\" }\n{\n  // presets: ...\n  // outputToCssLayers: ...\n  safelist: [\n    ...Array.from({ length: 6 }, (_, i) => `elevation-${i}`),\n    ['', '-0', '-sm', '-lg', '-xl', '-pill', '-circle', '-shaped'].map(suffix => `rounded${suffix}`),\n  ],\n}\n```\n\n<!-- TODO:\n  color prop is kinda similar, but it depends on which color you use.\n  - theme (semantic) colors are injected into HEAD as part of theme stylesheet.\n  - colors from Material color palette provided by the UnoCSS preset require\n    full class name to appear in the source code.\n\n  color prop will remove bg-* and text-* prefixes, but it may be a bit confusing\n\n  <v-card color=\"bg-orange-accent-2\" variant=\"flat\" />\n  <v-card color=\"text-lime-darken-3\" variant=\"tonal\" />\n-->\n\n<!-- TODO: cover approach to border prop after releasing ESLint plugin -->\n"
  },
  {
    "path": "packages/docs/src/pages/en/features/dates.md",
    "content": "---\nmeta:\n  title: Dates\n  description: Vuetify has first party date support that can easily be swapped for another date library\n  keywords: date, datepicker, datetime, time, calendar, picker, date library\nrelated:\n- /features/blueprints/\n- /features/global-configuration/\n- /features/treeshaking/\nfeatures:\n  github: /composables/date/\n  label: 'E: date'\n  report: true\n---\n\n# Dates\n\nEasily hook up date libraries that are used for components such as Date Picker and Calendar that require date functionality.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## Usage\n\nThe date composable provides a shared architecture that is used by components such as date picker and calendar. The default implementation is built using the native Date object, but can be swapped out for another date library. If no other date adapter is given, the default Vuetify one is used.\n\nWithin your application, import the **useDate** function and use it to access the date composable.\n\n```html { resource=\"src/views/Date.vue\" }\n<script setup>\n  import { useDate } from 'vuetify'\n\n  const date = useDate()\n\n  console.log(date.getMonth(new Date('March 1, 2021'))) // 2\n</script>\n```\n\n::: info\n\nFor a list of all supported date adapters, visit the [date-io](https://github.com/dmtrKovalenko/date-io#projects) project repository.\n\n:::\n\n### Format options\n\nThe date composable supports the following date formatting options:\n\n| Format Name | Format Output |\n| - | - |\n| fullDate | \"Jan 1, 2024\" |\n| fullDateWithWeekday | \"Tuesday, January 1, 2024\" |\n| normalDate | \"1 January\" |\n| normalDateWithWeekday | \"Wed, Jan 1\" |\n| shortDate | \"Jan 1\" |\n| year | \"2024\" |\n| month | \"January\" |\n| monthShort | \"Jan\" |\n| monthAndYear | \"January 2024\" |\n| monthAndDate | \"January 1\" |\n| weekday | \"Wednesday\" |\n| weekdayShort | \"Wed\" |\n| dayOfMonth | \"1\" |\n| hours12h | \"11\" |\n| hours24h | \"23\" |\n| minutes | \"44\" |\n| seconds | \"00\" |\n| fullTime | \"11:44 PM\" for US, \"23:44\" for Europe |\n| fullTime12h | \"11:44 PM\" |\n| fullTime24h | \"23:44\" |\n| fullDateTime | \"Jan 1, 2024 11:44 PM\" |\n| fullDateTime12h | \"Jan 1, 2024 11:44 PM\" |\n| fullDateTime24h | \"Jan 1, 2024 23:44\" |\n| keyboardDate | \"02/13/2024\" |\n| keyboardDateTime | \"02/13/2024 23:44\" |\n| keyboardDateTime12h | \"02/13/2024 11:44 PM\" |\n| keyboardDateTime24h | \"02/13/2024 23:44\" |\n\nThe following example shows how to use the date composable to format a date string:\n\n```html { resource=\"src/views/Date.vue\" }\n<script setup>\n  import { useDate } from 'vuetify'\n\n  const date = useDate()\n\n  const formatted = date.format('2010-04-13', 'fullDateWithWeekday')\n\n  console.log(formatted) // Tuesday, April 13, 2010\n</script>\n```\n\n### Custom formats\n\nYou can extend available formats by providing definitions matching your adapter capabilities.\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createVuetify } from 'vuetify'\n\nexport default createVuetify({\n  date: {\n    formats: {\n      // for built-in adapter\n      weekdayNarrow: { weekday: 'narrow' },\n      // for Moment or Day.js\n      weekdayNarrow: 'dd',\n      // for Luxon or DateFns\n      weekdayNarrow: 'EEEEE',\n    },\n  },\n})\n```\n\n```js\n// use registered key\ndate.format(adapter.date(), 'weekdayNarrow')\n```\n\nBuilt-in adapter accepts objects that will be passed to Intl.DateTimeFormat.\n\n```js\n// works only with built-in adapter\ndate.format(adapter.date(), { weekday: 'narrow' })\n```\n\n## API\n\n| Feature | Description |\n| - | - |\n| [useDate](/api/use-date/) | The date composable is used by components that require date functionality |\n\n<ApiInline hide-links />\n\n## Adapter\n\nThe built-in date adapter implements a subset of functionality from the [DateIOFormats](https://github.com/dmtrKovalenko/date-io/blob/master/packages/core/IUtils.d.ts) interface. Because of this, it's easy to swap in any date library supported by [date-io](https://github.com/dmtrKovalenko/date-io).\n\n### Using DateFns\n\nTo use DateFns as the date adapter, install the necessary packages:\n\n::: tabs\n\n```bash [pnpm]\npnpm install @date-io/date-fns date-fns\n```\n\n```bash [yarn]\nyarn add @date-io/date-fns date-fns\n```\n\n```bash [npm]\nnpm install @date-io/date-fns date-fns\n```\n\n```bash [bun]\nbun install @date-io/date-fns date-fns\n```\n\n:::\n\nThen configure Vuetify to use DateFns:\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createVuetify } from 'vuetify'\nimport DateFnsAdapter from \"@date-io/date-fns\"\n\nexport default createVuetify({\n  date: {\n    adapter: DateFnsAdapter,\n  },\n})\n```\n\nFor more information on DateFns, visit the [date-fns](https://date-fns.org/) documentation.\n\n### Using DayJs\n\nTo use DayJs as the date adapter, install the necessary packages:\n\n::: tabs\n\n```bash [pnpm]\npnpm install @date-io/dayjs dayjs\n```\n\n```bash [yarn]\nyarn add @date-io/dayjs dayjs\n```\n\n```bash [npm]\nnpm install @date-io/dayjs dayjs\n```\n\n```bash [bun]\nbun add @date-io/dayjs dayjs\n```\n\n:::\n\nThen configure Vuetify to use DayJs:\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createVuetify } from 'vuetify'\nimport DayJsAdapter from '@date-io/dayjs'\nimport en from 'dayjs/locale/en'\n\nexport default createVuetify({\n  date: {\n    adapter: DayJsAdapter,\n    locale: { en },\n  },\n})\n```\n\nFor more information on DayJs, visit the [dayjs](https://day.js.org/) documentation.\n\n### Using Luxon\n\nTo use Luxon as the date adapter, install the necessary packages:\n\n::: tabs\n\n```bash [pnpm]\npnpm install @date-io/luxon luxon\n```\n\n```bash [yarn]\nyarn add @date-io/luxon luxon\n```\n\n```bash [npm]\nnpm install @date-io/luxon luxon\n```\n\n```bash [bun]\nbun add @date-io/luxon luxon\n```\n\n:::\n\nThen configure Vuetify to use Luxon:\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createVuetify } from 'vuetify'\nimport LuxonAdapter from '@date-io/luxon'\n\nexport default createVuetify({\n  date: {\n    adapter: LuxonAdapter,\n  },\n})\n```\n\nFor more information on Luxon, visit the [luxon](https://moment.github.io/luxon/) documentation.\n\n### Using Moment\n\nTo use Moment as the date adapter, install the necessary packages:\n\n::: tabs\n\n```bash [pnpm]\npnpm install @date-io/moment moment\n```\n\n```bash [yarn]\nyarn add @date-io/moment moment\n```\n\n```bash [npm]\nnpm install @date-io/moment moment\n```\n\n```bash [bun]\nbun add @date-io/moment moment\n```\n\n:::\n\nThen configure Vuetify to use Moment:\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createVuetify } from 'vuetify'\nimport MomentAdapter from '@date-io/moment'\n\nexport default createVuetify({\n  date: {\n    adapter: MomentAdapter,\n  },\n})\n```\n\nFor more information on Moment, visit the [moment](https://momentjs.com/) documentation.\n\n## Typescript\n\nFor TypeScript users, an interface is also exposed for [module augmentation](https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation):\n\n```ts { resource=\"src/plugins/vuetify.js\" }\nexport default createVuetify({\n  ...\n})\n\ndeclare module 'vuetify' {\n  namespace DateModule {\n    interface Adapter extends LuxonAdapter {}\n  }\n}\n```\n\n## Localization\n\nThe date composable will use the current vuetify [locale](/features/internationalization/) for formatting and getting the first day of the week. These do not always line up perfectly, so a list of aliases can be provided to map language codes to locales. The following configuration will look up `en` keys for translations, but use `en-GB` for date formatting:\n\n```js { resource=\"src/plugins/vuetify.js\" }\nexport default createVuetify({\n  locale: {\n    locale: 'en',\n  },\n  date: {\n    locale: {\n      en: 'en-GB',\n    },\n  },\n})\n```\n\n## Create your own\n\nTo create your own date adapter, implement the **DateAdapter** interface:\n\n```ts\nimport type { DateAdapter } from 'vuetify'\n\nexport interface DateAdapter<TDate> {\n  date (value?: any): TDate | null\n  format (date: TDate, formatString: string): string\n  toJsTDate (value: TDate): TDate\n  parseISO (date: string): TDate\n  toISO (date: TDate): string\n\n  startOfDay (date: TDate): TDate\n  endOfDay (date: TDate): TDate\n  startOfMonth (date: TDate): TDate\n  endOfMonth (date: TDate): TDate\n  startOfYear (date: TDate): TDate\n  endOfYear (date: TDate): TDate\n\n  isBefore (date: TDate, comparing: TDate): boolean\n  isAfter (date: TDate, comparing: TDate): boolean\n  isEqual (date: TDate, comparing: TDate): boolean\n  isSameDay (date: TDate, comparing: TDate): boolean\n  isSameMonth (date: TDate, comparing: TDate): boolean\n  isValid (date: any): boolean\n  isWithinRange (date: TDate, range: [TDate, TDate]): boolean\n\n  addDays (date: TDate, amount: number): TDate\n  addMonths (date: TDate, amount: number): TDate\n\n  getYear (date: TDate): number\n  setYear (date: TDate, year: number): TDate\n  getDiff (date: TDate, comparing: TDate | string, unit?: string): number\n  getWeekArray (date: TDate): TDate[][]\n  getWeekdays (): string[]\n  getMonth (date: TDate): number\n  setMonth (date: TDate, month: number): TDate\n  getNextMonth (date: TDate): TDate\n}\n```\n\n## Inheritance\n\nYou can also extend and override build-in DateAdapter using class inheritance:\n\n```ts\nimport { VuetifyDateAdapter } from 'vuetify/date/adapters/vuetify'\n\nexport class MyAdapter extends VuetifyDateAdapter {\n  sayHello () {\n    return `Hello, current week starts at ${this.startOfWeek(this.date())}`\n  }\n  override startOfWeek (date: Date, firstDayOfWeek?: string | number): Date {\n    return super.startOfWeek(date, 2) // forcing Tuesday\n  }\n}\n```\n\n```ts { resource=\"src/plugins/vuetify.js\" }\nexport default createVuetify({\n  date: {\n    adapter: MyAdapter,\n  },\n  ...\n})\n\ndeclare module 'vuetify' {\n  namespace DateModule {\n    interface Adapter extends MyAdapter {}\n  }\n}\n```\n\n## String adapter\n\nDate objects can be inconvenient to work with, especially if you're just passing the value straight to a fetch request. Vuetify also exports a StringDateAdapter that will cause date components to emit strings instead.\n\n```ts { resource=\"src/plugins/vuetify.js\" }\nimport { StringDateAdapter } from 'vuetify/date/adapters/string'\n\nexport default createVuetify({\n  date: {\n    adapter: StringDateAdapter,\n  },\n})\n```\n"
  },
  {
    "path": "packages/docs/src/pages/en/features/display-and-platform.md",
    "content": "---\nemphasized: true\nmeta:\n  title: Display & Platform\n  description: Access display viewport information using the Vuetify Breakpoint composable.\n  keywords: breakpoints, grid breakpoints, platform details, screen size, display size\nrelated:\n  - /directives/resize/\n  - /styles/display/\n  - /styles/text-and-typography/\nfeatures:\n  github: /composables/display.ts\n  label: 'E: display'\n  report: true\n---\n\n# Display & Platform\n\nThe display composable provides a multitude of information about the current device\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## Usage\n\nThe **useDisplay** composable provides information on multiple aspects of the current device.\n\nThis enables you to control various aspects of your application based upon the window size, device type, and SSR state. This composable works in conjunction with [grids](/components/grids/) and other responsive utility classes (e.g. [display](/styles/display/)).\n\nThe following shows how to access the application's display information:\n\n```html { resource=\"Composition.vue\" }\n<script setup>\n  import { onMounted } from 'vue'\n  import { useDisplay } from 'vuetify'\n\n  const { mobile } = useDisplay()\n\n  onMounted(() => {\n    console.log(mobile.value) // false\n  })\n</script>\n```\n\nIf you are still using the Options API, you can access the display information on the global **$vuetify** variable. Note that refs are unwrapped here, so you don't need `.value`.\n\n```html { resource=\"Options.vue\" }\n<script>\n  export default {\n    mounted () {\n      console.log(this.$vuetify.display.mobile)\n    },\n  }\n</script>\n```\n\n## API\n\n| Component | Description |\n| - | - |\n| [useDisplay](/api/use-display/) | Composable |\n\n## Breakpoints and Thresholds\n\nThreshold values generate the ranges used for various breakpoints seen throughout vuetify and the `useDisplay` composable. The system uses an \"and up\" mentality starting from `xs` at 0px. The default threshold values are displayed below.\n\n<FeaturesBreakpointsTable />\n\nThese ranges power the various additional `AndUp` / `AndDown` properties accessible in `useDisplay`\n\n```ts\n{\n  smAndDown: boolean // < 960px\n  smAndUp: boolean // > 600px\n  mdAndDown: boolean // < 1280px\n  mdAndUp: boolean // > 960px\n  lgAndDown: boolean // < 1919px\n  lgAndUp: boolean // > 1280px\n  xlAndDown: boolean // < 2559px\n  xlAndUp: boolean // > 1920px\n}\n```\n\n## Options\n\nThe **useDisplay** composable has several configuration options, such as the ability to define custom values for breakpoints.\n\nFor example, the **thresholds** option modifies the values used for viewport calculations. The following snippet overrides **thresholds** values *xs* through *lg* and sets **mobileBreakpoint** to `sm`.\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createVuetify} from 'vuetify'\n\nexport default createVuetify({\n  display: {\n    mobileBreakpoint: 'sm',\n    thresholds: {\n      xs: 0,\n      sm: 340,\n      md: 540,\n      lg: 800,\n      xl: 1280,\n    },\n  },\n})\n```\n\n::: info\n  The **mobileBreakpoint** option accepts numbers and breakpoint keys.\n:::\n\n## Examples\n\nIn the following example, we use a switch statement and the current breakpoint name to modify the **height** property of the [v-card](/components/cards/) component:\n\n```html { resource=\"Component.vue\" }\n<template>\n  <v-card :height=\"height\">\n    ...\n  </v-card>\n</template>\n\n<script setup>\n  import { computed } from 'vue'\n  import { useDisplay } from 'vuetify'\n\n  const { name } = useDisplay()\n\n  const height = computed(() => {\n    // name is reactive and\n    // must use .value\n    switch (name.value) {\n      case 'xs': return 220\n      case 'sm': return 400\n      case 'md': return 500\n      case 'lg': return 600\n      case 'xl': return 800\n      case 'xxl': return 1200\n    }\n\n    return undefined\n  })\n</script>\n```\n\n### Interface\n\n```ts\n{\n  // Breakpoints\n  xs: boolean // 0 - 599\n  sm: boolean // 600 - 839\n  md: boolean // 840 - 1144\n  lg: boolean // 1145 - 1544\n  xl: boolean // 1545 - 2137\n  xxl: boolean // >= 2138\n  smAndDown: boolean // < 840\n  smAndUp: boolean // > 599\n  mdAndDown: boolean // < 1145\n  mdAndUp: boolean // > 839\n  lgAndDown: boolean // < 1545\n  lgAndUp: boolean // > 1144\n  xlAndDown: boolean // < 2138\n  xlAndUp: boolean // > 1544\n\n  // true if screen width < mobileBreakpoint\n  mobile: boolean\n  mobileBreakpoint: number | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl'\n\n  // Current breakpoint name (e.g. 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl')\n  name: string\n\n  // The current value of window.innerHeight and window.innerWidth\n  height: number\n  width: number\n\n  // Device userAgent information\n  platform: {\n    android: boolean\n    ios: boolean\n    cordova: boolean\n    electron: boolean\n    chrome: boolean\n    edge: boolean\n    firefox: boolean\n    opera: boolean\n    win: boolean\n    mac: boolean\n    linux: boolean\n    touch: boolean\n    ssr: boolean\n  }\n\n  // The values used to make Breakpoint calculations\n  thresholds: {\n    xs: number\n    sm: number\n    md: number\n    lg: number\n    xl: number\n    xxl: number\n  }\n}\n```\n\n## Using Setup\n\nUse the **useDisplay** composable alongside Vue 3's `setup` function to harness the power of the [Composition API](https://v3.vuejs.org/guide/composition-api-setup.html). In this example we show how to toggle the **fullscreen** property of `v-dialog` when the mobile breakpoint is active.\n\n```html { resource=\"Component.vue\" }\n<template>\n  <v-dialog :fullscreen=\"mobile\">\n    ...\n  </v-dialog>\n</template>\n\n<script setup>\n  import { useDisplay } from 'vuetify'\n\n  const { mobile } = useDisplay()\n</script>\n```\n\n### Breakpoint conditionals\n\nBreakpoint and conditional values return a `boolean` that is derived from the current viewport size. Additionally, the **breakpoint** composable follows the [Vuetify Grid](/components/grids) naming conventions and has access to properties such as **xs**, **smAndUp**, **mdAndDown**, and many others. In the following example we use the `setup` function to pass the *xs* and *mdAndUp* values to our template:\n\n```html { resource=\"Component.vue\" }\n<template>\n  <v-sheet\n    :min-height=\"mdAndUp ? 300 : '20vh'\"\n    :rounded=\"xs\"\n  >\n    ...\n  </v-sheet>\n</template>\n\n<script setup>\n  import { useDisplay } from 'vuetify'\n\n  // Destructure only the keys you want to use\n  const { xs, mdAndUp } = useDisplay()\n</script>\n```\n\nUsing the *dynamic* display values, we are able to adjust the minimum height of [v-sheet](/components/sheets/) to `300` when on the *medium* breakpoint or greater and only show rounded corners on *extra small* screens:\n\n## Component Mobile Breakpoints\n\nSome components within Vuetify have a **mobile-breakpoint** property which allows you to override the default value. These components reference the global mobileBreakpoint value that is generated at runtime using the provided options in the `vuetify.js` file.\n\nThe following components have built in support for the **mobile-breakpoint** property:\n\n| Component |\n| - |\n| [v-banner](/components/banners/) |\n| [v-navigation-drawer](/components/navigation-drawers/) |\n| [v-slide-group](/components/slide-groups/) |\n\nBy default, **mobileBreakpoint** is set to **lg**, which means that if the window is less than *1280* pixels in width (which is the default value for the **lg** threshold), then the **useDisplay** composable will update its **mobile** value to `true`.\n\nFor example, the [v-banner](/components/banners/) component implements different styling when its mobile versus desktop. In the following example, The first banner uses the global **mobile-breakpoint** value of **lg** while the second overrides this default with **580**:\n\n```html { resource=\"Component.vue\" }\n<template>\n  <div>\n    <v-banner>\n      ...\n    </v-banner>\n\n    <v-banner mobile-breakpoint=\"580\">\n      ...\n    </v-banner>\n  </div>\n</template>\n\n<script setup>\n  import { onMounted } from 'vue'\n  import { useDisplay } from 'vuetify'\n\n  const { width, mobile } = useDisplay()\n\n  onMounted(() => {\n    console.log(width.value) // 960\n    console.log(mobile.value) // true\n  })\n</script>\n```\n\nIf the screen width is 1024 pixels, the second banner would not convert into its mobile state.\n\n### useDisplay overrides\n\nSpecify a custom **mobileBreakpoint** value directly to the [useDisplay](/api/use-display/) composable and override the global value. In the following example we use a custom mobileBreakpoint value of **580**:\n\n```html { resource=\"Component.vue\" }\n<script setup>\n  import { onMounted } from 'vue'\n  import { useDisplay } from 'vuetify'\n\n  const { mobile } = useDisplay({ mobileBreakpoint: 580 })\n\n  // Given a viewport width of 960px\n  onMounted(() => {\n    console.log(mobile.value) // false\n  })\n</script>\n```\n\nIf you supply a value for the **name** argument, utilize the **displayClasses** property to apply the appropriate classes to your component. In the next example, the following classes would be applied to the root element of the component:\n\n```html { resource=\"Component.vue\" }\n<template>\n  <div\n    :class=\"[\n      'v-component',\n      displayClasses,\n    ]\"\n  >\n    <!-- v-component--mobile -->\n  </div>\n</template>\n\n<script setup>\n  import { defineName } from 'vue'\n  import { useDisplay } from 'vuetify'\n\n  const { displayClasses } = useDisplay({ mobileBreakpoint }, 'v-component')\n</script>\n```\n\nIf you leave out the name argument, displayClasses will use the default name set by Vue. The following example uses the default name of the local component:\n\n```html { resource=\"AppDrawer.vue\" }\n<template>\n  <v-navigation-drawer\n    :class=\"[\n      displayClasses, // 'app-drawer--mobile'\n    ]\"\n  >\n    ...\n  </v-navigation-drawer>\n</template>\n\n<script setup>\n  import { useDisplay } from 'vuetify'\n\n  const { displayClasses } = useDisplay({ mobileBreakpoint })\n</script>\n```\n"
  },
  {
    "path": "packages/docs/src/pages/en/features/global-configuration.md",
    "content": "---\nmeta:\n  title: Global configuration\n  description: Vuetify.config is an object containing global configuration options that modify the bootstrapping of your project.\n  keywords: vuetify config, global config, global vuetify config, configure vuetify options\nrelated:\n  - /features/accessibility/\n  - /features/treeshaking/\n  - /features/blueprints/\nfeatures:\n  github: /composables/defaults.ts\n  label: 'E: defaults'\n  report: true\n---\n\n# Global configuration\n\nVuetify allows you to set default prop values globally or per component when setting up your application. Using this functionality you can for example disable **ripple** on all components, or set the default **elevation** for all sheets or buttons.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## Setup\n\nUse the **defaults** property of the Vuetify configuration object to set default prop values. Here we have disabled **ripple** for all components that support it, and set the default **elevation** to `2` and the default **prepend-icon** to `$vuetify` for all `<v-btn>` components.\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createApp } from 'vue'\nimport { createVuetify } from 'vuetify'\n\nexport default createVuetify({\n  defaults: {\n    global: {\n      ripple: false,\n    },\n    VBtn: {\n      elevation: 2,\n      prependIcon: \"$vuetify\",\n    },\n  },\n})\n```\n\n::: warning\n  Default props should be indicated in camelCase.\n:::\n\n## Contextual defaults\n\nDefaults can also be configured for components nested within other components, for example if you want to set the default **variant** for all `<v-btn>` components nested within a `<v-card>` component:\n\n```js { resource=\"src/plugins/vuetify.js\" }\ncreateVuetify({\n  defaults: {\n    VCard: {\n      VBtn: { variant: 'outlined' },\n    },\n  },\n})\n```\n\nThis is used internally by some components already:\n\n- `<v-btn>` has `variant=\"text\"` when nested within a `<v-card-actions>` or `<v-toolbar>`\n- `<v-list>` has `bg-color=\"transparent\"` when nested within a `<v-navigation-drawer>`\n- Lists, chip groups, expansion panels, tabs, and forms all use this system to propagate certain props to their children, for example `<v-tabs disabled>` will set the default value of `disabled` to `true` for all `<v-tab>` components inside it.\n\n[v-defaults-provider](/components/defaults-providers/) can be used to set defaults for components within a specific scope.\n\n## Global class and styles\n\nDefine global classes and styles for all [built-in](/components/all/) components; including [virtual](/features/aliasing/#virtual-component-defaults) ones. This provides an immense amount of utility when building your application's design system and it reduces the amount of duplicated code in your templates.\n\nLet's say that you want to set the **text-transform** of all [v-btn](/components/buttons/) components to `none`, but are not interested in using [SASS variables](/features/sass-variables/). By simply adding the **style** property to a component's default values, you are able to apply custom values to all instances of said component.\n\nThe following code example modifies the **text-transform** CSS property of all `<v-btn>` components:\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createVuetify } from 'vuetify'\nimport { VBtn } from 'vuetify/components/VBtn'\n\nexport default createVuetify({\n  defaults: {\n    VBtn: {\n      style: 'text-transform: none;',\n    },\n  },\n})\n```\n\nAs an alternative, apply utility classes instead to achieve the same effect:\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createVuetify } from 'vuetify'\nimport { VBtn } from 'vuetify/components/VBtn'\n\nexport default createVuetify({\n  defaults: {\n    VBtn: {\n      class: 'text-none',\n    },\n  },\n})\n```\n\nAdditionally, it works with any valid Vue value type such as objects and arrays:\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createVuetify } from 'vuetify'\nimport { VBtn } from 'vuetify/components/VBtn'\n\nexport default createVuetify({\n  defaults: {\n    VBtn: {\n      style: [{ textTransform: 'none' }],\n    },\n  },\n})\n```\n\n::: warning\n  `class` and `style` cannot be used in the `global` object, only in specific components.\n:::\n\n## Using with virtual components\n\nWhether you are developing a wrapper framework or just a design system for your application, [virtual components](/features/aliasing/#virtual-component-defaults) are a powerful ally. Within the Vuetify defaults system, classes and styles are treated just like regular props but instead of being overwritten at the template level, they are merged.\n\nFor example, lets create an alias of the [v-btn](/components/buttons/) component and modify some of its default values:\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createVuetify } from 'vuetify'\nimport { VBtn } from 'vuetify/components/VBtn'\n\nexport default createVuetify({\n  aliases: {\n    VBtnPrimary: VBtn,\n  },\n\n  defaults: {\n    VBtnPrimary: {\n      class: ['v-btn--primary', 'text-none'],\n    },\n  },\n})\n```\n\nNow, use `<v-btn-primary>` in a template and apply a custom class:\n\n```html\n<template>\n  <v-btn-primary class=\"foobar\">Foobar</v-btn-primary>\n</template>\n```\n\nWhen compiled, the resulting HTML will contain both the globally defined classes and the custom one:\n\n```html\n<!-- Example HTML Output -->\n<button class=\"v-btn v-btn--primary text-none foobar\">Fizzbuzz</button>\n```\n\nThis is particularly useful when you have multiple variants of a component that need individual classes to target:\n\n```html { resource=\"src/components/HelloWorld.vue\" }\n<template>\n  <v-app>\n    <v-main>\n      <v-btn-primary>Primary</v-btn-primary>\n\n      <span class=\"mx-2\" />\n\n      <v-btn-secondary>Secondary</v-btn-secondary>\n    </v-main>\n  </v-app>\n</template>\n\n<style>\n  .v-btn.v-btn--primary {\n    background: linear-gradient(to right, #ff8a00, #da1b60);\n    color: white;\n  }\n  .v-btn.v-btn--secondary {\n    background: linear-gradient(to right, #da1b60, #ff8a00);\n    color: white;\n  }\n</style>\n```\n\nKeep in mind that virtual components do not inherit global class or styles from their extension. For example, the following Vuetify configuration uses a [v-chip](/components/chips/) as the alias for the virtual `<v-chip-primary>` component.\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createVuetify } from 'vuetify'\nimport { VChip } from 'vuetify/components/VChip'\n\nexport default createVuetify({\n  aliases: {\n    VChipPrimary: VChip,\n  },\n\n  defaults: {\n    VChipPrimary: {\n      class: 'v-chip--primary',\n    },\n    VChip: {\n      class: 'v-chip--custom',\n    },\n  },\n})\n```\n\nWhen `<v-chip-primary>` is used in a template, it will **not** have the `v-chip--custom` class.\n\n::: warning\nThere are some cases where a default class or style could be unintentionally passed down to an inner component. This mostly concerns [form inputs and controls](/components/all/#form-inputs-and-controls).\n:::\n\n## Using in custom components\n\nHook into the Vuetify defaults engine and configure your custom components the same way that we do. This feature makes it super easy to homogenize functionality across your application and reduce the amount of duplicated code.\n\nLet's start with an example by creating a basic component that accepts a single prop:\n\n```html { resource=\"src/components/MyComponent.vue\" }\n<template>\n  <div>I am {{ foo }}</div>\n</template>\n\n<script setup>\n  defineProps({ foo: String })\n</script>\n```\n\nNow, let's add our new component to the Vuetify defaults configuration object and assign a default value to its `foo` prop:\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createVuetify } from 'vuetify'\n\nexport default createVuetify({\n  defaults: {\n    MyComponent1: {\n      foo: 'bar',\n    },\n  },\n})\n```\n\nNext, import the `useDefaults` composable into `MyComponent1.vue`. This function has two optional arguments:\n\n- `props` - The props object used to generate the component's default values\n- `name` - The name of the component. This is used to reference the defaults key defined in your Vuetify configuration\n\nIn your template, assign the return value of `defineProps` to a variable and pass it to `useDefaults`:\n\n```html { resource=\"src/components/MyComponent1.vue\" }\n<template>\n  <div>I am {{ props.foo }}</div>\n</template>\n\n<script setup>\n  import { useDefaults } from 'vuetify'\n\n  const _props = defineProps({ foo: String })\n  const props = useDefaults(_props, 'MyComponent1')\n</script>\n```\n\nNotice that we have to explicitly use the `props` object in the template. This is because Vue automatically unwraps the values in `defineProps`.\n\n```diff\n-<div>I am {{ foo }}</div>\n+<div>I am {{ props.foo }}</div>\n```\n\n::: info\nThe **name** argument is optional and is inferred from the component's name if not provided.\n:::\n\nWhen `<MyComponent1>` is used in a template, it uses the default value assigned in the Vuetify config:\n\n```html\n<template>\n  <MyComponent1 /> <!-- I am bar -->\n</template>\n```\n\n### Nested defaults\n\nIt is possible to assign nested defaults within your component chain. This provides you with countless ways to configure your application and its components.\n\nLet's expand on the previous [example](#using-in-custom-components) by creating a new component, `<MyComponent2>` that uses `<MyComponent1>`:\n\n```html { resource=\"src/components/MyComponent2.vue\" }\n<template>\n  <MyComponent1 />\n</template>\n\n<script setup>\n  import MyComponent1 from './MyComponent1.vue'\n</script>\n```\n\nNow, let's add `<MyComponent2>` to the Vuetify defaults configuration object and assign a default value to `foo` prop of all nested `<MyComponent1>` components:\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createVuetify } from 'vuetify'\n\nexport default createVuetify({\n  defaults: {\n    MyComponent: { foo: 'bar' },\n\n    MyComponent2: {\n      MyComponent: { foo: 'baz' },\n    }\n  }\n})\n```\n\nHead back to the `MyComponent2.vue` file and import & invoke the `useDefaults` composable:\n\n```html { resource=\"src/components/MyComponent2.vue\" }\n<template>\n  <div>\n    <slot />\n  </div>\n</template>\n\n<script setup>\n  import MyComponent1 from './MyComponent1.vue'\n  import { useDefaults } from 'vuetify'\n\n  useDefaults()\n</script>\n```\n\nFinally, add both new components to a template and inspect the output:\n\n```html\n<template>\n  <v-app>\n    <v-main>\n      <MyComponent1 /> <!-- I am bar -->\n\n      <MyComponent2>\n        <MyComponent1 /> <!-- I am baz -->\n      </MyComponent2>\n    </v-main>\n  </v-app>\n</template>\n\n<script setup>\n  import MyComponent1 from './MyComponent1.vue'\n  import MyComponent2 from './MyComponent2.vue'\n</script>\n```\n\nNow, whenever `<MyComponent1>` is used within the `<MyComponent2>` component, it has a different assigned default value.\n"
  },
  {
    "path": "packages/docs/src/pages/en/features/hotkey.md",
    "content": "---\nmeta:\n  nav: Hotkeys\n  title: Hotkeys\n  description: Handle keyboard shortcuts within your application using the useHotkey composable\n  keywords: hotkeys, keyboard shortcuts, composable, useHotkey, key bindings\nrelated:\n  - /components/hotkeys/\n  - /features/accessibility/\n  - /features/global-configuration/\nfeatures:\n  github: /composables/hotkey\n  label: 'E: hotkey'\n  report: true\n---\n\n# Hotkeys\n\nProvides a simple and powerful way to register keyboard shortcuts that work across different platforms and input contexts.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## Quick start\n\nTo get started, import the `useHotkey` composable:\n\n```html { resource=\"path/to/Component.vue\"}\n<script setup>\n  import { useHotkey } from 'vuetify'\n\n  useHotkey('ctrl+s', () => {\n    console.log('Save action')\n  })\n</script>\n```\n\n## Usage\n\nThe **hotkey** composable takes a key combination string and a callback function. It automatically handles platform differences, key sequences, and provides options for customizing behavior.\n\n<ExamplesUsage name=\"hotkey\" />\n\n## API\n\n| Composable | Description |\n| - | - |\n| [useHotkey](/api/use-hotkey/) | The useHotkey composable |\n\n## Guide\n\nThe `useHotkey` composable provides a declarative way to handle keyboard shortcuts in your Vue applications. It automatically cleans up event listeners when components are unmounted and supports reactive key combinations.\n\n### Basic hotkeys\n\nRegister simple keyboard shortcuts by passing a key combination string and callback function:\n\n<ExamplesExample file=\"hotkey/basic\" />\n\n### Key sequences\n\nCreate multi-step keyboard shortcuts by separating keys with dashes. Users must press keys in sequence within the timeout period:\n\n<ExamplesExample file=\"hotkey/sequences\" />\n\n### Platform awareness\n\nThe composable automatically handles platform differences. Use `cmd` for cross-platform compatibility or specific modifiers for platform-specific behavior:\n\n<ExamplesExample file=\"hotkey/platform\" />\n\n### Reactive hotkeys\n\nKey combinations can be reactive, allowing you to change hotkeys dynamically:\n\n<ExamplesExample file=\"hotkey/reactive\" />\n\n### Options\n\nCustomize hotkey behavior with options for event type, input handling, and more:\n\n<ExamplesExample file=\"hotkey/options\" />\n\n## Configuration options\n\nThe `useHotkey` composable accepts an optional third parameter of type `HotkeyOptions` to customize its behavior:\n\n```typescript\ninterface HotkeyOptions {\n  event?: 'keydown' | 'keyup'\n  inputs?: boolean\n  preventDefault?: boolean\n  sequenceTimeout?: number\n}\n```\n\n### Event type\n\nControl which keyboard event triggers the hotkey:\n\n```js\n// Trigger on key press (default)\nuseHotkey('ctrl+s', handleSave, { event: 'keydown' })\n\n// Trigger on key release\nuseHotkey('ctrl+s', handleSave, { event: 'keyup' })\n```\n\n**When to use:**\n\n- `keydown`: For actions that should trigger immediately when pressed (most common)\n- `keyup`: For actions that should wait until the key is released, useful for preventing repeated triggers\n\n### Input handling\n\nBy default, hotkeys are disabled when input elements are focused to prevent conflicts with typing:\n\n```js\n// Default: hotkeys disabled in input fields\nuseHotkey('ctrl+s', handleSave)\n\n// Allow hotkeys even when inputs are focused\nuseHotkey('ctrl+s', handleSave, { inputs: true })\n```\n\n**Best practices:**\n\n- Keep `inputs: false` (default) for global shortcuts like save/copy/paste\n- Use `inputs: true` for application-specific shortcuts that should work everywhere\n- Consider using different key combinations for input-specific actions\n\n### Prevent default behavior\n\nControl whether the browser's default behavior for the key combination is prevented:\n\n```js\n// Prevent browser default (recommended for most cases)\nuseHotkey('ctrl+s', handleSave, { preventDefault: true })\n\n// Allow browser default behavior\nuseHotkey('f5', handleRefresh, { preventDefault: false })\n```\n\n**When to disable:**\n\n- When you want to enhance rather than replace browser behavior\n- For accessibility keys that should maintain their original function\n- When testing or debugging hotkey interactions\n\n### Sequence timeout\n\nFor key sequences, control how long users have between keystrokes:\n\n```js\n// Default: 1 second between sequence steps\nuseHotkey('ctrl+k-p', openPalette)\n\n// Faster timeout for expert users\nuseHotkey('ctrl+k-p', openPalette, { sequenceTimeout: 500 })\n\n// Longer timeout for accessibility\nuseHotkey('ctrl+k-p', openPalette, { sequenceTimeout: 2000 })\n```\n\n## Key combination syntax\n\nThe hotkey string supports various modifiers and special keys:\n\n### Modifiers\n\n- <v-kbd>cmd</v-kbd> / <v-kbd>meta</v-kbd> - Command key (Mac) / Control key (PC) - **recommended over <v-kbd>ctrl</v-kbd> for cross-platform**\n- <v-kbd>ctrl</v-kbd> - Control key (all platforms)\n- <v-kbd>alt</v-kbd> - Alt key (all platforms)\n- <v-kbd>shift</v-kbd> - Shift key (all platforms)\n\n### Special keys\n\n- <v-kbd>enter</v-kbd>, <v-kbd>escape</v-kbd>, <v-kbd>tab</v-kbd>, <v-kbd>space</v-kbd>, <v-kbd>backspace</v-kbd>, <v-kbd>delete</v-kbd>\n- <v-kbd>arrowup</v-kbd>, <v-kbd>arrowdown</v-kbd>, <v-kbd>arrowleft</v-kbd>, <v-kbd>arrowright</v-kbd>\n- <v-kbd>home</v-kbd>, <v-kbd>end</v-kbd>, <v-kbd>pageup</v-kbd>, <v-kbd>pagedown</v-kbd>\n- <v-kbd>f1</v-kbd> through <v-kbd>f12</v-kbd>\n- <v-kbd>plus</v-kbd>, <v-kbd>slash</v-kbd>, <v-kbd>underscore</v-kbd>, and <v-kbd>minus</v-kbd>/<v-kbd>hyphen</v-kbd> for literal <v-kbd>+</v-kbd>, <v-kbd>/</v-kbd>, <v-kbd>_</v-kbd>, and <v-kbd>-</v-kbd>\n\n### Syntax rules\n\n- Parsing is performed left to right, so `ctrl+s-a` will produce \"`ctrl+s` and then `a`\"\n- Use `+` or `_` to combine modifiers with keys: `ctrl+s`, `ctrl_s`\n- Use `/` to separate alternative keys or combinations: `ctrl+k/ctrl+f`, `up/down`\n- Use `-` to create sequences: `ctrl+k-p` (Ctrl+K, then P) `ctrl+k/ctrl+f-p` (Ctrl+K or Ctrl+F, then P)\n- Keys are case-insensitive: `Ctrl+S` equals `ctrl+s`\n\nCheck out [all possible keycodes](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code/code_values).\n\n## Manual cleanup\n\nThe composable automatically manages cleanup during the Vue component's unmount lifecycle event. If you need to perform manual cleanup, you can save the cleanup function returned by the composable. Executing this function will remove the hotkey listener.\n\n```js\nconst cleanup = useHotkey('ctrl+s', () => {\n  console.log('Save action')\n})\n\n// Later, manually cleanup\ncleanup()\n```\n\n## Avoiding key binding conflicts\n\nPrevent conflicts by avoiding reserved shortcuts and organizing hotkeys systematically:\n\n### Common conflicts to avoid\n\n```js\n// ❌ Browser shortcuts\nuseHotkey('f5', handleAction)        // Refresh\nuseHotkey('ctrl+t', handleAction)    // New tab\nuseHotkey('ctrl+w', handleAction)    // Close tab\n\n// ❌ OS shortcuts\nuseHotkey('alt+tab', handleAction)   // Window switching\n\n// ✅ Safe alternatives\nuseHotkey('cmd+shift+r', handleAction)\nuseHotkey('cmd+k-t', handleAction)\nuseHotkey('alt+1', handleAction)\n```\n\n## Best practices\n\n::: info\nHotkeys are a powerful feature, but they utilize APIs that are managed by the browser and the operating system. The reliability of the key bindings you make are subject to factors that can be difficult to control. It's recommended you test your key bindings in the browsers and operating systems you are targeting.\n:::\n\n- **Test cross-platform**: _Verify shortcuts work_ on Windows, macOS, and Linux!\n- **Use modifier combinations**: Prefer `Ctrl+Shift+Key` for custom actions\n- **Document your shortcuts**: Maintain a list of all application hotkeys in your application\n"
  },
  {
    "path": "packages/docs/src/pages/en/features/icon-fonts.md",
    "content": "---\nemphasized: true\nmeta:\n  title: Icon Fonts\n  description: Vuetify supports Material Design Icons, Font awesome and other icon sets through prefixes and global options.\n  keywords: vue icon component, iconfont, icon libraries, vuetify icons\nrelated:\n  - /components/icons\n  - /components/buttons\n  - /components/avatars\nfeatures:\n  github: /composables/icons.tsx\n  label: 'E: icons'\n  report: true\n---\n\n# Icon Fonts\n\nOut of the box, Vuetify supports many popular icon libraries - [Material Design Icons](https://pictogrammers.com/library/mdi/), [Font Awesome](https://fontawesome.com/), [Phosphor](https://phosphoricons.com/), [Lucide](https://lucide.dev/), [Tabler](https://tabler.io/icons), and more.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## Usage\n\nTo change your font library, import one of the pre-defined icon sets or provide your own.\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createVuetify } from 'vuetify'\nimport { aliases, mdi } from 'vuetify/iconsets/mdi'\n\nexport default createVuetify({\n  icons: {\n    defaultSet: 'mdi',\n    aliases,\n    sets: {\n      mdi,\n    },\n  },\n})\n```\n\n```html\n<template>\n  <v-icon icon=\"mdi-home\" />\n</template>\n```\n\nIn the above examples we import the default `mdi` icon set and its corresponding aliases. These aliases reference commonly used types of icons that are utilized by Vuetify components.\n\n::: info\n\nWhile it is still possible to supply the icon value through the default slot in Vuetify 3+ (`<v-icon>mdi-home</v-icon>`), we recommend using the `icon` prop instead.\n\n:::\n\n## Installing icon fonts\n\nYou are required to include the specified icon library (even when using the default icons from [Material Design Icons](https://pictogrammers.com/library/mdi/)). This can be done by including a CDN link or importing the icon library into your application.\n\n::: info\n\nIn this page \"Material Icons\" is used to refer to the [official google icons](https://fonts.google.com/icons) and \"Material Design Icons\" refers to the [extended third-party library](https://pictogrammers.com/library/mdi/)\n\n:::\n\n### Material Design Icons\n\nThis is the default icon set used by Vuetify. It supports local installation with a build process or a CDN link. The following shows how to add the CDN link to your `index.html`:\n\n#### MDI - CSS\n\n```html\n<link href=\"https://cdn.jsdelivr.net/npm/@mdi/font@5.x/css/materialdesignicons.min.css\" rel=\"stylesheet\">\n```\n\nOr as a local dependency:\n\n::: tabs\n\n```bash [pnpm]\npnpm add @mdi/font -D\n```\n\n```bash [yarn]\nyarn add @mdi/font -D\n```\n\n```bash [npm]\nnpm install @mdi/font -D\n```\n\n```bash [bun]\nbun add @mdi/font -D\n```\n\n:::\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport '@mdi/font/css/materialdesignicons.css' // Ensure you are using css-loader\nimport { createVuetify } from 'vuetify'\n\nexport default createVuetify({\n  icons: {\n    defaultSet: 'mdi', // This is already the default value - only for display purposes\n  },\n})\n```\n\n::: error\n\n**DO NOT** use a CDN link without specifying a package *version*. Failure to do so can result in unexpected changes to your application with new releases.\n\n:::\n\n#### MDI - JS SVG\n\nThis is the recommended installation when optimizing your application for production, as only icons used for Vuetify components internally will be imported into your application bundle. You will need to provide your own icons for the rest of the app.\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createVuetify } from 'vuetify'\nimport { aliases, mdi } from 'vuetify/iconsets/mdi-svg'\n\nexport default createVuetify({\n  icons: {\n    defaultSet: 'mdi',\n    aliases,\n    sets: {\n      mdi,\n    },\n  },\n})\n```\n\n`@mdi/js` or [unplugin-icons](https://github.com/antfu/unplugin-icons) are two alternatives to get the rest of the icons that you will need in your application.\n\nIf you want to stick with `@mdi/js`, use the SVG paths as designated in [@mdi/js](https://www.npmjs.com/package/@mdi/js) and\nonly import the icons that you need.\n\nThe following example shows how to use an imported icon within a `.vue` SFC template:\n\n::: tabs\n\n```bash [pnpm]\npnpm add @mdi/js -D\n```\n\n```bash [yarn]\nyarn add @mdi/js -D\n```\n\n```bash [npm]\nnpm install @mdi/js -D\n```\n\n```bash [bun]\nbun add @mdi/js -D\n```\n\n:::\n\n```html\n<template>\n  <v-icon :icon=\"mdiAccount\" />\n</template>\n\n<script setup>\n  import { mdiAccount } from '@mdi/js'\n</script>\n```\n\nOr the icons you want to use can be added as aliases to simplify reuse:\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createVuetify } from 'vuetify'\nimport { aliases, mdi } from 'vuetify/iconsets/mdi-svg'\nimport { mdiAccount } from '@mdi/js'\n\nexport default createVuetify({\n  icons: {\n    defaultSet: 'mdi',\n    aliases: {\n      ...aliases,\n      account: mdiAccount,\n    },\n    sets: {\n      mdi,\n    },\n  },\n})\n```\n\n```html\n<template>\n  <v-icon icon=\"$account\" />\n</template>\n```\n\n#### MDI - Icon search\n\nUse this tool to search for any Material Design Icons and copy them to your clipboard by clicking the item.\n\n<DocIconList />\n\n#### UnoCSS icon sets\n\nVuetify provides pre-configured icon sets that work with [UnoCSS Preset Icons](https://unocss.dev/presets/icons). All icons are tree-shaken so only the icons you use are included in your final CSS bundle.\n\n| Icon library | Iconify package | Vuetify import | Default set name |\n|---|---|---|---|\n| [Material Design Icons](https://pictogrammers.com/library/mdi/) | `@iconify-json/mdi` | `vuetify/iconsets/mdi-unocss` | `mdi` |\n| [Font Awesome 6](https://fontawesome.com/) | `@iconify-json/fa6-solid`<br>`@iconify-json/fa6-regular` | `vuetify/iconsets/fa6` | `fa6` |\n| [Phosphor](https://phosphoricons.com/) | `@iconify-json/ph` | `vuetify/iconsets/ph` | `ph` |\n| [Lucide](https://lucide.dev/) | `@iconify-json/lucide` | `vuetify/iconsets/lucide` | `lucide` |\n| [Tabler](https://tabler.io/icons) | `@iconify-json/tabler` | `vuetify/iconsets/tabler` | `tabler` |\n| [Remix Icon](https://remixicon.com/) | `@iconify-json/ri` | `vuetify/iconsets/ri` | `ri` |\n| [BoxIcons](https://boxicons.com/) | `@iconify-json/bx` | `vuetify/iconsets/bx` | `bx` |\n| [Carbon](https://carbondesignsystem.com/elements/icons/library/) | `@iconify-json/carbon` | `vuetify/iconsets/carbon` | `carbon` |\n| [Material Symbols](https://fonts.google.com/icons) | `@iconify-json/material-symbols` | `vuetify/iconsets/ms` | `ms` |\n\nInstall `unocss` and the Iconify package for your chosen library:\n\n::: tabs\n\n```bash [pnpm]\npnpm add unocss @iconify-json/ph -D\n```\n\n```bash [yarn]\nyarn add unocss @iconify-json/ph -D\n```\n\n```bash [npm]\nnpm install unocss @iconify-json/ph -D\n```\n\n```bash [bun]\nbun add unocss @iconify-json/ph -D\n```\n\n:::\n\nThen configure UnoCSS in your project (read the [UnoCSS integration section](https://unocss.dev/integrations/) for further details).\n\n::: warning\n\nDon't change the default prefix `i-` of UnoCSS preset-icons, Vuetify icon sets rely on it.\n\n:::\n\n```js { resource=\"unocss.config.js\" }\nimport { presetIcons, defineConfig } from 'unocss'\n\nexport default defineConfig({\n  presets: [\n    presetIcons({\n      processor(props) {\n        delete props.color\n      },\n    }),\n  ],\n})\n```\n\nRegister the icon set in your Vuetify configuration. The following example uses Phosphor, but you can substitute any set from the table above:\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createVuetify } from 'vuetify'\nimport { aliases, ph } from 'vuetify/iconsets/ph'\n\nexport default createVuetify({\n  icons: {\n    defaultSet: 'ph',\n    aliases,\n    sets: {\n      ph,\n    },\n  },\n})\n```\n\n### Material Icons\n\nFor projects without a build process, it is recommended to import the icons from CDN.\n\n#### Material Icons - CSS\n\n```html\n<link href=\"https://fonts.googleapis.com/css?family=Material+Icons\" rel=\"stylesheet\">\n```\n\nSome Material Icons are missing by default. For example, `person` and `person_outline` are available, but `visibility_outline` isn't, while `visibility` is. To use the missing icons, replace the existing `<link>` with the following:\n\n```html\n<link\n  rel=\"stylesheet\"\n  href=\"https://fonts.googleapis.com/css?family=Material+Icons|Material+Icons+Outlined|Material+Icons+Two+Tone|Material+Icons+Round|Material+Icons+Sharp\"\n/>\n```\n\nAlternatively, it is possible to install locally using yarn or npm. Keep in mind that this is not an official google repository and may not contain all icons.\n\n::: tabs\n\n```bash [pnpm]\npnpm add material-design-icons-iconfont -D\n```\n\n```bash [yarn]\nyarn add material-design-icons-iconfont -D\n```\n\n```bash [npm]\nnpm install material-design-icons-iconfont -D\n```\n\n```bash [bun]\nbun add material-design-icons-iconfont -D\n```\n\n:::\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport 'material-design-icons-iconfont/dist/material-design-icons.css' // Ensure your project is capable of handling css files\nimport { createVuetify } from 'vuetify'\nimport { aliases, md } from 'vuetify/iconsets/md'\n\nexport default createVuetify({\n  icons: {\n    defaultSet: 'md',\n    aliases,\n    sets: {\n      md,\n    },\n  },\n})\n```\n\n```html\n<template>\n  <v-icon icon=\"home\" />\n</template>\n```\n\n### Font Awesome\n\nThe easiest way to get started with **FontAwesome** is to use a CDN.\n\n#### FA 5 - CSS\n\n```html\n<link href=\"https://use.fontawesome.com/releases/v5.0.13/css/all.css\" rel=\"stylesheet\">\n```\n\nTo install locally you can pull in the [free](https://fontawesome.com/) version of **FontAwesome** using your preferred package manager:\n\n::: tabs\n\n```bash [pnpm]\npnpm add @fortawesome/fontawesome-free -D\n```\n\n```bash [yarn]\nyarn add @fortawesome/fontawesome-free -D\n```\n\n```bash [npm]\nnpm install @fortawesome/fontawesome-free -D\n```\n\n```bash [bun]\nbun add @fortawesome/fontawesome-free -D\n```\n\n:::\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport '@fortawesome/fontawesome-free/css/all.css' // Ensure your project is capable of handling css files\nimport { createVuetify } from 'vuetify'\nimport { aliases, fa } from 'vuetify/iconsets/fa'\n\nexport default createVuetify({\n  icons: {\n    defaultSet: 'fa',\n    aliases,\n    sets: {\n      fa,\n    },\n  },\n})\n```\n\n```html\n<template>\n  <v-icon icon=\"fas fa-home\" />\n</template>\n```\n\n::: error\n\nThe JavaScript version (`all.js`) of the FontAwesome icons will **NOT** work with Vue\n\n:::\n\n#### FA 4 - CSS\n\nThe easiest way to get started with **FontAwesome** is to use a CDN.\n\n```html\n<link href=\"https://cdn.jsdelivr.net/npm/font-awesome@4.x/css/font-awesome.min.css\" rel=\"stylesheet\">\n```\n\nTo install FontAwesome **4** locally is the same as its newer version, just from a different package. You will be using the `font-awesome` package as opposed to `@fortawesome`.\n\n::: tabs\n\n```bash [pnpm]\npnpm add font-awesome@4.7.0 -D\n```\n\n```bash [yarn]\nyarn add font-awesome@4.7.0 -D\n```\n\n```bash [npm]\nnpm install font-awesome@4.7.0 -D\n```\n\n```bash [bun]\nbun add font-awesome@4.7.0 -D\n```\n\n:::\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport 'font-awesome/css/font-awesome.min.css' // Ensure your project is capable of handling css files\nimport { createVuetify } from 'vuetify'\nimport { aliases, fa } from 'vuetify/iconsets/fa4'\n\nexport default createVuetify({\n  icons: {\n    defaultSet: 'fa',\n    aliases,\n    sets: {\n      fa,\n    },\n  },\n})\n```\n\n```html\n<template>\n  <v-icon icon=\"fa-check\" />\n</template>\n```\n\n#### FA 5 - SVG\n\nInstall the following packages.\n\n::: tabs\n\n```bash [pnpm]\npnpm add @fortawesome/fontawesome-svg-core @fortawesome/vue-fontawesome @fortawesome/free-solid-svg-icons @fortawesome/free-regular-svg-icons -D\n```\n\n```bash [yarn]\nyarn add @fortawesome/fontawesome-svg-core @fortawesome/vue-fontawesome @fortawesome/free-solid-svg-icons @fortawesome/free-regular-svg-icons -D\n```\n\n```bash [npm]\nnpm install @fortawesome/fontawesome-svg-core @fortawesome/vue-fontawesome @fortawesome/free-solid-svg-icons @fortawesome/free-regular-svg-icons -D\n```\n\n```bash [bun]\nbun add @fortawesome/fontawesome-svg-core @fortawesome/vue-fontawesome @fortawesome/free-solid-svg-icons @fortawesome/free-regular-svg-icons -D\n```\n\n:::\n\nThen register the global `font-awesome-icon` component and use the pre-defined `fa-svg` icon set. If you have access to Font Awesome Pro icons they can be added to the library in the same way.\n\n```js { resource=\"src/main.js\" }\nimport { createApp } from 'vue'\nimport { createVuetify } from 'vuetify'\nimport { aliases, fa } from 'vuetify/iconsets/fa-svg'\nimport { library } from '@fortawesome/fontawesome-svg-core'\nimport { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'\nimport { fas } from '@fortawesome/free-solid-svg-icons'\nimport { far } from '@fortawesome/free-regular-svg-icons'\n\nconst app = createApp()\n\napp.component('font-awesome-icon', FontAwesomeIcon) // Register component globally\nlibrary.add(fas) // Include needed solid icons\nlibrary.add(far) // Include needed regular icons\n\nconst vuetify = createVuetify({\n  icons: {\n    defaultSet: 'fa',\n    aliases,\n    sets: {\n      fa,\n    },\n  },\n})\n\napp.use(vuetify)\n\napp.mount('#app')\n```\n\n```html\n<template>\n  <v-icon icon=\"fas fa-home\" />\n</template>\n```\n\n## Icon aliases\n\nIcon aliases allow you to define short, reusable names for icons that can map to different sources — such as icon names from a set, local Vue components, or raw SVG paths. Aliases are referenced with an initial `$` followed by the name of the alias, e.g. `$product`. The following icons are available as aliases for use in Vuetify components:\n\n<DocIconTable />\n\n### Custom aliases\n\nIf you are developing custom Vuetify components, you can extend the `aliases` object to utilize the same functionality that internal Vuetify components use. This makes it easier to manage icons consistently throughout your project.\n\nHere’s an example:\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createVuetify } from 'vuetify'\nimport AccountIcon from './account-icon.vue'\nimport ClosetIcon from './closet-icon.vue'\n\nexport const customIcons = {\n  mdiCustomAlias: 'mdi-tag',\n  account: AccountIcon,\n  annotation: [\n    'M14 9.45h-1v-1a1 1 0 0 0-2 0v1h-1a1 1 0 0 0 0 2h1v1a1 1 0 0 0 2 0v-1h1a1 1 0 0 0 0-2Zm6.46.18A8.5 8.5 0 1 0 6 16.46l5.3 5.31a1 1 0 0 0 1.42 0L18 16.46a8.46 8.46 0 0 0 2.46-6.83Zm-3.86 5.42l-4.6 4.6l-4.6-4.6a6.49 6.49 0 0 1-1.87-5.22A6.57 6.57 0 0 1 8.42 5a6.47 6.47 0 0 1 7.16 0a6.57 6.57 0 0 1 2.89 4.81a6.49 6.49 0 0 1-1.87 5.24Z',\n  ],\n  closet: ClosetIcon,\n}\n\nexport const vuetify = createVuetify({\n  theme: {\n    defaultTheme: 'light',\n    //\n  },\n  icons: {\n    defaultSet: 'mdi',\n    aliases: {\n      ...customIcons,\n    },\n  },\n})\n```\n\n```html\n<template>\n  <v-btn prepend-icon=\"$account\">Custom Icon 1</v-btn>\n  <v-btn prepend-icon=\"$mdiCustomAlias\">Custom Icon 2</v-btn>\n  <v-btn prepend-icon=\"$closet\">Custom Icon 3</v-btn>\n  <v-btn prepend-icon=\"$annotation\">Custom Icon 4</v-btn>\n  <v-btn prepend-icon=\"mdi-close\">Default MDI Icon</v-btn>\n</template>\n```\n\nIn this setup:\n\n* `$account` and `$closet` render your own Vue component SVG icons.\n* `$mdiCustomAlias` references an alias for the `mdi-tag` icon.\n* `$annotation` references inline SVG path data.\n\nThis approach gives you flexibility: you can mix external libraries with your own icons seamlessly, while keeping your templates cleaner and easier to maintain.\n\n## Multiple icon sets\n\nOut of the box, Vuetify supports the use of multiple *different* icon sets at the same time. The following example demonstrates how to change the default icon font to Font Awesome (`fa`) while still maintaining access to the original Material Design Icons (`mdi`) through the use of a prefix:\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createVuetify } from 'vuetify'\nimport { aliases, fa } from 'vuetify/iconsets/fa'\nimport { mdi } from 'vuetify/iconsets/mdi'\n\nexport default createVuetify({\n  icons: {\n    defaultSet: 'fa',\n    aliases,\n    sets: {\n      fa,\n      mdi,\n    },\n  },\n})\n```\n\n```html\n<template>\n  <v-icon icon=\"fas fa-plus\" /> // This renders a FontAwesome icon\n  <v-icon icon=\"mdi:mdi-minus\" /> // This renders a MDI icon\n</template>\n```\n\n::: info\n\nIt is not necessary to provide a prefix (such as `mdi:`) for icons from the default icon set\n\n:::\n\n## Creating a custom icon set\n\nAn icon set consists of an object with one property `component` which should be a functional component that receives props of type `IconsProps`, and renders an icon.\n\nIn order to use a custom set as the default icon set, you must also add the necessary *aliases* that correspond to values used by Vuetify components.\n\n```ts { resource=\"src/iconsets/custom.ts\" }\nimport { h } from 'vue'\nimport type { IconSet, IconAliases, IconProps } from 'vuetify'\n\nconst aliases: IconAliases = {\n  collapse: '...',\n  complete: '...',\n  cancel: '...',\n  close: '...',\n  delete: '...',\n  clear: '...',\n  success: '...',\n  info: '...',\n  warning: '...',\n  error: '...',\n  prev: '...',\n  next: '...',\n  checkboxOn: '...',\n  checkboxOff: '...',\n  checkboxIndeterminate: '...',\n  delimiter: '...',\n  sortAsc: '...',\n  sortDesc: '...',\n  sort: '...',\n  expand: '...',\n  menu: '...',\n  subgroup: '...',\n  dropdown: '...',\n  radioOn: '...',\n  radioOff: '...',\n  edit: '...',\n  ratingEmpty: '...',\n  ratingFull: '...',\n  ratingHalf: '...',\n  loading: '...',\n  first: '...',\n  last: '...',\n  unfold: '...',\n  file: '...',\n  plus: '...',\n  minus: '...',\n  calendar:  '...',\n}\n\nconst custom: IconSet = {\n  component: (props: IconProps) => h(...),\n}\n\nexport { aliases, custom }\n```\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createVuetify } from 'vuetify'\nimport { aliases, custom } from '../iconsets/custom'\n\nexport default createVuetify({\n  icons: {\n    defaultSet: 'custom',\n    aliases,\n    sets: {\n      custom,\n    },\n  },\n})\n```\n"
  },
  {
    "path": "packages/docs/src/pages/en/features/internationalization.md",
    "content": "---\nmeta:\n  title: Internationalization (i18n)\n  description: Vuetify supports language Internationalization (i18n) from a wide range of locales and easily integrates vue-i18n.\n  keywords: i18n, language, internationalization\nrelated:\n  - /features/accessibility/\n  - /components/locale-providers/\n  - /getting-started/browser-support/\nfeatures:\n  github: /composables/locale.ts\n  label: 'i18n'\n  report: true\n---\n\n# Internationalization (i18n)\n\nVuetify supports language Internationalization (i18n) of its components.\n\n<PageFeatures />\n\n<PromotedEntry />\n\nWhen bootstrapping your application you can specify available locales and the default locale with the **defaultLocale** option. The **locale** service also supports easy integration with [vue-i18n](https://vue-i18n.intlify.dev/). Using a locale that has an RTL (right-to-left) language also affects the directionality of the Vuetify components.\n\n## Getting started\n\nTo set the available locale messages or the default locale, supply the **locale** option when installing Vuetify.\n\n```js { resource=\"main.js\" }\nimport { createApp } from 'vue'\nimport { createVuetify } from 'vuetify'\n\n// Translations provided by Vuetify\nimport { pl, zhHans } from 'vuetify/locale'\n\n// Your own translation file\nimport sv from './i18n/vuetify/sv'\n\nconst app = createApp()\n\nconst vuetify = createVuetify({\n  locale: {\n    locale: 'zhHans',\n    fallback: 'sv',\n    messages: { zhHans, pl, sv },\n  },\n})\n\napp.use(vuetify)\n\napp.mount('#app')\n```\n\nYou can change the locale during runtime by using the `useLocale` composable.\n\n```html { resource=\"Composition.vue\" }\n<script setup>\n  import { useLocale } from 'vuetify'\n\n  const { current } = useLocale()\n\n  function changeLocale (locale) {\n    current.value = locale\n  }\n</script>\n```\n\nIf you are still using the Options API, you can access the locale settings on `this.$vuetify.locale`.\n\n```html { resource=\"Options.vue\" }\n<script>\n  export default {\n    methods: {\n      changeLocale (locale) {\n        this.$vuetify.locale.current = locale\n      },\n    },\n  }\n</script>\n```\n\n## API\n\n| Feature | Description |\n| - | - |\n| [useLocale](/api/use-locale/) | The locale composable is used |\n| [v-locale-provider](/api/v-locale-provider/) | The locale provider component is used to scope a portion of your application to a different locale than the default one |\n\n<ApiInline hide-links />\n\n## Scoped languages\n\nUsing the `v-locale-provider` component it is possible to scope a portion of your application to a different locale than the default one.\n\n```html { resource=\"src/App.vue\" }\n<template>\n  <v-app>\n    <v-select></v-select> <!-- Will use default locale -->\n\n    <v-locale-provider locale=\"ja\">\n      <v-select></v-select> <!-- Will use ja locale -->\n    </v-locale-provider>\n  </v-app>\n</template>\n```\n\n## RTL\n\nRTL (Right To Left) support is built in for all localizations that ship with Vuetify. If a [supported language](#supported-languages) is flagged as RTL, all content directions are automatically switched. See the [next section](#creating-a-custom-locale) for information on how to add RTL support to a custom locale.\n\nThe following example demonstrates how to force RTL for a specific section of your content, without switching the current language, by using the `v-locale-provider` component:\n\n```html { resource=\"src/App.vue\" }\n<v-app>\n  <v-card>...</v-card> <!-- default locale used here -->\n\n  <v-locale-provider rtl>\n    <v-card>...<v-card> <!-- default locale used here, but with RTL active -->\n  </v-locale-provider>\n</v-app>\n```\n\n## Creating a custom locale\n\nTo create your own locale messages, copy and paste the content of `vuetify/src/locale/en.ts` to a new file, and change the localized strings. You can also specify if they should be displayed RTL or not by using the `rtl` property of the locale options.\n\n```js { resource=\"src/locales/customLocale.js\" }\nexport default {\n  badge: '...',\n  close: '...',\n  ...\n}\n```\n\n```js { resource=\"src/main.js\" }\nimport { createVuetify } from 'vuetify'\nimport customLocale from './locales/customLocale'\n\nconst vuetify = createVuetify({\n  locale: {\n    locale: 'customLocale',\n    messages: { customLocale },\n    rtl: {\n      customLocale: true,\n    },\n  },\n})\n```\n\n## Custom Vuetify components\n\nIf you are building custom Vuetify components that need to hook into the locale service, you can use the `t` function from the **useLocale** composable, or the `$vuetify.locale` property when using Options API.\n\n```html { resource=\"Component.vue\" }\n<template>\n  <div class=\"my-component\">\n    {{ text }}\n  </div>\n</template>\n\n<script setup>\n  import { useLocale } from 'vuetify'\n\n  const { t } = useLocale()\n  const text = t('$vuetify.my-component.text')\n</script>\n```\n\n::: warning\n  The Vuetify locale service only provides a basic translation function `t`, and should really only be used for internal or custom Vuetify components. It is recommended that you use a proper i18n library such as [vue-i18n](https://vue-i18n.intlify.dev/) in your own application. Vuetify does provide support for integrating with other libraries.\n:::\n\n## vue-i18n\n\nIf you are using the vue-i18n library, you can very easily integrate it with Vuetify. This allows you to keep all of your translations in one place. Simply create an entry for $vuetify within your messages and add the corresponding language changes. Then hook up vue-i18n to Vuetify by using the provided adapter function (as seen in the example below).\n\n```js { resource=\"src/main.js\" }\nimport { createApp } from 'vue'\nimport { createVuetify } from 'vuetify'\nimport { createVueI18nAdapter } from 'vuetify/locale/adapters/vue-i18n'\nimport { createI18n, useI18n } from 'vue-i18n'\nimport { en, sv } from 'vuetify/locale'\n\nconst messages = {\n  en: {\n    $vuetify: {\n      ...en,\n      dataIterator: {\n        rowsPerPageText: 'Items per page:',\n        pageText: '{0}-{1} of {2}',\n      },\n    },\n  },\n  sv: {\n    $vuetify: {\n      ...sv,\n      dataIterator: {\n        rowsPerPageText: 'Element per sida:',\n        pageText: '{0}-{1} av {2}',\n      },\n    },\n  },\n}\n\nconst i18n = createI18n({\n  legacy: false, // Vuetify does not support the legacy mode of vue-i18n\n  locale: 'sv',\n  fallbackLocale: 'en',\n  messages,\n})\n\nconst vuetify = createVuetify({\n  locale: {\n    adapter: createVueI18nAdapter({ i18n, useI18n }),\n  },\n})\n\nconst app = createApp()\n\napp.use(i18n)\napp.use(vuetify)\n\napp.mount('#app')\n```\n\n## Supported languages\n\nCurrently Vuetify provides translations in the following languages:\n\n- **af** - Afrikaans (Afrikaans)\n- **ar** - Arabic (العربية)\n- **az** - Azerbaijani (Azərbaycan)\n- **bg** - Bulgarian (български)\n- **ca** - Catalan (català)\n- **ckb** - Central Kurdish (کوردی)\n- **cs** - Czech (čeština)\n- **da** - Danish (Dansk)\n- **de** - German (Deutsch)\n- **el** - Greek (Ελληνικά)\n- **en** - English\n- **es** - Spanish (Español)\n- **et** - Estonian (eesti)\n- **fa** - Persian (فارسی)\n- **fi** - Finnish (suomi)\n- **fr** - French (Français)\n- **he** - Hebrew (עברית)\n- **hr** - Croatian (hrvatski jezik)\n- **hu** - Hungarian (magyar)\n- **id** - Indonesian (Indonesian)\n- **it** - Italian (Italiano)\n- **ja** - Japanese (日本語)\n- **km** - Khmer (ខ្មែរ)\n- **ko** - Korean (한국어)\n- **lt** - Lithuanian (lietuvių kalba)\n- **lv** - Latvian (latviešu valoda)\n- **nl** - Dutch (Nederlands)\n- **no** - Norwegian (Norsk)\n- **pl** - Polish (język polski)\n- **pt** - Portuguese (Português)\n- **ro** - Romanian (Română)\n- **ru** - Russian (Русский)\n- **sk** - Slovak (slovenčina)\n- **sl** - Slovene (slovenski jezik)\n- **srCyrl** - Serbian (српски језик)\n- **srLatn** - Serbian (srpski jezik)\n- **sv** - Swedish (svenska)\n- **th** - Thai (ไทย)\n- **tr** - Turkish (Türkçe)\n- **uk** - Ukrainian (Українська)\n- **vi** - Vietnamese (Tiếng Việt)\n- **zhHans** - Chinese (中文)\n- **zhHant** - Chinese (正體中文)\n"
  },
  {
    "path": "packages/docs/src/pages/en/features/rules.md",
    "content": "---\nmeta:\n  nav: Validation rules\n  title: Validation rules composable\n  description: Vuetify implements a set of validation rules that can be overwritten\n  keywords: Form validation, vuetify form validation, rules composable, validation rules\nrelated:\n  - /components/forms/\n  - /features/internationalization/\nfeatures:\n  github: /labs/rules/\n  label: 'E: rules'\n  report: true\n---\n\n# Validation rules\n\nThe rules composable provide a multitude of validation rules to be used with form inputs.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## Installation\n\nTo use the Rules plugin, you'll need to import and register it with your Vuetify instance:\n\n```js\nimport { createVue } from 'vue'\nimport { createVuetify } from 'vuetify'\nimport { createRulesPlugin } from 'vuetify/labs/rules'\n\nconst app = createVue()\nconst vuetify = createVuetify()\n\napp.use(createRulesPlugin({ /* options */ }, vuetify.locale))\n```\n\nThis will make the rules system available throughout your application. The plugin accepts options for customizing validation rules and integrates with Vuetify's locale system for internationalization.\n\nInside of components, you can now import and utilize the rules composable:\n\n```js\nimport { useRules } from 'vuetify/labs/rules'\n\nconst rules = useRules()\n```\n\n## Usage\n\nWithin your application, import the useRules function and use it to access the rules composable.\nExisting rules' error messages can also be customized on the fly, to fit specific field cases.\n\n```html { resource=\"src/views/ValidationForm.vue\" }\n<template>\n  <v-app>\n    <v-container>\n      <v-form validate-on=\"submit\" @submit.prevent=\"submit\">\n        <v-text-field :rules=\"[rules.required()]\" label=\"Email\" />\n\n        <v-btn text=\"Submit\" type=\"submit\"/>\n      </v-form>\n    </v-container>\n  </v-app>\n</template>\n\n<script setup>\n  import { useRules } from 'vuetify/labs/rules'\n\n  const rules = useRules()\n\n  async function submit (event) {\n    await event\n  }\n</script>\n```\n\n## API\n\nBelow is a table of the available validation rules provided by the rules composable, including their arguments or options:\n\n| Rule Name    | Description                                                                 | Arguments/Options                  |\n|--------------|-----------------------------------------------------------------------------|------------------------------------|\n| required     | Ensures the field is not empty.                                             | `err?: string`                     |\n| email        | Validates that the field contains a valid email address.                    | `err?: string`                     |\n| number       | Validates that the field contains a number.                                 | `err?: string`                     |\n| integer      | Validates that the field contains an integer.                               | `err?: string`                     |\n| capital      | Ensures the field contains at least one capital letter.                     | `err?: string`                     |\n| maxLength    | Validates that the field does not exceed a specified maximum length.        | `len: number, err?: string`        |\n| minLength    | Validates that the field meets a specified minimum length.                  | `len: number, err?: string`        |\n| strictLength | Ensures the field has an exact specified length.                            | `len: number, err?: string`        |\n| exclude      | Ensures the field does not contain any of the specified values.             | `exclude: string[], err?: string`  |\n| notEmpty     | Ensures the field is not empty (similar to required).                       | `err?: string`                     |\n| pattern      | Validates that the field matches a specified regular expression pattern.    | `options: RegExp, err?: string`    |\n\n## Guide\n\nThe `useRules` composable doesn't return rules directly but RuleBuilders that allows to customize\nerror messages and to provide options when necessary.\n\n### Error message\n\nDefault error messages can be field-level redefined.\n\n```html { resource=\"src/App.vue\" }\n<v-form>\n  <v-text-field\n    label=\"Username\"\n    :rules=\"[rules.required('You have to fill this field!')]\"\n  ></v-text-field>\n</v-form>\n```\n\n### Options\n\nSome RuleBuilders need options to work. For example `maxLength` needs a number as first parameter:\n\n```html { resource=\"src/App.vue\" }\n<v-form>\n  <v-text-field\n    label=\"Username\"\n    :rules=\"[rules.maxLength(10)]\"\n  ></v-text-field>\n</v-form>\n```\n\nIn this case, error message can be redefined as second parameter:\n\n```html { resource=\"src/App.vue\" }\n<v-form>\n  <v-text-field\n    label=\"Username\"\n    :rules=\"[rules.maxLength(10, 'You can\\'t write over 10 characters')]\"\n  ></v-text-field>\n</v-form>\n```\n\n<!--\n## Aliases\n\nRules can also be used in inputs using the alias names syntax:\n\n```html { resource=\"src/App.vue\" }\n<v-form>\n  <v-text-field\n    label=\"Username\"\n    :rules=\"['$required']\"\n  ></v-text-field>\n</v-form>\n```\n\nRuleBuilders parameters can also be passed using an Array:\n\n```html { resource=\"src/App.vue\" }\n<v-form>\n  <v-text-field\n    label=\"Username\"\n    :rules=\"[\n      ['$required', 'This field is mandatory'],\n      ['$maxLength', 10, 'You can\\'t write over 10 characters']\n    ]\"\n  ></v-text-field>\n</v-form>\n```\n-->\n\n## Custom rules\n\nVuetify comes with an existing set of validation rules but you can overwrite them or add yours.\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createVue } from 'vue'\nimport { createVuetify } from 'vuetify'\nimport { createRulesPlugin } from 'vuetify/labs/rules'\n\nconst app = createVue()\nconst vuetify = createVuetify()\n\napp.use(createRulesPlugin({\n  aliases: {\n    // Create a new rule named \"pinCode\"\n    pinCode: err => {\n      return v => (/^[\\d]{4}$/.test(v)) || err || 'Field must contain a 4-digit PIN'\n    },\n    // Overwrite an existing rule by redefining it\n    integer: err => {\n      return v => Number.isInteger(v) || err || 'Field must contain an integer value'\n    },\n  },\n}, vuetify.locale)\n```\n"
  },
  {
    "path": "packages/docs/src/pages/en/features/sass-variables.md",
    "content": "---\nmeta:\n  title: SASS variables\n  description: Customize Vuetify's internal styles by modifying SASS variables.\n  keywords: sass variables, scss variables, modifying Vuetify styles\nrelated:\n  - /styles/colors/\n  - /features/theme/\n  - /features/treeshaking/\nfeatures:\n  label: 'sass'\n  report: true\n---\n\n# SASS variables\n\nVuetify uses **SASS/SCSS** to craft the style and appearance of all aspects of the framework.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n::: info\n\nIt is recommended to familiarize yourself with the [Treeshaking](/features/treeshaking/) guide before continuing.\n\n:::\n\n## Installation\n\nVuetify works out of the box without any additional compilers needing to be installed but does support advanced use-cases such as modifying the underlying variables of the framework. Vite provides built-in support for sass, less and stylus files without the need to install Vite-specific plugins for them; just the corresponding pre-processor itself.\n\nTo begin modifying Vuetify's internal variables, install the [sass](https://sass-lang.com/) pre-processor:\n\n::: tabs\n\n```bash [pnpm]\n  pnpm install -D sass-loader sass\n```\n\n```bash [yarn]\n  yarn add -D sass\n```\n\n```bash [npm]\n  npm install -D sass-loader sass\n```\n\n```bash [bun]\n  bun add -D sass-loader sass\n```\n\n:::\n\nFor additional details about css-pre-processors, please refer to the official vite page at: <https://vitejs.dev/guide/features.html#css-pre-processors> or official vue-cli-page at: <https://cli.vuejs.org/guide/css.html#pre-processors>\n\n## Usage\n\nThere are many SASS variables such as **font size**, **font family**, and **line height** that can be configured globally. An extensive list of configurable global SASS variables can be found [here](/api/globals/). To start, follow the plugin setup guide from [treeshaking](/features/treeshaking/) then add `styles.configFile` to the plugin options:\n\n```js { resource=\"vite.config.js\" }\nvuetify({\n  styles: {\n    configFile: 'src/styles/settings.scss',\n  },\n})\n```\n\n`configFile` will be resolved relative to the project root, and loaded before each of vuetify's stylesheets. Next, create a **settings.scss** file in your **src/styles** directory:\n\n```scss { resource=\"src/styles/settings.scss\" }\n@use 'vuetify/settings' with (\n  // variables go here\n);\n```\n\nWithin your style file, specify the variables you want to override, and that's it.\n\n::: info\n\n`'@use 'vuetify'` should only be used for the [`$utilities`](/features/sass-variables/#disabling-utility-classes), [`$color-pack`](/features/sass-variables/#disabling-color-packs), and [`$reset`](/styles/css-reset/#css-reset) settings.\n\n:::\n\n::: warning\n\n`'vuetify/styles'` should not be used in sass files as it resolves to precompiled css ([vitejs/vite#7809](https://github.com/vitejs/vite/issues/7809)). `'vuetify'` and `'vuetify/settings'` are valid and safe to use\n\n:::\n\n::: warning\n\nIf your values contain commas, such as if you are setting `$body-font-family` with multiple fonts, you must surround the value with parentheses, like this: `$body-font-family: ('Roboto', sans-serif)`. Otherwise the commas will be reported as a syntax error.\n\n:::\n\n## Variable API\n\nThere are many SASS/SCSS variables that can be customized across the entire Vuetify framework. You can browse all the variables using the tool below:\n\n<FeaturesSassApi />\n\nAvailable SASS variables are located on each component's API page.\n\n![image](https://github.com/vuetifyjs/vuetify/assets/9064066/967da002-5a9e-4bce-8285-1fa9b849e36d \"VBtn SASS Variables\")\n\n## Usage in templates\n\nYou can access [global](/api/globals/) and per-component variables in Vue templates simply by importing the settings file:\n\n```html { resource=\"Comp1.vue\" }\n<style lang=\"scss\">\n  @use './settings';\n\n  .my-button {\n    height: settings.$button-height;\n  }\n</style>\n```\n\nKeep in mind that to obtain settings from Vuetify, you must forward its variables from within your local stylesheet. In the following example we modify `settings.scss` to **forward** instead of **use**:\n\n```diff { resource=\"src/styles/settings.scss\" }\n- @use 'vuetify/settings' with (\n+ @forward 'vuetify/settings' with (\n```\n\n## Disabling utility classes\n\nUtility classes are a powerful feature of Vuetify, but they can also be unnecessary for some projects. You can either disable them all at once or selecively keeping only what you plan to use. To disable all utility classes, set the entire `$utilities` variable to `false`:\n\n```scss { resource=\"src/styles/main.scss\" }\n@use 'vuetify' with (\n  $utilities: false,\n);\n```\n\nEach utility class is generated with a set of options that are defined [here](https://github.com/vuetifyjs/vuetify/blob/master/packages/vuetify/src/styles/settings/_utilities.scss). Disable individual classes by setting their corresponding variable to `false`.\n\n::: info\n\nVuetify includes several utility classes that are not covered by the `$utilities` map: `elevation`, `hidden`, `sr-only`, and `pointer-events`. If you want to disable these styles while keeping some utilities enabled, you can use the `$misc` variable. See the example at the end of the snippet below.\n\n:::\n\n```scss { resource=\"src/styles/main.scss\" }\n@use 'vuetify' with (\n  $utilities: (\n    \"align-content\": false,\n    \"align-items\": false,\n    \"align-self\": false,\n    \"border-bottom\": false,\n    \"border-current\": false,\n    \"border-end\": false,\n    \"border-opacity\": false,\n    \"border-start\": false,\n    \"border-style\": false,\n    \"border-top\": false,\n    \"border\": false,\n    \"bottom\": false,\n    \"cursor\": false,\n    \"display\": false,\n    \"fill-height\": false,\n    \"flex-direction\": false,\n    \"flex-grow\": false,\n    \"flex-shrink\": false,\n    \"flex-wrap\": false,\n    \"flex\": false,\n    \"float:ltr\": false,\n    \"float:rtl\": false,\n    \"float\": false,\n    \"font-italic\": false,\n    \"font-weight\": false,\n    \"gap-column\": false,\n    \"gap-row\": false,\n    \"gap\": false,\n    \"height-screen\": false,\n    \"height\": false,\n    \"justify-content\": false,\n    \"justify-items\": false,\n    \"left\": false,\n    \"margin-bottom\": false,\n    \"margin-end\": false,\n    \"margin-left\": false,\n    \"margin-right\": false,\n    \"margin-start\": false,\n    \"margin-top\": false,\n    \"margin-x\": false,\n    \"margin-y\": false,\n    \"margin\": false,\n    \"negative-margin-bottom\": false,\n    \"negative-margin-end\": false,\n    \"negative-margin-left\": false,\n    \"negative-margin-right\": false,\n    \"negative-margin-start\": false,\n    \"negative-margin-top\": false,\n    \"negative-margin-x\": false,\n    \"negative-margin-y\": false,\n    \"negative-margin\": false,\n    \"opacity\": false,\n    \"order\": false,\n    \"overflow-wrap\": false,\n    \"overflow-x\": false,\n    \"overflow-y\": false,\n    \"overflow\": false,\n    \"padding-bottom\": false,\n    \"padding-end\": false,\n    \"padding-left\": false,\n    \"padding-right\": false,\n    \"padding-start\": false,\n    \"padding-top\": false,\n    \"padding-x\": false,\n    \"padding-y\": false,\n    \"padding\": false,\n    \"position\": false,\n    \"right\": false,\n    \"rounded-bottom-end\": false,\n    \"rounded-bottom-start\": false,\n    \"rounded-bottom\": false,\n    \"rounded-end\": false,\n    \"rounded-start\": false,\n    \"rounded-top-end\": false,\n    \"rounded-top-start\": false,\n    \"rounded-top\": false,\n    \"rounded\": false,\n    \"text-align\": false,\n    \"text-decoration\": false,\n    \"text-mono\": false,\n    \"text-opacity\": false,\n    \"text-overflow\": false,\n    \"text-transform\": false,\n    \"top\": false,\n    \"typography\": false,\n    \"white-space\": false,\n    \"width\": false,\n  ),\n  $misc: (\n    'pointer-events': false,\n    'sr-only': false,\n    \"elevation\": false,\n    \"hidden\": false,\n  ),\n);\n```\n\nThis is useful when you want to use your own implementation of these styles. For example, if your design system uses standardized shadow levels instead of Vuetify's elevation classes, you can disable the built-in elevation styles and define your own.\n\n## Disabling color packs\n\nColor packs are handy for quickly applying a color to a component but mostly unused in production. To disable them, set the `$color-pack` variable to `false`:\n\n```scss { resource=\"src/styles/main.scss\" }\n@use 'vuetify' with (\n  $color-pack: false,\n);\n```\n\n## Enabling CSS cascade layers\n\n[Cascade layers](https://developer.mozilla.org/en-US/docs/Web/CSS/@layer) are a modern CSS feature that makes it easier to write custom styles without having to deal with specificity issues and `!important`. This will be included by default in Vuetify 4 but can optionally be used now:\n\n```scss { resource=\"src/styles/settings.scss\" }\n@forward 'vuetify/settings' with (\n  $layers: true,\n);\n```\n\n```ts { resource=\"src/plugins/vuetify.ts\" }\nexport default createVuetify({\n  theme: {\n    layers: true,\n  },\n})\n```\n\nImport order of stylesheets becomes much more important with layers enabled, `import 'vuetify/styles'` or a file containing `@use 'vuetify'` **must** be loaded *before* any components or the CSS reset will take precedence over component styles and break everything.\n\n- If you have separate plugin files make sure to import vuetify's before `App.vue`.\n- Imports generated by `import.meta.glob(..., { eager: true })` are hoisted, if you use this for components or files that import components it should be in another file separate from any style imports to ensure `vuetify/styles` is always first.\n\nYour own styles will always<sup>*</sup> override vuetify's if you don't use `@layer` yourself, or you can specify an order for custom layers in a stylesheet loaded before vuetify.\n\n```css { resource=\"src/styles/layers.css\" }\n@layer base, vuetify, overrides;\n```\n\n\\* Layers invert `!important`, so anything trying to override an important vuetify style must also be in a layer. { class=\"text-body-small\" }\n\n## Caveats\n\nWhen using sass variables, there are a few considerations to be aware of.\n\n### Duplicated CSS\n\nPlacing actual styles or importing a regular stylesheet into the settings file will cause them to be duplicated everywhere the file is imported.\nOnly put variables, mixins, and functions in the settings file, styles should be placed in the main stylesheet or loaded another way.\n\n### Build performance\n\nVuetify loads precompiled CSS by default, enabling variable customization will switch to the base SASS files instead which must be recompiled with your project.\nThis can be a performance hit if you're using more than a few vuetify components, and also forces you to use the same SASS compiler version as us.\n\nPerformance can be improved with Vite by using the modern sass compiler. Replace your `sass` dependency with `sass-embedded`, update vite to 5.4 or later, and set [`css.preprocessorOptions.sass.api`](https://vitejs.dev/config/shared-options#css-preprocessoroptions) to `'modern-compiler'` in the vite config.\n\n### Symlinks\n\nPNPM and Yarn 2+ create symlinks to library files instead of copying them to node_modules, sass doesn't seem to like this and sometimes doesn't apply the configuration.\n\n### sass-loader with `api: 'modern'`\n\nYou might have to write a custom importer plugin to load the settings file.\n"
  },
  {
    "path": "packages/docs/src/pages/en/features/scrolling.md",
    "content": "---\nmeta:\n  title: Programmatic scrolling\n  description: Handle scrolling within your application by using the goTo function\n  keywords: programmatic scrolling, vuetify goto, goto\nrelated:\n  - /directives/scroll/\n  - /features/application-layout/\n  - /components/slide-groups/\nfeatures:\n  github: /composables/goto.ts\n  label: 'E: goto'\n  report: true\n---\n\n# Programmatic scrolling\n\nHandle scrolling within your application by using the **goTo** function.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## Usage\n\nThe **goTo** method takes two parameters **target** and **options**. **target** can be either a pixel offset from the top of the page, a valid css selector, or an element reference. **options** is an object that includes **duration**, **easing**, **container**, and **offset**.\n\n<ExamplesExample file=\"scroll/usage\" />\n\n## API\n\n| Directive | Description |\n| - | - |\n| [useGoTo](/api/use-go-to/) | The useGoTo composable |\n\n<ApiInline hide-links />\n\n<!--## Use with router\n\nThe **goTo** function can be individually imported and invoked anywhere. This is particularly useful when hooking up to [vue-router](https://router.vuejs.org/).\n\n```js { resource=\"src/router.js\" }\nimport Router from 'vue-router'\nimport goTo from 'vuetify/lib/services/goto'\n\nexport default new Router({\n  scrollBehavior: (to, from, savedPosition) => {\n    let scrollTo = 0\n\n    if (to.hash) {\n      scrollTo = to.hash\n    } else if (savedPosition) {\n      scrollTo = savedPosition.y\n    }\n\n    return goTo(scrollTo)\n  },\n  routes: [\n    //\n  ],\n})\n```\n-->\n"
  },
  {
    "path": "packages/docs/src/pages/en/features/theme.md",
    "content": "---\nemphasized: true\nmeta:\n  title: Theme\n  description: Setup your application's theme and supplemental colors in a flash.\n  keywords: theme, themes, theming, color, colors\nrelated:\n  - /styles/colors/\n  - /styles/transitions/\n  - /getting-started/wireframes/\nfeatures:\n  github: /composables/theme.ts\n  label: 'E: theme'\n  report: true\n---\n\n# Theme configuration\n\nCustomize your application's default text colors, surfaces, and more. Easily modify your theme programmatically in real time. Vuetify comes with standard support for light and dark variants.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## API\n\n| Feature | Description |\n| - | - |\n| [useTheme](/api/use-theme/) | The theme composable allows you to get information about, and modify the current theme |\n| [v-theme-provider](/api/v-theme-provider/) | The theme provider component modifies the theme of all its children |\n\n<ApiInline hide-links />\n\n## Setup\n\nVuetify includes three built-in themes: **light**, **dark**, and **system**. Use the **defaultTheme** option to specify your application's default theme. The following example sets the default theme to **dark**:\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createApp } from 'vue'\nimport { createVuetify } from 'vuetify'\n\nexport default createVuetify({\n  theme: {\n    defaultTheme: 'dark', // 'system' | 'light' | 'dark'\n  },\n})\n```\n\n## Changing theme\n\nThe theme instance has 3 functions to change the theme:\n\n- **change**: Change to a specific name\n- **toggle**: Toggle between two themes / defaults to light and dark\n- **cycle**: Cycle between all or a specific subset of themes in any order\n\n```html\n<template>\n  <v-app>\n    <v-main>\n      <v-container>\n        <!-- Toggle between Light / Dark -->\n        <v-btn\n          @click=\"theme.toggle()\"\n          text=\"Toggle Light / Dark\"\n        ></v-btn>\n\n        <!-- Change to a specific theme -->\n        <v-btn\n          @click=\"theme.change('dark')\"\n          text=\"Change to Dark\"\n        ></v-btn>\n\n        <!-- Cycle between all themes -->\n        <v-btn\n          @click=\"theme.cycle()\"\n          text=\"Cycle All Themes\"\n        ></v-btn>\n\n        <!-- Cycle between specific themes -->\n        <v-btn\n          @click=\"theme.cycle(['custom', 'light', 'system'])\"\n          text=\"Cycle Specific Themes\"\n        ></v-btn>\n      </v-container>\n    </v-main>\n  </v-app>\n</template>\n\n<script setup>\n  import { useTheme } from 'vuetify'\n\n  const theme = useTheme()\n</script>\n```\n\n<br>\n\nYou should keep in mind that most of the Vuetify components support the **theme** prop. When used a new context is created for _that_ specific component and **all** of its children. In the following example, the [v-btn](/components/buttons/) uses the **dark** theme because it is applied to its parent [v-card](/components/cards/).\n\n```html\n<template>\n  <v-app>\n    <v-card theme=\"dark\">\n      <!-- button uses dark theme -->\n      <v-btn>foo</v-btn>\n    </v-card>\n  </v-app>\n</template>\n```\n\nYou can use the `<v-theme-provider>` component to dynamically apply different themes to larger sections of your application, without having to set the **theme** prop on each individual component. In the following example, we apply a custom theme named `high-contrast`.\n\n```html\n<template>\n  <v-app>\n    <!-- uses the current default theme -->\n    <v-card>...</v-card>\n\n    <v-theme-provider theme=\"high-contrast\">\n      <!-- uses the high-contrast theme -->\n      <v-card>...</v-card>\n      <v-btn>...</v-btn>\n    </v-theme-provider>\n  </v-app>\n</template>\n```\n\n### System theme\n\nThe **system** theme uses the user's system preference for 'light' or 'dark' mode, based on the **prefers-color-scheme** media query. It is evaluated at run-time and reacts to changes in the user's system preference.\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createApp } from 'vue'\nimport { createVuetify } from 'vuetify'\n\nexport default createVuetify({\n  theme: {\n    defaultTheme: 'system',\n  },\n})\n```\n\n## Custom themes\n\nAdding new themes is as easy as defining a new property in the **theme.themes** object. A theme is a collection of colors and options that change the overall look and feel of your application. One of these options designates the theme as being either a **light** or **dark** variation.\n\nThis makes it possible for Vuetify to implement Material Design concepts such as elevated surfaces having a lighter overlay color the higher up they are. Find out more about dark themes on the official [Material Design](https://material.io/design/color/dark-theme.html) page.\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createApp } from 'vue'\nimport { createVuetify } from 'vuetify'\n\nconst myCustomLightTheme = {\n  dark: false,\n  colors: {\n    background: '#FFFFFF',\n    surface: '#FFFFFF',\n    'surface-bright': '#FFFFFF',\n    'surface-light': '#EEEEEE',\n    'surface-variant': '#424242',\n    'on-surface-variant': '#EEEEEE',\n    primary: '#1867C0',\n    'primary-darken-1': '#1F5592',\n    secondary: '#48A9A6',\n    'secondary-darken-1': '#018786',\n    error: '#B00020',\n    info: '#2196F3',\n    success: '#4CAF50',\n    warning: '#FB8C00',\n  },\n  variables: {\n    'border-color': '#000000',\n    'border-opacity': 0.12,\n    'high-emphasis-opacity': 0.87,\n    'medium-emphasis-opacity': 0.60,\n    'disabled-opacity': 0.38,\n    'idle-opacity': 0.04,\n    'hover-opacity': 0.04,\n    'focus-opacity': 0.12,\n    'selected-opacity': 0.08,\n    'activated-opacity': 0.12,\n    'pressed-opacity': 0.12,\n    'dragged-opacity': 0.08,\n    'theme-kbd': '#212529',\n    'theme-on-kbd': '#FFFFFF',\n    'theme-code': '#F5F5F5',\n    'theme-on-code': '#000000',\n  }\n}\n\nexport default createVuetify({\n  theme: {\n    defaultTheme: 'myCustomLightTheme',\n    themes: {\n      myCustomLightTheme,\n    },\n  },\n})\n```\n\n## Custom theme colors\n\nThe Vuetify theme system supports adding custom colors. When configuring the Vuetify theme settings, add your custom colors to the **colors** object and Vuetify will generate a number of CSS classes and variables for you to use in your application.\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createApp } from 'vue'\nimport { createVuetify } from 'vuetify'\n\nexport default createVuetify({\n  theme: {\n    defaultTheme: 'myCustomTheme',\n    themes: {\n      myCustomTheme: {\n        dark: false,\n        colors: {\n          ..., // We have omitted the standard color properties here to emphasize the custom one that we've added\n          something: '#00ff00',\n        },\n      },\n    },\n  },\n})\n```\n\nCustom properties for colors are a list of `red, green, blue`, so the `rgb()` or `rgba()` function has to be used:\n\n```html\n<template>\n  <div class=\"bg-something on-something\">background color with appropriate text color contrast</div>\n\n  <div class=\"text-something\">text color</div>\n\n  <div class=\"border-something\">border color</div>\n</template>\n\n<style>\n  .custom-class {\n    background: rgb(var(--v-theme-something))\n    color: rgba(var(--v-theme-on-something), 0.9)\n  }\n</style>\n```\n\n## Color variations\n\nThe Vuetify theme system can help you generate any number of **variations** for the colors in your theme. The following example shows how to generate 1 lighten and 2 darken variants for the `primary` and `secondary` colors.\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createApp } from 'vue'\nimport { createVuetify } from 'vuetify'\n\nexport default createVuetify({\n  theme: {\n    defaultTheme: 'myCustomTheme',\n    variations: {\n      colors: ['primary', 'secondary'],\n      lighten: 1,\n      darken: 2,\n    },\n    themes: {\n      //\n    },\n  },\n})\n```\n\n```html\n<template>\n  <div class=\"text-primary-lighten-1\">text color</div>\n\n  <div class=\"text-primary-darken-1\">text color</div>\n\n  <div class=\"text-primary-darken-2\">text color</div>\n</template>\n```\n\n## Disable theme\n\nThe theme functionality can be disabled by setting the **theme** configuration property to `false`. This prevents the creation of the Vuetify stylesheet, and theme classes will not be applied to components.\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createApp } from 'vue'\nimport { createVuetify } from 'vuetify'\n\nexport default createVuetify({\n  theme: false,\n})\n```\n\n## Theme object structure\n\n```ts\ninterface ThemeInstance {\n  /**\n   * Raw theme objects\n   * Can be mutated to add new themes or update existing colors\n   */\n  themes: Ref<{ [name: string]: ThemeDefinition }>\n\n  /**\n   * Name of the current theme\n   * Inherited from parent components\n   */\n  readonly name: Ref<string>\n\n  /** Processed theme object, includes automatically generated colors */\n  readonly current: Ref<ThemeDefinition>\n  readonly computedThemes: Ref<{ [name: string]: ThemeDefinition }>\n\n  readonly global: {\n    /** Name of the current global theme */\n    name: Ref<string>\n\n    /**\n     * Processed theme object of the current global theme\n     * Equivalent to `theme.computedThemes.value[theme.global.name.value]`\n     */\n    readonly current: Ref<ThemeDefinition>\n  }\n}\n```\n\n## CSP Nonce\n\nPages with the `script-src` or `style-src` CSP rules enabled may require a **nonce** to be specified for embedded style tags.\n\n```html\n<!-- Use with script-src -->\nContent-Security-Policy: script-src 'self' 'nonce-dQw4w9WgXcQ'\n\n<!-- Use with style-src -->\nContent-Security-Policy: style-src 'self' 'nonce-dQw4w9WgXcQ'\n```\n\n```ts { resource=\"src/plugins/vuetify.ts\" }\nimport { createVuetify } from 'vuetify'\n\nexport const vuetify = createVuetify({\n  theme: {\n    cspNonce: 'dQw4w9WgXcQ',\n  },\n})\n```\n\n## Implementation\n\nVuetify generates theme styles at runtime according to the given configuration. The generated styles are injected into the `<head>` section of the DOM in a `<style>` tag with a default **id** of `vuetify-theme-stylesheet`.\n\n### Microfrontends\n\nAn application using microfrontends with multiple instances of Vuetify may need to define unique **theme.stylesheetId** values for each microfrontend in order to prevent conflicts between their generated stylesheets.\nFurther, such a scenario might require styles to be scoped to a specific microfrontend, which can be achieved by setting the **theme.scope** property.\nFor example, a microfrontend mounted in an element `#my-app` can define a **theme.scope** of `#my-app` to scope its styles to that element and its children instead of `:root` and global classes.\n"
  },
  {
    "path": "packages/docs/src/pages/en/features/treeshaking.md",
    "content": "---\nmeta:\n  title: Treeshaking\n  description: Vuetify provides automatic treeshaking via the vuetify-loader. Use only the features that you need and drastically reduce your package bundle size.\n  keywords: a la carte, a-la-carte, vuetify single import, vuetify import, component importing, reduce vuetify size, treeshaking, tree shaking\nrelated:\n  - /features/sass-variables/\n  - /features/blueprints/\n  - /introduction/why-vuetify/\nfeatures:\n  report: true\n---\n\n# Treeshaking\n\nBeing a component framework, Vuetify will always grow horizontally. Depending on your project, a small bundle size may be a requirement.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## Automatic treeshaking\n\nTreeshaking enables you to drastically lower your build size by only including the components you actually use in the final bundle. Vuetify comes with plugins for both [Webpack](https://webpack.js.org/) and [vite](https://vitejs.dev/) that enable automatic treeshaking.\n\nInstall [webpack-plugin-vuetify](https://www.npmjs.com/package/webpack-plugin-vuetify) or [vite-plugin-vuetify](https://www.npmjs.com/package/vite-plugin-vuetify) then enable it in your bundler configuration. Make sure the vuetify plugin comes after the vue plugin or it won't work correctly.\n\n::: tabs\n\n```js [Vite] { resource=\"vite.config.js\" }\nimport { defineConfig } from 'vite'\nimport vue from '@vitejs/plugin-vue'\nimport vuetify from 'vite-plugin-vuetify'\n\nexport default defineConfig({\n  plugins: [\n    vue(),\n    vuetify(),\n  ],\n})\n```\n\n```js [Webpack] { resource=\"webpack.config.js\" }\nconst { VueLoaderPlugin } = require('vue-loader')\nconst { VuetifyPlugin } = require('webpack-plugin-vuetify')\n\nmodule.exports = {\n  plugins: [\n    new VueLoaderPlugin(),\n    new VuetifyPlugin(),\n  ],\n}\n```\n\n```js [Vue CLI] { resource=\"vue.config.js\" }\nconst { VuetifyPlugin } = require('webpack-plugin-vuetify')\n\nmodule.exports = {\n  plugins: [\n    new VuetifyPlugin(),\n  ],\n}\n```\n\n::: tab Nuxt\n<p class=\"ma-4\">Nuxt also uses the vite plugin:</p>\n\n```js { resource=\"nuxt.config.js\" }\nimport vuetify from 'vite-plugin-vuetify'\n\nexport default defineNuxtConfig({\n  //...\n  vite: {\n    plugins: [\n      vuetify(),\n    ]\n  },\n})\n```\n\n:::\n\nAnd that's it! Vuetify components and directives will be automatically imported into your application wherever they are used. If you had any wildcard imports they can now be removed.\n\n```diff { resource=\"src/main.js\" }\n  import 'vuetify/styles'\n  import { createVuetify } from 'vuetify'\n- import * as components from 'vuetify/components'\n- import * as directives from 'vuetify/directives'\n```\n\n<PromotedPromoted />\n\n## Manual imports\n\nComponents can be manually imported when not using the loader plugin.\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createApp } from 'vue'\nimport { createVuetify } from 'vuetify'\nimport { VCard } from 'vuetify/components/VCard'\nimport { VRating } from 'vuetify/components/VRating'\nimport { VToolbar } from 'vuetify/components/VToolbar'\nimport { Ripple } from 'vuetify/directives'\n\nconst vuetify = createVuetify({\n  components: {\n    VCard,\n    VRating,\n    VToolbar,\n  },\n  directives: {\n    Ripple,\n  },\n})\n\nexport default vuetify\n```\n\nYou can also import components locally in .vue files, as seen below.\n\n```html { resource=\"Component.vue\" }\n<template>\n  <v-card>\n    <v-card-title>...</v-card-title>\n    <v-card-text>...</v-card-text>\n  </v-card>\n</template>\n\n<script setup>\n  import { VCard, VCardText, VCardTitle } from 'vuetify/components/VCard'\n</script>\n```\n\n## Limitations\n\nWhen using the loader plugin, there are a few scenarios which will require manually importing components.\n\n### Dynamic components\n\nWhen using dynamic components the plugin is unable to parse which vuetify components are being rendered. This commonly occurs when using the built-in Vue `<component>`. More information about dynamic components can be found in the official Vue [documentation](https://vuejs.org/guide/essentials/component-basics.html#dynamic-components).\n\n<!--\n`v-data-iterator` can use any component via the content-tag prop. This component must be registered [globally](#markup-js-a-la-carte-manual):\n\n```html\n<template>\n  <v-data-iterator content-tag=\"v-layout\">\n    ...\n  </v-data-iterator>\n</template>\n```\n\n```js\n// src/plugins/vuetify.js\n\nimport Vue from 'vue'\nimport Vuetify, { VLayout } from 'vuetify/lib'\n\nVue.use(Vuetify, {\n  components: { VLayout },\n})\n\nconst opts = {}\n\nexport default new Vuetify(opts)\n```\n-->\n\nDynamic components using `<component>` can just be imported in setup components:\n\n```html { resource=\"Component.vue\" }\n<template>\n  <component :is=\"button ? VBtn : VChip\" />\n</template>\n\n<script setup>\n  import { VBtn } from 'vuetify/components/VBtn'\n  import { VChip } from 'vuetify/components/VChip'\n  import { shallowRef } from 'vue'\n\n  const button = shallowRef(false)\n</script>\n```\n\nOr registered locally in options components:\n\n```html { resource=\"Component.vue\" }\n<template>\n  <component :is=\"button ? 'v-btn' : 'v-chip'\" />\n</template>\n\n<script>\n  import { VBtn } from 'vuetify/components/VBtn'\n  import { VChip } from 'vuetify/components/VChip'\n\n  export default {\n    components: { VBtn, VChip },\n    data: () => ({ button: false }),\n  }\n</script>\n```\n\n### Import groups\n\nAll components are available at both `vuetify/components` and `vuetify/components/<group>`. Use of the latter is preferred however as it only loads files that are needed. Treeshaking will still work in production builds if you use `vuetify/components`, but during development it will cause a performance hit by loading styles even for components you aren't using.\n"
  },
  {
    "path": "packages/docs/src/pages/en/getting-started/browser-support.md",
    "content": "---\nemphasized: true\nmeta:\n  title: Browser support\n  description: Vuetify is a progressive framework that supports all evergreen browsers.\n  keywords: vuetify browser support\nrelated:\n  - /getting-started/installation/\n  - /introduction/why-vuetify/\n  - /features/sass-variables/\n---\n\n# Browser support\n\nVuetify 4 is a next generation framework that takes advantage of the latest web technology features and requires an evergreen browser to function.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## Browsers\n\nThis is not an exhaustive list of compatible browsers, but the main targeted ones. If you are using a browser that is not listed here, it is not officially supported.\n\n| Browser                 | Version | Status                           |\n|-------------------------|:--------|----------------------------------|\n| Chromium (Chrome, Edge) | 119     | ✅ Supported <sup>*</sup>         |\n| ^^                      | 99      | ⚠️ Partial support <sup>**</sup> |\n| Firefox                 | 128     | ✅ Supported <sup>*</sup>         |\n| ^^                      | 97      | ⚠️ Partial support <sup>**</sup> |\n| Safari                  | 16.4    | ✅ Supported                      |\n| Internet Explorer       |         | ⛔ Not supported                  |\n| Other Browsers          |         | ❓ Not officially supported       |\n\n<p class=\"text-body-small\">* All browsers on iOS use WebKit and have the same support as Safari</p>\n<p class=\"text-body-small\">** Some components may have incorrect colors due to lack of support for <AppLink href=\"https://www.w3.org/TR/css-color-5/#relative-colors\">relative color syntax</AppLink> (e.g. <v-code>rgb(from ...)</v-code>)</p>\n\nThis table is updated with minor releases of Vuetify. Chrome, Firefox, and Safari will be supported at least two years back from the Vuetify x.x.0 release date.\nCurrent start date is December 2023.\n\nSupport for older browsers may be possible with additional [polyfills](https://cdnjs.cloudflare.com/polyfill/) and [PostCSS plugins](https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-logical), but has not been tested and is not guaranteed. If you need to support older browsers we recommend using Vuetify 2 or 3.\n"
  },
  {
    "path": "packages/docs/src/pages/en/getting-started/contributing.md",
    "content": "---\nmeta:\n  title: Contributing\n  description: Contributing to open source helps developers access amazing tools for free. Learn how you can help develop the Vuetify framework.\n  keywords: contribute, contributing, feature request\nrelated:\n  - /getting-started/unit-testing/\n  - /about/code-of-conduct/\n  - /introduction/roadmap/\n---\n\n# Contributing\n\nVuetify is made possible by an amazing community that submits issues, creates pull requests, and provides invaluable feedback.\n\n<PageFeatures />\n\n<PromotedEntry />\n\nIt is our job to enable you to create amazing applications. A lot of the time, you come across something that can be made better. Maybe you find a bug, or you have an idea for additional functionality. That's great! It's as easy as cloning the Vuetify repository to get started working in a development environment.\n\n<PromotedPromoted slug=\"vuetify-discord\" />\n\n## Reporting Issues\n\nThe issue list of this repo is exclusively for bug reports and feature requests. Non-conforming issues will be closed immediately. Before reporting an issue:\n\n- Search for similar [issues], it may have been answered already.\n  > If a similar issue already exists, you do not need to open another issue for this, if you want to help with it in any way, you can help by giving appropriate information in the already existing issue.\n- Try to reproduce with the [latest](https://github.com/vuetifyjs/vuetify/releases/latest) version in [Vuetify Play](https://play.vuetifyjs.com/) or a repository that can be cloned to produce the expected behavior.\n- Make sure that the reproduction is **MINIMAL** and **CONCISE**\n\nThese steps ensure that we have all the information necessary to quickly triage and resolve your issue. Once your reproduction is complete, submit a new issue using the [Vuetify Issue Creator](https://issues.vuetifyjs.com/). Using this issue creator is required, otherwise the issue will be closed automatically.\n\nWhen writing an issue please provide as much detail as possible. Note that \"reproduction steps\" should be a series of actions another developer should take after clicking your reproduction link, not a recollection of how you discovered the bug.\n\nIssues that are convoluted and lacking a proper reproduction may be closed by a member of the [Core Team]. For additional questions regarding reporting issues and creating reproductions, join the official Vuetify Discord [community].\n\n::: tip\nWhen you create a reproduction, exclude all **elements, properties, and data variables** that are not needed for the reproduction. This helps drastically reduce the time it takes to triage the issue and ultimately resolve it.\n:::\n\nIn the next section you will learn step-by-step how to set up your local environment and how to configure Vuetify for development.\n\n## Local development\n\nThe Vuetify repository is a [lerna](https://github.com/lerna/lerna) monorepo that connects the vuetify library, docs, api generator, and reduces the friction of working with multiple projects at once. The following guide is designed to get you up and running in no time.\n\n### Setting up your environment\n\nWe recommend using [FNM](https://github.com/Schniz/fnm#installation) (with all four [options](https://github.com/Schniz/fnm/blob/master/docs/configuration.md) enabled) to automatically set up and use the exect node and pnpm versions specified in package.json.\n\nRequired software:\n\n- [Git](https://git-scm.com/) >v2.20\n- [Node.js](https://nodejs.org/) 24\n- [pnpm](https://pnpm.io/)\n\nSome of our dependencies use [node-gyp](https://github.com/nodejs/node-gyp#installation) to build themselves. You don't need to install node-gyp itself but may require additional tools, especially on windows. See the node-gyp documentation for more details.\n\nOnce you have everything installed, clone the repository:\n\n```bash\n# Using HTTPS\ngit clone https://github.com/vuetifyjs/vuetify.git\n\n# Using SSH\ngit clone git@github.com:vuetifyjs/vuetify.git\n```\n\n::: info\n[Which remote URL should I use?](https://docs.github.com/en/free-pro-team@latest/github/using-git/which-remote-url-should-i-use)\n:::\n\nThen install dependencies and perform an initial build to link all the packages together:\n\n```bash\n# Navigate to the vuetify folder\ncd vuetify\n\n# Install all project dependencies\npnpm i\n\n# Build the packages\npnpm build vuetify\npnpm build api\n```\n\nThe build process compiles all the Vuetify packages for development and may take a while (grab some ☕). Once the packages are built, you can start developing.\n\n### Vuetify\n\nThe Vuetify library is located in `packages/vuetify`. In `packages/vuetify/dev` you will find a `Playground.vue` file; running `pnpm dev` from the project root will start a dev server on **localhost:8090** with this file loaded. Test your changes in the Playground.vue file you copied, then paste its contents into your pull request when you're ready.\n\nYou can also test Vuetify in your own project using [`pnpm link`](https://pnpm.io/cli/link):\n\n- Navigate to `packages/vuetify`\n- Run `pnpm link --global`\n- Navigate to your project's directory\n- Run `pnpm link --global vuetify`\n- Clear Vite's cache by deleting  `node_modules/.vite` folder\n\nIf your project is using vuetify-loader you will have to run `pnpm build:lib` in the vuetify package to see changes, otherwise you can use `pnpm watch` for incremental builds.\n\n#### Playground.vue\n\nThe **Playground** file is a cleanroom used for Vuetify development and is the recommended way to iterate on changes within the framework.\n\n```html\n<template>\n  <v-app>\n    <v-container>\n      <!--  -->\n    </v-container>\n  </v-app>\n</template>\n\n<script setup>\n  //\n</script>\n```\n\n#### Automated testing\n\nVuetify uses [Vitest](https://vitest.dev/) for unit tests, [Vitest browser mode](https://vitest.dev/guide/browser/why.html) with Playwright for component interaction tests, and [Vizzly](https://vizzly.dev/) for visual regression tests.\n\n- `pnpm test` - run all tests\n- `pnpm test:unit` - run only unit tests\n- `pnpm test:browser` - run only browser tests\n- `pnpm test:open` - run browser tests in a chrome window\n  - use this if you need devtools to debug a failing test\n- `pnpm test:screen` - run only screenshot tests, saves a report to http://localhost:47392/\n- `pnpm tdd` - start the vizzly dev server, follow with `test`, `test:screen`, `test:browser`, or `test:open` to actually run tests. Screenshot baselines and diffs can be managed and viewed at http://localhost:47392/\n  - run `pnpm tdd:stop` when you're done to kill the background process\n\nThe `test:*` commands all accept a list of test names to filter by, eg. `pnpm test textfield textarea` to only run VTextField and VTextarea tests.\n\n##### Visual regression workflow\n\n- Checkout the base branch (`master` or `dev`)\n- Run `pnpm tdd`\n- Visit http://localhost:47392/stats and click \"Reset baselines\"\n- Run `pnpm test:screen`\n- Click \"Accept all changes\"\n- Checkout your PR branch\n- Run `pnpm test:screen` again\n- Any visual differences will be shown on http://localhost:47392\n\n### Documentation\n\nThe documentation is located in `packages/docs` but also uses some files from `packages/api-generator`. A dev server for the documentation can be started by running `pnpm dev docs` from the project root and will be available on [localhost:8095](http://localhost:8095/) by default.\n\nIf you want to see changes from Vuetify in the documentation you need to run `pnpm build:lib` in the vuetify package before starting the documentation server.\n\n### API Generator\n\nAll api descriptions are managed via the api-generator package. This package must be built prior to running or building the docs. Descriptions can be updated via the JSON files located in the `src/locale/en` folder. Some general guidelines to follow when handling api descriptions are:\n\n- `en` language only. Translations are handled via [Crowdin](https://crowdin.com/project/vuetify).\n- Prop names should be formatted using bold markdown eg: **prop-name**.\n- Slot and other code related text should be formatted using code markdown eg: `some-slot`.\n- Description keys should be in camelCase, except for `slot` keys which should be kebab-case.\n- Put keys in alphabetical order.\n- Descriptions utilize a hierarchy of `generic.json` < `Source.json` < `Component.json` to reduce duplication. Source can be viewed using the **Developer Mode** in docs settings.\n\n#### Adding API Documentation\n\nWhen creating a new component (or composable, though this is typically done by the Vuetify team), you need to add a corresponding JSON file named `ComponentName.json` in `packages/api-generator/src/locale/en/`. This file should contain descriptions for props, slots, events, and exposed methods. After adding or updating JSON files, run `pnpm build api` to regenerate the dist language files. Keep in mind:\n\n- Changes to Vuetify require a rebuild before building the API\n- The API must be built before running the documentation server\n\nEnabling **developer mode** in the documentation settings will allow you to see the source of truth on API description pages.\n\n### Submitting Changes / Pull Requests\n\nFirst you should create a fork of the vuetify repository to push your changes to. Information on forking repositories can be found in the [GitHub documentation](https://help.github.com/en/github/getting-started-with-github/fork-a-repo).\n\nThen add your fork as a remote in git:\n\n```bash\n# Using HTTPS\ngit remote add fork https://github.com/YOUR_USERNAME/vuetify.git\n\n# Using SSH\ngit remote add fork git@github.com:YOUR_USERNAME/vuetify.git\n```\n\n#### Choosing a base branch\n\nBefore starting development you should know which branch to base your changes on. If in doubt use master as changes to master can usually be merged into a different branch without rebasing.\n\n| Version   | Type of change                 | Branch      |\n|-----------|--------------------------------|-------------|\n| Vuetify 4 | Documentation                  | `master`    |\n| Vuetify 4 | Bug fixes                      | `master`    |\n| Vuetify 4 | New features                   | `dev`       |\n| Vuetify 5 | Features with breaking changes | `next`      |\n| Vuetify 3 | Documentation                  | `v3-stable` |\n| Vuetify 3 | Bug fixes                      | `v3-stable` |\n| Vuetify 2 | Documentation                  | `v2-stable` |\n\n```bash\n# Switch to the desired branch\n# v4\ngit switch master\n# v3\ngit switch v3-stable\n\n# Pull down any upstream changes\ngit pull\n\n# Create a new branch to work on\ngit switch --create fix/1234-some-issue\n```\n\n::: warning\nNever commit directly to the base branches, always create a feature branch to work on\n:::\n\nCommit your changes following [our guidelines](#commit-guidelines), then push the branch to your fork with `git push -u fork` and open a pull request on the Vuetify repository following the provided template.\n\n::: error\nPull requests that include unrelated commits or your local merges will be **CLOSED** without notice\n:::\n\n## Working with GitHub\n\nVuetify's repository lives on [GitHub](https://github.com/vuetifyjs/vuetify) and is the primary location for all development related information.\n\nSome of the more notable links within these services include:\n\n**GitHub**\n\n- [Issues]\n- [Discussions](https://github.com/vuetifyjs/vuetify/discussions)\n\n----\n\nThe following sections are designed to familiarize you with our standard operating procedures for Vuetify development.\n\n<PromotedPromoted slug=\"vue-jobs\" />\n\n### Issue triage\n\nWith the size and popularity of Vuetify has come a constant influx of new issues, questions, and feature requests. To organize these requests the [Core Team] developed tools to aid not only the triaging of issues, but creating them as well.\n\nThe [Issues] board makes heavy use of GitHub's label system with some light automation, such as adding the `triage` label to new issues.\n\n#### For Docs - Language\n\nWe **do not** accept PRs for any documentation changes pertaining to languages other than `en`. All changes for languages other than `en` are to be submitted through our [Crowdin project](https://crowdin.com/project/vuetify). You can help translate in one of 2 ways:\n\n- Using in-context translation service directly through the documentation site. To get started simply select `Help Translate` in the language drop down in the docs.\n- Directly through the [Crowdin project](https://crowdin.com/project/vuetify).\n\n**Note**: Languages will not be added to the language drop down on the docs site until they have at least 50% of their translations completed.\n\n### Requesting new features\n\nPending\n\n### Commit guidelines\n\nAll commit messages are required to follow the [conventional-changelog](https://github.com/conventional-changelog/conventional-changelog) standard using the _angular_ preset. This standard format consists of 2 types of commits:\n\n- With scope: `<type>(scope): <subject>`\n\n  ```bash\n  fix(VSelect): don't close when a detachable child is clicked\n\n  fixes #12354\n  ```\n\n- Without scope: `<type>: <subject>`\n\n  ```bash\n  docs: restructure nav components\n\n  Moved duplicated functionality in drawer to reduce\n  scope of responsibility\n  ```\n\n#### General Rules\n\n- Commit messages must have a subject line and may have body copy. These must be separated by a blank line.\n- The subject line must not exceed 60 characters\n- The subject line must be written in imperative mood (fix, not fixed / fixes etc.)\n- The body copy must include a reference all issues resolved:\n\n  ```bash\n  docs(sass-variables): fix broken link to api\n\n  resolves #3219\n  resolves #3254\n  ```\n\n- The body copy must be wrapped at 72 characters\n- The body copy must only contain explanations as to what and why, never how. The latter belongs in documentation and implementation.\n\n#### Commit types\n\nThe following is a list of **commit types** used in the _angular_ preset:\n\n- **feat:** Commits that result in new features or functionalities. Backwards compatible features will release with the next **MINOR** whereas breaking changes will be in the next **MAJOR**. The body of a commit with breaking changes must begin with `BREAKING CHANGE`, followed by a description of how the API has changed.\n- **fix:** Commits that provide fixes for bugs within vuetify's codebase.\n- **docs:** Commits that provide updates to the docs.\n- **style:** Commits that do not affect how the code runs, these are simply changes to formatting.\n- **refactor:** Commits that neither fixes a bug nor adds a feature.\n- **perf:** Commits that improve performance.\n- **test:** Commits that add missing or correct existing tests.\n- **chore:** Other commits that don't modify src or test files.\n- **revert:** Commits that revert previous commits.\n\n<PromotedPromoted slug=\"vuetify-reddit\" />\n\n[community]: https://community.vuetifyjs.com/\n[core team]: /about/meet-the-team/\n[issues]: https://github.com/vuetifyjs/vuetify/issues\n"
  },
  {
    "path": "packages/docs/src/pages/en/getting-started/elevation-migration.md",
    "content": "---\nmeta:\n  nav: Elevation migration\n  title: Elevation migration\n  description: Guide for migrating from MD2 to MD3 elevation shadows\n  keywords: elevation, shadows, md2, md3, material design, migration\nrelated:\n  - /getting-started/upgrade-guide/\n  - /styles/elevation/\n---\n\n# Elevation Migration Guide\n\nVuetify 4 introduces Material Design 3 (MD3) elevation shadows, which differ significantly from the previous MD2 system. This guide helps you understand the changes and provides options for maintaining MD2 shadows if needed.\n\n## Adapt CSS classes\n\nUpdate your elevation classes to use the new 0-5 scale.\n\n| MD2 (old)           | MD3 (new)            |\n|---------------------|----------------------|\n| `elevation-0`       | `elevation-0` (0dp)  |\n| `elevation-{1-3}`   | `elevation-1` (1dp)  |\n| `elevation-{4-6}`   | `elevation-2` (3dp)  |\n| `elevation-{7-11}`  | `elevation-3` (6dp)  |\n| `elevation-{12-16}` | `elevation-4` (8dp)  |\n| `elevation-{17-24}` | `elevation-5` (12dp) |\n\n\\* \"dp\" (density-independent pixels) is a relative unit from Material Design\n\nThe same levels change should be applied to direct uses of Sass `elevation(...)` helper.\n\n```scss\n@import 'vuetify/lib/styles/tools/_elevation.sass'\n\n.summary-panel {\n  @include elevation(15) // <- migration necessary\n}\n```\n\n## Migrating customizations\n\nMD2 shadows provided by Vuetify exposed a possibility to customize via :\n\n```scss\n/* Legacy variables, no longer used */\n$shadow-key-umbra-opacity: var(--v-shadow-key-umbra-opacity, rgba(0, 0, 0, 0.2));\n$shadow-key-penumbra-opacity: var(--v-shadow-key-penumbra-opacity, rgba(0, 0, 0, 0.14));\n$shadow-key-ambient-opacity: var(--v-shadow-key-ambient-opacity, rgba(0, 0, 0, 0.12));\n\n$shadow-key-umbra: (...);\n$shadow-key-penumbra: (...);\n$shadow-key-ambient: (...);\n```\n\n```scss\n/* New variables is Sass */\n$shadow-key-color: rgba(var(--v-shadow-color), var(--v-shadow-key-opacity, 0.3));\n$shadow-ambient-color: rgba(var(--v-shadow-color), var(--v-shadow-ambient-opacity, 0.15));\n\n$shadow-key: (...);\n$shadow-ambient: (...);\n```\n\nNote that color and opacity controls has been split into separate CSS variables.\n\n## Reverting to legacy MD2 Shadows\n\nIf you need to maintain MD2 shadows for compatibility, add the following CSS to your project after Vuetify styles. The `!important` declarations ensure these override the MD3 shadows:\n\n```css { resource=\"src/styles/legacy-elevation.css\" }\n/* Legacy MD2 Elevation Shadows */\n.elevation-0 {\n  box-shadow:\n    0px 0px 0px 0px rgba(0, 0, 0, 0.2),\n    0px 0px 0px 0px rgba(0, 0, 0, 0.14),\n    0px 0px 0px 0px rgba(0, 0, 0, 0.12) !important;\n}\n.elevation-1 {\n  box-shadow:\n    0px 2px 1px -1px rgba(0, 0, 0, 0.2),\n    0px 1px 1px 0px rgba(0, 0, 0, 0.14),\n    0px 1px 3px 0px rgba(0, 0, 0, 0.12) !important;\n}\n.elevation-2 {\n  box-shadow:\n    0px 3px 1px -2px rgba(0, 0, 0, 0.2),\n    0px 2px 2px 0px rgba(0, 0, 0, 0.14),\n    0px 1px 5px 0px rgba(0, 0, 0, 0.12) !important;\n}\n.elevation-3 {\n  box-shadow:\n    0px 3px 3px -2px rgba(0, 0, 0, 0.2),\n    0px 3px 4px 0px rgba(0, 0, 0, 0.14),\n    0px 1px 8px 0px rgba(0, 0, 0, 0.12) !important;\n}\n.elevation-4 {\n  box-shadow:\n    0px 2px 4px -1px rgba(0, 0, 0, 0.2),\n    0px 4px 5px 0px rgba(0, 0, 0, 0.14),\n    0px 1px 10px 0px rgba(0, 0, 0, 0.12) !important;\n}\n.elevation-5 {\n  box-shadow:\n    0px 3px 5px -1px rgba(0, 0, 0, 0.2),\n    0px 5px 8px 0px rgba(0, 0, 0, 0.14),\n    0px 1px 14px 0px rgba(0, 0, 0, 0.12) !important;\n}\n.elevation-6 {\n  box-shadow:\n    0px 3px 5px -1px rgba(0, 0, 0, 0.2),\n    0px 6px 10px 0px rgba(0, 0, 0, 0.14),\n    0px 1px 18px 0px rgba(0, 0, 0, 0.12) !important;\n}\n.elevation-7 {\n  box-shadow:\n    0px 4px 5px -2px rgba(0, 0, 0, 0.2),\n    0px 7px 10px 1px rgba(0, 0, 0, 0.14),\n    0px 2px 16px 1px rgba(0, 0, 0, 0.12) !important;\n}\n.elevation-8 {\n  box-shadow:\n    0px 5px 5px -3px rgba(0, 0, 0, 0.2),\n    0px 8px 10px 1px rgba(0, 0, 0, 0.14),\n    0px 3px 14px 2px rgba(0, 0, 0, 0.12) !important;\n}\n.elevation-9 {\n  box-shadow:\n    0px 5px 6px -3px rgba(0, 0, 0, 0.2),\n    0px 9px 12px 1px rgba(0, 0, 0, 0.14),\n    0px 3px 16px 2px rgba(0, 0, 0, 0.12) !important;\n}\n.elevation-10 {\n  box-shadow:\n    0px 6px 6px -3px rgba(0, 0, 0, 0.2),\n    0px 10px 14px 1px rgba(0, 0, 0, 0.14),\n    0px 4px 18px 3px rgba(0, 0, 0, 0.12) !important;\n}\n.elevation-11 {\n  box-shadow:\n    0px 6px 7px -4px rgba(0, 0, 0, 0.2),\n    0px 11px 15px 1px rgba(0, 0, 0, 0.14),\n    0px 4px 20px 3px rgba(0, 0, 0, 0.12) !important;\n}\n.elevation-12 {\n  box-shadow:\n    0px 7px 8px -4px rgba(0, 0, 0, 0.2),\n    0px 12px 17px 2px rgba(0, 0, 0, 0.14),\n    0px 5px 22px 4px rgba(0, 0, 0, 0.12) !important;\n}\n.elevation-13 {\n  box-shadow:\n    0px 7px 8px -4px rgba(0, 0, 0, 0.2),\n    0px 13px 19px 2px rgba(0, 0, 0, 0.14),\n    0px 5px 24px 4px rgba(0, 0, 0, 0.12) !important;\n}\n.elevation-14 {\n  box-shadow:\n    0px 7px 9px -4px rgba(0, 0, 0, 0.2),\n    0px 14px 21px 2px rgba(0, 0, 0, 0.14),\n    0px 5px 26px 4px rgba(0, 0, 0, 0.12) !important;\n}\n.elevation-15 {\n  box-shadow:\n    0px 8px 9px -5px rgba(0, 0, 0, 0.2),\n    0px 15px 22px 2px rgba(0, 0, 0, 0.14),\n    0px 6px 28px 5px rgba(0, 0, 0, 0.12) !important;\n}\n.elevation-16 {\n  box-shadow:\n    0px 8px 10px -5px rgba(0, 0, 0, 0.2),\n    0px 16px 24px 2px rgba(0, 0, 0, 0.14),\n    0px 6px 30px 5px rgba(0, 0, 0, 0.12) !important;\n}\n.elevation-17 {\n  box-shadow:\n    0px 8px 11px -5px rgba(0, 0, 0, 0.2),\n    0px 17px 26px 2px rgba(0, 0, 0, 0.14),\n    0px 6px 32px 5px rgba(0, 0, 0, 0.12) !important;\n}\n.elevation-18 {\n  box-shadow:\n    0px 9px 11px -5px rgba(0, 0, 0, 0.2),\n    0px 18px 28px 2px rgba(0, 0, 0, 0.14),\n    0px 7px 34px 6px rgba(0, 0, 0, 0.12) !important;\n}\n.elevation-19 {\n  box-shadow:\n    0px 9px 12px -6px rgba(0, 0, 0, 0.2),\n    0px 19px 29px 2px rgba(0, 0, 0, 0.14),\n    0px 7px 36px 6px rgba(0, 0, 0, 0.12) !important;\n}\n.elevation-20 {\n  box-shadow:\n    0px 10px 13px -6px rgba(0, 0, 0, 0.2),\n    0px 20px 31px 3px rgba(0, 0, 0, 0.14),\n    0px 8px 38px 7px rgba(0, 0, 0, 0.12) !important;\n}\n.elevation-21 {\n  box-shadow:\n    0px 10px 13px -6px rgba(0, 0, 0, 0.2),\n    0px 21px 33px 3px rgba(0, 0, 0, 0.14),\n    0px 8px 40px 7px rgba(0, 0, 0, 0.12) !important;\n}\n.elevation-22 {\n  box-shadow:\n    0px 10px 14px -6px rgba(0, 0, 0, 0.2),\n    0px 22px 35px 3px rgba(0, 0, 0, 0.14),\n    0px 8px 42px 7px rgba(0, 0, 0, 0.12) !important;\n}\n.elevation-23 {\n  box-shadow:\n    0px 11px 14px -7px rgba(0, 0, 0, 0.2),\n    0px 23px 36px 3px rgba(0, 0, 0, 0.14),\n    0px 9px 44px 8px rgba(0, 0, 0, 0.12) !important;\n}\n.elevation-24 {\n  box-shadow:\n    0px 11px 15px -7px rgba(0, 0, 0, 0.2),\n    0px 24px 38px 3px rgba(0, 0, 0, 0.14),\n    0px 9px 46px 8px rgba(0, 0, 0, 0.12) !important;\n}\n```\n"
  },
  {
    "path": "packages/docs/src/pages/en/getting-started/frequently-asked-questions.md",
    "content": "---\nmeta:\n  title: Frequently asked questions\n  description: Stuck on a problem? Check out the most frequently asked questions by the Vuetify community.\n  keywords: frequently asked questions, faq\nrelated:\n  - /introduction/why-vuetify/\n  - /getting-started/contributing/\n  - /getting-started/installation/\n---\n\n# Frequently asked questions\n\nStuck on a particular problem? Check some of these common gotchas before creating a ticket. If you still cannot find what you are looking for, you can submit an [issue](https://issues.vuetifyjs.com/) on GitHub or ask in our [community](https://community.vuetifyjs.com/).\n\n<PageFeatures />\n\n<VoPromotionsCardHighlight class=\"mb-4\" slug=\"vuetify-discord-subscriber-help\" />\n\n## Questions\n\nThe following responses are a collection of common questions asked by the Vuetify community.\n\n* **What is Vuetify?** { #what-is-vuetify }\n\n  Vuetify is a Vue.js framework that helps to create beautiful and responsive user interfaces. It includes a wide variety of customizable and reusable components for building modern applications.\n\n* **Does Vuetify provide support?** { #does-vuetify-provide-support }\n\n  Vuetify is a free to use Open Source project released under the [MIT](https://opensource.org/licenses/MIT) license. There are multiple ways to receive support for Vuetify:\n\n  * Join our [Discord Community](https://community.vuetifyjs.com/) - (Free/Paid)\n  * Ask a question on [GitHub Discussions](https://discussions.vuetifyjs.com/) - (Free)\n  * Get [Chat Support](/introduction/enterprise-support/) from Vuetify - (Paid)\n\n* **What is the difference between Vuetify and Vue?** { #what-is-the-difference-between-vuetify-and-vue }\n\n  Vuetify is a framework that is built on top of Vue.js. It is a collection of components that can be used to build applications. Vue.js is a JavaScript framework that is used to build user interfaces.\n\n* **What versions of Vue.js are compatible with Vuetify?** { #what-versions-of-vuejs-are-compatible-with-vuetify }\n\n  Vuetify is compatible with Vue.js 3.0.0 and above.\n\n* **Is Vuetify 2 still supported?** { #is-vuetify-2-still-supported }\n\n  Vuetify 2 reached End of Life (EOL) on [January 25th, 2025](/introduction/long-term-support/). For security and commercial support, see our partner, [HeroDevs](https://www.herodevs.com/support/vuetify-nes?utm_source=partnership&utm_medium=partnership&utm_campaign=partnership&utm_id=vuetify2).\n\n* **Can I use Vuetify with other CSS frameworks?** { #can-i-use-vuetify-with-other-css-frameworks }\n\n  Yes, you can use Vuetify with other CSS frameworks, but it is typically not recommended. If you are integrating Vuetify into an existing application that is using another CSS framework, you may want to disable the default color and utility generation. See the [SASS Variables](/features/sass-variables/) page for more information.\n\n* **Can I customize the styling of Vuetify components?** { #can-i-customize-the-styling-of-vuetify-components}\n\n  Yes, you can customize the styling of Vuetify components using the [Global configuration](/features/global-configuration/). Vuetify also provides [SASS variables](/features/sass-variables/) that can be overridden to change the look and feel of the components.\n\n* **Where can I get help with Vuetify?** { #where-can-i-get-help-with-vuetify }\n\n  If you need help with an issue, please use one of our help channels:\n\n  * [Vuetify Enterprise Support](/introduction/enterprise-support/)\n  * [Discord Community](https://community.vuetifyjs.com/)\n  * [GitHub Discussions](https://discussions.vuetifyjs.com/)\n\n* **Can I contribute to Vuetify?** { #can-i-contribute-to-vuetify }\n\n  Yes, we welcome all contributions. Please see our [contributing guide](/getting-started/contributing/) for more information.\n\n* **Can I use Vuetify with server-side rendering?** { #can-i-use-vuetify-with-server-side-rendering }\n\n  Yes, Vuetify supports server-side rendering. Set the `ssr` property to `true` in your `vuetify` configuration object.\n\n  ```js { resource=\"src/plugins/vuetify.js\" }\n  import { createVuetify } from 'vuetify'\n\n  export default createVuetify({\n    ssr: true,\n  })\n  ```\n\n* **Is there support for Nuxt 3?** { #is-there-support-for-nuxt-3 }\n\n  Yes, Vuetify 3 is compatible with Nuxt 3 but does not currently have a community Nuxt module.\n\n* **What is Vuetify Labs?** { #what-is-vuetify-labs }\n\n  Vuetify Labs is a collection of components that are still in development. They are not considered stable and may change at any time. They are not included in the default Vuetify installation and must be imported individually. See the [Labs](/labs/introduction/) page for more information.\n\n* **Does Vuetify have Nightly Builds?** { #does-vuetify-have-nightly-builds }\n\n  Yes, Vuetify has nightly builds. See the [Nightly Builds](/getting-started/installation/#nightly-builds) page for more information.\n\n* **I found a bug, what should I do?** { #i-found-a-bug-what-should-i-do }\n\n  Please create a new [issue](https://issues.vuetifyjs.com/) with our Issue Generator. Please make sure to check for existing issues before creating a new one.\n\n* **Why did Vuetify 3 change `value` to `model-value`?**\n\n  The `value` prop was changed in Vue 3 to support a new `v-model` syntax. See the official Vue docs for more information on [Component v-model](https://vuejs.org/guide/components/v-model.html).\n\n* **Is Vuetify 3 compatible with `@vue/compat`?**\n\n  Not directly, you have to set `configureCompat({ MODE: 3 })` globally and `MODE: 2` in each of your components that you want to run in compatibility mode. There will still be some incorrect warnings that can be ignored with the `-ATTR_FALSE_VALUE` filter in devtools.\n\n<PromotedPromoted type=\"theme\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/getting-started/grid-legacy-mode.md",
    "content": "---\nmeta:\n  nav: Grid legacy mode\n  title: Grid legacy mode\n  description: How to restore the previous grid behavior using negative margins and column padding\n  keywords: grid, legacy, v-row, v-col, migration, upgrade, negative margins, padding\nrelated:\n  - /getting-started/upgrade-guide/\n  - /components/grids/\n---\n\n# Grid Legacy Mode\n\nVuetify 4 introduces an overhaul to the grid system utilizing CSS `gap` instead of negative margins on rows and padding on columns. If you need to maintain compatibility with the previous layout behavior, you can use the CSS overrides below.\n\n## Differences between old and new\n\n| Previous                                 | New                                  |\n|------------------------------------------|--------------------------------------|\n| Negative margins in VRow                 | CSS `gap` property                   |\n| Column spaced by padding                 | No padding (gap handles spacing)     |\n| Simple percentage (e.g. `flex: 0 0 75%`) | Calculated width accounting for gaps |\n\nInternal class names changed as well\n\n| Previous                  | New                             |\n|---------------------------|---------------------------------|\n| `.v-row--dense`           | `.v-row--density-comfortable`   |\n| `.v-col-{n}`              | `.v-col--cols-{n}`              |\n| `.v-col-{breakpoint}-{n}` | `.v-col--cols-{breakpoint}-{n}` |\n| `.offset-{n}`             | `.v-col--offset-{n}`            |\n\n## CSS Override\n\nAdd the following CSS to your application to restore the legacy grid behavior.\n\n```scss\n@layer vuetify-overrides {\n  .v-row {\n    gap: unset;\n    margin: calc(var(--v-col-gap-y) * -.5) calc(var(--v-col-gap-x) * -.5);\n  }\n  .v-row + .v-row {\n    margin-top: calc(var(--v-col-gap-y) * .5);\n  }\n  .v-col {\n    padding: calc(var(--v-col-gap-y) * .5) calc(var(--v-col-gap-x) * .5);\n    flex-basis: var(--v-col-is-size, calc(100% * var(--v-col-size) / var(--v-col-size-columns))) var(--v-col-is-auto, auto) var(--v-col-is-grow, 0);\n  }\n  .v-col:where([class*='v-col--offset-']) {\n    margin-inline-start: calc(100% * var(--v-col-offset) / var(--v-col-size-columns))\n  }\n}\n```\n"
  },
  {
    "path": "packages/docs/src/pages/en/getting-started/installation.md",
    "content": "---\nmeta:\n  nav: Installation\n  title: Get started with Vuetify 4\n  description: Details for v4 release - faq, changes, and upgrading.\n  keywords: migration, releases, upgrading vuetify, beta, v4\nrelated:\n  - /getting-started/contributing/\n  - /introduction/roadmap/\n  - /getting-started/release-notes/\n---\n\n<script setup>\n  import { version } from 'vuetify'\n</script>\n\n# Get started with Vuetify 4\n\nGet started with Vuetify, the world’s most popular Vue.js framework for building feature rich, blazing fast applications.\n\n<PageFeatures />\n\n## Installation\n\nVuetify has support for multiple different installation paths with the most common scaffolding tool being [create-vuetify](https://github.com/vuetifyjs/create-vuetify)\n\nFor more information regarding supported package managers, please visit their official websites:\n\n* [pnpm](https://pnpm.io/)\n* [yarn](https://yarnpkg.com/)\n* [npm](https://npmjs.org/)\n* [bun](https://bun.sh/package-manager)\n\n## Using Vite\n\nTo get started with Vuetify 4, simply paste the following code into your terminal:\n\n::: tabs\n\n```bash [pnpm]\npnpm create vuetify\n```\n\n```bash [yarn]\nyarn create vuetify\n```\n\n```bash [npm]\nnpm create vuetify@latest\n```\n\n```bash [bun]\nbun create vuetify\n```\n\n:::\n\nThis command prompts you with a few options before generating your scaffolded Vue / Vuetify 4 project.\n\n```bash\nsuccess Installed \"create-vuetify@x.x.x\" with binaries:\n    - create-vuetify\n\n? Project name: ❯ vuetify-project // the folder to generate your application\n? Use TypeScript?: ❯ No / Yes\n? Would you like to install dependencies with yarn, npm, or pnpm?:\n  ❯ yarn\n    npm\n    pnpm\n    bun\n    none\n```\n\nAfter making your selections, [create-vuetify](https://github.com/vuetifyjs/create-vuetify) will generate the structure for your new application.\n\nOnce the scaffold is complete, start the vite development server by running the following commands:\n\n```bash\ncd vuetify-project\npnpm dev\n```\n\n<PromotedEntry />\n\n## Using Nuxt 3\n\n[Nuxt](https://nuxt.com/) is an open-source framework that has helpful features to quickly get you started with developing a full-stack Vue app, such as file-based routing, SSR and component auto-imports.\n\n### Manual setup\n\nNuxt is powered by Nitro and can be used with Vite or Webpack 5 bundlers, so the steps to get Vuetify working in Nuxt 3 are quite similar to [the manual steps described below](#existing-projects).\n\nStart off creating a nuxt app by executing the following commands:\n\n::: tabs\n\n```bash [pnpm]\npnpx nuxi@latest init <project-name>\ncd <project-name>\n# Create a .npmrc file with shamefully-hoist=true\npnpm install\n```\n\n```bash [yarn]\nnpx nuxi@latest init <project-name>\ncd <project-name>\nyarn\n```\n\n```bash [npm]\nnpx nuxi@latest init <project-name>\ncd <project-name>\nnpm install\n```\n\n```bash [bun]\nbunx nuxi@latest init <project-name>\ncd <project-name>\nbun install\n```\n\n:::\n\nand then install the required Vuetify modules as dependencies:\n\n::: tabs\n\n```bash [pnpm]\npnpm i -D vuetify vite-plugin-vuetify\npnpm i @mdi/font\n```\n\n```bash [yarn]\nyarn add -D vuetify vite-plugin-vuetify\nyarn add @mdi/font\n```\n\n```bash [npm]\nnpm i -D vuetify vite-plugin-vuetify\nnpm i @mdi/font\n```\n\n```bash [bun]\nbun add -d vuetify vite-plugin-vuetify\nbun add @mdi/font\n```\n\n:::\n\nNext, integrate the following entries into your `nuxt.config.ts` file:\n\n```ts { data-resource=\"nuxt.config.ts\" }\nimport vuetify, { transformAssetUrls } from 'vite-plugin-vuetify'\nexport default defineNuxtConfig({\n  //...\n  build: {\n    transpile: ['vuetify'],\n  },\n  vite: {\n    plugins: [\n      // @ts-expect-error\n      vuetify({ autoImport: true }),\n    ],\n    vue: {\n      template: {\n        transformAssetUrls,\n      },\n    },\n  },\n})\n```\n\nNuxt allows you to change its Vite config by using its built-in hook `vite:extendConfig`. In its callback function, add the Vuetify plugin to the array of Vite plugins. To resolve relative asset URLs that are passed to Vuetify components such as `VImg` (e.g. `~/assets/img/some.png`) the `transformAssetUrls` function needs to be added in the `vite` entry .\n\nIn the next step, initialize Vuetify and add it to the main Vue app instance. This can be done in the `plugins` folder as any plugin that is placed in this folder will be automatically loaded by Nuxt at startup.\n\n```ts { data-resource=\"~/plugins/vuetify.ts\" }\n// import this after install `@mdi/font` package\nimport '@mdi/font/css/materialdesignicons.css'\n\nimport 'vuetify/styles'\nimport { createVuetify } from 'vuetify'\n\nexport default defineNuxtPlugin((app) => {\n  const vuetify = createVuetify({\n    // ... your configuration\n  })\n  app.vueApp.use(vuetify)\n})\n```\n\nFinally, add Vuetify's root `VApp` component either in `~/app.vue` or `~/layouts/default.vue`, for example:\n\n```html { data-resource=\"app.vue\" }\n<template>\n  <NuxtLayout>\n    <v-app>\n      <NuxtPage />\n    </v-app>\n  </NuxtLayout>\n</template>\n```\n\nor\n\n```html { data-resource=\"~/layouts/default.vue\" }\n<template>\n  <v-app>\n    <!-- .... -->\n  </v-app>\n</template>\n```\n\nYou should now have access to all Vuetify components and tools in the Nuxt app.\n\n### vuetify-nuxt-module\n\nAlternatively, you can use the [vuetify-nuxt-module](https://github.com/vuetifyjs/nuxt-module) (works only with Vite). The module is strongly opinionated and has a built-in default configuration out of the box. You can use it without any configuration, and it will work for most use cases.\n\nCheck the [documentation](https://nuxt.vuetifyjs.com/) for more information on how to use it.\n\n## Using Laravel\n\nThe `createApp()` setup may differ, especially if your Laravel application uses [inertiajs](https://inertiajs.com/client-side-setup). As long as you chain with`.use()`, Vuetify should be properly registered and available.\n\n```js  { data-resource=resources/js/app.ts }\nimport { createApp } from 'vue'\n\n// Vuetify\nimport '@mdi/font/css/materialdesignicons.css'\nimport 'vuetify/styles'\nimport { createVuetify } from 'vuetify'\n\nconst app = createApp()\n\n// Register Vuetify as plugin\nconst vuetify = createVuetify()\napp.use(vuetify).mount(\"#app\")\n```\n\n```js { data-resource=vite-config.ts }\nimport vuetify from 'vite-plugin-vuetify'\n// ... other imports\n\nexport default defineConfig({\n  plugins: [\n    // ... other plugins\n    vuetify({ autoImport: true }),\n  ],\n})\n```\n\nIf font is defined at `resources/views/app.blade.php`, Vuetify's font settings will not take effect.\n\n## Using CDN\n\nWe recommend using the latest version of Vuetify 4 from [jsdelivr](https://www.jsdelivr.com/). All components and styles are included.\n\n`https://cdn.jsdelivr.net/npm/vuetify@{{ version }}/dist/vuetify.min.css` { .text-truncate }\n\n`https://cdn.jsdelivr.net/npm/vuetify@{{ version }}/dist/vuetify.min.js` { .text-truncate }\n\nRememeber to include additional script for Vue.js. See full example below:\n\n```html\n<!DOCTYPE html>\n<html>\n  <head>\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width\">\n    <!-- ... -->\n    <link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/vuetify@{{ version }]/dist/vuetify.min.css\" />\n  </head>\n  <body>\n    <div id=\"app\">\n      <v-app>\n        <v-container>\n          <v-text-field label=\"My field\" />\n        </v-container>\n      </v-app>\n    </div>\n    <script src=\"https://cdn.jsdelivr.net/npm/vue@{{ version }}/dist/vue.global.prod.js\"></script>\n    <script src=\"https://cdn.jsdelivr.net/npm/vuetify@{{ version }}/dist/vuetify.min.js\"></script>\n    <script>\n      const { createApp } = Vue\n      const { createVuetify } = Vuetify\n      const vuetify = createVuetify()\n      const app = createApp()\n      app.use(vuetify).mount('#app')\n    </script>\n  </body>\n</html>\n```\n\n## Using as ES Module with CDN\n\nTo import Vuetify (and Vue) using an [import map](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap) you can use the same CDN but contain it in a ES module without tooling\n\n::: info\n  Unlike regular CDN links, import map expects `.../vuetify.esm.js` (**\\*esm.js** instead of **\\*.min.js**)\n:::\n\n```html\n<head>\n  <link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/vuetify@{{ version }}/dist/vuetify.min.css\" />\n  <link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/@mdi/font@latest/css/materialdesignicons.min.css\" />\n  <link rel=\"stylesheet\" href=\"https://fonts.bunny.net/css?family=roboto:400,500,700\" />\n  <script type=\"importmap\">\n  {\n    \"imports\": {\n      \"vue\": \"https://cdn.jsdelivr.net/npm/vue@latest/dist/vue.esm-browser.js\",\n      \"vuetify\": \"https://cdn.jsdelivr.net/npm/vuetify@{{ version }}/dist/vuetify.esm.js\"\n    }\n  }\n  </script>\n</head>\n```\n\n```html\n<script type=\"module\">\n  import { createApp, ref, computed } from \"vue\"\n  import { createVuetify } from \"vuetify\"\n  //... setup as usual\n</script>\n```\n\n## Using Vitepress\n\nYou can use Vuetify's components in your Vitepress static site.\n\nAfter initializing your Vitepress project, add Vuetify to your dependencies\n\n::: tabs\n\n```bash [pnpm]\npnpm i vuetify\n```\n\n```bash [yarn]\nyarn add vuetify\n```\n\n```bash [npm]\nnpm i vuetify\n```\n\n```bash [bun]\nbun add vuetify\n```\n\n:::\n\nThen, in your `.vitepress/theme/index.ts`\n\n```ts\nimport DefaultTheme from 'vitepress/theme'\nimport 'vuetify/styles'\nimport * as components from 'vuetify/components'\nimport * as directives from 'vuetify/directives'\nimport { createVuetify } from 'vuetify'\n\nconst vuetify = createVuetify({ components, directives })\n\nexport default {\n  extends: DefaultTheme,\n  enhanceApp({ app }) {\n    app.use(vuetify)\n  },\n}\n```\n\n## Existing projects\n\nFollow these steps if for example you are adding Vuetify to an existing project, or simply do not want to use a scaffolding tool.\n\n::: tabs\n\n```bash [pnpm]\npnpm i vuetify\n```\n\n```bash [yarn]\nyarn add vuetify\n```\n\n```bash [npm]\nnpm i vuetify\n```\n\n```bash [bun]\nbun add vuetify\n```\n\n:::\n\n::: tip\n\nIf you are upgrading from an earlier version of Vuetify, make sure to check out our [Upgrade Guide](/getting-started/upgrade-guide/)\n\n:::\n\nIn the file where you create the Vue application, add the following code\n\n```js\nimport { createApp } from 'vue'\n\n// Vuetify\nimport 'vuetify/styles'\nimport { createVuetify } from 'vuetify'\nimport * as components from 'vuetify/components'\nimport * as directives from 'vuetify/directives'\n\n// Components\nimport App from './App.vue'\n\nconst vuetify = createVuetify({\n  components,\n  directives,\n})\n\ncreateApp(App).use(vuetify).mount('#app')\n```\n\nThis will include all components and directives regardless of whether or not you are using them. If you instead only want to include used components, have a look at the [Vite](https://npmjs.com/package/vite-plugin-vuetify) or [Webpack](https://npmjs.com/package/webpack-plugin-vuetify) plugins, depending on your setup. The plugins also makes it possible to customize SCSS variables.\n\nLastly, do not forget to install [icons](/features/icon-fonts/).\n\n## Fonts\n\nVuetify uses Roboto as its default font. To ensure your project renders correctly, you need to add the Roboto font yourself. We recommend using @fontsource/roboto or bundling with unplugin-fonts which is the default used in [vuetify-create](https://github.com/vuetifyjs/create) installations.\n\n### Option A — Install via @fontsource/roboto\n\n::: tabs\n\n```bash [pnpm]\npnpm i @fontsource/roboto\n```\n\n```bash [yarn]\nyarn add @fontsource/roboto\n```\n\n```bash [npm]\nnpm i @fontsource/roboto\n```\n\n```bash [bun]\nbun add @fontsource/roboto\n```\n\n:::\n\nThen import the styles you need in your main.ts or main.js:\n\n```js\nimport '@fontsource/roboto/100.css'\nimport '@fontsource/roboto/300.css'\nimport '@fontsource/roboto/400.css'\nimport '@fontsource/roboto/500.css'\nimport '@fontsource/roboto/700.css'\nimport '@fontsource/roboto/900.css'\n\n/* optional italic styles */\nimport '@fontsource/roboto/100-italic.css'\nimport '@fontsource/roboto/300-italic.css'\nimport '@fontsource/roboto/400-italic.css'\nimport '@fontsource/roboto/500-italic.css'\nimport '@fontsource/roboto/700-italic.css'\nimport '@fontsource/roboto/900-italic.css'\n```\n\n### Option B — Install via unplugin-fonts + @fontsource  (recommended)\n\n::: tabs\n\n```bash [pnpm]\npnpm i --save-dev unplugin-fonts\npnpm i @fontsource/roboto\n```\n\n```bash [yarn]\nyarn add --save-dev unplugin-fonts\nyarn add @fontsource/roboto\n```\n\n```bash [npm]\nnpm i --save-dev unplugin-fonts\nnpm i @fontsource/roboto\n```\n\n```bash [bun]\nbun add --save-dev unplugin-fonts\nbun add @fontsource/roboto\n```\n\n:::\n\nUpdate your vite.config.ts:\n\n```ts\nimport { defineConfig } from 'vite'\nimport ViteFonts from 'unplugin-fonts/vite'\n\nexport default defineConfig({\n  plugins: [\n    ViteFonts({\n      fontsource: {\n        families: [\n          {\n            name: 'Roboto',\n            weights: [100, 300, 400, 500, 700, 900],\n            styles: ['normal', 'italic'],\n          },\n        ],\n      },\n    }),\n  ],\n})\n```\n\nAnd import the generated CSS once in your main.ts or main.js:\n\n```ts\nimport 'unfonts.css'\n```\n\n## SSR caveats\n\nVue 3 has no way to automatically detect if SSR is used &mdash; so nuxt, gridsome, and other SSR frameworks must manually set the `ssr` option to `true` in order to properly render the application.\n\n```js { data-resource=\"src/plugins/vuetify.js\" }\nimport '@mdi/font/css/materialdesignicons.css'\nimport 'vuetify/styles'\n\nconst vuetify = createVuetify({\n  ssr: true,\n})\n```\n\n## Exposed exports\n\nThe following export paths exist for the Vuetify framework:\n\n### JS / TS\n\n| Name                             | Description                                                                                                                                        |\n|----------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------|\n| `vuetify`                        | Main entry point. Contains `createVuetify()` and public composables.                                                                               |\n| `vuetify/styles`                 | Precompiled global CSS (reset, utilities, etc.), no component styles. Will be redirected to SASS if `styles.configFile` is set in vite or webpack. |\n| `vuetify/components`             | All components. Not recommended as it will include all components during development, slowing down your build.                                     |\n| `vuetify/components/<name>`      | Individual components. Grouped by top-level name, for example VListItem, VListGroup, and VListItemTitle are all in `vuetify/components/VList`.     |\n| `vuetify/directives`             | All directives.                                                                                                                                    |\n| `vuetify/directives/<name>`      | Individual directives.                                                                                                                             |\n| `vuetify/blueprints/<name>`      | Preset collections of prop defaults.                                                                                                               |\n| `vuetify/locale`                 | Translations for strings in vuetify components. Each language is a named export.                                                                   |\n| `vuetify/locale/adapters/<name>` | Adapters to retrieve translations from other libraries such as vue-i18n.                                                                           |\n| `vuetify/iconsets/<name>`        | Icon presets, see [Icon Fonts](/features/icon-fonts/)                                                                                              |\n\n### SASS\n\nSee [SASS Variables](/features/sass-variables/) for more information.\n\n| Name               | Description                                                                                     |\n|--------------------|-------------------------------------------------------------------------------------------------|\n| `vuetify`          | Global CSS (reset, utilities, etc.), no component styles. Equivalent to `vuetify/styles` in JS. |\n| `vuetify/settings` | All SASS variables, including component variables.                                              |\n| `vuetify/tools`    | Mixins and functions.                                                                           |\n\n## Nightly Builds\n\nThe three development branches (`master`, `dev`, and `next`) are automatically published to NPM at 1200 UTC under the [`@vuetify/nightly`](https://www.npmjs.com/package/@vuetify/nightly?activeTab=versions) namespace. They may be outdated or buggy and are therefore not officially supported and are only supplied for testing purposes. These builds can be installed with a [package alias](https://docs.npmjs.com/cli/v8/commands/npm-install#:~:text=Install%20a%20package%20under%20a%20custom%20alias).\n\n| Branch name | Purpose          | package.json entry                         | Changelog                                                           |\n|-------------|------------------|--------------------------------------------|---------------------------------------------------------------------|\n| `master`    | Bug fixes        | `\"vuetify\": \"npm:@vuetify/nightly@latest\"` | [Changelog](https://unpkg.com/@vuetify/nightly@latest/CHANGELOG.md) |\n| `dev`       | New features     | `\"vuetify\": \"npm:@vuetify/nightly@dev\"`    | [Changelog](https://unpkg.com/@vuetify/nightly@dev/CHANGELOG.md)    |\n| `next`      | Breaking changes | `\"vuetify\": \"npm:@vuetify/nightly@next\"`   | [Changelog](https://unpkg.com/@vuetify/nightly@next/CHANGELOG.md)   |\n\n```diff\n \"devDependencies\": {\n-  \"vuetify\": \"^3.3.0\"\n+  \"vuetify\": \"npm:@vuetify/nightly@3.3.0-master.2023-05-21\"\n }\n```\n\n## Questions\n\nHave a question that belongs here? Tell us in our [Discord Community](https://community.vuetifyjs.com/) or create a request on our [Issue Generator](https://issues.vuetifyjs.com/).\n\n<PromotedPromoted slug=\"vuetify-discord\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/getting-started/release-notes.md",
    "content": "---\nfluid: true\nmeta:\n  title: Release notes\n  description: Stay up to date with the latest release notes. The migration guides will also help you migrate applications though major releases.\n  keywords: migration, releases, upgrading vuetify\nrelated:\n  - /introduction/long-term-support/\n  - /getting-started/contributing/\n  - /introduction/roadmap/\n---\n\n# Release notes\n\nThe Vuetify team performs releases on a weekly basis.\n\n<PageFeatures />\n\n<PromotedEntry slug=\"vuetify-one\" />\n\n<DocReleases />\n"
  },
  {
    "path": "packages/docs/src/pages/en/getting-started/typography-migration.md",
    "content": "---\nmeta:\n  nav: Typography migration\n  title: Typography migration\n  description: Guide for migrating from legacy SCSS typography to MD3 typography system\n  keywords: typography, migration, md3, scss, upgrade\nrelated:\n  - /getting-started/upgrade-guide/\n  - /styles/text-and-typography/\n---\n\n# Typography Migration Guide\n\nThis page describes changes introduced in **v4.0.0** and maps the legacy typography variants to the new Material Design 3 (MD3) variants.\n\n## Quick Reference\n\n<DocTypographyPreview />\n\n## Conservative Migration Mapping\n\nIf you want to keep text sizes as close as possible to the previous MD2 sizes, use this mapping table:\n\n| Legacy MD2 Class  | MD2 Size | Recommended MD3 Class | MD3 Size | Notes                                     |\n|-------------------|----------|-----------------------|----------|-------------------------------------------|\n| `text-h1`         | 96px     | n/a                   | n/a      | ⚠️ needs custom variant                   |\n| `text-h2`         | 60px     | `text-display-large`  | 57px     | Close match                               |\n| `text-h3`         | 48px     | `text-display-medium` | 45px     | Close match                               |\n| `text-h4`         | 34px     | `text-headline-large` | 32px     | Close match                               |\n| `text-h5`         | 24px     | `text-headline-small` | 24px     | ✓ Exact match                             |\n| `text-h6`         | 20px     | `text-title-large`    | 22px     | Close match                               |\n| `text-subtitle-1` | 16px     | `text-body-large`     | 16px     | ✓ Exact match                             |\n| `text-subtitle-2` | 14px     | `text-title-small`    | 14px     | ✓ Exact match (500 weight)                |\n| `text-body-1`     | 16px     | `text-body-large`     | 16px     | ✓ Exact match                             |\n| `text-body-2`     | 14px     | `text-body-medium`    | 14px     | ✓ Exact match                             |\n| `text-button`     | 14px     | `text-label-large`    | 14px     | ✓ Exact match (no uppercase)              |\n| `text-caption`    | 12px     | `text-body-small`     | 12px     | ✓ Exact match                             |\n| `text-overline`   | 12px     | `text-label-medium`   | 12px     | ⚠️ No uppercase, different letter spacing |\n\n::: warning Important Notes\n\n- **Large headings (h1-h3)**: MD3 display variants are significantly smaller than MD2 headings. Consider customizing these sizes if maintaining visual hierarchy is critical.\n- **Title variants (new in MD3)**: The `text-title-*` variants provide better semantic alternatives for medium-sized headings and subtitles with appropriate font weights (400-500). Use these instead of body variants when you need emphasized text.\n- **text-overline**: The `text-label-small` or `text-label-medium` classes don't include `text-transform: uppercase` by default. Use `text-uppercase` utility class or customize the variant.\n- **Font weight differences**: Some MD3 variants have different font weights. Check the [full comparison table](#key-differences) below for details.\n:::\n\n## Migration Steps\n\n### 1. Update class names in HTML templates\n\nReplace legacy class names with MD3 equivalents:\n\n```html\n<!-- Before -->\n<h1 class=\"text-h1\">Title</h1>\n<p class=\"text-body-1\">Content</p>\n<span class=\"text-caption\">Small text</span>\n\n<!-- After -->\n<h1 class=\"text-display-large\">Title</h1>\n<p class=\"text-body-large\">Content</p>\n<span class=\"text-body-small\">Small text</span>\n```\n\n### 2. Sass customization\n\nIf your app has some customization applied to `$typography`, it needs to be re-mapped to new variants.\n\n```scss { resource=\"src/settings.scss\" }\n// Before\nuse 'vuetify/settings' with (\n  $typography: (\n    'h1': (// <- only adds `text-h1` as a new class next to MD3 variants\n      'size': 3rem,\n      'weight': 400,\n    ),\n  ),\n)\n```\n\n```scss { resource=\"src/settings.scss\" }\n// After\nuse 'vuetify/settings' with (\n  $typography: (\n    'display-large': (// <- migrated to semantic equivalent\n      'size': 3rem,\n      'weight': 400, // <- can be skipped, same as default\n    ),\n  ),\n)\n```\n\n### Detached Sass variables\n\nNew typography configuration does not cover `text-transform`. So some of the Sass variables are now detached from typography and default to `none`.\n\n| Sass Variable                | Legacy value                                          |\n|------------------------------|-------------------------------------------------------|\n| `$button-text-transform`     | `settings.$typography` » `button` » `text-transform`  |\n| `$card-text-text-transform`  | `settings.$typography` » `body-2` » `text-transform`  |\n| `$system-bar-text-transform` | `settings.$typography` » `caption` » `text-transform` |\n\nIn order to restore the customized values, pass them directly to the specific variables:\n\n```scss { resource=\"src/settings.scss\" }\n@use 'vuetify/settings' with (\n  $button-text-transform: uppercase,\n  $card-text-text-transform: none,\n  $system-bar-text-transform: none,\n);\n```\n\n## Breaking Changes\n\n1. **Class names**: All default typography classes changed to align with Material Design 3\n2. **No text-transform by default**: The `overline` → `label-small` is not an equivalent replacement as it looses `uppercase`, letter spacing is 3x smaller, etc.\n3. **Different sizing**: MD3 variants follow Material Design 3 specifications which differ from MD2\n\n### Restoring MD2 typography\n\nIf you want to avoid visual regression entirely, you can restore MD2 typography using configuration snippets bellow.\n\n```scss { resource=\"src/typography.scss\" }\n$body-font-family: 'Roboto', sans-serif;\n$heading-font-family: $body-font-family;\n\n$typography: (\n  (\n    'h1': (\n      'size': 6rem,\n      'weight': 300,\n      'line-height': 1,\n      'letter-spacing': -.015625em,\n      'font-family': $heading-font-family,\n      'text-transform': none\n    ),\n    'h2': (\n      'size': 3.75rem,\n      'weight': 300,\n      'line-height': 1,\n      'letter-spacing': -.0083333333em,\n      'font-family': $heading-font-family,\n      'text-transform': none\n    ),\n    'h3': (\n      'size': 3rem,\n      'weight': 400,\n      'line-height': 1.05,\n      'letter-spacing': normal,\n      'font-family': $heading-font-family,\n      'text-transform': none\n    ),\n    'h4': (\n      'size': 2.125rem,\n      'weight': 400,\n      'line-height': 1.175,\n      'letter-spacing': .0073529412em,\n      'font-family': $heading-font-family,\n      'text-transform': none\n    ),\n    'h5': (\n      'size': 1.5rem,\n      'weight': 400,\n      'line-height': 1.333,\n      'letter-spacing': normal,\n      'font-family': $heading-font-family,\n      'text-transform': none\n    ),\n    'h6': (\n      'size': 1.25rem,\n      'weight': 500,\n      'line-height': 1.6,\n      'letter-spacing': .0125em,\n      'font-family': $heading-font-family,\n      'text-transform': none\n    ),\n    'subtitle-1': (\n      'size': 1rem,\n      'weight': normal,\n      'line-height': 1.75,\n      'letter-spacing': .009375em,\n      'font-family': $body-font-family,\n      'text-transform': none\n    ),\n    'subtitle-2': (\n      'size': .875rem,\n      'weight': 500,\n      'line-height': 1.6,\n      'letter-spacing': .0071428571em,\n      'font-family': $body-font-family,\n      'text-transform': none\n    ),\n    'body-1': (\n      'size': 1rem,\n      'weight': 400,\n      'line-height': 1.5,\n      'letter-spacing': .03125em,\n      'font-family': $body-font-family,\n      'text-transform': none\n    ),\n    'body-2': (\n      'size': .875rem,\n      'weight': 400,\n      'line-height': 1.425,\n      'letter-spacing': .0178571429em,\n      'font-family': $body-font-family,\n      'text-transform': none\n    ),\n    'button': (\n      'size': .875rem,\n      'weight': 500,\n      'line-height': 2.6,\n      'letter-spacing': .0892857143em,\n      'font-family': $body-font-family,\n      'text-transform': uppercase\n    ),\n    'caption': (\n      'size': .75rem,\n      'weight': 400,\n      'line-height': 1.667,\n      'letter-spacing': .0333333333em,\n      'font-family': $body-font-family,\n      'text-transform': none\n    ),\n    'overline': (\n      'size': .75rem,\n      'weight': 500,\n      'line-height': 2.667,\n      'letter-spacing': .1666666667em,\n      'font-family': $body-font-family,\n      'text-transform': uppercase\n    )\n  ),\n  $typography\n);\n\n$flat-typography: ();\n@each $type, $values in $typography {\n  $flat-typography: map-deep-merge(\n    $flat-typography,\n    (#{$type}: (\n      map.get($values, 'size'),\n      map.get($values, 'weight'),\n      map.get($values, 'line-height'),\n      map.get($values, 'letter-spacing'),\n      map.get($values, 'font-family'),\n      map.get($values, 'text-transform'),\n    ))\n  );\n}\n```\n\n```scss { resource=\"src/settings.scss\" }\n@use './typography' as *;\n@use 'vuetify/settings' with (\n  $utilities: (\n    \"typography\": (\n      property: (\n        font-size,\n        font-weight,\n        line-height,\n        letter-spacing,\n        font-family,\n        text-transform // <-- restoring this line\n      ),\n      values: $flat-typography, // <-- ensures we only generate MD2 variants\n    ),\n  ),\n\n  $alert-title-font-size: tools.map-deep-get(.$typography, 'h6', 'size'),\n  $alert-title-font-weight: tools.map-deep-get(.$typography, 'h6', 'weight'),\n  $alert-title-letter-spacing: tools.map-deep-get(.$typography, 'h6', 'letter-spacing'),\n  $banner-font-size: tools.map-deep-get(.$typography, 'body-2', 'size'),\n  $banner-line-height: tools.map-deep-get(.$typography, 'subtitle-2', 'line-height'),\n  $breadcrumbs-item-icon-font-size: tools.map-deep-get(.$typography, 'body-1', 'size'),\n  $breadcrumbs-line-height: tools.map-deep-get(.$typography, 'subtitle-2', 'line-height'),\n  $button-font-size: tools.map-deep-get(.$typography, 'button', 'size'),\n  $button-font-weight: tools.map-deep-get(.$typography, 'button', 'weight'),\n  $button-text-letter-spacing: tools.map-deep-get(.$typography, 'button', 'letter-spacing'),\n  $button-text-transform: tools.map-deep-get(.$typography, 'button', 'text-transform'),\n  $card-title-font-size: tools.map-deep-get(.$typography, 'h6', 'size'),\n  $card-title-font-weight: tools.map-deep-get(.$typography, 'h6', 'weight'),\n  $card-title-letter-spacing: tools.map-deep-get(.$typography, 'h6', 'letter-spacing'),\n  $card-title-line-height: tools.map-deep-get(.$typography, 'h6', 'line-height'),\n  $card-subtitle-font-size: tools.map-deep-get(.$typography, 'body-2', 'size'),\n  $card-subtitle-font-weight: tools.map-deep-get(.$typography, 'body-2', 'weight'),\n  $card-subtitle-letter-spacing: tools.map-deep-get(.$typography, 'body-2', 'letter-spacing'),\n  $card-subtitle-line-height: tools.map-deep-get(.$typography, 'body-2', 'line-height'),\n  $card-text-font-size: tools.map-deep-get(.$typography, 'body-2', 'size'),\n  $card-text-font-weight: tools.map-deep-get(.$typography, 'body-2', 'weight'),\n  $card-text-letter-spacing: tools.map-deep-get(.$typography, 'body-2', 'letter-spacing'),\n  $card-text-line-height: tools.map-deep-get(.$typography, 'body-2', 'line-height'),\n  $card-text-text-transform: tools.map-deep-get(.$typography, 'body-2', 'text-transform'),\n  $chip-font-size: tools.map-deep-get(.$typography, \"button\", \"size\"),\n  $dialog-card-text-letter-spacing: tools.map-deep-get(.$typography, 'body-1', 'letter-spacing'),\n  $empty-state-headline-font-size: functions.map-deep-get(.$typography, 'h2', 'size'),\n  $empty-state-headline-font-weight: functions.map-deep-get(.$typography, 'h2', 'weight'),\n  $empty-state-headline-line-height: functions.map-deep-get(.$typography, 'h2', 'line-height'),\n  $empty-state-headline-mobile-font-size: functions.map-deep-get(.$typography, 'h4', 'size'),\n  $empty-state-text-font-size: functions.map-deep-get(.$typography, 'body-2', 'size'),\n  $empty-state-text-font-weight: functions.map-deep-get(.$typography, 'body-2', 'weight'),\n  $empty-state-text-line-height: functions.map-deep-get(.$typography, 'body-2', 'line-height'),\n  $empty-state-title-font-size: functions.map-deep-get(.$typography, 'h6', 'size'),\n  $empty-state-title-font-weight: functions.map-deep-get(.$typography, 'h6', 'weight'),\n  $empty-state-title-line-height: functions.map-deep-get(.$typography, 'h6', 'line-height'),\n  $fab-font-size: tools.map-deep-get(.$typography, 'button', 'size'),\n  $fab-font-weight: tools.map-deep-get(.$typography, 'button', 'weight'),\n  $input-font-size: tools.map-deep-get(.$typography, 'body-1', 'size'),\n  $input-font-weight: tools.map-deep-get(.$typography, 'body-1', 'weight'),\n  $list-item-nav-subtitle-font-weight: tools.map-deep-get(.$typography, 'body-2', 'weight'),\n  $list-item-nav-subtitle-letter-spacing: tools.map-deep-get(.$typography, 'body-2', 'letter-spacing'),\n  $list-item-subtitle-font-size: tools.map-deep-get(.$typography, 'body-2', 'size'),\n  $list-item-subtitle-font-weight: tools.map-deep-get(.$typography, 'body-2', 'weight'),\n  $list-item-subtitle-letter-spacing: tools.map-deep-get(.$typography, 'body-2', 'letter-spacing'),\n  $list-item-title-font-size: tools.map-deep-get(.$typography, 'body-1', 'size'),\n  $list-item-title-font-weight: tools.map-deep-get(.$typography, 'body-1', 'weight'),\n  $list-item-title-letter-spacing: tools.map-deep-get(.$typography, 'subtitle-1', 'letter-spacing'),\n  $list-item-title-line-height: tools.map-deep-get(.$typography, 'body-1', 'line-height'),\n  $slider-thumb-label-font-size: tools.map-deep-get(.$typography, 'caption', 'size'),\n  $snackbar-font-size: tools.map-deep-get(.$typography, 'body-2', 'size'),\n  $snackbar-font-weight: tools.map-deep-get(.$typography, 'body-2', 'weight'),\n  $snackbar-letter-spacing: tools.map-deep-get(.$typography, 'body-2', 'letter-spacing'),\n  $snackbar-line-height: tools.map-deep-get(.$typography, 'body-2', 'line-height'),\n  $system-bar-font-size: tools.map-deep-get(.$typography, 'caption', 'size'),\n  $system-bar-font-weight: tools.map-deep-get(.$typography, 'caption', 'weight'),\n  $system-bar-letter-spacing: tools.map-deep-get(.$typography, 'caption', 'letter-spacing'),\n  $system-bar-line-height: tools.map-deep-get(.$typography, 'caption', 'line-height'),\n  $system-bar-text-transform: tools.map-deep-get(.$typography, 'caption', 'text-transform'),\n  $table-header-font-size: tools.map-deep-get(.$typography, 'caption', 'size'),\n  $table-font-size: tools.map-deep-get(.$typography, 'body-2', 'size'),\n  $table-row-font-size: tools.map-deep-get(.$typography, 'subtitle-2', 'size'),\n  $icon-btn-font-size: tools.map-deep-get(.$typography, 'button', 'size'),\n  $icon-btn-font-weight: tools.map-deep-get(.$typography, 'button', 'weight'),\n);\n```\n"
  },
  {
    "path": "packages/docs/src/pages/en/getting-started/unit-testing.md",
    "content": "---\nmeta:\n  title: Unit testing\n  description: Learn how to create unit tests with vue-test-utils and Vuetify components in your Vue application.\n  keywords: unit testing vuetify, testing vuetify, vuetify spec tests\nrelated:\n  - /getting-started/frequently-asked-questions/\n  - /getting-started/contributing/\n  - /components/text-fields/\n---\n\n# Unit Testing\n\nAdd regression protection by adding unit tests to your Vuetify application\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## Usage\n\nUnit tests are an important (and sometimes ignored) part of developing applications. They help us secure our processes and workflows, ensuring that the most critical parts of our projects are protected from accidental mistakes or oversights in our development.\n\nBecause of this, Vue has its own testing utility called [vue-test-utils](https://test-utils.vuejs.org/). It provides useful features for interacting with Vue components and works with many popular test runners.\n\n## Using Vite\n\n[Vite](https://vitejs.dev/) is a fast, opinionated frontend build tool that serves your code via native ES Module imports during dev and bundles it with Rollup for production. It provides a great developer experience and is the recommended build tool for Vuetify applications.\n\nFirst, update your **vite.config.js** file to inline the `vuetify` dependency:\n\n```js { resource=\"vite.config.js\" }\nimport { defineConfig } from 'vite'\n\nexport default defineConfig({\n  test: {\n    globals: true,\n    environment: 'jsdom',\n    server: {\n      deps: {\n        inline: ['vuetify'],\n      },\n    },\n  },\n})\n```\n\n### Setup Vitest\n\n[Vitest](https://vitest.dev/) is a popular test runner that provides a great developer experience. It is fast, easy to use, and provides useful features like snapshot testing. To get started, install the following dependencies:\n\n::: tabs\n\n```bash [pnpm]\npnpm add @vue/test-utils vitest resize-observer-polyfill --save-dev\n```\n\n```bash [yarn]\nyarn add @vue/test-utils vitest resize-observer-polyfill --dev\n```\n\n```bash [npm]\nnpm install @vue/test-utils vitest resize-observer-polyfill --save-dev\n```\n\n```bash [bun]\nbun add @vue/test-utils vitest resize-observer-polyfill --dev\n```\n\n:::\n\nOnce installed, create a new folder at the root of your application named **tests/spec** and add a new file named **HelloWorld.spec.js**. The following example shows how to setup a basic unit test for a Vuetify component:\n\n```js { resource=\"tests/spec/HelloWorld.spec.js\" }\nimport { mount } from '@vue/test-utils'\nimport { expect, test } from 'vitest'\nimport { createVuetify } from 'vuetify'\nimport * as components from 'vuetify/components'\nimport * as directives from 'vuetify/directives'\nimport HelloWorld from '../../src/components/HelloWorld.vue'\n\nconst vuetify = createVuetify({\n  components,\n  directives,\n})\n\nglobal.ResizeObserver = require('resize-observer-polyfill')\n\ntest('displays message', () => {\n  const wrapper = mount({\n    template: '<v-layout><hello-world></hello-world></v-layout>'\n  }, {\n    props: {},\n    global: {\n      components: {\n        HelloWorld,\n      },\n      plugins: [vuetify],\n    }\n  })\n\n  // Assert the rendered text of the component\n  expect(wrapper.text()).toContain('Components')\n})\n```\n\n## Testing Vuetify Components\n\nWhen testing Vuetify components, we recommend running tests in a real browser environment instead of `jsdom`.\n\n### Recommended Test Runners\n\n* [Vitest (browser mode)](https://vitest.dev/guide/browser/) – Fast, Vite-native test runner with browser support.\n* [Playwright](https://playwright.dev/) – End-to-end testing in actual browsers.\n* [Cypress](https://www.cypress.io/) – Great for integration and E2E tests.\n\n### Rendering with Vuetify\n\nTo properly render Vuetify components in tests, create a Vuetify instance and pass it to the test renderer. You don’t need to mock transitions or other internals.\n\n```ts { resource=\"vuetify/packages/vuetify/test/index.ts\" }\nexport function render<C> (\n  component: C,\n  options?: RenderOptions<C> | null,\n  vuetifyOptions?: VuetifyOptions\n): RenderResult {\n  const vuetify = createVuetify(mergeDeep({ icons: { aliases } }, vuetifyOptions))\n\n  const defaultOptions = {\n    global: {\n      stubs: {\n        transition: false,\n        'transition-group': false,\n      },\n      plugins: [vuetify],\n    },\n  }\n\n  const mountOptions = mergeDeep(defaultOptions, options!, (a, b) => a.concat(b))\n\n  return _render(component, mountOptions)\n}\n```\n\n### Using `data-testid`\n\nFor reliable queries in tests, use `data-testid` attributes in your components:\n\n```html\n<v-btn data-testid=\"submit-btn\">Submit</v-btn>\n```\n\n```ts\nconst { getByTestId } = render(MyComponent)\nexpect(getByTestId('submit-btn')).toBeInTheDocument()\n```\n\n### Accessibility Considerations\n\nTests should respect user accessibility preferences. Configure [prefers-reduced-motion](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion) when testing animations to avoid flakiness and ensure accessibility compliance.\n"
  },
  {
    "path": "packages/docs/src/pages/en/getting-started/upgrade-guide.md",
    "content": "---\nemphasized: true\nmeta:\n  nav: Upgrade guide\n  title: Upgrade guide\n  description: Detailed instruction on how to upgrade Vuetify to 4.0\n  keywords: migration, upgrade, releases, upgrading vuetify, alpha, v4\nrelated:\n  - /introduction/roadmap/\n  - /introduction/long-term-support/\n  - /introduction/enterprise-support/\n---\n\n# Upgrade Guide\n\nThis page contains a detailed list of breaking changes and the steps required to upgrade your application to Vuetify 4\n\n<PageFeatures />\n\n## Quick Start with Vuetify MCP\n\nThe fastest way to check your project for breaking changes is with [Vuetify MCP](https://github.com/vuetifyjs/mcp/). To get started, run the following in your terminal:\n\n```bash\n# Claude Code\nclaude mcp add --transport http vuetify-mcp https://mcp.vuetifyjs.com/mcp\n\n# Configure for hosted remote server\nnpx -y @vuetify/mcp config --remote\n\n# Or configure for local installation\nnpx -y @vuetify/mcp config\n```\n\nOnce the MCP server is set up and loaded you will gain access to new tools such as:\n\n- `get_upgrade_guide`: Get a list of all breaking changes in the upgrade guide.\n- `get_v4_breaking_changes`: Get a list of all breaking changes in Vuetify 4.\n\nNow, prompt your agent with the following:\n\n```text\nUsing the vuetify-mcp server, scan this project for Vuetify 3 to 4 breaking changes. List each issue found with the file, line number, and recommended fix.\n```\n\nThis will automatically analyze your codebase and provide a tailored list of changes you need to make.\n\nIf you have any questions about the upgrade process, come visit us at [community.vuetifyjs.com](https://community.vuetifyjs.com/).\n\n## Multi-step migration\n\nSeveral breaking changes in Vuetify 4 can be temporarily reverted by pasting short CSS or configuration snippets — notably [CSS reset](#css-reset), [typography](#typography), [elevation](#elevation), and [grid](#grid-system-vrow-and-vcol). This means you can migrate incrementally: restore the legacy behavior first, then update each area at your own pace.\n\nEven though these migrations mostly come down to adjusting CSS classes, manually reviewing every affected template can be time-consuming without automated visual regression tests. For large projects (typically over 200 components), we recommend scanning your codebase for relevant usage before starting:\n\n- **HTML elements** — `<h1>` through `<h6>` (affected by CSS reset)\n- **Grid usage** — `<v-row>` and `<v-col>`, with specific focus on ad-hoc spacing adjustments (i.e. classes like `mx-0`, `pa-0`)\n- **Grid attributes** — `dense`, `align`, `justify`, `order`, `align-self` (affected by grid changes)\n- **Shadows** — `elevation-*` classes and `elevation` attributes or CSS overrides (affected by elevation changes)\n- **CSS classes** — `text-h1` … `text-h6`, `text-subtitle-1`, `text-body-2`, `text-caption`, `text-overline`, `elevation-*`, `offset-*` (affected by typography)\n\nIdentify the areas with the highest usage first, apply the corresponding compatibility snippets, and then schedule the full class-by-class migration as a follow-up.\n\n[vuetify-codemods](https://www.npmjs.com/package/vuetify-codemods) can be used to automate many of these changes.\n\n## Styles\n\n### Style entry points\n\nThere are now pre-compiled entry points for the most common style changes. If you have a Sass file that only sets `$color-pack: false` or `$utilities: false` you can replace it with `import 'vuetify/styles/core'`. See [Style entry points](/styles/entry-points) for more information.\n\n### CSS reset\n\nThe CSS reset has been mostly removed, with style normalisation being moved to individual components instead. You can inspect the exact [changes](https://github.com/vuetifyjs/vuetify/pull/20960/changes#diff-87996fc432835581ad883bedbc1975ad3a3f44b5747b2b831e3fa03dfdabb91f) to learn more. Here is the high level overview:\n\n- global `* { padding: 0; margin: 0; }` is gone - no longer resets all elements\n- `<button>`, `<input>`, `<select>` have their browser-native borders and background colors.\n\nIf you notice browser styles adding unnecessary spaces and impact text size, it is recommended to assess the scope of visual regression and selectively apply spacing resets:\n\n```css\n@layer vuetify-core.reset {\n  ul, ol, figure, details, summary {\n    padding: 0;\n    margin: 0;\n  }\n\n  h1, h2, h3, h4, h5, h6 {\n    margin: 0;\n  }\n}\n```\n\nRestoring most of the previous reset styles would be heavy-handed, but will get the job done as well.\n\n```css\n@layer vuetify-core.reset {\n  * { padding: 0; margin: 0; }\n  a:active, a:hover { outline-width: 0; }\n  code, kbd, pre, samp { font-family: monospace; }\n  pre { font-size: 1em; }\n  small { font-size: 80%; }\n  sub, sup {\n    font-size: 75%;\n    line-height: 0;\n    position: relative;\n    vertical-align: baseline;\n  }\n  sub { bottom: -0.25em; }\n  sup { top: -0.5em; }\n  textarea { resize: vertical; }\n  button,\n  input,\n  select,\n  textarea {\n    background-color: transparent;\n    border-style: none;\n  }\n  select {\n    -moz-appearance: none;\n    -webkit-appearance: none;\n  }\n  legend {\n    display: table;\n    max-width: 100%;\n    white-space: normal;\n  }\n}\n```\n\n### Layers\n\nCascade layers are now being used everywhere. If you have other styles that are not using `@layer` they will now always take priority over vuetify.\n\nIf you were already using `$layers: true` in Vuetify 3, there are now five top-level layers instead of one.\n\n```diff\n- @layer base, vuetify, overrides;\n+ @layer base, vuetify-core, vuetify-components, vuetify-overrides, vuetify-utilities, vuetify-final, overrides;\n```\n\nThis can be used to easily interleave your own layers with ours:\n\n```css\n@layer vuetify-core, base, vuetify-components, vuetify-overrides, overrides, vuetify-utilities, utilities, vuetify-final;\n```\n\nIf you had any usages of `@layer vuetify.*` in your styles they should be replaced with your own layer name with an appropriate declaration order.\n\n### Typography\n\nThe typography system has been updated from Material Design 2 to Material Design 3. Variant names have changed:\n\n| MD2 (Legacy)           | MD3 (New)                                             |\n|------------------------|-------------------------------------------------------|\n| `h1` - `h3`            | `display-large`, `display-medium`, `display-small`    |\n| `h4` - `h6`            | `headline-large`, `headline-medium`, `headline-small` |\n| `subtitle-1`, `body-1` | `body-large`                                          |\n| `body-2`               | `body-medium`                                         |\n| `caption`              | `body-small`                                          |\n| `button`, `subtitle-2` | `label-large`                                         |\n| `overline`             | `label-small`                                         |\n\nFor detailed mapping and migration instructions, see [Typography Migration](/getting-started/typography-migration/).\n\n### Breakpoints\n\nThe default breakpoints have been reduced to better match modern device sizes:\n\n| Breakpoint | Change              |\n|------------|---------------------|\n| xs         | 0 (unchanged)       |\n| sm         | 600px (unchanged)   |\n| md         | ~~960px~~  » 840px  |\n| lg         | ~~1280px~~ » 1145px |\n| xl         | ~~1920px~~ » 1545px |\n| xxl        | ~~2560px~~ » 2138px |\n\nOne of the components specifically impacted by those changes is VContainer. See the detailed information about those changes [below](#vcontainer).\n\nv3 breakpoints can be restored with the following configuration:\n\n```js { resource=\"src/plugins/vuetify.ts\" }\nexport default createVuetify({\n  display: {\n    thresholds: {\n      md: 960,\n      lg: 1280,\n      xl: 1920,\n      xxl: 2560,\n    },\n  },\n})\n```\n\n```scss { resource=\"src/styles/_settings.scss\" }\n@use 'vuetify/settings' with (\n  $grid-breakpoints: (\n    'md': 960px,\n    'lg': 1280px,\n    'xl': 1920px,\n    'xxl': 2560px,\n  ),\n);\n```\n\n### Elevation\n\nElevation classes (shadows) have been updated to Material Design 3 which uses 6 levels (0-5) instead of 25 (0-24).\n\n| MD3 elevation levels |\n|----------------------|\n| `elevation-0` (0dp)  |\n| `elevation-1` (1dp)  |\n| `elevation-2` (3dp)  |\n| `elevation-3` (6dp)  |\n| `elevation-4` (8dp)  |\n| `elevation-5` (12dp) |\n\n\\* \"dp\" (density-independent pixels) is a relative unit from Material Design\n\nSee [Elevation migration](/getting-started/elevation-migration) for details and tips to restore legacy MD2 levels if needed.\n\n## Themes\n\nThe default theme has been changed from **light** to **system**. This means that the default theme will now be the same as the user's system preference. You can change this by setting the **defaultTheme** theme option:\n\n```diff { resource=\"src/plugins/vuetify.ts\" }\nexport default createVuetify({\n+ theme: {\n+   defaultTheme: 'light',\n+ },\n})\n```\n\nTheme colors now support transparency. `rgb(var(--v-theme-color))` will continue to work the same as before, but `rgba(var(--v-theme-color), 0.8)` should be changed to either `color-mix(in srgb, rgb(var(--v-theme-color)) 80%, transparent)` or `rgb(from rgb(var(--v-theme-color)) / 0.8)` when used with a transparent theme color.\n\n## Components\n\n### VBtn display\n\nIn Vuetify 3, VField's layout was changed from `display: flex` to `display: grid` to better handle its internal elements. However, the grid implementation had limitations with gap control, so in Vuetify 4 we've reverted back to using `display: flex`.\n\nThe **$button-stacked-icon-margin** Sass variable has been removed and replaced with **$button-stacked-gap**. This change allows for more consistent and flexible spacing between elements within the field. If you modified this value, update its variable target:\n\n```diff { resource=\"styles/styles.scss\"}\n  @use 'vuetify/settings' with (\n-   $button-stacked-icon-margin: 8px,\n+   $button-stacked-gap,\n  );\n```\n\n### VBtn text-transform\n\nThe default `text-transform` of _uppercase_ has been **removed**. To restore the previous behavior, set the `text-transform` prop to `uppercase`.\n\n- Set it in the Sass variables for buttons:\n\n```scss\n@use 'vuetify/settings' with (\n  $button-text-transform: 'uppercase',\n)\n```\n\n- Set it as a global default:\n\n```js\nimport { createVuetify } from 'vuetify'\n\nconst vuetify = createVuetify({\n  defaults: {\n    VBtn: {\n      class: 'text-uppercase',\n      // or if you are using $utilities: false\n      style: 'text-transform: uppercase;',\n    },\n  },\n})\n```\n\n- Manually type uppercase letters:\n\n```diff\n- <v-btn>button</v-btn>\n+ <v-btn>BUTTON</v-btn>\n```\n\n### VBadge\n\nThe **$badge-dot-border-radius** Sass variable has been changed from `4.5px` to `50%`. Both values produce the same result for the default dot size. If your app increases dot size and prefer them square-ish, you might want to undo the change.\n\n```diff { resource=\"src/styles/settings/_variables.scss\" }\n@use 'vuetify/settings' with (\n-  $badge-dot-border-radius: 4.5px,\n+  $badge-dot-border-radius: 50%,\n);\n```\n\n### VContainer\n\nContainer component won't center the content vertically when paired with `fill-height`. If you depend on this behavior, you can supplement the missing styles with utility classes:\n\n```diff\n<v-container\n-  class=\"fill-height\"\n+  class=\"fill-height d-flex align-center flex-wrap\"\n/>\n```\n\n#### Max widths\n\nThe calculation for `$container-max-widths` has changed to round values down to the nearest 100px for more predictable sizing. With the default breakpoints, this results in the following container widths:\n\n| Breakpoint | Change              |\n|------------|---------------------|\n| md         | ~~900px~~  » 700px  |\n| lg         | ~~1200px~~ » 1000px |\n| xl         | ~~1800px~~ » 1400px |\n| xxl        | ~~2400px~~ » 2000px |\n\n### VCounter\n\nVCounter is used to display the counter hint under VTextField, VTextarea and VFieldInput. The **$counter-color** and `color` was replaced in favor of opacity. If you modified this value, move it to target CSS class directly:\n\n```scss { resource=\"styles/styles.scss\"}\n.v-counter {\n  opacity: 1;\n  color: /* your $counter-color */;\n}\n```\n\n### VFileInput\n\nRemoved the **$file-input-details-padding-inline** Sass variable.\n\n```diff { resource=\"src/styles/settings/_variables.scss\" }\n@use 'vuetify/settings' with (\n-  $file-input-details-padding-inline: <value>\n+  $input-details-padding-inline: <value>\n);\n```\n\n### VForm\n\nSlot variables are no longer refs, read-only values passed to slots are now unwrapped:\n\n```diff\n  <VForm>\n    <template #default=\"{ isValid, validate }\">\n      <VBtn @click=\"validate\" text=\"validate\" />\n-     Form is {{ isValid.value ? 'valid' : 'invalid' }}\n+     Form is {{ isValid ? 'valid' : 'invalid' }}\n    </template>\n  </VForm>\n```\n\nThe following properties are affected:\n\n- errors\n- isDisabled\n- isReadonly\n- isValidating\n- isValid\n- items\n\n### VRadioGroup\n\nRemoved the **$radio-group-details-padding-inline** Sass variable.\n\n```diff { resource=\"src/styles/settings/_variables.scss\" }\n@use 'vuetify/settings' with (\n-  $radio-group-details-padding-inline: <value>\n+  $input-details-padding-inline: <value>\n);\n```\n\n### VSelect/VCombobox/VAutocomplete\n\n`item` in slots has been renamed to `internalItem` for consistency with VList and VDataTable. `item` is still available but is now an alias for `internalItem.raw` which seems like the most common use case.\n\nYou can rename:\n\n```diff\n  <VSelect item-title=\"name\">\n-   <template #item=\"{ item, props }\">\n-     <VListItem v-bind=\"props\" :title=\"item.title\" />\n+   <template #item=\"{ internalItem, props }\">\n+     <VListItem v-bind=\"props\" :title=\"internalItem.title\" />\n    </template>\n  </VSelect>\n```\n\nOr alias:\n\n```diff\n  <VSelect>\n-   <template #item=\"{ item, props }\">\n+   <template #item=\"{ internalItem: item, props }\">\n      <VListItem v-bind=\"props\" :title=\"item.raw.name\" />\n    </template>\n  </VSelect>\n```\n\nOr remove `.raw`:\n\n```diff\n  <VSelect>\n    <template #item=\"{ item, props }\">\n-     <VListItem v-bind=\"props\" :title=\"item.raw.name\" />\n+     <VListItem v-bind=\"props\" :title=\"item.name\" />\n    </template>\n  </VSelect>\n```\n\n### VSnackbar\n\n::: warning\nThis component has its internal HTML structure overhauled to incorporate **header** and **prepend** slots\n:::\n\nRemoved the `multi-line` prop and the **$snackbar-multi-line-wrapper-min-height** Sass variable. It can be replaced with `min-height` equivalent.\n\n```diff\n  <VSnackbar\n    v-model=\"visible\"\n-    multi-line\n+    min-height=\"68\"\n    :text=\"message\"\n  />\n```\n\n### VSnackbarQueue\n\n::: warning\nThis component has been rewritten to enable showing multiple snackbars at once\n:::\n\nThe `default` slot has been renamed to `item`. The slot props remain the same.\n\n```diff\n<v-snackbar-queue v-model=\"messages\">\n-  <template v-slot:default=\"{ item }\">\n+  <template v-slot:item=\"{ item }\">\n    <v-snackbar v-bind=\"item\" />\n  </template>\n</v-snackbar-queue>\n```\n\n### VTextField\n\nRemoved the **$text-field-details-padding-inline** Sass variable.\n\n```diff { resource=\"src/styles/settings/_variables.scss\" }\n@use 'vuetify/settings' with (\n-  $text-field-details-padding-inline: <value>\n+  $input-details-padding-inline: <value>\n);\n```\n\n### Grid System (VRow and VCol)\n\nThe grid system has been refactored to use CSS `gap` instead of negative margins on rows and padding on columns. This change provides more flexibility and predictable spacing behavior.\n\n#### Layout mechanism changes\n\n| Previous                                                      | New                                    |\n|---------------------------------------------------------------|----------------------------------------|\n| Negative margins (`margin: -12px`)                            | No margins on VRow                     |\n| Gaps from padding                                             | No default padding, utilizes CSS `gap` |\n| Widths from hardcoded percentage (e.g., `75%` for `.v-col-9`) | Calculated width accounting for gaps   |\n\n#### Prop changes on VRow\n\n| Previous                         | New                                              |\n|----------------------------------|--------------------------------------------------|\n| `dense`                          | `density=\"compact\"` or `gap=\"8\"`             |\n| `align` prop on VRow             | use utility class (e.g., `align-start`)          |\n| `justify` prop on VRow           | use utility class (e.g., `justify-center`)       |\n| `align-content` prop on VRow     | use utility class (e.g., `align-content-center`) |\n| `align-sm`, `justify-md`, etc.   | use responsive utility classes                   |\n| no fine-grained control over gap | `gap` prop accepts number, string, or `[x, y]`   |\n\n#### Prop changes on VCol\n\n| Previous                                | New                                                 |\n|-----------------------------------------|-----------------------------------------------------|\n| `order` prop on VCol                    | use utility class (e.g., `order-1`)                 |\n| props like `order-sm`, `order-md`, etc. | use responsive utility classes (e.g., `order-sm-1`) |\n| `align-self` prop on VCol               | use utility class (e.g., `align-self-center`)       |\n| `.offset-{n}` (offset classes)          | `offset` prop                                       |\n\n<v-expansion-panels class=\"mb-4\" flat>\n<v-expansion-panel title=\"Migration examples\" bg-color=\"surface-variant-alt\">\n<v-expansion-panel-text>\n\n**Alignment (VRow):**\n\n```diff\n- <v-row align=\"center\" justify=\"space-between\">\n+ <v-row class=\"align-center justify-space-between\">\n```\n\n**Responsive alignment:**\n\n```diff\n- <v-row align-sm=\"start\" align-md=\"center\" justify-lg=\"end\">\n+ <v-row class=\"align-sm-start align-md-center justify-lg-end\">\n```\n\n**Order (VCol):**\n\n```diff\n- <v-col order=\"2\" order-md=\"1\">\n+ <v-col class=\"order-2 order-md-1\">\n```\n\n**Align self (VCol):**\n\n```diff\n- <v-col align-self=\"center\">\n+ <v-col class=\"align-self-center\">\n```\n\n**Dense rows:**\n\n```diff\n- <v-row dense>\n+ <v-row density=\"compact\">\n```\n\n</v-expansion-panel-text>\n</v-expansion-panel>\n</v-expansion-panels>\n\n#### Offset class changes\n\nOffset classes have been renamed from `.offset-*` to `.v-col-offset-*` for namespace consistency:\n\n```diff\n- <v-col offset=\"3\" offset-md=\"2\">\n+ <v-col offset=\"3\" offset-md=\"2\">  <!-- Props still work the same -->\n```\n\nThe component props (`offset`, `offset-sm`, etc.) continue to work unchanged, but if you were using the CSS classes directly, update them:\n\n```diff\n- <div class=\"v-col offset-6\">\n+ <div class=\"v-col v-col-offset-6\">\n```\n\n#### Sass variables cleanup\n\n`$form-grid-gutter` was replaced with `$grid-density`. New values subtract values from the default gutter\n\n```diff\n- $form-grid-gutter: $spacer * 2 !default;\n+ $grid-density: ('default': 0, 'comfortable': -1, 'compact': -2) !default;\n```\n\nSass variable `$grid-gutters` was removed. If your existing project had some custom definition set for this variable, you might want to adjust the variables below:\n\n```scss { resource=\"src/styles/settings/_variables.scss\" }\n@use 'vuetify/settings' with (\n  $avatar-margin-end: 8px;\n  $avatar-margin-start: 8px;\n\n  $icon-left-margin-left: 8px;\n  $icon-margin-end: 8px;\n  $icon-margin-start: 8px;\n\n  $icon-btn-margin-start: 8px;\n  $icon-btn-margin-end: 8px;\n}\n```\n\n#### Restoring the legacy grid behavior\n\nIf you need to maintain the previous grid behavior (negative margins and column padding), see the [Grid Legacy Mode](/getting-started/grid-legacy-mode) guide.\n\n## Defaults\n\n`undefined` values are now skipped when merging prop defaults. This button would have been grey in v3, but is now green:\n\n```jsx\ncreateVuetify({\n  defaults: {\n    VBtn: { color: 'green' },\n  },\n})\n\n<VDefaultsProvider :defaults=\"{ VBtn: { color: undefined }}\">\n  <VBtn />\n</VDefaultsProvider>\n```\n\nReplace `undefined` with `null` if you do actually want it to override the global default value.\n"
  },
  {
    "path": "packages/docs/src/pages/en/getting-started/wireframes.md",
    "content": "---\nmeta:\n  title: Wireframes\n  description: Select from a multitude of Vuetify Material Design layouts built to help kickstart your application.\n  keywords: pre-defined layouts, layouts, application layout, material design layouts\nrelated:\n  - /features/application-layout/\n  - /features/theme/\n  - /features/blueprints/\n---\n\n# Wireframes\n\nThe Vuetify **layout system** makes it easy to rapidly scaffold an application's UI regions with little effort.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## Examples\n\nThese templates are known as **wireframes** and are designed to provide a consistent approach to layouts, layering, and shadows. They are a starting point that is meant to be modified to meet the specific needs of your application.\n\n<GettingStartedWireframeExamples />\n\n::: info\n  Additional information on how these templates are structured is located on the [Application page](/features/application-layout/).\n:::\n"
  },
  {
    "path": "packages/docs/src/pages/en/index.md",
    "content": "---\nlayout: home\nmeta:\n  title: Vuetify — A Vue Component Framework\n  description: Vuetify is a no design skills required Open Source UI Component Framework for Vue. It provides you with all of the tools necessary to create beautiful content rich web applications.\n  keywords: vue, vue components, vue ui components, material design components, vuetify, component framework, component library\n---\n\n<HomeEntry />\n\n<HomeSpecialSponsor />\n\n<HomeGalleryComponents />\n\n<v-divider />\n\n<HomeSponsors />\n\n<v-divider />\n\n<HomeEcosystem />\n\n<v-divider  />\n\n<HomeVuetifyOne />\n\n<v-divider  />\n\n<HomeTooling />\n\n<v-divider />\n\n<HomeSnips />\n\n<v-divider />\n\n<HomeStore />\n\n<v-divider color=\"primary\" />\n\n<HomeSupport />\n\n<v-divider />\n\n<HomeDiscord />\n\n<v-divider />\n\n<HomeBlogs />\n"
  },
  {
    "path": "packages/docs/src/pages/en/introduction/enterprise-support.md",
    "content": "---\nfluid: true\nmeta:\n  nav: For Enterprise\n  title: Professional Support Services\n  description: Get the most out of your application with professional support services from the experts behind Vuetify.\n  keywords: vuetify enterprise, vuetify support, vuetify professional support, vuetify help\nrelated:\n  - /introduction/long-term-support/\n  - /about/security-disclosure/\n  - /about/meet-the-team/\n---\n\n# Professional Support Services\n\nGet the most out of your application with professional support services from the experts behind Vuetify.\n\n## Single Developer Support\n\nGet direct access to the Vuetify team through our private [Discord server](https://community.vuetifyjs.com/). Ask questions, get help, and chat with the team.\n\n<IntroductionDiscordDeck />\n\n<br>\n\n## Consulting Services\n\n[Epicmax](https://www.epicmax.co/?ref=vuetify) is a leading Vue.js development company and an official Vuetify partner. With over 8 years of experience and more than 60 successful projects, we help companies worldwide build, modernize, and scale applications using Vue.js and Vuetify.\n\n<IntroductionConsultingServices />\n\n<br>\n\n## Extended LTS support from HeroDevs\n\nStill using Vuetify 2 in your application? We've partnered with HeroDevs to provide extended support for Vuetify 2 users who require ongoing maintenance, security updates, and technical assistance. If your organization needs to remain on Vuetify 2 for the foreseeable future, this dedicated support ensures you can continue running your applications with confidence. Learn more about Vuetify 2 extended support options [here](https://v2.vuetifyjs.com/about/eol/).\n"
  },
  {
    "path": "packages/docs/src/pages/en/introduction/long-term-support.md",
    "content": "---\nmeta:\n  title: Long-term support\n  description: Vuetify provides long-term support to the last major release for 18 months for critical bugs and security vulnerabilities\n  keywords: lts, long-term support\nrelated:\n  - /introduction/enterprise-support/\n  - /getting-started/contributing/\n  - /about/meet-the-team/\n---\n\n# Long-term support\n\nVuetify provides long-term support to the last major release for 18 months for critical bugs and security vulnerabilities.\n\n<PageFeatures />\n\n<PromotedEntry />\n\nWe understand that many projects that utilize Vuetify have development cycles that prevent upgrading to the latest version. In order to provide developers and businesses peace of mind when adopting Vuetify, we commit to at minimum of **6 months** for critical bugs and security vulnerabilities for the latest _minor_ of the last _major_ release.\n\n| Version                                   | Status        | Initial Release Date | LTS Start Date  | LTS End Date       |\n|-------------------------------------------|---------------|----------------------|-----------------|--------------------|\n| [Vuetify 4.x](https://vuetifyjs.com/)     | 🚀 Active     | February 23rd, 2026  | N/A             | N/A                |\n| [Vuetify 3.x](https://v3.vuetifyjs.com/)  | 🔧 Maintained | November 1st, 2022   | TBA             | TBA                |\n| [Vuetify 2.7](https://v2.vuetifyjs.com/)  | 📦 Archived   | July 23rd, 2019      | July 5th, 2023  | January 23rd, 2025 |\n| [Vuetify 1.5](https://v15.vuetifyjs.com/) | 📦 Archived   | February 5th, 2019   | July 31st, 2019 | July 31st, 2020    |\n\nHave questions? Reach out to us in our [Discord community](https://community.vuetifyjs.com).\n"
  },
  {
    "path": "packages/docs/src/pages/en/introduction/roadmap.md",
    "content": "---\nmeta:\n  nav: Roadmap\n  title: The Vuetify roadmap\n  description: The upcoming planned features and new functionality coming to Vuetify. New components, new directives, and much much more!\n  keywords: vuetify roadmap, future plans, new vuetify features\nrelated:\n  - /introduction/long-term-support/\n  - /introduction/enterprise-support/\n  - /getting-started/browser-support/\n---\n\n# The Vuetify roadmap\n\nVuetify is always under development. We are constantly working towards improving the existing codebase, adding new features, and expanding the ecosystem with developer tooling that makes building applications even easier.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## 2025/2026 Roadmap\n\nThe following is a list of all planned components for the year 2025.\n\n### Versions\n\n| Version                                                                 | Planned Release |\n|-------------------------------------------------------------------------|-----------------|\n| [v4.0 (Revisionist)](https://github.com/vuetifyjs/vuetify/milestone/62) | Q1 2026         |\n| [v4.1](https://github.com/vuetifyjs/vuetify/milestone/77)               | TBD             |\n\n### New form components and features\n\n| Name                                                              | Entering Labs | Production Release |\n|-------------------------------------------------------------------|---------------|--------------------|\n| [validation rules](/features/rules)                               | *             | Q1 2026            |\n| [v-file-upload](/components/file-upload/)                         | *             | Q1 2026            |\n| [v-date-input](/components/date-inputs/)                          | *             | Q1 2026            |\n| [v-color-input](/components/color-inputs/)                        | *             | Q1 2026            |\n| [v-mask-input](/components/mask-inputs/)                          | *             | Q2 2026            |\n| [v-time-input](https://github.com/vuetifyjs/vuetify/pull/19709)   | Q1 2026       | Q3 2026            |\n| [v-month-picker](https://github.com/vuetifyjs/vuetify/pull/22534) | Q1 2026       | TBD                |\n| v-date-time-picker                                                | Q1 2026       | TBD                |\n| v-date-range-picker                                               | Q2 2026       | TBD                |\n| v-password-input                                                  | Q2 2026       | TBD                |\n| [v-editor](https://github.com/vuetifyjs/vuetify/pull/21653)       | TBD           | TBD                |\n\n\\* Already in Labs { .text-body-small }\n\n### Other components and features\n\n| Name                                                                 | Entering Labs | Production Release |\n|----------------------------------------------------------------------|---------------|--------------------|\n| [v-icon-btn](/components/icon-buttons/)                              | *             | Q1 2026            |\n| [v-video](/components/videos)                                        | *             | TBD                |\n| [v-pie](/components/pie-charts)                                      | *             | TBD                |\n| [v-command-palette](https://github.com/vuetifyjs/vuetify/pull/22403) | Q1 2026       | TBD                |\n| [v-avatar-group](https://github.com/vuetifyjs/vuetify/pull/22495)    | Q1 2026       | TBD                |\n| [v-heatmap](https://github.com/vuetifyjs/vuetify/pull/22535)         | Q2 2026       | TBD                |\n| v-split-btn                                                          | Q2 2026       | TBD                |\n| v-feature-discovery                                                  | TBD           | TBD                |\n| v-drag (directive)                                                   | TBD           | TBD                |\n| v-chat                                                               | TBD           | TBD                |\n\n\\* Already in Labs { .text-body-small }\n\n## Released\n\nThe following are the already released **minor** and **major** version updates. Find more information on the [latest releases](https://github.com/vuetifyjs/vuetify/releases/latest) on GitHub.\n\n### v4.0 (Revisionist)\n\n- **Released:** February 2026\n- **Target Release:** Q1 2026\n- **Notes:** [v4.0 Release](/getting-started/release-notes/?version=v4.0.0)\n- **Overview:**\n  - enables CSS layers and drops all `!important`\n  - elevation and typography aligned with MD3\n  - overhaul of Grid system and VSnackbarQueue\n  - reduced CSS reset - respecting browser defaults\n- **Milestone Issues:** [Github Issues](https://github.com/vuetifyjs/vuetify/milestone/62)\n\n### v3.12 (Warden)\n\n- **Released:** February 2026\n- **Target Release:** Q1 2026\n- **Notes:** [v3.12 Release](/getting-started/release-notes/?version=v3.12.0)\n- **Overview:**\n  - VSelect/VAutocomplete/VCombobox — new `menu-header` and `menu-footer` slots\n  - VDataTable — control over paging strategy with `page-by` prop\n  - `mdi-unocss` icon set\n  - Introduced 2 new components to the main framework from Labs:\n    - [v-command-palette](/components/command-palettes/)\n    - [v-avatar-group](/components/avatar-groups/)\n- **Milestone Issues:** [Github Issues](https://github.com/vuetifyjs/vuetify/milestone/86)\n\n### v3.11 (Harbinger)\n\n- **Released:** November 2025\n- **Target Release:** Q4 2025\n- **Notes:** [v3.11 Release](/getting-started/release-notes/?version=v3.11.0)\n- **Overview:**\n  - Introduced 2 new components to the main framework from Labs:\n    - [v-calendar](/components/calendars/)\n    - [v-hotkey](/components/hotkeys/)\n- **Milestone Issues:** [Github Issues](https://github.com/vuetifyjs/vuetify/milestone/82)\n\n### v3.10 (Argos)\n\n- **Released:** September 2025\n- **Target Release:** Q3 2025\n- **Notes:** [v3.10 Release](/getting-started/release-notes/?version=v3.10.0)\n- **Overview:**\n  - Now using `prefers-reduced-motion` to disable animations\n  - v2 compatible calendar implementation in Labs\n- **Milestone Issues:** [Github Issues](https://github.com/vuetifyjs/vuetify/milestone/80)\n\n### v3.9 (Zealot)\n\n- **Released:** July 2025\n- **Target Release:** Q2 2025\n- **Notes:** [v3.9 Release](/getting-started/release-notes/?version=v3.9.0)\n- **Overview:**\n  - New `StringDateAdapter`\n  - Automatic system theme and toggle methods\n  - Introduced 2 new components to the main framework from Labs:\n    - [v-treeview](/components/treeview/)\n    - [v-time-picker](/components/time-pickers/)\n- **Milestone Issues:** [Github Issues](https://github.com/vuetifyjs/vuetify/milestone/78)\n\n### v3.8 (Andromeda)\n\n- **Released:** March 2025\n- **Target Release:** Q4 2024\n- **Notes:** [v3.8 Release](/getting-started/release-notes/?version=v3.8.0)\n- **Overview:**\n  - Improved typescript support\n  - Introduced 2 new components to the main framework from Labs:\n    - [v-number-input](/components/number-inputs/)\n    - [v-snackbar-queue](/components/snackbar-queue/)\n- **Milestone Issues:** [Github Issues](https://github.com/vuetifyjs/vuetify/milestone/74)\n\n### v3.7 (Odyssey)\n\n- **Released:** August 2024\n- **Target Release:** Q3 2024\n- **Notes:** [v3.7 Release](/getting-started/release-notes/?version=v3.7.0)\n- **Overview:** Added more validation options and proper submenu support.\n- **Milestone Issues:** [Github Issues](https://github.com/vuetifyjs/vuetify/milestone/73)\n\n### v3.6 (Nebula)\n\n- **Released:** April 2024\n- **Hero:** [Banner](https://cdn.vuetifyjs.com/docs/images/release-banners/nebula-36.png)\n- **Target Release:** Q2 2024\n- **Notes:** [v3.6 Release](/getting-started/release-notes/?version=v3.6.0)\n- **Overview:** Introduced 5 new components to the main framework from Labs:\n  - [v-fab](/components/floating-action-buttons/)\n  - [v-empty-state](/components/empty-states/)\n  - [v-sparkline](/components/sparklines/)\n  - [v-speed-dial](/components/speed-dials/)\n  - [v-confirm-edit](/components/confirm-edit/)\n  - Multiple bug fixes and improvements.\n- **Milestone Issues:** [Github Issues](https://github.com/vuetifyjs/vuetify/milestone/72)\n\n### v3.5 (Polaris)\n\n- **Released:** January 2024\n- **Hero:** [Banner](https://cdn.vuetifyjs.com/docs/images/release-banners/polaris-35.png)\n- **Target Release:** Q1 2024\n- **Notes:** [v3.5 Release](/getting-started/release-notes/?version=v3.5.0)\n- **Overview:** A maintenance cycle post v3.4 that will focuses on bug fixes and general improvements.\n- **Milestone Issues:** [Github Issues](https://github.com/vuetifyjs/vuetify/milestone/70)\n\n### v3.4 (Blackguard)\n\n- **Released:** November 2023\n- **Hero:** [Banner](https://cdn.vuetifyjs.com/docs/images/release-banners/blackguard-34.png)\n- **Target Release:** Q3 2023\n- **Notes:** [v3.4 Release](/getting-started/release-notes/?version=v3.4.0)\n- **Overview:** Introduced 8 updated components to the main framework from Labs:\n  - [v-bottom-sheet](/components/bottom-sheets/)\n  - [v-data-iterator](/components/data-iterators/)\n  - [v-data-table](/components/data-tables/)\n  - [v-date-picker](/components/date-pickers/)\n  - [v-infinite-scroll](/components/infinite-scroller/)\n  - [v-opt-input](/components/otp-input/)\n  - [v-skeleton-loader](/components/skeleton-loaders/)\n  - [v-stepper](/components/steppers/).\n- **Milestone Issues:** [Github Issues](https://github.com/vuetifyjs/vuetify/milestone/61)\n\n### v3.3 (Icarus)\n\n- **Released:** May 2023\n- **Target Release:** Q2 2023\n- **Notes:** [v3.3 Release](/getting-started/release-notes/?version=v3.3.0)\n- **Overview:** A small intermediary minor that will release alongside Vue v3.3 and include a few small features.\n- **Milestone Issues:** [Github Issues](https://github.com/vuetifyjs/vuetify/milestone/67)\n\n### v3.2 (Orion)\n\n- **Released:** April 2023\n- **Target Release:** Q2 2023\n- **Notes:** [v3.2 Release](/getting-started/release-notes/?version=v3.2.0)\n- **Overview:** New and ported components from v2. Exposed defaults system for public use, allowing you to hook into the global default configuration with your components. More information in the [release notes](/getting-started/release-notes/?version=v3.2.0)\n- **Milestone Issues:** [Github Issues](https://github.com/vuetifyjs/vuetify/milestone/53)\n\n### v3.1 (Valkyrie)\n\n- **Released:** January 2023\n- **Target Release:** Q1 2023\n- **Notes:** [v3.1 Release](/getting-started/release-notes/?version=v3.1.0)\n- **Overview:** First post v3 release that will focus on porting remaining missing v2 components and general bug fixing.\n- **Milestone Issues:** [Github Issues](https://github.com/vuetifyjs/vuetify/milestone/56)\n\n### Vuetify Labs { id=\"labs\" }\n\n- **Released:** January 2023\n- **Target Release:** Q4 2022\n- **Overview:** Labs is a new package that includes large components from Vuetify 2 in a pre-production state. More information is located on the [Labs introduction](/labs/introduction/) page.\n\n### v3.0 (Titan)\n\n- **Released:** October 2022\n- **Notes:** [v3.0 Release](/getting-started/release-notes/?version=v3.0.0)\n- **Overview:**\n  - Rebuilt for Vue 3 using the new [composition api](https://vue-composition-api-rfc.netlify.com/)\n  - Global properties that allow you to make large overarching changes to your app\n  - Improved SASS variable customization and extensibility with [Built-In Modules](https://sass-lang.com/documentation/modules)\n  - New [Vue CLI presets](https://github.com/vuetifyjs/vue-cli-plugins) for generating pre-built starting projects\n  - First party [Vite](https://vitejs.dev/) support for lightning fast development\n  - Greatly improved TypeScript support\n  - Better framework coverage with E2E testing using Cypress\n\n----\n\n## Contributing\n\nIf you'd like to help contribute to Vuetify, head to our [Contribution guide](/getting-started/contributing/) for more information on how to get started.\n\n## Archived\n\nThe following releases are old and unsupported **minor** and **major** versions:\n\n### v2.7 (Nirvana)\n\n- **Released:** July 2023\n- **Target Release:** Q2 2023\n- **Notes:** [v2.7 Release](/getting-started/release-notes/?version=v2.7.0)\n- **LTS Support until:** January 2025\n- **Milestone Issues:** [Github Issues](https://github.com/vuetifyjs/vuetify/milestone/59)\n\n### v2.6 (Horizon)\n\n- **Released**: November 2021\n- **Notes**: [v2.6 Release](/getting-started/release-notes/?version=v2.6.0)\n- **Overview**:\n  New [v-otp-input](/components/otp-input/) component, calendar event and scrolling improvements, minor features for other components.\n\n### v2.5 (Avalon)\n\n- **Released:** May 2021\n- **Notes:** [v2.5 Release](/getting-started/release-notes/?version=v2.5.0)\n- **Overview:**\n  The v2.5 release adds a multitude of new functionality to [v-data-table](/components/data-tables/) and [v-text-field](/components/text-fields/), as well as bug fixes for the [click-outside](/directives/click-outside/) directive, [v-carousel](/components/carousels/) component, and more.\n- **Objectives:**\n  - Expand functionality of `v-data-table`\n  - Quality of life improvements\n  - General bug fixes\n\n### v2.4 (Endurance)\n\n- **Released:** December 2020\n- **Notes:** [v2.4 Release](/getting-started/release-notes/?version=v2.4.0)\n- **Overview:**\n  The v2.4 release provides bug fixes, features and quality of life changes for Vuetify as we prepare for v3 Alpha. This release contains some new features that we are building into Vuetify 3 right now such as new slots for `v-carousel` and support for globally defined icon components.\n- **Objectives:**\n  - Add **plain** property for `v-btn`\n  - Add new locales\n    - Azerbaijani\n    - Central Kurdish\n  - Add typography css classes `text-pre` and `text-pre-wrap`\n  - Add new slots for `v-carousel`\n  - Support for a globally defined icon components\n  - Improved accessibility in the `v-menu` component\n\n### v2.3 (Liberator)\n\n- **Released:** June 2020\n- **Notes:** [v2.3 Release](/getting-started/release-notes/?version=v2.3.0)\n- **Overview:**\n  The v2.3 release was dropped earlier in the year to focus on v3 development but was revived when COVID-19 showed up. This release is packed full of quality of life changes, new features such as the `v-virtual-scroll` component, responsive typography css classes.\n- **Objectives:**\n  - Add new css helper classes for `text-decoration`, `border-radius`, `typography`, and more.\n  - Add new `v-virtual-scroll` component\n  - Improve *Date Pickers, Data Tables, and Calendars*\n  - Harden framework in preparation for **LTS version**\n\n### v2.2 (Tigris)\n\n- **Released:** January 2020\n- **Notes:** [v2.2 Release](/getting-started/release-notes/?version=v2.2.0)\n- **Overview:**\n  The introduction of Vuetify Presets. Will include the entire Material Design Studies collection and be *user customizable*. Will streamline the process for altering the default styles for the framework. Thousands of SASS variables will be added and a lookup tree for finding those variables will put into the documentation. For more information on Google's studies, please [navigate here](https://material.io/design/material-studies/about-our-material-studies.html).\n- **Objectives:**\n  - Add *thousands* of new SASS variables\n  - Create a new Vuetify Service for bootstrapping pre-configured framework options; **Preset**\n  - Create presets for the official [Material Design Studies](https://material.io/design/material-studies/about-our-material-studies.html)\n  - Add new features and improve code styling of `v-badge`\n  - Add new features and improve code styling of `v-expansion-panels`\n  - new `v-theme-provider` component\n\n### v2.1 (Vanguard)\n\n- **Released:** October 2019\n- **Notes:** [v2.1 Release](/getting-started/release-notes/?version=v2.1.0)\n- **Overview:**\n  A maintenance cycle to work on bugs from the v2.0 release. This includes performance issues, incorrect or missing a11y, RTL, regressions and general fixes. This will allow the team to catch up on the backlog of tasks that have accumulated over the 8 month development cycle of the previous release.\n- **Objectives:**\n  - Add new components\n    - `v-lazy`\n    - `v-skeleton-loader`\n  - Add new directives\n    - `v-intersect`\n    - `v-mutate`\n  - Add lazy loading support for `v-img`\n\n### v2.0 (Arcadia)\n\n- **Released:** July 2019\n- **Notes:** [v2.0 Release](/getting-started/release-notes/?version=v2.0.0)\n- **Overview:**\n  A complete rebuild of the framework core. Improving the layout and theme systems, platform integration, accessibility, RTL and performance. Update all components to the [Material Design 2](https://material.io/design/) specification. Add additional functionality to multiple existing components and setup v1.5 for [Long-term Support](/introduction/long-term-support).\n- **Objectives:**\n  - Add new components\n    - `v-app-bar`\n    - `v-banner`\n    - `v-chip-group`\n    - `v-color-picker`\n    - `v-file-input`\n    - `v-list-item-group`\n    - `v-overlay`\n    - `v-simple-table`\n    - `v-slide-group`\n  - Complete update to Material Design 2\n  - Convert from Javascript to Typescript\n  - Convert from Stylus to Sass\n  - Convert from avoriaz to vue-test-utils\n\n### v1.5\n\n- **Released:** February 2019\n- **Support until:** August 1st, 2020\n- **Notes:** [v1.5 Release](/getting-started/release-notes/?version=v1.5.0)\n- **Overview:**\n  Added new component, `v-calendar`. Improved functionality of `v-sparkline` with new **bar** and **fill** properties. Improved `v-treeview` and prepared for LTS. Navigate to the [Long-term Support Page](/introduction/long-term-support) for more information on LTS.\n\n::: error\n  v1.5 reached end of life on **July 31st, 2020** and is no longer actively maintained. It is recommended to update to the latest stable version of Vuetify using our [Upgrade guide](/getting-started/upgrade-guide/).\n:::\n\n### v1.4\n\n- **Released:** December 2018\n- **Notes:** [v1.4 Release](/getting-started/release-notes/?version=v1.4.0)\n- **Overview:**\n  Added new components `v-sparkline` and abstracted `v-toolbar`'s functionality into multiple components for easier maintainability and testing. Rebuilt the entire documentation to make it easier for contributors and maintenance from the team.\n\n----\n\n### v1.3\n\n- **Released:** December 2018\n- **Notes:** [v1.3 Release](/getting-started/release-notes/?version=v1.3.0)\n- **Overview:**\n  Added new components, `v-treeview`, `v-timeline` and `v-item-group`. Unified the interfaces used in `v-tabs` and `v-carousel`. Improved the **vuetify-loader** to support effortless application tree-shaking of Vuetify components.\n\n----\n\n### v1.2\n\n- **Released:** October 2018\n- **Notes:** [v1.2 Release](/getting-started/release-notes/?version=v1.2.0)\n- **Overview:**\n  Added new components, `v-img`, `v-rating` and `v-hover`. Improved theme propagation system and expanded the functionality of the colors used with components such as HEX and RGBA. Als added numerous new locales.\n\n----\n\n### v1.1\n\n- **Released:** July 2018\n- **Notes:** [v1.1 Release](/getting-started/release-notes/?version=v1.1.0)\n- **Overview:**\n  A complete rebuild of all form functionality including all inputs and selection controls. Abstracted features from components like `v-select` into new implementations, `v-autocomplete`, `v-combobox` for more scoped functionality and easier testing. This release also marked the first official support of **RTL** languages.\n\n----\n\n### v1.0\n\n- **Released:** February 2018\n- **Notes:** [v1.0 Release](/getting-started/release-notes/?version=v1.0.0)\n- **Overview:**\n  The official v1.0 release party. After 18 months and Kael's sanity, we rolled into our first **MAJOR** release. This included a multitude of brand new components, features and functionality.\n\n----\n\n### Alpha release\n\n- **Released:** December 2016\n- **Overview:**\n  Vuetify is officially announced to the public. The framework initially shipped with 40 components and came in at a whopping 46kb.\n"
  },
  {
    "path": "packages/docs/src/pages/en/introduction/sponsors-and-backers.md",
    "content": "---\nmeta:\n  nav: Sponsors and backers\n  title: Sponsoring Vuetify\n  description: Help support Vuetify by backing the project. This helps with the maintenance of existing features and the development of new ones.\n  keywords: sponsor, backer, donations, patron, supporting vuetify, vuetify support\nrelated:\n  - /introduction/enterprise-support/\n  - /introduction/roadmap/\n  - /about/meet-the-team/\n---\n\n# Sponsor Vuetify development\n\nVuetify is an [MIT licensed](https://github.com/vuetifyjs/vuetify/blob/master/LICENSE.md) open-source project that's completely free to use.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## Preamble\n\nVuetify is actively maintained by a dedicated team of open-source contributors who help guide the future of the framework. The time and dedication it takes to maintain the core framework and ecosystem packages is substantial. You can support Vuetify’s open-source project by becoming a backer through one of the following methods:\n\n## One-time donations\n\nOne-time donations can be made through [PayPal](https://paypal.me/vuetify).\n\n## Recurring Pledges\n\nRecurring pledges come with **exclusive** perks such as priority GitHub issues, application auditing, and having your logo placed on this website.\n\n- [Become a backer or sponsor via GitHub](https://github.com/sponsors/johnleider).\n- [Become a backer or sponsor through Open Collective](https://opencollective.com/vuetify) (a transparent fund for supporting the development and maintenance of Vuetify).\n\n## Current Project Sponsors\n\nWe thank all of our project sponsors for their continued support of Vuetify. If you have any questions about sponsorship, please reach out to [sponsor@vuetifyjs.com](mailto:sponsor@vuetifyjs.com) for more information.\n\n### Special\n\nThank you to our special sponsor. Your support is greatly appreciated.\n\n<SponsorSponsors tier=\"-2\" width=\"240\" />\n\n<br>\n\n### Diamond\n\nThese sponsors have pledged $1,500 per month.\n\n<SponsorSponsors tier=\"1\" />\n\n<br>\n\n### Platinum\n\nThese sponsors have pledged $500 per month.\n\n<SponsorSponsors tier=\"2\" />\n\n<br>\n\n### Gold\n\nThese sponsors have pledged $250 per month.\n\n<SponsorSponsors tier=\"3\" />\n\n<br>\n\n### Service\n\nThese sponsors help keep the lights on by providing free services to the Vuetify project.\n\n<SponsorSponsors tier=\"6\" />\n\n<br>\n\n### Affiliate\n\nWe work with these companies to provide you with the best possible experience.\n\n<SponsorSponsors tier=\"5\" />\n\n<br>\n\n## Bottom line\n\nIf you run a business and are using Vuetify in a revenue-generating product, it makes business sense to sponsor Vuetify development: *it ensures the project that your product relies on stays healthy and actively maintained*. Your sponsorship and contributions help support the ongoing development and maintenance of Vuetify.\n\nIf you have any questions, please reach out to [sponsor@vuetifyjs.com](mailto:sponsor@vuetifyjs.com).\n"
  },
  {
    "path": "packages/docs/src/pages/en/introduction/why-vuetify.md",
    "content": "---\nmeta:\n  nav: Why Vuetify?\n  title: Why Vuetify?\n  description: Vuetify has an extremely active community, provides easy to use Material Design components and is consistently updated.\n  keywords: why vuetify, best vue framework, best ui framework, best component framework, best ui library, best component library\nrelated:\n  - /getting-started/installation/\n  - /introduction/roadmap/\n  - /introduction/enterprise-support/\n---\n\n# Introduction\n\nLearn more about what Vuetify is, how to create an application from scratch, browse API references, sample code, tutorials, and more.\n\n<PageFeatures />\n\n<PromotedEntry slug=\"vuetify-snips\" />\n\n## What is Vuetify?\n\nSince its initial release in 2014, [Vue.js](https://vuejs.org/) has grown to be among the most popular JavaScript frameworks in the world. One of the reasons for this popularity is the wide use of [components](https://vuejs.org/guide/essentials/component-basics.html) which enable developers to create small modules to be used and re-used throughout an application. Vuetify is a collection of pre-made components paired with powerful features such [dynamic themes](/features/theme/), [global defaults](/features/global-configuration/), [application layouts](/features/application-layout/), and more. Its goal is to provide developers with all of the necessary tools to build rich and engaging user experiences.\n\n* [Why you should use it](#why-vuetify)\n* [Features at a glance](#feature-guides)\n\n## Getting started\n\nThe fastest way to try Vuetify is in the browser at [Vuetify Play](https://play.vuetifyjs.com/). For a complete list of installation options please navigate to the [Installation page](/getting-started/installation/).\n\n## Why Vuetify? { id=\"why-vuetify\" }\n\nVuetify is a powerful Vue Component Framework built from the ground up to be easy to learn and rewarding to master. Our collection of UI components maintain a consistent style throughout your application with enough customization options to meet any use-case.\n\n### It's free { id=\"its-free\" }\n\nVuetify is an Open Source project available for free under the [MIT licensed](https://opensource.org/licenses/MIT). Additionally, Vuetify's source code is available on GitHub, allowing developers to modify and contribute to its development if they choose to do so.\n\n### Flexible components\n\nEvery component in Vuetify is handcrafted under the guise of Google's [Material Design specification](https://material.io/) and comes with hundreds of customization options that fit any style or design; even if it's not Material. Write Vue templates that are as concise or verbose as you want using exclusively or in combination, **props**, **slots**, and **components**.\n\n### Tooling\n\nVuetify has a large ecosystem of supporting tools that enrich the development experience that range from project creation to design UI kits.\n\n* 🎨 [Figma UI Component Kit](https://store.vuetifyjs.com/products/vuetify-ui-kit-figma)\n* ⚡ [First-party Vite support](https://github.com/vuetifyjs/vuetify-loader/tree/master/packages/vite-plugin)\n* 🏗️ [Pre-configured Vue 3 applications for TypeScript and JavaScript](https://tryvuetify.com)\n* ⌨️ Intellisense & autocomplete support for [VSCode](https://code.visualstudio.com/docs/editor/intellisense) and [JetBrains](https://www.jetbrains.com/help/rider/Auto-Completing_Code.html) products\n* 🖼️ [Wireframe examples](/getting-started/wireframes/)\n\n### Community\n\nWhen you develop with Vuetify, you are never alone. Stuck on a problem? Take advantage of our massive [Discord community](https://community.vuetifyjs.com/) and collaborate with other Vuetify developers in one of our public help channels. Need a more personalized support solution? Vuetify offers [Enterprise support](/introduction/enterprise-support/) with options tailored to individuals and businesses. Check out some other ways to [Sponsor Vuetify development](/introduction/sponsors-and-backers/).\n\n<PromotedPromoted slug=\"vuetify-discord\" />\n\n### Professional and Enterprise support\n\nVuetify offers an array of support services designed to help you get the most out of your application. Let our experience team provide you with the tools that you need to succeed with:\n\n* ↗️ Vuetify version upgrades\n* 📊 Performance review & analysis\n* ⛑️ SLA & direct support\n\nFor more information regarding our professional support options, navigate to our [Enterprise support](/introduction/enterprise-support/) page.\n\n### Active development\n\nVuetify has been in active development since 2016 and is constantly responding to community issues and reports at breakneck speed, allowing you to get your hands on bug fixes and enhancements more often. Our overall release cadence typically follows:\n\n* 🔨 PATCH **(Weekly)**\n* ⛏️ MINOR **(Quarterly)**\n* ⚒️ MAJOR **(Bi-yearly to Yearly)**\n\nIn addition, after every MAJOR release, the previous version is still maintained with 18 months of [Long-term support](/introduction/long-term-support/).\n\nSo what are you waiting for? Head over to the [Installation](/getting-started/installation/) page and start building your next great idea today.\n\n## Feature Guides\n\nLearn more about the inner workings of Vuetify and become a skilled **v-developer** with our detailed feature guides. Each guide is designed to teach you how to get the most out of your development experience with information on: how to build responsive pages using [Layouts](/features/application-layout/), how to customize the style of your application with [SASS variables](/features/sass-variables/), and how to slim down your application's package size via [Treeshaking](/features/treeshaking/), and more.\n\n| Feature | Skill level | Time to read |\n| ------- | ----------- | ------------ |\n| [Bidirectionality (LTR/RTL)](/features/internationalization/) | Beginner | 1 min |\n| [Global configuration](/features/global-configuration/) | Beginner | 1 min |\n| [Icon Fonts](/features/icon-fonts/) | Beginner | 15 min |\n| [Layouts](/features/application-layout/) | Beginner | 5 min |\n| [Theme](/features/theme/) | Beginner | 15 min |\n| [Accessibility (a11y)](/features/accessibility) | Intermediate | 10 min |\n| [Aliasing](/features/aliasing/) | Intermediate | 5 min |\n| [Application layout](/features/application-layout/) | Intermediate | 15 min |\n| [Dates](/features/dates/) | Intermediate | 10 min |\n| [Display & Platform](/features/display-and-platform/) | Intermediate | 15 min |\n| [Internationalization (i18n)](/features/internationalization/) | Intermediate | 5 min |\n| [SASS variables](/features/sass-variables/) | Intermediate | 10 min |\n| [Blueprints](/features/blueprints/) | Advanced | 10 min |\n| [Treeshaking](/features/treeshaking/) | Advanced | 15 min |\n| [Hotkeys](/features/hotkey/) | Advanced | 10 min |\n\nCan't find what you're looking for? Help us improve! Please reach out to [hello@vuetifyjs.com](mailto:hello@vuetifyjs.com) with your feedback or join us in the Vuetify [Discord community](https://community.vuetifyjs.com/).\n"
  },
  {
    "path": "packages/docs/src/pages/en/labs/introduction.md",
    "content": "---\nmeta:\n  nav: Introduction\n  title: Introduction to Labs\n  description: A collection of in-development components for testing purposes before final release\n  keywords: labs\nrelated:\n  - /getting-started/installation/\n  - /getting-started/browser-support/\n  - /introduction/sponsors-and-backers/\n---\n\n# Vuetify Labs\n\nExperiment and use in-development components before they're released.\n\n<PageFeatures />\n\n## What is Labs? { id=what-is-labs }\n\nLabs is a new way for developers to use unfinished components in an alpha state.\n\n::: error\nComponents available through Labs are considered **NOT** production ready and only to be used for testing purposes. Breaking changes will be introduced in patch releases and no support will be provided.\n:::\n\n## Usage\n\nUsing a Labs component is as simple as importing from `vuetify/labs`. The following example shows how to import and bootstrap `v-picker` in your component:\n\n```html\n<template>\n  <v-picker />\n</template>\n\n<script setup>\n  import { VPicker } from 'vuetify/labs/VPicker'\n</script>\n```\n\nAlternatively you can make the component available globally by importing it in your Vuetify plugin file:\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createVuetify } from 'vuetify'\nimport { VPicker } from 'vuetify/labs/VPicker'\n\nexport default createVuetify({\n  components: {\n    VPicker,\n  },\n})\n```\n\nWhen Vuetify instantiates it will register `VPicker` as a usable component within templates.\n\nIf you wish to install all available Vuetify components use the following code snippet:\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createVuetify } from 'vuetify'\nimport * as components from 'vuetify/components'\nimport * as labsComponents from 'vuetify/labs/components'\n\nexport default createVuetify({\n  components: {\n    ...components,\n    ...labsComponents,\n  },\n})\n```\n\n<PromotedEntry />\n\n## Available Components\n\nThe following is a list of available and up-and-coming components for use with Labs:\n\n| Component                                            | Description                                                | Min Version                                                |\n|------------------------------------------------------|------------------------------------------------------------|------------------------------------------------------------|\n| [v-color-input](/components/color-inputs/)           | A color input component                                    | [vTBD](/getting-started/release-notes/?version=vTBD)       |\n| [v-date-input](/components/date-inputs/)             | A date input component                                     | [v3.6.0](/getting-started/release-notes/?version=v3.6.0)   |\n| [v-pull-to-refresh](/components/pull-to-refresh/)    | A component to update content by screen swipes             | [v3.6.0](/getting-started/release-notes/?version=v3.6.0)   |\n| [v-stepper-vertical](/components/vertical-steppers/) | Vertical version of v-stepper                              | [v3.6.5](/getting-started/release-notes/?version=v3.6.5)   |\n| [v-video](/components/videos/)                       | A customizable wrapper for native video element            | [v3.9.3](/getting-started/release-notes/?version=v3.9.3)   |\n| [v-pie](/components/pie-charts/)                     | A component to display data as interactive pie/donut chart | [v3.9.3](/getting-started/release-notes/?version=v3.9.3)   |\n| [v-avatar-group](/components/avatar-groups/)         | A component to group and display multiple avatars          | [v3.12.0](/getting-started/release-notes/?version=v3.12.0) |\n| [v-command-palette](/components/command-palettes/)   | A searchable command palette component                     | [v3.12.0](/getting-started/release-notes/?version=v3.12.0) |\n\n::: warning\nLab component APIs are **NOT** finalized and can and will change. You should **EXPECT** for things to break during the course of development.\n:::\n"
  },
  {
    "path": "packages/docs/src/pages/en/one.md",
    "content": "---\nlayout: home\nmeta:\n  nav: One\n  title: Vuetify One\n  description: Subscribe to Vuetify One and power the future of Vuetify while getting premium tools and features\n  keywords: vuetify one, vuetify subscription, support vuetify, vuetify sponsors, vuetify backers, vuetify premium\n---\n\n<div class=\"text-start\">\n<OneHero />\n\n<OneSubscribeCard />\n\n<OneProperties />\n\n<OneRoadmap />\n\n<OneFAQ />\n</div>\n"
  },
  {
    "path": "packages/docs/src/pages/en/resources/brand-kit.md",
    "content": "---\nfluid: true\nmeta:\n  nav: Brand Kit\n  title: Brand Kit & Assets\n  description: Get access to the Vuetify logo and other brand assets\n  keywords: vuetify logo, vuetify assets, vuetify media kit, vuetify brand kit\nrelated:\n  - /getting-started/installation/\n  - /features/blueprints/\n  - /about/meet-the-team/\n---\n\n# Brand Kit\n\nExplore the Vuetify Brand Kit, your source for official logos and branding assets.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## Vuetify Logo\n\nThe Vuetify logo encapsulates the essence of modern web development, combining sleek design with Vue.js principles. Its symmetrical lines and bold color palette reflect the framework's commitment to efficiency, flexibility, and elegance, resonating with developers and designers alike.\n\n<ResourcesLogos />\n\n## Color Palette\n\nThe Vuetify logo color palette is comprised of 4 colors, each used for a different shape. The colors are designed to work together harmoniously, creating a unified and balanced look.\n\n<ResourcesColorPalette />\n\n<br>\n\n::: success\n\nNeed something not on this page? Reach out to us at [hello@vuetifyjs.com](mailto:hello@vuetifyjs.com) and we'll be happy to help.\n\n:::\n"
  },
  {
    "path": "packages/docs/src/pages/en/resources/jobs-for-vue.md",
    "content": "---\nfluid: true\nmeta:\n  nav: Jobs\n  title: Vue & Vuetify jobs\n  description: Vue.js & Vuetify jobs for developers and businesses. Apply to Software Engineer, Full Stack Developer, Senior Software Engineer and more!\n  keywords: Vue.js Jobs, Vue.js careers, Vue.js job search, work in Vue.js, Vuetify jobs for Vue\nrelated:\n  - /introduction/why-vuetify/\n  - /introduction/enterprise-support/\n---\n\n# Vue and Vuetify jobs\n\nFind top Vue.js developers, ready to join your team; or browse available openings and land your next job!\n\n<PageFeatures />\n\n<PromotedPromoted slug=\"enterprise-support\" />\n\n<DocVueJobs />\n"
  },
  {
    "path": "packages/docs/src/pages/en/resources/made-with-vuetify.md",
    "content": "---\nbackmatter: false\nfluid: true\nmeta:\n  nav: Made with Vuetify\n  title: Made with Vuetify\n  description: Check out these amazing projects built using Vuetify.\n  keywords: made with vuetify, vuetify projects, vuetify apps, vuetify plugins, vuetify themes\nrelated:\n  - /getting-started/installation/\n  - /resources/themes/\n  - /resources/ui-kits/\n---\n\n# Made with Vuetify\n\nCheck out these amazing projects built using Vuetify.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n<DocMadeWithVuetifyGallery pagination />\n\n<br />\n\n<DocMadeWithVueAttribution />\n"
  },
  {
    "path": "packages/docs/src/pages/en/resources/search-engine.md",
    "content": "---\nmeta:\n  title: Search Engine\n  description: Add Vuetify as a search engine to your Chrome browser for quick access to the documentation\n  keywords: search engine, vuetify search engine, vuetify chrome search engine, vuetify chrome extension\nrelated:\n  - /getting-started/installation/\n  - /introduction/why-vuetify/\n---\n\n# Search engine\n\nAdd Vuetify as a browser search engine for quick access to the documentation.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## Setup\n\nThe Vuetify documentation supports being a search engine for your browser. This allows you to query directly from the url bar without having to navigate to the site first. To add Vuetify as a search engine, follow the steps below:\n\n### For Chrome\n\n1. Open Chrome settings\n  ![image](https://github.com/vuetifyjs/vuetify/assets/9064066/3b83a0a1-a51d-4c88-bf1b-0200a1f6b532)\n2. Search for \"Manage search engines and site search\"\n  ![search](https://github.com/vuetifyjs/vuetify/assets/9064066/8fd8f1e4-ebed-4c8a-9444-16163c580a60)\n3. Scroll down to \"Site search\" and click the <v-kbd>Add</v-kbd> button to add a new search engine\n  ![image](https://github.com/vuetifyjs/vuetify/assets/9064066/87d7775f-0f92-4f12-b9dd-01195f80df31)\n4. Enter the following information into the \"Add search engine\" dialog:\n\n* Search engine: `Vuetify` { .ms-4 }\n* Shortcut: `vt` (or whatever you prefer) { .ms-4 }\n* URL with %s in place of query: `https://vuetifyjs.com/?search=%s` { .ms-4 }\n\n5. Hit the <v-kbd>Add</v-kbd> button to save the search engine\n6. Open your browster and type `vt` into the url bar followed by a space or tab:\n  ![image](https://github.com/vuetifyjs/vuetify/assets/9064066/07869a65-bcc4-44c2-a900-3f69eea1be4b)\n7. Type your search query and hit enter to search the Vuetify documentation\n  ![image](https://github.com/vuetifyjs/vuetify/assets/9064066/e91092f4-f308-4ed4-9b4a-33ac189aec19)\n\n### For Edge\n\n1. Open Edge Settings\n  ![step1](https://github.com/vuetifyjs/vuetify/assets/9064066/696182cf-5eab-4229-a007-5521186f8058)\n2. Search for \"Address bar and search\"\n  ![edge-search](https://github.com/vuetifyjs/vuetify/assets/9064066/9b9487c3-34d6-44b4-81e2-45ba30da2977)\n3. Click the <v-kbd>Add</v-kbd> button to add a new search engine\n  ![step2](https://github.com/vuetifyjs/vuetify/assets/9064066/eb50602a-bb6d-4933-92cd-e4f0edbc8a86)\n4. Entry the following information into the \"Add search engine\" dialog:\n\n* Search engine: `Vuetify` { .ms-4 }\n* Shortcut: `vt` (or whatever you prefer) { .ms-4 }\n* URL with %s in place of query: `https://vuetifyjs.com/?search=%s` { .ms-4 }\n\n![add search engine](https://github.com/vuetifyjs/vuetify/assets/9064066/8b31e827-5b16-4ba8-b220-bcbe139986ff)\n\n5. Hit the <v-kbd>Add</v-kbd> button to save the search engine\n6. Open your browster and type `vt` into the url bar followed by a space or tab:\n  ![search bar](https://github.com/vuetifyjs/vuetify/assets/9064066/59311829-e564-4c80-a0c9-d33e7aacfd21)\n7. Type your search query and hit enter to search the Vuetify documentation\n  ![step5](https://github.com/vuetifyjs/vuetify/assets/9064066/8245afd9-bceb-41dd-8310-50e4137d1fca)\n\n### For Firefox\n\nVuetify documentation website includes `/search.xml` with OpenSearch description that allows Firefox users to [add a custom search engine](https://support.mozilla.org/en-US/kb/add-or-remove-search-engine-firefox#w_add-a-search-engine-from-the-search-bar). If you don't see an option in the address bar you might need to restore dedicated search field (it can be hidden afterwards).\n\n**Note**: when using browser based on Firefox (like Zen or Waterfox) please check the settings page first as they might include <v-kbd>Add</v-kbd> button under the list of enabled search engines. When present, you can follow regular instructions for Chrome.\n"
  },
  {
    "path": "packages/docs/src/pages/en/resources/themes.md",
    "content": "---\nmeta:\n  nav: Themes\n  title: Free & Premium Vuetify themes\n  description: Vuetify offers numerous pre-build starter and premium themes. Kickstart your next application today, no design skills needed.\n  keywords: vuetify themes, pre-built material themes, premium themes\nrelated:\n  - /getting-started/installation/\n  - /features/blueprints/\n  - /features/theme/\n---\n\n<script setup>\n  import { onMounted } from 'vue'\n  import { useShopifyStore } from '@/stores/shopify'\n\n  const store = useShopifyStore()\n\n  onMounted(() => {\n    store.fetch()\n  })\n</script>\n\n# Vuetify Themes\n\nVuetify offers both **free** and **premium** pre-made themes designed to get you started in a flash. Free themes are available to install through Vue CLI or you can simply download the source.\n\n<PageFeatures />\n\n---\n\n## Vuetify\n\nThe following themes are created and maintained by Vuetify. They are available for free through the Vuetify store.\n\n<DocThemeVendor name=\"Vuetify\" />\n\n---\n\n<br>\n\n## UI Lib\n\nUI Lib is a collection of free and premium themes built on top of Vuetify.\n\n<DocThemeVendor name=\"UI Lib\" />\n\n---\n\n<br>\n\n## WrapPixel\n\nCreate web apps and products using WrapPixel's product ready Vue Admin Templates, UI Kits, Themes, Templates and Dashboards.\n\n<DocThemeVendor name=\"WrapPixel\" />\n\n---\n\n<br>\n\n## Theme Selection\n\nTheme Selection offers an array of visually appealing, user-friendly UI kits and themes. Catering to a variety of platforms, they deliver efficient design solutions for a streamlined digital experience.\n\n<DocThemeVendor name=\"ThemeSelection\" />\n\n<br>\n\n## CodedThemes\n\nCraft powerful web applications and products effortlessly with CodedThemes. Explore our ready-to-use Vue Admin Templates, UI Kits, Themes, and Dashboards to streamline your development process and enhance your digital projects.\n\n<DocThemeVendor name=\"CodedThemes\" />\n\n<br>\n\n::: success\n\nWant to feature your themes here? [Contact us!](mailto:hello@vuetifyjs.com?subject=Theme+affiliation) to learn more about becoming a vendor.\n\n:::\n"
  },
  {
    "path": "packages/docs/src/pages/en/resources/ui-kits.md",
    "content": "---\nmeta:\n  title: UI Kits\n  description: Vuetify offers numerous pre-built component kits for both Figma and Adobe Xd. Kickstart your next application today.\n  keywords: vuetify ui kit, vuetify ui, ui kits, ui kit figma, ui kit adobe xd\nrelated:\n  - /getting-started/wireframes/\n  - /features/theme/\n  - /getting-started/installation/\n---\n\n# Vuetify UI Kits\n\nEasily create design prototypes with Figma components that match Vuetify's.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n----\n\n## Usage\n\nThe Vuetify UI Kit is a free component plugin for Figma that streamlines building your applications.\n\n### Figma Plugin\n\nThe fastest and easiest way to use the Vuetify UI Kit is to install it as a [plugin for Figma](https://www.figma.com/community/file/1266515419060480209).\n\n### Digital Download\n\nIf you need to manually install the plugin for whatever reason, you can download the latest version from the [Vuetify Store](https://store.vuetifyjs.com/).\n\n1. [Download](https://store.vuetifyjs.com/products/vuetify-ui-kit-figma) for free from the our store\n2. Unzip **vuetify3-ui-light-kit.fig** from `vuetify-figma-ui-kit.zip`\n3. Open Figma and create a new project:\n  ![UI Kit New Project](https://cdn.vuetifyjs.com/docs/images/ui-kits/ui-kit-new-project.png)\n4. Select **Import file** and navigate to where you unzipped `vuetify3-ui-light-kit.fig`:\n  ![UI Kit Import File](https://cdn.vuetifyjs.com/docs/images/ui-kits/ui-kit-import-file.png)\n5. Create a new design file:\n  ![UI Kit New Design File](https://cdn.vuetifyjs.com/docs/images/ui-kits/ui-kit-new-design-file.png)\n6. Access components within your projects by selecting **Assets** and then searching for the desired component:\n  ![UI Kit Search Assets](https://cdn.vuetifyjs.com/docs/images/ui-kits/ui-kit-search-assets.png)\n"
  },
  {
    "path": "packages/docs/src/pages/en/styles/border-radius.md",
    "content": "---\nmeta:\n  title: Border radius\n  description: Use border utilities to quickly style the border-radius of any element.\n  keywords: border radius classes, radius utilities, vuetify radius helper classes\nrelated:\n  - /styles/text-and-typography/\n  - /components/sheets/\n  - /components/buttons/\nfeatures:\n  report: true\n---\n\n# Border radius\n\nUse border utilities to quickly style the border-radius of any element.\n\n<PageFeatures />\n\n| Class | Properties |\n| - | - |\n| **rounded** | border-radius: 4px; |\n| **rounded-0** | border-radius: 0; |\n| **rounded-sm** | border-radius: 2px; |\n| **rounded-md** | border-radius: 4px; |\n| **rounded-lg** | border-radius: 8px; |\n| **rounded-xl** | border-radius: 24px; |\n| **rounded-pill** | border-radius: 9999px; |\n| **rounded-circle** | border-radius: 50%; |\n| **rounded-shaped** | border-radius: 24px 0 |\n| **rounded-t** | border-top-left-radius: 4px;<br>border-top-right-radius: 4px; |\n| **rounded-t-0** | border-top-left-radius: 0;<br>border-top-right-radius: 0; |\n| **rounded-t-sm** | border-top-left-radius: 2px;<br>border-top-right-radius: 2px; |\n| **rounded-t-md** | border-top-left-radius: 4px;<br>border-top-right-radius: 4px; |\n| **rounded-t-lg** | border-top-left-radius: 8px;<br>border-top-right-radius: 8px; |\n| **rounded-t-xl** | border-top-left-radius: 24px;<br>border-top-right-radius: 24px; |\n| **rounded-t-pill** | border-top-left-radius: 9999px;<br>border-top-right-radius: 9999px; |\n| **rounded-t-circle** | border-top-left-radius: 50%;<br>border-top-right-radius: 50%; |\n| **rounded-t-shaped** | border-top-left-radius: 24px; border-top-right-radius: 0; |\n| **rounded-te** | border-top-right-radius: 4px; |\n| **rounded-te-0** | border-top-right-radius: 0; |\n| **rounded-te-sm** | border-top-right-radius: 2px; |\n| **rounded-te-md** | border-top-right-radius: 4px; |\n| **rounded-te-lg** | border-top-right-radius: 8px; |\n| **rounded-te-xl** | border-top-right-radius: 24px; |\n| **rounded-te-pill** | border-top-right-radius: 9999px; |\n| **rounded-te-circle** | border-top-right-radius: 50%; |\n| **rounded-te-shaped** | border-top-right-radius: 24px<br>border-top-left-radius: 0; |\n| **rounded-ts** | border-top-left-radius: 4px; |\n| **rounded-ts-0** | border-top-left-radius: 0; |\n| **rounded-ts-sm** | border-top-left-radius: 2px; |\n| **rounded-ts-md** | border-top-left-radius: 4px; |\n| **rounded-ts-lg** | border-top-left-radius: 8px; |\n| **rounded-ts-xl** | border-top-left-radius: 24px; |\n| **rounded-ts-pill** | border-top-left-radius: 9999px; |\n| **rounded-ts-circle** | border-top-left-radius: 50%; |\n| **rounded-ts-shaped** | border-top-left-radius: 24px; border-top-right-radius: 0; |\n| **rounded-e** | border-inline-end-radius: 4px; |\n| **rounded-e-0** | border-inline-end-radius: 0; |\n| **rounded-e-sm** | border-inline-end-radius: 2px; |\n| **rounded-e-md** | border-inline-end-radius: 4px; |\n| **rounded-e-lg** | border-inline-end-radius: 8px; |\n| **rounded-e-xl** | border-inline-end-radius: 24px; |\n| **rounded-e-pill** | border-inline-end-radius: 9999px; |\n| **rounded-e-circle** | border-inline-end-radius: 50%; |\n| **rounded-e-shaped** | border-inline-end-radius: 0; border-inline-start-radius: 24px; |\n| **rounded-b** | border-bottom-left-radius: 4px;<br>border-bottom-right-radius: 4px; |\n| **rounded-b-0** | border-bottom-left-radius: 0;<br>border-bottom-right-radius: 0; |\n| **rounded-b-sm** | border-bottom-left-radius: 2px;<br>border-bottom-right-radius: 2px; |\n| **rounded-b-md** | border-bottom-left-radius: 4px;<br>border-bottom-right-radius: 4px; |\n| **rounded-b-lg** | border-bottom-left-radius: 8px;<br>border-bottom-right-radius: 8px; |\n| **rounded-b-xl** | border-bottom-left-radius: 24px;<br>border-bottom-right-radius: 24px; |\n| **rounded-b-pill** | border-bottom-left-radius: 9999px;<br>border-bottom-right-radius: 9999px; |\n| **rounded-b-circle** | border-bottom-left-radius: 50%;<br>border-bottom-right-radius: 50%; |\n| **rounded-b-shaped** | border-bottom-left-radius: 0; border-bottom-right-radius: 24px; |\n| **rounded-be** | border-bottom-right-radius: 4px; |\n| **rounded-be-0** | border-bottom-right-radius: 0; |\n| **rounded-be-sm** | border-bottom-right-radius: 2px; |\n| **rounded-be-md** | border-bottom-right-radius: 4px; |\n| **rounded-be-lg** | border-bottom-right-radius: 8px; |\n| **rounded-be-xl** | border-bottom-right-radius: 24px; |\n| **rounded-be-pill** | border-bottom-right-radius: 9999px; |\n| **rounded-be-circle** | border-bottom-right-radius: 50%; |\n| **rounded-be-shaped** | border-bottom-right-radius: 24px; border-bottom-left-radius: 0; |\n| **rounded-bs** | border-inline-start-radius: 4px; |\n| **rounded-bs-0** | border-inline-start-radius: 0; |\n| **rounded-bs-sm** | border-inline-start-radius: 2px; |\n| **rounded-bs-md** | border-inline-start-radius: 4px; |\n| **rounded-bs-lg** | border-inline-start-radius: 8px; |\n| **rounded-bs-xl** | border-inline-start-radius: 24px; |\n| **rounded-bs-pill** | border-inline-start-radius: 9999px; |\n| **rounded-bs-circle** | border-inline-start-radius: 50%; |\n| **rounded-bs-shaped** | border-inline-start-radius: 24px; border-inline-end-radius: 0; |\n| **rounded-s** | border-inline-start-radius: 4px; |\n| **rounded-s-0** | border-inline-start-radius: 0; |\n| **rounded-s-sm** | border-inline-start-radius: 2px; |\n| **rounded-s-md** | border-inline-start-radius: 4px; |\n| **rounded-s-lg** | border-inline-start-radius: 8px; |\n| **rounded-s-xl** | border-inline-start-radius: 24px; |\n| **rounded-s-pill** | border-inline-start-radius: 9999px; |\n| **rounded-s-circle** | border-inline-start-radius: 50%; |\n| **rounded-s-shaped** | border-inline-start-radius: 24px; border-inline-end-radius: 0; { style=\"max-height: 420px;\" fixed-header } |\n\n<PromotedEntry />\n\n## Usage\n\nThe `border-radius` utilities allow you to quickly style the border-radius of any element.\n\n### Rounded corners\n\nUse the **rounded**, **rounded-0**, **rounded-sm**, **rounded-md**, **rounded-lg**, and **rounded-xl** classes to set the border-radius of an element.\n\n<ExamplesExample file=\"border-radius/misc-rounded-corners\" />\n\n### Pill and circle\n\nUse the **rounded-pill** and **rounded-circle** classes to create pill and circle shapes.\n\n<ExamplesExample file=\"border-radius/misc-pill-and-circle\" />\n\n### Rounding by side\n\nUse the **rounded-t-\\***, **rounded-b-\\***, **rounded-s-\\***, and **rounded-e-\\*** classes to set the border-radius of an element on a specific side.\n\n<ExamplesExample file=\"border-radius/misc-rounding-by-side\" />\n\n### Rounding by corner\n\nUse the **rounded-te-\\***, **rounded-ts-\\***, **rounded-be-\\***, and **rounded-bs-\\*** classes to set the border-radius of an element on a specific corner.\n\n<ExamplesExample file=\"border-radius/misc-rounding-by-corner\" />\n\n### No rounding\n\nUse the **rounded-0** class to remove the border-radius from an element.\n\n<ExamplesExample file=\"border-radius/misc-removing-border-radius\" />\n\n### Components\n\n::: info\n\nWhen using the **rounded** property on components, omit the `rounded-` prefix. For example, use `rounded=\"sm\"` instead of `rounded-sm`.\n\n:::\n\nSetting the **rounded** property applies a component specific border-radius class, such as `v-sheet--rounded`. This is to ensure that basic rounded usage persists even if the utility classes are disabled.\n\n<ExamplesExample file=\"border-radius/misc-components\" />\n\n## SASS variables\n\nYou can also use the following SASS variables to customize the border radius:\n\n```scss\n$rounded: (\n  0: 0,\n  'sm': $border-radius-root / 2,\n  null: $border-radius-root,\n  'md': $border-radius-root,\n  'lg': $border-radius-root * 2,\n  'xl': $border-radius-root * 6,\n  'pill': 9999px,\n  'circle': 50%\n);\n```\n\nDisable border-radius class generation by setting the $rounded variable to **false**.\n\n```sass { resource=\"src/styles/settings.scss\" }\n@use 'vuetify/settings' with (\n  $rounded: false\n);\n```\n"
  },
  {
    "path": "packages/docs/src/pages/en/styles/borders.md",
    "content": "---\nmeta:\n  title: Borders\n  description: Use border utilities to quickly style the border of any element.\n  keywords: border classes, border utilities, vuetify border helper classes\nrelated:\n  - /styles/border-radius/\n  - /styles/display/\n  - /styles/content/\nfeatures:\n  report: true\n---\n\n# Borders\n\nUtilities for controlling the border of elements in your application.\n\n<PageFeatures />\n\n| Class | Properties |\n| - | - |\n| **border** | border: thin solid rgba(var(--v-border-color), var(--v-border-opacity)); |\n| **border-thin** | border-width: thin; |\n| **border-sm** | border-width: 1px; |\n| **border-md** | border-width: 2px; |\n| **border-lg** | border-width: 4px; |\n| **border-xl** | border-width: 8px; |\n| **border-0** | border-width: 0; |\n| **border-t** | border-top-width: thin; |\n| **border-t-0** | border-top-width: 0; |\n| **border-t-thin** | border-top-width: thin; |\n| **border-t-sm** | border-top-width: 1px; |\n| **border-t-md** | border-top-width: 2px; |\n| **border-t-lg** | border-top-width: 4px; |\n| **border-t-xl** | border-top-width: 8px; |\n| **border-e** | border-inline-end-width: thin; |\n| **border-e-0** | border-inline-end-width: 0; |\n| **border-e-thin** | border-inline-end-width: thin; |\n| **border-e-sm** | border-inline-end-width: 1px; |\n| **border-e-md** | border-inline-end-width: 2px; |\n| **border-e-lg** | border-inline-end-width: 4px; |\n| **border-e-xl** | border-inline-end-width: 8px; |\n| **border-b** | border-bottom-width: thin; |\n| **border-b-0** | border-bottom-width: 0; |\n| **border-b-thin** | border-bottom-width: thin; |\n| **border-b-sm** | border-bottom-width: 1px; |\n| **border-b-md** | border-bottom-width: 2px; |\n| **border-b-lg** | border-bottom-width: 4px; |\n| **border-b-xl** | border-bottom-width: 8px; |\n| **border-s** | border-inline-start-width: thin; |\n| **border-s-0** | border-inline-start-width: 0; |\n| **border-s-thin** | border-inline-start-width: thin; |\n| **border-s-sm** | border-inline-start-width: 1px; |\n| **border-s-md** | border-inline-start-width: 2px; |\n| **border-s-lg** | border-inline-start-width: 4px; |\n| **border-s-xl** | border-inline-start-width: 8px; |\n| **border-opacity-0** | --v-border-opacity: 0; |\n| **border-opacity** | --v-border-opacity: .12; |\n| **border-opacity-25** | --v-border-opacity: .25; |\n| **border-opacity-50** | --v-border-opacity: .5; |\n| **border-opacity-75** | --v-border-opacity: .75; |\n| **border-opacity-100** | --v-border-opacity: 1; |\n| **border-dashed** | border-style: dashed; |\n| **border-dotted** | border-style: dotted; |\n| **border-double** | border-style: double; |\n| **border-solid** | border-style: solid; { style=\"max-height: 420px;\" fixed-header } |\n\n<PromotedEntry />\n\n## Usage\n\nThe `border` utilities allow you to quickly style the border of any element.\n\n### All sides\n\nUse the **border**, **border-0**, **border-sm**, **border-md**, **border-lg**, and **border-xl** classes to set the border width of an element.\n\n<ExamplesExample file=\"border/all\" />\n\n### Individual sides\n\nUse the **border-\\***, **border-\\*-0**, **border-\\*-sm**, **border-\\*-md**, **border-\\*-lg**, and **border-\\*-xl** classes to set the border width of an element on a specific side.\n\n<ExamplesExample file=\"border/sides\" />\n\n### Border styles\n\nUse the **border-dashed**, **border-dotted**, **border-double**, and **border-solid** classes to set the border style of an element.\n\n<ExamplesExample file=\"border/styles\" />\n\n### Theme colors\n\nComponents that support the **border** property can take advantage of all border utility classes. This includes colors generated by your theme.\n\n<ExamplesExample file=\"border/colors\" />\n\n| Class | Properties |\n| - | - |\n| **border-primary** | --v-border-color: var(--v-theme-primary); |\n| **border-secondary** | --v-border-color: var(--v-theme-secondary); |\n| **border-accent** | --v-border-color: var(--v-theme-accent); |\n| **border-error** | --v-border-color: var(--v-theme-error); |\n| **border-info** | --v-border-color: var(--v-theme-info); |\n| **border-success** | --v-border-color: var(--v-theme-success); |\n| **border-warning** | --v-border-color: var(--v-theme-warning); |\n| **border-surface** | --v-border-color: var(--v-theme-surface); |\n| **border-background** | --v-border-color: var(--v-theme-background); |\n| **border-surface-light** | --v-border-color: var(--v-theme-surface-light); |\n| **border-surface-variant** | --v-border-color: var(--v-theme-surface-variant); |\n| **border-surface-bright** | --v-border-color: var(--v-theme-surface-bright); |\n| **border-current** | --v-border-color: currentColor; { style=\"max-height: 420px;\" fixed-header } |\n\n### Components\n\n::: info\n\nWhen using the **border** property on components, omit the `border-` prefix. For example, use `border=\"sm\"` instead of `border=\"border-sm\"`.\n\n:::\n\nSetting the **border** property to true applies a component specific border class, such as `v-card--border`. This is to ensure that basic border usage persists even if the utility classes are disabled.\n\n<ExamplesExample file=\"border/card\" />\n\n## SASS variables\n\nYou can also use the following SASS variables to customize the border color and width:\n\n```sass { resource=\"src/styles/settings.scss\" }\n@use 'vuetify/settings' with (\n  $borders: (\n    0: 0,\n    null: thin,\n    thin: thin,\n    sm: 1px,\n    md: 2px,\n    lg: 4px,\n    xl: 8px\n  )\n);\n```\n\nDisable border class generation by setting the $borders variable to **false**.\n\n```sass { resource=\"src/styles/settings.scss\" }\n@use 'vuetify/settings' with (\n  $borders: false\n);\n```\n"
  },
  {
    "path": "packages/docs/src/pages/en/styles/colors.md",
    "content": "---\nmeta:\n  title: Material color palette\n  description: Learn about the colors of Material Design. Consume the javascript color pack directly in your application.\n  keywords: colors, material design colors, vuetify color pack, material color classes\nrelated:\n  - /features/theme/\n  - /resources/themes/\n  - /getting-started/wireframes/\n---\n\n# Colors\n\nOut of the box you get access to all colors in the [Material Design specification](https://material.io/design/color/the-color-system.html) through **sass** and **javascript**. These values can be used within your style sheets, your component files and on actual components via the **color** prop.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## Classes\n\nEach color from the specification gets converted to a **background** and **text** variant for styling within your application through a class, e.g. `<div class=\"bg-red\">` or `<span class=\"text-red\">`. These class colors are defined [here](https://github.com/vuetifyjs/vuetify/blob/master/packages/vuetify/src/styles/settings/_colors.scss).\n\n<ExamplesExample file=\"color/classes\" />\n\nText colors also support **darken** and **lighten** variants using `text-{color}-{lighten|darken}-{n}`\n\n<ExamplesExample file=\"color/text-classes\" />\n\n## Javascript color pack\n\nVuetify has an optional javascript color pack that you can import and use within your application. This can also be used to help define your application's theme.\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport { createVuetify } from 'vuetify'\n\nimport colors from 'vuetify/util/colors'\n\nexport default createVuetify({\n  theme: {\n    themes: {\n      light: {\n        dark: false,\n        colors: {\n          primary: colors.red.darken1, // #E53935\n          secondary: colors.red.lighten4, // #FFCDD2\n          ...\n        }\n      },\n    },\n  },\n})\n```\n\n## Sass color pack\n\nWhile convenient, the color pack increases the CSS export size by ~30kb. Some projects may only require the classes that are created at runtime from the Vuetify **theme** system. To disable the color pack feature, follow [sass variables](/features/sass-variables) and set `$color-pack: false`{.text-no-wrap}.\n\n```scss { resource=\"main.scss\" }\n@use 'vuetify' with (\n  $color-pack: false,\n);\n```\n\n## Material colors\n\nBelow is a list of the Material design color palette grouped by primary color\n\n<FeaturesColorPalette />\n"
  },
  {
    "path": "packages/docs/src/pages/en/styles/content.md",
    "content": "---\nmeta:\n  title: Content\n  description: Vuetify provides custom styling for various HTML elements.\n  keywords: content, html, markup\nrelated:\n  - /styles/text-and-typography/\n  - /styles/display/\n  - /styles/spacing/\nfeatures:\n  report: true\n---\n\n# Content\n\nVuetify has custom styling for multiple standard elements.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## Block quote\n\n> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Harum maiores modi quidem veniam, expedita quis laboriosam, ullam facere adipisci, iusto, voluptate sapiente corrupti asperiores rem nemo numquam fuga ab at.\n{.blockquote}\n\n## Paragraphs\n\nLorem ipsum dolor sit amet, consectetur adipisicing elit. Harum maiores modi quidem veniam, expedita quis laboriosam, ullam facere adipisci, iusto, voluptate sapiente corrupti asperiores rem nemo numquam fuga ab at.\n\nLorem ipsum dolor sit amet, consectetur adipisicing elit. Harum maiores modi quidem veniam, expedita quis laboriosam, ullam facere adipisci, iusto, voluptate sapiente corrupti asperiores rem nemo numquam fuga ab at.\n\n## Code\n\nExample of an inline `<code>` element.\n\n## Variables\n\n<var>v</var> = <var>u</var> * <var>e</var>\n"
  },
  {
    "path": "packages/docs/src/pages/en/styles/css-reset.md",
    "content": "---\nemphasized: true\nmeta:\n  title: CSS Reset\n  description: Vuetify applies a minimal CSS reset to normalize browser inconsistencies.\n  keywords: css reset, vuetify css reset\nrelated:\n  - /styles/colors/\n  - /styles/text-and-typography/\n  - /features/sass-variables/\n---\n\n# CSS Reset\n\nMinimal base styles for Vuetify projects.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## Bootstrapping\n\nVuetify applies a minimal CSS reset to normalize browser inconsistencies while keeping the footprint small.\n\n::: warning\n  The Vuetify style reset is applied globally and affects default elements such as `button` and `input`. This also includes anything located outside of the [v-app](/components/application) component.\n:::\n\nIt can be disabled with [sass variables](/features/sass-variables/#sass-variables) by setting `$reset: false`, but you may have to manually reset some styles for components to display correctly.\n\n## Reset Features\n\nBelow is a list of styles applied by the reset:\n\n- Apply `box-sizing: border-box` in all elements.\n- Reset `margin` in `html` and `body`.\n- Specify `background-repeat: no-repeat` in all elements and pseudo elements.\n- Inherit `text-decoration` and `vertical-align` to `::before` and `::after`.\n- Reset `border-radius` in input elements.\n- Specify font inheritance of form elements.\n- Apply `cursor: pointer` to button elements.\n- Apply `tab-size: 4` in `html`.\n- Style `cursor` by aria attributes.\n- Minor consitency improvements for search and number inputs.\n\nFor a complete list of all applied styles, see the [reset stylesheet](https://github.com/vuetifyjs/vuetify/blob/master/packages/vuetify/src/styles/generic/_reset.scss).\n"
  },
  {
    "path": "packages/docs/src/pages/en/styles/cursor.md",
    "content": "---\nmeta:\n  title: Cursor\n  description: Assign a custom cursor to any element.\n  keywords: cursor, utility, helper, class\nrelated:\n  - /styles/content/\n  - /styles/spacing/\n  - /styles/text-and-typography/\nfeatures:\n  report: true\n---\n\n# Cursor\n\nUtilities for controlling the cursor styling when hovering over elements.\n\n<PageFeatures />\n\n| Class | Properties |\n| - | - |\n| **cursor-auto** | cursor: auto; |\n| **cursor-default** | cursor: default; |\n| **cursor-grab** | cursor: grab; |\n| **cursor-grabbing** | cursor: grabbing; |\n| **cursor-help** | cursor: help; |\n| **cursor-move** | cursor: move; |\n| **cursor-none** | cursor: none; |\n| **cursor-not-allowed** | cursor: not-allowed; |\n| **cursor-pointer** | cursor: pointer; |\n| **cursor-progress** | cursor: progress; |\n| **cursor-text** | cursor: text; |\n| **cursor-wait** | cursor: wait; { style=\"max-height: 420px;\" fixed-header } |\n\n<PromotedEntry />\n\n## Usage\n\nApply custom cursor styling to a component or element.\n\n<ExamplesExample file=\"cursor/usage\" />\n\n## SASS variables\n\nYou can also use the following SASS variables to customize the border color and width:\n\n```scss { resource=\"src/styles/settings.scss\" }\n@use 'vuetify/settings' with (\n  $utilities: (\n    \"cursor\": (\n      property: cursor,\n      class: cursor,\n      values: auto default pointer wait text move help not-allowed progress grab grabbing none\n    )\n  )\n);\n```\n\nDisable the generation of **cursor** utility classes by overwriting the utilities value:\n\n```scss { resource=\"src/styles/settings.scss\" }\n@use 'vuetify/settings' with (\n  $utilities: (\n    \"cursor\": false,\n  ),\n);\n```\n"
  },
  {
    "path": "packages/docs/src/pages/en/styles/display.md",
    "content": "---\nmeta:\n  title: Display\n  description: Display helper classes allow you to control when elements should display based upon viewport.\n  keywords: display helper classes, display classes, vuetify display\nrelated:\n  - /styles/text-and-typography/\n  - /directives/resize/\n  - /features/display-and-platform/\nfeatures:\n  report: true\n---\n\n# Display\n\nDisplay helpers control content visibility and display type based on the viewport.\n\n<PageFeatures />\n\n| Class | Properties |\n| - | - |\n| **d-none** | display: none; |\n| **d-sm-none** | display: none; |\n| **d-md-none** | display: none; |\n| **d-lg-none** | display: none; |\n| **d-xl-none** | display: none; |\n| **d-xxl-none** | display: none; |\n| **d-sm-flex** | display: flex; |\n| **d-md-flex** | display: flex; |\n| **d-lg-flex** | display: flex; |\n| **d-xl-flex** | display: flex; |\n| **d-xxl-flex** | display: flex; |\n| **d-sm-inline** | display: inline; |\n| **d-md-inline** | display: inline; |\n| **d-lg-inline** | display: inline; |\n| **d-xl-inline** | display: inline; |\n| **d-xxl-inline** | display: inline; |\n| **d-sm-inline-block** | display: inline-block; |\n| **d-md-inline-block** | display: inline-block; |\n| **d-lg-inline-block** | display: inline-block; |\n| **d-xl-inline-block** | display: inline-block; |\n| **d-xxl-inline-block** | display: inline-block; |\n| **d-sm-table** | display: table; |\n| **d-md-table** | display: table; |\n| **d-lg-table** | display: table; |\n| **d-xl-table** | display: table; |\n| **d-xxl-table** | display: table; |\n| **d-sm-table-cell** | display: table-cell; |\n| **d-md-table-cell** | display: table-cell; |\n| **d-lg-table-cell** | display: table-cell; |\n| **d-xl-table-cell** | display: table-cell; |\n| **d-xxl-table-cell** | display: table-cell; |\n| **d-sm-table-row** | display: table-row; |\n| **d-md-table-row** | display: table-row; |\n| **d-lg-table-row** | display: table-row; |\n| **d-xl-table-row** | display: table-row; |\n| **d-xxl-table-row** | display: table-row; |\n| **d-sm-flex** | display: flex; |\n| **d-md-flex** | display: flex; |\n| **d-lg-flex** | display: flex; |\n| **d-xl-flex** | display: flex; |\n| **d-xxl-flex** | display: flex; |\n| **d-sm-inline-flex** | display: inline-flex; |\n| **d-md-inline-flex** | display: inline-flex; |\n| **d-lg-inline-flex** | display: inline-flex; |\n| **d-xl-inline-flex** | display: inline-flex; |\n| **d-xxl-inline-flex** | display: inline-flex; |\n| **d-print-none** | display: none; |\n| **d-print-inline** | display: inline; |\n| **d-print-inline-block** | display: inline-block; |\n| **d-print-block** | display: block; |\n| **d-print-table** | display: table; |\n| **d-print-table-cell** | display: table-cell; |\n| **d-print-table-row** | display: table-row; |\n| **d-print-flex** | display: flex; |\n| **d-print-inline-flex** | display: inline-flex; |\n| **d-sr-only** | display: none; |\n| **d-sr-only-focusable** | display: none; { style=\"max-height: 420px;\" fixed-header } |\n\n<PromotedEntry />\n\n<FeaturesBreakpointsTable />\n\n## Usage\n\nSpecify the element's `display` property. These classes can be applied to all breakpoints from `xs` to `xxl`. When using a base class,`.d-{value}`, it is inferred to be `.d-xs-{value}`.\n\n- `.d-{value}` for `xs`\n- `.d-{breakpoint}-{value}` for `sm`, `md`, `lg`, `xl`, and `xxl`\n\nThe _value_ property is one of:\n\n- `none`\n- `inline`\n- `inline-block`\n- `block`\n- `table`\n- `table-cell`\n- `table-row`\n- `flex`\n- `inline-flex`\n\nWhen setting a specific breakpoint for a display helper class, it will apply to all screen widths from the designation and up. For example, `d-lg-flex` will apply to `lg`, `xl` and `xxl` size screens.\n\n<ExamplesExample file=\"display/display-inline\" />\n\n<ExamplesExample file=\"display/display-block\" />\n\n## Visibility\n\nConditionally display an element based upon the current **viewport**. Breakpoint utility classes always apply from the bottom up. That means if you have `.d-none`, it will apply to all breakpoints. However, `.d-md-none` will apply to only `md` and up.\n\n| Screen size         | Class                            |\n|---------------------|----------------------------------|\n| Hidden on all       | `.d-none`                        |\n| Hidden only on xs   | `.d-none .d-sm-flex`             |\n| Hidden only on sm   | `.d-sm-none .d-md-flex`          |\n| Hidden only on md   | `.d-md-none .d-lg-flex`          |\n| Hidden only on lg   | `.d-lg-none .d-xl-flex`          |\n| Hidden only on xl   | `.d-xl-none .d-xxl-flex`         |\n| Hidden only on xxl  | `.d-xxl-none`                    |\n| Visible on all      | `.d-flex`                        |\n| Visible only on xs  | `.d-flex .d-sm-none`             |\n| Visible only on sm  | `.d-none .d-sm-flex .d-md-none`  |\n| Visible only on md  | `.d-none .d-md-flex .d-lg-none`  |\n| Visible only on lg  | `.d-none .d-lg-flex .d-xl-none`  |\n| Visible only on xl  | `.d-none .d-xl-flex .d-xxl-none` |\n| Visible only on xxl | `.d-none .d-xxl-flex`            |\n\n<ExamplesExample file=\"display/visibility\" />\n\nAlternatively you can hide an element based upon the current **viewport** using lateral display helper classes. These classes can be applied using the following format `hidden-{breakpoint}-{condition?}`\n\nThe _condition_ applies the class base on:\n\n- nothing - hide the element only on the specified breakpoint\n- `and-down` - hide the element on the specified breakpoint and down - `sm` through `xl` only\n- `and-up` - hide the element on the specified breakpoint and up - `sm` through `xl` only\n\n`hidden-{breakpoint}-and-up` is equivalent to `d-{breakpoint}-none`.\n\n**Media types** can also be targeted using the `only` condition. Both `hidden-screen-only` and `hidden-print-only` are currently supported.\n\n### Caveats\n\n::: info\nIt is important to note that using any of the display classes above will result in any display style previously added being overwritten. This is because of the classes using `!important` in their display styling.\n:::\n\n## Display in print\n\nYou can also change the display property when printing. Print utility classes can also be combined with none print display utilities.\n\n<ExamplesExample file=\"display/print\" />\n\n## Accessibility\n\n### Screen readers\n\nUse the `d-sr` utility classes to conditionally hide content on all devices _except_ screen readers.\n\n- `d-sr-only` visually hides elements but will still announce to **screen readers**.\n- `d-sr-only-focusable` visually hides an element until it is focused. This is useful when implementing _skip links_.\n"
  },
  {
    "path": "packages/docs/src/pages/en/styles/elevation.md",
    "content": "---\nemphasized: true\nmeta:\n  title: Elevation\n  description: Elevation helper classes allow you to control relative depth, or distance, between two surfaces along the z-axis.\n  keywords: elevation helper classes, elevation classes, vuetify elevation\nrelated:\n  - /components/cards/\n  - /components/sheets/\n  - /components/bottom-navigation/\nfeatures:\n  report: true\n---\n\n# Elevation\n\nThe elevation helpers control the relative depth between surfaces along the **z-axis**. Following Material Design 3 guidelines, Vuetify uses 6 elevation levels (0-5). Elevation values are measured in **dp** (density-independent pixels), a unit that ensures consistent sizing across different screen densities.\n\n<PageFeatures />\n\n| Class           | Level (dp) | Usage                                 |\n|-----------------|------------|---------------------------------------|\n| **elevation-0** | 0dp        | No shadow - flat surfaces             |\n| **elevation-1** | 1dp        | Cards, buttons (elevated)             |\n| **elevation-2** | 3dp        | Menus, rich tooltip, floating app bar |\n| **elevation-3** | 6dp        | Dialogs, snackbars, FABs              |\n| **elevation-4** | 8dp        | Dragged elements                      |\n| **elevation-5** | 12dp       |                                       |\n\nIn MD3, elevation changes are commonly used to indicate interactive states. For example, a card at rest might use `elevation-1`, rising to `elevation-2` on hover and `elevation-3` when pressed or dragged.\n\n<PromotedEntry />\n\n## Usage\n\nThe `elevation` helper classes allow you to assign a custom **z-depth** to any element.\n\n<ExamplesExample file=\"elevation/usage\" />\n\n## Examples\n\n### Props\n\n#### Dynamic elevation\n\nNumerous components utilize the **elevatable** mixin and are given an **elevation** prop. For components that are not supported, you can dynamically change the class\n\n<ExamplesExample file=\"elevation/prop-dynamic\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/styles/entry-points.md",
    "content": "---\nemphasized: true\nmeta:\n  title: Entry points\n  description: Vuetify style entry points\n  keywords: styles, sass, variables, configuration, core\nrelated:\n  - /styles/css-reset/\n  - /styles/colors/\n  - /features/sass-variables/\n---\n\n# Style entry points\n\nVuetify allows you to import styles via JavaScript (pre-compiled CSS) or SASS (SCSS). Choosing the right entry point depends on whether you need a quick setup or deep customization capabilities (such as overriding SASS variables).\n\n## From javascript\n\nImports in this section are typically added to your `main.js` or `main.ts` file. These are pre-compiled CSS files, meaning you cannot override SASS variables with them, but they are the easiest way to get started.\n\n### All-in-one\n\nThe `vuetify/styles` is the **standard, all-in-one import**. It includes the core framework, utility classes, and the layout system.\n\n* **Best for:** Most applications that do not require granular control over CSS file size.\n* **Usage:**\n\n  ```js { resource=\"src/plugins/vuetify.js\" }\n  import 'vuetify/styles'\n  import { createVuetify } from 'vuetify'\n  ```\n\n### Individual modules\n\nIf you are strictly managing bundle size or using a manual build process, you can import style modules individually.\n\n#### `vuetify/styles/core`\n\nContains the CSS reset, typography fundamentals, and basic application structure.\n\n::: info\n**Note:** This **must be first** in your import order to ensure the CSS layers have not already been declared elsewhere.\n:::\n\n#### `vuetify/styles/colors`\n\nIncludes the Material Design color palette utility classes (e.g., `text-red`, `bg-blue-darken-1`). If you are defining your own theme colors and do not use the standard Material palette classes, you may omit this.\n\n#### `vuetify/styles/utilities`\n\nContains helper classes for layout and spacing (e.g., `d-flex`, `mt-4`, `pa-2`).\n\n**Example of modular import:**\n\n```js { resource=\"src/plugins/vuetify.js\" }\nimport 'vuetify/styles/core'      // Reset and structure (Required first)\nimport 'vuetify/styles/colors'    // Optional: standard color classes\nimport 'vuetify/styles/utilities' // Optional: helper classes\n```\n\n-----\n\n## From SASS\n\nUsing SASS entry points allows you to utilize Vuetify's compilation-time features. This is required if you wish to override global SASS variables (like changing the default font or border radius) or use Vuetify's internal mixins.\n\n### Main entry point\n\nThe `vuetify/styles` acts as the main entry point to load the framework's styles. `$color-pack` and `$utilities` can be configured on this import if you aren't using `styles.configFile`.\n\n```scss { resource=\"src/styles/main.scss\" }\n@use 'vuetify';\n// OR (these both point to the same file)\n@use 'vuetify/styles';\n```\n\nThis would be the same as only importing `vuetify/styles/core`:\n\n```scss { resource=\"src/styles/main.scss\" }\n@use 'vuetify' with (\n  $color-pack: false,\n  $utilities: false,\n);\n```\n\n### Sass settings\n\nThe `vuetify/settings` module is used to configure global SASS variables. See [sass variables](/features/sass-variables) for more information.\n\n**Example configuration:**\n\n```scss { resource=\"src/styles/_settings.scss\" }\n@use 'vuetify/settings' with (\n  $utilities: false,\n  $body-font-family: ('Remora Sans', sans-serif),\n);\n```\n"
  },
  {
    "path": "packages/docs/src/pages/en/styles/flex.md",
    "content": "---\nmeta:\n  title: Flex\n  description: Flex helper classes allow you to modify flexbox parents and children.\n  keywords: flex helper classes, flex classes, vuetify flex\nrelated:\n  - /styles/display/\n  - /components/grids/\n  - /styles/css-reset/\nfeatures:\n  report: true\n---\n\n# Flex\n\nControl the layout of flex containers with alignment, justification and more with responsive flexbox utilities.\n\n<PageFeatures />\n\n| Class | Properties |\n| - | - |\n| **d-flex** | display: flex; |\n| **d-inline-flex** | display: inline-flex; |\n| **d-sm-flex** | display: flex; |\n| **d-sm-inline-flex** | display: inline-flex; |\n| **d-md-flex** | display: flex; |\n| **d-md-inline-flex** | display: inline-flex; |\n| **d-lg-flex** | display: flex; |\n| **d-lg-inline-flex** | display: inline-flex; |\n| **d-xl-flex** | display: flex; |\n| **d-xl-inline-flex** | display: inline-flex; |\n| **flex-fill** | flex: 1 1 auto; |\n| **flex-sm-fill** | flex: 1 1 auto; |\n| **flex-md-fill** | flex: 1 1 auto; |\n| **flex-lg-fill** | flex: 1 1 auto; |\n| **flex-xl-fill** | flex: 1 1 auto; |\n| **flex-1-1** | flex: 1 1 auto; |\n| **flex-sm-1-1** | flex: 1 1 auto; |\n| **flex-md-1-1** | flex: 1 1 auto; |\n| **flex-lg-1-1** | flex: 1 1 auto; |\n| **flex-xl-1-1** | flex: 1 1 auto; |\n| **flex-1-0** | flex: 1 0 auto; |\n| **flex-sm-1-0** | flex: 1 0 auto; |\n| **flex-md-1-0** | flex: 1 0 auto; |\n| **flex-lg-1-0** | flex: 1 0 auto; |\n| **flex-xl-1-0** | flex: 1 0 auto; |\n| **flex-0-1** | flex: 0 1 auto; |\n| **flex-sm-0-1** | flex: 0 1 auto; |\n| **flex-md-0-1** | flex: 0 1 auto; |\n| **flex-lg-0-1** | flex: 0 1 auto; |\n| **flex-xl-0-1** | flex: 0 1 auto; |\n| **flex-0-0** | flex: 0 0 auto; |\n| **flex-sm-0-0** | flex: 0 0 auto; |\n| **flex-md-0-0** | flex: 0 0 auto; |\n| **flex-lg-0-0** | flex: 0 0 auto; |\n| **flex-xl-0-0** | flex: 0 0 auto; |\n| **flex-1-1-0** | flex: 1 1 0%; |\n| **flex-sm-1-1-0** | flex: 1 1 0%; |\n| **flex-md-1-1-0** | flex: 1 1 0%; |\n| **flex-lg-1-1-0** | flex: 1 1 0%; |\n| **flex-xl-1-1-0** | flex: 1 1 0%; |\n| **flex-1-1-100** | flex: 1 1 100%; |\n| **flex-sm-1-1-100** | flex: 1 1 100%; |\n| **flex-md-1-1-100** | flex: 1 1 100%; |\n| **flex-lg-1-1-100** | flex: 1 1 100%; |\n| **flex-xl-1-1-100** | flex: 1 1 100%; |\n| **flex-1-0-0** | flex: 1 0 0%; |\n| **flex-sm-1-0-0** | flex: 1 0 0%; |\n| **flex-md-1-0-0** | flex: 1 0 0%; |\n| **flex-lg-1-0-0** | flex: 1 0 0%; |\n| **flex-xl-1-0-0** | flex: 1 0 0%; |\n| **flex-1-0-100** | flex: 1 0 100%; |\n| **flex-sm-1-0-100** | flex: 1 0 100%; |\n| **flex-md-1-0-100** | flex: 1 0 100%; |\n| **flex-lg-1-0-100** | flex: 1 0 100%; |\n| **flex-xl-1-0-100** | flex: 1 0 100%; |\n| **flex-0-1-0** | flex: 0 1 0%; |\n| **flex-sm-0-1-0** | flex: 0 1 0%; |\n| **flex-md-0-1-0** | flex: 0 1 0%; |\n| **flex-lg-0-1-0** | flex: 0 1 0%; |\n| **flex-xl-0-1-0** | flex: 0 1 0%; |\n| **flex-0-1-100** | flex: 0 1 100%; |\n| **flex-sm-0-1-100** | flex: 0 1 100%; |\n| **flex-md-0-1-100** | flex: 0 1 100%; |\n| **flex-lg-0-1-100** | flex: 0 1 100%; |\n| **flex-xl-0-1-100** | flex: 0 1 100%; |\n| **flex-0-0-0** | flex: 0 0 0% |\n| **flex-sm-0-0-0** | flex: 0 0 0% |\n| **flex-md-0-0-0** | flex: 0 0 0% |\n| **flex-lg-0-0-0** | flex: 0 0 0% |\n| **flex-xl-0-0-0** | flex: 0 0 0% |\n| **flex-0-0-100** | flex: 0 0 100%; |\n| **flex-sm-0-0-100** | flex: 0 0 100%; |\n| **flex-md-0-0-100** | flex: 0 0 100%; |\n| **flex-lg-0-0-100** | flex: 0 0 100%; |\n| **flex-xl-0-0-100** | flex: 0 0 100%; |\n| **ga-0** | gap: 0; |\n| **ga-1** | gap: 4px; |\n| **ga-2** | gap: 8px; |\n| **ga-3** | gap: 12px; |\n| **ga-4** | gap: 16px; |\n| **ga-5** | gap: 20px; |\n| **ga-6** | gap: 24px; |\n| **ga-7** | gap: 28px; |\n| **ga-8** | gap: 32px; |\n| **ga-9** | gap: 36px; |\n| **ga-10** | gap: 40px; |\n| **ga-11** | gap: 44px; |\n| **ga-12** | gap: 48px; |\n| **ga-13** | gap: 52px; |\n| **ga-14** | gap: 56px; |\n| **ga-15** | gap: 60px; |\n| **ga-16** | gap: 64px; |\n| **ga-sm-0** | gap: 0; |\n| **ga-sm-1** | gap: 4px; |\n| **ga-sm-2** | gap: 8px; |\n| **ga-sm-3** | gap: 12px; |\n| **ga-sm-4** | gap: 16px; |\n| **ga-sm-5** | gap: 20px; |\n| **ga-sm-6** | gap: 24px; |\n| **ga-sm-7** | gap: 28px; |\n| **ga-sm-8** | gap: 32px; |\n| **ga-sm-9** | gap: 36px; |\n| **ga-sm-10** | gap: 40px; |\n| **ga-sm-11** | gap: 44px; |\n| **ga-sm-12** | gap: 48px; |\n| **ga-sm-13** | gap: 52px; |\n| **ga-sm-14** | gap: 56px; |\n| **ga-sm-15** | gap: 60px; |\n| **ga-sm-16** | gap: 64px; |\n| **ga-md-0** | gap: 0; |\n| **ga-md-1** | gap: 4px; |\n| **ga-md-2** | gap: 8px; |\n| **ga-md-3** | gap: 12px; |\n| **ga-md-4** | gap: 16px; |\n| **ga-md-5** | gap: 20px; |\n| **ga-md-6** | gap: 24px; |\n| **ga-md-7** | gap: 28px; |\n| **ga-md-8** | gap: 32px; |\n| **ga-md-9** | gap: 36px; |\n| **ga-md-10** | gap: 40px; |\n| **ga-md-11** | gap: 44px; |\n| **ga-md-12** | gap: 48px; |\n| **ga-md-13** | gap: 52px; |\n| **ga-md-14** | gap: 56px; |\n| **ga-md-15** | gap: 60px; |\n| **ga-md-16** | gap: 64px; |\n| **ga-lg-0** | gap: 0; |\n| **ga-lg-1** | gap: 4px; |\n| **ga-lg-2** | gap: 8px; |\n| **ga-lg-3** | gap: 12px; |\n| **ga-lg-4** | gap: 16px; |\n| **ga-lg-5** | gap: 20px; |\n| **ga-lg-6** | gap: 24px; |\n| **ga-lg-7** | gap: 28px; |\n| **ga-lg-8** | gap: 32px; |\n| **ga-lg-9** | gap: 36px; |\n| **ga-lg-10** | gap: 40px; |\n| **ga-lg-11** | gap: 44px; |\n| **ga-lg-12** | gap: 48px; |\n| **ga-lg-13** | gap: 52px; |\n| **ga-lg-14** | gap: 56px; |\n| **ga-lg-15** | gap: 60px; |\n| **ga-lg-16** | gap: 64px; |\n| **ga-xl-0** | gap: 0; |\n| **ga-xl-1** | gap: 4px; |\n| **ga-xl-2** | gap: 8px; |\n| **ga-xl-3** | gap: 12px; |\n| **ga-xl-4** | gap: 16px; |\n| **ga-xl-5** | gap: 20px; |\n| **ga-xl-6** | gap: 24px; |\n| **ga-xl-7** | gap: 28px; |\n| **ga-xl-8** | gap: 32px; |\n| **ga-xl-9** | gap: 36px; |\n| **ga-xl-10** | gap: 40px; |\n| **ga-xl-11** | gap: 44px; |\n| **ga-xl-12** | gap: 48px; |\n| **ga-xl-13** | gap: 52px; |\n| **ga-xl-14** | gap: 56px; |\n| **ga-xl-15** | gap: 60px; |\n| **ga-xl-16** | gap: 64px; |\n| **flex-row** | flex-direction: row; |\n| **flex-row-reverse** | flex-direction: row-reverse; |\n| **flex-column** | flex-direction: column; |\n| **flex-column-reverse** | flex-direction: column-reverse; |\n| **flex-sm-row** | flex-direction: row; |\n| **flex-sm-row-reverse** | flex-direction: row-reverse; |\n| **flex-sm-column** | flex-direction: column; |\n| **flex-sm-column-reverse** | flex-direction: column-reverse; |\n| **flex-md-row** | flex-direction: row; |\n| **flex-md-row-reverse** | flex-direction: row-reverse; |\n| **flex-md-column** | flex-direction: column; |\n| **flex-md-column-reverse** | flex-direction: column-reverse; |\n| **flex-lg-row** | flex-direction: row; |\n| **flex-lg-row-reverse** | flex-direction: row-reverse; |\n| **flex-lg-column** | flex-direction: column; |\n| **flex-lg-column-reverse** | flex-direction: column-reverse; |\n| **flex-xl-row** | flex-direction: row; |\n| **flex-xl-row-reverse** | flex-direction: row-reverse; |\n| **flex-xl-column** | flex-direction: column; |\n| **flex-xl-column-reverse** | flex-direction: column-reverse; |\n| **justify-start** | justify-content: flex-start; |\n| **justify-end** | justify-content: flex-end; |\n| **justify-center** | justify-content: center; |\n| **justify-space-between** | justify-content: space-between; |\n| **justify-space-around** | justify-content: space-around; |\n| **justify-space-evenly** | justify-content: space-evenly; |\n| **justify-sm-start** | justify-content: flex-start; |\n| **justify-sm-end** | justify-content: flex-end; |\n| **justify-sm-center** | justify-content: center; |\n| **justify-sm-space-between** | justify-content: space-between; |\n| **justify-sm-space-around** | justify-content: space-around; |\n| **justify-sm-space-evenly** | justify-content: space-evenly; |\n| **justify-md-start** | justify-content: flex-start; |\n| **justify-md-end** | justify-content: flex-end; |\n| **justify-md-center** | justify-content: center; |\n| **justify-md-space-between** | justify-content: space-between; |\n| **justify-md-space-around** | justify-content: space-around; |\n| **justify-md-space-evenly** | justify-content: space-evenly; |\n| **justify-lg-start** | justify-content: flex-start; |\n| **justify-lg-end** | justify-content: flex-end; |\n| **justify-lg-center** | justify-content: center; |\n| **justify-lg-space-between** | justify-content: space-between; |\n| **justify-lg-space-around** | justify-content: space-around; |\n| **justify-lg-space-evenly** | justify-content: space-evenly; |\n| **justify-xl-start** | justify-content: flex-start; |\n| **justify-xl-end** | justify-content: flex-end; |\n| **justify-xl-center** | justify-content: center; |\n| **justify-xl-space-between** | justify-content: space-between; |\n| **justify-xl-space-around** | justify-content: space-around; |\n| **justify-xl-space-evenly** | justify-content: space-evenly; |\n| **align-start** | align-items: flex-start; |\n| **align-end** | align-items: flex-end; |\n| **align-center** | align-items: center; |\n| **align-baseline** | align-items: baseline; |\n| **align-stretch** | align-items: stretch; |\n| **align-sm-start** | align-items: flex-start; |\n| **align-sm-end** | align-items: flex-end; |\n| **align-sm-center** | align-items: center; |\n| **align-sm-baseline** | align-items: baseline; |\n| **align-sm-stretch** | align-items: stretch; |\n| **align-md-start** | align-items: flex-start; |\n| **align-md-end** | align-items: flex-end; |\n| **align-md-center** | align-items: center; |\n| **align-md-baseline** | align-items: baseline; |\n| **align-md-stretch** | align-items: stretch; |\n| **align-lg-start** | align-items: flex-start; |\n| **align-lg-end** | align-items: flex-end; |\n| **align-lg-center** | align-items: center; |\n| **align-lg-baseline** | align-items: baseline; |\n| **align-lg-stretch** | align-items: stretch; |\n| **align-xl-start** | align-items: flex-start; |\n| **align-xl-end** | align-items: flex-end; |\n| **align-xl-center** | align-items: center; |\n| **align-xl-baseline** | align-items: baseline; |\n| **align-xl-stretch** | align-items: stretch; |\n| **align-self-start** | align-self: flex-start; |\n| **align-self-end** | align-self: flex-end; |\n| **align-self-center** | align-self: center; |\n| **align-self-baseline** | align-self: baseline; |\n| **align-self-auto** | align-self: auto; |\n| **align-self-stretch** | align-self: stretch; |\n| **align-self-sm-start** | align-self: flex-start; |\n| **align-self-sm-end** | align-self: flex-end; |\n| **align-self-sm-center** | align-self: center; |\n| **align-self-sm-baseline** | align-self: baseline; |\n| **align-self-sm-auto** | align-self: auto; |\n| **align-self-sm-stretch** | align-self: stretch; |\n| **align-self-md-start** | align-self: flex-start; |\n| **align-self-md-end** | align-self: flex-end; |\n| **align-self-md-center** | align-self: center; |\n| **align-self-md-baseline** | align-self: baseline; |\n| **align-self-md-auto** | align-self: auto; |\n| **align-self-md-stretch** | align-self: stretch; |\n| **align-self-lg-start** | align-self: flex-start; |\n| **align-self-lg-end** | align-self: flex-end; |\n| **align-self-lg-center** | align-self: center; |\n| **align-self-lg-baseline** | align-self: baseline; |\n| **align-self-lg-auto** | align-self: auto; |\n| **align-self-lg-stretch** | align-self: stretch; |\n| **align-self-xl-start** | align-self: flex-start; |\n| **align-self-xl-end** | align-self: flex-end; |\n| **align-self-xl-center** | align-self: center; |\n| **align-self-xl-baseline** | align-self: baseline; |\n| **align-self-xl-auto** | align-self: auto; |\n| **align-self-xl-stretch** | align-self: stretch; |\n| **flex-sm-nowrap** | flex-wrap: nowrap; |\n| **flex-sm-wrap** | flex-wrap: wrap; |\n| **flex-sm-wrap-reverse** | flex-wrap: wrap-reverse; |\n| **flex-md-nowrap** | flex-wrap: nowrap; |\n| **flex-md-wrap** | flex-wrap: wrap; |\n| **flex-md-wrap-reverse** | flex-wrap: wrap-reverse; |\n| **flex-lg-nowrap** | flex-wrap: nowrap; |\n| **flex-lg-wrap** | flex-wrap: wrap; |\n| **flex-lg-wrap-reverse** | flex-wrap: wrap-reverse; |\n| **flex-xl-nowrap** | flex-wrap: nowrap; |\n| **flex-xl-wrap** | flex-wrap: wrap; |\n| **flex-xl-wrap-reverse** | flex-wrap: wrap-reverse; |\n| **order-first** | order: -1; |\n| **order-0** | order: 0; |\n| **order-1** | order: 1; |\n| **order-2** | order: 2; |\n| **order-3** | order: 3; |\n| **order-4** | order: 4; |\n| **order-5** | order: 5; |\n| **order-6** | order: 6; |\n| **order-7** | order: 7; |\n| **order-8** | order: 8; |\n| **order-9** | order: 9; |\n| **order-10** | order: 10; |\n| **order-11** | order: 11; |\n| **order-12** | order: 12; |\n| **order-last** | order: 13; |\n| **order-sm-first** | order: -1; |\n| **order-sm-0** | order: 0; |\n| **order-sm-1** | order: 1; |\n| **order-sm-2** | order: 2; |\n| **order-sm-3** | order: 3; |\n| **order-sm-4** | order: 4; |\n| **order-sm-5** | order: 5; |\n| **order-sm-6** | order: 6; |\n| **order-sm-7** | order: 7; |\n| **order-sm-8** | order: 8; |\n| **order-sm-9** | order: 9; |\n| **order-sm-10** | order: 10; |\n| **order-sm-11** | order: 11; |\n| **order-sm-12** | order: 12; |\n| **order-sm-last** | order: 13; |\n| **order-md-first** | order: -1; |\n| **order-md-0** | order: 0; |\n| **order-md-1** | order: 1; |\n| **order-md-2** | order: 2; |\n| **order-md-3** | order: 3; |\n| **order-md-4** | order: 4; |\n| **order-md-5** | order: 5; |\n| **order-md-6** | order: 6; |\n| **order-md-7** | order: 7; |\n| **order-md-8** | order: 8; |\n| **order-md-9** | order: 9; |\n| **order-md-10** | order: 10; |\n| **order-md-11** | order: 11; |\n| **order-md-12** | order: 12; |\n| **order-md-last** | order: 13; |\n| **order-lg-first** | order: -1; |\n| **order-lg-0** | order: 0; |\n| **order-lg-1** | order: 1; |\n| **order-lg-2** | order: 2; |\n| **order-lg-3** | order: 3; |\n| **order-lg-4** | order: 4; |\n| **order-lg-5** | order: 5; |\n| **order-lg-6** | order: 6; |\n| **order-lg-7** | order: 7; |\n| **order-lg-8** | order: 8; |\n| **order-lg-9** | order: 9; |\n| **order-lg-10** | order: 10; |\n| **order-lg-11** | order: 11; |\n| **order-lg-12** | order: 12; |\n| **order-lg-last** | order: 13; |\n| **order-xl-first** | order: -1; |\n| **order-xl-0** | order: 0; |\n| **order-xl-1** | order: 1; |\n| **order-xl-2** | order: 2; |\n| **order-xl-3** | order: 3; |\n| **order-xl-4** | order: 4; |\n| **order-xl-5** | order: 5; |\n| **order-xl-6** | order: 6; |\n| **order-xl-7** | order: 7; |\n| **order-xl-8** | order: 8; |\n| **order-xl-9** | order: 9; |\n| **order-xl-10** | order: 10; |\n| **order-xl-11** | order: 11; |\n| **order-xl-12** | order: 12; |\n| **order-xl-last** | order: 13; |\n| **align-content-start** | align-content: flex-start; |\n| **align-content-end** | align-content: flex-end; |\n| **align-content-center** | align-content: center; |\n| **align-content-space-between** | align-content: space-between; |\n| **align-content-space-around** | align-content: space-around; |\n| **align-content-space-evenly** | align-content: space-evenly; |\n| **align-content-stretch** | align-content: stretch; |\n| **align-content-sm-start** | align-content: flex-start; |\n| **align-content-sm-end** | align-content: flex-end; |\n| **align-content-sm-center** | align-content: center; |\n| **align-content-sm-space-between** | align-content: space-between; |\n| **align-content-sm-space-around** | align-content: space-around; |\n| **align-content-sm-space-evenly** | align-content: space-evenly; |\n| **align-content-sm-stretch** | align-content: stretch; |\n| **align-content-md-start** | align-content: flex-start; |\n| **align-content-md-end** | align-content: flex-end; |\n| **align-content-md-center** | align-content: center; |\n| **align-content-md-space-between** | align-content: space-between; |\n| **align-content-md-space-around** | align-content: space-around; |\n| **align-content-md-space-evenly** | align-content: space-evenly; |\n| **align-content-md-stretch** | align-content: stretch; |\n| **align-content-lg-start** | align-content: flex-start; |\n| **align-content-lg-end** | align-content: flex-end; |\n| **align-content-lg-center** | align-content: center; |\n| **align-content-lg-space-between** | align-content: space-between; |\n| **align-content-lg-space-around** | align-content: space-around; |\n| **align-content-lg-space-evenly** | align-content: space-evenly; |\n| **align-content-lg-stretch** | align-content: stretch; |\n| **align-content-xl-start** | align-content: flex-start; |\n| **align-content-xl-end** | align-content: flex-end; |\n| **align-content-xl-center** | align-content: center; |\n| **align-content-xl-space-between** | align-content: space-between; |\n| **align-content-xl-space-around** | align-content: space-around; |\n| **align-content-xl-space-evenly** | align-content: space-evenly; |\n| **align-content-xl-stretch** | align-content: stretch; |\n| **flex-nowrap** | flex-wrap: nowrap; |\n| **flex-wrap** | flex-wrap: wrap; |\n| **flex-wrap-reverse** | flex-wrap: wrap-reverse; |\n| **flex-grow-0** | flex-grow: 0; |\n| **flex-grow-1** | flex-grow: 1; |\n| **flex-shrink-0** | flex-shrink: 0; |\n| **flex-shrink-1** | flex-shrink: 1; |\n| **flex-sm-grow-0** | flex-grow: 0; |\n| **flex-md-grow-0** | flex-grow: 0; |\n| **flex-lg-grow-0** | flex-grow: 0; |\n| **flex-xl-grow-0** | flex-grow: 0; |\n| **flex-sm-grow-1** | flex-grow: 1; |\n| **flex-md-grow-1** | flex-grow: 1; |\n| **flex-lg-grow-1** | flex-grow: 1; |\n| **flex-xl-grow-1** | flex-grow: 1; |\n| **flex-sm-shrink-0** | flex-shrink: 0; |\n| **flex-md-shrink-0** | flex-shrink: 0; |\n| **flex-lg-shrink-0** | flex-shrink: 0; |\n| **flex-xl-shrink-0** | flex-shrink: 0; |\n| **flex-sm-shrink-1** | flex-shrink: 1; |\n| **flex-md-shrink-1** | flex-shrink: 1; |\n| **flex-lg-shrink-1** | flex-shrink: 1; |\n| **flex-xl-shrink-1** | flex-shrink: 1; { style=\"max-height: 420px;\" fixed-header } |\n\n<PromotedEntry />\n\n## Usage\n\nUsing `display` utilities you can turn any element into a flexbox container transforming **direct children elements** into flex items. Using additional flex property utilities, you can customize their interaction even further.\n\n<ExamplesExample file=\"flex/flexbox\" />\n\n<ExamplesExample file=\"flex/flexbox-inline\" />\n\nYou can also customize flex utilities to apply based upon various breakpoints.\n\n### Caveats\n\n::: info\nIt is important to note that using any of the display classes above will result in any display style previously added being overwritten. This is because of the classes using `!important` in their display styling.\n:::\n\n## Flex shorthand\n\nThe flex utility classes can be used to modify the **flex** css property. This makes it easy to position flex items within a flex container.\n\n<ExamplesExample file=\"flex/flex-flex\" />\n\n## Flex direction\n\nBy default, `d-flex` applies `flex-direction: row` and can generally be omitted. However, there may be situations where you need to explicitly define it.\n\n<ExamplesExample file=\"flex/flex-direction\" />\n\nThe `flex-column` and `flex-column-reverse` utility classes can be used to change the orientation of the flexbox container.\n\n<ExamplesExample file=\"flex/flex-column\" />\n\n## Flex justify\n\nThe `justify-content` flex setting can be changed using the flex justify classes. This by default will modify the flexbox items on the **x-axis** but is reversed when using `flex-direction: column`, modifying the **y-axis**. Choose from `start` (browser default), `end`, `center`, `space-between`, `space-around`, or `space-evenly`.\n\n<ExamplesExample file=\"flex/flex-justify\" />\n\n## Flex align\n\nThe `align-items` flex setting can be changed using the flex align classes. This by default will modify the flexbox items on the **y-axis** but is reversed when using `flex-direction: column`, modifying the **x-axis**. Choose from `start`, `end`, `center`, `baseline`, or `stretch` (browser default).\n\n<ExamplesExample file=\"flex/flex-align\" />\n\n## Flex align self\n\nThe `align-self` flex setting can be changed using the flex align-self classes. This by default will modify individual flexbox items across the **y-axis** but is reversed when using `flex-direction: column`, modifying the **x-axis**. Choose from `start`, `end`, `center`, `baseline`, `stretch`, or `auto` (browser default, applies align-items property from flex container).\n\n<ExamplesExample file=\"flex/flex-align-self\" />\n\n## Auto margins\n\nUsing the margin helper classes in a flexbox container, you can control the positioning of flex items on the **x-axis** or **y-axis** when using `flex-row` or `flex-column` respectively.\n\n<ExamplesExample file=\"flex/margins\" />\n\n### Using align-items\n\nMixing `flex-direction: column` and `align-items`, you can utilize `.mt-auto` and `.mb-auto` helper classes to adjust flex item positioning.\n\n<ExamplesExample file=\"flex/margins-align-items\" />\n\n## Flex wrap\n\nBy default `.d-flex` does not provide any wrapping (behaves similarly to `flex-wrap: nowrap`). This can be modified by applying flex-wrap helper classes in the format `flex-{condition}` where condition can be `nowrap`, `wrap`, or `wrap-reverse`.\n\n<ExamplesExample file=\"flex/flex-nowrap\" />\n\n<ExamplesExample file=\"flex/flex-wrap\" />\n\n<ExamplesExample file=\"flex/flex-wrap-reverse\" />\n\nThese helper classes can also be applied in the format `flex-{breakpoint}-{condition}` to create more responsive variations based on breakpoints. The following combinations are available:\n\n## Flex order\n\nYou can change the visual order of flex items with the `order` utilities.\n\n<ExamplesExample file=\"flex/flex-order\" />\n\n## Flex align content\n\nThe `align-content` flex setting can be changed using the flex align-content classes. This by default will modify the wrapped flexbox content across the **y-axis** but is reversed when using `flex-direction: column`, modifying the **x-axis**. Choose from `start`, `end`, `center`, `space-between`, `space-around`, `space-evenly` or `stretch` (browser default).\n\n<ExamplesExample file=\"flex/flex-align-content\" />\n\n## Flex grow and shrink\n\nVuetify has helper classes for applying grow and shrink manually. These can be applied by adding the helper class in the format `flex-{condition}-{value}`, where condition can be either `grow` or `shrink` and value can be either `0` or `1`. The condition `grow` will permit an element to grow to fill available space, whereas `shrink` will permit an element to shrink down to only the space needs for its contents. However, this will only happen if the element must shrink to fit their container such as a container resize or being effected by a `flex-grow-1`. The value `0` will prevent the condition from occurring whereas `1` will permit the condition. The following classes are available:\n\n<ExamplesExample file=\"flex/grow-shrink\" />\n\nThese helper classes can also be applied in the format `flex-{breakpoint}-{condition}-{state}` to create more responsive variations based on breakpoints. The following combinations are available:\n"
  },
  {
    "path": "packages/docs/src/pages/en/styles/float.md",
    "content": "---\nmeta:\n  title: Float\n  description: Float helper classes allow you to control the float property of an element based upon the viewport size.\n  keywords: float helper classes, float classes, vuetify float\nrelated:\n  - /styles/text-and-typography/\n  - /styles/transitions/\n  - /styles/content/\nfeatures:\n  report: true\n---\n\n# Float\n\nApplies a custom float across any breakpoint with responsive float utilities.\n\n<PageFeatures />\n\n| Class | Properties |\n| - | - |\n| **float-left** | float: left; |\n| **float-right** | float: right; |\n| **float-start** | float: start; |\n| **float-end** | float: end; |\n| **float-none** | float: none; |\n| **float-sm-left** |  float: left; |\n| **float-sm-right** |  float: right; |\n| **float-sm-start** |  float: start; |\n| **float-sm-end** |  float: end; |\n| **float-sm-none** |  float: none; |\n| **float-md-left** |  float: left; |\n| **float-md-right** |  float: right; |\n| **float-md-start** |  float: start; |\n| **float-md-end** |  float: end; |\n| **float-md-none** |  float: none; |\n| **float-lg-left** |  float: left; |\n| **float-lg-right** |  float: right; |\n| **float-lg-start** |  float: start; |\n| **float-lg-end** |  float: end; |\n| **float-lg-none** |  float: none; |\n| **float-xl-left** |  float: left; |\n| **float-xl-right** |  float: right; |\n| **float-xl-start** |  float: start; |\n| **float-xl-end** |  float: end; |\n| **float-xl-none** |  float: none; { style=\"max-height: 420px;\" fixed-header } |\n\n<PromotedEntry />\n\n<FeaturesBreakpointsTable />\n\n## Usage\n\nFloat utility classes apply floating based upon the current viewport size using the [CSS float property](https://developer.mozilla.org/en-US/docs/Web/CSS/float).\n\n## Classes\n\nEasily toggle a float with a class:\n\n<ExamplesExample file=\"float/classes\" />\n\n## Responsive\n\nFloats can also be applied on a per breakpoint (viewport) basis.\n\n<ExamplesExample file=\"float/responsive\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/styles/layers.md",
    "content": "---\nemphasized: true\nmeta:\n  title: CSS Layers\n  description: Vuetify 4 uses cascade layers to avoid specificity problems\n  keywords: cascade layers, vuetify !important\nrelated:\n  - /features/sass-variables/\n---\n\n::: success\nThis feature was introduced in [v3.6.0 (Nebula)](/getting-started/release-notes/?version=v3.6.0)\n:::\n\n# CSS Layers\n\n[Cascade layers](https://developer.mozilla.org/en-US/docs/Web/CSS/@layer) are a modern CSS feature that makes it easier to write custom styles without having to deal with specificity issues and `!important`.\n\nImport order of stylesheets becomes much more important with layers, therefore `import 'vuetify/styles'` or a file containing `@use 'vuetify'` **must** be loaded *before* any components or the CSS reset will take precedence over component styles and break everything. If you have separate plugin files make sure to import the vuetify plugin before `App.vue` or any other components.\n\nVuetify defines five layers containing all the framework styles:\n\n```css\n@layer vuetify-core, vuetify-components, vuetify-overrides, vuetify-utilities, vuetify-final;\n```\n\n- core: This layer has the CSS reset and a few global styles for fonts.\n- components: Does what it says on the tin, the majority of component styles live here.\n- overrides: Contextual styles for nested components, for example `.v-dialog > .v-card`. This layer replaces rules that would have used `!important` in Vuetify 3.\n- utilities: Theme and helper classes such as `.bg-primary` and `.pa-4`.\n- final: Transitions, and rules that must always take priority like `forced-colors`.\n\nYour own styles will always override vuetify's if you don't use `@layer` yourself, or you can specify an order for custom layers in a stylesheet loaded before vuetify. Vuetify's layers must remain in the same order for everything to display correctly, but you can add your own between or around them.\n\n```css { resource=\"src/styles/layers.css\" }\n@layer base,\n  vuetify-core,\n  vuetify-components,\n  components,\n  vuetify-overrides,\n  overrides,\n  vuetify-utilities,\n  vuetify-final;\n```\n\n## Utilities group\n\nThe `vuetify-utilities` layer itself contains nested sublayers to control the order of utility styles:\n\n```css\n@layer vuetify-utilities {\n  @layer theme-base;\n  @layer typography;\n  @layer helpers;\n  @layer theme-background;\n  @layer theme-foreground;\n}\n```\n\n- **theme-base**: CSS custom properties for theme colors and other variables, applied to `:root` or a scoped selector.\n- **typography**: Typography classes (`.text-headline-large`, `.text-body-small`, etc.)\n- **helpers**: Utility classes like spacing (`.pa-4`, `.ma-2`), display (`.d-flex`), and text alignment (`.text-center`).\n- **theme-background**: Background color utilities such as `.bg-primary` and `.bg-surface`.\n- **theme-foreground**: Text color utilities such as `.text-primary` and `.text-error`.\n\nThis ordering ensures that explicit color utilities (background and foreground) can override helper classes when both are applied to the same element.\n"
  },
  {
    "path": "packages/docs/src/pages/en/styles/opacity.md",
    "content": "---\nmeta:\n  title: Opacity\n  description: Use opacity utilities to quickly style the opacity of any element.\n  keywords: opacity classes, opacity utilities, vuetify opacity helper classes\nrelated:\n  - /styles/border-radius/\n  - /styles/display/\n  - /styles/content/\nfeatures:\n  report: true\n---\n\n# Opacity\n\nUtilities for controlling the opacity of elements in your application.\n\n<PageFeatures />\n\n| Class | Properties |\n| - | - |\n| **opacity-0** | opacity: 0; |\n| **opacity-10** | opacity: .1; |\n| **opacity-20** | opacity: .2; |\n| **opacity-30** | opacity: .3; |\n| **opacity-40** | opacity: .4; |\n| **opacity-50** | opacity: .5; |\n| **opacity-60** | opacity: .6; |\n| **opacity-70** | opacity: .7; |\n| **opacity-80** | opacity: .8; |\n| **opacity-90** | opacity: .9; |\n| **opacity-100** | opacity: 1; |\n| **opacity-hover** | opacity: var(--v-hover-opacity); |\n| **opacity-focus** | opacity: var(--v-focus-opacity); |\n| **opacity-selected** | opacity: var(--v-selected-opacity); |\n| **opacity-activated** | opacity: var(--v-activated-opacity); |\n| **opacity-pressed** | opacity: var(--v-pressed-opacity); |\n| **opacity-dragged** | opacity: var(--v-dragged-opacity); { style=\"max-height: 420px;\" fixed-header } |\n\n<PromotedEntry />\n\n## Usage\n\nThe `opacity` utilities allow you to quickly change the opacity of any element.\n\n<ExamplesExample file=\"opacity/misc-opacity\" />\n\n### Hover\n\nUsing the [v-hover](/components/hover/) component, conditionally apply an opacity class when the element is hovered over.\n\n<ExamplesExample file=\"opacity/misc-hover\" />\n\n## SASS variables\n\nYou can also use the following SASS variables to customize the opacity color and width:\n\n```sass { resource=\"src/styles/settings.scss\" }\n@use 'vuetify/settings' with (\n  $opacities: (\n    hover: var(--v-hover-opacity),\n    focus: var(--v-focus-opacity),\n    selected: var(--v-selected-opacity),\n    activated: var(--v-activated-opacity),\n    pressed: var(--v-pressed-opacity),\n    dragged: var(--v-dragged-opacity),\n    0: 0,\n    10: .1,\n    20: .2,\n    30: .3,\n    40: .4,\n    50: .5,\n    60: .6,\n    70: .7,\n    80: .8,\n    90: .9,\n    100: 1\n  )\n);\n```\n\nDisable opacity class generation by setting the $opacities variable to **false**.\n\n```sass { resource=\"src/styles/settings.scss\" }\n@use 'vuetify/settings' with (\n  $opacities: false\n);\n```\n"
  },
  {
    "path": "packages/docs/src/pages/en/styles/overflow.md",
    "content": "---\nmeta:\n  title: Overflow\n  description: Overflow helper classes allow you to configure how content overflows when it becomes too large.\n  keywords: overflow helper classes, overflow classes, vuetify overflow\nrelated:\n  - /styles/elevation/\n  - /styles/content/\n  - /components/grids/\nfeatures:\n  report: true\n---\n\n# Overflow\n\nConfigure how content overflows when it becomes out of container bounds.\n\n<PageFeatures />\n\n| Class | Properties |\n| - | - |\n| **overflow** | overflow: auto; |\n| **overflow-auto** | overflow: auto; |\n| **overflow-hidden** | overflow: hidden; |\n| **overflow-visible** | overflow: visible; |\n| **overflow-x** | overflow-x: auto; |\n| **overflow-x-auto** | overflow-x: auto; |\n| **overflow-x-hidden** | overflow-x: hidden; |\n| **overflow-x-scroll** | overflow-x: scroll; |\n| **overflow-x-visible** | overflow-x: visible; |\n| **overflow-y** | overflow-y: auto; |\n| **overflow-y-auto** | overflow-y: auto; |\n| **overflow-y-hidden** | overflow-y: hidden; |\n| **overflow-y-scroll** | overflow-y: scroll; { style=\"max-height: 420px;\" fixed-header } |\n| **overflow-y-visible** | overflow-y: visible; |\n\n<PromotedEntry />\n\n## Usage\n\nSpecify the elements `overflow`, `overflow-x`, or `overflow-y` property. These classes can be applied using the following format: `{overflow}-{value}`. Where **overflow** refers to the type: `overflow`, `overflow-x` or `overflow-y` and **value** can be one of: `auto`, `hidden`, or `visible`\n\n### Overflow property\n\n`overflow-auto` is used to add scrollbars to an element when its content overflows the bounds. while `overflow-hidden` is used to clip any content that overflows the bounds. `overflow-visible` will prevent content from being clipped even when it overflows the bounds.\n\n<ExamplesExample file=\"overflow/overflow\" />\n\n### Overflow X property\n\n**overflow-x** can be used to specify horizontal overflows to an element if needed.\n\n<ExamplesExample file=\"overflow/overflow-x\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/styles/position.md",
    "content": "---\nmeta:\n  title: Position\n  description: Use position utilities to quickly style the positioning of any element.\n  keywords: position classes, positioning utilities, vuetify position helper classes\nrelated:\n  - /styles/display/\n  - /styles/spacing/\n  - /styles/flex/\nfeatures:\n  report: true\n---\n\n# Position\n\nUtilities for controlling the positioning of elements in your application.\n\n<PageFeatures />\n\n| Class | Properties |\n| - | - |\n| **position-static** | position: static; |\n| **position-relative** | position: relative; |\n| **position-absolute** | position: absolute; |\n| **position-fixed** | position: fixed; |\n| **position-sticky** | position: sticky; |\n| **top-0** | top: 0; |\n| **right-0** | right: 0; |\n| **bottom-0** | bottom: 0; |\n| **left-0** | left: 0; |\n\n<PromotedEntry />\n\n## Usage\n\nThe `position` utilities allow you to quickly style the positioning of any element. These classes can be used to apply the `position` and `top`, `right`, `bottom`, and `left` properties to an element.\n\n### Static\n\nThe default position value for all elements is `static`. This means that the element is positioned according to the normal flow of the document. The `top`, `right`, `bottom`, `left` properties have no effect on a statically positioned element.\n\n<ExamplesExample file=\"position/static\" />\n\n### Relative\n\nThe `position-relative` class allows you to position an element relative to its normal position in the document. This means that the `top`, `right`, `bottom`, and `left` properties can be used to move the element from its normal position.\n\n<ExamplesExample file=\"position/relative\" />\n\n### Absolute\n\nThe `position-absolute` class allows you to position an element relative to its closest positioned ancestor. If no positioned ancestor is found, the element is positioned relative to the document body.\n\n<ExamplesExample file=\"position/absolute\" />\n\n### Fixed\n\nThe `position-fixed` class allows you to position an element relative to the viewport. This means that the element will stay in the same position even when the page is scrolled.\n\n<ExamplesExample file=\"position/fixed\" />\n\n### Sticky\n\nThe `position-sticky` class allows you to position an element based on the user's scroll position. The element is treated as `relative` until it crosses a specified threshold, at which point it is treated as `fixed`.\n\n<ExamplesExample file=\"position/sticky\" />\n\n## SASS Variables\n\nDisable position class generation by setting $position, $top, $right, $bottom, and $left to **false**.\n\n```scss { resource=\"src/styles/settings.scss\" }\n@use 'vuetify/settings' with (\n  $utilities: (\n    position: false,\n    top: false,\n    right: false,\n    bottom: false,\n    left: false\n  )\n);\n"
  },
  {
    "path": "packages/docs/src/pages/en/styles/sizing.md",
    "content": "---\nmeta:\n  title: Sizing\n  description: Modify the dimension of block level elements using one of the Vuetify sizing utility classes.\n  keywords: css height, css width, sizing elements, element dimensions\nrelated:\n  - /styles/content/\n  - /styles/flex/\n  - /styles/text-and-typography/\nfeatures:\n  report: true\n---\n\n# Sizing\n\nSizing utility classes are used to modify the dimensions of an element.\n\n<PageFeatures />\n\n| Class        | Description      |\n| ------------ |------------------|\n| **h-auto**   | height: auto   |\n| **h-screen** | height: 100vh |\n| **h-0**      | height: 0      |\n| **h-25**     | height: 25%    |\n| **h-50**     | height: 50%    |\n| **h-75**     | height: 75%    |\n| **h-100**    | height: 100%   |\n| **fill-height** | height: 100% |\n| **height-screen** | height: 100dvh |\n| **w-auto**   | width: auto    |\n| **w-0**      | width: 0       |\n| **w-33**     | width: 33% |\n| **w-25**     | width: 25%     |\n| **w-50**     | width: 50%     |\n| **w-66**     | width: 66% |\n| **w-75**     | width: 75%     |\n| **w-100**    | width: 100% { style=\"max-height: 420px;\" fixed-header }  |\n\n<PromotedEntry />\n\n## Usage\n\nThe sizing utility classes allow you to quickly style the dimensions of any element. These classes can be used to apply the `height` and `width` properties to an element.\n\n### Height\n\nSpecify the `height` property of **block level elements** with a utility class. The following classes are applied using the format `.{prefix}-{size}` ; where _prefix_ is **h** and _size_ is the value.\n\n<ExamplesExample file=\"sizing/height\" />\n\n### Width\n\nSpecify the `width` property of **block level elements** with a utility class. The following classes are applied using the format `.{prefix}-{size}` ; where _prefix_ is **w** and _size_ is the value.\n\n| Class        | Description     |\n\n<ExamplesExample file=\"sizing/width\" />\n\n## SASS Variables\n\nYou can also use the following SASS variables to customize the generated height and width classes:\n\n```scss { resource=\"src/styles/settings.scss\" }\n@use 'vuetify/settings' with (\n  $utilities: (\n    \"fill-height\": (\n      property: height,\n      class: fill,\n      values: (\n        height: 100%\n      )\n    ),\n    \"height\": (\n      property: height,\n      responsive: true,\n      class: h,\n      values: (\n        auto: auto,\n        screen: 100vh,\n        0: 0,\n        25: 25%,\n        50: 50%,\n        75: 75%,\n        100: 100%\n      )\n    ),\n    \"height-screen\": (\n      property: height,\n      class: h,\n      values: (\n        screen: 100dvh\n      )\n    ),\n    \"width\": (\n      property: width,\n      responsive: true,\n      class: w,\n      values: (\n        auto: auto,\n        0: 0,\n        25: 25%,\n        33: 33%,\n        50: 50%,\n        66: 66%,\n        75: 75%,\n        100: 100%\n      )\n    )\n  )\n);\n```\n\nDisable height/width class generation by setting the the fill-height, height, height-screen, and, width variables to **false**.\n\n```scss { resource=\"src/styles/settings.scss\" }\n@use 'vuetify/settings' with (\n  $utilities: (\n    \"fill-height\": false,\n    \"height\": false,\n    \"height-screen\": false,\n    \"width\": false\n  )\n);\n```\n"
  },
  {
    "path": "packages/docs/src/pages/en/styles/spacing.md",
    "content": "---\nmeta:\n  title: Spacing\n  description: Spacing helper classes allow you to apply margin or padding to any element in increments from 1 to 5.\n  keywords: spacing helper classes, spacing classes, vuetify spacing\nrelated:\n  - /styles/elevation/\n  - /styles/content/\n  - /components/grids/\nfeatures:\n  report: true\n---\n\n# Spacing\n\nUpdate your layout without creating new classes. Spacing helpers are useful for modifying the padding and margin of an element.\n\n<PageFeatures />\n\n| Class | Properties |\n| - | - |\n| **ga-0** | gap: 0; |\n| **ga-1** | gap: 4px; |\n| **ga-2** | gap: 8px; |\n| **ga-3** | gap: 12px; |\n| **ga-4** | gap: 16px; |\n| **ga-5** | gap: 20px; |\n| **ga-6** | gap: 24px; |\n| **ga-7** | gap: 28px; |\n| **ga-8** | gap: 32px; |\n| **ga-9** | gap: 36px; |\n| **ga-10** | gap: 40px; |\n| **ga-11** | gap: 44px; |\n| **ga-12** | gap: 48px; |\n| **ga-13** | gap: 52px; |\n| **ga-14** | gap: 56px; |\n| **ga-15** | gap: 60px; |\n| **ga-16** | gap: 64px; |\n| **ma-0** | margin: 0; |\n| **ma-1** | margin: 4px; |\n| **ma-2** | margin: 8px; |\n| **ma-3** | margin: 12px; |\n| **ma-4** | margin: 16px; |\n| **ma-5** | margin: 20px; |\n| **ma-6** | margin: 24px; |\n| **ma-7** | margin: 28px; |\n| **ma-8** | margin: 32px; |\n| **ma-9** | margin: 36px; |\n| **ma-10** | margin: 40px; |\n| **ma-11** | margin: 44px; |\n| **ma-12** | margin: 48px; |\n| **ma-13** | margin: 52px; |\n| **ma-14** | margin: 56px; |\n| **ma-15** | margin: 60px; |\n| **ma-16** | margin: 64px; |\n| **ml-0** | margin-left: 0; |\n| **ml-1** | margin-left: 4px; |\n| **ml-2** | margin-left: 8px; |\n| **ml-3** | margin-left: 12px; |\n| **ml-4** | margin-left: 16px; |\n| **ml-5** | margin-left: 20px; |\n| **ml-6** | margin-left: 24px; |\n| **ml-7** | margin-left: 28px; |\n| **ml-8** | margin-left: 32px; |\n| **ml-9** | margin-left: 36px; |\n| **ml-10** | margin-left: 40px; |\n| **ml-11** | margin-left: 44px; |\n| **ml-12** | margin-left: 48px; |\n| **ml-13** | margin-left: 52px; |\n| **ml-14** | margin-left: 56px; |\n| **ml-15** | margin-left: 60px; |\n| **ml-16** | margin-left: 64px; |\n| **ms-0** | margin-left: 0; (LTR) / margin-right: 0; (RTL) |\n| **ms-1** | margin-left: 4px; (LTR) / margin-right: 4px; (RTL) |\n| **ms-2** | margin-left: 8px; (LTR) / margin-right: 8px; (RTL) |\n| **ms-3** | margin-left: 12px; (LTR) / margin-right: 12px; (RTL) |\n| **ms-4** | margin-left: 16px; (LTR) / margin-right: 16px; (RTL) |\n| **ms-5** | margin-left: 20px; (LTR) / margin-right: 20px; (RTL) |\n| **ms-6** | margin-left: 24px; (LTR) / margin-right: 24px; (RTL) |\n| **ms-7** | margin-left: 28px; (LTR) / margin-right: 28px; (RTL) |\n| **ms-8** | margin-left: 32px; (LTR) / margin-right: 32px; (RTL) |\n| **ms-9** | margin-left: 36px; (LTR) / margin-right: 36px; (RTL) |\n| **ms-10** | margin-left: 40px; (LTR) / margin-right: 40px; (RTL) |\n| **ms-11** | margin-left: 44px; (LTR) / margin-right: 44px; (RTL) |\n| **ms-12** | margin-left: 48px; (LTR) / margin-right: 48px; (RTL) |\n| **ms-13** | margin-left: 52px; (LTR) / margin-right: 52px; (RTL) |\n| **ms-14** | margin-left: 56px; (LTR) / margin-right: 56px; (RTL) |\n| **ms-15** | margin-left: 60px; (LTR) / margin-right: 60px; (RTL) |\n| **ms-16** | margin-left: 64px; (LTR) / margin-right: 64px; (RTL) |\n| **mt-0** | margin-top: 0; |\n| **mt-1** | margin-top: 4px; |\n| **mt-2** | margin-top: 8px; |\n| **mt-3** | margin-top: 12px; |\n| **mt-4** | margin-top: 16px; |\n| **mt-5** | margin-top: 20px; |\n| **mt-6** | margin-top: 24px; |\n| **mt-7** | margin-top: 28px; |\n| **mt-8** | margin-top: 32px; |\n| **mt-9** | margin-top: 36px; |\n| **mt-10** | margin-top: 40px; |\n| **mt-11** | margin-top: 44px; |\n| **mt-12** | margin-top: 48px; |\n| **mt-13** | margin-top: 52px; |\n| **mt-14** | margin-top: 56px; |\n| **mt-15** | margin-top: 60px; |\n| **mt-16** | margin-top: 64px; |\n| **mr-0** | margin-right: 0; |\n| **mr-1** | margin-right: 4px; |\n| **mr-2** | margin-right: 8px; |\n| **mr-3** | margin-right: 12px; |\n| **mr-4** | margin-right: 16px; |\n| **mr-5** | margin-right: 20px; |\n| **mr-6** | margin-right: 24px; |\n| **mr-7** | margin-right: 28px; |\n| **mr-8** | margin-right: 32px; |\n| **mr-9** | margin-right: 36px; |\n| **mr-10** | margin-right: 40px; |\n| **mr-11** | margin-right: 44px; |\n| **mr-12** | margin-right: 48px; |\n| **mr-13** | margin-right: 52px; |\n| **mr-14** | margin-right: 56px; |\n| **mr-15** | margin-right: 60px; |\n| **mr-16** | margin-right: 64px; |\n| **me-0** | margin-right: 0; (LTR) / margin-left: 0; (RTL) |\n| **me-1** | margin-right: 4px; (LTR) / margin-left: 4px; (RTL) |\n| **me-2** | margin-right: 8px; (LTR) / margin-left: 8px; (RTL) |\n| **me-3** | margin-right: 12px; (LTR) / margin-left: 12px; (RTL) |\n| **me-4** | margin-right: 16px; (LTR) / margin-left: 16px; (RTL) |\n| **me-5** | margin-right: 20px; (LTR) / margin-left: 20px; (RTL) |\n| **me-6** | margin-right: 24px; (LTR) / margin-left: 24px; (RTL) |\n| **me-7** | margin-right: 28px; (LTR) / margin-left: 28px; (RTL) |\n| **me-8** | margin-right: 32px; (LTR) / margin-left: 32px; (RTL) |\n| **me-9** | margin-right: 36px; (LTR) / margin-left: 36px; (RTL) |\n| **me-10** | margin-right: 40px; (LTR) / margin-left: 40px; (RTL) |\n| **me-11** | margin-right: 44px; (LTR) / margin-left: 44px; (RTL) |\n| **me-12** | margin-right: 48px; (LTR) / margin-left: 48px; (RTL) |\n| **me-13** | margin-right: 52px; (LTR) / margin-left: 52px; (RTL) |\n| **me-14** | margin-right: 56px; (LTR) / margin-left: 56px; (RTL) |\n| **me-15** | margin-right: 60px; (LTR) / margin-left: 60px; (RTL) |\n| **me-16** | margin-right: 64px; (LTR) / margin-left: 64px; (RTL) |\n| **mb-0** | margin-bottom: 0; |\n| **mb-1** | margin-bottom: 4px; |\n| **mb-2** | margin-bottom: 8px; |\n| **mb-3** | margin-bottom: 12px; |\n| **mb-4** | margin-bottom: 16px; |\n| **mb-5** | margin-bottom: 20px; |\n| **mb-6** | margin-bottom: 24px; |\n| **mb-7** | margin-bottom: 28px; |\n| **mb-8** | margin-bottom: 32px; |\n| **mb-9** | margin-bottom: 36px; |\n| **mb-10** | margin-bottom: 40px; |\n| **mb-11** | margin-bottom: 44px; |\n| **mb-12** | margin-bottom: 48px; |\n| **mb-13** | margin-bottom: 52px; |\n| **mb-14** | margin-bottom: 56px; |\n| **mb-15** | margin-bottom: 60px; |\n| **mb-16** | margin-bottom: 64px; |\n| **ma-n1** | margin: -4px; |\n| **ma-n2** | margin: -8px; |\n| **ma-n3** | margin: -12px; |\n| **ma-n4** | margin: -16px; |\n| **ma-n5** | margin: -20px; |\n| **ma-n6** | margin: -24px; |\n| **ma-n7** | margin: -28px; |\n| **ma-n8** | margin: -32px; |\n| **ma-n9** | margin: -36px; |\n| **ma-n10** | margin: -40px; |\n| **ma-n11** | margin: -44px; |\n| **ma-n12** | margin: -48px; |\n| **ma-n13** | margin: -52px; |\n| **ma-n14** | margin: -56px; |\n| **ma-n15** | margin: -60px; |\n| **ma-n16** | margin: -64px; |\n| **ml-n1** | margin-left: -4px; |\n| **ml-n2** | margin-left: -8px; |\n| **ml-n3** | margin-left: -12px; |\n| **ml-n4** | margin-left: -16px; |\n| **ml-n5** | margin-left: -20px; |\n| **ml-n6** | margin-left: -24px; |\n| **ml-n7** | margin-left: -28px; |\n| **ml-n8** | margin-left: -32px; |\n| **ml-n9** | margin-left: -36px; |\n| **ml-n10** | margin-left: -40px; |\n| **ml-n11** | margin-left: -44px; |\n| **ml-n12** | margin-left: -48px; |\n| **ml-n13** | margin-left: -52px; |\n| **ml-n14** | margin-left: -56px; |\n| **ml-n15** | margin-left: -60px; |\n| **ml-n16** | margin-left: -64px; |\n| **ms-n1** | margin-left: -4px; (LTR) / margin-right: -4px; (RTL) |\n| **ms-n2** | margin-left: -8px; (LTR) / margin-right: -8px; (RTL) |\n| **ms-n3** | margin-left: -12px; (LTR) / margin-right: -12px; (RTL) |\n| **ms-n4** | margin-left: -16px; (LTR) / margin-right: -16px; (RTL) |\n| **ms-n5** | margin-left: -20px; (LTR) / margin-right: -20px; (RTL) |\n| **ms-n6** | margin-left: -24px; (LTR) / margin-right: -24px; (RTL) |\n| **ms-n7** | margin-left: -28px; (LTR) / margin-right: -28px; (RTL) |\n| **ms-n8** | margin-left: -32px; (LTR) / margin-right: -32px; (RTL) |\n| **ms-n9** | margin-left: -36px; (LTR) / margin-right: -36px; (RTL) |\n| **ms-n10** | margin-left: -40px; (LTR) / margin-right: -40px; (RTL) |\n| **ms-n11** | margin-left: -44px; (LTR) / margin-right: -44px; (RTL) |\n| **ms-n12** | margin-left: -48px; (LTR) / margin-right: -48px; (RTL) |\n| **ms-n13** | margin-left: -52px; (LTR) / margin-right: -52px; (RTL) |\n| **ms-n14** | margin-left: -56px; (LTR) / margin-right: -56px; (RTL) |\n| **ms-n15** | margin-left: -60px; (LTR) / margin-right: -60px; (RTL) |\n| **ms-n16** | margin-left: -64px; (LTR) / margin-right: -64px; (RTL) |\n| **mt-n1** | margin-top: -4px; |\n| **mt-n2** | margin-top: -8px; |\n| **mt-n3** | margin-top: -12px; |\n| **mt-n4** | margin-top: -16px; |\n| **mt-n5** | margin-top: -20px; |\n| **mt-n6** | margin-top: -24px; |\n| **mt-n7** | margin-top: -28px; |\n| **mt-n8** | margin-top: -32px; |\n| **mt-n9** | margin-top: -36px; |\n| **mt-n10** | margin-top: -40px; |\n| **mt-n11** | margin-top: -44px; |\n| **mt-n12** | margin-top: -48px; |\n| **mt-n13** | margin-top: -52px; |\n| **mt-n14** | margin-top: -56px; |\n| **mt-n15** | margin-top: -60px; |\n| **mt-n16** | margin-top: -64px; |\n| **mr-n1** | margin-right: -4px; |\n| **mr-n2** | margin-right: -8px; |\n| **mr-n3** | margin-right: -12px; |\n| **mr-n4** | margin-right: -16px; |\n| **mr-n5** | margin-right: -20px; |\n| **mr-n6** | margin-right: -24px; |\n| **mr-n7** | margin-right: -28px; |\n| **mr-n8** | margin-right: -32px; |\n| **mr-n9** | margin-right: -36px; |\n| **mr-n10** | margin-right: -40px; |\n| **mr-n11** | margin-right: -44px; |\n| **mr-n12** | margin-right: -48px; |\n| **mr-n13** | margin-right: -52px; |\n| **mr-n14** | margin-right: -56px; |\n| **mr-n15** | margin-right: -60px; |\n| **mr-n16** | margin-right: -64px; |\n| **me-n1** | margin-right: -4px; (LTR) / margin-left: -4px; (RTL) |\n| **me-n2** | margin-right: -8px; (LTR) / margin-left: -8px; (RTL) |\n| **me-n3** | margin-right: -12px; (LTR) / margin-left: -12px; (RTL) |\n| **me-n4** | margin-right: -16px; (LTR) / margin-left: -16px; (RTL) |\n| **me-n5** | margin-right: -20px; (LTR) / margin-left: -20px; (RTL) |\n| **me-n6** | margin-right: -24px; (LTR) / margin-left: -24px; (RTL) |\n| **me-n7** | margin-right: -28px; (LTR) / margin-left: -28px; (RTL) |\n| **me-n8** | margin-right: -32px; (LTR) / margin-left: -32px; (RTL) |\n| **me-n9** | margin-right: -36px; (LTR) / margin-left: -36px; (RTL) |\n| **me-n10** | margin-right: -40px; (LTR) / margin-left: -40px; (RTL) |\n| **me-n11** | margin-right: -44px; (LTR) / margin-left: -44px; (RTL) |\n| **me-n12** | margin-right: -48px; (LTR) / margin-left: -48px; (RTL) |\n| **me-n13** | margin-right: -52px; (LTR) / margin-left: -52px; (RTL) |\n| **me-n14** | margin-right: -56px; (LTR) / margin-left: -56px; (RTL) |\n| **me-n15** | margin-right: -60px; (LTR) / margin-left: -60px; (RTL) |\n| **me-n16** | margin-right: -64px; (LTR) / margin-left: -64px; (RTL) |\n| **mb-n1** | margin-bottom: -4px; |\n| **mb-n2** | margin-bottom: -8px; |\n| **mb-n3** | margin-bottom: -12px; |\n| **mb-n4** | margin-bottom: -16px; |\n| **mb-n5** | margin-bottom: -20px; |\n| **mb-n6** | margin-bottom: -24px; |\n| **mb-n7** | margin-bottom: -28px; |\n| **mb-n8** | margin-bottom: -32px; |\n| **mb-n9** | margin-bottom: -36px; |\n| **mb-n10** | margin-bottom: -40px; |\n| **mb-n11** | margin-bottom: -44px; |\n| **mb-n12** | margin-bottom: -48px; |\n| **mb-n13** | margin-bottom: -52px; |\n| **mb-n14** | margin-bottom: -56px; |\n| **mb-n15** | margin-bottom: -60px; |\n| **mb-n16** | margin-bottom: -64px; |\n| **ma-auto** | margin: auto; |\n| **ml-auto** | margin-left: auto; |\n| **ms-auto** | margin-left: auto; (LTR) / margin-right: auto; (RTL) |\n| **mt-auto** | margin-top: auto; |\n| **mr-auto** | margin-right: auto; |\n| **me-auto** | margin-right: auto; (LTR) / margin-left: auto; (RTL) |\n| **mb-auto** | margin-bottom: auto; |\n| **pa-0** | padding: 0; |\n| **pa-1** | padding: 4px; |\n| **pa-2** | padding: 8px; |\n| **pa-3** | padding: 12px; |\n| **pa-4** | padding: 16px; |\n| **pa-5** | padding: 20px; |\n| **pa-6** | padding: 24px; |\n| **pa-7** | padding: 28px; |\n| **pa-8** | padding: 32px; |\n| **pa-9** | padding: 36px; |\n| **pa-10** | padding: 40px; |\n| **pa-11** | padding: 44px; |\n| **pa-12** | padding: 48px; |\n| **pa-13** | padding: 52px; |\n| **pa-14** | padding: 56px; |\n| **pa-15** | padding: 60px; |\n| **pa-16** | padding: 64px; |\n| **pl-0** | padding-left: 0; |\n| **pl-1** | padding-left: 4px; |\n| **pl-2** | padding-left: 8px; |\n| **pl-3** | padding-left: 12px; |\n| **pl-4** | padding-left: 16px; |\n| **pl-5** | padding-left: 20px; |\n| **pl-6** | padding-left: 24px; |\n| **pl-7** | padding-left: 28px; |\n| **pl-8** | padding-left: 32px; |\n| **pl-9** | padding-left: 36px; |\n| **pl-10** | padding-left: 40px; |\n| **pl-11** | padding-left: 44px; |\n| **pl-12** | padding-left: 48px; |\n| **pl-13** | padding-left: 52px; |\n| **pl-14** | padding-left: 56px; |\n| **pl-15** | padding-left: 60px; |\n| **pl-16** | padding-left: 64px; |\n| **ps-0** | padding-left: 0; (LTR) / padding-right: 0; (RTL) |\n| **ps-1** | padding-left: 4px; (LTR) / padding-right: 4px; (RTL) |\n| **ps-2** | padding-left: 8px; (LTR) / padding-right: 8px; (RTL) |\n| **ps-3** | padding-left: 12px; (LTR) / padding-right: 12px; (RTL) |\n| **ps-4** | padding-left: 16px; (LTR) / padding-right: 16px; (RTL) |\n| **ps-5** | padding-left: 20px; (LTR) / padding-right: 20px; (RTL) |\n| **ps-6** | padding-left: 24px; (LTR) / padding-right: 24px; (RTL) |\n| **ps-7** | padding-left: 28px; (LTR) / padding-right: 28px; (RTL) |\n| **ps-8** | padding-left: 32px; (LTR) / padding-right: 32px; (RTL) |\n| **ps-9** | padding-left: 36px; (LTR) / padding-right: 36px; (RTL) |\n| **ps-10** | padding-left: 40px; (LTR) / padding-right: 40px; (RTL) |\n| **ps-11** | padding-left: 44px; (LTR) / padding-right: 44px; (RTL) |\n| **ps-12** | padding-left: 48px; (LTR) / padding-right: 48px; (RTL) |\n| **ps-13** | padding-left: 52px; (LTR) / padding-right: 52px; (RTL) |\n| **ps-14** | padding-left: 56px; (LTR) / padding-right: 56px; (RTL) |\n| **ps-15** | padding-left: 60px; (LTR) / padding-right: 60px; (RTL) |\n| **ps-16** | padding-left: 64px; (LTR) / padding-right: 64px; (RTL) |\n| **pt-0** | padding-top: 0; |\n| **pt-1** | padding-top: 4px; |\n| **pt-2** | padding-top: 8px; |\n| **pt-3** | padding-top: 12px; |\n| **pt-4** | padding-top: 16px; |\n| **pt-5** | padding-top: 20px; |\n| **pt-6** | padding-top: 24px; |\n| **pt-7** | padding-top: 28px; |\n| **pt-8** | padding-top: 32px; |\n| **pt-9** | padding-top: 36px; |\n| **pt-10** | padding-top: 40px; |\n| **pt-11** | padding-top: 44px; |\n| **pt-12** | padding-top: 48px; |\n| **pt-13** | padding-top: 52px; |\n| **pt-14** | padding-top: 56px; |\n| **pt-15** | padding-top: 60px; |\n| **pt-16** | padding-top: 64px; |\n| **pr-0** | padding-right: 0; |\n| **pr-1** | padding-right: 4px; |\n| **pr-2** | padding-right: 8px; |\n| **pr-3** | padding-right: 12px; |\n| **pr-4** | padding-right: 16px; |\n| **pr-5** | padding-right: 20px; |\n| **pr-6** | padding-right: 24px; |\n| **pr-7** | padding-right: 28px; |\n| **pr-8** | padding-right: 32px; |\n| **pr-9** | padding-right: 36px; |\n| **pr-10** | padding-right: 40px; |\n| **pr-11** | padding-right: 44px; |\n| **pr-12** | padding-right: 48px; |\n| **pr-13** | padding-right: 52px; |\n| **pr-14** | padding-right: 56px; |\n| **pr-15** | padding-right: 60px; |\n| **pr-16** | padding-right: 64px; |\n| **pe-0** | padding-right: 0; (LTR) / padding-left: 0; (RTL) |\n| **pe-1** | padding-right: 4px; (LTR) / padding-left: 4px; (RTL) |\n| **pe-2** | padding-right: 8px; (LTR) / padding-left: 8px; (RTL) |\n| **pe-3** | padding-right: 12px; (LTR) / padding-left: 12px; (RTL) |\n| **pe-4** | padding-right: 16px; (LTR) / padding-left: 16px; (RTL) |\n| **pe-5** | padding-right: 20px; (LTR) / padding-left: 20px; (RTL) |\n| **pe-6** | padding-right: 24px; (LTR) / padding-left: 24px; (RTL) |\n| **pe-7** | padding-right: 28px; (LTR) / padding-left: 28px; (RTL) |\n| **pe-8** | padding-right: 32px; (LTR) / padding-left: 32px; (RTL) |\n| **pe-9** | padding-right: 36px; (LTR) / padding-left: 36px; (RTL) |\n| **pe-10** | padding-right: 40px; (LTR) / padding-left: 40px; (RTL) |\n| **pe-11** | padding-right: 44px; (LTR) / padding-left: 44px; (RTL) |\n| **pe-12** | padding-right: 48px; (LTR) / padding-left: 48px; (RTL) |\n| **pe-13** | padding-right: 52px; (LTR) / padding-left: 52px; (RTL) |\n| **pe-14** | padding-right: 56px; (LTR) / padding-left: 56px; (RTL) |\n| **pe-15** | padding-right: 60px; (LTR) / padding-left: 60px; (RTL) |\n| **pe-16** | padding-right: 64px; (LTR) / padding-left: 64px; (RTL) |\n| **pb-0** | padding-bottom: 0; |\n| **pb-1** | padding-bottom: 4px; |\n| **pb-2** | padding-bottom: 8px; |\n| **pb-3** | padding-bottom: 12px; |\n| **pb-4** | padding-bottom: 16px; |\n| **pb-5** | padding-bottom: 20px; |\n| **pb-6** | padding-bottom: 24px; |\n| **pb-7** | padding-bottom: 28px; |\n| **pb-8** | padding-bottom: 32px; |\n| **pb-9** | padding-bottom: 36px; |\n| **pb-10** | padding-bottom: 40px; |\n| **pb-11** | padding-bottom: 44px; |\n| **pb-12** | padding-bottom: 48px; |\n| **pb-13** | padding-bottom: 52px; |\n| **pb-14** | padding-bottom: 56px; |\n| **pb-15** | padding-bottom: 60px; |\n| **pb-16** | padding-bottom: 64px; { style=\"max-height: 420px;\" fixed-header } |\n\n<PromotedEntry />\n\n## Usage\n\nThe helper classes apply **margin**, **padding**, or **gap** to an element ranging from _0 to 16_. Each size increment was designed to align with common Material Design spacings. These classes can be applied using the following format `{property}{direction}-{size}`.\n\n<ExamplesExample file=\"spacing/usage\" />\n\nThe **property** applies the type of spacing:\n\n- `m` - applies `margin`\n- `p` - applies `padding`\n- `g` - applies `gap`\n\nThe **direction** designates the side the property applies to:\n\n- `t` - applies the spacing for `margin-top` and `padding-top`\n- `b` - applies the spacing for `margin-bottom` and `padding-bottom`\n- `l` - applies the spacing for `margin-left` and `padding-left`\n- `r` - applies the spacing for `margin-right`, `padding-right`, and `row-gap`\n- `s` - applies the spacing for `margin-left`/`padding-left` _(in LTR mode)_ and `margin-right`/`padding-right` _(in RTL mode)_\n- `e` - applies the spacing for `margin-right`/`padding-right` _(in LTR mode)_ and `margin-left`/`padding-left` _(in RTL mode)_\n- `x` - applies the spacing for margin and padding `*-left` and `*-right`\n- `y` - applies the spacing for margin and padding `*-top` and `*-bottom`\n- `a` - applies the spacing for `margin`, `padding` and `gap` in all directions\n- `c` - applies the spacing for `column-gap`\n\nThe **size** controls the increment of the property in 4px intervals:\n\n- `0` - eliminates all `margin`, `padding` or `gap` by setting it to `0`\n- `1` - sets `margin`, `padding` or `gap` to 4px\n- `2` - sets `margin`, `padding` or `gap` to 8px\n- `3` - sets `margin`, `padding` or `gap` to 12px\n- `4` - sets `margin`, `padding` or `gap` to 16px\n- `5` - sets `margin`, `padding` or `gap` to 20px\n- `6` - sets `margin`, `padding` or `gap` to 24px\n- `7` - sets `margin`, `padding` or `gap` to 28px\n- `8` - sets `margin`, `padding` or `gap` to 32px\n- `9` - sets `margin`, `padding` or `gap` to 36px\n- `10` - sets `margin`, `padding` or `gap` to 40px\n- `11` - sets `margin`, `padding` or `gap` to 44px\n- `12` - sets `margin`, `padding` or `gap` to 48px\n- `13` - sets `margin`, `padding` or `gap` to 52px\n- `14` - sets `margin`, `padding` or `gap` to 56px\n- `15` - sets `margin`, `padding` or `gap` to 60px\n- `16` - sets `margin`, `padding` or `gap` to 64px\n- `n1` - sets `margin` to -4px\n- `n2` - sets `margin` to -8px\n- `n3` - sets `margin` to -12px\n- `n4` - sets `margin` to -16px\n- `n5` - sets `margin` to -20px\n- `n6` - sets `margin` to -24px\n- `n7` - sets `margin` to -28px\n- `n8` - sets `margin` to -32px\n- `n9` - sets `margin` to -36px\n- `n10` - sets `margin` to -40px\n- `n11` - sets `margin` to -44px\n- `n12` - sets `margin` to -48px\n- `n13` - sets `margin` to -52px\n- `n14` - sets `margin` to -56px\n- `n15` - sets `margin` to -60px\n- `n16` - sets `margin` to -64px\n- `auto` - sets the spacing to **auto**\n\n## Examples\n\n### Breakpoints\n\nVuetify comes with a 12 point grid system built using Flexbox. Spacing is used to create specific layouts within an application's content. It consists of 5 media breakpoints used to target specific screen sizes or orientations: **xs**, **sm**, **md**, **lg** and **xl**. The default resolutions are defined below in the _Viewport Breakpoints_ table and can be modified by customizing the [breakpoint service config](/features/display-and-platform/).\n\n<FeaturesBreakpointsTable />\n\nThe helper classes apply **margin** or **padding** at a given breakpoint. These classes can be applied using the following format: `{property}{direction}-{breakpoint}-{size}`. This does not apply to **xs** as it is inferred; e.g. `ma-xs-2` equals `ma-2`.\n\n<ExamplesExample file=\"spacing/breakpoints\" />\n\n### Horizontal\n\nMargin helper classes let you easily center content horizontally.\n\n<ExamplesExample file=\"spacing/horizontal\" />\n\n### Gap\n\nUse the gap helper classes to easily apply a gap between content.\n\n<ExamplesExample file=\"spacing/gap\" />\n\n### Negative margin\n\nMargin can also be applied negatively at the same **1 to 16** intervals.\n\n<ExamplesExample file=\"spacing/negative-margin\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/styles/text-and-typography.md",
    "content": "---\nemphasized: true\nmeta:\n  title: Text and typography\n  description: View the various typography styles. From display to labels, with various weights, sizes and italics.\n  keywords: typography, headings, titles, text\nrelated:\n  - /styles/display/\n  - /styles/content/\n  - /features/internationalization/\nfeatures:\n  report: true\n  spec: https://m3.material.io/styles/typography/type-scale-tokens\n---\n\n# Text and typography\n\nControl text size, alignment, wrapping, overflow, transforms and more. By default, Vuetify uses the Material Design 3 specification [Roboto Font](https://fonts.google.com/specimen/Roboto).\n\n<PageFeatures />\n\n| Class | Properties |\n| - | - |\n| **text-display-large** | font-size: 57px;<br>font-weight: 500;<br>line-height: 64px;<br>letter-spacing: -0.25px; |\n| **text-display-medium** | font-size: 45px;<br>font-weight: 500;<br>line-height: 52px;<br>letter-spacing: 0px; |\n| **text-display-small** | font-size: 36px;<br>font-weight: 500;<br>line-height: 44px;<br>letter-spacing: 0px; |\n| **text-headline-large** | font-size: 32px;<br>font-weight: 500;<br>line-height: 40px;<br>letter-spacing: 0px; |\n| **text-headline-medium** | font-size: 28px;<br>font-weight: 500;<br>line-height: 36px;<br>letter-spacing: 0px; |\n| **text-headline-small** | font-size: 24px;<br>font-weight: 500;<br>line-height: 32px;<br>letter-spacing: 0px; |\n| **text-title-large** | font-size: 22px;<br>font-weight: 400;<br>line-height: 30px;<br>letter-spacing: 0px; |\n| **text-title-medium** | font-size: 16px;<br>font-weight: 500;<br>line-height: 24px;<br>letter-spacing: 0.15px; |\n| **text-title-small** | font-size: 14px;<br>font-weight: 500;<br>line-height: 20px;<br>letter-spacing: 0.1px; |\n| **text-body-large** | font-size: 16px;<br>font-weight: 400;<br>line-height: 24px;<br>letter-spacing: 0.5px; |\n| **text-body-medium** | font-size: 14px;<br>font-weight: 400;<br>line-height: 20px;<br>letter-spacing: 0.25px; |\n| **text-body-small** | font-size: 12px;<br>font-weight: 400;<br>line-height: 16px;<br>letter-spacing: 0.4px; |\n| **text-label-large** | font-size: 14px;<br>font-weight: 500;<br>line-height: 20px;<br>letter-spacing: 0.1px; |\n| **text-label-medium** | font-size: 12px;<br>font-weight: 500;<br>line-height: 16px;<br>letter-spacing: 0.5px; |\n| **text-label-small** | font-size: 11px;<br>font-weight: 500;<br>line-height: 16px;<br>letter-spacing: 0.5px; |\n| **text-high-emphasis** | color: rgba(var(--v-theme-on-background), var(--v-high-emphasis-opacity)); |\n| **text-medium-emphasis** | color: rgba(var(--v-theme-on-background), var(--v-medium-emphasis-opacity)); |\n| **text-disabled** | color: rgba(var(--v-theme-on-background), var(--v-disabled-opacity)); |\n| **text-uppercase** | text-transform: uppercase; |\n| **text-lowercase** | text-transform: lowercase; |\n| **text-capitalize** | text-transform: capitalize; |\n| **text-none** | text-transform: none; |\n| **text-start** | text-align: start; |\n| **text-center** | text-align: center; |\n| **text-end** | text-align: end; |\n| **text-justify** | text-align: justify; |\n| **text-left** | text-align: left; |\n| **text-right** | text-align: right; |\n| **text-truncate** | overflow: hidden;<br>text-overflow: ellipsis;<br>white-space: nowrap; |\n| **text-no-wrap** | white-space: nowrap; |\n| **text-pre-wrap** | white-space: pre-wrap; |\n| **text-break** | overflow-wrap: break-word; |\n| **text-decoration-none** | text-decoration: none; |\n| **text-decoration-overline** | text-decoration: overline; |\n| **text-decoration-underline** | text-decoration: underline; |\n| **text-decoration-line-through** | text-decoration: line-through; |\n| **font-weight-black** | font-weight: 900; |\n| **font-weight-bold** | font-weight: 700; |\n| **font-weight-semibold** | font-weight: 600; |\n| **font-weight-medium** | font-weight: 500; |\n| **font-weight-regular** | font-weight: 400; |\n| **font-weight-light** | font-weight: 300; |\n| **font-weight-thin** | font-weight: 100; |\n| **font-italic** | font-style: italic; |\n| **text-{breakpoint}-display-large** | Set the text-display-large style for the specified breakpoint. |\n| **text-{breakpoint}-display-medium** | Set the text-display-medium style for the specified breakpoint. |\n| **text-{breakpoint}-display-small** | Set the text-display-small style for the specified breakpoint. |\n| **text-{breakpoint}-headline-large** | Set the text-headline-large style for the specified breakpoint. |\n| **text-{breakpoint}-headline-medium** | Set the text-headline-medium style for the specified breakpoint. |\n| **text-{breakpoint}-headline-small** | Set the text-headline-small style for the specified breakpoint. |\n| **text-{breakpoint}-title-large** | Set the text-title-large style for the specified breakpoint. |\n| **text-{breakpoint}-title-medium** | Set the text-title-medium style for the specified breakpoint. |\n| **text-{breakpoint}-title-small** | Set the text-title-small style for the specified breakpoint. |\n| **text-{breakpoint}-body-large** | Set the text-body-large style for the specified breakpoint. |\n| **text-{breakpoint}-body-medium** | Set the text-body-medium style for the specified breakpoint. |\n| **text-{breakpoint}-body-small** | Set the text-body-small style for the specified breakpoint. |\n| **text-{breakpoint}-label-large** | Set the text-label-large style for the specified breakpoint. |\n| **text-{breakpoint}-label-medium** | Set the text-label-medium style for the specified breakpoint. |\n| **text-{breakpoint}-label-small** | Set the text-label-small style for the specified breakpoint. { style=\"max-height: 600px;\" fixed-header } |\n\n<PromotedEntry />\n\n## Usage\n\nControl the size and style of text using the Typography helper classes. These values are based upon the [Material Design type specification](https://m3.material.io/styles/typography/type-scale-tokens).\n\n<ExamplesExample file=\"text-and-typography/typography\" />\n\n### Breakpoints\n\nAll of the typography classes support the responsive breakpoints seen in other parts of the framework. The base class `.text-{variant}` corresponds to the `xsAndUp` breakpoint, while the classes `.text-{breakpoint}-{variant}` can be used for the rest of the breakpoints (`sm`, `md`, `lg` and `xl`).\n\nThe following example shows a slightly contrived example of how one can use the different classes to effect:\n\n<ExamplesExample file=\"text-and-typography/typography-breakpoints\" />\n\n### Font emphasis\n\nMaterial design, by default, supports **100, 300, 400, 500, 700, 900** font weights and italicized text.\n\n<ExamplesExample file=\"text-and-typography/font-emphasis\" />\n\n## Text\n\n### Alignment\n\nAlignment helper classes allow you to easily re-align text.\n\n<ExamplesExample file=\"text-and-typography/text-alignment\" />\n\nThe alignment classes also support responsive breakpoints.\n\n<ExamplesExample file=\"text-and-typography/text-alignment-responsive\" />\n\n### Decoration\n\nRemove text decoration with the `.text-decoration-none` class or add an *overline, underline or line-through* by using `.text-decoration-overline`, `.text-decoration-underline`, and `.text-decoration-line-through`.\n\n<ExamplesExample file=\"text-and-typography/text-decoration\" />\n\n### Opacity\n\nOpacity helper classes allow you to easily adjust the emphasis of text. `text-high-emphasis` has the same opacity as default text. `text-medium-emphasis` is used for hints and helper text. De-emphasize text with `text-disabled`.\n\n<ExamplesExample file=\"text-and-typography/text-opacity\" />\n\n### Transform\n\nText can be transformed with text capitalization classes.\n\n<ExamplesExample file=\"text-and-typography/text-transform\" />\n\nText breaking and the removal of `text-transform` is also possible. In the first example, the `text-transform: uppercase` custom class is overwritten and allows the text casing to remain. In the second example, we break up a longer word to fit the available space.\n\n<ExamplesExample file=\"text-and-typography/text-break\" />\n\n### Wrapping and overflow\n\nYou can prevent wrapping text with the `.text-no-wrap` utility class.\n\n<ExamplesExample file=\"text-and-typography/text-no-wrap\" />\n\nLonger content can be truncated with a text ellipsis using the `.text-truncate` utility class.\n\n::: info\n  **Requires** `display: inline-block` **or** `display: block`.\n:::\n\n<ExamplesExample file=\"text-and-typography/text-truncate\" />\n\n## Customizing Fonts\n\nBy default, Vuetify uses **Roboto** as font family for regular text and headings. You can customize the font-family by overriding the following SASS variables:\n\n- `$body-font-family` — Used for body text and most components\n- `$heading-font-family` — Used for headings. (defaults to `$body-font-family`)\n\n### Loading Custom Fonts\n\nBefore configuring Vuetify, ensure your chosen font is available in your application. There are several ways to load fonts:\n\n- **Fonts from CDN** — Add an `@import` in your CSS or a `<link>` tag in your HTML\n- **Local font files** — Use `@font-face` declarations\n- **NPM packages** — Install packages like `@fontsource/open-sans`\n\n### Configuring Vuetify\n\nEnsure you have [SASS Variables](/features/sass-variables) configured in your project, then set the font-family variables:\n\n```scss { resource=\"src/styles/settings.scss\" }\n@use 'sass:string';\n@use 'vuetify/settings' with (\n  $body-font-family: string.unquote('\"Open Sans\", sans-serif'),\n  $heading-font-family: string.unquote('\"Montserrat\", sans-serif')\n);\n```\n\n### Using CSS Variables\n\nYou can use CSS custom properties for font-family values, allowing runtime changes or integration with theming systems:\n\n```scss { resource=\"src/styles/settings.scss\" }\n@use 'vuetify/settings' with (\n  $body-font-family: var(--font-sans)\n  // $heading-font-family inherits the same font in this example\n);\n```\n\n## RTL Alignment\n\nWhen using [RTL](/features/bidirectionality), you may want to keep the alignment regardless of current text direction. This can be achieved by setting the direction to either `left` or `right`.\n\nIf instead you want the alignment to respond to the current text direction, use `start` and `end`.\n\n<ExamplesExample file=\"text-and-typography/text-rtl\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/styles/transitions.md",
    "content": "---\nmeta:\n  title: Transitions\n  description: Utilize Vuetify's built in CSS and Javascript transitions within components.\n  keywords: motion, transitions, vuetify transitions\nrelated:\n  - /components/menus/\n  - /styles/colors/\n  - /components/expansion-panels/\n---\n\n# Transitions\n\nSmooth animations help make a UI feel great. Using Vue's transition system and re-usable functional components, you can easily control the motion of your application. Most components can have their transition altered through the **transition** prop.\n\n<PageFeatures />\n\n<PromotedEntry />\n\n## API\n\n| Name | Description |\n| - | - |\n| [v-expand-transition](/api/v-expand-transition/) | The expand transition is used in Expansion Panels and List Groups. There is also a horizontal version available with `v-expand-x-transition`. |\n| [v-expand-both-transition](/api/v-both-expand-transition/) | Used to expand content in both directions. |\n| [v-fab-transition](/api/v-fab-transition/) | An example of the fab transition can be found in the `v-speed-dial` component. |\n| [v-fade-transition](/api/v-fade-transition/) | An example of the fade transition can be found on the Carousel component. |\n| [v-scale-transition](/api/v-scale-transition/) | Many of Vuetify's components contain a **transition** prop which allows you to specify your own. |\n| [v-scroll-x-transition](/api/v-scroll-x-transition/) | Scroll X transitions continue along the horizontal axis. |\n| [v-scroll-x-reverse-transition](/api/v-scroll-x-reverse-transition/) | Scroll X reverse transitions continue along the horizontal axis. |\n| [v-scroll-y-transition](/api/v-scroll-y-transition/) | Scroll Y transitions continue along the vertical axis. |\n| [v-scroll-y-reverse-transition](/api/v-scroll-y-reverse-transition/) | Scroll Y reverse transitions continue along the vertical axis. |\n| [v-slide-x-transition](/api/v-slide-x-transition/) | Slide X transitions slide in from the left. |\n| [v-slide-x-reverse-transition](/api/v-slide-x-reverse-transition/) | Slide X reverse transitions slide in from the right. |\n| [v-slide-y-transition](/api/v-slide-y-transition/) | Slide Y transitions slide in from the top. |\n| [v-slide-y-reverse-transition](/api/v-slide-y-reverse-transition/) | Slide Y reverse transitions slide in from the bottom. |\n| [v-dialog-top-transition](/api/v-dialog-top-transition/) | Dialog transitions slide in from the top. |\n| [v-dialog-bottom-transition](/api/v-dialog-bottom-transition/) | Dialog transitions slide in from the bottom. |\n\n<ApiInline hide-links />\n\n## Examples\n\n<!--\n### Props\n\n#### Custom Origin\n\nProgrammatically control the transition origin with a simple prop.\n\n<ExamplesExample file=\"transitions/prop-custom-origin\" />\n-->\n\n### Misc\n\n#### Expand x\n\nThe expand transition is used in Expansion Panels and List Groups. There is also a horizontal version available with `v-expand-x-transition`.\n\n<ExamplesExample file=\"transitions/misc-expand-x\" />\n\nWhen using `v-expand-transition` or `v-expand-x-transition`, the transition works by animating an element’s height or width between `0` and its natural size. Because of this, applying **padding directly to the transitioning element** (such as `v-alert`) can cause jittery or uneven animations.\n\nIf you need padding, wrap your content in a container element (like a `div` or `v-card`) and apply the transition to that container instead. This ensures the expand transition runs smoothly, since the wrapper div has no conflicting padding or margin.\n\n<ExamplesExample file=\"transitions/misc-expand-x-padding\" />\n\n#### Fab\n\nAn example of the fab transition can be found in the `v-speed-dial` component.\n\n<ExamplesExample file=\"transitions/misc-fab\" />\n\n#### Fade\n\nAn example of the fade transition can be found on the Carousel component.\n\n<ExamplesExample file=\"transitions/misc-fade\" />\n\n#### Scale\n\nMany of Vuetify's components contain a **transition** prop which allows you to specify your own.\n\n<ExamplesExample file=\"transitions/misc-scale\" />\n\n#### Scroll x\n\nScroll X transitions continue along the horizontal axis.\n\n<ExamplesExample file=\"transitions/misc-scroll-x\" />\n\n#### Scroll y\n\nScroll Y transitions continue along the vertical axis.\n\n<ExamplesExample file=\"transitions/misc-scroll-y\" />\n\n#### Slide x\n\nSlide x transitions move along the horizontal axis.\n\n<ExamplesExample file=\"transitions/misc-slide-x\" />\n\n#### Slide y\n\nAnimations use the application's `$primary-transition`.\n\n<ExamplesExample file=\"transitions/misc-slide-y\" />\n\n#### Todo list\n\nUsing multiple custom transitions, it is easy to bring a simple todo list to life!\n\n<ExamplesExample file=\"transitions/misc-todo\" />\n\n## Create your own\n\nYou can use Vuetify's transition helper function to easily create your own custom transitions.\n\n```js\nimport { createCssTransition } from 'vuetify/util/transitions';\n\ncreateCssTransition('my-transition')\n```\n\nThe argument passed to the **createCssTransition** function will be the name of the transition that you can hook into your style. This is an example of what `my-transition` looks like:\n\n```scss\n.my-transition {\n  &-enter-active,\n  &-leave-active {\n    position: absolute;\n    transition: 1s;\n  }\n\n  &-enter-from,\n  &-leave-to {\n    opacity: 0;\n  }\n}\n```\n\nYou can now use this custom transition in a few different ways.\n\n### As a component\n\nThe **createCssTransition** function will return a component that you can use in your template.\n\n<ExamplesExample file=\"transitions/create-css-transition-component\" />\n\n### As a prop\n\nMany of Vuetify’s components contain a **transition** prop. You can send the name of your custom transition to the transition prop.\n\n<ExamplesExample file=\"transitions/create-css-transition-prop\" />\n"
  },
  {
    "path": "packages/docs/src/pages/en/user/dashboard.md",
    "content": "---\nlayout: user\nmeta:\n  nav: Dashboard\n  title: User Dashboard\n  description: User Dashboard\n  keywords: user dashboard\n---\n<script setup>\n  import DashboardDashboardEmptyState from '@/components/dashboard/DashboardEmptyState.vue'\n</script>\n\n<DashboardDashboardEmptyState />\n"
  },
  {
    "path": "packages/docs/src/pages/en/wireframes/baseline.md",
    "content": "---\nlayout: wireframe\nmeta:\n  title: Baseline Wireframe\n  keywords: vuetify wireframe, vuetify app, vue app\n  description: A baseline wireframe template for Vuetify\n---\n<script setup>\n  import Baseline from '@/examples/wireframes/baseline.vue'\n</script>\n\n<baseline />\n"
  },
  {
    "path": "packages/docs/src/pages/en/wireframes/constrained.md",
    "content": "---\nlayout: wireframe\nmeta:\n  title: Constrained Wireframe\n  keywords: vuetify wireframe, vuetify app, vue app\n  description: A constrained wireframe template for Vuetify\n---\n<script setup>\n  import Constrained from '@/examples/wireframes/constrained.vue'\n</script>\n\n<constrained />\n"
  },
  {
    "path": "packages/docs/src/pages/en/wireframes/discord.md",
    "content": "---\nlayout: wireframe\nmeta:\n  title: Discord Wireframe\n  keywords: vuetify wireframe, vuetify app, vue app\n  description: A discord wireframe template for Vuetify\n---\n<script setup>\n  import Discord from '@/examples/wireframes/discord.vue'\n</script>\n\n<discord />\n"
  },
  {
    "path": "packages/docs/src/pages/en/wireframes/extended-toolbar.md",
    "content": "---\nlayout: wireframe\nmeta:\n  title: Extended Toolbar Wireframe\n  keywords: vuetify wireframe, vuetify app, vue app\n  description: A toolbar wireframe template for Vuetify\n---\n<script setup>\n  import ExtendedToolbar from '@/examples/wireframes/extended-toolbar.vue'\n</script>\n\n<extended-toolbar />\n"
  },
  {
    "path": "packages/docs/src/pages/en/wireframes/inbox.md",
    "content": "---\nlayout: wireframe\nmeta:\n  title: Inbox Wireframe\n  keywords: vuetify wireframe, vuetify app, vue app\n  description: A inbox wireframe template for Vuetify\n---\n<script setup>\n  import Inbox from '@/examples/wireframes/inbox.vue'\n</script>\n\n<inbox />\n"
  },
  {
    "path": "packages/docs/src/pages/en/wireframes/side-navigation.md",
    "content": "---\nlayout: wireframe\nmeta:\n  title: Base Wireframe\n---\n<script setup>\n  import SideNavigation from '@/examples/wireframes/side-navigation.vue'\n</script>\n\n<side-navigation />\n"
  },
  {
    "path": "packages/docs/src/pages/en/wireframes/steam.md",
    "content": "---\nlayout: wireframe\nmeta:\n  title: Steam Wireframe\n  keywords: vuetify wireframe, vuetify app, vue app\n  description: A steam wireframe template for Vuetify\n---\n<script setup>\n  import Steam from '@/examples/wireframes/steam.vue'\n</script>\n\n<steam />\n"
  },
  {
    "path": "packages/docs/src/pages/en/wireframes/system-bar.md",
    "content": "---\nlayout: wireframe\nmeta:\n  title: System bar Wireframe\n  keywords: vuetify wireframe, vuetify app, vue app\n  description: A system bar wireframe template for Vuetify\n---\n<script setup>\n  import SystemBar from '@/examples/wireframes/system-bar.vue'\n</script>\n\n<system-bar />\n"
  },
  {
    "path": "packages/docs/src/pages/en/wireframes/three-column.md",
    "content": "---\nlayout: wireframe\nmeta:\n  title: Three column Wireframe\n  keywords: vuetify wireframe, vuetify app, vue app\n  description: A three-column wireframe template for Vuetify\n---\n<script setup>\n  import ThreeColumn from '@/examples/wireframes/three-column.vue'\n</script>\n\n<three-column />\n"
  },
  {
    "path": "packages/docs/src/plugins/global-components.ts",
    "content": "import { defineAsyncComponent } from 'vue'\n\n// Types\nimport type { App } from 'vue'\n\nexport function installGlobalComponents (app: App) {\n  app\n    .component('AppMarkdown', defineAsyncComponent(() => import('@/components/app/Markdown.vue')))\n}\n"
  },
  {
    "path": "packages/docs/src/plugins/i18n.ts",
    "content": "// Imports\nimport { createI18n } from 'vue-i18n'\n\n// Types\nimport type { App } from 'vue'\n\nconst messages = Object.fromEntries(\n  Object.entries(\n    import.meta.glob('../i18n/messages/*.json', { eager: true }))\n    .map(([key, value]) => {\n      return [key.slice(key.lastIndexOf('/') + 1, -5), (value as any).default]\n    }),\n)\n\nexport function installI18n (app: App) {\n  const localeStore = useLocaleStore()\n\n  const i18n = createI18n({\n    legacy: false,\n    locale: localeStore.locale,\n    messages,\n  })\n\n  watch(() => localeStore.locale, locale => {\n    i18n.global.locale.value = locale\n  })\n\n  app.use(i18n)\n}\n"
  },
  {
    "path": "packages/docs/src/plugins/icons.ts",
    "content": "/* eslint-disable max-len */\nexport {\n  mdiAccessPoint,\n  mdiAccount,\n  mdiAccountBox,\n  mdiAccountCircle,\n  mdiAccountCircleOutline,\n  mdiAccountFilter,\n  mdiAccountGroupOutline,\n  mdiAccountMultiple,\n  mdiAccountMultipleOutline,\n  mdiAccountOutline,\n  mdiAccountSupervisorCircle,\n  mdiAirballoon,\n  mdiAlarm,\n  mdiAlarmCheck,\n  mdiAlert,\n  mdiAlertCircle,\n  mdiAlertCircleOutline,\n  mdiAlertOctagon,\n  mdiAndroid,\n  mdiAntenna,\n  mdiAppleKeyboardCommand,\n  mdiAppleKeyboardControl,\n  mdiAppleKeyboardShift,\n  mdiAppleKeyboardOption,\n  mdiApps,\n  mdiArchivePlusOutline,\n  mdiArrowCollapseLeft,\n  mdiArrowCollapseRight,\n  mdiArrowDown,\n  mdiArrowLeft,\n  mdiArrowLeftBoldBoxOutline,\n  mdiArrowRight,\n  mdiArrowRightBold,\n  mdiArrowRightBoldBoxOutline,\n  mdiArrowRightThick,\n  mdiArrowUp,\n  mdiArrowUpBold,\n  mdiArrowUpBoldBox,\n  mdiArrowUpBoldBoxOutline,\n  mdiArrowUpBoldCircleOutline,\n  mdiAxisArrow,\n  mdiBackspace,\n  mdiBackupRestore,\n  mdiBattery,\n  mdiBeaker,\n  mdiBeakerOutline,\n  mdiBeer,\n  mdiBell,\n  mdiBellOutline,\n  mdiBellRing,\n  mdiBellRingOutline,\n  mdiBike,\n  mdiBlinds,\n  mdiBook,\n  mdiBookMultiple,\n  mdiBookmark,\n  mdiBookmarkMinus,\n  mdiBookmarkOutline,\n  mdiBookOpenPageVariant,\n  mdiBookVariant,\n  mdiBottleTonicPlus,\n  mdiBriefcase,\n  mdiBriefcaseVariant,\n  mdiBriefcaseVariantOutline,\n  mdiBrightness5,\n  mdiBroadcast,\n  mdiBrush,\n  mdiBugOutline,\n  mdiBullhorn,\n  mdiBullhornOutline,\n  mdiBullseye,\n  mdiBullseyeArrow,\n  mdiCached,\n  mdiCakeVariant,\n  mdiCalendar,\n  mdiCalendarBlank,\n  mdiCalendarBlankOutline,\n  mdiCalendarRange,\n  mdiCallSplit,\n  mdiCamera,\n  mdiCancel,\n  mdiCardBulleted,\n  mdiCart,\n  mdiCartOutline,\n  mdiCast,\n  mdiCellphone,\n  mdiChartLine,\n  mdiCheck,\n  mdiCheckBold,\n  mdiCheckboxBlankOutline,\n  mdiCheckboxMarked,\n  mdiCheckboxMarkedCircle,\n  mdiCheckCircle,\n  mdiApplicationBracketsOutline,\n  mdiCheckCircleOutline,\n  mdiCheckOutline,\n  mdiChevronDoubleLeft,\n  mdiChevronDoubleRight,\n  mdiChevronDown,\n  mdiChevronLeft,\n  mdiChevronRight,\n  mdiAccountGroup,\n  mdiChevronUp,\n  mdiCircle,\n  mdiCircleEditOutline,\n  mdiCircleHalf,\n  mdiCircleOutline,\n  mdiNewBox,\n  mdiCity,\n  mdiClipboardMultipleOutline,\n  mdiClipboardText,\n  mdiClipboardTextOutline,\n  mdiClock,\n  mdiClockOutline,\n  mdiClockStart,\n  mdiClockTimeFourOutline,\n  mdiClose,\n  mdiCloseCircle,\n  mdiCloseCircleOutline,\n  mdiClosedCaption,\n  mdiClosedCaptionOutline,\n  mdiCloud,\n  mdiCloudOutline,\n  mdiCloudUpload,\n  mdiCodeJson,\n  mdiCodeTags,\n  mdiCodeTagsCheck,\n  mdiCog,\n  mdiCogOutline,\n  mdiCogs,\n  mdiComment,\n  mdiUnfoldLessHorizontal,\n  mdiUnfoldMoreVertical,\n  mdiArrowCollapseVertical,\n  mdiCompassOutline,\n  mdiConsole,\n  mdiContentCopy,\n  mdiContentSave,\n  mdiContentSaveCogOutline,\n  mdiControllerClassicOutline,\n  mdiCookie,\n  mdiCreationOutline,\n  mdiCreditCardOutline,\n  mdiCrosshairsGps,\n  mdiCrown,\n  mdiCupcake,\n  mdiCursorPointer,\n  mdiDatabaseSearchOutline,\n  mdiDelete,\n  mdiDeleteOutline,\n  mdiDesktopTowerMonitor,\n  mdiDialpad,\n  mdiDomain,\n  mdiDotsHorizontal,\n  mdiDotsVertical,\n  mdiDownloadBoxOutline,\n  mdiDropbox,\n  mdiEarth,\n  mdiEmail,\n  mdiEmailOpen,\n  mdiEmailOpenOutline,\n  mdiEmailOutline,\n  mdiEmoticon,\n  mdiEmoticonCool,\n  mdiEmoticonDead,\n  mdiEmoticonExcited,\n  mdiEmoticonHappy,\n  mdiEmoticonNeutral,\n  mdiEmoticonOutline,\n  mdiEmoticonSad,\n  mdiEmoticonTongue,\n  mdiExport,\n  mdiExportVariant,\n  mdiEye,\n  mdiEyedropper,\n  mdiEyeOff,\n  mdiFacebook,\n  mdiFactory,\n  mdiFastForward,\n  mdiFileDocumentOutline,\n  mdiFileExcel,\n  mdiFileFind,\n  mdiFilePlus,\n  mdiFileImage,\n  mdiFileOutline,\n  mdiFilePdfBox,\n  mdiFileTree,\n  mdiFilter,\n  mdiFilterVariant,\n  mdiFindReplace,\n  mdiFire,\n  mdiFireCircle,\n  mdiFirework,\n  mdiFlag,\n  mdiFlaskEmptyOutline,\n  mdiFlaskOutline,\n  mdiFolder,\n  mdiFolderNetwork,\n  mdiFolderOpen,\n  mdiFolderOutline,\n  mdiFolderPlus,\n  mdiFolderZipOutline,\n  mdiFoodApple,\n  mdiFormatAlignCenter,\n  mdiFormatAlignJustify,\n  mdiFormatAlignLeft,\n  mdiFormatAlignRight,\n  mdiFormatBold,\n  mdiFormatColorFill,\n  mdiFormatColorText,\n  mdiFormatHeader1,\n  mdiFormatItalic,\n  mdiFormatListBulleted,\n  mdiFormatListBulletedSquare,\n  mdiFormatListChecks,\n  mdiFormatListNumbered,\n  mdiFormatUnderline,\n  mdiFormatVerticalAlignBottom,\n  mdiFormatWrapInline,\n  mdiForum,\n  mdiForward,\n  mdiFullscreen,\n  mdiFullscreenExit,\n  mdiFunction,\n  mdiGavel,\n  mdiGestureTapButton,\n  mdiGithub,\n  mdiGlassMug,\n  mdiGlassMugVariant,\n  mdiGlassWine,\n  mdiGoogleNearby,\n  mdiHandBackRight,\n  mdiHandBackRightOutline,\n  mdiHandshakeOutline,\n  mdiHeadQuestionOutline,\n  mdiHeart,\n  mdiHeartOutline,\n  mdiHeartPulse,\n  mdiHelpCircleOutline,\n  mdiHistory,\n  mdiHome,\n  mdiHomeCity,\n  mdiHomeOutline,\n  mdiHomeVariant,\n  mdiHorseVariantFast,\n  mdiHumanMaleBoard,\n  mdiHumanMaleFemaleChild,\n  mdiIceCream,\n  mdiImage,\n  mdiImageEdit,\n  mdiImageEditOutline,\n  mdiImageFilterHdr,\n  mdiImageOutline,\n  mdiInboxArrowDown,\n  mdiInformation,\n  mdiInformationOutline,\n  mdiInstagram,\n  mdiKeyboardOutline,\n  mdiKeyboardReturn,\n  mdiKeyboardSpace,\n  mdiLabel,\n  mdiLanguageHtml5,\n  mdiLanguageMarkdown,\n  mdiLanguageMarkdownOutline,\n  mdiLaptop,\n  mdiLayersOutline,\n  mdiLayersTriple,\n  mdiLeaf,\n  mdiLicense,\n  mdiLifebuoy,\n  mdiLightningBolt,\n  mdiLightbulbOnOutline,\n  mdiLink,\n  mdiLinkedin,\n  mdiLiquor,\n  mdiListStatus,\n  mdiLock,\n  mdiLockOutline,\n  mdiLogin,\n  mdiLoginVariant,\n  mdiLogoutVariant,\n  mdiMagnify,\n  mdiMagnifyMinusOutline,\n  mdiMagnifyPlusOutline,\n  mdiMapMarker,\n  mdiMapMarkerOff,\n  mdiMapMarkerOutline,\n  mdiMaterialDesign,\n  mdiMedal,\n  mdiMenu,\n  mdiMenuDown,\n  mdiMenuLeft,\n  mdiMenuRight,\n  mdiMenuUp,\n  mdiMessage,\n  mdiMessageOutline,\n  mdiMessageText,\n  mdiMessageTextOutline,\n  mdiMicrophone,\n  mdiMicrophoneOff,\n  mdiMinus,\n  mdiMinusBox,\n  mdiMinusCircle,\n  mdiMonitor,\n  mdiMonitorScreenshot,\n  mdiMonitorSmall,\n  mdiMusicNote,\n  mdiNature,\n  mdiNewspaperVariantOutline,\n  mdiNodejs,\n  mdiNumeric,\n  mdiNumeric0,\n  mdiNumeric0Box,\n  mdiNumeric1,\n  mdiNumeric1Box,\n  mdiNumeric2,\n  mdiNumeric2Box,\n  mdiNumeric3,\n  mdiNumeric3Box,\n  mdiNumeric4,\n  mdiNumeric4Box,\n  mdiNumeric5,\n  mdiNumeric5Box,\n  mdiNumeric6,\n  mdiNumeric6Box,\n  mdiNumeric7,\n  mdiNumeric7Box,\n  mdiNumeric8,\n  mdiNumeric8Box,\n  mdiNumeric9,\n  mdiNumeric9Box,\n  mdiOpenInNew,\n  mdiPackage,\n  mdiPackageVariant,\n  mdiPackageVariantClosed,\n  mdiPageFirst,\n  mdiPageLayoutSidebarLeft,\n  mdiPageLast,\n  mdiPageNext,\n  mdiPalette,\n  mdiPaletteOutline,\n  mdiPaletteSwatchOutline,\n  mdiPaperclip,\n  mdiPause,\n  mdiPencil,\n  mdiPencilOutline,\n  mdiPhone,\n  mdiPhoneInTalk,\n  mdiPhoneHangupOutline,\n  mdiPictureInPictureBottomRight,\n  mdiPin,\n  mdiPinOff,\n  mdiPinOutline,\n  mdiPlay,\n  mdiPlayCircleOutline,\n  mdiPlus,\n  mdiPlusCircle,\n  mdiPlusOutline,\n  mdiPost,\n  mdiPostOutline,\n  mdiPound,\n  mdiPower,\n  mdiPuzzle,\n  mdiPuzzleOutline,\n  mdiRadioboxBlank,\n  mdiRadioboxMarked,\n  mdiRecord,\n  mdiReddit,\n  mdiRefresh,\n  mdiReply,\n  mdiRewind,\n  mdiRocketLaunchOutline,\n  mdiSass,\n  mdiSchool,\n  mdiScriptText,\n  mdiScriptTextOutline,\n  mdiSend,\n  mdiServerPlus,\n  mdiShapeOutline,\n  mdiShareVariant,\n  mdiShareVariantOutline,\n  mdiShieldLockOutline,\n  mdiShieldStarOutline,\n  mdiSignal,\n  mdiSignalCellularOutline,\n  mdiSilverware,\n  mdiSilverwareForkKnife,\n  mdiSineWave,\n  mdiSkipNext,\n  mdiSkipPrevious,\n  mdiSnowflake,\n  mdiSortAscending,\n  mdiSortDescending,\n  mdiSourceCommit,\n  mdiSpaceInvaders,\n  mdiSpeedometer,\n  mdiSpeedometerMedium,\n  mdiSquare,\n  mdiStar,\n  mdiStarCircle,\n  mdiStarCircleOutline,\n  mdiStarHalfFull,\n  mdiStarOutline,\n  mdiStorefrontOutline,\n  mdiStoreOutline,\n  mdiSvg,\n  mdiSwapVertical,\n  mdiTable,\n  mdiTablet,\n  mdiTag,\n  mdiTagOutline,\n  mdiTarget,\n  mdiTelevisionPlay,\n  mdiTextBoxSearchOutline,\n  mdiThemeLightDark,\n  mdiThumbDown,\n  mdiThumbUp,\n  mdiTicket,\n  mdiTimerSand,\n  mdiTire,\n  mdiTranslate,\n  mdiTrashCan,\n  mdiTriangle,\n  mdiTwitter,\n  mdiUnfoldMoreHorizontal,\n  mdiUpdate,\n  mdiUpload,\n  mdiVariable,\n  mdiVectorDifferenceAb,\n  mdiVideoInputComponent,\n  mdiVideoOff,\n  mdiVideoOutline,\n  mdiVideoVintage,\n  mdiViewDashboard,\n  mdiViewDashboardOutline,\n  mdiViewGridOutline,\n  mdiViewListOutline,\n  mdiViewModule,\n  mdiVolumeHigh,\n  mdiVolumeLow,\n  mdiVolumeMedium,\n  mdiVolumeVariantOff,\n  mdiVuetify,\n  mdiWater,\n  mdiWeatherHurricane,\n  mdiWeatherNight,\n  mdiWeatherPouring,\n  mdiWeatherSunny,\n  mdiWeatherWindy,\n  mdiWhiteBalanceSunny,\n  mdiWidgetsOutline,\n  mdiWifi,\n  mdiWifiStrength2,\n  mdiWifiStrength3,\n  mdiWifiStrength4,\n  mdiWifiStrengthAlertOutline,\n  mdiWindowMaximize,\n  mdiWindowMinimize,\n  mdiWindowRestore,\n  mdiWrench,\n} from '@mdi/js'\n\nexport const mdiDiscord = 'M22,24L16.75,19L17.38,21H4.5A2.5,2.5 0 0,1 2,18.5V3.5A2.5,2.5 0 0,1 4.5,1H19.5A2.5,2.5 0 0,1 22,3.5V24M12,6.8C9.32,6.8 7.44,7.95 7.44,7.95C8.47,7.03 10.27,6.5 10.27,6.5L10.1,6.33C8.41,6.36 6.88,7.53 6.88,7.53C5.16,11.12 5.27,14.22 5.27,14.22C6.67,16.03 8.75,15.9 8.75,15.9L9.46,15C8.21,14.73 7.42,13.62 7.42,13.62C7.42,13.62 9.3,14.9 12,14.9C14.7,14.9 16.58,13.62 16.58,13.62C16.58,13.62 15.79,14.73 14.54,15L15.25,15.9C15.25,15.9 17.33,16.03 18.73,14.22C18.73,14.22 18.84,11.12 17.12,7.53C17.12,7.53 15.59,6.36 13.9,6.33L13.73,6.5C13.73,6.5 15.53,7.03 16.56,7.95C16.56,7.95 14.68,6.8 12,6.8M9.93,10.59C10.58,10.59 11.11,11.16 11.1,11.86C11.1,12.55 10.58,13.13 9.93,13.13C9.29,13.13 8.77,12.55 8.77,11.86C8.77,11.16 9.28,10.59 9.93,10.59M14.1,10.59C14.75,10.59 15.27,11.16 15.27,11.86C15.27,12.55 14.75,13.13 14.1,13.13C13.46,13.13 12.94,12.55 12.94,11.86C12.94,11.16 13.45,10.59 14.1,10.59Z'\nexport const mdiFormatTextdirectionLToR = 'M21,18L17,14V17H5V19H17V22M9,10V15H11V4H13V15H15V4H17V2H9A4,4 0 0,0 5,6A4,4 0 0,0 9,10Z'\nexport const mdiFormatTextdirectionRToL = 'M8,17V14L4,18L8,22V19H20V17M10,10V15H12V4H14V15H16V4H18V2H10A4,4 0 0,0 6,6A4,4 0 0,0 10,10Z'\n// Custom: Bluesky official path provided by user (single path, 24x24 viewBox)\nexport const mdiBluesky = 'M12 10.8c-1.087-2.114-4.046-6.053-6.798-7.995C2.566.944 1.561 1.266.902 1.565.139 1.908 0 3.08 0 3.768c0 .69.378 5.65.624 6.479.815 2.736 3.713 3.66 6.383 3.364.136-.02.275-.039.415-.056-.138.022-.276.04-.415.056-3.912.58-7.387 2.005-2.83 7.078 5.013 5.19 6.87-1.113 7.823-4.308.953 3.195 2.05 9.271 7.733 4.308 4.267-4.308 1.172-6.498-2.74-7.078a8.741 8.741 0 0 1-.415-.056c.14.017.279.036.415.056 2.67.297 5.568-.628 6.383-3.364.246-.828.624-5.79.624-6.478 0-.69-.139-1.861-.902-2.206-.659-.298-1.664-.62-4.3 1.24C16.046 4.748 13.087 8.687 12 10.8Z'\n"
  },
  {
    "path": "packages/docs/src/plugins/octokit.ts",
    "content": "// Imports\nimport { Octokit } from '@octokit/core'\n\nexport default new Octokit()\n"
  },
  {
    "path": "packages/docs/src/plugins/one.ts",
    "content": "// Styles\nimport '@vuetify/one/styles'\n\n// Types\nimport type { App } from 'vue'\n\nexport function installOne (app: App) {\n  return app.use(createOne())\n}\n"
  },
  {
    "path": "packages/docs/src/plugins/pinia.ts",
    "content": "// Imports\nimport { createPinia } from 'pinia'\nimport { one } from '@vuetify/one'\nimport { markRaw } from 'vue'\n\n// Types\nimport type { App } from 'vue'\nimport type { Router } from 'vue-router'\n\nexport const pinia = createPinia()\n\nexport function installPinia (app: App, router: Router) {\n  pinia.use(({ store }) => {\n    store.router = markRaw(router)\n  })\n\n  pinia.use(\n    one(\n      ['docs', 'home'],\n      import.meta.env.VITE_API_SERVER_URL,\n    )\n  )\n\n  app.use(pinia)\n}\n"
  },
  {
    "path": "packages/docs/src/plugins/pwa.ts",
    "content": "// Types\nimport type { Router } from 'vue-router'\n\nexport async function installPwa (router: Router) {\n  const store = usePwaStore()\n\n  await router.isReady()\n\n  router.beforeEach(async (to, from) => {\n    if (to.path !== from.path) {\n      if (store.pendingUpdate && !store.isUpdating) {\n        console.log('Reloading page to update service worker')\n        window.location.pathname = to.fullPath\n      }\n\n      navigator.serviceWorker?.getRegistration().then(reg => {\n        reg?.update()\n      })\n    }\n  })\n\n  if ('serviceWorker' in navigator) {\n    navigator.serviceWorker.addEventListener('controllerchange', async () => {\n      console.log('controllerchange')\n      store.isUpdating = false\n      store.pendingUpdate = true\n    })\n\n    if (store.availableOffline) {\n      store.registerWorker()\n    } else if (localStorage.getItem('vuetify:availableOffline') == null) {\n      store.removeWorker()\n    }\n  }\n}\n"
  },
  {
    "path": "packages/docs/src/plugins/vuetify.ts",
    "content": "// Styles\nimport 'vuetify/styles'\n\n// Imports\nimport { createVuetify } from 'vuetify'\nimport { VChip } from 'vuetify/components/VChip'\nimport { VBtn } from 'vuetify/components/VBtn'\nimport { VSwitch } from 'vuetify/components/VSwitch'\nimport { VSvgIcon } from 'vuetify/components/VIcon'\nimport { VSnackbarQueue } from 'vuetify/components/VSnackbarQueue'\n\n// Icons\nimport { fa } from 'vuetify/iconsets/fa'\nimport { md } from 'vuetify/iconsets/md'\nimport { mdi } from 'vuetify/iconsets/mdi-svg'\nimport * as mdiSvg from './icons'\nimport { aliases } from '@vuetify/one'\n\n// Locales\nimport { en, sv } from 'vuetify/locale'\n\n// Types\nimport type { App } from 'vue'\nimport type { IconProps } from 'vuetify'\n\nexport function installVuetify (app: App) {\n  const vuetify = createVuetify({\n    components: {\n      VSnackbarQueue,\n    },\n    aliases: {\n      BorderChip: VChip,\n      NewInChip: VChip,\n      PageFeatureChip: VChip,\n      PrimaryBtn: VBtn,\n      SettingsSwitch: VSwitch,\n    },\n    defaults: {\n      global: {\n        eager: false,\n      },\n      NewInChip: {\n        appendIcon: 'mdi-page-next',\n        class: 'ms-2 text-mono',\n        color: 'success',\n        label: true,\n        size: 'small',\n        tag: 'div',\n        variant: 'flat',\n\n        VIcon: {\n          class: 'ms-2',\n          size: 'small',\n        },\n      },\n      PageFeatureChip: {\n        variant: 'tonal',\n        border: true,\n        class: 'text-medium-emphasis me-2 mb-2',\n        size: 'small',\n      },\n      PrimaryBtn: {\n        border: true,\n        class: 'text-none',\n        color: 'primary',\n        slim: true,\n        size: 'small',\n        variant: 'outlined',\n\n        VProgressCircular: {\n          indeterminate: true,\n          size: 16,\n          width: 1,\n        },\n      },\n      SettingsSwitch: {\n        class: 'ps-1 mb-2',\n        color: 'primary',\n        density: 'compact',\n        inset: true,\n        trueIcon: 'mdi-check',\n        falseIcon: '$close',\n        hideDetails: 'auto',\n      },\n      BorderChip: {\n        border: true,\n        label: true,\n        size: 'small',\n        variant: 'text',\n\n        VIcon: {\n          color: 'medium-emphasis',\n          size: 'small',\n        },\n      },\n    },\n    locale: {\n      locale: 'en',\n      messages: {\n        en,\n        sv,\n      },\n    },\n    icons: {\n      defaultSet: 'mdi',\n      sets: {\n        fa,\n        md,\n        mdiSvg: mdi,\n        mdi: {\n          component: (props: IconProps) => {\n            const icon = mdiSvg[camelize(props.icon as string) as keyof typeof mdiSvg]\n            return h(VSvgIcon, { ...props, icon })\n          },\n        },\n      },\n      aliases,\n    },\n    theme: {\n      themes: {\n        light: {\n          colors: {\n            'surface-variant-alt': '#dedede',\n            primary: '#1867c0',\n            secondary: '#5CBBF6',\n            tertiary: '#E57373',\n            accent: '#005CAF',\n            quarternary: '#B0D1E8',\n            'surface-bright': '#fafafa',\n          },\n        },\n        dark: {\n          colors: {\n            'surface-variant-alt': '#333333',\n            primary: '#2196F3',\n            secondary: '#424242',\n            tertiary: '#E57373',\n            accent: '#FF4081',\n            quarternary: '#B0D1E8',\n            'surface-bright': '#474747',\n          },\n        },\n        blackguard: {\n          dark: true,\n          colors: {\n            background: '#0f0c24',\n            primary: '#e7810d',\n            surface: '#1e184a',\n            'on-surface-variant': '#4c219e',\n            info: '#9c27b0',\n            accent: '#FF4081',\n            success: '#84b38a',\n            'surface-bright': '#362b89',\n          },\n          variables: {\n            'theme-code': '#15123d',\n          },\n        },\n      },\n    },\n  })\n  app.use(vuetify)\n}\n"
  },
  {
    "path": "packages/docs/src/service-worker.js",
    "content": "import { cacheManifestEntries, cleanCache, ensureCacheableResponse, messageSW, openCache } from '@/utils/pwa'\n\nlet PREVIOUS_MANIFEST\nconst MANIFEST = self.__WB_MANIFEST\nconst manifestUrls = new Set(MANIFEST.map(e => '/' + e.url))\n\nself.addEventListener('message', async event => {\n  if (event.data === 'sw:update' || event.data?.type === 'SKIP_WAITING') {\n    console.log('[SW] Skip waiting')\n    self.skipWaiting()\n  } else if (event.data?.type === 'GET_MANIFEST') {\n    console.log('[SW] Sending manifest')\n    event.ports[0].postMessage(MANIFEST)\n  } else {\n    console.log('[SW] Unknown message', event.data)\n  }\n\n  event.ports[0].postMessage({ type: 'DONE' })\n})\n\nself.addEventListener('install', event => {\n  console.log('[SW] Installed')\n  event.waitUntil((async () => {\n    if (self.registration.active) {\n      await Promise.race([\n        new Promise(resolve => setTimeout(resolve, 500)),\n        messageSW(self.registration.active, { type: 'GET_MANIFEST' })\n          .then(manifest => {\n            PREVIOUS_MANIFEST = manifest\n            console.log('[SW] Received manifest')\n          }),\n      ])\n    }\n    await removeWorkboxCaches()\n    const clients = await self.clients.matchAll({\n      includeUncontrolled: true,\n    })\n    await cacheManifestEntries(MANIFEST, (value, total) => {\n      clients.forEach(client => {\n        client.postMessage({ type: 'PROGRESS', value, total })\n      })\n    })\n    self.skipWaiting()\n  })())\n})\n\nself.addEventListener('activate', event => {\n  console.log('[SW] Activated')\n  event.waitUntil((async () => {\n    await self.clients.claim()\n    if (PREVIOUS_MANIFEST) {\n      await cleanCache(PREVIOUS_MANIFEST)\n    }\n    console.log('[SW] Ready')\n  })())\n})\n\nself.addEventListener('fetch', event => {\n  const url = new URL(event.request.url)\n\n  if (!['http:', 'https:'].includes(url.protocol)) return\n\n  if (event.request.method !== 'GET') return\n\n  if (['https://tag.researchnow.com', 'https://srv.carbonads.net', 'https://pixel.adsafeprotected.com', 'https://cdn4.buysellads.net', 'https://ad.doubleclick.net'].includes(url.origin)) {\n    return\n  }\n\n  if (url.origin === self.location.origin) {\n    if (event.request.mode === 'navigate' &&\n      event.request.destination === 'document') {\n      return event.respondWith(matchPrecache('/_fallback.html'))\n    } else if (manifestUrls.has(url.pathname)) {\n      return event.respondWith(matchPrecache(event.request))\n    }\n  }\n\n  if (event.request.destination !== 'document') {\n    return event.respondWith(networkFirst(event.request))\n  }\n})\n\nasync function matchPrecache (request) {\n  const precache = await openCache('precache')\n  const matched = await precache.match(request)\n  if (matched) return matched\n  const response = fetch(request)\n  response.then(response => {\n    response = ensureCacheableResponse(response)\n    if (response.status === 200) {\n      precache.put(response.url, response.clone())\n    } else {\n      console.error(`[SW] Failed to fetch missing precached asset ${request.url}`)\n    }\n  })\n  return response\n}\n\nasync function networkFirst (request) {\n  const cache = await openCache('runtime')\n  const fromNetwork = fetch(request).then(response => ensureCacheableResponse(response)).catch(() => null)\n  const race = Promise.race([\n    fromNetwork,\n    new Promise(resolve => setTimeout(() => resolve('timeout'), 3000)),\n  ])\n\n  try {\n    const response = await race\n    if (response === 'timeout' || !response) {\n      const cached = await caches.match(request)\n      if (cached) return cached\n      throw new Error('Network timeout and no cache available')\n    }\n    const is400 = response?.status >= 400 && response?.status < 500\n    if (response?.status === 200) {\n      cache.put(request, response.clone())\n    } else if (!is400) {\n      await cache.delete(request)\n    }\n    return response\n  } catch (e) {\n    console.warn('[SW] Failed to fetch', e)\n    const cached = await caches.match(request)\n    return cached || Response.error()\n  }\n}\n\nfunction removeWorkboxCaches () {\n  return caches.keys().then(keys => {\n    keys = keys.filter(key => key.startsWith('workbox-') || key.endsWith(self.registration.scope))\n    if (keys.length) {\n      console.log('[SW] Removing workbox caches')\n      return Promise.all(\n        keys.map(key => caches.delete(key))\n      )\n    }\n  })\n}\n"
  },
  {
    "path": "packages/docs/src/shims.d.ts",
    "content": "declare module '*.md' {\n  import type { ComponentOptions } from 'vue'\n  const component: ComponentOptions\n  export default component\n}\n\ndeclare module '*.vue' {\n  import type { DefineComponent } from 'vue'\n  const component: DefineComponent<{}, {}, any>\n  export default component\n}\n\ndeclare module 'virtual:mdi-js-icons' {\n  export interface IconEntry {\n    name: string\n    aliases: string[]\n    path: string\n  }\n  export const icons: IconEntry[]\n}\n\ndeclare module 'virtual:api-list' {\n  const list: string[]\n  export default list\n}\n\ndeclare module 'markdown-it-header-sections' {\n  import type { PluginSimple } from 'markdown-it'\n\n  const MarkdownItHeaderSections: PluginSimple\n  export default MarkdownItHeaderSections\n}\n\ndeclare module 'markdown-it-attrs' {\n  import type { PluginWithOptions } from 'markdown-it'\n\n  const MarkdownItAttrs: PluginWithOptions<{\n    leftDelimiter?: string\n    rightDelimiter?: string\n    allowedAttributes?: string[]\n  }>\n  export default MarkdownItAttrs\n}\n\ndeclare module 'markdown-it-link-attributes' {\n  import type { PluginWithOptions } from 'markdown-it'\n\n  interface Config {\n    pattern?: string\n    attrs: Record<string, string>\n  }\n\n  const MarkdownItLinkAttributes: PluginWithOptions<Config | Config[]>\n  export default MarkdownItLinkAttributes\n}\n\ndeclare module 'markdown-it-emoji/bare.js'\n\ndeclare module 'virtual:examples' {\n  import type { Component } from 'vue'\n\n  export function getExample (name: string): Promise<{\n    component: Component\n    source: string\n  }>\n}\n\ndeclare module 'vue-instantsearch/vue3/es/src/instantsearch.js'\n\ndeclare module 'async-es/eachLimit'\n"
  },
  {
    "path": "packages/docs/src/stores/ads.ts",
    "content": "// Types\ninterface Ad {\n  slug: string\n  title: string\n  metadata?: {\n    url: string\n    type: string\n    description?: string\n    // eslint-disable-next-line camelcase\n    description_short?: string\n    sponsored: boolean\n    discoverable: boolean\n    src: string\n    images?: {\n      logo?: {\n        url: string\n      }\n      preview?: {\n        url: string\n      }\n      background?: {\n        url: string\n      }\n    }\n  }\n}\n\nexport const useAdsStore = defineStore('ads', () => {\n  const ads = ref<Ad[]>([])\n\n  onBeforeMount(async () => {\n    if (ads.value.length) return\n\n    const { bucket } = useCosmic()\n\n    const { objects = [] }: { objects: Ad[] } = (\n      await bucket?.objects\n        .find({ type: 'ads' })\n        .props('slug,title,metadata')\n        .status('published')\n    ) || {}\n\n    ads.value = objects\n  })\n\n  return { ads }\n})\n"
  },
  {
    "path": "packages/docs/src/stores/app.ts",
    "content": "// Data\nimport data from '@/data/nav.json'\n\n// Types\nexport type Category = {\n  icon: string\n  color: string\n}\n\ntype RootState = {\n  apiSearch: string\n  drawer: boolean | null\n  toc: boolean | null\n  scrolling: boolean\n  items: NavItem[]\n  pages: string[]\n  settings: boolean\n  categories: Record<string, Category>\n}\n\ntype NavItem = {\n  divider?: boolean\n  title?: string\n  subheader?: string\n  inactiveIcon?: string\n  activeIcon?: string\n  items?: NavItem[]\n  emphasized?: boolean\n}\n\nexport const useAppStore = defineStore('app', {\n  state: () => ({\n    apiSearch: '',\n    drawer: null,\n    toc: null,\n    scrolling: false,\n    items: Array.from(data),\n    pages: getPages(data as NavItem[]),\n    settings: false,\n    categories: {\n      api: {\n        icon: 'mdi-flask-outline',\n        color: 'orange',\n      },\n      components: {\n        icon: 'mdi-view-dashboard-outline',\n        color: 'indigo-darken-1',\n      },\n      features: {\n        icon: 'mdi-image-edit-outline',\n        color: 'red',\n      },\n      directives: {\n        icon: 'mdi-function',\n        color: 'blue-grey',\n      },\n      'getting-started': {\n        icon: 'mdi-speedometer',\n        color: 'teal',\n      },\n      introduction: {\n        icon: 'mdi-script-text-outline',\n        color: 'green',\n      },\n      about: {\n        icon: '$vuetify',\n        color: 'primary',\n      },\n      resources: {\n        icon: 'mdi-human-male-board',\n        color: 'pink',\n      },\n      styles: {\n        icon: 'mdi-palette-outline',\n        color: 'deep-purple-accent-4',\n      },\n      themes: {\n        icon: 'mdi-script-text-outline',\n        color: 'pink',\n      },\n      labs: {\n        icon: 'mdi-beaker-outline',\n        color: 'purple',\n      },\n    },\n  } as RootState),\n})\n\nfunction getPage (item: NavItem, parent = ''): string[] {\n  const title = `${parent}${parent ? '/' : ''}${item?.title ?? item}`\n\n  return item?.items?.length ? getPages(\n    item.items,\n    title\n  ) : [title]\n}\n\nfunction getPages (items: NavItem[] = [], parent = ''): string[] {\n  let array: any = []\n\n  for (const item of items) {\n    if (item?.divider || item?.subheader) continue\n\n    array = [...array, ...getPage(item, parent)]\n  }\n\n  return array\n}\n"
  },
  {
    "path": "packages/docs/src/stores/commits.ts",
    "content": "// Plugins\nimport type { components as octokitComponents } from '@octokit/openapi-types'\n\nexport type Commit = octokitComponents['schemas']['commit']\n\ntype State = {\n  commits: Commit[]\n  isLoading: boolean\n}\n\nconst url = import.meta.env.VITE_API_SERVER_URL\n\nexport const useCommitsStore = defineStore('commits', {\n  state: (): State => ({\n    commits: [] as Commit[],\n    isLoading: false,\n  }),\n\n  actions: {\n    async fetch () {\n      this.isLoading = true\n\n      try {\n        const res = await fetch(`${url}/github/commits`, {\n          method: 'GET',\n          credentials: 'include',\n        }).then(async res => res.json())\n\n        this.commits = res\n      } catch (err: any) {\n        console.warn(`Failed to fetch commits: ${err.message}`)\n      }\n\n      this.isLoading = false\n    },\n  },\n\n  getters: {\n    latest (state) {\n      return state.commits?.[0]\n    },\n  },\n})\n"
  },
  {
    "path": "packages/docs/src/stores/jobs.ts",
    "content": "// Types\ntype Job = {\n  id: number\n  title: string\n  description: string\n  avatar: string\n  company: string\n  locations: string[]\n  published: string\n  url: string\n  via: string\n}\n\ntype VueJobsJob = {\n  description: string\n  link: string\n  locations: string[]\n  organization: {\n    name: string\n    avatar: string\n  }\n  published_at: string\n  remote: string\n  title: string\n}\n\ntype FreeflowJob = {\n  compensation: string\n  created: string\n  description: string\n  location: string\n  number: number\n  post_url: string\n  title: string\n}\n\nasync function fetchVueJobs () {\n  const res = await fetch('https://app.vuejobs.com/feed/vuetify?format=json', {\n    method: 'get',\n    headers: { 'Content-Type': 'application/json' },\n  }).then(res => res.json())\n\n  return res.data.map((job: VueJobsJob) => ({\n    id: job.title,\n    title: job.title,\n    description: job.description,\n    avatar: job.organization.avatar,\n    company: job.organization.name,\n    locations: job.locations.length ? job.locations : ['Remote'],\n    published: job.published_at,\n    url: job.link,\n    via: 'vue-jobs',\n  }))\n}\n\nasync function fetchFreeflowJobs () {\n  const res = await fetch('https://public.freeflow.network/api/jobs', {\n    method: 'get',\n    headers: {\n      'Content-Type': 'application/json',\n      'X-Api-Key': 'anidjttnd2339590052',\n    },\n  }).then(res => res.json())\n\n  return res.map((job: FreeflowJob) => ({\n    id: job.number,\n    title: job.title,\n    description: job.description.length > 200 ? job.description.slice(0, 200) + '...' : job.description,\n    avatar: undefined,\n    company: 'Vuetify Discord',\n    locations: ['Remote'],\n    published: job.created,\n    url: job.post_url,\n    via: 'discord',\n  }))\n}\n\nexport const useJobsStore = defineStore('jobs', () => {\n  const jobs = ref<Job[]>([])\n\n  onBeforeMount(async () => {\n    if (jobs.value.length) return\n\n    jobs.value.push(...await fetchVueJobs())\n    jobs.value.push(...await fetchFreeflowJobs())\n\n    jobs.value.sort((a, b) => {\n      return new Date(b.published).getTime() - new Date(a.published).getTime()\n    })\n  })\n\n  return { jobs }\n})\n"
  },
  {
    "path": "packages/docs/src/stores/locale.ts",
    "content": "// Types\ntype RootState = {\n  locale: string\n}\n\nexport const useLocaleStore = defineStore('locale', {\n  state: () => ({\n    locale: preferredLocale(),\n  } as RootState),\n})\n"
  },
  {
    "path": "packages/docs/src/stores/made-with-vuetify.ts",
    "content": "export const useMadeWithVuetifyStore = defineStore('made-with-vuetify', () => {\n  const items = shallowRef([])\n\n  onBeforeMount(async () => {\n    const res = await fetch('https://madewithvuejs.com/api/tag/vuetify', {\n      priority: 'low',\n    })\n      .then(res => res.json())\n\n    items.value = res.data\n  })\n\n  return { items }\n})\n"
  },
  {
    "path": "packages/docs/src/stores/pins.ts",
    "content": "export type Pin = {\n  category: string\n  title: string\n  to: string\n}\n\nexport const usePinsStore = defineStore('pins', () => {\n  const user = useUserStore()\n  const route = useRoute()\n\n  const pins = ref<Pin[]>([])\n  const isPinning = shallowRef(false)\n\n  const pageIsPinned = computed(() => pins.value.some(p => p.to === route.path))\n\n  function toggle (value: boolean, pin: Pin) {\n    let array = pins.value.slice()\n\n    if (value) {\n      array.push(pin)\n    } else {\n      array = array.filter(p => p.to !== pin.to)\n    }\n\n    array.sort((a, b) => {\n      if (a.title > b.title) return 1\n      if (a.title < b.title) return -1\n      return 0\n    })\n\n    pins.value = array\n\n    save()\n  }\n\n  function load () {\n    // TODO: remove next one release\n    pins.value = (user.ecosystem.docs.pins.pinned || []) as any\n  }\n\n  function save () {\n    // TODO: remove once fixed in one\n    user.ecosystem.docs.pins.pinned = pins.value as any\n  }\n\n  return {\n    pins,\n    isPinning,\n    pageIsPinned,\n    toggle,\n    load,\n    save,\n  }\n})\n"
  },
  {
    "path": "packages/docs/src/stores/promotions.ts",
    "content": "// Types\ntype CosmicImage = {\n  url: string\n}\n\ninterface Promotion {\n  text: string\n  images: {\n    default: CosmicImage\n    logoLight: CosmicImage\n    logoDark: CosmicImage\n    bgDark: CosmicImage\n    bgLight: CosmicImage\n  }\n  url: string\n  discoverable: boolean\n  advertisement: boolean\n  startDate: string | null\n  endDate: string | null\n  price: number\n  type: string\n}\n\nexport const usePromotionsStore = defineStore('promotions', () => {\n  const promotions = ref<Promotion[]>([])\n\n  onBeforeMount(async () => {\n    if (promotions.value.length) return\n\n    const { bucket } = useCosmic()\n\n    const { objects = [] }: { objects: Promotion[] } = (\n      await bucket?.objects\n        .find({ type: 'promotions' })\n        .props('metadata,slug,title')\n        .status('published')\n    ) || {}\n\n    promotions.value = objects\n  })\n\n  return { promotions }\n})\n"
  },
  {
    "path": "packages/docs/src/stores/pwa.ts",
    "content": "export const usePwaStore = defineStore('pwa', () => {\n  const isOffline = shallowRef(!navigator.onLine)\n  const isUpdating = shallowRef(false)\n  const nextManifest = shallowRef()\n  const pendingUpdate = shallowRef(false)\n  const prevManifest = shallowRef()\n  const progress = shallowRef(0)\n  const progressTotal = shallowRef(0)\n\n  window.addEventListener('online', () => isOffline.value = false)\n  window.addEventListener('offline', () => isOffline.value = true)\n\n  const _availableOffline = shallowRef(localStorage.getItem('vuetify:availableOffline') === 'true')\n  const availableOffline = computed({\n    get: () => _availableOffline.value,\n    set: val => {\n      _availableOffline.value = val\n      localStorage.setItem('vuetify:availableOffline', String(val))\n      if (val) {\n        registerWorker()\n      } else {\n        removeWorker()\n      }\n    },\n  })\n\n  function registerWorker () {\n    navigator.serviceWorker.addEventListener('message', e => {\n      if (e.data?.type === 'PROGRESS') {\n        isUpdating.value = true\n        progress.value = e.data.value\n        progressTotal.value = e.data.total\n      }\n    })\n    navigator.serviceWorker.register('/service-worker.js', {\n      scope: '/',\n    })\n  }\n\n  async function removeWorker () {\n    const registration = await navigator.serviceWorker.getRegistration()\n    await window.caches.delete(`precache-${location.origin}`)\n    await window.caches.delete(`runtime-${location.origin}`)\n    if (await registration?.unregister()) {\n      window.location.reload()\n    }\n  }\n\n  return {\n    availableOffline,\n    isOffline,\n    isUpdating,\n    nextManifest,\n    pendingUpdate,\n    prevManifest,\n    progress,\n    progressTotal,\n    registerWorker,\n    removeWorker,\n  }\n})\n"
  },
  {
    "path": "packages/docs/src/stores/releases.ts",
    "content": "// Plugins\nimport type { components as octokitComponents } from '@octokit/openapi-types'\n\nexport type Release = octokitComponents['schemas']['release']\n\ntype State = {\n  releases: Release[]\n  isLoading: boolean\n  page: number\n}\n\nconst url = import.meta.env.VITE_API_SERVER_URL\n\nexport const useReleasesStore = defineStore('releases', {\n  state: (): State => ({\n    releases: [] as Release[],\n    isLoading: false,\n    page: 1,\n  }),\n\n  actions: {\n    format (release: Release) {\n      return {\n        ...release,\n        props: {\n          prependIcon: `mdi-numeric-${release.tag_name.slice(1, 2)}-box`,\n          title: release.tag_name,\n        },\n      }\n    },\n    async fetch () {\n      this.isLoading = true\n\n      let data = []\n      try {\n        data = await fetch(`${url}/github/releases?page=${this.page}`, {\n          method: 'GET',\n          credentials: 'include',\n        }).then(res => res.json())\n      } catch (err: any) {\n        console.error(err)\n      }\n\n      for (const release of data) {\n        this.releases.push(this.format(release))\n      }\n\n      this.isLoading = false\n      this.page++\n    },\n    async find (tag: string) {\n      if (!tag.startsWith('v')) tag = `v${tag}`\n\n      const found = this.releases.find(release => release.tag_name === tag)\n\n      if (found) return found\n\n      this.isLoading = true\n\n      let res: any\n\n      if (tag.length >= 6) {\n        try {\n          res = await fetch(`${url}/github/releases/find?tag=${tag}`, {\n            method: 'GET',\n            credentials: 'include',\n          }).then(res => res.json())\n        } catch (err: any) {\n          console.error(err)\n        }\n      }\n\n      this.isLoading = false\n\n      if (res) {\n        this.releases.push(this.format(res))\n\n        return res\n      }\n    },\n  },\n})\n"
  },
  {
    "path": "packages/docs/src/stores/shopify.ts",
    "content": "interface Product {\n  href: string\n  title: string\n  src: string\n  price: number\n}\n\ninterface Vendor {\n  name: string\n  products: Product[]\n}\n\ntype State = {\n  vendors: Vendor[]\n}\n\nexport const useShopifyStore = defineStore('vendors', {\n  state: (): State => ({\n    vendors: [],\n  }),\n\n  actions: {\n    async fetch () {\n      if (this.vendors.length) return\n\n      const { bucket } = useCosmic()\n\n      const { objects = [] } = (\n        await bucket?.objects\n          .find({ type: 'vendors' })\n          .props('metadata')\n          .sort('created_at')\n      ) || {}\n\n      if (objects?.length) {\n        this.vendors = objects[0].metadata.vendors\n      }\n    },\n  },\n\n  getters: {\n    byVendor: state => {\n      return state.vendors.reduce((acc, vendor) => {\n        acc[vendor.name] = vendor\n        return acc\n      }, {} as Record<string, Vendor>)\n    },\n  },\n})\n"
  },
  {
    "path": "packages/docs/src/stores/sponsors.ts",
    "content": "// Types\nexport interface Sponsor {\n  metadata: {\n    tier: number\n  }\n  slug: string\n  title: string\n}\n\nexport const useSponsorsStore = defineStore('sponsors', () => {\n  const sponsors = ref<Sponsor[]>([])\n\n  async function fetchSponsors () {\n    if (sponsors.value.length) return\n\n    const { bucket } = useCosmic()\n    const { objects = [] }: { objects: Sponsor[] } = (\n      await bucket?.objects\n        .find({\n          type: 'sponsors',\n          'metadata.active': true,\n        })\n        .props('metadata,slug,title')\n        .sort('created_at')\n    ) || {}\n\n    sponsors.value = objects\n  }\n\n  onServerPrefetch(fetchSponsors)\n  onBeforeMount(fetchSponsors)\n\n  const byTier = computed(() => {\n    const tiers: Record<string, Sponsor[]> = {}\n\n    for (const sponsor of sponsors.value) {\n      const tier = sponsor.metadata.tier\n\n      if (!tiers[tier]) {\n        tiers[tier] = []\n      }\n\n      tiers[tier].push(sponsor)\n    }\n\n    return tiers\n  })\n\n  function bySlug (slug: string) {\n    return sponsors.value.find(sponsor => {\n      return sponsor.slug === slug\n    })\n  }\n\n  return { sponsors, bySlug, byTier }\n})\n"
  },
  {
    "path": "packages/docs/src/stores/spot.ts",
    "content": "// Types\ninterface Spot {\n  slug: string\n  metadata: {\n    sponsor: string\n    href: string\n    image: {\n      url: string\n    }\n  }\n}\n\nexport const useSpotStore = defineStore('spot', () => {\n  const { bucket } = useCosmic()\n\n  const adapter = useDate()\n  const today = adapter.startOfDay(adapter.date())\n  const tomorrow = adapter.endOfDay(today)\n\n  const spots = ref<Spot[]>([])\n\n  const spot = computed(() => spots.value[0]?.metadata)\n\n  onBeforeMount(async () => {\n    if (spots.value.length) return\n\n    const { objects = [] }: { objects: Spot[] } = (\n      await bucket?.objects\n        .find({\n          type: 'spots',\n          'metadata.start_date': {\n            $lte: today,\n          },\n          'metadata.end_date': {\n            $gte: tomorrow,\n          },\n        })\n        .props('metadata,slug')\n        .status('published')\n    ) || {}\n\n    spots.value = objects\n  })\n\n  return { spot }\n})\n"
  },
  {
    "path": "packages/docs/src/stores/team-members.ts",
    "content": "// Plugins\nimport octokit from '@/plugins/octokit'\n\n// Data\nimport team from '@/data/team.json'\n\nexport type Member = {\n  discord?: string\n  focus?: string[]\n  funding?: string[]\n  languages: string[]\n  linkedin?: string\n  location?: string\n  work?: string\n  name: string\n  avatar?: string\n  github?: string\n  team: string\n  twitter?: string\n  joined?: string\n}\n\nexport type GithubMember = {\n  avatar_url: string\n  login: string\n}\n\nexport const useTeamMembersStore = defineStore('team-members', () => {\n  const members = ref<Member[]>([])\n\n  for (const key in team) {\n    const record: Member = (team as Record<string, Member>)[key]\n\n    members.value.push({\n      ...record,\n      github: key,\n    })\n  }\n\n  onBeforeMount(async () => {\n    const res = await octokit.request('GET /orgs/vuetifyjs/members')\n    const data = res.data as GithubMember[]\n\n    members.value = members.value.map(member => {\n      const record = data.find(u => u.login.localeCompare(member.github ?? '', 'en', {\n        sensitivity: 'base',\n      }) === 0)\n\n      return {\n        avatar: record?.avatar_url,\n        ...member,\n      }\n    })\n  })\n\n  return { members }\n})\n"
  },
  {
    "path": "packages/docs/src/utils/analytics.ts",
    "content": "/* eslint-disable camelcase */\nimport { track } from 'swetrix'\n\nexport function sweClick (\n  event_category: string,\n  event_label: string,\n  value: string\n) {\n  track({\n    ev: 'click',\n    meta: {\n      category: event_category,\n      label: event_label,\n      value,\n    },\n  })\n}\n"
  },
  {
    "path": "packages/docs/src/utils/api.ts",
    "content": "export type Item = {\n  name: string\n  source: string\n  type?: string | string[]\n  anyOf: Item[]\n  enum?: string[]\n  parameters?: Item[]\n  returnType?: Item\n  default: any\n  description: Record<string, string>\n  descriptionSource?: Record<string, string>\n  snippet: string\n  value: any\n  example: string\n  props: unknown\n  $ref?: string\n  properties?: Record<string, Item>\n  items?: Item | Item[]\n  minItems?: number\n  maxItems?: number\n  allOf?: Item[]\n}\n\nexport function stripLinks (str: string): [string, Record<string, string>] {\n  let out = str.slice()\n  const obj: Record<string, string> = {}\n  const regexp = /<a.*?>(.*?)<\\/a>/g\n\n  let matches = regexp.exec(str)\n\n  while (matches !== null) {\n    obj[matches[1]] = matches[0]\n    out = out.replace(matches[0], matches[1])\n\n    matches = regexp.exec(str)\n  }\n\n  return [out, obj]\n}\n\nexport function insertLinks (str: string, stripped: Record<string, string>) {\n  for (const [key, value] of Object.entries(stripped)) {\n    str = str.replaceAll(new RegExp(`(^|\\\\W)(${key})(\\\\W|$)`, 'g'), `$1${value}$3`)\n  }\n  return str\n}\n"
  },
  {
    "path": "packages/docs/src/utils/globals.ts",
    "content": "const IN_BROWSER = typeof window !== 'undefined'\nconst IS_DEBUG = import.meta.env.DEBUG === 'true'\nconst IS_PROD = import.meta.env.NODE_ENV === 'production'\nconst IS_SERVER = import.meta.env.SSR\n\nexport {\n  IN_BROWSER,\n  IS_DEBUG,\n  IS_PROD,\n  IS_SERVER,\n}\n"
  },
  {
    "path": "packages/docs/src/utils/helpers.ts",
    "content": "export function copyElementContent (el: HTMLElement) {\n  if (!IN_BROWSER) return\n\n  el.setAttribute('contenteditable', 'true')\n  el.focus()\n\n  document.execCommand('selectAll', false, undefined)\n  document.execCommand('copy')\n\n  el.removeAttribute('contenteditable')\n}\n\nexport function getBranch () {\n  const branch = IN_BROWSER\n    ? window.location.hostname.split('.')[0]\n    : 'master'\n\n  return ['master', 'dev', 'next'].includes(branch) ? branch : 'master'\n}\n\nexport const wait = (timeout: number) => {\n  return new Promise(resolve => setTimeout(resolve, timeout))\n}\n\nexport async function waitForReadystate () {\n  if (\n    !IN_BROWSER ||\n    document.readyState === 'interactive'\n  ) return\n\n  await new Promise(resolve => {\n    const cb = () => {\n      window.requestAnimationFrame(resolve)\n      window.removeEventListener('DOMContentLoaded', cb)\n    }\n\n    window.addEventListener('DOMContentLoaded', cb)\n  })\n}\n\n/** Jaro-Winkler distance between two strings */\n// eslint-disable-next-line max-statements\nexport function getDistance (s1: string, s2: string) {\n  // Exit early if either are empty.\n  if (s1.length === 0 || s2.length === 0) {\n    return 0\n  }\n\n  // Exit early if they're an exact match.\n  if (s1 === s2) {\n    return 1\n  }\n\n  const range = (Math.floor(Math.max(s1.length, s2.length) / 2)) - 1\n  const s1Matches = new Array(s1.length)\n  const s2Matches = new Array(s2.length)\n\n  let m = 0\n  for (let i = 0; i < s1.length; i++) {\n    const low = (i >= range) ? i - range : 0\n    const high = (i + range <= (s2.length - 1)) ? (i + range) : (s2.length - 1)\n\n    for (let j = low; j <= high; j++) {\n      if (s1Matches[i] !== true && s2Matches[j] !== true && s1[i] === s2[j]) {\n        ++m\n        s1Matches[i] = s2Matches[j] = true\n        break\n      }\n    }\n  }\n\n  // Exit early if no matches were found.\n  if (m === 0) {\n    return 0\n  }\n\n  // Count the transpositions.\n  let j; let k = 0\n  let numTrans = 0\n\n  for (let i = 0; i < s1.length; i++) {\n    if (s1Matches[i] === true) {\n      for (j = k; j < s2.length; j++) {\n        if (s2Matches[j] === true) {\n          k = j + 1\n          break\n        }\n      }\n\n      if (s1[i] !== s2[j]) {\n        ++numTrans\n      }\n    }\n  }\n\n  let weight = (m / s1.length + m / s2.length + (m - (numTrans / 2)) / m) / 3\n  let l = 0\n  const p = 0.1\n\n  if (weight > 0.7) {\n    while (s1[l] === s2[l] && l < 4) {\n      ++l\n    }\n\n    weight = weight + l * p * (1 - weight)\n  }\n\n  return weight\n}\n\nexport function getMatchMedia () {\n  if (!IN_BROWSER) return\n\n  return window.matchMedia('(prefers-color-scheme: dark)')\n}\n\nconst onRE = /^on[^a-z]/\nexport const isOn = (key: string) => onRE.test(key)\nexport const eventName = (name: string) => name.slice(2, 3).toLowerCase() + name.slice(3)\n\nexport function propsToString (props: Record<string, any>, bound: string[] = [], indent = 1) {\n  const displayedProps =\n    Object.entries(props)\n      .filter(([k, v]) => v !== undefined)\n      .map(([k, v]) => {\n        if (bound.includes(k)) return `:${k}=\"${v}\"`\n        if (isOn(k)) {\n          return v === true ? `@${eventName(k)}` : `@${eventName(k)}=\"${v}\"`\n        }\n        if (v === true) return k\n        if (typeof v === 'string') return `${k}=\"${v}\"`\n        if (Array.isArray(v)) return `:${k}=\"['${v.join(\"', '\")}']\"`\n        if (Object(v) === v) return `:${k}=\"${JSON.stringify(v).replace(/\"/g, \"'\")}\"`\n\n        return `:${k}=\"${v}\"`\n      })\n\n  const propsString = displayedProps.join(' ')\n\n  const shouldWrap = propsString.length > 50\n  if (!shouldWrap) {\n    return !propsString ? '' : ' ' + propsString\n  } else {\n    return '\\n' + displayedProps.map(v => '  '.repeat(indent) + v).join('\\n') + '\\n' + '  '.repeat(indent - 1)\n  }\n}\n\nexport function wrapInArray<T> (v: T | T[] | null | undefined): T[] {\n  return v == null\n    ? []\n    : Array.isArray(v)\n      ? v : [v]\n}\n"
  },
  {
    "path": "packages/docs/src/utils/markdown-it-rules.ts",
    "content": "import container from 'markdown-it-container'\nimport Token from 'markdown-it/lib/token.mjs'\nimport type MarkdownIt from 'markdown-it'\nimport type { RenderRule } from 'markdown-it/lib/renderer.mjs'\n\nfunction addCodeRules (md: MarkdownIt) {\n  const fence = md.renderer.rules.fence\n\n  md.renderer.rules.fence = function (tokens, idx, options, env, self) {\n    const handler = fence || self.renderToken\n    const token = tokens[idx]\n    const lang = extractLang(token.info || '')\n\n    return `<AppMarkup resource=\"${token?.attrs?.[0][1] ?? ''}\" language=\"${lang}\" class=\"mb-4\">${handler(tokens, idx, options, env, self)}</AppMarkup>`\n  }\n  md.renderer.rules.code_inline = function (tokens, idx) {\n    const token = tokens[idx]\n\n    const attrs = Object.entries(\n      (token.attrs || []).reduce((acc, [key, value]) => {\n        acc[key] = acc[key] ? acc[key] + ' ' + value : value\n        return acc\n      }, {} as Record<string, string>)\n    ).map(([key, value]) => `${key}=\"${value}\"`).join(' ')\n\n    return `<v-code ${attrs}>${md.utils.escapeHtml(token.content)}</v-code>`\n  }\n\n  createContainer(md, 'error')\n  createContainer(md, 'info')\n  createContainer(md, 'success')\n  createContainer(md, 'warning')\n  createContainer(md, 'tip', 'TIP')\n  createTabs(md)\n}\n\nfunction addImageRules (md: MarkdownIt) {\n  md.renderer.rules.image = (tokens, idx, options, env, self) => {\n    const token = tokens[idx]\n    const alt = token.content\n    const placeholder = token.attrGet('placeholder') ? 'https://cdn.vuetifyjs.com/docs/images/graphics/placeholder.png' : undefined\n    const src = placeholder ?? token.attrGet('src')\n    const title = token.attrGet('title') ?? ''\n    // const isEntry = alt.toLowerCase().includes('entry')\n    const height = token.attrGet('height') ?? ''\n\n    return `\n<AppFigure\n  ${alt ? `alt=\"${alt}\"` : ''}\n  ${src ? `src=\"${src}\"` : ''}\n  ${title ? `title=\"${title}\"` : ''}\n  ${height ? `height=\"${height}\"` : ''}\n/>\n`\n  }\n}\n\nfunction addHrRules (md: MarkdownIt) {\n  md.renderer.rules.hr = function (tokens, idx, options, env, self) {\n    return '<AppDivider />'\n  }\n}\n\nfunction addUnderlineRules (md: MarkdownIt) {\n  const renderEm: RenderRule = (tokens, idx, opts, env, self) => {\n    const token = tokens[idx]\n    if (token.markup === '_') {\n      token.tag = 'span'\n\n      token.type === 'em_open' && token.attrSet('style', 'text-decoration: underline;')\n    }\n    return self.renderToken(tokens, idx, opts)\n  }\n\n  md.renderer.rules.em_open = renderEm\n  md.renderer.rules.em_close = renderEm\n}\n\nfunction addHeadingRules (md: MarkdownIt) {\n  md.renderer.rules.heading_open = (tokens, idx, options, env, self) => {\n    const level = tokens[idx].markup.length\n    const next = tokens[idx + 1]\n    const children = next ? next.children : []\n    const [, href] = children?.[0].attrs?.[1] ?? []\n\n    if (next?.children) {\n      next.children = next.children.filter(token => !['link_open', 'link_close'].includes(token.type))\n    }\n\n    tokens[idx].tag = 'AppHeading'\n    tokens[idx].attrSet('href', href ?? '')\n    tokens[idx].attrSet('level', level.toString())\n\n    return self.renderToken(tokens, idx, options)\n  }\n  md.renderer.rules.heading_close = (tokens, idx, options, env, self) => {\n    tokens[idx].tag = 'AppHeading'\n\n    return self.renderToken(tokens, idx, options)\n  }\n}\n\nfunction addLinkRules (md: MarkdownIt) {\n  md.renderer.rules.link_open = md.renderer.rules.link_close = (tokens, idx, options, env, self) => {\n    tokens[idx].tag = 'AppLink'\n\n    return self.renderToken(tokens, idx, options)\n  }\n}\n\nfunction addTableRules (md: MarkdownIt) {\n  md.renderer.rules.table_open = md.renderer.rules.table_close = (tokens, idx, options, env, self) => {\n    tokens[idx].tag = 'AppTable'\n\n    return self.renderToken(tokens, idx, options)\n  }\n}\n\nexport default [\n  addCodeRules,\n  addHeadingRules,\n  addHrRules,\n  addLinkRules,\n  addImageRules,\n  addTableRules,\n  addUnderlineRules,\n]\n\n/**\n * Inspired by vitepress\n * https://github.com/vuejs/vitepress/blob/f9cfd16/src/node/markdown/plugins/containers.ts\n */\nfunction createContainer (md: MarkdownIt, type: string, title?: string) {\n  md.use(container, type, {\n    render (tokens, idx) {\n      const token = tokens[idx]\n      if (token.nesting === 1) {\n        return `<Alert type=\"${type}\">\\n` + (title ? `<p><strong>${title}:</strong></p>\\n` : '')\n      } else {\n        return `</Alert>\\n`\n      }\n    },\n  } satisfies { render: RenderRule })\n}\n\nfunction createTabs (md: MarkdownIt) {\n  // Inject \"::: tab\" around code blocks\n  md.core.ruler.push('tabs', state => {\n    let inTabs = false\n    let level = 0\n    for (let i = 0; i < state.tokens.length; i++) {\n      const token = state.tokens[i]\n\n      if (token.type === 'container_tabs_open') {\n        inTabs = true\n        level = token.level\n      } else if (token.type === 'container_tabs_close') {\n        inTabs = false\n      } else if (inTabs && token.level === level + 1 && token.type === 'fence' && token.tag === 'code') {\n        const title = extractTitle(token.info)\n        token.level += 1\n        const openToken = new Token('container_tab_open', 'div', 1)\n        openToken.info = ` tab ${title}`\n        openToken.markup = ':::'\n        openToken.block = true\n        openToken.level = level + 1\n        const closeToken = new Token('container_tab_close', 'div', -1)\n        closeToken.level = level + 1\n        closeToken.block = true\n        state.tokens.splice(i, 0, openToken)\n        state.tokens.splice(i + 2, 0, closeToken)\n        i += 2\n      }\n    }\n  })\n\n  md.use(container, 'tabs', {\n    render (tokens, idx) {\n      if (tokens[idx].nesting === 1) {\n        let tabs = ''\n        for (let i = idx + 1; i < tokens.length; i++) {\n          const token = tokens[i]\n\n          if (token.type === 'container_tab_open') {\n            const title = token.info.trim().slice('tab'.length).trim()\n            tabs += `<v-tab value=\"${title}\" variant=\"plain\" class=\"text-none\">${title}</v-tab>\\n`\n          } else if (token.type === 'container_tabs_close') break\n        }\n\n        return `<DocTabs>\\n<template #tabs>\\n${tabs}</template>\\n<template #content>\\n`\n      } else {\n        return `</template>\\n</DocTabs>\\n`\n      }\n    },\n  } satisfies { render: RenderRule })\n\n  md.use(container, 'tab', {\n    render (tokens, idx) {\n      if (tokens[idx].nesting === 1) {\n        const title = tokens[idx].info.trim().slice('tab'.length).trim()\n        return `<v-window-item value=\"${title}\">\\n`\n      } else {\n        return `\\n</v-window-item>\\n`\n      }\n    },\n  } satisfies { render: RenderRule })\n}\n\nfunction extractTitle (info: string) {\n  return info.match(/\\[(.*)\\]/)?.[1] || extractLang(info) || 'txt'\n}\n\nfunction extractLang (info: string) {\n  return info\n    .trim()\n    .replace(/:(no-)?line-numbers({| |$).*/, '')\n    .replace(/(-vue|{| ).*$/, '')\n    .replace(/^vue-html$/, 'template')\n}\n"
  },
  {
    "path": "packages/docs/src/utils/markdown-it.ts",
    "content": "import MarkdownItPrism from 'markdown-it-prism'\nimport MarkdownItLinkAttributes from 'markdown-it-link-attributes'\nimport MarkdownItAttrs from 'markdown-it-attrs'\nimport MarkdownItAnchor from 'markdown-it-anchor'\nimport MarkdownItHeaderSections from 'markdown-it-header-sections'\nimport MarkdownItMultimdTable from 'markdown-it-multimd-table'\nimport markdownRules from './markdown-it-rules'\nimport Emoji from 'markdown-it-emoji/bare.js'\nimport type MarkdownIt from 'markdown-it'\n\nexport function configureMarkdown (\n  md: MarkdownIt,\n  options: Partial<{ headerSections: boolean }> = {}\n) {\n  md.use(MarkdownItPrism)\n    .use(MarkdownItLinkAttributes, {\n      matcher (href: string) {\n        return /^https?:\\/\\//.test(href)\n      },\n      attrs: {\n        target: '_blank',\n        rel: 'noopener',\n      },\n    })\n    .use(MarkdownItAttrs)\n    .use(MarkdownItAnchor, {\n      tabIndex: false,\n      permalink: MarkdownItAnchor.permalink.headerLink(),\n      slugify: (str: unknown) => {\n        let slug = String(str)\n          .trim()\n          .toLowerCase()\n          .replace(/[\\s,.[\\]{}()/]+/g, '-')\n          .replace(/[^a-z0-9 -]/g, c => c.charCodeAt(0).toString(16))\n          .replace(/-{2,}/g, '-')\n          .replace(/^-*|-*$/g, '')\n\n        if (slug.charAt(0).match(/[^a-z]/g)) {\n          slug = 'section-' + slug\n        }\n\n        return encodeURIComponent(slug)\n      },\n    })\n    .use(Emoji, {\n      defs: {\n        rocket: '🚀',\n        wrench: '🔧',\n        microscope: '🔬',\n        arrows_counterclockwise: '🔄',\n        fire: '🔥',\n        test_tube: '🧪',\n      },\n    })\n    .use(MarkdownItMultimdTable, {\n      rowspan: true,\n    })\n\n  if (options.headerSections !== false) {\n    md.use(MarkdownItHeaderSections)\n  }\n\n  markdownRules.forEach(rule => rule(md))\n\n  return md\n}\n"
  },
  {
    "path": "packages/docs/src/utils/metadata.ts",
    "content": "interface Metadata {\n  title: string\n  description: string\n  keywords: string\n}\n\nexport function genAppMetaInfo (defaults: any) {\n  const metadata = (genMetaInfo as any)(...Object.values(defaults))\n\n  metadata.link.push(...genLink())\n\n  return metadata\n}\n\nexport function genMetaInfo (\n  title: string,\n  description: string,\n  keywords: string,\n  assets: string[] = [],\n) {\n  const length = (description ?? '').length\n\n  description = length <= 117\n    ? description\n    : `${description.slice(0, 116)}...`\n\n  const options = {\n    description,\n    keywords,\n    title,\n  }\n\n  return {\n    link: assets.map(href => ({ rel: 'stylesheet', href })),\n    meta: [\n      { key: 'description', name: 'description', content: description },\n      { key: 'keywords', name: 'keywords', content: keywords },\n      ...genFacebookMetaInfo(),\n      ...genOpenGraphMetaInfo(options),\n      ...genTwitterMetaInfo(),\n    ] as (Record<string, any>[]),\n    title,\n  }\n}\n\nfunction genFacebookMetaInfo () {\n  return parseMeta('fb', { app_id: '542948969434243' })\n}\n\nfunction genLink () {\n  const rels = ['preconnect', 'dns-prefetch']\n  const hrefs = [\n    'https://api.cosmicjs.com/',\n    'https://cdn.carbonads.com/',\n    'https://srv.carbonads.net/',\n    'https://www.google-analytics.com/',\n  ]\n  const link = [\n    { rel: 'shortcut icon', href: '/favicon.ico' },\n    // { rel: 'manifest', href: '/manifest.json' },\n    {\n      rel: 'search',\n      type: 'application/opensearchdescription+xml',\n      href: '/search.xml',\n      title: 'Vuetify',\n    },\n  ]\n\n  for (const rel of rels) {\n    for (const href of hrefs) {\n      link.push({ rel, href })\n    }\n  }\n\n  return link\n}\n\nfunction genOpenGraphMetaInfo (args: Metadata) {\n  return parseMeta('og', {\n    description: args.description,\n    image: 'https://cdn.vuetifyjs.com/docs/images/graphics/og-image.png',\n    site_name: 'Vuetify',\n    title: args.title,\n    type: 'website',\n  })\n}\n\nfunction parseMeta (\n  prefix: string,\n  metadata: Record<string, string>,\n) {\n  const meta = []\n\n  for (const key in metadata) {\n    const content = metadata[key]\n    const property = `${prefix}:${key}`\n\n    meta.push({\n      key: property,\n      property,\n      content,\n    })\n  }\n\n  return meta\n}\n\nfunction genTwitterMetaInfo () {\n  return parseMeta('twitter', {\n    image: 'https://cdn.vuetifyjs.com/docs/images/graphics/og-image.png',\n    card: 'summary_large_image',\n    domain: 'https://vuetifyjs.com/',\n    site: '@vuetifyjs',\n  })\n}\n"
  },
  {
    "path": "packages/docs/src/utils/pwa.ts",
    "content": "import eachLimit from 'async-es/eachLimit'\n\ntype ManifestEntry = { url: string, revision?: string }\ntype Manifest = ManifestEntry[]\n\nexport async function openCache (name: string) {\n  return caches.open(`${name}-${location.origin}`)\n}\n\nexport async function cacheManifestEntries (\n  manifest: Manifest,\n  progress?: (value: number, total: number) => void\n) {\n  const cache = await openCache('precache')\n  let count = 0\n  const total = manifest.length\n  await eachLimit(manifest, 8, async ({ url, revision }: ManifestEntry) => {\n    let response\n    try {\n      const _url = new URL(url, location.origin)\n      if (revision) {\n        _url.searchParams.set('WB_REVISION', revision)\n      }\n      response = ensureCacheableResponse(await fetch(_url))\n    } catch (err: any) {\n      console.warn(`[SW] Failed to cache ${url}`, err.message)\n      return\n    }\n    if (response.status === 200) {\n      await cache.put(url, response)\n    } else {\n      console.warn(`[SW] Failed to cache ${url}`, response.status, response.statusText)\n    }\n    progress?.(++count, total)\n  })\n  console.log('[SW] Precached', total, 'files')\n}\n\nexport async function cleanCache (previousManifest: Manifest) {\n  if (!previousManifest) return\n\n  const precache = await openCache('precache')\n\n  const responses = await Promise.all(\n    previousManifest.map(entry => precache.match(entry.url))\n  )\n\n  // Date of earliest entry in the old manifest\n  const date = Array.from(\n    new Set(responses.filter(v => !!v).map(getDate))\n  ).reduce((acc, val) => Math.min(acc, val), Date.now())\n\n  console.log('[SW] Cleaning caches before', new Date(date))\n\n  let n = 0\n  for (const cache of [precache, await openCache('runtime')]) {\n    for (const req of await cache.keys()) {\n      const res = await cache.match(req)\n      if (res && getDate(res) < date) {\n        ++n\n        await cache.delete(req)\n      }\n    }\n  }\n  console.log(`[SW] Cleared ${n} old items from cache`)\n}\n\nfunction getDate (response: Response) {\n  const date = new Date(Object.fromEntries(response.headers).date)\n  return date.getTime()\n}\n\nexport function ensureCacheableResponse (response: Response) {\n  if (!response.redirected) return response\n\n  if (!response.url || new URL(response.url).origin !== location.origin) {\n    console.error('[SW] Uncacheable redirect', response.url, response)\n    return Response.error()\n  }\n\n  const cloned = response.clone()\n  return new Response(cloned.body, {\n    headers: new Headers(cloned.headers),\n    status: cloned.status,\n    statusText: cloned.statusText,\n  })\n}\n\nexport function messageSW (sw: ServiceWorker, data: {}): Promise<any> {\n  return new Promise(resolve => {\n    const messageChannel = new MessageChannel()\n    messageChannel.port1.onmessage = (event: MessageEvent) => {\n      resolve(event.data)\n    }\n    sw.postMessage(data, [messageChannel.port2])\n  })\n}\n"
  },
  {
    "path": "packages/docs/src/utils/routes.ts",
    "content": "// Imports\nimport locales from '@/i18n/locales.json'\nimport generatedPages from 'virtual:generated-pages'\nimport redirects from '@/data/301.json'\n\n// Regexp\n// const genericLocaleRegexp = /[a-z]{2,3}|[a-z]{2,3}-[a-zA-Z]{4}|[a-z]{2,3}-[A-Z]{2,3}/\nexport const languagePattern = locales.filter(l => l.enabled).map(lang => lang.alternate || lang.locale).join('|')\nexport const disabledLanguagePattern = locales.filter(l => !l.enabled).map(lang => lang.alternate || lang.locale).join('|')\nexport const anyLanguagePattern = locales.map(lang => lang.alternate || lang.locale).join('|')\n\nexport function preferredLocale (locale = 'en') {\n  if (!IN_BROWSER) return locale\n\n  const languages = ([] as string[]).concat(window.localStorage.getItem('currentLocale') || [], navigator.languages || [])\n\n  return languages.find(l => locales.some(locale => locale.enabled && l === (locale.alternate || locale.locale))) || locale\n}\n\nexport function rpath (path = '') {\n  const locale = preferredLocale()\n  const [_url, hash] = path.split('#')\n  const [url, query] = _url.split('?')\n\n  return leadingSlash(trailingSlash([\n    '',\n    locale,\n    ...url.split('/').filter(p => !!p && p !== locale),\n  ].filter(v => v != null).join('/'))) + (hash ? `#${hash}` : '') + (query ? `?${query}` : '')\n}\n\nexport function leadingSlash (str: string) {\n  return str.startsWith('/') ? str : '/' + str\n}\n\nexport function trailingSlash (str: string) {\n  return str.endsWith('/') ? str : str + '/'\n}\n\nexport const generatedRoutes = generatedPages.map(route => ({\n  ...route,\n  path: trailingSlash(route.path),\n}))\n\nexport const redirectRoutes = IN_BROWSER ? Object.entries(redirects).flatMap(([from, to]) => [\n  {\n    path: `/${from}`,\n    redirect: to,\n  },\n  {\n    path: `/:locale(${anyLanguagePattern})/${from}`,\n    redirect: to,\n  },\n]) : []\n"
  },
  {
    "path": "packages/docs/src/vite-env.d.ts",
    "content": "/// <reference types=\"vite/client\" />\n"
  },
  {
    "path": "packages/docs/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"esModuleInterop\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"incremental\": false,\n    \"lib\": [\n      \"dom\",\n      \"dom.iterable\",\n      \"esnext\"\n    ],\n    \"module\": \"esnext\",\n    \"moduleResolution\": \"bundler\",\n    \"noUnusedLocals\": true,\n    \"paths\": {\n      \"@/*\": [\"./src/*\"]\n    },\n    \"resolveJsonModule\": true,\n    \"skipLibCheck\": true,\n    \"strict\": true,\n    \"strictNullChecks\": true,\n    \"allowJs\": true,\n    \"allowImportingTsExtensions\": true,\n    \"target\": \"esnext\",\n    \"types\": [\n      \"vite/client\",\n      \"vite-plugin-pages/client\",\n      \"vite-plugin-vue-layouts/client\",\n      \"vite-plugin-pwa/client\",\n      \"vue-router\"\n    ],\n    \"outDir\": \"./dist\"\n  },\n  \"include\": [\n    \"build\",\n    \"src\",\n    \"./auto-imports.d.ts\",\n    \"./components.d.ts\",\n    \"../api-generator/src/shims.d.ts\"\n  ],\n  \"exclude\": [\"dist\", \"node_modules\"],\n}\n"
  },
  {
    "path": "packages/docs/vite.config.mts",
    "content": "import path from 'upath'\nimport fs from 'node:fs/promises'\nimport { fileURLToPath } from 'node:url'\n\nimport { defineConfig, loadEnv } from 'vite'\nimport AutoImport from 'unplugin-auto-import/vite'\nimport Vue, { parseVueRequest } from '@vitejs/plugin-vue'\nimport ViteFonts from 'unplugin-fonts/vite'\nimport Pages from 'vite-plugin-pages'\nimport Layouts from 'vite-plugin-vue-layouts'\nimport Components from 'unplugin-vue-components/vite'\nimport Markdown from 'vite-plugin-md'\nimport { VitePWA } from 'vite-plugin-pwa'\nimport VueI18n from '@intlify/unplugin-vue-i18n/vite'\nimport Inspect from 'vite-plugin-inspect'\nimport Vuetify from 'vite-plugin-vuetify'\nimport basicSsl from '@vitejs/plugin-basic-ssl'\nimport MagicString from 'magic-string'\n\nimport { configureMarkdown } from './build/markdown-it'\nimport Api from './build/api-plugin'\nimport { Examples } from './build/examples-plugin'\nimport { genAppMetaInfo } from './src/utils/metadata'\nimport { MdiJs } from './build/mdi-js'\nimport { frontmatterBuilder, getRouteMeta, scriptFixer } from './build/markdownBuilders'\n\nconst resolve = (file: string) => fileURLToPath(new URL(file, import.meta.url))\n\nconst ssrTransformCustomDirective = () => {\n  return {\n    props: [],\n    needRuntime: true,\n  }\n}\n\nexport default defineConfig(({ command, mode, isSsrBuild }) => {\n  Object.assign(process.env, loadEnv(mode, process.cwd(), ''))\n\n  let allRoutes: any[]\n\n  return {\n    logLevel: 'info',\n    resolve: {\n      alias: [\n        { find: '@', replacement: `${resolve('src')}/` },\n        { find: 'node-fetch', replacement: 'isomorphic-fetch' },\n        { find: /^vue$/, replacement: isSsrBuild ? 'vue' : 'vue/dist/vue.runtime.esm-bundler.js' },\n      ],\n    },\n    define: {\n      'process.env.NODE_ENV': mode === 'production' || isSsrBuild ? '\"production\"' : '\"development\"',\n      __INTLIFY_PROD_DEVTOOLS__: 'false',\n    },\n    css: {\n      preprocessorOptions: {\n        sass: {\n          api: 'modern-compiler'\n        }\n      },\n    },\n    build: {\n      sourcemap: true,\n      modulePreload: false,\n      cssCodeSplit: false,\n      minify: true,\n      rollupOptions: {\n        output: isSsrBuild ? { inlineDynamicImports: true } : {\n          // TODO: these options currently cause a request cascade\n          // experimentalMinChunkSize: 20 * 1024,\n          // manualChunks (id) {\n          //   if (\n          //     ['vue/', '@vue/', 'vue-', 'pinia', '@vueuse/'].some(part => id.includes('node_modules/' + part)) ||\n          //     id === '\\0plugin-vue:export-helper'\n          //   ) return 'vendor'\n          //   if (id.includes('packages/vuetify/')) return 'vuetify'\n          //   if (id.includes('packages/docs/src/api')) return 'api-pages'\n          // }\n        },\n      },\n    },\n    esbuild: {\n      lineLimit: 1000,\n    },\n    plugins: [\n      // https://github.com/unplugin/unplugin-auto-import\n      AutoImport({\n        include: [/\\.[tj]sx?$/, /\\.vue$/, /\\.vue\\?vue/, /\\.md$/],\n        dirs: [\n          './src/composables/**',\n          './src/stores/**',\n          './src/utils/**',\n        ],\n        imports: [\n          'vue',\n          'vue-router',\n          'pinia',\n          {\n            '@vuetify/one': [\n              'createOne',\n              'useAuthStore',\n              'useHttpStore',\n              'useOneStore',\n              'useUserStore',\n              'useQueueStore',\n              'useSettingsStore',\n              'useProductsStore',\n            ],\n            'lodash-es': ['camelCase', 'kebabCase', 'upperFirst'],\n            vue: ['camelize', 'mergeProps'],\n            vuetify: ['useDate', 'useDisplay', 'useGoTo', 'useRtl', 'useTheme'],\n            'vue-i18n': ['useI18n'],\n          }\n        ],\n        vueTemplate: true,\n      }),\n\n      // https://github.com/stafyniaksacha/vite-plugin-fonts\n      ViteFonts({\n        google: {\n          families: [{\n            name: 'Roboto',\n            styles: 'wght@100;300;400;500;700;900',\n          }],\n        },\n      }),\n\n      Api(),\n\n      // https://github.com/antfu/unplugin-vue-components\n      Components({\n        directoryAsNamespace: true,\n        include: [/\\.vue$/, /\\.vue\\?vue/, /\\.md$/, /\\.md\\?vue/],\n        exclude: [],\n        excludeNames: ['AppMarkdown'],\n      }),\n\n      // https://github.com/JohnCampionJr/vite-plugin-vue-layouts\n      Layouts({\n        layoutsDirs: 'src/layouts',\n        importMode (name) {\n          return name === 'home' ? 'sync' : 'async'\n        }\n      }),\n\n      // https://github.com/antfu/vite-plugin-md\n      Markdown({\n        wrapperClasses: '',\n        exposeFrontmatter: true,\n        exposeExcerpt: false,\n        markdownItSetup: configureMarkdown,\n        builders: [frontmatterBuilder(), scriptFixer()]\n      }),\n\n      // https://github.com/hannoeru/vite-plugin-pages\n      Pages({\n        extensions: ['vue', 'md'],\n        dirs: [\n          { dir: 'src/pages', baseRoute: '' },\n        ],\n        extendRoute (route) {\n          let [locale, category, ...rest] = route.path.split('/').slice(1)\n\n          const idx = route.component.toLowerCase().indexOf(locale)\n          locale = ~idx ? route.component.slice(idx, idx + locale.length) : locale\n\n          const meta = getRouteMeta(route.component, locale)\n\n          if (meta.disabled) {\n            return { disabled: true }\n          }\n\n          return {\n            ...route,\n            path: '/' + [locale, category, ...rest].filter(Boolean).join('/') + '/',\n            meta: {\n              ...meta,\n              category,\n              locale,\n            },\n          }\n        },\n        onRoutesGenerated (routes) {\n          allRoutes = routes.filter(route => !route.disabled)\n          return allRoutes.map(route => ({\n            ...route,\n            meta: JSON.parse(JSON.stringify({ // remove undefined\n              category: route.meta.category,\n              emphasized: route.meta.emphasized,\n              layout: route.meta.layout,\n              locale: route.meta.locale,\n              nav: route.meta.nav,\n              title: route.meta.title,\n            }))\n          }))\n        },\n        importMode (filepath) {\n          return [\n            '/src/pages/en/getting-started/installation.md',\n            '/src/pages/en/index.md'\n          ].includes(filepath) ? 'sync' : 'async'\n        }\n      }),\n\n      // https://github.com/antfu/vite-plugin-pwa\n      VitePWA({\n        srcDir: 'src',\n        filename: 'service-worker.js',\n        strategies: 'injectManifest',\n        includeAssets: ['favicon.ico'],\n        injectRegister: false,\n        injectManifest: {\n          globIgnores: ['**/*.html', '**/*.map'],\n          additionalManifestEntries: [\n            { url: '_fallback.html', revision: Date.now().toString(16) },\n          ],\n          dontCacheBustURLsMatching: /^\\/?assets\\//,\n          maximumFileSizeToCacheInBytes: 24 * 1024 ** 2,\n        },\n        manifest: {\n          name: 'Vuetify',\n          description: 'Vuetify UI Library Documentation',\n          short_name: 'Vuetify',\n          theme_color: '#1867C0',\n          display: 'minimal-ui',\n          display_override: ['minimal-ui', 'browser'],\n          icons: [\n            {\n              src: 'img/icons/android-chrome-192x192.png',\n              sizes: '192x192',\n              type: 'image/png',\n            },\n            {\n              src: 'img/icons/android-chrome-512x512.png',\n              sizes: '512x512',\n              type: 'image/png',\n            },\n          ],\n        },\n      }),\n\n      {\n        // Remove options block from examples\n        name: 'vuetify:example-setup',\n        transform (code, id) {\n          const { filename, query } = parseVueRequest(id)\n          if (query.raw || query.url) return\n          if (filename.includes('packages/docs/src/examples')) {\n            const composition = /(<script setup>[\\w\\W]*?<\\/script>)/g.exec(code)\n            const options = /(<script>[\\w\\W]*?<\\/script>)/g.exec(code)\n\n            if (composition && options) {\n              const s = new MagicString(code)\n              s.remove(options.index, options.index + options[0].length + 1)\n              return {\n                code: s.toString(),\n                map: s.generateMap({ hires: true }),\n              }\n            }\n          }\n        }\n      },\n\n      // mdi js names and aliases from `@mdi/svg`\n      MdiJs(),\n\n      Vue({\n        include: [/\\.vue$/, /\\.md$/],\n        // https://github.com/vuejs/vue-next/issues/3298\n        template: {\n          compilerOptions: {\n            directiveTransforms: {\n              ripple: ssrTransformCustomDirective,\n            },\n          },\n        },\n      }),\n\n      Vuetify({\n        autoImport: { labs: true },\n        styles: command === 'serve' || mode === 'development' ? 'sass' : true,\n      }),\n\n      // https://github.com/intlify/bundle-tools/tree/main/packages/vite-plugin-vue-i18n\n      VueI18n({\n        compositionOnly: true,\n        include: [resolve('src/i18n/messages/**')],\n      }),\n\n      Examples(),\n\n      {\n        name: 'vuetify:example-blocks',\n        transform (code, id) {\n          const type = id.includes('vue&type=playground-resources') ? 'playgroundResources'\n            : id.includes('vue&type=playground-setup') ? 'playgroundSetup'\n            : id.includes('vue&type=example-meta') ? 'exampleMeta'\n            : null\n          if (!type) return\n\n          return {\n            code: `export default Comp => Comp['${type}'] = \\`${code.replace(/`/g, '\\\\`')}\\``,\n            map: null,\n          }\n        },\n      },\n\n      {\n        // lightweight head-only ssg\n        name: 'vuetify:ssg',\n        enforce: 'post',\n        transformIndexHtml: {\n          order: 'post',\n          async handler (html) {\n            if (mode !== 'production') return html\n\n            await fs.mkdir('dist', { recursive: true })\n            await fs.writeFile(path.join('dist/_fallback.html'), html)\n\n            const routes = allRoutes.filter(({ path: route }) => {\n              return route !== '/' &&\n                !['/eo-UY/', '/api/', '/user/', ':', '*'].some(v => route.includes(v))\n            }).map(route => {\n              const meta = genAppMetaInfo({\n                title: `${route.meta.title}${route.path === '/en/' ? '' : ' — Vuetify'}`,\n                description: route.meta.description,\n                keywords: route.meta.keywords,\n              })\n              const metaContent = [\n                `<title>${meta.title}</title>`,\n                ...meta.meta.map((v: any) => {\n                  const attrs = Object.keys(v).filter(k => k !== 'key').map(k => `${k}=\"${v[k]}\"`).join(' ')\n                  return `<meta ${attrs}>`\n                }),\n                ...meta.link.map((v: any) => {\n                  const attrs = Object.keys(v).map(k => `${k}=\"${v[k]}\"`).join(' ')\n                  return `<link ${attrs}>`\n                }),\n              ].join('\\n    ')\n              const content = html.replace('<!-- @inject-meta -->', metaContent)\n              return {\n                path: route.path,\n                content\n              }\n            })\n\n            for (const route of routes) {\n              const filename = path.join('dist', route.path, 'index.html')\n              await fs.mkdir(path.dirname(filename), { recursive: true })\n              await fs.writeFile(filename, route.content)\n            }\n\n            return routes.find(r => r.path === '/en/')?.content\n          }\n        },\n      },\n\n      Inspect(),\n\n      process.env.HTTPS === 'true' ? basicSsl() : undefined,\n    ],\n\n    optimizeDeps: {\n      include: [\n        'vue',\n        'vue-router',\n        'vue-instantsearch/vue3/es/src/instantsearch.js',\n        'algoliasearch',\n        'markdown-it-prism',\n        'markdown-it-link-attributes',\n        'markdown-it-attrs',\n        'markdown-it-anchor',\n        'markdown-it-header-sections',\n        'markdown-it-emoji/bare.js',\n        'markdown-it-container',\n        'markdown-it/lib/token.mjs',\n        'markdown-it-multimd-table',\n        'lodash-es',\n        'fflate',\n        '@cosmicjs/sdk',\n      ],\n      // In development mode, prevent pre-bundling of @vuetify libs for HMR linking\n      exclude: process.env.NODE_ENV ==='development' ? ['@vuetify/one'] : [],\n    },\n\n    ssr: {\n      noExternal: ['vue-i18n', '@vuelidate/core', 'pinia'],\n    },\n\n    server: {\n      port: +(process.env.PORT ?? 8095),\n      warmup: {\n        clientFiles: ['./index.html'],\n      },\n    },\n  }\n})\n"
  },
  {
    "path": "packages/vuetify/.browserslistrc",
    "content": ">0.5%\nChrome >0 and since 2023-12\nChromeAndroid >0 and since 2023-12\nFirefox >0 and since 2023-12\nFirefoxAndroid >0 and since 2023-12\nSafari >0 and since 2023-12\niOS >0 and since 2023-12\nnot dead\nnot op_mini all\nnot and_uc 1\n"
  },
  {
    "path": "packages/vuetify/.eslintignore",
    "content": "/build/\n\n# playground components type definitions generated by unplugin-vue-components\n/dev/components.d.ts\n\n# Built files\n/es5/\n/lib/\n/lib-temp/\n/dist/\n/cypress/\n*.spec.cy.ts\n*.spec.cy.tsx\n"
  },
  {
    "path": "packages/vuetify/.eslintrc.cjs",
    "content": "module.exports = {\n  globals: {\n    __VUETIFY_VERSION__: true,\n    __REQUIRED_VUE__: true,\n  },\n  extends: [\n    // 'plugin:import/typescript', // slow, only enable if needed\n  ],\n  rules: {\n    'no-console': 'error',\n    'no-debugger': 'error',\n    'no-labels': 'off',\n\n    // 'vue/html-self-closing': 'off',\n    // 'vue/html-closing-bracket-spacing': 'off',\n    // 'local-rules/no-render-string-reference': 'error',\n    'local-rules/no-components-index': 'error',\n    'local-rules/no-nullish-coalescing-in-condition': 'error',\n\n    'no-restricted-imports': ['error', {\n      paths: [{\n        name: 'vue',\n        importNames: ['defineComponent'],\n        message: 'Please use wrapped function from @/util instead',\n      }],\n    }],\n\n    // 'import/no-cycle': 'warn',\n    // 'import/no-self-import': 'warn',\n  },\n  overrides: [\n    {\n      files: 'src/**/*',\n      rules: {\n        'local-rules/sort-imports': 'warn',\n      },\n    },\n    {\n      files: 'dev/Playground.vue',\n      rules: {\n        'max-len': 'off',\n      },\n    },\n    {\n      files: '**/*.spec.?(browser.){ts,tsx}',\n      plugins: ['vitest'],\n      extends: ['plugin:vitest/legacy-all'],\n      rules: {\n        'local-rules/vitest-global-imports': 'error',\n\n        'no-restricted-imports': 'off',\n\n        'vitest/no-commented-out-tests': 'off',\n        'vitest/prefer-expect-assertions': 'off',\n        'vitest/max-expects': 'off',\n        'vitest/consistent-test-filename': 'off',\n        'vitest/prefer-to-be-truthy': 'off',\n        'vitest/prefer-to-be-falsy': 'off',\n        'vitest/no-hooks': 'off',\n        'vitest/prefer-lowercase-title': 'off',\n        'vitest/require-hook': 'off',\n        'vitest/prefer-snapshot-hint': 'off',\n        'vitest/no-disabled-tests': 'off',\n        'vitest/prefer-strict-equal': 'off',\n        'vitest/prefer-called-with': 'off',\n\n        'vitest/no-focused-tests': ['error', { fixable: false }],\n      },\n    },\n  ],\n}\n"
  },
  {
    "path": "packages/vuetify/.gitignore",
    "content": "/dev/Playground.vue\n/dev/components.d.ts\n/cypress/screenshots\n\n# Built files\n/es5/\n/lib/\n/lib-temp/\n/types-temp/\n/dist/\n/dev/dist/\n\n# local env files\n.env.local\n.env.*.local\n\n# Log files\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# Editor directories and files\n.idea\n.vscode\n*.suo\n*.ntvs*\n*.njsproj\n*.sln\n*.sw?\n\n.vercel\n.vizzly\n"
  },
  {
    "path": "packages/vuetify/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2016-now Vuetify, LLC\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "packages/vuetify/README.md",
    "content": "<div align=\"center\">\n  <picture>\n    <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://cdn.vuetifyjs.com/docs/images/one/logos/vuetify-logo-dark.png\">\n    <img alt=\"Vuetify Logo\" src=\"https://cdn.vuetifyjs.com/docs/images/one/logos/vuetify-logo-light.png\" height=\"100\">\n  </picture>\n</div>\n\n<p align=\"center\">\n  <a href=\"https://www.npmjs.com/package/vuetify\">\n    <img src=\"https://img.shields.io/npm/dt/vuetify.svg\" alt=\"Downloads\">\n  </a>\n  <a href=\"https://www.npmjs.com/package/vuetify\">\n    <img src=\"https://img.shields.io/npm/dm/vuetify.svg\" alt=\"Downloads\">\n  </a>\n  <br>\n  <a href=\"https://github.com/vuetifyjs/vuetify/blob/master/LICENSE.md\">\n    <img src=\"https://img.shields.io/npm/l/vuetify.svg\" alt=\"License\">\n  </a>\n  <a href=\"https://community.vuetifyjs.com\">\n    <img src=\"https://discordapp.com/api/guilds/340160225338195969/widget.png\" alt=\"Chat\">\n  </a>\n  <br>\n  <a href=\"https://www.npmjs.com/package/vuetify\">\n    <img src=\"https://img.shields.io/npm/v/vuetify.svg\" alt=\"Version\">\n  </a>\n  <a href=\"https://cdnjs.com/libraries/vuetify\">\n    <img src=\"https://img.shields.io/cdnjs/v/vuetify.svg\" alt=\"CDN\">\n  </a>\n</p>\n\n### 🖥️ Documentation\n\nTo check out the documentation, visit [vuetifyjs.com](https://vuetifyjs.com).\n\n![Crowdin Uploads](https://github.com/vuetifyjs/vuetify/workflows/Crowdin%20Uploads/badge.svg?branch=master)\n\n### ⚡ Quick Start\n\nGetting started with Vuetify is easy. To create a new project, choose your package manager and run one of the following commands:\n\nUsing [pnpm](https://pnpm.io/)\n\n```bash\npnpm create vuetify\n```\n\nUsing [yarn](https://yarnpkg.com/)\n\n```bash\nyarn create vuetify\n```\n\nUsing [npm](https://npmjs.com/)\n\n```bash\nnpm create vuetify@latest\n```\n\nUsing [bun](https://bun.sh/)\n\n```bash\nbun create vuetify\n```\n\nFor more information on how to get started, such as using Nuxt or Laravel, check out the official [Installation guide](https://vuetifyjs.com/getting-started/installation/).\n\n### 💖 Supporting Vuetify\n\nVuetify is a [MIT licensed](https://opensource.org/licenses/MIT) project that is developed and maintained by the [Core Team](https://vuetifyjs.com/about/meet-the-team/). Sponsor Vuetify and receive some **awesome perks** and support Open Source Software at the same time! 🎉\n\n<ul>\n  <li>\n    <a href=\"https://github.com/users/johnleider/sponsorship\">Become a backer or sponsor on GitHub</a>\n  </li>\n  <li>\n    <a href=\"https://opencollective.com/vuetify\">Become a backer or sponsor on Open Collective</a>\n    <strong><small>(supports the Core team)</small></strong>\n  </li>\n  <li>\n    <a href=\"https://tidelift.com/subscription/request-a-demo?utm_source=npm-vuetify&utm_medium=referral&utm_campaign=enterprise\">Become a subscriber on Tidelift</a>\n  </li>\n  <li>\n    <a href=\"https://paypal.me/vuetify\">Make a one-time payment with Paypal</a>\n  </li>\n</ul>\n\n### What's the difference between GitHub Sponsors and OpenCollective?\n\nFunds donated through GitHub Sponsors directly support [John Leider](https://github.com/sponsors/johnleider) and the ongoing development and maintenance of Vuetify. Funds donated via Open Collective are managed with transparent expenses and will be used for compensating work and expenses for Core team members. Your name/logo will receive proper recognition and exposure by donating on either platform.\n\n<h3><b>Special Sponsor</b></h3>\n\n<table>\n  <tbody>\n    <tr>\n      <td>\n        <a href=\"https://www.deepcloud.swiss/\" target=\"_blank\">\n          <img height=\"65px\" src=\"https://cdn.cosmicjs.com/20504e40-6cbc-11ef-b5ae-a594bb4a8e67-deepcloud-light.svg\">\n        </a>\n      </td>\n    </tr>\n  </tbody>\n</table>\n\n<h3><b>Diamond Sponsors</b></h3>\n\n<table>\n  <tbody>\n    <tr>\n      <td>\n        <a href=\"https://route4me.com/\">\n          <img height=\"40px\" src=\"https://cdn.cosmicjs.com/3b7a95b0-5360-11ef-b1ea-f56c65dfade9-route-4-me-light.png\">\n        </a>\n      </td>\n      <td>\n        <a href=\"https://www.abacus.ch/\">\n          <img height=\"40px\" src=\"https://cdn.cosmicjs.com/0b978be0-6cbb-11ef-b5ae-a594bb4a8e67-abacus-light.svg\">\n        </a>\n      </td>\n      <td>\n        <a href=\"https://www.hoop.swiss/\">\n          <img height=\"40px\" src=\"https://cdn.cosmicjs.com/94012850-6cbc-11ef-b5ae-a594bb4a8e67-hoop-light.svg\">\n        </a>\n      </td>\n    </tr>\n  </tbody>\n</table>\n\n<h3><b>Platinum Sponsors</b></h3>\n\n<table>\n  <tbody>\n    <tr>\n      <td style=\"text-align: center;\">\n        <a href=\"https://www.muenchen.de/\">\n          <img height=\"30px\" src=\"https://imgix.cosmicjs.com/af2ce530-eaa2-11ed-ba82-019c4666da06-itm-logo.png\">\n        </a>\n      </td>\n    </tr>\n    <tr></tr>\n  </tbody>\n</table>\n\n---\n\n### 🚀 Introduction\n\nVuetify is a no design skills required UI Library with beautifully handcrafted Vue Components. No design skills required — everything you need to create amazing applications is at your fingertips. Vuetify has a massive API that supports any use-case. Some highlights include:\n\n- **Customizable:** Extensive customization options with [SASS/SCSS](https://vuetifyjs.com/features/sass-variables/) and [Default configuration](https://vuetifyjs.com/features/presets/) and [Blueprints](https://vuetifyjs.com/features/blueprints/)\n- **Responsive Layout:** The default configuration of Vuetify components is responsive, allowing your application to adapt to different screen sizes.\n- **Theme System:** A powerful color system that makes it easy to style your application with a consistent color palette.\n- **Vite Support:** _Smaller_ bundle sizes with **automatic** tree-shaking\n- **6 months** Long-term support for [Major releases](https://vuetifyjs.com/introduction/long-term-support/)\n- **Internationalization:** 42+ supported languages\n\n#### Browser Support\n\nVuetify supports all **modern browsers**, including Safari 13+ (using [polyfills](https://vuetifyjs.com/getting-started/browser-support)). Components are designed for a minimum width of _320px_.\n\n### 🌎 Vuetify Ecosystem\n\n#### Resources\n\n<table>\n  <thead>\n    <tr>\n      <th>Name</th>\n      <th>Description</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <td>\n        <a href=\"https://github.com/vuetifyjs/awesome/\">\n          🕶️&nbsp;Vuetify&nbsp;Awesome\n        </a>\n      </td>\n      <td>Awesome stuff built with Vuetify.</td>\n    </tr>\n    <tr>\n      <td>\n        <a href=\"https://bin.vuetifyjs.com/\">\n          🗑️&nbsp;Vuetify&nbsp;Bin\n        </a>\n      </td>\n      <td>A pastebin for saving code snippets.</td>\n    </tr>\n    <tr>\n      <td>\n        <a href=\"https://github.com/vuetifyjs/create/\">\n          🫧&nbsp;Vuetify&nbsp;Create\n        </a>\n      </td>\n      <td>Scaffolding tools for creating new Vuetify projects.</td>\n    </tr>\n    <tr>\n      <td>\n        <a href=\"https://community.vuetifyjs.com/\">\n          💭&nbsp;Vuetify&nbsp;Discord\n        </a>\n      </td>\n      <td>Our massive and inclusive Discord server where you can ask questions, share feedback, and connect with other Vuetify developers.</td>\n    </tr>\n    <tr>\n      <td>\n        <a href=\"https://github.com/vuetifyjs/eslint-config-vuetify\">\n          🧹&nbsp;Vuetify&nbsp;ESLint\n        </a>\n      </td>\n      <td>An opinionated [ESLint config](https://github.com/vuetifyjs/eslint-config-vuetify) for styling and an [ESLint plugin](https://github.com/vuetifyjs/eslint-plugin-vuetify) for upgrading Vuetify version.</td>\n    </tr>\n    <tr>\n      <td>\n        <a href=\"https://issues.vuetifyjs.com/\">\n          🐛&nbsp;Vuetify&nbsp;Issues\n        </a>\n      </td>\n      <td>A web application for reporting bugs and issues with Vuetify, Documentation, or one of our other packages.</td>\n    </tr>\n    <tr>\n      <td>\n        <a href=\"https://github.com/vuetifyjs/vuetify-loader\">\n          📦&nbsp;Vuetify&nbsp;Loader\n        </a>\n      </td>\n      <td>A monorepo of compiler plugins for autoloading Vuetify components and configuring styles.</td>\n    </tr>\n    <tr>\n      <td>\n        <a href=\"https://github.com/vuetifyjs/mcp/\">\n          🧠&nbsp;Vuetify&nbsp;MCP\n        </a>\n      </td>\n      <td>A Model Context Protocol server for developing with Vuetify and Agents.</td>\n    </tr>\n    <tr>\n      <td>\n        <a href=\"https://play.vuetifyjs.com/\">\n          🎮&nbsp;Vuetify&nbsp;Playground\n        </a>\n      </td>\n      <td>A Vuetify 3 playground built using <a href=\"https://github.com/vuejs/repl\">vuejs/repl</a> where you can play with our components.</td>\n    </tr>\n    <tr>\n      <td>\n        <a href=\"https://snips.vuetifyjs.com\">\n          ✂️&nbsp;Vuetify&nbsp;Snips\n        </a>\n      </td>\n      <td>Pre-built code snippets for Vuetify components that you can use in your projects</td>\n    </tr>\n    <tr>\n      <td>\n        <a href=\"https://store.vuetifyjs.com/\">\n          🛒&nbsp;Vuetify&nbsp;Store\n        </a>\n      </td>\n      <td>The official Vuetify Store where you can download free digital products, purchase pre-made themes, and more.</td>\n    </tr>\n  </tbody>\n</table>\n\n### 🙋‍♂️ Questions\n\nFor help and support questions, please use our [Discord community](https://community.vuetifyjs.com). This issue list of this repo is **exclusively** for bug reports and feature requests.\n\n### 🐛 Issues\n\nUse our [Issue generator](https://issues.vuetifyjs.com) to report bugs and request new features.\n\nPlease make sure to read the [Important Information](https://github.com/vuetifyjs/vuetify/blob/master/.github/CONTRIBUTING.md#important-information) before opening an issue. Issues not confirming to the guidelines may be closed immediately.\n\n2️⃣ Vuetify 2 Support\nVuetify 2 is now End Of Life (EOL) and is no longer supported, even for security issues. Commercial support for this version is available from our partner, [HeroDevs](https://www.herodevs.com/support/vuetify-nes?utm_source=partnership&utm_medium=partnership&utm_campaign=partnership&utm_id=vuetify2).\n\n### 📝 Changelog\n\nDetailed changes for each release are documented in the [release notes](https://vuetifyjs.com/getting-started/release-notes/).\n\n### 💁‍♂️ Contributing\n\nDevelopers interested in contributing should read the [Code of Conduct](./CODE_OF_CONDUCT.md) and the [Contribution Guide](https://vuetifyjs.com/getting-started/contributing/).\n\n> Please do **not** ask general questions in an issue. Issues are only to report bugs, suggest\n  enhancements, or request new features. For general questions and discussions, ask in the [community chat](https://community.vuetifyjs.com/).\n\nTo help you get you familiar with our contribution process, we have a list of [good first issues](https://github.com/vuetifyjs/vuetify/labels/good%20first%20issue) that contain bugs which have a relatively limited scope. This is a great place to get started. If you have any questions, please join us on the [community chat](https://community.vuetifyjs.com).\n\nWe also have a list of [help wanted](https://github.com/vuetifyjs/vuetify/labels/help%20wanted) issues that you might want to check.\n\n### 📑 License\n\nVuetify is available under the [MIT](https://opensource.org/licenses/MIT) software license.\n\nCopyright (c) 2016-present Vuetify, LLC\n\n---\n\nThis project exists thanks to all the people who contribute 😍!\n\n<a href=\"https://github.com/vuetifyjs/vuetify/graphs/contributors\"><img src=\"https://opencollective.com/vuetify/contributors.svg?width=890&button=false\" /></a>\n"
  },
  {
    "path": "packages/vuetify/_settings.scss",
    "content": "@forward './lib/styles/settings';\n@forward './dist/component-variables';\n@forward './dist/component-variables-labs';\n"
  },
  {
    "path": "packages/vuetify/_styles.scss",
    "content": "@forward './lib/styles/main';\n"
  },
  {
    "path": "packages/vuetify/_tools.scss",
    "content": "@forward './lib/styles/tools';\n"
  },
  {
    "path": "packages/vuetify/babel.config.js",
    "content": "import fs from 'node:fs/promises'\n\nconst vuetifyPackage = JSON.parse(await fs.readFile('./package.json', 'utf8'))\n\nexport default {\n  assumptions: {\n    noDocumentAll: true\n  },\n  ignore: [/\\.d\\.ts$/],\n  presets: [\n    ['@babel/preset-env', {\n      modules: false,\n    }],\n    '@babel/preset-typescript',\n  ],\n  plugins: [\n    ['@vuetify/babel-plugin-jsx', { optimize: false, enableObjectSlots: false }],\n    ['transform-define', {\n      __VUETIFY_VERSION__: vuetifyPackage.version,\n      __REQUIRED_VUE__: vuetifyPackage.peerDependencies.vue,\n    }],\n    ['module-resolver', {\n      root: ['.'],\n      alias: {\n        '@': './src',\n      },\n    }],\n  ],\n  env: {\n    test: {\n      presets: [\n        ['@babel/preset-env', {\n          targets: { node: true },\n          modules: 'commonjs',\n        }],\n      ],\n    },\n    lib: {\n      ignore: ['**/__tests__'],\n      plugins: [\n        ['babel-plugin-add-import-extension', { extension: 'js' }],\n        ['./build/babel-plugin-replace-import-extension', { extMapping: {\n          '.sass': '.css',\n          '.scss': '.css',\n        }}],\n      ],\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/build/babel-plugin-replace-import-extension.js",
    "content": "function transformExtension(filepath, extMapping) {\n  if (!filepath.startsWith('./') && !filepath.startsWith('../')) {\n    // Package import\n    return filepath;\n  }\n\n  const idx = filepath.lastIndexOf('.');\n  if (idx === -1 || filepath.includes('/', idx)) {\n    // No extension\n    const newExt = extMapping[''];\n    if (newExt) {\n      return filepath + newExt;\n    }\n    return filepath;\n  }\n\n  for (const [origExt, newExt] of Object.entries(extMapping).sort(\n    (a, b) => b[0].length - a[0].length\n  )) {\n    if (filepath.endsWith(origExt)) {\n      return filepath.slice(0, -origExt.length) + newExt;\n    }\n  }\n  return filepath;\n}\n\nfunction getOption(state, key) {\n  const opts = state.opts || {};\n  return opts[key];\n}\n\n\nexport default function ({types: t}) {\n  return {\n    visitor: {\n      ImportDeclaration(path, state) {\n        const extMapping = getOption(state, 'extMapping');\n        if (!extMapping) {\n          return;\n        }\n        const source = path.node.source;\n\n        source.value = transformExtension(source.value, extMapping);\n      },\n      // For re-exporting\n      'ExportNamedDeclaration|ExportAllDeclaration'(path, state) {\n        const extMapping = getOption(state, 'extMapping');\n        if (!extMapping) {\n          return;\n        }\n        const source = path.node.source;\n        if (source == null) {\n          return;\n        }\n\n        source.value = transformExtension(source.value, extMapping);\n      },\n    },\n  };\n}\n"
  },
  {
    "path": "packages/vuetify/build/constants.js",
    "content": "import packageJson from '../package.json' with { type: 'json' }\nimport path from 'upath'\nimport { fileURLToPath } from 'node:url'\n\nexport const banner = `/*!\n* Vuetify v${packageJson.version}\n* Forged by John Leider\n* Released under the MIT License.\n*/\\n`\n\nexport const root = path.resolve(fileURLToPath(import.meta.url), '../..')\nexport const srcDir = path.resolve(root, 'src')\nexport const libDir = path.resolve(root, 'lib')\nexport const unpluginLibDistDir = path.resolve(libDir, 'unplugin')\nexport const labsDir = path.resolve(srcDir, 'labs')\n\nexport const externals = Array.from(Object.keys(packageJson.devDependencies))\n"
  },
  {
    "path": "packages/vuetify/build/rollup.config.js",
    "content": "import path from 'upath'\nimport { mkdirp } from 'mkdirp'\nimport { writeFile } from 'node:fs/promises'\nimport { fileURLToPath } from 'node:url'\n\nimport packageJson from '../package.json' with { type: 'json' }\n\nimport alias from '@rollup/plugin-alias'\nimport sass from 'rollup-plugin-sass'\nimport { babel } from '@rollup/plugin-babel'\nimport terser from '@rollup/plugin-terser'\nimport { nodeResolve } from '@rollup/plugin-node-resolve'\n\nimport autoprefixer from 'autoprefixer'\nimport cssnano from 'cssnano'\nimport postcss from 'postcss'\nimport { simple as walk } from 'acorn-walk'\nimport {\n  banner,\n  labsDir,\n  libDir,\n  root,\n  srcDir,\n} from './constants.js'\n\nconst extensions = ['.ts', '.tsx', '.js', '.jsx', '.es6', '.es', '.mjs']\n\n/** @type {import(\"rollup\").RollupOptions[]} */\nconst options = [\n  {\n    input: 'src/entry-bundler.ts',\n    output: [\n      {\n        file: 'dist/vuetify.esm.js',\n        format: 'es',\n        sourcemap: true,\n        banner,\n      },\n      {\n        file: 'dist/vuetify.js',\n        name: 'Vuetify',\n        format: 'umd',\n        globals: { vue: 'Vue' },\n        sourcemap: true,\n        banner,\n      },\n      {\n        file: 'dist/vuetify.cjs',\n        name: 'Vuetify',\n        format: 'umd',\n        globals: { vue: 'Vue' },\n        sourcemap: true,\n        banner,\n      },\n      {\n        file: 'dist/vuetify.min.js',\n        name: 'Vuetify',\n        format: 'umd',\n        globals: { vue: 'Vue' },\n        plugins: [terser({\n          format: { comments: /^!/, ecma: 2015, semicolons: false },\n        })],\n        sourcemap: true,\n        banner,\n      },\n    ],\n    external: ['vue'],\n    plugins: [\n      nodeResolve({ extensions }),\n      babel({\n        extensions,\n        babelHelpers: 'inline',\n      }),\n      sass({\n        options: {\n          charset: false,\n          silenceDeprecations: ['legacy-js-api'],\n        },\n        output (styles, styleNodes) {\n          // Complete CSS bundle\n          mkdirp(path.resolve(root, 'dist')).then(() => {\n            return Promise.all([\n              postcss([autoprefixer]).process(styles, { from: 'src' }),\n              postcss([autoprefixer, cssnano({\n                preset: 'default',\n                postcssZindex: false,\n                reduceIdents: false,\n              })]).process(styles, { from: 'src' }),\n            ])\n          }).then(result => {\n            writeFile(path.resolve(root, 'dist/vuetify.css'), banner + result[0].css, 'utf8')\n            writeFile(path.resolve(root, 'dist/vuetify.min.css'), banner + result[1].css, 'utf8')\n          })\n\n          // Individual CSS files\n          for (const {id, content} of styleNodes) {\n            const relativePath = path.relative(srcDir, id)\n            const out = path.parse(path.join(libDir, relativePath))\n            mkdirp(out.dir).then(() => {\n              writeFile(path.join(out.dir, out.name + '.css'), content, 'utf8')\n            })\n          }\n        },\n      }),\n      alias({\n        entries: [\n          { find: /^@\\/(.*)/, replacement: fileURLToPath(new URL('../src/$1', import.meta.url)) },\n        ],\n      }),\n      {\n        async buildEnd () {\n          const components = Object.create(null)\n          const directives = []\n          const variables = []\n\n          { // Components\n            const { importedIds } = this.getModuleInfo(\n              (await this.resolve('src/components/index.ts')).id\n            )\n            await Promise.all(importedIds.map(async id => {\n              const importFrom = path.relative(srcDir, id).replace(/\\/index\\.ts$/, '')\n\n              if (await this.resolve(path.join(id, '../_variables.scss')) != null) {\n                variables.push(id)\n              }\n\n              const { ast } = this.getModuleInfo(id)\n              walk(ast, {\n                ExportNamedDeclaration (node) {\n                  node.specifiers.forEach(node => {\n                    components[node.exported.name] = importFrom\n                  })\n                  node.declaration?.declarations.forEach(node => {\n                    components[node.id.name] = importFrom\n                  })\n                },\n              })\n            }))\n          }\n\n          { // Directives\n            const { ast, importedIds } = this.getModuleInfo(\n              (await this.resolve('src/directives/index.ts')).id\n            )\n            await Promise.all(importedIds.map(async id => {\n              if (await this.resolve(path.join(id, '../_variables.scss')) != null) {\n                variables.push(id)\n              }\n            }))\n            walk(ast, {\n              ExportNamedDeclaration (node) {\n                node.specifiers.forEach(node => {\n                  directives.push(node.exported.name)\n                })\n              },\n            })\n          }\n\n          this.emitFile({\n            type: 'asset',\n            fileName: 'json/importMap.json',\n            source: JSON.stringify({\n              components: Object.fromEntries(Object.entries(components).map(entry => [entry[0], {\n                from: entry[1],\n                styles: [], // TODO\n              }])),\n              directives,\n            }, null, 2),\n          })\n\n          this.emitFile({\n            type: 'asset',\n            fileName: '_component-variables.sass',\n            source: variables.map(id => {\n              return `@forward '` + path.join(\n                '../lib',\n                path.relative(srcDir, id),\n                '../_variables.scss'\n              ) + `'`\n            }).sort().join('\\n'),\n          })\n        },\n      },\n    ],\n  },\n  {\n    input: 'src/labs/entry-bundler.ts',\n    output: [\n      {\n        file: 'dist/vuetify-labs.js',\n        name: 'Vuetify',\n        format: 'umd',\n        globals: { vue: 'Vue' },\n        banner,\n      },\n      {\n        file: 'dist/vuetify-labs.cjs',\n        name: 'Vuetify',\n        format: 'umd',\n        globals: { vue: 'Vue' },\n        banner,\n      },\n      {\n        file: 'dist/vuetify-labs.esm.js',\n        format: 'es',\n        sourcemap: true,\n        banner,\n      },\n    ],\n    external: ['vue'],\n    plugins: [\n      nodeResolve({ extensions }),\n      babel({\n        extensions,\n        babelHelpers: 'inline',\n      }),\n      sass({\n        options: {\n          charset: false,\n          silenceDeprecations: ['legacy-js-api'],\n        },\n        output (styles, styleNodes) {\n          mkdirp(path.resolve(root, 'dist')).then(() => {\n            return Promise.all([\n              postcss([autoprefixer]).process(styles, { from: 'src' }),\n              postcss([autoprefixer, cssnano({\n                preset: 'default',\n                postcssZindex: false,\n                reduceIdents: false,\n              })]).process(styles, { from: 'src' }),\n            ])\n          }).then(result => {\n            writeFile(path.resolve(root, 'dist/vuetify-labs.css'), banner + result[0].css, 'utf8')\n            writeFile(path.resolve(root, 'dist/vuetify-labs.min.css'), banner + result[1].css, 'utf8')\n          })\n\n          // Individual CSS files\n          styleNodes = styleNodes.filter(node => path.normalize(node.id).startsWith(labsDir));\n          for (const { id, content } of styleNodes) {\n            const relativePath = path.relative(srcDir, id)\n            const out = path.parse(path.join(libDir, relativePath))\n            mkdirp(out.dir).then(() => {\n              writeFile(path.join(out.dir, out.name + '.css'), content, 'utf8')\n            })\n          }\n        },\n      }),\n      alias({\n        entries: [\n          { find: /^@\\/(.*)/, replacement: fileURLToPath(new URL('../src/$1', import.meta.url)) },\n        ],\n      }),\n      {\n        async buildEnd () {\n          const components = Object.create(null)\n          const variables = []\n\n          { // Components\n            const { importedIds } = this.getModuleInfo(\n              (await this.resolve('src/labs/components.ts')).id\n            )\n            await Promise.all(importedIds.map(async id => {\n              const importFrom = path.relative(srcDir, id).replace(/\\/index\\.ts$/, '')\n\n              if (await this.resolve(path.join(id, '../_variables.scss')) != null) {\n                variables.push(id)\n              }\n\n              const { ast } = this.getModuleInfo(id)\n              walk(ast, {\n                ExportNamedDeclaration (node) {\n                  node.specifiers.forEach(node => {\n                    components[node.exported.name] = importFrom\n                  })\n                  node.declaration?.declarations.forEach(node => {\n                    components[node.id.name] = importFrom\n                  })\n                },\n              })\n            }))\n          }\n\n          this.emitFile({\n            type: 'asset',\n            fileName: 'json/importMap-labs.json',\n            source: JSON.stringify({\n              components: Object.fromEntries(Object.entries(components).map(entry => [entry[0], {\n                from: entry[1],\n                styles: [], // TODO\n              }])),\n            }, null, 2),\n          })\n\n          this.emitFile({\n            type: 'asset',\n            fileName: '_component-variables-labs.sass',\n            source: variables.map(id => {\n              return `@forward '` + path.join(\n                '../lib',\n                path.relative(srcDir, id),\n                '../_variables.scss'\n              ) + `'`\n            }).sort().join('\\n'),\n          })\n        }\n      }\n    ],\n  },\n  {\n    input: 'src/entry-styles.ts',\n    output: [\n      { format: 'es', dir: 'dist' },\n    ],\n    onwarn (warning, defaultHandler) {\n      if (warning.code === 'EMPTY_BUNDLE') return\n      defaultHandler(warning)\n    },\n    plugins: [\n      sass({\n        options: {\n          charset: false,\n          silenceDeprecations: ['legacy-js-api'],\n        },\n        output (styles, styleNodes) {\n          // Individual CSS files\n          for (const { id, content } of styleNodes) {\n            const relativePath = path.relative(srcDir, id)\n            const out = path.parse(path.join(libDir, relativePath))\n            mkdirp(out.dir).then(() => {\n              writeFile(path.join(out.dir, out.name + '.css'), content, 'utf8')\n            })\n          }\n        },\n      }),\n      {\n        generateBundle (options, bundle) {\n          delete bundle['entry-styles.js']\n        }\n      }\n    ],\n  },\n]\n\nexport default options\n"
  },
  {
    "path": "packages/vuetify/build/rollup.types.config.js",
    "content": "import fs from 'node:fs/promises'\nimport { fileURLToPath } from 'node:url'\n\nimport dts from 'rollup-plugin-dts'\nimport fg from 'fast-glob'\nimport mm from 'micromatch'\nimport MagicString from 'magic-string'\nimport { codeTransform } from './types-code-transform.js'\n\nimport importMap from '../dist/json/importMap.json' with { type: 'json' }\nimport importMapLabs from '../dist/json/importMap-labs.json' with { type: 'json' }\n\n/**\n * @param input {string}\n * @param output {string}\n * @param renderChunk {import(\"rollup\").RenderChunkHook | undefined}\n * @param filter {(files: string[]) => string[] | undefined}\n * @returns {import(\"rollup\").RollupOptions[]}\n */\nfunction createTypesConfig (input, output, renderChunk, filter) {\n  input = 'lib/' + input\n  let files = fg.sync(input)\n\n  if (filter) files = filter(files)\n\n  return files.map(file => {\n    const outputFile = output.replace('*', mm.capture(input, file)[0])\n    /** @type {import(\"rollup\").RollupOptions} */\n    const options = {\n      input: file,\n      output: [{ file: outputFile, format: 'es', sourcemap: false }],\n      plugins: [\n        dts(),\n        {\n          async renderChunk (code) {\n            code = new MagicString(code)\n\n            if (renderChunk) await renderChunk(code)\n\n            codeTransform(code)\n\n            const map = code.generateMap({\n              // source: 'source.js',\n              // file: 'converted.js.map',\n              includeContent: false,\n            })\n            return {\n              code: code.toString(),\n              map: null,\n            }\n          }\n        },\n      ],\n    }\n    return options\n  })\n}\n\n/**\n * @param useImport {boolean|undefined}\n * @returns {Promise<string>}\n */\nasync function getShims (useImport) {\n  let components\n  if (useImport) {\n    components = Object.keys(importMap.components).map(name => (\n        `    ${name}: typeof import('vuetify/components')['${name}']`\n      )).join('\\n')\n      + '\\n'\n      + Object.keys(importMapLabs.components).map(name => (\n        `    ${name}: typeof import('vuetify/labs/components')['${name}']`\n      )).join('\\n')\n  } else {\n    // All the components are already in scope, let's just assume rollup hasn't renamed any\n    components = [...Object.keys(importMap.components), ...Object.keys(importMapLabs.components)]\n      .map(name => `    ${name}: ${name}`).join('\\n')\n  }\n\n  const directives = importMap.directives.map(name => (\n    `    v${name}: typeof import('vuetify/directives')['${name}']`\n  )).join('\\n')\n\n  return (await fs.readFile(fileURLToPath(new URL('../src/shims.d.ts', import.meta.url)), { encoding: 'utf8' }))\n    .replaceAll(/^\\s*\\/\\/ @skip-build\\s[\\s\\S]*?\\s$/gm, '')\n    .replace(/^\\s*\\/\\/ @generate-components$/gm, components)\n    .replace(/^\\s*\\/\\/ @generate-directives$/gm, directives)\n}\n\n/** @type {import(\"rollup\").RollupOptions[]} */\nconst options = [\n  createTypesConfig('entry-bundler.d.ts', 'dist/vuetify.d.ts', async code => {\n    code.replaceAll(/type index_d\\$1_V(\\w+) = V(\\w+);/gm, 'declare const index_d$$1_V$1: typeof V$2;')\n    code.append('\\n\\n')\n    code.append((await getShims()).replace(', VNodeChild } from \\'vue\\'', ' } from \\'vue\\''))\n  }),\n  createTypesConfig('labs/entry-bundler.d.ts', 'dist/vuetify-labs.d.ts', async code => {\n    code.replaceAll(/type allComponents_d_V(\\w+) = V(\\w+);/gm, 'declare const allComponents_d_V$1: typeof V$2;')\n    code.append('\\n\\n')\n    code.append((await getShims()).replace(', VNodeChild } from \\'vue\\'', ' } from \\'vue\\''))\n  }),\n  createTypesConfig('framework.d.ts', 'lib/framework.d.ts', async code => {\n    code.append('\\n\\n')\n    code.append(await getShims(true))\n  }),\n].flat()\n\nexport default options\n"
  },
  {
    "path": "packages/vuetify/build/run-tests.js",
    "content": "import { spawn } from 'child_process'\n\nconst args = process.argv.slice(2)\n\nlet child\n\nif (process.platform === 'win32') {\n  // pnpm test -i\n  child = spawn('pnpm.cmd', ['test:win32', ...args], { stdio: 'inherit' })\n} else {\n  // pnpm test\n  child = spawn('pnpm', ['test:unix', ...args], { stdio: 'inherit' })\n}\n\nchild.on('exit', process.exit)\n"
  },
  {
    "path": "packages/vuetify/build/transform-types.js",
    "content": "import fg from 'fast-glob'\nimport fs from 'node:fs/promises'\nimport { codeTransform } from './types-code-transform.js'\nimport path from 'upath'\n\nconst files = fg.sync('lib/**/*.d.ts')\n\nconst importRegexp = /(?<a1>(?:import|export)(?:[^;])*?from ['\"])(?<a2>(?:\\.\\.?|@)(?:\\/[^;'\"]*)?)(?<a3>['\"];)|(?<b1>import\\(['\"])(?<b2>(?:\\.\\.?|@)(?:\\/[^;'\"]*)?)(?<b3>['\"]\\))/gm\n\nfor (const name of files) {\n  const code = await fs.readFile(name, 'utf-8')\n\n  let newCode = codeTransform(code)\n\n  for (const match of code.matchAll(importRegexp)) {\n    const pre = match.groups.a1 ?? match.groups.b1\n    let matchPath = match.groups.a2 ?? match.groups.b2\n    const post = match.groups.a3 ?? match.groups.b3\n\n    let target = matchPath\n    if (target.startsWith('@/')) {\n      target = path.relative(path.dirname(name), target.replace(/^@\\//, 'lib/'))\n      if (!target.startsWith('.')) {\n        target = './' + target\n      }\n    }\n\n    if (!/\\.[jt]s$/.test(target)) {\n      try {\n        const dir = await fs.stat(path.join(path.dirname(name), target))\n        target = target + '/index.js'\n      } catch (err) {\n        if (err.code !== 'ENOENT') throw err\n        target = target + '.js'\n      }\n    }\n    if (target !== matchPath) {\n      newCode = newCode.replace(match[0], pre + target + post)\n    }\n  }\n\n  if (newCode === code) continue\n  await fs.writeFile(name, newCode, 'utf-8')\n}\n"
  },
  {
    "path": "packages/vuetify/build/types-code-transform.js",
    "content": "/**\n * @param code {string}\n * @returns {string}\n */\nexport function codeTransform (code) {\n  return code\n    // ignore missing vue-router\n    .replaceAll(/import([^;])*?from 'vue-router'/gm, '// @ts-ignore\\n$&')\n    // tsc adds extra export statements to namespaces that break module augmentation\n    .replaceAll(/^\\s*export \\{\\s*\\};?$/gm, '')\n    // ignore style imports\n    .replaceAll(/import '[^']*\\.s[ac]ss';$/gm, '')\n}\n"
  },
  {
    "path": "packages/vuetify/dev/App.vue",
    "content": "<template>\n  <Playground />\n</template>\n\n<script setup>\n  import Playground from './Playground.vue'\n</script>\n"
  },
  {
    "path": "packages/vuetify/dev/Playground.template.vue",
    "content": "<template>\n  <v-app>\n    <v-container>\n      <!-- -->\n    </v-container>\n  </v-app>\n</template>\n\n<script>\n  export default {\n    name: 'Playground',\n    setup () {\n      return {\n        //\n      }\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/vuetify/dev/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <title>Vuetify Dev Playground</title>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <link href='https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons' rel=\"stylesheet\" type=\"text/css\">\n    <link rel=\"stylesheet\" href=\"https://use.fontawesome.com/releases/v5.0.13/css/all.css\">\n    <link rel=\"icon\" type=\"image/png\" href=\"./favicon.png\" sizes=\"16x16\">\n  </head>\n  <body>\n    <div id=\"app\"></div>\n    <script type=\"module\" src=\"/index.js\"></script>\n  </body>\n</html>\n"
  },
  {
    "path": "packages/vuetify/dev/index.js",
    "content": "import vuetify from './vuetify'\nimport App from './App.vue'\n\nimport { routes } from './router'\nimport viteSSR from 'vite-ssr/vue'\n\nimport { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'\nimport { library } from '@fortawesome/fontawesome-svg-core'\nimport { fas } from '@fortawesome/free-solid-svg-icons'\n\nlibrary.add(fas)\n\nexport default viteSSR(App, { routes }, ({ app }) => {\n  app.use(vuetify)\n  app.component('FontAwesomeIcon', FontAwesomeIcon)\n})\n"
  },
  {
    "path": "packages/vuetify/dev/router.js",
    "content": "import { h } from 'vue'\n\nconst home = {\n  setup: () => () => h('div', 'hello'),\n}\nconst page1 = {\n  setup: () => () => h('div', 'page1'),\n}\nconst page2 = {\n  setup: () => () => h('div', 'page2'),\n}\nconst nested1 = {\n  setup: () => () => h('div', 'nested1'),\n}\nconst nested2 = {\n  setup: () => () => h('div', 'nested2'),\n}\n\nexport const routes = [\n  {\n    path: '/',\n    name: 'home',\n    component: home,\n  },\n  {\n    path: '/page1',\n    name: 'page1',\n    component: page1,\n  },\n  {\n    path: '/page2',\n    name: 'page2',\n    component: page2,\n  },\n  {\n    path: '/nested/page1',\n    name: 'Nested 1',\n    component: nested1,\n  },\n  {\n    path: '/nested/page2',\n    name: 'Nested 2',\n    component: nested2,\n  },\n  { path: '/:pathMatch(.*)*', redirect: '/' },\n]\n"
  },
  {
    "path": "packages/vuetify/dev/vuetify/date.js",
    "content": "import { StringDateAdapter } from '@/composables/date/adapters/string'\n// import DateFnsAdapter from '@date-io/date-fns'\n// import { enAU, enUS, ja, sv } from 'date-fns/locale'\n\n// import DayJsAdapter from '@date-io/dayjs'\n\n// import LuxonAdapter from '@date-io/luxon'\n\n// import MomentAdapter from '@date-io/moment'\n\nexport default {\n  // adapter: DateFnsAdapter,\n  // adapter: StringDateAdapter,\n  formats: {\n    // dayOfMonth: date => date.getDate(),\n  },\n  locale: {\n    en: 'en-US',\n    // en: 'en-AU',\n    // en: enAU,\n    // en: enUS,\n    // ja,\n    // sv,\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/dev/vuetify/defaults.js",
    "content": "export default {\n  //\n}\n"
  },
  {
    "path": "packages/vuetify/dev/vuetify/icons.js",
    "content": "import { aliases } from '@/iconsets/mdi-svg'\nimport { mdi } from '@/iconsets/mdi'\nimport { fa } from '@/iconsets/fa-svg'\n\nexport default {\n  defaultSet: 'mdi',\n  aliases,\n  sets: {\n    mdi,\n    fa,\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/dev/vuetify/locale.js",
    "content": "import { ar, en, ja, sv } from '@/locale'\n\nexport default {\n  messages: {\n    en,\n    ar,\n    sv,\n    ja,\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/dev/vuetify.js",
    "content": "import '@mdi/font/css/materialdesignicons.css'\nimport '@/styles/main.sass'\n\nimport { createVuetify } from '@/framework'\nimport * as directives from '@/directives'\n\nimport date from './vuetify/date'\nimport defaults from './vuetify/defaults'\nimport icons from './vuetify/icons'\nimport locale from './vuetify/locale'\n\nexport default createVuetify({\n  directives,\n  ssr: !!process.env.VITE_SSR,\n  date,\n  defaults,\n  icons,\n  locale,\n  theme: { defaultTheme: 'light' },\n})\n"
  },
  {
    "path": "packages/vuetify/package.json",
    "content": "{\n  \"name\": \"vuetify\",\n  \"description\": \"Vue Material Component Framework\",\n  \"version\": \"4.0.3\",\n  \"author\": {\n    \"name\": \"John Leider\",\n    \"email\": \"john@vuetifyjs.com\"\n  },\n  \"license\": \"MIT\",\n  \"homepage\": \"https://vuetifyjs.com\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/vuetifyjs/vuetify.git\",\n    \"directory\": \"packages/vuetify\"\n  },\n  \"keywords\": [\n    \"vuetify\",\n    \"ui framework\",\n    \"component framework\",\n    \"ui library\",\n    \"component library\",\n    \"material components\",\n    \"vue framework\"\n  ],\n  \"bugs\": {\n    \"url\": \"https://issues.vuetifyjs.com\"\n  },\n  \"funding\": {\n    \"type\": \"github\",\n    \"url\": \"https://github.com/sponsors/johnleider\"\n  },\n  \"type\": \"module\",\n  \"main\": \"lib/framework.js\",\n  \"module\": \"lib/framework.js\",\n  \"jsdelivr\": \"dist/vuetify.js\",\n  \"unpkg\": \"dist/vuetify.js\",\n  \"types\": \"lib/framework.d.ts\",\n  \"sass\": \"lib/styles/main.sass\",\n  \"styles\": \"lib/styles/main.css\",\n  \"sideEffects\": [\n    \"*.sass\",\n    \"*.scss\",\n    \"*.css\",\n    \"*.vue\"\n  ],\n  \"files\": [\n    \"dist/\",\n    \"lib/\",\n    \"_settings.scss\",\n    \"_styles.scss\",\n    \"_tools.scss\",\n    \"CHANGELOG.md\"\n  ],\n  \"exports\": {\n    \".\": {\n      \"sass\": \"./lib/styles/main.sass\",\n      \"style\": \"./lib/styles/main.css\",\n      \"types\": \"./lib/framework.d.ts\",\n      \"default\": \"./lib/framework.js\"\n    },\n    \"./styles\": {\n      \"sass\": \"./lib/styles/main.sass\",\n      \"default\": \"./lib/styles/main.css\"\n    },\n    \"./styles/core\": {\n      \"sass\": \"./lib/styles/core.scss\",\n      \"default\": \"./lib/styles/core.css\"\n    },\n    \"./styles/colors\": {\n      \"sass\": \"./lib/styles/colors.scss\",\n      \"default\": \"./lib/styles/colors.css\"\n    },\n    \"./styles/utilities\": {\n      \"sass\": \"./lib/styles/utilities.scss\",\n      \"default\": \"./lib/styles/utilities.css\"\n    },\n    \"./styles/*\": \"./lib/styles/*\",\n    \"./framework\": \"./lib/framework.js\",\n    \"./blueprints\": \"./lib/blueprints/index.js\",\n    \"./blueprints/*\": \"./lib/blueprints/*.js\",\n    \"./components\": \"./lib/components/index.js\",\n    \"./components/*\": \"./lib/components/*/index.js\",\n    \"./directives\": \"./lib/directives/index.js\",\n    \"./directives/*\": \"./lib/directives/*/index.js\",\n    \"./locale\": \"./lib/locale/index.js\",\n    \"./locale/adapters/*\": \"./lib/locale/adapters/*.js\",\n    \"./iconsets/*\": \"./lib/iconsets/*.js\",\n    \"./labs/components\": \"./lib/labs/components.js\",\n    \"./labs/*\": \"./lib/labs/*/index.js\",\n    \"./util/colors\": \"./lib/util/colors.js\",\n    \"./date/adapters/*\": \"./lib/composables/date/adapters/*.js\",\n    \"./util/transitions\": \"./lib/components/transitions/createTransition.js\",\n    \"./dist/vuetify.js\": {\n      \"types\": \"./dist/vuetify.d.ts\",\n      \"import\": \"./dist/vuetify.esm.js\",\n      \"default\": \"./dist/vuetify.cjs\"\n    },\n    \"./dist/vuetify-labs.js\": {\n      \"types\": \"./dist/vuetify-labs.d.ts\",\n      \"import\": \"./dist/vuetify-labs.esm.js\",\n      \"default\": \"./dist/vuetify-labs.cjs\"\n    },\n    \"./*.mjs\": \"./*.js\",\n    \"./*\": \"./*\"\n  },\n  \"typesVersions\": {\n    \"*\": {\n      \"*\": [\n        \"*\",\n        \"dist/*\",\n        \"lib/*\",\n        \"lib/*.d.ts\",\n        \"lib/*/index.d.ts\"\n      ]\n    }\n  },\n  \"scripts\": {\n    \"watch\": \"pnpm build:lib --watch\",\n    \"dev\": \"NODE_ENV=development vite\",\n    \"dev:ssr\": \"NODE_ENV=development VITE_SSR=true vite-ssr\",\n    \"dev:prod\": \"vite build -w\",\n    \"dev:typecheck\": \"vue-tsc --noEmit --skipLibCheck --project ./tsconfig.dev.json\",\n    \"build\": \"rimraf lib dist && pnpm build:lib && concurrently \\\"pnpm build:dist\\\" \\\"pnpm build:types:lib\\\" -n \\\"dist,types\\\" --kill-others-on-fail -gr && pnpm build:types:bundle\",\n    \"build:dist\": \"rollup --config build/rollup.config.js\",\n    \"build:lib\": \"NODE_ENV=lib babel src --out-dir lib --source-maps --extensions \\\".ts\\\",\\\".tsx\\\",\\\".snap\\\" --copy-files --no-copy-ignored --out-file-extension .js\",\n    \"build:types\": \"pnpm build:types:lib && pnpm build:types:bundle\",\n    \"build:types:lib\": \"tsgo --pretty --emitDeclarationOnly -p tsconfig.dist.json && node build/transform-types.js\",\n    \"build:types:bundle\": \"rollup --config build/rollup.types.config.js\",\n    \"tsc\": \"tsc\",\n    \"tdd\": \"vizzly tdd start\",\n    \"tdd:stop\": \"vizzly tdd stop\",\n    \"test\": \"vitest\",\n    \"test:unit\": \"vitest --project unit\",\n    \"test:browser\": \"vitest --project browser\",\n    \"test:open\": \"TEST_BAIL=1 vitest --project browser -w\",\n    \"test:coverage\": \"pnpm test --coverage\",\n    \"test:screen\": \"node ../../scripts/tdd-run.js \",\n    \"test:all\": \"concurrently -gr 'vitest --project unit' 'vitest --project browser --shard=1/5' 'vitest --project browser --shard=2/5' 'vitest --project browser --shard=3/5' 'vitest --project browser --shard=4/5' 'vitest --project browser --shard=5/5'\",\n    \"lint\": \"concurrently -n \\\"tsc,eslint\\\" --kill-others-on-fail \\\"tsgo -p tsconfig.checks.json --noEmit --pretty\\\" \\\"eslint src -f codeframe --max-warnings 0\\\"\",\n    \"lint:fix\": \"concurrently -n \\\"tsc,eslint\\\" \\\"tsgo -p tsconfig.checks.json --noEmit --pretty\\\" \\\"eslint --fix src\\\"\"\n  },\n  \"devDependencies\": {\n    \"@date-io/core\": \"3.2.0\",\n    \"@date-io/date-fns\": \"3.2.1\",\n    \"@date-io/dayjs\": \"^3.2.0\",\n    \"@date-io/luxon\": \"^3.2.0\",\n    \"@date-io/moment\": \"^3.2.0\",\n    \"@fortawesome/fontawesome-svg-core\": \"^6.7.2\",\n    \"@fortawesome/free-solid-svg-icons\": \"^6.7.2\",\n    \"@fortawesome/vue-fontawesome\": \"^3.0.8\",\n    \"@intlify/devtools-types\": \"^11.1.12\",\n    \"@rollup/plugin-alias\": \"^5.1.1\",\n    \"@rollup/plugin-babel\": \"^6.1.0\",\n    \"@rollup/plugin-node-resolve\": \"^16.0.3\",\n    \"@rollup/plugin-typescript\": \"^12.3.0\",\n    \"@testing-library/dom\": \"npm:@vuetify/testing-library-dom@1.0.3\",\n    \"@testing-library/user-event\": \"^14.6.1\",\n    \"@testing-library/vue\": \"^8.1.0\",\n    \"@types/resize-observer-browser\": \"^0.1.11\",\n    \"@vitejs/plugin-vue-jsx\": \"^5.1.2\",\n    \"@vitest/browser-playwright\": \"^4.0.13\",\n    \"@vitest/coverage-istanbul\": \"^4.0.13\",\n    \"@vitest/ui\": \"^4.0.13\",\n    \"@vizzly-testing/cli\": \"^0.22.2\",\n    \"@vizzly-testing/vitest\": \"^0.1.1\",\n    \"@vue/reactivity\": \"^3.5.25\",\n    \"@vue/shared\": \"^3.5.25\",\n    \"@vue/test-utils\": \"^2.4.6\",\n    \"@vuetify/babel-plugin-jsx\": \"^1.7.0\",\n    \"acorn-walk\": \"^8.3.4\",\n    \"autoprefixer\": \"^10.4.22\",\n    \"babel-plugin-add-import-extension\": \"1.5.1\",\n    \"babel-plugin-module-resolver\": \"^5.0.2\",\n    \"babel-plugin-transform-define\": \"^2.1.4\",\n    \"babel-polyfill\": \"^6.26.0\",\n    \"cssnano\": \"^7.1.2\",\n    \"csstype\": \"^3.2.3\",\n    \"cy-mobile-commands\": \"^0.3.0\",\n    \"date-fns\": \"^3.6.0\",\n    \"dayjs\": \"^1.11.19\",\n    \"dotenv\": \"^16.5.0\",\n    \"eslint-plugin-vitest\": \"0.5.4\",\n    \"expect\": \"^30.2.0\",\n    \"fast-glob\": \"^3.3.3\",\n    \"identity-obj-proxy\": \"^3.0.0\",\n    \"jsdom\": \"^27.2.0\",\n    \"luxon\": \"^3.7.2\",\n    \"micromatch\": \"^4.0.8\",\n    \"moment\": \"^2.30.1\",\n    \"playwright\": \"^1.57.0\",\n    \"postcss\": \"^8.5.3\",\n    \"roboto-fontface\": \"^0.10.0\",\n    \"timezone-mock\": \"^1.3.6\",\n    \"ts-node\": \"^10.9.2\",\n    \"unplugin-auto-import\": \"19.3.0\",\n    \"unplugin-vue-components\": \"^0.28.0\",\n    \"upath\": \"^2.0.1\",\n    \"vite-live-preview\": \"^0.4.0\",\n    \"vite-ssr\": \"^0.17.2\",\n    \"vitest\": \"^4.0.13\",\n    \"vue\": \"^3.5.25\",\n    \"vue-i18n\": \"^11.1.12\",\n    \"vue-router\": \"^4.6.3\"\n  },\n  \"peerDependencies\": {\n    \"typescript\": \">=4.7\",\n    \"vite-plugin-vuetify\": \">=2.1.0\",\n    \"vue\": \"^3.5.0\",\n    \"webpack-plugin-vuetify\": \">=3.1.0\"\n  },\n  \"peerDependenciesMeta\": {\n    \"typescript\": {\n      \"optional\": true\n    },\n    \"webpack-plugin-vuetify\": {\n      \"optional\": true\n    },\n    \"vite-plugin-vuetify\": {\n      \"optional\": true\n    }\n  },\n  \"publishConfig\": {\n    \"access\": \"public\"\n  },\n  \"vetur\": {\n    \"tags\": \"dist/json/tags.json\",\n    \"attributes\": \"dist/json/attributes.json\"\n  },\n  \"web-types\": \"dist/json/web-types.json\"\n}\n"
  },
  {
    "path": "packages/vuetify/playgrounds/Playground.datatable.vue",
    "content": "<template>\n  <v-app>\n    <div>\n      <v-text-field v-model=\"search\" variant=\"outlined\" label=\"Search\" />\n    </div>\n\n    <h1>header rowspan/colspan</h1>\n    <v-data-table\n      :headers=\"complex\"\n      :items=\"items\"\n    >\n      <template #header.header>\n        foo\n      </template>\n    </v-data-table>\n\n    <!-- <v-data-table\n      show-select\n      :headers=\"simple\"\n      :items=\"items\"\n      :search=\"search\"\n      multi-sort\n      show-expand\n    >\n      <template #expanded-row=\"{ columns }\">\n        <tr>\n          <td :colspan=\"columns.length\">\n            hello\n          </td>\n        </tr>\n      </template>\n    </v-data-table> -->\n\n    <!-- <div>\n      <v-autocomplete\n        :items=\"people\"\n        filled\n        chips\n        closable-chips\n        color=\"blue-grey-lighten-2\"\n        label=\"Select\"\n        item-title=\"name\"\n        item-value=\"name\"\n        multiple\n        :filter-keys=\"['name']\"\n      />\n    </div> -->\n\n    <!--\n    <h1>expanded</h1>\n    <v-data-table\n      :headers=\"simple\"\n      :items=\"items\"\n      expand-on-click\n    >\n      <template v-slot:expanded-row=\"{ columns }\">\n        <tr>\n          <td :colspan=\"columns.length\">\n            This is an expanded row\n          </td>\n        </tr>\n      </template>\n    </v-data-table> -->\n\n    <!-- <h1>group</h1>\n    <v-data-table\n      show-select\n      :headers=\"simple\"\n      :items=\"groupItems\"\n      :group-by=\"[{ key: 'two', order: 'asc' }, { key: 'three', order: 'asc' }]\"\n      :items-per-page=\"-1\"\n    ></v-data-table> -->\n\n    <!-- <h1>server</h1>\n    <v-data-table-server\n      show-select\n      :headers=\"simple\"\n      :items=\"remoteItems\"\n      :items-length=\"1000\"\n      :loading=\"loading\"\n      @update:options=\"getItems\"\n    ></v-data-table-server> -->\n\n    <!-- <h1>virtual</h1>\n    <v-data-table-virtual\n      :headers=\"simple\"\n      :items=\"serverItems\"\n      :search=\"search\"\n      fixed-header\n      height=\"500px\"\n    >\n      <template #item.four>\n        <v-btn>hello</v-btn>\n      </template>\n    </v-data-table-virtual> -->\n\n    <!-- <h1>simple</h1>\n    <v-table>\n      <thead>\n        <tr>\n          <th>One</th>\n          <th>Two</th>\n          <th>Three</th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr>\n          <td>foo</td>\n          <td>bar</td>\n          <td>fizz</td>\n        </tr>\n      </tbody>\n    </v-table> -->\n\n  </v-app>\n</template>\n\n<script lang=\"ts\">\n  import { defineComponent } from 'vue'\n\n  const serverItems = Array(1000).fill(0).map((_, i) => ({ id: i, name: `Name ${i}`, one: i, two: Math.random() > 0.5 ? 'foo' : 'bar', three: Math.random() > 0.5 ? 'hello' : 'world', four: i }))\n\n  const items = Array(20).fill(0).map((_, i) => ({ id: i, name: `Name ${i}`, one: i, two: Math.random() > 0.5 ? 'foo' : 'bar', three: Math.random() > 0.5 ? 'hello' : 'world', four: i }))\n\n  const groupItems = [\n    { id: 1, name: 'Name 1', two: 'foo', three: 'hello' },\n    { id: 2, name: 'Name 2', two: 'foo', three: 'world' },\n    { id: 3, name: 'Name 3', two: 'foo', three: 'hello' },\n    { id: 4, name: 'Name 4', two: 'bar', three: 'world' },\n    { id: 5, name: 'Name 5', two: 'bar', three: 'world' },\n    { id: 6, name: 'Name 6', two: 'bar', three: 'hello' },\n  ]\n\n  const srcs = {\n    1: 'https://cdn.vuetifyjs.com/images/lists/1.jpg',\n    2: 'https://cdn.vuetifyjs.com/images/lists/2.jpg',\n    3: 'https://cdn.vuetifyjs.com/images/lists/3.jpg',\n    4: 'https://cdn.vuetifyjs.com/images/lists/4.jpg',\n    5: 'https://cdn.vuetifyjs.com/images/lists/5.jpg',\n  }\n\n  export default defineComponent({\n    data: () => ({\n      people: [\n        { name: 'Sandra Adams', group: 'Group 1', avatar: srcs[1] },\n        { name: 'Ali Connors', group: 'Group 1', avatar: srcs[2] },\n        { name: 'Trevor Hansen', group: 'Group 1', avatar: srcs[3] },\n        { name: 'Tucker Smith', group: 'Group 1', avatar: srcs[2] },\n        { name: 'Britta Holt', group: 'Group 2', avatar: srcs[4] },\n        { name: 'Jane Smith ', group: 'Group 2', avatar: srcs[5] },\n        { name: 'John Smith', group: 'Group 2', avatar: srcs[1] },\n        { name: 'Sandra Williams', group: 'Group 2', avatar: srcs[3] },\n      ],\n      groupItems,\n      serverItems,\n      simple: [\n        {\n          title: 'Name',\n          id: 'name',\n        },\n        {\n          title: 'Two',\n          id: 'two',\n        },\n        {\n          title: 'Three',\n          id: 'three',\n        },\n        {\n          title: 'Four',\n          id: 'four',\n          align: 'end',\n        },\n      ],\n      test: [\n        [\n          {\n            title: 'Group 1',\n            colspan: 1,\n            width: 200,\n            fixed: true,\n          },\n          {\n            title: 'Group 2',\n            colspan: 1,\n            fixed: true,\n          },\n          {\n            title: 'Group 3',\n            colspan: 2,\n          },\n        ],\n        [\n          {\n            title: 'A',\n            id: 'one',\n            fixed: true,\n            width: 200,\n          },\n          {\n            title: 'B',\n            id: 'two',\n            fixed: true,\n            width: 200,\n          },\n          {\n            title: 'C',\n            id: 'three',\n            width: 200,\n          },\n          {\n            title: 'D',\n            id: 'four',\n            width: 200,\n          },\n        ],\n      ],\n      complex: [\n        [\n          {\n            id: 'data-table-select',\n            rowspan: 3,\n            fixed: true,\n            width: 48,\n          },\n          {\n            title: 'Name',\n            id: 'name',\n            rowspan: 3,\n            fixed: true,\n            width: 200,\n          },\n          {\n            title: 'Header',\n            colspan: 4,\n            id: 'header',\n          },\n        ],\n        [\n          {\n            title: 'Section',\n            colspan: 2,\n          },\n          {\n            title: 'Section',\n            colspan: 2,\n          },\n        ],\n        [\n          {\n            title: 'One',\n            id: 'one',\n            width: 200,\n            fixed: true,\n          },\n          {\n            title: 'Two',\n            id: 'two',\n            width: 200,\n          },\n          {\n            title: 'Three',\n            id: 'three',\n          },\n          {\n            title: 'Four',\n            id: 'four',\n          },\n        ],\n      ],\n      search: '',\n      // headers: [\n      //   {\n      //     id: 'end',\n      //     name: 'Two rows',\n      //     maxWidth: '2fr',\n      //   },\n      //   {\n      //     id: 'one',\n      //     name: 'One',\n      //   },\n      //   {\n      //     id: 'two',\n      //     name: 'Two',\n      //   },\n      // ],\n      items,\n      remoteItems: serverItems.slice(0, 10),\n      timeout: null as any,\n      loading: false,\n    }),\n    methods: {\n      getItems ({ startIndex, stopIndex }: any) {\n        this.loading = true\n        clearTimeout(this.timeout)\n        this.timeout = setTimeout(() => {\n          this.remoteItems = serverItems.slice(startIndex, stopIndex)\n          this.loading = false\n        }, 1000)\n      },\n    },\n  })\n</script>\n"
  },
  {
    "path": "packages/vuetify/playgrounds/Playground.infinite.vue",
    "content": "<template>\n  <v-infinite-scroll\n    height=\"300\"\n    side=\"both\"\n    @load=\"load\"\n  >\n    <template v-for=\"(item, index) in items\" :key=\"item\">\n      <div :class=\"['px-2', index % 2 === 0 ? 'bg-grey-lighten-2' : '']\">\n        Item number {{ item }}\n      </div>\n    </template>\n  </v-infinite-scroll>\n</template>\n\n<script>\n  export default {\n    data: () => ({\n      items: Array.from({ length: 50 }, (k, v) => v + 1),\n    }),\n\n    methods: {\n      load ({ side, done }) {\n        setTimeout(() => {\n          if (side === 'start') {\n            const arr = Array.from({ length: 10 }, (k, v) => this.items[0] - (10 - v))\n            this.items = [...arr, ...this.items]\n          } else if (side === 'end') {\n            const arr = Array.from({ length: 10 }, (k, v) => this.items.at(-1) + 1 + v)\n            this.items = [...this.items, ...arr]\n          }\n\n          done('ok')\n        }, 1000)\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/vuetify/playgrounds/Playground.items.vue",
    "content": "<template>\n  <v-card\n    max-width=\"450\"\n    class=\"mx-auto\"\n  >\n    <v-toolbar\n      color=\"cyan\"\n      dark\n    >\n      <v-app-bar-nav-icon variant=\"text\"></v-app-bar-nav-icon>\n\n      <v-toolbar-title>Inbox</v-toolbar-title>\n\n      <v-spacer></v-spacer>\n\n      <v-btn variant=\"text\" icon=\"mdi-magnify\"></v-btn>\n    </v-toolbar>\n\n    <v-list\n      lines=\"three\"\n      :items=\"items\"\n      item-title=\"subject\"\n      :item-props=\"itemProps\"\n    >\n      <template v-slot:subtitle=\"{ item }\">\n        <div>\n          <span class=\"text-primary\">{{ item.from }}</span>\n          <span> &mdash; {{ item.content }}</span>\n        </div>\n      </template>\n    </v-list>\n\n    <v-select\n      v-model=\"select\"\n      :items=\"sitems\"\n      item-title=\"state\"\n      item-value=\"abbr\"\n      label=\"Select\"\n      persistent-hint\n      single-line\n    ></v-select>\n    <pre>{{ JSON.stringify(select, null, 2) }}</pre>\n\n    <v-select\n      v-model=\"select2\"\n      :items=\"sitems\"\n      item-title=\"state\"\n      item-value=\"abbr\"\n      label=\"Select\"\n      persistent-hint\n      single-line\n      return-object\n    ></v-select>\n    <pre>{{ JSON.stringify(select2, null, 2) }}</pre>\n\n    <v-autocomplete\n      v-model=\"values\"\n      :items=\"aitems\"\n      outlined\n      dense\n      chips\n      label=\"Outlined\"\n      multiple\n    ></v-autocomplete>\n    <pre>{{ JSON.stringify(values, null, 2) }}</pre>\n\n    <v-autocomplete\n      v-model=\"ovalues\"\n      :items=\"aoitems\"\n      outlined\n      dense\n      chips\n      label=\"Outlined\"\n      multiple\n      return-object\n    ></v-autocomplete>\n    <pre>{{ JSON.stringify(ovalues, null, 2) }}</pre>\n\n    <v-combobox\n      v-model=\"combo\"\n      v-model:items=\"citems\"\n      label=\"Combobox\"\n      multiple\n      outlined\n      dense\n    ></v-combobox>\n\n    <pre>{{ JSON.stringify(combo, null, 2) }}</pre>\n\n    <v-combobox\n      v-model=\"combosingle\"\n      v-model:items=\"citems\"\n      label=\"Combobox\"\n      outlined\n      dense\n    ></v-combobox>\n\n    <div class=\"py-10\" />\n    <div class=\"py-10\" />\n    <div class=\"py-10\" />\n  </v-card>\n</template>\n\n<script>\n  export default {\n    data: () => ({\n      combo: ['Vuetify', 'Programming'],\n      combosingle: 'Programming',\n      citems: [\n        'Programming',\n        'Design',\n        'Vue',\n        'Vuetify',\n      ],\n      aitems: ['foo', 'bar', 'fizz', 'buzz'],\n      aoitems: [\n        { title: 'foo', value: 'foo' },\n        { title: 'bar', value: 'bar' },\n        { title: 'fizz', value: 'fizz' },\n        { title: 'buzz', value: 'buzz' },\n      ],\n      ovalues: [\n        { title: 'foo', value: 'foo' },\n      ],\n      values: ['foo', 'bar'],\n      value: null,\n      select: 'FL',\n      select2: { state: 'Georgia', abbr: 'GA' },\n      sitems: [\n        { state: 'Florida', abbr: 'FL' },\n        { state: 'Georgia', abbr: 'GA' },\n        { state: 'Nebraska', abbr: 'NE' },\n        { state: 'California', abbr: 'CA' },\n        { state: 'New York', abbr: 'NY' },\n      ],\n      items: [\n        { type: 'subheader', subject: 'Today' },\n        {\n          avatarUrl: 'https://cdn.vuetifyjs.com/images/lists/1.jpg',\n          subject: 'Brunch this weekend?',\n          from: 'Ali Connors',\n          content: 'I\\'ll be in your neighborhood doing errands this weekend. Do you want to hang out?',\n          subtitle: `<span class=\"text-primary\">Ali Connors</span> &mdash; `,\n        },\n        { type: 'divider', inset: true },\n        {\n          avatarUrl: 'https://cdn.vuetifyjs.com/images/lists/2.jpg',\n          subject: 'Summer BBQ',\n          from: 'Alex Scott',\n          content: 'Wish I could come, but I\\'m out of town this weekend.',\n          subtitle: `<span class=\"text-primary\">to Alex, Scott, Jennifer</span> &mdash; Wish I could come, but I'm out of town this weekend.`,\n        },\n        { type: 'divider', inset: true },\n        {\n          avatarUrl: 'https://cdn.vuetifyjs.com/images/lists/3.jpg',\n          subject: 'Oui oui',\n          from: 'Sandra adams',\n          content: 'Do you have Paris recommendations? Have you ever been?',\n          subtitle: '<span class=\"text-primary\">Sandra Adams</span> &mdash; Do you have Paris recommendations? Have you ever been?',\n        },\n        { type: 'divider', inset: true },\n        {\n          avatarUrl: 'https://cdn.vuetifyjs.com/images/lists/4.jpg',\n          subject: 'Birthday gift',\n          from: 'Trevor Hansen',\n          content: 'Have any ideas about what we should get Heidi for her birthday?',\n          subtitle: '<span class=\"text-primary\">Trevor Hansen</span> &mdash; ',\n        },\n        { type: 'divider', inset: true },\n        {\n          avatarUrl: 'https://cdn.vuetifyjs.com/images/lists/5.jpg',\n          subject: 'Recipe to try',\n          from: 'Britta Holt',\n          content: 'We should eat this: Grate, Squash, Corn, and tomatillo Tacos.',\n          subtitle: '<span class=\"text-primary\">Britta Holt</span> &mdash; We should eat this: Grate, Squash, Corn, and tomatillo Tacos.',\n        },\n      ],\n    }),\n    methods: {\n      itemProps (item) {\n        if (item.type === 'divider') return { inset: true }\n\n        if (item.type !== 'subheader') return { prependAvatar: item.avatarUrl }\n      },\n    },\n  }\n</script>\n"
  },
  {
    "path": "packages/vuetify/playgrounds/Playground.list.vue",
    "content": "<template>\n  <div>\n    <!-- <v-autocomplete\n      :items=\"people\"\n      filled\n      chips\n      closable-chips\n      color=\"blue-grey-lighten-2\"\n      label=\"Select\"\n      item-title=\"name\"\n      item-value=\"name\"\n      multiple\n    >\n      <template v-slot:chip=\"{ props, item }\">\n        <v-chip\n          v-bind=\"props\"\n          :prepend-avatar=\"item.raw.avatar\"\n          :text=\"item.raw.name\"\n        ></v-chip>\n      </template>\n      <template v-slot:item=\"{ props, item }\">\n        <v-list-item\n          v-bind=\"props\"\n          :prepend-avatar=\"item.raw.avatar\"\n          :title=\"item.raw.name\"\n          :subtitle=\"item.raw.group\"\n        ></v-list-item>\n      </template>\n    </v-autocomplete>\n  </div>\n  <div>\n    <v-autocomplete\n      :items=\"people\"\n      filled\n      chips\n      closable-chips\n      color=\"blue-grey-lighten-2\"\n      label=\"Select\"\n      item-title=\"name\"\n      item-value=\"name\"\n      multiple\n    >\n      <template v-slot:chip=\"{ props, item }\">\n        <v-chip\n          v-bind=\"props\"\n          :prepend-avatar=\"item.raw.avatar\"\n          :text=\"item.raw.name\"\n        ></v-chip>\n      </template>\n    </v-autocomplete>\n  </div>\n  <div>\n    <v-select\n      :items=\"people\"\n      filled\n      chips\n      closable-chips\n      color=\"blue-grey-lighten-2\"\n      label=\"Select\"\n      item-title=\"name\"\n      item-value=\"name\"\n      multiple\n    >\n      <template v-slot:chip=\"{ props, item }\">\n        <v-chip\n          v-bind=\"props\"\n          :prepend-avatar=\"item.raw.avatar\"\n          :text=\"item.raw.name\"\n        ></v-chip>\n      </template>\n      <template v-slot:item=\"{ props, item }\">\n        <v-list-item\n          v-bind=\"props\"\n          :prepend-avatar=\"item.raw.avatar\"\n          :title=\"item.raw.name\"\n          :subtitle=\"item.raw.group\"\n        ></v-list-item>\n      </template>\n    </v-select>\n  </div>\n  <div>\n    <v-select\n      :items=\"people\"\n      filled\n      chips\n      closable-chips\n      color=\"blue-grey-lighten-2\"\n      label=\"Select\"\n      item-title=\"name\"\n      item-value=\"name\"\n      multiple\n    >\n      <template v-slot:chip=\"{ props, item }\">\n        <v-chip\n          v-bind=\"props\"\n          :prepend-avatar=\"item.raw.avatar\"\n          :text=\"item.raw.name\"\n        ></v-chip>\n      </template>\n    </v-select>\n  </div>\n\n  <div>\n    <v-combobox\n      :items=\"people\"\n      filled\n      chips\n      closable-chips\n      color=\"blue-grey-lighten-2\"\n      label=\"Select\"\n      item-title=\"name\"\n      item-value=\"name\"\n      multiple\n    >\n      <template v-slot:chip=\"{ props, item }\">\n        <v-chip\n          v-bind=\"props\"\n          :prepend-avatar=\"item.raw.avatar\"\n          :text=\"item.raw.name\"\n        ></v-chip>\n      </template>\n      <template v-slot:item=\"{ props, item }\">\n        <v-list-item\n          v-bind=\"props\"\n          :prepend-avatar=\"item.raw.avatar\"\n          :title=\"item.raw.name\"\n          :subtitle=\"item.raw.group\"\n        ></v-list-item>\n      </template>\n    </v-combobox>\n  </div>\n  <div>\n    <v-combobox\n      :items=\"people\"\n      filled\n      chips\n      closable-chips\n      color=\"blue-grey-lighten-2\"\n      label=\"Select\"\n      item-title=\"name\"\n      item-value=\"name\"\n      multiple\n    >\n      <template v-slot:chip=\"{ props, item }\">\n        <v-chip\n          v-bind=\"props\"\n          :prepend-avatar=\"item.raw.avatar\"\n          :text=\"item.raw.name\"\n        ></v-chip>\n      </template>\n    </v-combobox> -->\n    <div>\n      <v-select\n        :items=\"people\"\n        filled\n        chips\n        closable-chips\n        color=\"blue-grey-lighten-2\"\n        label=\"Select\"\n        multiple\n      ></v-select>\n\n      <v-list :items=\"people\" />\n    </div>\n  </div>\n</template>\n\n<script>\n  const srcs = {\n    1: 'https://cdn.vuetifyjs.com/images/lists/1.jpg',\n    2: 'https://cdn.vuetifyjs.com/images/lists/2.jpg',\n    3: 'https://cdn.vuetifyjs.com/images/lists/3.jpg',\n    4: 'https://cdn.vuetifyjs.com/images/lists/4.jpg',\n    5: 'https://cdn.vuetifyjs.com/images/lists/5.jpg',\n  }\n\n  export default {\n    data: () => ({\n      people: [\n        // { type: 'subheader', name: 'Group 1' },\n        // { name: 'Sandra Adams', group: 'Group 1', avatar: srcs[1] },\n        // { name: 'Ali Connors', group: 'Group 1', avatar: srcs[2] },\n        // { name: 'Trevor Hansen', group: 'Group 1', avatar: srcs[3] },\n        // { name: 'Tucker Smith', group: 'Group 1', avatar: srcs[2] },\n        // { type: 'divider' },\n        // { type: 'subheader', name: 'Group 2' },\n        // { name: 'Britta Holt', group: 'Group 2', avatar: srcs[4] },\n        // { name: 'Jane Smith ', group: 'Group 2', avatar: srcs[5] },\n        // { name: 'John Smith', group: 'Group 2', avatar: srcs[1] },\n        {\n          title: 'Group 1',\n          children: [\n            { title: 'Jane Smith ', group: 'Group 1', avatar: srcs[5] },\n            { type: 'divider' },\n            { title: 'Britta Holt', group: 'Group 1', avatar: srcs[4] },\n          ],\n          divider: true,\n        },\n        { type: 'divider' },\n        {\n          title: 'Group 2',\n          children: [\n            { title: 'Trevor Hansen', group: 'Group 2', avatar: srcs[3] },\n            { title: 'Ali Connors', group: 'Group 2', avatar: srcs[2] },\n          ],\n        },\n      ],\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/vuetify/playgrounds/Playground.nested.vue",
    "content": "<template>\n  <v-app>\n    <div class=\"pa-10\">\n      <h2>async load of items</h2>\n      <v-list :items=\"loadedItems\" :open-strategy=\"loadItems\" :opened=\"opened\" />\n\n      <h2>custom ctrl + click open strategy</h2>\n      <v-list :items=\"listItems\" :open-strategy=\"openStrategyFn\" density=\"compact\">\n        <template #prepend v-if=\"useSlot\">\n          foo\n        </template>\n      </v-list>\n      <v-btn @click=\"doStuff\">click me</v-btn>\n\n      <h2>router integration</h2>\n      <v-list v-model:selected=\"test\" v-model:opened=\"open\">\n        <v-list-item active-color=\"primary\" to=\"/\" exact title=\"foo\" />\n        <v-list-item active-color=\"primary\" to=\"/page1\" title=\"bar\" />\n        <v-list-group>\n          <template #header=\"props\">\n            <v-list-item active-color=\"primary\" v-bind=\"props\" :active=\"$route.path.startsWith('/nested')\" title=\"header\" />\n          </template>\n          <v-list-item active-color=\"primary\" to=\"/nested/page1\" title=\"baz\" />\n          <v-list-item active-color=\"primary\" to=\"/nested/page2\" title=\"bro\" />\n        </v-list-group>\n      </v-list>\n\n      <h2>value prop</h2>\n      <v-list v-model:active=\"test2\" v-model:opened=\"open2\">\n        <v-list-item value=\"/\" title=\"foo\" />\n        <v-list-item value=\"/page1\" title=\"bar\" />\n        <v-list-group>\n          <template #header=\"props\">\n            <v-list-item v-bind=\"props\" title=\"header\" />\n          </template>\n          <v-list-item value=\"/nested/page1\" title=\"baz\" />\n          <v-list-item value=\"/nested/page2\" title=\"bro\" />\n          <v-list-group>\n            <template #header=\"props\">\n              <v-list-item v-bind=\"props\" title=\"header 2\" />\n            </template>\n            <v-list-item value=\"/nested/foo/page1\" title=\"baz 2\" />\n            <v-list-item value=\"/nested/foo/page2\" title=\"bro 2\" />\n          </v-list-group>\n        </v-list-group>\n      </v-list>\n      {{ test2 }}\n\n      <h2>with checkbox and selected</h2>\n      <v-list :items=\"listItems\" v-model:selected=\"selected\">\n        <template #item=\"props\">\n          <v-list-item v-bind=\"props\">\n            <template #prepend=\"{ select, isSelected }\">\n              <input type=\"checkbox\" :checked=\"isSelected\" @click=\"select(!isSelected)\" />\n            </template>\n          </v-list-item>\n        </template>\n      </v-list>\n      {{ selected }}\n\n      <h2>open on programmatic activate</h2>\n      <v-list v-model:active=\"openOnSelect\" v-model:opened=\"openStuff\" active-strategy=\"multiple\" ref=\"listRef\">\n        <v-list-group>\n          <template #header=\"props\">\n            <v-list-item v-bind=\"props\" title=\"group 1\" />\n          </template>\n          <v-list-item value=\"a\" title=\"a\" />\n          <v-list-item value=\"b\" title=\"b\" />\n        </v-list-group>\n        <v-list-group>\n          <template #header=\"props\">\n            <v-list-item v-bind=\"props\" title=\"group 2\" />\n          </template>\n          <v-list-item value=\"c\" title=\"c\" />\n          <v-list-item value=\"d\" title=\"d\" />\n        </v-list-group>\n        <v-list-group>\n          <template #header=\"props\">\n            <v-list-item v-bind=\"props\" title=\"group 3\" />\n          </template>\n          <v-list-item value=\"e\" title=\"e\" />\n          <v-list-item value=\"f\" title=\"f\" />\n          <v-list-group>\n            <template #header=\"props\">\n              <v-list-item v-bind=\"props\" title=\"group 4\" />\n            </template>\n            <v-list-item value=\"g\" title=\"g\" />\n            <v-list-item value=\"h\" title=\"h\" />\n          </v-list-group>\n        </v-list-group>\n      </v-list>\n      <v-btn @click=\"activateStuff\">activate</v-btn>\n\n      <h2>select strategies</h2>\n      <select v-model=\"selectStrategy\">\n        <option value=\"single-leaf\">single-leaf</option>\n        <option value=\"leaf\">leaf</option>\n      </select>\n      <v-list :items=\"listItems\" :select-strategy=\"selectStrategy\" />\n\n      <h2>open strategies</h2>\n      <select v-model=\"openStrategy\">\n        <option value=\"single\">single</option>\n        <option value=\"multiple\">multiple</option>\n      </select>\n      <v-list :items=\"listItems\" :open-strategy=\"openStrategy\" />\n\n      <h2>router view</h2>\n      <router-view />\n    </div>\n  </v-app>\n</template>\n\n<script>\n  export default {\n    name: 'Playground',\n    data: () => ({\n      useSlot: false,\n      selected: [],\n      selectStrategy: 'leaf',\n      openStrategy: 'multiple',\n      openStuff: null,\n      openOnSelect: null,\n      foo: null,\n      open: null,\n      test: null,\n      open2: null,\n      test2: ['/nested/foo/page2'],\n      listItems: [\n        {\n          title: 'Foo',\n          subtitle: 'Bar',\n          value: 'foo',\n        },\n        {\n          title: 'Bar',\n          value: 'bar',\n          prependIcon: '$close',\n        },\n        {\n          title: 'Group 1',\n          children: [\n            {\n              title: 'Child 1',\n              subtitle: 'Subtitle',\n              // value: 'child1',\n            },\n            {\n              title: 'Child 2',\n              prependIcon: '$close',\n              children: [\n                {\n                  title: 'Grandchild 1',\n                  value: 'grandchild1',\n                  // prependIcon: '$collapse',\n                },\n              ],\n            },\n          ],\n        },\n        // {\n        //   title: 'Group 2',\n        //   children: [\n        //     {\n        //       title: 'Child 3',\n        //     },\n        //   ],\n        // },\n      ],\n      items: [\n        {\n          value: 'a',\n          text: 'a',\n        },\n        {\n          value: 'group1',\n          text: 'group1',\n          children: [\n            {\n              value: 'b',\n              text: 'b',\n            },\n            {\n              value: 'group3',\n              text: 'group3',\n              children: [\n                {\n                  value: 'e',\n                  text: 'e',\n                },\n                {\n                  value: 'f',\n                  text: 'f',\n                },\n              ],\n            },\n          ],\n        },\n        {\n          value: 'group2',\n          text: 'group2',\n          children: [\n            {\n              value: 'c',\n              text: 'd',\n            },\n            {\n              value: 'd',\n              text: 'd',\n            },\n          ],\n        },\n      ],\n      loadedItems: [\n        {\n          value: 'root',\n          title: 'root',\n          loaded: false,\n          children: [],\n        },\n      ],\n      opened: [],\n      isCtrl: false,\n      count: 1,\n    }),\n    mounted () {\n      window.addEventListener('mousedown', this.ctrlHandler, { passive: true })\n    },\n    beforeUnmount () {\n      window.removeEventListener('mousedown', this.ctrlHandler, { passive: true })\n    },\n    methods: {\n      ctrlHandler (e) {\n        this.isCtrl = e.ctrlKey\n      },\n      openStrategyFn ({ id, value, opened, children }) {\n        const items = [id]\n\n        while (items.length) {\n          const item = items.shift()\n\n          if (!children.has(item)) continue\n\n          if (value) {\n            opened.add(item)\n          } else {\n            opened.delete(item)\n          }\n\n          if (this.isCtrl) {\n            items.push(...children.get(item))\n          }\n        }\n\n        return opened\n      },\n      findItem (id) {\n        const queue = [...this.loadedItems]\n\n        while (queue.length) {\n          const item = queue.shift()\n          console.log('check', item, id)\n\n          if (item.value === id) return item\n\n          if (item.children?.length) queue.push(...item.children)\n        }\n\n        return null\n      },\n      loadItems ({ id, value, opened, children, parents }) {\n        const item = this.findItem(id)\n\n        if (item.loaded) {\n          value ? this.opened.push(id) : this.opened.splice(this.opened.indexOf(id), 1)\n        } else {\n          setTimeout(() => {\n            const value = `child #${this.count++}`\n            item.children.push({\n              value,\n              title: value,\n              loaded: false,\n              children: [],\n            })\n            item.loaded = true\n\n            this.opened.push(id)\n          }, 1000)\n        }\n      },\n      activateStuff () {\n        const foo = ['a', 'g']\n        this.openOnSelect = foo\n        // console.log(this.$refs.listRef)\n        for (const k of foo) {\n          this.$refs.listRef.open(k, true)\n        }\n        // this.$refs.listRef.openParents(['a', 'g'])\n        // this.openStuff = ['a', 'g']\n      },\n      doStuff () {\n        // this.listItems = this.listItems.map((item, i) => i === 0 ? ({\n        //   ...item,\n        //   prependIcon: '$expand',\n        // }) : item)\n        this.useSlot = !this.useSlot\n      },\n    },\n  }\n</script>\n\n<style lang=\"sass\">\n  .v-nested\n    input[type=\"checkbox\"]\n      margin: 4px\n\n  .v-nested-item:not(.v-nested-item--header)\n    display: flex\n    align-items: center\n    margin-left: 21px\n\n  .v-nested-group\n    .items\n      margin-left: calc(20px)\n\n  // .v-list-group__header.v-list-item--active\n  //   .v-list-item__overlay\n  //     display: none\n\n</style>\n"
  },
  {
    "path": "packages/vuetify/playgrounds/Playground.slider.vue",
    "content": "<template>\n  <v-app :theme=\"theme\">\n    <div>\n      <v-btn @click=\"rtl = !rtl\">rtl</v-btn>\n      <v-btn @click=\"theme = theme === 'light' ? 'dark' : 'light'\">theme</v-btn>\n      <v-btn @click=\"disabled = !disabled\">disabled</v-btn>\n    </div>\n    <v-locale-provider :rtl=\"rtl\">\n      <div class=\"ma-10 d-flex flex-column\">\n        Regular\n        <v-slider\n          v-model=\"model\"\n          direction=\"vertical\"\n        />\n        <v-slider\n          v-model=\"model\"\n          direction=\"horizontal\"\n        />\n\n        min/max\n        <v-slider\n          v-model=\"model7\"\n          direction=\"vertical\"\n          min=\"10\"\n          max=\"25\"\n          thumb-label=\"always\"\n        />\n        <v-slider\n          v-model=\"model7\"\n          direction=\"horizontal\"\n          min=\"10\"\n          max=\"25\"\n          thumb-label=\"always\"\n        />\n\n        Step size\n        <v-slider\n          v-model=\"model2\"\n          direction=\"vertical\"\n          step-size=\"5\"\n        />\n        <v-slider\n          v-model=\"model2\"\n          direction=\"horizontal\"\n          step-size=\"5\"\n        />\n\n        show-ticks\n        <v-slider\n          v-model=\"model3\"\n          direction=\"vertical\"\n          step-size=\"5\"\n          show-ticks=\"always\"\n        />\n        <v-slider\n          v-model=\"model3\"\n          direction=\"horizontal\"\n          step-size=\"5\"\n          show-ticks=\"always\"\n        />\n\n        custom-ticks\n        <v-slider\n          v-model=\"model3\"\n          direction=\"vertical\"\n          step-size=\"2\"\n          show-ticks=\"always\"\n          :ticks=\"[0, 10, 90]\"\n        />\n        <v-slider\n          v-model=\"model3\"\n          direction=\"horizontal\"\n          step-size=\"2\"\n          show-ticks=\"always\"\n          :ticks=\"[0, 10, 90]\"\n        />\n\n        thumb-label\n        <select v-model=\"thumbLabel\">\n          <option :value=\"true\">true</option>\n          <option value=\"always\">always</option>\n        </select>\n        <v-slider\n          v-model=\"model4\"\n          direction=\"vertical\"\n          :thumb-label=\"thumbLabel\"\n        />\n        <v-slider\n          v-model=\"model4\"\n          direction=\"horizontal\"\n          :thumb-label=\"thumbLabel\"\n        />\n\n        sizes\n        <v-slider\n          v-model=\"model5\"\n          direction=\"vertical\"\n          track-size=\"20\"\n          thumb-size=\"40\"\n          tick-size=\"8\"\n          step-size=\"10\"\n          show-ticks=\"always\"\n        />\n        <v-slider\n          v-model=\"model5\"\n          direction=\"horizontal\"\n          track-size=\"20\"\n          thumb-size=\"40\"\n          tick-size=\"8\"\n          step-size=\"10\"\n          show-ticks=\"always\"\n        />\n\n        disabled\n        <v-slider\n          v-model=\"model6\"\n          direction=\"vertical\"\n          disabled\n        />\n        <v-slider\n          v-model=\"model6\"\n          direction=\"horizontal\"\n          disabled\n        />\n\n        crane\n        <v-slider\n          direction=\"horizontal\"\n          step-size=\"10\"\n          show-ticks=\"always\"\n          rounded=\"0\"\n          color=\"#E30425\"\n        />\n\n        tick-label slot\n        <v-slider\n          direction=\"horizontal\"\n          show-ticks=\"always\"\n          step-size=\"1\"\n          min=\"0\"\n          max=\"3\"\n        >\n          <template #tick-label=\"props\">\n            {{ seasons[props.index] }}\n          </template>\n        </v-slider>\n\n        thumb-label slot\n        <v-slider\n          direction=\"horizontal\"\n          thumb-label=\"always\"\n          step-size=\"1\"\n          min=\"0\"\n          max=\"3\"\n        >\n          <template #thumb-label=\"props\">\n            {{ emojis[props.modelValue] }}\n          </template>\n        </v-slider>\n\n      </div>\n\n      <div class=\"ma-10 d-flex flex-column\">\n        Regular\n        <v-range-slider\n          v-model=\"model1\"\n          direction=\"vertical\"\n        />\n        <v-range-slider\n          v-model=\"model1\"\n          direction=\"horizontal\"\n        />\n\n        min/max\n        <v-range-slider\n          v-model=\"model17\"\n          direction=\"vertical\"\n          min=\"10\"\n          max=\"25\"\n          thumb-label=\"always\"\n        />\n        <v-range-slider\n          v-model=\"model17\"\n          direction=\"horizontal\"\n          min=\"10\"\n          max=\"25\"\n          thumb-label=\"always\"\n        />\n\n        Step size\n        <v-range-slider\n          v-model=\"model12\"\n          direction=\"vertical\"\n          step-size=\"5\"\n        />\n        <v-range-slider\n          v-model=\"model12\"\n          direction=\"horizontal\"\n          step-size=\"5\"\n        />\n\n        Ticks\n        <v-range-slider\n          v-model=\"model13\"\n          direction=\"vertical\"\n          step-size=\"5\"\n          show-ticks=\"always\"\n        />\n        <v-range-slider\n          v-model=\"model13\"\n          direction=\"horizontal\"\n          step-size=\"5\"\n          show-ticks=\"always\"\n        />\n\n        thumb-label\n        <v-range-slider\n          v-model=\"model14\"\n          direction=\"vertical\"\n          thumb-label=\"always\"\n        />\n        <v-range-slider\n          v-model=\"model14\"\n          direction=\"horizontal\"\n          thumb-label=\"always\"\n        />\n\n        sizes\n        <v-range-slider\n          v-model=\"model15\"\n          direction=\"vertical\"\n          track-size=\"20\"\n          thumb-size=\"40\"\n          tick-size=\"8\"\n          step-size=\"10\"\n          show-ticks=\"always\"\n        />\n        <v-range-slider\n          v-model=\"model15\"\n          direction=\"horizontal\"\n          track-size=\"20\"\n          thumb-size=\"40\"\n          tick-size=\"8\"\n          step-size=\"10\"\n          show-ticks=\"always\"\n        />\n\n        disabled\n        <v-range-slider\n          v-model=\"model16\"\n          direction=\"vertical\"\n          disabled\n        />\n        <v-range-slider\n          v-model=\"model16\"\n          direction=\"horizontal\"\n          disabled\n        />\n\n        crane\n        <v-range-slider\n          direction=\"horizontal\"\n          step-size=\"10\"\n          show-ticks=\"always\"\n          rounded=\"0\"\n          color=\"#E30425\"\n        />\n      </div>\n    </v-locale-provider>\n  </v-app>\n</template>\n\n<script>\n  export default {\n    name: 'Playground',\n    data: () => ({\n      thumbLabel: true,\n      arr: [10, 30],\n      foo: null,\n      test: 3,\n      model: 1,\n      model2: 0,\n      model3: 60,\n      model4: 0,\n      model5: 0,\n      model6: 25,\n      model7: 15,\n      model1: [10, 30],\n      model12: [10, 30],\n      model13: [10, 30],\n      model14: [10, 30],\n      model15: [10, 30],\n      model16: [10, 30],\n      model17: [15, 20],\n      seasons: ['spring', 'summer', 'fall', 'winter'],\n      emojis: ['😭', '🙁', '😊', '😍'],\n      theme: 'light',\n      rtl: false,\n    }),\n  }\n</script>\n"
  },
  {
    "path": "packages/vuetify/src/__tests__/framework.spec.browser.tsx",
    "content": "// Utilities\nimport { mount } from '@vue/test-utils'\nimport { createVuetify } from '@/framework'\n\ndescribe('framework', () => {\n  describe('install', () => {\n    it('should return install function', () => {\n      const vuetify = createVuetify()\n\n      expect('install' in vuetify).toBe(true)\n    })\n\n    it('should install provided components', () => {\n      const Foo = { name: 'Foo', render: () => (<div />) }\n      const vuetify = createVuetify({\n        components: {\n          Foo,\n        },\n      })\n\n      const TestComponent = {\n        name: 'TestComponent',\n        props: {},\n        render: () => (<foo />),\n      }\n\n      mount(TestComponent, {\n        global: {\n          plugins: [vuetify],\n        },\n      })\n\n      expect('[Vue warn]: Failed to resolve component: foo').not.toHaveBeenTipped()\n    })\n\n    it('should install provided directives', () => {\n      const Foo = { mounted: () => null }\n      const vuetify = createVuetify({\n        directives: {\n          Foo,\n        },\n      })\n\n      const TestComponent = {\n        name: 'TestComponent',\n        props: {},\n        render: () => (<div v-foo />),\n      }\n\n      mount(TestComponent, {\n        global: {\n          plugins: [vuetify],\n        },\n      })\n\n      expect('[Vue warn]: Failed to resolve directive: foo').not.toHaveBeenTipped()\n    })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/auto-imports.d.ts",
    "content": "/* eslint-disable */\n/* prettier-ignore */\n// @ts-nocheck\n// noinspection JSUnusedGlobalSymbols\n// Generated by unplugin-auto-import\n// biome-ignore lint: disable\nexport {}\ndeclare global {\n  const afterAll: typeof import('vitest')['afterAll']\n  const afterEach: typeof import('vitest')['afterEach']\n  const assert: typeof import('vitest')['assert']\n  const beforeAll: typeof import('vitest')['beforeAll']\n  const beforeEach: typeof import('vitest')['beforeEach']\n  const describe: typeof import('vitest')['describe']\n  const expect: typeof import('vitest')['expect']\n  const it: typeof import('vitest')['it']\n  const vi: typeof import('vitest')['vi']\n}\n"
  },
  {
    "path": "packages/vuetify/src/blueprints/index.ts",
    "content": "export { md1 } from './md1'\nexport { md2 } from './md2'\nexport { md3 } from './md3'\n"
  },
  {
    "path": "packages/vuetify/src/blueprints/md1.ts",
    "content": "// Icons\nimport { mdi } from '@/iconsets/mdi'\n\n// Types\nimport type { Blueprint } from '@/framework'\n\nexport const md1: Blueprint = {\n  defaults: {\n    global: {\n      rounded: 'sm',\n    },\n    VAvatar: {\n      rounded: 'circle',\n    },\n    VAutocomplete: {\n      variant: 'underlined',\n    },\n    VBanner: {\n      color: 'primary',\n    },\n    VBtn: {\n      class: 'text-uppercase',\n      color: 'primary',\n      rounded: 0,\n    },\n    VCheckbox: {\n      color: 'secondary',\n      indentDetails: false,\n    },\n    VCombobox: {\n      variant: 'underlined',\n    },\n    VDatePicker: {\n      color: 'primary',\n      controlHeight: 44,\n      elevation: 1,\n      rounded: 0,\n      controlVariant: 'modal',\n\n      VBtn: {\n        color: 'high-emphasis',\n        rounded: 'circle',\n      },\n    },\n    VSelect: {\n      variant: 'underlined',\n    },\n    VSlider: {\n      color: 'primary',\n      indentDetails: false,\n    },\n    VSwitch: {\n      indentDetails: false,\n    },\n    VRadioGroup: {\n      indentDetails: false,\n    },\n    VRangeSlider: {\n      indentDetails: false,\n    },\n    VTabs: {\n      color: 'primary',\n    },\n    VTextarea: {\n      variant: 'underlined',\n    },\n    VTextField: {\n      variant: 'underlined',\n    },\n    VToolbar: {\n      VBtn: {\n        color: null,\n      },\n    },\n  },\n  icons: {\n    defaultSet: 'mdi',\n    sets: {\n      mdi,\n    },\n  },\n  theme: {\n    themes: {\n      light: {\n        colors: {\n          primary: '#3F51B5',\n          'primary-darken-1': '#303F9F',\n          'primary-lighten-1': '#C5CAE9',\n          secondary: '#FF4081',\n          'secondary-darken-1': '#F50057',\n          'secondary-lighten-1': '#FF80AB',\n          accent: '#009688',\n        },\n      },\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/blueprints/md2.ts",
    "content": "// Icons\nimport { mdi } from '@/iconsets/mdi'\n\n// Types\nimport type { Blueprint } from '@/framework'\n\nexport const md2: Blueprint = {\n  defaults: {\n    VAvatar: {\n      rounded: 'circle',\n    },\n    VAutocomplete: {\n      variant: 'filled',\n    },\n    VBanner: {\n      color: 'primary',\n    },\n    VBtn: {\n      class: 'text-uppercase',\n      color: 'primary',\n    },\n    VCheckbox: {\n      color: 'secondary',\n      indentDetails: true,\n    },\n    VCombobox: {\n      variant: 'filled',\n    },\n    VDatePicker: {\n      color: 'primary',\n      controlHeight: 56,\n      elevation: 2,\n      rounded: 'md',\n      controlVariant: 'modal',\n\n      VBtn: {\n        color: 'high-emphasis',\n        rounded: 'circle',\n      },\n    },\n    VRadioGroup: {\n      indentDetails: true,\n    },\n    VSelect: {\n      variant: 'filled',\n    },\n    VSlider: {\n      color: 'primary',\n      indentDetails: true,\n    },\n    VRangeSlider: {\n      indentDetails: true,\n    },\n    VSwitch: {\n      indentDetails: true,\n    },\n    VTabs: {\n      color: 'primary',\n    },\n    VTextarea: {\n      variant: 'filled',\n    },\n    VTextField: {\n      variant: 'filled',\n    },\n    VToolbar: {\n      VBtn: {\n        color: null,\n      },\n    },\n  },\n  icons: {\n    defaultSet: 'mdi',\n    sets: {\n      mdi,\n    },\n  },\n  theme: {\n    themes: {\n      light: {\n        colors: {\n          primary: '#6200EE',\n          'primary-darken-1': '#3700B3',\n          secondary: '#03DAC6',\n          'secondary-darken-1': '#018786',\n          error: '#B00020',\n        },\n      },\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/blueprints/md3.ts",
    "content": "// Icons\nimport { mdi } from '@/iconsets/mdi'\n\n// Types\nimport type { Blueprint } from '@/framework'\n\nexport const md3: Blueprint = {\n  defaults: {\n    VAppBar: {\n      flat: true,\n    },\n    VAutocomplete: {\n      variant: 'outlined',\n    },\n    VBanner: {\n      color: 'primary',\n    },\n    VBottomSheet: {\n      contentClass: 'rounded-t-xl overflow-hidden',\n    },\n    VBtn: {\n      color: 'primary',\n      rounded: 'xl',\n    },\n    VBtnGroup: {\n      rounded: 'xl',\n      VBtn: { rounded: null },\n    },\n    VCard: {\n      rounded: 'lg',\n    },\n    VCheckbox: {\n      color: 'secondary',\n      inset: true,\n      indentDetails: true,\n    },\n    VChip: {\n      rounded: 'sm',\n    },\n    VCombobox: {\n      variant: 'outlined',\n    },\n    VDateInput: {\n      variant: 'outlined',\n    },\n    VDatePicker: {\n      controlHeight: 48,\n      color: 'primary',\n      divided: true,\n      headerColor: '',\n      elevation: 1,\n      rounded: 'xl',\n\n      VBtn: {\n        color: 'high-emphasis',\n        rounded: 'circle',\n      },\n    },\n    VFileInput: {\n      variant: 'outlined',\n    },\n    VList: {\n      prependGap: 16,\n    },\n    VNavigationDrawer: {\n      // VList: {\n      //   nav: true,\n      //   VListItem: {\n      //     rounded: 'xl',\n      //   },\n      // },\n    },\n    VNumberInput: {\n      variant: 'outlined',\n\n      VBtn: {\n        color: undefined,\n        rounded: undefined,\n      },\n    },\n    VRadioGroup: {\n      indentDetails: true,\n    },\n    VSelect: {\n      variant: 'outlined',\n    },\n    VSlider: {\n      color: 'primary',\n      indentDetails: true,\n    },\n    VRangeSlider: {\n      indentDetails: true,\n    },\n    VSwitch: {\n      indentDetails: true,\n    },\n    VTabs: {\n      color: 'primary',\n    },\n    VTextarea: {\n      variant: 'outlined',\n    },\n    VTextField: {\n      variant: 'outlined',\n    },\n    VToolbar: {\n      VBtn: {\n        color: null,\n      },\n    },\n  },\n  icons: {\n    defaultSet: 'mdi',\n    sets: {\n      mdi,\n    },\n  },\n  theme: {\n    themes: {\n      light: {\n        colors: {\n          primary: '#6750a4',\n          secondary: '#b4b0bb',\n          tertiary: '#7d5260',\n          error: '#b3261e',\n          surface: '#fffbfe',\n        },\n      },\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VAlert/VAlert.sass",
    "content": "@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-alert\n    display: grid\n    flex: 1 1\n    grid-template-areas: \"prepend content append close\" \". content . .\"\n    grid-template-columns: max-content auto max-content max-content\n    position: relative\n    padding: $alert-padding\n    overflow: hidden\n    --v-border-color: #{$alert-border-color}\n\n    @include tools.position($alert-positions)\n    @include tools.rounded($alert-border-radius)\n    @include tools.variant($alert-variants...)\n\n    &--prominent\n      grid-template-areas: \"prepend content append close\" \"prepend content . .\"\n\n    &.v-alert--border\n      --v-border-opacity: #{$alert-border-opacity}\n\n      &.v-alert--border-start\n        padding-inline-start: $alert-padding + $alert-border-thin-width\n\n      &.v-alert--border-end\n        padding-inline-end: $alert-padding + $alert-border-thin-width\n\n    &--variant-plain\n      transition: $alert-plain-transition\n\n    @at-root\n      @include tools.density('v-alert', $alert-density) using ($modifier)\n        padding-bottom: $alert-padding + $modifier\n        padding-top: $alert-padding + $modifier\n\n        &.v-alert--border-top\n          padding-top: $alert-padding + $alert-border-thin-width + $modifier\n\n        &.v-alert--border-bottom\n          padding-bottom: $alert-padding + $alert-border-thin-width + $modifier\n\n    &:not(:has(.v-alert-title))\n      .v-alert__content\n        padding-block: calc((#{$alert-prepend-icon-size} - #{settings.$line-height-root} * 1rem) / 2)\n\n  .v-alert__border\n    border-radius: inherit\n    bottom: 0\n    left: 0\n    opacity: var(--v-border-opacity)\n    position: absolute\n    pointer-events: none\n    right: 0\n    top: 0\n    width: 100%\n\n    @include tools.border($alert-border...)\n\n    .v-alert--border-start &\n      border-inline-start-width: $alert-border-thin-width\n\n    .v-alert--border-end &\n      border-inline-end-width: $alert-border-thin-width\n\n    .v-alert--border-top &\n      border-top-width: $alert-border-thin-width\n\n    .v-alert--border-bottom &\n      border-bottom-width: $alert-border-thin-width\n\n  .v-alert__close\n    flex: 0 1 auto\n    grid-area: close\n\n    > .v-btn\n      margin-block: calc(-1 * (var(--v-btn-height) + 12px - #{$alert-prepend-icon-size}) / 2)\n\n  .v-alert__content\n    align-self: center\n    grid-area: content\n    overflow: hidden\n\n    > :first-child\n      margin-top: 0\n\n    > :last-child\n      margin-bottom: 0\n\n  .v-alert__append,\n  .v-alert__close\n    margin-inline-start: $alert-append-margin-inline-start\n\n  .v-alert__append\n    align-self: flex-start\n    grid-area: append\n\n    + .v-alert__close\n      margin-inline-start: $alert-append-close-margin-inline-start\n\n  .v-alert__prepend\n    align-self: flex-start\n    display: flex\n    align-items: center\n    grid-area: prepend\n    margin-inline-end: $alert-prepend-margin-inline-end\n    min-height: $alert-prepend-icon-size\n\n    > .v-icon\n      font-size: $alert-prepend-icon-size\n      height: $alert-prepend-icon-size\n      width: $alert-prepend-icon-size\n\n    .v-alert--prominent &\n      align-self: center\n\n  .v-alert__underlay\n    grid-area: none\n    position: absolute\n\n    .v-alert--border-start &\n      border-top-left-radius: 0\n      border-bottom-left-radius: 0\n\n    .v-alert--border-end &\n      border-top-right-radius: 0\n      border-bottom-right-radius: 0\n\n    .v-alert--border-top &\n      border-top-left-radius: 0\n      border-top-right-radius: 0\n\n    .v-alert--border-bottom &\n      border-bottom-left-radius: 0\n      border-bottom-right-radius: 0\n\n  .v-alert-title\n    align-items: center\n    align-self: center\n    display: flex\n    font-size: $alert-title-font-size\n    font-weight: $alert-title-font-weight\n    hyphens: $alert-title-hyphens\n    letter-spacing: $alert-title-letter-spacing\n    line-height: $alert-title-line-height\n    overflow-wrap: $alert-title-overflow-wrap\n    text-transform: $alert-title-text-transform\n    word-break: $alert-title-word-break\n    word-wrap: $alert-title-word-wrap\n\n  @media (forced-colors: active)\n    .v-alert\n      &:not(&--variant-text, &--variant-plain)\n        border-style: solid\n\n      &--variant-outlined,\n      &--variant-tonal\n        border-width: medium\n\n      &--variant-elevated,\n      &--variant-flat\n        border-width: thick\n"
  },
  {
    "path": "packages/vuetify/src/components/VAlert/VAlert.tsx",
    "content": "// Styles\nimport './VAlert.sass'\n\n// Components\nimport { VAlertTitle } from './VAlertTitle'\nimport { VBtn } from '@/components/VBtn'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\nimport { VIcon } from '@/components/VIcon'\n\n// Composables\nimport { useTextColor } from '@/composables/color'\nimport { makeComponentProps } from '@/composables/component'\nimport { makeDensityProps, useDensity } from '@/composables/density'\nimport { makeDimensionProps, useDimension } from '@/composables/dimensions'\nimport { makeElevationProps, useElevation } from '@/composables/elevation'\nimport { IconValue } from '@/composables/icons'\nimport { makeIconSizeProps, useIconSizes } from '@/composables/iconSizes'\nimport { useLocale } from '@/composables/locale'\nimport { makeLocationProps, useLocation } from '@/composables/location'\nimport { makePositionProps, usePosition } from '@/composables/position'\nimport { useProxiedModel } from '@/composables/proxiedModel'\nimport { makeRoundedProps, useRounded } from '@/composables/rounded'\nimport { makeTagProps } from '@/composables/tag'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\nimport { genOverlays, makeVariantProps, useVariant } from '@/composables/variant'\n\n// Utilities\nimport { toRef } from 'vue'\nimport { genericComponent, propsFactory } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\nconst allowedTypes = ['success', 'info', 'warning', 'error'] as const\n\ntype ContextualType = typeof allowedTypes[number]\n\nexport const makeVAlertProps = propsFactory({\n  border: {\n    type: [Boolean, String] as PropType<boolean | 'top' | 'end' | 'bottom' | 'start'>,\n    validator: (val: boolean | string) => {\n      return typeof val === 'boolean' || [\n        'top',\n        'end',\n        'bottom',\n        'start',\n      ].includes(val)\n    },\n  },\n  borderColor: String,\n  closable: Boolean,\n  closeIcon: {\n    type: IconValue,\n    default: '$close',\n  },\n  closeLabel: {\n    type: String,\n    default: '$vuetify.close',\n  },\n  icon: {\n    type: [Boolean, String, Function, Object] as PropType<false | IconValue>,\n    default: null,\n  },\n  modelValue: {\n    type: Boolean,\n    default: true,\n  },\n  prominent: Boolean,\n  title: String,\n  text: String,\n  type: {\n    type: String as PropType<ContextualType>,\n    validator: (val: ContextualType) => allowedTypes.includes(val),\n  },\n\n  ...makeComponentProps(),\n  ...makeDensityProps(),\n  ...makeDimensionProps(),\n  ...makeElevationProps(),\n  ...makeIconSizeProps(),\n  ...makeLocationProps(),\n  ...makePositionProps(),\n  ...makeRoundedProps(),\n  ...makeTagProps(),\n  ...makeThemeProps(),\n  ...makeVariantProps({ variant: 'flat' } as const),\n}, 'VAlert')\n\nexport type VAlertSlots = {\n  default: never\n  prepend: never\n  title: never\n  text: never\n  append: never\n  close: { props: Record<string, any> }\n}\n\nexport const VAlert = genericComponent<VAlertSlots>()({\n  name: 'VAlert',\n\n  props: makeVAlertProps(),\n\n  emits: {\n    'click:close': (e: MouseEvent) => true,\n    'update:modelValue': (value: boolean) => true,\n  },\n\n  setup (props, { emit, slots }) {\n    const isActive = useProxiedModel(props, 'modelValue')\n    const icon = toRef(() => {\n      if (props.icon === false) return undefined\n      if (!props.type) return props.icon\n\n      return props.icon ?? `$${props.type}`\n    })\n\n    const { iconSize } = useIconSizes(props, () => props.prominent ? 44 : undefined)\n    const { themeClasses } = provideTheme(props)\n    const { colorClasses, colorStyles, variantClasses } = useVariant(() => ({\n      color: props.color ?? props.type,\n      variant: props.variant,\n    }))\n    const { densityClasses } = useDensity(props)\n    const { dimensionStyles } = useDimension(props)\n    const { elevationClasses } = useElevation(props)\n    const { locationStyles } = useLocation(props)\n    const { positionClasses } = usePosition(props)\n    const { roundedClasses } = useRounded(props)\n    const { textColorClasses, textColorStyles } = useTextColor(() => props.borderColor)\n    const { t } = useLocale()\n\n    const closeProps = toRef(() => ({\n      'aria-label': t(props.closeLabel),\n      onClick (e: MouseEvent) {\n        isActive.value = false\n\n        emit('click:close', e)\n      },\n    }))\n\n    return () => {\n      const hasPrepend = !!(slots.prepend || icon.value)\n      const hasTitle = !!(slots.title || props.title)\n      const hasClose = !!(slots.close || props.closable)\n\n      const iconProps = {\n        density: props.density,\n        icon: icon.value,\n        size: props.iconSize || props.prominent\n          ? iconSize.value\n          : undefined,\n      }\n\n      return isActive.value && (\n        <props.tag\n          class={[\n            'v-alert',\n            props.border && {\n              'v-alert--border': !!props.border,\n              [`v-alert--border-${props.border === true ? 'start' : props.border}`]: true,\n            },\n            {\n              'v-alert--prominent': props.prominent,\n            },\n            themeClasses.value,\n            colorClasses.value,\n            densityClasses.value,\n            elevationClasses.value,\n            positionClasses.value,\n            roundedClasses.value,\n            variantClasses.value,\n            props.class,\n          ]}\n          style={[\n            colorStyles.value,\n            dimensionStyles.value,\n            locationStyles.value,\n            props.style,\n          ]}\n          role=\"alert\"\n        >\n          { genOverlays(false, 'v-alert') }\n\n          { props.border && (\n            <div\n              key=\"border\"\n              class={[\n                'v-alert__border',\n                textColorClasses.value,\n              ]}\n              style={ textColorStyles.value }\n            />\n          )}\n\n          { hasPrepend && (\n            <div key=\"prepend\" class=\"v-alert__prepend\">\n              { !slots.prepend ? (\n                <VIcon key=\"prepend-icon\" { ...iconProps } />\n              ) : (\n                <VDefaultsProvider\n                  key=\"prepend-defaults\"\n                  disabled={ !icon.value }\n                  defaults={{ VIcon: { ...iconProps } }}\n                  v-slots:default={ slots.prepend }\n                />\n              )}\n            </div>\n          )}\n\n          <div class=\"v-alert__content\">\n            { hasTitle && (\n              <VAlertTitle key=\"title\">\n                { slots.title?.() ?? props.title }\n              </VAlertTitle>\n            )}\n\n            { slots.text?.() ?? props.text }\n\n            { slots.default?.() }\n          </div>\n\n          { slots.append && (\n            <div key=\"append\" class=\"v-alert__append\">\n              { slots.append() }\n            </div>\n          )}\n\n          { hasClose && (\n            <div key=\"close\" class=\"v-alert__close\">\n              { !slots.close ? (\n                <VBtn\n                  key=\"close-btn\"\n                  icon={ props.closeIcon }\n                  size=\"x-small\"\n                  variant=\"text\"\n                  { ...closeProps.value }\n                />\n              ) : (\n                <VDefaultsProvider\n                  key=\"close-defaults\"\n                  defaults={{\n                    VBtn: {\n                      icon: props.closeIcon,\n                      size: 'x-small',\n                      variant: 'text',\n                    },\n                  }}\n                >\n                  { slots.close?.({ props: closeProps.value }) }\n                </VDefaultsProvider>\n              )}\n            </div>\n          )}\n        </props.tag>\n      )\n    }\n  },\n})\n\nexport type VAlert = InstanceType<typeof VAlert>\n"
  },
  {
    "path": "packages/vuetify/src/components/VAlert/VAlertTitle.ts",
    "content": "// Utilities\nimport { createSimpleFunctional } from '@/util'\n\nexport const VAlertTitle = createSimpleFunctional('v-alert-title')\n\nexport type VAlertTitle = InstanceType<typeof VAlertTitle>\n"
  },
  {
    "path": "packages/vuetify/src/components/VAlert/__tests__/VAlert.spec.browser.tsx",
    "content": "import { VAlert } from '..'\n\n// Utilities\nimport { render, screen, showcase } from '@test'\n\nconst defaultColors = ['success', 'info', 'warning', 'error', 'invalid']\n\nconst props = {\n  color: defaultColors,\n  icon: ['$vuetify'],\n  modelValue: true,\n}\n\nconst stories = {\n  'Default alert': <VAlert />,\n  'Icon alert': <VAlert icon=\"$vuetify\" />,\n}\n\n// Tests\ndescribe('VAlert', () => {\n  describe('color', () => {\n    it('supports default color props', async () => {\n      render(() => (\n        <>\n          { defaultColors.map((color, idx) => (\n            <VAlert color={ color } text={ idx.toString() }>\n              { color } alert\n            </VAlert>\n          ))}\n        </>\n      ))\n\n      const alerts = await screen.findAllByCSS('.v-alert')\n      expect(alerts).toHaveLength(defaultColors.length)\n\n      Array.from(alerts).forEach((alert, idx) => {\n        // TODO: useless assert\n        expect(alert).toHaveTextContent(defaultColors[idx])\n      })\n    })\n  })\n\n  showcase({ stories, props, component: VAlert })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VAlert/_variables.scss",
    "content": "@use '../../styles/settings';\n@use '../../styles/tools';\n\n// VAlert\n$alert-background: rgb(var(--v-theme-surface-light)) !default;\n$alert-border-color: currentColor !default;\n$alert-border-opacity: .38 !default;\n$alert-border-radius: settings.$border-radius-root !default;\n$alert-border-style: settings.$border-style-root !default;\n$alert-border-thin-width: 8px !default;\n$alert-border-width: 0 !default;\n$alert-color: tools.theme-color('on-surface-light', var(--v-high-emphasis-opacity)) !default;\n$alert-density: ('default': 0, 'comfortable': -1, 'compact': -2) !default;\n$alert-elevation: 1 !default;\n$alert-padding: 16px !default;\n$alert-plain-opacity: .62 !default;\n$alert-plain-transition: .2s opacity settings.$standard-easing !default;\n$alert-positions: absolute fixed sticky !default;\n$alert-prepend-margin-inline-end: 16px !default;\n$alert-prepend-icon-size: 1.75rem !default;\n$alert-append-margin-inline-start: 16px !default;\n$alert-append-close-margin-inline-start: 16px !default;\n\n// VAlertTitle\n$alert-title-font-size: tools.map-deep-get(settings.$typography, 'headline-small', 'size') !default;\n$alert-title-font-weight: tools.map-deep-get(settings.$typography, 'headline-small', 'weight') !default;\n$alert-title-hyphens: auto !default;\n$alert-title-letter-spacing: tools.map-deep-get(settings.$typography, 'headline-small', 'letter-spacing') !default;\n$alert-title-line-height: 1.75rem !default;\n$alert-title-overflow-wrap: normal !default;\n$alert-title-text-transform: none !default;\n$alert-title-word-break: normal !default;\n$alert-title-word-wrap: break-word !default;\n\n// VAlertText\n$alert-text-line-height: 1.35 !default;\n\n// Lists\n$alert-border: (\n  $alert-border-color,\n  $alert-border-style,\n  $alert-border-width,\n  $alert-border-thin-width\n) !default;\n\n$alert-variants: (\n  $alert-background,\n  $alert-color,\n  $alert-elevation,\n  $alert-plain-opacity,\n  'v-alert'\n) !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VAlert/index.ts",
    "content": "export { VAlert } from './VAlert'\nexport { VAlertTitle } from './VAlertTitle'\n"
  },
  {
    "path": "packages/vuetify/src/components/VApp/VApp.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-application\n    display: flex\n    background: $application-background\n    color: $application-color\n\n  .v-application__wrap\n    backface-visibility: hidden\n    display: flex\n    flex-direction: column\n    flex: 1 1 auto\n    max-width: 100%\n    min-height: 100vh\n    min-height: 100dvh\n    position: relative\n"
  },
  {
    "path": "packages/vuetify/src/components/VApp/VApp.tsx",
    "content": "// Styles\nimport './VApp.sass'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { createLayout, makeLayoutProps } from '@/composables/layout'\nimport { useRtl } from '@/composables/locale'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\n\n// Utilities\nimport { genericComponent, omit, propsFactory, useRender } from '@/util'\n\nexport const makeVAppProps = propsFactory({\n  ...makeComponentProps(),\n  ...omit(makeLayoutProps(), ['fullHeight']),\n  ...makeThemeProps(),\n}, 'VApp')\n\nexport const VApp = genericComponent()({\n  name: 'VApp',\n\n  props: makeVAppProps(),\n\n  setup (props, { slots }) {\n    const theme = provideTheme(props)\n    const { layoutClasses, getLayoutItem, items, layoutRef } = createLayout({ ...props, fullHeight: true })\n    const { rtlClasses } = useRtl()\n\n    useRender(() => (\n      <div\n        ref={ layoutRef }\n        class={[\n          'v-application',\n          theme.themeClasses.value,\n          layoutClasses.value,\n          rtlClasses.value,\n          props.class,\n        ]}\n        style={[\n          props.style,\n        ]}\n      >\n        <div class=\"v-application__wrap\">\n          { slots.default?.() }\n        </div>\n      </div>\n    ))\n\n    return {\n      getLayoutItem,\n      items,\n      theme,\n    }\n  },\n})\n\nexport type VApp = InstanceType<typeof VApp>\n"
  },
  {
    "path": "packages/vuetify/src/components/VApp/_variables.scss",
    "content": "@use '../../styles/settings';\n@use '../../styles/tools';\n\n// VApp\n$application-background: rgb(var(--v-theme-background)) !default;\n$application-color: tools.theme-color('on-background', var(--v-high-emphasis-opacity)) !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VApp/index.ts",
    "content": "export { VApp } from './VApp'\n"
  },
  {
    "path": "packages/vuetify/src/components/VAppBar/VAppBar.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-app-bar\n    display: flex\n\n    &.v-toolbar\n      @include tools.theme($app-bar-theme...)\n\n      &:not(.v-toolbar--flat)\n        @include tools.elevation($app-bar-elevation)\n\n    &:not(.v-toolbar--absolute)\n      padding-inline-end: var(--v-scrollbar-offset)\n"
  },
  {
    "path": "packages/vuetify/src/components/VAppBar/VAppBar.tsx",
    "content": "// Styles\nimport './VAppBar.sass'\n\n// Components\nimport { makeVToolbarProps, VToolbar } from '@/components/VToolbar/VToolbar'\n\n// Composables\nimport { makeLayoutItemProps, useLayoutItem } from '@/composables/layout'\nimport { useProxiedModel } from '@/composables/proxiedModel'\nimport { makeScrollProps, useScroll } from '@/composables/scroll'\nimport { useSsrBoot } from '@/composables/ssrBoot'\nimport { useToggleScope } from '@/composables/toggleScope'\n\n// Utilities\nimport { computed, ref, shallowRef, toRef, watchEffect } from 'vue'\nimport { genericComponent, omit, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { VToolbarSlots } from '@/components/VToolbar/VToolbar'\n\nexport const makeVAppBarProps = propsFactory({\n  scrollBehavior: String as PropType<'hide' | 'fully-hide' | 'inverted' | 'collapse' | 'elevate' | 'fade-image' | (string & {})>,\n  modelValue: {\n    type: Boolean,\n    default: true,\n  },\n  location: {\n    type: String as PropType<'top' | 'bottom'>,\n    default: 'top',\n    validator: (value: any) => ['top', 'bottom'].includes(value),\n  },\n\n  ...omit(makeVToolbarProps(), ['location']),\n  ...makeLayoutItemProps(),\n  ...makeScrollProps(),\n\n  height: {\n    type: [Number, String],\n    default: 64,\n  },\n}, 'VAppBar')\n\nexport const VAppBar = genericComponent<VToolbarSlots>()({\n  name: 'VAppBar',\n\n  props: makeVAppBarProps(),\n\n  emits: {\n    'update:modelValue': (value: boolean) => true,\n  },\n\n  setup (props, { slots }) {\n    const vToolbarRef = ref<VToolbar>()\n    const isActive = useProxiedModel(props, 'modelValue')\n    const scrollBehavior = computed(() => {\n      const behavior = new Set(props.scrollBehavior?.split(' ') ?? [])\n      return {\n        hide: behavior.has('hide'),\n        fullyHide: behavior.has('fully-hide'),\n        inverted: behavior.has('inverted'),\n        collapse: behavior.has('collapse'),\n        elevate: behavior.has('elevate'),\n        fadeImage: behavior.has('fade-image'),\n        // shrink: behavior.has('shrink'),\n      }\n    })\n    const canScroll = computed(() => {\n      const behavior = scrollBehavior.value\n      return (\n        behavior.hide ||\n        behavior.fullyHide ||\n        behavior.inverted ||\n        behavior.collapse ||\n        behavior.elevate ||\n        behavior.fadeImage ||\n        // behavior.shrink ||\n        !isActive.value\n      )\n    })\n\n    const appBarHeight = computed(() => {\n      const height = vToolbarRef.value?.contentHeight ?? 0\n      const extensionHeight = vToolbarRef.value?.extensionHeight ?? 0\n      return height + extensionHeight\n    })\n\n    const {\n      currentScroll,\n      scrollThreshold,\n      isScrollingUp,\n      scrollRatio,\n      isAtBottom,\n      reachedBottomWhileScrollingDown,\n      hasEnoughScrollableSpace,\n    } = useScroll(props, { canScroll, layoutSize: appBarHeight })\n\n    const canHide = toRef(() => (\n      scrollBehavior.value.hide ||\n      scrollBehavior.value.fullyHide\n    ))\n    const isCollapsed = computed(() => props.collapse || (\n      scrollBehavior.value.collapse &&\n      (scrollBehavior.value.inverted ? scrollRatio.value > 0 : scrollRatio.value === 0)\n    ))\n    const isFlat = computed(() => props.flat || (\n      scrollBehavior.value.fullyHide &&\n      !isActive.value\n    ) || (\n      scrollBehavior.value.elevate &&\n      (scrollBehavior.value.inverted ? currentScroll.value > 0 : currentScroll.value === 0)\n    ))\n    const opacity = computed(() => (\n      scrollBehavior.value.fadeImage\n        ? (scrollBehavior.value.inverted ? 1 - scrollRatio.value : scrollRatio.value)\n        : undefined\n    ))\n    const height = computed(() => {\n      if (scrollBehavior.value.hide && scrollBehavior.value.inverted) return 0\n\n      const height = vToolbarRef.value?.contentHeight ?? 0\n      const extensionHeight = vToolbarRef.value?.extensionHeight ?? 0\n\n      if (!canHide.value) return (height + extensionHeight)\n\n      return currentScroll.value < scrollThreshold.value || scrollBehavior.value.fullyHide\n        ? (height + extensionHeight)\n        : height\n    })\n\n    useToggleScope(() => !!props.scrollBehavior, () => {\n      watchEffect(() => {\n        if (!canHide.value) {\n          isActive.value = true\n          return\n        }\n\n        if (scrollBehavior.value.inverted) {\n          isActive.value = currentScroll.value > scrollThreshold.value\n          return\n        }\n\n        // If there's not enough scrollable space, don't apply scroll-hide behavior at all\n        // This prevents flickering/bouncing animations on short pages\n        if (!hasEnoughScrollableSpace.value) {\n          isActive.value = true\n          return\n        }\n\n        // Prevent navbar from showing when we reached bottom while scrolling down\n        // This handles the case where scroll momentum causes to hit bottom during hide transition\n        if (reachedBottomWhileScrollingDown.value) {\n          isActive.value = false\n          return\n        }\n\n        // Normal behavior: show when scrolling up (and not at bottom) or above threshold\n        isActive.value = (isScrollingUp.value && !isAtBottom.value) || (currentScroll.value < scrollThreshold.value)\n      })\n    })\n\n    const { ssrBootStyles } = useSsrBoot()\n    const { layoutItemStyles } = useLayoutItem({\n      id: props.name,\n      order: computed(() => parseInt(props.order, 10)),\n      position: toRef(() => props.location),\n      layoutSize: height,\n      elementSize: shallowRef(undefined),\n      active: isActive,\n      absolute: toRef(() => props.absolute),\n    })\n\n    useRender(() => {\n      const toolbarProps = omit(VToolbar.filterProps(props), ['location'])\n\n      return (\n        <VToolbar\n          ref={ vToolbarRef }\n          class={[\n            'v-app-bar',\n            {\n              'v-app-bar--bottom': props.location === 'bottom',\n            },\n            props.class,\n          ]}\n          style={[\n            {\n              ...layoutItemStyles.value,\n              '--v-toolbar-image-opacity': opacity.value,\n              height: undefined,\n              ...ssrBootStyles.value,\n            },\n            props.style,\n          ]}\n          { ...toolbarProps }\n          collapse={ isCollapsed.value }\n          flat={ isFlat.value }\n          v-slots={ slots }\n        />\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VAppBar = InstanceType<typeof VAppBar>\n"
  },
  {
    "path": "packages/vuetify/src/components/VAppBar/VAppBarNavIcon.tsx",
    "content": "// Components\nimport { makeVBtnProps, VBtn } from '@/components/VBtn/VBtn'\n\n// Utilities\nimport { genericComponent, omit, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { VBtnSlots } from '@/components/VBtn/VBtn'\n\nexport const makeVAppBarNavIconProps = propsFactory({\n  ...omit(makeVBtnProps({\n    icon: '$menu',\n    variant: 'text' as const,\n  }), ['spaced']),\n}, 'VAppBarNavIcon')\n\nexport const VAppBarNavIcon = genericComponent<VBtnSlots>()({\n  name: 'VAppBarNavIcon',\n\n  props: makeVAppBarNavIconProps(),\n\n  setup (props, { slots }) {\n    useRender(() => (\n      <VBtn\n        { ...props }\n        class={[\n          'v-app-bar-nav-icon',\n        ]}\n        v-slots={ slots }\n      />\n    ))\n\n    return {}\n  },\n})\n\nexport type VAppBarNavIcon = InstanceType<typeof VAppBarNavIcon>\n"
  },
  {
    "path": "packages/vuetify/src/components/VAppBar/VAppBarTitle.tsx",
    "content": "// Components\nimport { makeVToolbarTitleProps, VToolbarTitle } from '@/components/VToolbar/VToolbarTitle'\n\n// Utilities\nimport { genericComponent, useRender } from '@/util'\n\n// Types\nimport type { VToolbarTitleSlots } from '@/components/VToolbar/VToolbarTitle'\n\nexport const VAppBarTitle = genericComponent<VToolbarTitleSlots>()({\n  name: 'VAppBarTitle',\n\n  props: makeVToolbarTitleProps(),\n\n  setup (props, { slots }) {\n    useRender(() => (\n      <VToolbarTitle\n        { ...props }\n        class=\"v-app-bar-title\"\n        v-slots={ slots }\n      />\n    ))\n\n    return {}\n  },\n})\n\nexport type VAppBarTitle = InstanceType<typeof VAppBarTitle>\n"
  },
  {
    "path": "packages/vuetify/src/components/VAppBar/__tests__/VAppBar.spec.browser.tsx",
    "content": "// Components\nimport { VAppBar } from '..'\nimport { VLayout } from '@/components/VLayout'\nimport { VMain } from '@/components/VMain'\n\n// Utilities\nimport { render, screen, scroll } from '@test'\nimport { ref } from 'vue'\n\ndescribe('VAppBar', () => {\n  it('allows custom height', async () => {\n    const height = ref(64)\n    render(() => (\n      <VLayout>\n        <VAppBar height={ height.value } />\n      </VLayout>\n    ))\n\n    await expect.element(screen.getByCSS('.v-app-bar')).toHaveStyle({ height: '64px' })\n\n    height.value = 128\n    await expect.element(screen.getByCSS('.v-app-bar')).toHaveStyle({ height: '128px' })\n  })\n\n  it('supports density', async () => {\n    const density = ref<any>('default')\n    render(() => (\n      <VLayout>\n        <VAppBar density={ density.value } />\n      </VLayout>\n    ))\n\n    await expect.element(screen.getByCSS('.v-app-bar')).toHaveStyle({ height: '64px' })\n\n    density.value = 'prominent'\n    await expect.element(screen.getByCSS('.v-app-bar')).toHaveStyle({ height: '128px' })\n\n    density.value = 'comfortable'\n    await expect.element(screen.getByCSS('.v-app-bar')).toHaveStyle({ height: '56px' })\n\n    density.value = 'compact'\n    await expect.element(screen.getByCSS('.v-app-bar')).toHaveStyle({ height: '48px' })\n  })\n\n  describe('scroll behavior', () => {\n    it('hides on scroll', async () => {\n      const scrollBehavior = ref('hide')\n      render(() => (\n        <VLayout>\n          <VAppBar scrollBehavior={ scrollBehavior.value } />\n          <VMain style=\"min-height: 200vh;\" />\n        </VLayout>\n      ))\n\n      await expect.element(screen.getByCSS('.v-app-bar')).toBeInViewport()\n\n      await scroll({ top: 500 })\n      await expect.element(screen.getByCSS('.v-app-bar')).not.toBeInViewport()\n\n      await scroll({ top: 250 })\n      await expect.element(screen.getByCSS('.v-app-bar')).toBeInViewport()\n\n      await scroll({ top: 0 })\n      await expect.element(screen.getByCSS('.v-app-bar')).toBeInViewport()\n\n      scrollBehavior.value = 'hide inverted'\n      await expect.element(screen.getByCSS('.v-app-bar')).not.toBeInViewport()\n\n      await scroll({ top: 500 })\n      await expect.element(screen.getByCSS('.v-app-bar')).toBeInViewport()\n\n      await scroll({ top: 250 })\n      await expect.element(screen.getByCSS('.v-app-bar')).not.toBeInViewport()\n\n      await scroll({ top: 0 })\n      await expect.element(screen.getByCSS('.v-app-bar')).not.toBeInViewport()\n    })\n\n    it('should hide correctly when scroll to the bottom', async () => {\n      render(() => (\n        <VLayout>\n          <VAppBar scrollBehavior=\"hide\" />\n          <VMain style=\"min-height: 300px\">\n            { Array.from({ length: 7 }, () => (\n              <div class=\"pa-16 ma-2 w-50 bg-green text-center\">box</div>\n            ))}\n          </VMain>\n        </VLayout>\n      ))\n\n      await expect.element(screen.getByCSS('.v-app-bar')).toBeInViewport()\n\n      await scroll({ top: 1000 })\n      await expect.element(screen.getByCSS('.v-app-bar')).not.toBeInViewport()\n    })\n\n    it('collapses', async () => {\n      render(() => (\n        <VLayout>\n          <VAppBar scrollBehavior=\"scroll\" />\n          <VMain style=\"min-height: 200vh;\" />\n        </VLayout>\n      ))\n\n      await expect.element(screen.getByCSS('.v-app-bar')).toBeInViewport()\n\n      await scroll({ top: 500 })\n      await scroll({ top: 0 })\n      await expect.element(screen.getByCSS('.v-app-bar')).not.toHaveClass('v-toolbar--collapse')\n    })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VAppBar/_variables.scss",
    "content": "@use \"sass:map\";\n@use \"../../styles/settings/variables\";\n@use \"../../styles/tools/functions\";\n\n// VAppBar\n$app-bar-background: rgb(var(--v-theme-surface)) !default;\n$app-bar-border-color: variables.$border-color-root !default;\n$app-bar-border-radius: map.get(variables.$rounded, '0') !default;\n$app-bar-border-style: variables.$border-style-root !default;\n$app-bar-border-thin-width: 0 0 thin !default;\n$app-bar-border-width: 0 !default;\n$app-bar-collapsed-border-radius: 24px !default;\n$app-bar-collapsed-max-width: 112px !default;\n$app-bar-color: functions.theme-color('on-surface', var(--v-high-emphasis-opacity)) !default;\n$app-bar-density-comfortable-padding: 4px !default;\n$app-bar-density-compact-padding: 0 !default;\n$app-bar-density-default-padding: 8px !default;\n$app-bar-elevation: 2 !default;\n$app-bar-flat-elevation: 0 !default;\n$app-bar-image-height: inherit !default;\n$app-bar-image-object-fit: cover !default;\n$app-bar-image-width: inherit !default;\n$app-bar-padding-end: 4px !default;\n$app-bar-padding-start: 4px !default;\n$app-bar-prominent-height: 128px !default;\n$app-bar-rounded-border-radius: variables.$border-radius-root !default;\n$app-bar-scrolled-title-padding-bottom: 9px !default;\n$app-bar-shaped-border-radius: map.get(variables.$rounded, 'xl') $app-bar-border-radius !default;\n$app-bar-title-font-size: functions.map-deep-get(variables.$typography, 'headline-medium', 'size') !default;\n$app-bar-title-padding: 6px 20px !default;\n$app-bar-transition: .2s variables.$standard-easing !default;\n\n// Lists\n$app-bar-border: (\n  $app-bar-border-color,\n  $app-bar-border-style,\n  $app-bar-border-width,\n  $app-bar-border-thin-width\n) !default;\n\n$app-bar-theme: (\n  $app-bar-background,\n  $app-bar-color\n) !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VAppBar/index.ts",
    "content": "export { VAppBar } from './VAppBar'\nexport { VAppBarNavIcon } from './VAppBarNavIcon'\nexport { VAppBarTitle } from './VAppBarTitle'\n"
  },
  {
    "path": "packages/vuetify/src/components/VAutocomplete/VAutocomplete.sass",
    "content": "@use 'sass:selector'\n@use 'sass:math'\n@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n@use '../VSelect/mixins' as *\n\n@include tools.layer('components')\n  .v-autocomplete\n    @include select-compact-chip-label\n\n    .v-field\n      .v-text-field__prefix,\n      .v-text-field__suffix,\n      .v-field__input,\n      .v-field__input > input,\n      &.v-field\n        cursor: text\n\n    .v-field\n      .v-field__input\n        > input\n          flex: 1 1\n\n    .v-field\n      input\n        min-width: $autocomplete-focused-input\n\n      &:not(.v-field--focused)\n        input\n          min-width: 0\n\n    .v-field--dirty\n      .v-autocomplete__selection\n        margin-inline-end: $autocomplete-selection-gap\n\n    .v-autocomplete__selection-text\n      overflow: hidden\n      text-overflow: ellipsis\n      white-space: nowrap\n\n  .v-autocomplete\n    &__content\n      overflow: hidden\n      @include tools.elevation($autocomplete-content-elevation)\n\n      @at-root #{selector.append('.v-menu > .v-overlay__content', &)}\n        @include tools.rounded($autocomplete-content-border-radius)\n\n      > .v-sheet\n        display: flex\n        flex-direction: column\n\n    &__mask\n      background: rgb(var(--v-theme-surface-light))\n\n    &__selection\n      display: inline-flex\n      align-items: center\n      height: calc($input-font-size * $input-line-height)\n      letter-spacing: inherit\n      line-height: inherit\n      max-width: calc(100% - $autocomplete-selection-gap - $autocomplete-input-buffer)\n\n    &__selection\n      &:first-child\n        margin-inline-start: 0\n\n    &--selecting-index\n      .v-autocomplete__selection\n        opacity: var(--v-medium-emphasis-opacity)\n\n        &--selected\n          opacity: 1\n\n      .v-field__input > input\n        caret-color: transparent\n\n    &--single:not(.v-autocomplete--selection-slot)\n      &.v-text-field input\n        flex: 1 1\n        position: absolute\n        left: 0\n        right: 0\n        width: 100%\n        padding-inline: inherit\n\n      .v-field--active\n        input\n          transition: none\n\n      .v-field--dirty:not(.v-field--focused)\n        input\n          opacity: 0\n\n      .v-field--focused\n        .v-autocomplete__selection\n          opacity: 0\n\n    &__menu-icon\n      margin-inline-start: 4px\n      transition: $autocomplete-transition\n\n      .v-autocomplete--active-menu &\n        transform: rotate(180deg)\n"
  },
  {
    "path": "packages/vuetify/src/components/VAutocomplete/VAutocomplete.tsx",
    "content": "// Styles\nimport './VAutocomplete.sass'\n\n// Components\nimport { VAvatar } from '@/components/VAvatar'\nimport { VCheckboxBtn } from '@/components/VCheckbox'\nimport { VChip } from '@/components/VChip'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\nimport { VDivider } from '@/components/VDivider'\nimport { VIcon } from '@/components/VIcon'\nimport { useInputIcon } from '@/components/VInput/InputIcon'\nimport { VList, VListItem, VListSubheader } from '@/components/VList'\nimport { VMenu } from '@/components/VMenu'\nimport { makeSelectProps } from '@/components/VSelect/VSelect'\nimport { VSheet } from '@/components/VSheet'\nimport { makeVTextFieldProps, VTextField } from '@/components/VTextField/VTextField'\nimport { VVirtualScroll } from '@/components/VVirtualScroll'\n\n// Composables\nimport { useScrolling } from '../VSelect/useScrolling'\nimport { useTextColor } from '@/composables/color'\nimport { highlightResult, makeFilterProps, useFilter } from '@/composables/filter'\nimport { useFocusGroups } from '@/composables/focusGroups'\nimport { useForm } from '@/composables/form'\nimport { forwardRefs } from '@/composables/forwardRefs'\nimport { useItems } from '@/composables/list-items'\nimport { useLocale } from '@/composables/locale'\nimport { useMenuActivator } from '@/composables/menuActivator'\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { computed, mergeProps, nextTick, ref, shallowRef, toRef, watch } from 'vue'\nimport {\n  checkPrintable,\n  deepEqual,\n  ensureValidVNode,\n  genericComponent,\n  IN_BROWSER,\n  matchesSelector,\n  noop,\n  omit,\n  propsFactory,\n  useRender,\n  wrapInArray,\n} from '@/util'\n\n// Types\nimport type { PropType, Ref } from 'vue'\nimport type { VFieldSlots } from '@/components/VField/VField'\nimport type { VInputSlots } from '@/components/VInput/VInput'\nimport type { ListItem } from '@/composables/list-items'\nimport type { GenericProps, SelectItemKey } from '@/util'\n\ntype Primitive = string | number | boolean | symbol\n\ntype Val <T, ReturnObject extends boolean> = [T] extends [Primitive]\n  ? T\n  : (ReturnObject extends true ? T : any)\n\ntype Value <T, ReturnObject extends boolean, Multiple extends boolean> =\n  Multiple extends true\n    ? readonly Val<T, ReturnObject>[]\n    : Val<T, ReturnObject> | null\n\nexport const makeVAutocompleteProps = propsFactory({\n  autoSelectFirst: {\n    type: [Boolean, String] as PropType<boolean | 'exact'>,\n  },\n  clearOnSelect: Boolean,\n  search: String,\n\n  ...makeFilterProps({ filterKeys: ['title'] }),\n  ...makeSelectProps(),\n  ...omit(makeVTextFieldProps({\n    modelValue: null,\n    role: 'combobox',\n  }), ['validationValue', 'dirty']),\n}, 'VAutocomplete')\n\ntype ItemType<T> = T extends readonly (infer U)[] ? U : never\n\nexport const VAutocomplete = genericComponent<new <\n  T extends readonly any[],\n  Item = ItemType<T>,\n  ReturnObject extends boolean = false,\n  Multiple extends boolean = false,\n  V extends Value<Item, ReturnObject, Multiple> = Value<Item, ReturnObject, Multiple>\n>(\n  props: {\n    items?: T\n    itemTitle?: SelectItemKey<ItemType<T>>\n    itemValue?: SelectItemKey<ItemType<T>>\n    itemProps?: SelectItemKey<ItemType<T>>\n    returnObject?: ReturnObject\n    multiple?: Multiple\n    modelValue?: V | null\n    'onUpdate:modelValue'?: (value: V) => void\n  },\n  slots: Omit<VInputSlots & VFieldSlots, 'default'> & {\n    item: { item: Item, internalItem: ListItem<Item>, index: number, props: Record<string, unknown> }\n    chip: { item: Item, internalItem: ListItem<Item>, index: number, props: Record<string, unknown> }\n    selection: { item: Item, internalItem: ListItem<Item>, index: number }\n    subheader: { props: Record<string, unknown>, index: number }\n    divider: { props: Record<string, unknown>, index: number }\n    'prepend-item': never\n    'append-item': never\n    'no-data': never\n    'menu-header': { search: Ref<string | undefined>, filteredItems: ListItem<Item>[] }\n    'menu-footer': { search: Ref<string | undefined>, filteredItems: ListItem<Item>[] }\n  }\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VAutocomplete',\n\n  props: makeVAutocompleteProps(),\n\n  emits: {\n    'update:focused': (focused: boolean) => true,\n    'update:search': (value: any) => true,\n    'update:modelValue': (value: any) => true,\n    'update:menu': (value: boolean) => true,\n  },\n\n  setup (props, { slots }) {\n    const { t } = useLocale()\n    const vTextFieldRef = ref<VTextField>()\n    const isFocused = shallowRef(false)\n    const isPristine = shallowRef(true)\n    const listHasFocus = shallowRef(false)\n    const vMenuRef = ref<VMenu>()\n    const vVirtualScrollRef = ref<VVirtualScroll>()\n    const selectionIndex = shallowRef(-1)\n    const _searchLock = shallowRef<string | null>(null)\n    const { items, transformIn, transformOut } = useItems(props)\n    const { textColorClasses, textColorStyles } = useTextColor(() => vTextFieldRef.value?.color)\n    const { InputIcon } = useInputIcon(props)\n    const search = useProxiedModel(props, 'search', '')\n    const model = useProxiedModel(\n      props,\n      'modelValue',\n      [],\n      v => transformIn(v === null ? [null] : wrapInArray(v)),\n      v => {\n        const transformed = transformOut(v)\n        return props.multiple ? transformed : (transformed[0] ?? null)\n      }\n    )\n    const counterValue = computed(() => {\n      return typeof props.counterValue === 'function' ? props.counterValue(model.value)\n        : typeof props.counterValue === 'number' ? props.counterValue\n        : model.value.length\n    })\n    const form = useForm(props)\n    const { filteredItems, getMatches } = useFilter(\n      props,\n      items,\n      () => _searchLock.value ?? (isPristine.value ? '' : search.value))\n\n    const displayItems = computed(() => {\n      if (props.hideSelected && _searchLock.value === null) {\n        return filteredItems.value.filter(filteredItem => !model.value.some(s => s.value === filteredItem.value))\n      }\n      return filteredItems.value\n    })\n\n    const closableChips = toRef(() => props.closableChips && !form.isReadonly.value && !form.isDisabled.value)\n    const hasChips = computed(() => !!(props.chips || slots.chip))\n    const hasSelectionSlot = computed(() => hasChips.value || !!slots.selection)\n\n    const selectedValues = computed(() => model.value.map(selection => selection.props.value))\n\n    const firstSelectableItem = computed(() => displayItems.value.find(x => x.type === 'item' && !x.props.disabled))\n\n    const highlightFirst = computed(() => {\n      const selectFirst = props.autoSelectFirst === true ||\n        (props.autoSelectFirst === 'exact' && search.value === firstSelectableItem.value?.title)\n      return selectFirst &&\n        displayItems.value.length > 0 &&\n        !isPristine.value &&\n        !listHasFocus.value\n    })\n\n    const menuDisabled = computed(() => (\n      (props.hideNoData && !displayItems.value.length) ||\n      form.isReadonly.value || form.isDisabled.value\n    ))\n    const _menu = useProxiedModel(props, 'menu')\n    const menu = computed({\n      get: () => _menu.value,\n      set: v => {\n        if (_menu.value && !v && vMenuRef.value?.ΨopenChildren.size) return\n        if (v && menuDisabled.value) return\n        _menu.value = v\n      },\n    })\n\n    const { menuId, ariaExpanded, ariaControls } = useMenuActivator(props, menu)\n\n    const listRef = ref<VList>()\n    const headerRef = ref<HTMLElement>()\n    const footerRef = ref<HTMLElement>()\n    const listEvents = useScrolling(listRef, vTextFieldRef)\n    const { onTabKeydown } = useFocusGroups({\n      groups: [\n        { type: 'element' as const, contentRef: headerRef },\n        { type: 'list' as const, contentRef: listRef, displayItemsCount: () => displayItems.value.length },\n        { type: 'element' as const, contentRef: footerRef },\n      ],\n      onLeave: () => {\n        menu.value = false\n        vTextFieldRef.value?.focus()\n      },\n    })\n    function onClear (e: MouseEvent) {\n      if (props.openOnClear) {\n        menu.value = true\n      }\n\n      search.value = ''\n    }\n    function onMousedownControl () {\n      if (menuDisabled.value) return\n\n      menu.value = true\n    }\n    function onMousedownMenuIcon (e: MouseEvent) {\n      if (menuDisabled.value) return\n\n      if (isFocused.value) {\n        e.preventDefault()\n        e.stopPropagation()\n      }\n      menu.value = !menu.value\n    }\n    function onMenuKeydown (e: KeyboardEvent) {\n      if (e.key === 'Tab') {\n        onTabKeydown(e)\n      }\n\n      if (listRef.value?.$el.contains(e.target) && (checkPrintable(e) || e.key === 'Backspace')) {\n        vTextFieldRef.value?.focus()\n      }\n    }\n\n    // eslint-disable-next-line complexity\n    function onKeydown (e: KeyboardEvent) {\n      if (form.isReadonly.value) return\n\n      const selectionStart = vTextFieldRef.value?.selectionStart\n      const length = model.value.length\n\n      if (['Enter', 'ArrowDown', 'ArrowUp'].includes(e.key)) {\n        e.preventDefault()\n      }\n\n      if (['Enter', 'ArrowDown'].includes(e.key)) {\n        menu.value = true\n      }\n\n      if (['Escape'].includes(e.key)) {\n        menu.value = false\n      }\n\n      if (\n        highlightFirst.value &&\n        ['Enter', 'Tab'].includes(e.key) &&\n        firstSelectableItem.value &&\n        !model.value.some(({ value }) => value === firstSelectableItem.value!.value)\n      ) {\n        select(firstSelectableItem.value)\n      }\n\n      if (e.key === 'ArrowDown' && highlightFirst.value) {\n        listRef.value?.focus('next')\n      }\n\n      if (['Backspace', 'Delete'].includes(e.key)) {\n        if (\n          !props.multiple &&\n          hasSelectionSlot.value &&\n          model.value.length > 0 &&\n          !search.value\n        ) return select(model.value[0], false)\n\n        if (~selectionIndex.value) {\n          e.preventDefault()\n          const originalSelectionIndex = selectionIndex.value\n          select(model.value[selectionIndex.value], false)\n\n          selectionIndex.value = originalSelectionIndex >= length - 1 ? (length - 2) : originalSelectionIndex\n        } else if (e.key === 'Backspace' && !search.value) {\n          selectionIndex.value = length - 1\n        }\n\n        return\n      }\n\n      if (!props.multiple) return\n\n      if (e.key === 'ArrowLeft') {\n        if (selectionIndex.value < 0 && selectionStart && selectionStart > 0) return\n\n        const prev = selectionIndex.value > -1\n          ? selectionIndex.value - 1\n          : length - 1\n\n        if (model.value[prev]) {\n          selectionIndex.value = prev\n        } else {\n          const searchLength = search.value?.length ?? null\n          selectionIndex.value = -1\n          vTextFieldRef.value?.setSelectionRange(searchLength, searchLength)\n        }\n      } else if (e.key === 'ArrowRight') {\n        if (selectionIndex.value < 0) return\n\n        const next = selectionIndex.value + 1\n\n        if (model.value[next]) {\n          selectionIndex.value = next\n        } else {\n          selectionIndex.value = -1\n          vTextFieldRef.value?.setSelectionRange(0, 0)\n        }\n      } else if (~selectionIndex.value && checkPrintable(e)) {\n        selectionIndex.value = -1\n      }\n    }\n\n    function onChange (e: Event) {\n      if (matchesSelector(vTextFieldRef.value, ':autofill') || matchesSelector(vTextFieldRef.value, ':-webkit-autofill')) {\n        const item = items.value.find(item => item.title === (e.target as HTMLInputElement).value)\n        if (item) {\n          select(item)\n        }\n      }\n    }\n\n    function onAfterEnter () {\n      if (props.eager) {\n        vVirtualScrollRef.value?.calculateVisibleItems()\n      }\n    }\n    function onAfterLeave () {\n      if (isFocused.value) {\n        isPristine.value = true\n        vTextFieldRef.value?.focus()\n      }\n      _searchLock.value = null\n    }\n\n    function onFocusin (e: FocusEvent) {\n      isFocused.value = true\n      setTimeout(() => {\n        listHasFocus.value = true\n      })\n    }\n    function onFocusout (e: FocusEvent) {\n      listHasFocus.value = false\n      if (!vTextFieldRef.value?.$el.contains(e.relatedTarget as Node)) {\n        isFocused.value = false\n      }\n    }\n    function onUpdateModelValue (v: any) {\n      if (v == null || (v === '' && !props.multiple && !hasSelectionSlot.value)) model.value = []\n    }\n\n    function onBlur (e: FocusEvent) {\n      const menuContent = vMenuRef.value?.contentEl\n      if (menuContent?.contains(e.relatedTarget as Node)) {\n        isFocused.value = true\n      }\n    }\n\n    const isSelecting = shallowRef(false)\n\n    /** @param set - null means toggle */\n    function select (item: ListItem | undefined, set: boolean | null = true) {\n      if (!item || item.props.disabled) return\n\n      if (props.multiple) {\n        const index = model.value.findIndex(selection => (props.valueComparator || deepEqual)(selection.value, item.value))\n        const add = set == null ? !~index : set\n\n        if (~index) {\n          const value = add ? [...model.value, item] : [...model.value]\n          value.splice(index, 1)\n          model.value = value\n        } else if (add) {\n          model.value = [...model.value, item]\n        }\n\n        if (props.clearOnSelect) {\n          search.value = ''\n        }\n      } else {\n        const add = set !== false\n        model.value = add ? [item] : []\n        _searchLock.value = isPristine.value ? '' : (search.value ?? '')\n        search.value = add && !hasSelectionSlot.value ? item.title : ''\n\n        // watch for search watcher to trigger\n        nextTick(() => {\n          menu.value = false\n          isPristine.value = true\n        })\n      }\n    }\n\n    watch(isFocused, (val, oldVal) => {\n      if (val === oldVal) return\n\n      if (val) {\n        isSelecting.value = true\n        search.value = (props.multiple || hasSelectionSlot.value) ? '' : String(model.value.at(-1)?.props.title ?? '')\n        isPristine.value = true\n\n        nextTick(() => isSelecting.value = false)\n      } else {\n        if (!props.multiple && search.value == null) model.value = []\n        menu.value = false\n        if (!isPristine.value && search.value) {\n          _searchLock.value = search.value\n        }\n        search.value = ''\n        selectionIndex.value = -1\n      }\n    })\n\n    watch(search, val => {\n      if (!isFocused.value || isSelecting.value) return\n\n      if (val) menu.value = true\n\n      isPristine.value = !val\n    })\n\n    watch(menu, val => {\n      if (!props.hideSelected && val && model.value.length && isPristine.value) {\n        const index = displayItems.value.findIndex(\n          item => model.value.some(s => item.value === s.value)\n        )\n        IN_BROWSER && window.requestAnimationFrame(() => {\n          index >= 0 && vVirtualScrollRef.value?.scrollToIndex(index)\n        })\n      }\n      if (val) _searchLock.value = null\n    })\n\n    watch(items, (newVal, oldVal) => {\n      if (menu.value) return\n\n      if (isFocused.value && !oldVal.length && newVal.length) {\n        menu.value = true\n      }\n    })\n\n    useRender(() => {\n      const hasList = !!(\n        (!props.hideNoData || displayItems.value.length) ||\n        slots['prepend-item'] ||\n        slots['append-item'] ||\n        slots['no-data']\n      )\n      const isDirty = model.value.length > 0\n      const textFieldProps = VTextField.filterProps(props)\n\n      const menuSlotProps = {\n        search,\n        filteredItems: filteredItems.value,\n      }\n\n      return (\n        <VTextField\n          ref={ vTextFieldRef }\n          { ...textFieldProps }\n          v-model={ search.value }\n          onUpdate:modelValue={ onUpdateModelValue }\n          v-model:focused={ isFocused.value }\n          validationValue={ model.externalValue }\n          counterValue={ counterValue.value }\n          dirty={ isDirty }\n          onChange={ onChange }\n          class={[\n            'v-autocomplete',\n            `v-autocomplete--${props.multiple ? 'multiple' : 'single'}`,\n            {\n              'v-autocomplete--active-menu': menu.value,\n              'v-autocomplete--chips': !!props.chips,\n              'v-autocomplete--selection-slot': !!hasSelectionSlot.value,\n              'v-autocomplete--selecting-index': selectionIndex.value > -1,\n            },\n            props.class,\n          ]}\n          style={ props.style }\n          readonly={ form.isReadonly.value }\n          placeholder={ isDirty ? undefined : props.placeholder }\n          onClick:clear={ onClear }\n          onMousedown:control={ onMousedownControl }\n          onKeydown={ onKeydown }\n          onBlur={ onBlur }\n          aria-expanded={ ariaExpanded.value }\n          aria-controls={ ariaControls.value }\n        >\n          {{\n            ...slots,\n            default: ({ id }) => (\n              <>\n                <VMenu\n                  id={ menuId.value }\n                  ref={ vMenuRef }\n                  v-model={ menu.value }\n                  activator=\"parent\"\n                  contentClass=\"v-autocomplete__content\"\n                  disabled={ menuDisabled.value }\n                  eager={ props.eager }\n                  maxHeight={ 310 }\n                  openOnClick={ false }\n                  closeOnContentClick={ false }\n                  onAfterEnter={ onAfterEnter }\n                  onAfterLeave={ onAfterLeave }\n                  { ...props.menuProps }\n                >\n                  <VSheet\n                    elevation={ props.menuElevation }\n                    onFocusin={ onFocusin }\n                    onKeydown={ onMenuKeydown }\n                  >\n                    { slots['menu-header'] && (\n                      <header ref={ headerRef }>\n                        { slots['menu-header'](menuSlotProps) }\n                      </header>\n                    )}\n\n                    { hasList && (\n                      <VList\n                        key=\"autocomplete-list\"\n                        ref={ listRef }\n                        filterable\n                        selected={ selectedValues.value }\n                        selectStrategy={ props.multiple ? 'independent' : 'single-independent' }\n                        onMousedown={ (e: MouseEvent) => e.preventDefault() }\n                        onFocusout={ onFocusout }\n                        tabindex=\"-1\"\n                        selectable={ !!displayItems.value.length }\n                        aria-live=\"polite\"\n                        aria-labelledby={ `${id.value}-label` }\n                        aria-multiselectable={ props.multiple }\n                        color={ props.itemColor ?? props.color }\n                        { ...listEvents }\n                        { ...props.listProps }\n                      >\n                      { slots['prepend-item']?.() }\n\n                      { !displayItems.value.length && !props.hideNoData && (slots['no-data']?.() ?? (\n                        <VListItem key=\"no-data\" title={ t(props.noDataText) } />\n                      ))}\n\n                      <VVirtualScroll ref={ vVirtualScrollRef } renderless items={ displayItems.value } itemKey=\"value\">\n                        { ({ item, index, itemRef }) => {\n                          const itemProps = mergeProps(item.props, {\n                            ref: itemRef,\n                            key: item.value,\n                            active: (highlightFirst.value && item === firstSelectableItem.value) ? true : undefined,\n                            onClick: () => select(item, null),\n                            'aria-posinset': index + 1,\n                            'aria-setsize': displayItems.value.length,\n                          })\n\n                          if (item.type === 'divider') {\n                            return slots.divider?.({ props: item.raw, index }) ?? (\n                              <VDivider { ...item.props } key={ `divider-${index}` } />\n                            )\n                          }\n\n                          if (item.type === 'subheader') {\n                            return slots.subheader?.({ props: item.raw, index }) ?? (\n                              <VListSubheader { ...item.props } key={ `subheader-${index}` } />\n                            )\n                          }\n\n                          return slots.item?.({\n                            item: item.raw,\n                            internalItem: item,\n                            index,\n                            props: itemProps,\n                          }) ?? (\n                            <VListItem { ...itemProps } role=\"option\">\n                            {{\n                              prepend: ({ isSelected }) => (\n                                <>\n                                  { props.multiple && !props.hideSelected ? (\n                                    <VCheckboxBtn\n                                      key={ item.value }\n                                      modelValue={ isSelected }\n                                      ripple={ false }\n                                      tabindex=\"-1\"\n                                      aria-hidden\n                                      onClick={ (event: MouseEvent) => event.preventDefault() }\n                                    />\n                                  ) : undefined }\n\n                                  { item.props.prependAvatar && (\n                                    <VAvatar image={ item.props.prependAvatar } />\n                                  )}\n\n                                  { item.props.prependIcon && (\n                                    <VIcon icon={ item.props.prependIcon } />\n                                  )}\n                                </>\n                              ),\n                              title: () => {\n                                return isPristine.value\n                                  ? item.title\n                                  : highlightResult('v-autocomplete', item.title, getMatches(item)?.title)\n                              },\n                            }}\n                          </VListItem>\n                          )\n                        }}\n                      </VVirtualScroll>\n\n                      { slots['append-item']?.() }\n                    </VList>\n                    )}\n\n                    { slots['menu-footer'] && (\n                      <footer ref={ footerRef }>\n                        { slots['menu-footer'](menuSlotProps) }\n                      </footer>\n                    )}\n                  </VSheet>\n                </VMenu>\n\n                { model.value.map((item, index) => {\n                  function onChipClose (e: Event) {\n                    e.stopPropagation()\n                    e.preventDefault()\n\n                    select(item, false)\n                  }\n\n                  const slotProps = mergeProps(VChip.filterProps(item.props), {\n                    'onClick:close': onChipClose,\n                    onKeydown (e: KeyboardEvent) {\n                      if (e.key !== 'Enter' && e.key !== ' ') return\n\n                      e.preventDefault()\n                      e.stopPropagation()\n\n                      onChipClose(e)\n                    },\n                    onMousedown (e: MouseEvent) {\n                      e.preventDefault()\n                      e.stopPropagation()\n                    },\n                    modelValue: true,\n                    'onUpdate:modelValue': undefined,\n                  })\n\n                  const hasSlot = hasChips.value ? !!slots.chip : !!slots.selection\n                  const slotContent = hasSlot\n                    ? ensureValidVNode(\n                      hasChips.value\n                        ? slots.chip!({ item: item.raw, internalItem: item, index, props: slotProps })\n                        : slots.selection!({ item: item.raw, internalItem: item, index })\n                    )\n                    : undefined\n\n                  if (hasSlot && !slotContent) return undefined\n\n                  return (\n                    <div\n                      key={ item.value }\n                      class={[\n                        'v-autocomplete__selection',\n                        index === selectionIndex.value && [\n                          'v-autocomplete__selection--selected',\n                          textColorClasses.value,\n                        ],\n                      ]}\n                      style={ index === selectionIndex.value ? textColorStyles.value : {} }\n                    >\n                      { hasChips.value ? (\n                        !slots.chip ? (\n                          <VChip\n                            key=\"chip\"\n                            closable={ closableChips.value }\n                            size=\"small\"\n                            text={ item.title }\n                            disabled={ item.props.disabled }\n                            { ...slotProps }\n                          />\n                        ) : (\n                          <VDefaultsProvider\n                            key=\"chip-defaults\"\n                            defaults={{\n                              VChip: {\n                                closable: closableChips.value,\n                                size: 'small',\n                                text: item.title,\n                              },\n                            }}\n                          >\n                            { slotContent }\n                          </VDefaultsProvider>\n                        )\n                      ) : (\n                        slotContent ?? (\n                          <span class=\"v-autocomplete__selection-text\">\n                            { item.title }\n                            { props.multiple && (index < model.value.length - 1) && (\n                              <span class=\"v-autocomplete__selection-comma\">,</span>\n                            )}\n                          </span>\n                        )\n                      )}\n                    </div>\n                  )\n                })}\n              </>\n            ),\n            'append-inner': (...args) => (\n              <>\n                { slots['append-inner']?.(...args) }\n                { props.menuIcon ? (\n                  <VIcon\n                    class=\"v-autocomplete__menu-icon\"\n                    color={ vTextFieldRef.value?.fieldIconColor }\n                    icon={ props.menuIcon }\n                    onMousedown={ onMousedownMenuIcon }\n                    onClick={ noop }\n                    aria-hidden\n                    tabindex=\"-1\"\n                  />\n                ) : undefined }\n                { props.appendInnerIcon && (\n                  <InputIcon\n                    key=\"append-icon\"\n                    name=\"appendInner\"\n                    color={ args[0].iconColor.value }\n                  />\n                )}\n              </>\n            ),\n          }}\n        </VTextField>\n      )\n    })\n\n    return forwardRefs({\n      isFocused,\n      isPristine,\n      menu,\n      search,\n      filteredItems,\n      select,\n    }, vTextFieldRef)\n  },\n})\n\nexport type VAutocomplete = InstanceType<typeof VAutocomplete>\n"
  },
  {
    "path": "packages/vuetify/src/components/VAutocomplete/__tests__/VAutocomplete.spec.browser.tsx",
    "content": "// Components\nimport { VAutocomplete } from '../VAutocomplete'\nimport { VForm } from '@/components/VForm'\n\n// Utilities\nimport { render, screen, showcase, userEvent, waitAnimationFrame, waitIdle } from '@test'\nimport { findAllByRole, queryAllByRole, within } from '@testing-library/vue'\nimport { commands } from 'vitest/browser'\nimport { cloneVNode, ref } from 'vue'\n\nconst variants = ['underlined', 'outlined', 'filled', 'solo', 'plain'] as const\nconst densities = ['default', 'comfortable', 'compact'] as const\nconst items = ['California', 'Colorado', 'Florida', 'Georgia', 'Texas', 'Wyoming'] as const\n\nconst stories = Object.fromEntries(Object.entries({\n  'Default input': <VAutocomplete />,\n  Disabled: <VAutocomplete items={ items } disabled />,\n  Affixes: <VAutocomplete items={ items } prefix=\"prefix\" suffix=\"suffix\" />,\n  'Prepend/append': <VAutocomplete items={ items } prependIcon=\"$vuetify\" appendIcon=\"$vuetify\" />,\n  'Prepend/append inner': <VAutocomplete items={ items } prependInnerIcon=\"$vuetify\" appendInnerIcon=\"$vuetify\" />,\n  Placeholder: <VAutocomplete items={ items } placeholder=\"placeholder\" persistentPlaceholder />,\n}).map(([k, v]) => [k, (\n  <div class=\"d-flex flex-column flex-grow-1\">\n    { variants.map(variant => (\n      densities.map(density => (\n        <div class=\"d-flex align-start\" style=\"gap: 0.4rem; height: 100px;\">\n          { cloneVNode(v, { variant, density, label: `${variant} ${density}` }) }\n          { cloneVNode(v, { variant, density, label: `with value`, modelValue: ['California'] }) }\n          { cloneVNode(v, { variant, density, label: `chips`, chips: true, modelValue: ['California'] }) }\n          <VAutocomplete\n            variant={ variant }\n            density={ density }\n            modelValue={['California']}\n            label=\"selection slot\"\n            { ...v.props }\n          >{{\n            selection: ({ item }) => {\n              return item\n            },\n          }}\n          </VAutocomplete>\n        </div>\n      ))\n    )).flat()}\n  </div>\n)]))\n\ndescribe('VAutocomplete', () => {\n  it('should close only first chip', async () => {\n    const items = ['Item 1', 'Item 2', 'Item 3', 'Item 4']\n\n    const selectedItems = ref(['Item 1', 'Item 2', 'Item 3'])\n\n    render(() => (\n      <VAutocomplete\n        items={ items }\n        v-model={ selectedItems.value }\n        chips\n        closableChips\n        multiple\n      />\n    ))\n\n    const closeButtons = await screen.findAllByTestId('close-chip')\n    await userEvent.click(closeButtons[0])\n\n    expect(selectedItems.value).toEqual(['Item 2', 'Item 3'])\n  })\n\n  it('should have selected chip with array of strings', async () => {\n    const items = ref(['California', 'Colorado', 'Florida'])\n\n    const selectedItems = ref(['California', 'Colorado'])\n\n    const { container } = render(() => (\n      <VAutocomplete\n        v-model={ selectedItems.value }\n        items={ items.value }\n        chips\n        multiple\n        closableChips\n      />\n    ))\n\n    await userEvent.click(container)\n    await commands.waitStable('.v-list')\n\n    const menu = await screen.findByRole('listbox')\n\n    let activeItems = await findAllByRole(menu, 'option', { selected: true })\n    expect(activeItems).toHaveLength(2)\n\n    await userEvent.click(activeItems[0])\n    activeItems = await findAllByRole(menu, 'option', { selected: true })\n    expect(activeItems).toHaveLength(1)\n    expect(selectedItems.value).toEqual(['Colorado'])\n\n    await userEvent.click(await screen.findByTestId('close-chip'))\n    expect(screen.queryAllByTestId('close-chip')).toHaveLength(0)\n    expect(selectedItems.value).toEqual([])\n  })\n\n  it('should have selected chip with return-object', async () => {\n    const items = ref([\n      {\n        title: 'Item 1',\n        value: 'item1',\n      },\n      {\n        title: 'Item 2',\n        value: 'item2',\n      },\n    ])\n\n    const selectedItems = ref([\n      {\n        title: 'Item 1',\n        value: 'item1',\n      },\n    ])\n\n    const { container } = render(() => (\n      <VAutocomplete\n        v-model={ selectedItems.value }\n        items={ items.value }\n        returnObject\n        chips\n        multiple\n      />\n    ))\n\n    await userEvent.click(container)\n    await commands.waitStable('.v-list')\n\n    const menu = await screen.findByRole('listbox')\n\n    let activeItems = await findAllByRole(menu, 'option', { selected: true })\n    expect(activeItems).toHaveLength(1)\n\n    await userEvent.click(activeItems[0])\n    expect(selectedItems.value).toHaveLength(0)\n    activeItems = queryAllByRole(menu, 'option', { selected: true })\n    expect(activeItems).toHaveLength(0)\n  })\n\n  it('should work with objects when using multiple and item-value', async () => {\n    const items = ref([\n      {\n        text: 'Item 1',\n        id: 'item1',\n      },\n      {\n        text: 'Item 2',\n        id: 'item2',\n      },\n      {\n        text: 'Item 3',\n        id: 'item3',\n      },\n    ])\n\n    const selectedItems = ref([\n      {\n        text: 'Item 1',\n        id: 'item1',\n      },\n      {\n        text: 'Item 2',\n        id: 'item2',\n      },\n    ])\n\n    const { container } = render(() => (\n      <VAutocomplete\n        v-model={ selectedItems.value }\n        items={ items.value }\n        multiple\n        returnObject\n        itemTitle=\"text\"\n        itemValue=\"id\"\n      />\n    ))\n\n    await userEvent.click(container)\n    await commands.waitStable('.v-list')\n\n    const menu = await screen.findByRole('listbox')\n\n    const activeItems = await findAllByRole(menu, 'option', { selected: true })\n    expect(activeItems).toHaveLength(2)\n\n    const inputField = await screen.findByCSS('.v-field')\n    expect(inputField).toHaveTextContent('Item 1')\n    expect(inputField).toHaveTextContent('Item 2')\n\n    await userEvent.click(activeItems[0])\n\n    expect(inputField).not.toHaveTextContent('Item 1')\n    expect(inputField).toHaveTextContent('Item 2')\n    expect(selectedItems.value).toEqual([{\n      text: 'Item 2',\n      id: 'item2',\n    }])\n  })\n\n  it('should clear input on blur when using multiple', async () => {\n    const items = ref([\n      {\n        text: '21',\n        id: 'item1',\n      },\n      {\n        text: '22',\n        id: 'item2',\n      },\n      {\n        text: '23',\n        id: 'item3',\n      },\n    ])\n\n    const selectedItems = ref([\n      {\n        text: '21',\n        id: 'item1',\n      },\n      {\n        text: '22',\n        id: 'item2',\n      },\n    ])\n\n    const { container } = render(() => (\n      <VAutocomplete\n        v-model={ selectedItems.value }\n        items={ items.value }\n        multiple\n        itemTitle=\"text\"\n        itemValue=\"text\"\n      />\n    ))\n\n    await userEvent.click(container)\n\n    const menu = await screen.findByRole('listbox')\n\n    const activeItems = await findAllByRole(menu, 'option', { selected: true })\n    expect(activeItems).toHaveLength(2)\n\n    expect(document.activeElement).toBe(within(container).getByCSS('input'))\n\n    const input = within(container).getByCSS('input')\n    expect(input).toHaveValue('')\n  })\n\n  it('should not be clickable when in readonly', async () => {\n    const items = ['Item 1', 'Item 2', 'Item 3', 'Item 4']\n\n    const selectedItems = 'Item 1'\n\n    const { element } = render(() => (\n      <VAutocomplete\n        items={ items }\n        modelValue={ selectedItems }\n        readonly\n      />\n    ))\n\n    await userEvent.click(element)\n\n    expect(screen.queryAllByRole('listbox')).toHaveLength(0)\n    expect(element).not.toHaveClass('v-select--active-menu')\n\n    screen.getByCSS('input').focus()\n    await userEvent.keyboard('{ArrowDown}')\n\n    expect(screen.queryAllByRole('listbox')).toHaveLength(0)\n    expect(element).not.toHaveClass('v-select--active-menu')\n  })\n\n  it('should not be clickable when in readonly form', async () => {\n    const items = ['Item 1', 'Item 2', 'Item 3', 'Item 4']\n\n    const selectedItems = 'Item 1'\n\n    render(() => (\n      <VForm readonly>\n        <VAutocomplete\n          items={ items }\n          modelValue={ selectedItems }\n          readonly\n        />\n      </VForm>\n    ))\n\n    const element = screen.getByCSS('.v-autocomplete')\n\n    await userEvent.click(element)\n    expect(screen.queryAllByRole('listbox')).toHaveLength(0)\n    expect(element).not.toHaveClass('v-select--active-menu')\n\n    screen.getByCSS('input').focus()\n    await userEvent.keyboard('{ArrowDown}')\n\n    expect(screen.queryAllByRole('listbox')).toHaveLength(0)\n    expect(element).not.toHaveClass('v-select--active-menu')\n  })\n\n  it('should remove selection if search is cleared', async () => {\n    const items = ref([\n      { title: 'Item 1', value: 'Item 1' },\n      { title: 'Item 2', value: 'Item 2' },\n    ])\n\n    const selectedItems = ref(null)\n\n    const { element } = render(() => (\n      <VAutocomplete\n        v-model={ selectedItems.value }\n        items={ items.value }\n        returnObject\n      />\n    ))\n\n    await userEvent.click(element)\n    const options = await screen.findAllByRole('option')\n    expect(options).toHaveLength(2)\n\n    await userEvent.click(options[0])\n\n    await userEvent.click(element)\n    await userEvent.keyboard('{ControlOrMeta>}a{/ControlOrMeta}{Backspace}')\n    await userEvent.click(document.body)\n\n    expect(element).not.toHaveTextContent('Item 1')\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/16210\n  it('should return item object as the argument of item-title function', async () => {\n    const items = [\n      { id: 1, name: 'a' },\n      { id: 2, name: 'b' },\n    ]\n\n    const selectedItems = ref(null)\n\n    const itemTitle = vi.fn((item: any) => {\n      return 'Item: ' + JSON.stringify(item)\n    })\n\n    const { element } = render(() => (\n      <VAutocomplete\n        items={ items }\n        v-model={ selectedItems.value }\n        itemTitle={ itemTitle }\n        itemValue=\"id\"\n      />\n    ))\n\n    await userEvent.click(element)\n    await commands.waitStable('.v-list')\n\n    await userEvent.click(screen.getAllByRole('option')[0])\n    expect(selectedItems.value).toBe(1)\n\n    expect(itemTitle).toHaveBeenCalledWith({ id: 1, name: 'a' }, expect.anything())\n\n    expect(element).toHaveTextContent('Item: {\"id\":1,\"name\":\"a\"}')\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/16442\n  describe('null value', () => {\n    it('should allow null as legit itemValue', async () => {\n      const items = [\n        { name: 'Default Language', code: null },\n        { code: 'en-US', name: 'English' },\n        { code: 'de-DE', name: 'German' },\n      ]\n\n      const selectedItems = null\n\n      const { element } = render(() => (\n        <VAutocomplete\n          items={ items }\n          modelValue={ selectedItems }\n          itemTitle=\"name\"\n          itemValue=\"code\"\n        />\n      ))\n\n      expect(element).toHaveTextContent('Default Language')\n    })\n\n    it('should mark input as \"not dirty\" when the v-model is null, but null is not present in the items', async () => {\n      const items = [\n        { code: 'en-US', name: 'English' },\n        { code: 'de-DE', name: 'German' },\n      ]\n\n      render(() => (\n        <VAutocomplete\n          label=\"Language\"\n          items={ items }\n          modelValue={ null }\n          itemTitle=\"name\"\n          itemValue=\"code\"\n        />\n      ))\n\n      expect(screen.getByCSS('.v-field')).not.toHaveClass('v-field--dirty')\n    })\n  })\n\n  describe('hide-selected', () => {\n    it('should hide selected item(s)', async () => {\n      const items = ['Item 1', 'Item 2', 'Item 3', 'Item 4']\n      const selectedItems = ['Item 1', 'Item 2']\n\n      const { element } = render(() => (\n        <VAutocomplete\n          items={ items }\n          modelValue={ selectedItems }\n          hideSelected\n          multiple\n        />\n      ))\n\n      await userEvent.click(element)\n      await commands.waitStable('.v-list')\n\n      const listItems = screen.getAllByRole('option')\n      expect(listItems).toHaveLength(2)\n      expect(listItems[0]).toHaveTextContent('Item 3')\n      expect(listItems[1]).toHaveTextContent('Item 4')\n    })\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/16055\n  it('should not replicate html select hotkeys in v-autocomplete', async () => {\n    const items = ref(['aaa', 'foo', 'faa'])\n\n    const selectedItems = ref(undefined)\n\n    const { element } = render(() => (\n      <VAutocomplete\n        v-model={ selectedItems.value }\n        items={ items.value }\n      />\n    ))\n\n    await userEvent.click(element)\n    await userEvent.keyboard('f')\n    await expect.poll(() => screen.findAllByRole('option')).toHaveLength(2)\n    expect(selectedItems.value).toBeUndefined()\n  })\n\n  it('should conditionally show placeholder', async () => {\n    const { rerender, getByCSS } = render(VAutocomplete, {\n      props: { placeholder: 'Placeholder' },\n    })\n\n    const input = getByCSS('input')\n    expect(input).toHaveAttribute('placeholder', 'Placeholder')\n\n    await rerender({ label: 'Label' })\n    await expect.element(input).toBeVisible()\n    expect(Number(window.getComputedStyle(input, '::placeholder').opacity)).toBe(0)\n\n    input.focus()\n    await waitAnimationFrame()\n    expect(input).toHaveAttribute('placeholder', 'Placeholder')\n    await expect.element(input).toBeVisible()\n    expect(Number(window.getComputedStyle(input, '::placeholder').opacity)).toBeGreaterThan(0.2)\n\n    input.blur()\n    await rerender({ persistentPlaceholder: true })\n    expect(input).toHaveAttribute('placeholder', 'Placeholder')\n    await expect.element(input).toBeVisible()\n    expect(Number(window.getComputedStyle(input, '::placeholder').opacity)).toBeGreaterThan(0.2)\n\n    await rerender({ modelValue: 'Foobar' })\n    expect(input).not.toHaveAttribute('placeholder')\n\n    await rerender({ multiple: true, modelValue: ['Foobar'] })\n    expect(input).not.toHaveAttribute('placeholder')\n  })\n\n  it('should keep TextField focused while selecting items from open menu', async () => {\n    const { element } = render(() => (\n      <VAutocomplete\n        multiple\n        items={['California', 'Colorado', 'Florida', 'Georgia', 'Texas', 'Wyoming']}\n      />\n    ))\n\n    await userEvent.click(element)\n\n    await userEvent.keyboard('{ArrowDown}{ArrowDown}{ArrowDown}c')\n\n    expect(document.activeElement).toBe(within(element).getByCSS('input'))\n  })\n\n  it('should not open menu when closing a chip', async () => {\n    const { element } = render(() => (\n      <VAutocomplete\n        chips\n        closableChips\n        items={['foo', 'bar']}\n        label=\"Autocomplete\"\n        modelValue={['foo', 'bar']}\n        multiple\n      />\n    ))\n\n    expect(screen.queryByRole('listbox')).toBeNull()\n\n    await userEvent.click(screen.getAllByTestId('close-chip')[0])\n    await waitAnimationFrame()\n    expect(screen.queryByRole('listbox')).toBeNull()\n\n    await userEvent.click(screen.getAllByTestId('close-chip')[0])\n    await waitAnimationFrame()\n    expect(screen.queryByRole('listbox')).toBeNull()\n\n    await userEvent.click(element)\n    await screen.findByRole('listbox')\n\n    await userEvent.keyboard('{Escape}')\n    await expect.poll(() => screen.queryByRole('listbox')).toBeNull()\n  })\n\n  describe('auto-select-first', () => {\n    async function setup () {\n      const selectedItems = ref()\n      const { element } = render(() => (\n        <VAutocomplete\n          v-model={ selectedItems.value }\n          items={['California', 'Colorado', 'Florida', 'Georgia', 'Texas', 'Wyoming']}\n          multiple\n          autoSelectFirst\n        />\n      ))\n      const getItems = () => screen.queryAllByRole('option')\n\n      await userEvent.click(element)\n      await commands.waitStable('.v-list')\n      await expect.poll(getItems).toHaveLength(6)\n\n      await userEvent.keyboard('Cal')\n      await expect.poll(() => getItems()[0]).toHaveClass('v-list-item--active')\n\n      return { selectedItems, element, getItems }\n    }\n\n    it('should auto-select-first item when pressing enter', async () => {\n      const { selectedItems, getItems } = await setup()\n\n      await userEvent.keyboard('{Enter}')\n      await expect.poll(getItems).toHaveLength(1)\n      expect(selectedItems.value).toStrictEqual(['California'])\n    })\n\n    it('should auto-select-first item when pressing tab', async () => {\n      const { selectedItems, getItems } = await setup()\n\n      await userEvent.keyboard('{Tab}')\n      await expect.poll(getItems).toHaveLength(0)\n      expect(selectedItems.value).toStrictEqual(['California'])\n    })\n\n    it('should not auto-select-first item when blur', async () => {\n      const { selectedItems, getItems } = await setup()\n\n      await userEvent.click(document.body)\n      await expect.poll(getItems).toHaveLength(0)\n      expect(selectedItems.value).toBeUndefined()\n    })\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/18796\n  // https://github.com/vuetifyjs/vuetify/issues/19235\n  it('should allow deleting single selection via closable-chips', async () => {\n    const selectedItem = ref('California')\n\n    const { getByTestId } = render(() => (\n      <VAutocomplete\n        v-model={ selectedItem.value }\n        chips\n        closableChips\n        items={['California', 'Colorado', 'Florida', 'Georgia', 'Texas', 'Wyoming']}\n      />\n    ))\n\n    await userEvent.click(getByTestId('close-chip'))\n    expect(selectedItem.value).toBeNull()\n  })\n\n  it('should allow deleting multiple selection via closable-chips', async () => {\n    const selectedItem = ref(['California'])\n\n    const { getByTestId } = render(() => (\n      <VAutocomplete\n        v-model={ selectedItem.value }\n        chips\n        closableChips\n        multiple\n        items={['California', 'Colorado', 'Florida', 'Georgia', 'Texas', 'Wyoming']}\n      />\n    ))\n\n    await userEvent.click(getByTestId('close-chip'))\n    expect(selectedItem.value).toHaveLength(0)\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/19261\n  it('should not remove single selection on list item click', async () => {\n    const selectedItem = ref('abc')\n\n    const { element } = render(() => (\n      <VAutocomplete\n        v-model={ selectedItem.value }\n        items={['abc', 'def']}\n      />\n    ))\n\n    await userEvent.click(element)\n    await commands.waitStable('.v-list')\n    const items = await screen.findAllByRole('option')\n    expect(items).toHaveLength(2)\n\n    await userEvent.click(items[0])\n    await waitAnimationFrame()\n    expect(selectedItem.value).toBe('abc')\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/18556\n  it('should show menu if focused and items are added', async () => {\n    const { rerender } = render(VAutocomplete)\n\n    await userEvent.keyboard('{Tab}')\n    await waitAnimationFrame()\n    expect(screen.queryByRole('listbox')).toBeNull()\n\n    await rerender({ items: ['Foo', 'Bar'] })\n    await expect(screen.findByRole('listbox')).resolves.toBeVisible()\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/19346\n  it('should not show menu when focused and existing non-empty items are changed', async () => {\n    const { element, rerender } = render(VAutocomplete, {\n      props: { items: ['Foo', 'Bar'] },\n    })\n\n    await userEvent.click(element)\n    await expect.poll(() => screen.findByRole('listbox')).toBeVisible()\n\n    await userEvent.click(screen.getAllByRole('option')[0])\n    await rerender({ items: ['Foo', 'Bar', 'test', 'test 2'] })\n    await waitIdle()\n    await expect.poll(() => screen.queryByRole('listbox')).toBeNull()\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/17573\n  // When using selection slot or chips, input displayed next to chip/selection slot should be always empty\n  it('should always have empty input value when it is unfocused and when using selection slot or chips', async () => {\n    const items = ['Item 1', 'Item 2', 'Item 3', 'Item 4']\n    const selectedItem = ref('Item 1')\n\n    const { element, getByCSS } = render(() => (\n      <VAutocomplete\n        items={ items }\n        chips\n        v-model={ selectedItem.value }\n      />\n    ))\n\n    await userEvent.click(element)\n    const input = getByCSS('input')\n    expect(input).toHaveValue('')\n\n    // Blur input with a custom search input value\n    await userEvent.keyboard('test')\n    input.blur()\n    await expect.poll(() => selectedItem.value).toBe('Item 1')\n    expect(input).toHaveValue('')\n\n    // Search existing item and click to select\n    await userEvent.click(element)\n    expect(input).toHaveValue('')\n    await userEvent.keyboard('Item 1')\n    await userEvent.click(await screen.findByRole('option'))\n    await expect.poll(() => selectedItem.value).toBe('Item 1')\n  })\n\n  it('should not fire @update:focus twice when clicking bottom of input', async () => {\n    const onFocus = vi.fn()\n    const { element } = render(() => (\n      <VAutocomplete onUpdate:focused={ onFocus } />\n    ))\n\n    await userEvent.click(element, { position: { x: 10, y: 55 } })\n\n    expect(onFocus).toHaveBeenCalledTimes(1)\n  })\n\n  describe('menu-header and menu-footer slots', () => {\n    it('should render menu-header and menu-footer slots', async () => {\n      const { element } = render(() => (\n        <VAutocomplete menu items={['Item #1', 'Item #2']}>\n          {{\n            'menu-header': () => (\n              <div data-testid=\"header-content\">My Header</div>\n            ),\n            'menu-footer': () => (\n              <div data-testid=\"footer-content\">My Footer</div>\n            ),\n          }}\n        </VAutocomplete>\n      ))\n\n      await userEvent.click(element)\n      await commands.waitStable('.v-list')\n\n      expect(screen.getByTestId('header-content')).toHaveTextContent('My Header')\n      expect(screen.getByTestId('footer-content')).toHaveTextContent('My Footer')\n    })\n\n    it('should navigate between header, list, and footer with Tab', async () => {\n      const { element } = render(() => (\n        <VAutocomplete menu items={['Item #1', 'Item #2', 'Item #3']}>\n          {{\n            'menu-header': () => (\n              <div>\n                <button data-testid=\"header-btn\">Header Button</button>\n              </div>\n            ),\n            'menu-footer': () => (\n              <div>\n                <button data-testid=\"footer-btn\">Footer Button</button>\n              </div>\n            ),\n          }}\n        </VAutocomplete>\n      ))\n\n      await userEvent.click(element)\n      await commands.waitStable('.v-list')\n\n      // Navigate to list first\n      await userEvent.keyboard('{ArrowDown}')\n      await expect.poll(() => screen.getByTestId('header-btn')).toHaveFocus()\n\n      // Tab to list\n      await userEvent.keyboard('{Tab}')\n      expect(screen.getAllByRole('option').at(0)).toHaveFocus()\n\n      // Tab to footer\n      await userEvent.keyboard('{Tab}')\n      expect(screen.getByTestId('footer-btn')).toHaveFocus()\n\n      // Shift+Tab back to list\n      await userEvent.keyboard('{Shift>}{Tab}{/Shift}')\n      await expect.poll(() => screen.getAllByRole('option').at(0)).toHaveFocus()\n\n      // Shift+Tab back to header\n      await userEvent.keyboard('{Shift>}{Tab}{/Shift}')\n      expect(screen.getByTestId('header-btn')).toHaveFocus()\n    })\n  })\n\n  showcase({ stories })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VAutocomplete/_variables.scss",
    "content": "@forward '../VInput/variables';\n@use '../../styles/settings';\n\n// Defaults\n$autocomplete-content-border-radius: 4px !default;\n$autocomplete-content-elevation: 2 !default;\n$autocomplete-focused-input: 64px !default;\n$autocomplete-input-buffer: 2px !default;\n$autocomplete-line-height: 1.75 !default;\n$autocomplete-selection-gap: 2px !default;\n$autocomplete-transition: .2s settings.$standard-easing !default;\n$autocomplete-chips-control-min-height: 64px !default;\n$autocomplete-chips-margin-top: null !default;\n$autocomplete-chips-margin-bottom: null !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VAutocomplete/index.ts",
    "content": "export { VAutocomplete } from './VAutocomplete'\n"
  },
  {
    "path": "packages/vuetify/src/components/VAvatar/VAvatar.sass",
    "content": "@use '../../styles/settings'\n@use '../../styles/tools'\n@use './mixins' as *\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-avatar\n    flex: none\n    align-items: center\n    display: inline-flex\n    justify-content: center\n    line-height: $avatar-line-height\n    overflow: hidden\n    position: relative\n    text-align: center\n    transition: 0.2s settings.$standard-easing\n    transition-property: width, height\n    vertical-align: $avatar-vertical-align\n\n    @include avatar-sizes($avatar-sizes)\n    @include avatar-density(('height', 'width'), $avatar-density)\n    @include tools.border($avatar-border...)\n    @include tools.rounded($avatar-border-radius)\n    @include tools.variant($avatar-variants...)\n\n    &--rounded\n      @include tools.rounded($avatar-rounded-border-radius)\n\n    &--start\n      margin-inline-end: $avatar-margin-start\n\n    &--end\n      margin-inline-start: $avatar-margin-end\n\n    .v-img\n      height: 100%\n      width: 100%\n"
  },
  {
    "path": "packages/vuetify/src/components/VAvatar/VAvatar.tsx",
    "content": "// Styles\nimport './VAvatar.sass'\n\n// Components\nimport { VBadge } from '@/components/VBadge/VBadge'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\nimport { VIcon } from '@/components/VIcon'\nimport { VImg } from '@/components/VImg'\n\n// Composables\nimport { makeBorderProps, useBorder } from '@/composables/border'\nimport { makeComponentProps } from '@/composables/component'\nimport { makeDensityProps, useDensity } from '@/composables/density'\nimport { IconValue } from '@/composables/icons'\nimport { makeRoundedProps, useRounded } from '@/composables/rounded'\nimport { makeSizeProps, useSize } from '@/composables/size'\nimport { makeTagProps } from '@/composables/tag'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\nimport { genOverlays, makeVariantProps, useVariant } from '@/composables/variant'\n\n// Utilities\nimport { computed } from 'vue'\nimport { genericComponent, isObject, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\nexport const makeVAvatarProps = propsFactory({\n  badge: {\n    type: [Boolean, Object] as PropType<boolean | VBadge['$props']>,\n    default: false,\n  },\n  start: Boolean,\n  end: Boolean,\n  icon: IconValue,\n  image: String,\n  text: String,\n\n  ...makeBorderProps(),\n  ...makeComponentProps(),\n  ...makeDensityProps(),\n  ...makeRoundedProps(),\n  ...makeSizeProps(),\n  ...makeTagProps(),\n  ...makeThemeProps(),\n  ...makeVariantProps({ variant: 'flat' } as const),\n}, 'VAvatar')\n\nexport type VAvatarSlots = {\n  default: never\n  badge: never\n}\n\nexport const VAvatar = genericComponent<VAvatarSlots>()({\n  name: 'VAvatar',\n\n  props: makeVAvatarProps(),\n\n  setup (props, { slots }) {\n    const { themeClasses } = provideTheme(props)\n    const { borderClasses } = useBorder(props)\n    const { colorClasses, colorStyles, variantClasses } = useVariant(props)\n    const { densityClasses } = useDensity(props)\n    const { roundedClasses } = useRounded(props)\n    const { sizeClasses, sizeStyles } = useSize(props)\n\n    const badgeDotSize = computed(() => {\n      switch (props.size) {\n        case 'x-small': return 8\n        case 'small': return 10\n        case 'large': return 14\n        case 'x-large': return 16\n        default: return 12\n      }\n    })\n\n    const badgeOffset = computed(() => {\n      const { floating } = isObject(props.badge) ? props.badge : {}\n      return (floating ? badgeDotSize.value / 2 : 0) - 1.5\n    })\n\n    const badgeProps = computed(() => {\n      return {\n        bordered: true,\n        dot: !slots.badge,\n        dotSize: badgeDotSize.value,\n        offsetX: badgeOffset.value,\n        offsetY: badgeOffset.value,\n        color: typeof props.badge === 'string' ? props.badge : 'primary',\n        ...isObject(props.badge) ? props.badge : {},\n      }\n    })\n\n    useRender(() => {\n      const avatar = (\n        <props.tag\n          class={[\n            'v-avatar',\n            {\n              'v-avatar--start': props.start,\n              'v-avatar--end': props.end,\n            },\n            themeClasses.value,\n            borderClasses.value,\n            colorClasses.value,\n            densityClasses.value,\n            roundedClasses.value,\n            sizeClasses.value,\n            variantClasses.value,\n            props.class,\n          ]}\n          style={[\n            colorStyles.value,\n            sizeStyles.value,\n            props.style,\n          ]}\n        >\n          { !slots.default ? (\n            props.image\n              ? (<VImg key=\"image\" src={ props.image } alt=\"\" cover />)\n              : props.icon\n                ? (<VIcon key=\"icon\" icon={ props.icon } />)\n                : props.text\n          ) : (\n            <VDefaultsProvider\n              key=\"content-defaults\"\n              defaults={{\n                VImg: {\n                  cover: true,\n                  src: props.image,\n                },\n                VIcon: {\n                  icon: props.icon,\n                },\n              }}\n            >\n              { slots.default() }\n            </VDefaultsProvider>\n          )}\n\n          { genOverlays(false, 'v-avatar') }\n        </props.tag>\n      )\n\n      return props.badge\n        ? (\n          <VBadge\n            { ...badgeProps.value }\n            v-slots={{\n              default: () => avatar,\n              badge: slots.badge,\n            }}\n          />\n        )\n        : avatar\n    })\n\n    return {}\n  },\n})\n\nexport type VAvatar = InstanceType<typeof VAvatar>\n"
  },
  {
    "path": "packages/vuetify/src/components/VAvatar/_mixins.scss",
    "content": "@use 'sass:map';\n@use 'sass:meta';\n@use '../../styles/settings';\n@use './variables' as *;\n\n@mixin avatar-sizes ($map: $avatar-sizes) {\n  @each $sizeName, $multiplier in settings.$size-scales {\n    $size: map.get($map, 'height') + (8 * $multiplier);\n\n    &.v-avatar--size-#{$sizeName} {\n      --v-avatar-height: #{$size};\n    }\n  }\n}\n\n@mixin avatar-density ($properties, $densities) {\n  @each $density, $multiplier in $densities {\n    $value: calc(var(--v-avatar-height) + #{$multiplier * settings.$spacer});\n\n    &.v-avatar--density-#{$density} {\n      @if meta.type-of($properties) == \"list\" {\n        @each $property in $properties {\n          #{$property}: $value;\n        }\n      }\n      @else {\n        #{$properties}: $value;\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VAvatar/_variables.scss",
    "content": "@use \"sass:map\";\n@use '../../styles/settings';\n@use \"../../styles/settings/variables\";\n@use \"../../styles/tools/functions\";\n\n// Defaults\n$avatar-background: rgb(var(--v-theme-surface)) !default;\n$avatar-border-radius: map.get(variables.$rounded, 'circle') !default;\n$avatar-border-color: settings.$border-color-root !default;\n$avatar-border-radius: map.get(settings.$rounded, 0) !default;\n$avatar-border-style: settings.$border-style-root !default;\n$avatar-border-thin-width: thin !default;\n$avatar-border-width: 0 !default;\n$avatar-color: functions.theme-color('on-surface', var(--v-medium-emphasis-opacity)) !default;\n$avatar-density: ('default': 0, 'comfortable': -1, 'compact': -2) !default;\n$avatar-elevation: 1 !default;\n$avatar-height: 40px !default;\n$avatar-line-height: normal !default;\n$avatar-plain-opacity: .62 !default;\n$avatar-rounded-border-radius: variables.$border-radius-root !default;\n$avatar-vertical-align: middle !default;\n$avatar-width: 40px !default;\n$avatar-margin-end: 8px !default;\n$avatar-margin-start: 8px !default;\n\n$avatar-sizes: () !default;\n$avatar-sizes: functions.map-deep-merge(\n  (\n    'height': $avatar-height,\n    'width': $avatar-width\n  ),\n  $avatar-sizes\n);\n\n$avatar-border: (\n  $avatar-border-color,\n  $avatar-border-style,\n  $avatar-border-width,\n  $avatar-border-thin-width\n) !default;\n\n$avatar-variants: (\n  $avatar-background,\n  $avatar-color,\n  $avatar-elevation,\n  $avatar-plain-opacity,\n  'v-avatar'\n) !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VAvatar/index.ts",
    "content": "export { VAvatar } from './VAvatar'\n"
  },
  {
    "path": "packages/vuetify/src/components/VBadge/VBadge.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-badge\n    display: inline-block\n    line-height: $badge-line-height\n\n  .v-badge__badge\n    align-items: center\n    display: inline-flex\n    border-radius: $badge-border-radius\n    font-family: $badge-font-family\n    font-size: $badge-font-size\n    font-weight: $badge-font-weight\n    height: $badge-height\n    justify-content: center\n    min-width: $badge-min-width\n    padding: $badge-padding\n    pointer-events: auto\n    position: absolute\n    text-align: center\n    text-indent: 0\n    transition: $badge-transition\n    white-space: nowrap\n\n    @include tools.theme($badge-theme...)\n\n    &:has(.v-icon)\n      padding: $badge-icon-padding\n\n    .v-badge--bordered &\n      &::after\n        border-radius: inherit\n        border-style: $badge-border-style\n        border-width: $badge-border-width\n        color: $badge-border-color\n        content: ''\n        position: absolute\n        inset: 0\n        transform: $badge-border-transform\n\n    .v-badge--dot &\n      border-radius: $badge-dot-border-radius\n      height: $badge-dot-height\n      min-width: 0\n      padding: 0\n      width: $badge-dot-width\n\n      &::after\n        border-width: $badge-dot-border-width\n\n    .v-badge--inline &\n      position: relative\n      vertical-align: $badge-inline-vertical-align\n\n    .v-icon\n      color: inherit\n      font-size: $badge-font-size\n      margin: $badge-icon-margin\n\n    img,\n    .v-img\n      height: 100%\n      width: 100%\n\n  .v-badge__wrapper\n    display: flex\n    position: relative\n\n    .v-badge--inline &\n      align-items: center\n      display: inline-flex\n      justify-content: center\n      margin: $badge-wrapper-margin\n\n@include tools.layer('trumps')\n  @media (forced-colors: active)\n    .v-badge__badge\n      forced-color-adjust: preserve-parent-color\n      background: highlight\n      color: highlighttext\n"
  },
  {
    "path": "packages/vuetify/src/components/VBadge/VBadge.tsx",
    "content": "// Styles\nimport './VBadge.sass'\n\n// Components\nimport { VIcon } from '@/components/VIcon'\n\n// Composables\nimport { useBackgroundColor, useTextColor } from '@/composables/color'\nimport { makeComponentProps } from '@/composables/component'\nimport { makeDimensionProps, useDimension } from '@/composables/dimensions'\nimport { IconValue } from '@/composables/icons'\nimport { useLocale } from '@/composables/locale'\nimport { makeLocationProps, useLocation } from '@/composables/location'\nimport { makeRoundedProps, useRounded } from '@/composables/rounded'\nimport { makeTagProps } from '@/composables/tag'\nimport { makeThemeProps, useTheme } from '@/composables/theme'\nimport { makeTransitionProps, MaybeTransition } from '@/composables/transition'\n\n// Utilities\nimport { convertToUnit, genericComponent, pickWithRest, propsFactory, useRender } from '@/util'\n\nexport type VBadgeSlots = {\n  default: never\n  badge: never\n}\n\nexport const makeVBadgeProps = propsFactory({\n  bordered: Boolean,\n  color: String,\n  content: [Number, String],\n  dot: Boolean,\n  dotSize: [Number, String],\n  floating: Boolean,\n  icon: IconValue,\n  inline: Boolean,\n  label: {\n    type: String,\n    default: '$vuetify.badge',\n  },\n  max: [Number, String],\n  modelValue: {\n    type: Boolean,\n    default: true,\n  },\n  offsetX: [Number, String],\n  offsetY: [Number, String],\n  textColor: String,\n\n  ...makeComponentProps(),\n  ...makeLocationProps({ location: 'top end' } as const),\n  ...makeRoundedProps(),\n  ...makeTagProps(),\n  ...makeThemeProps(),\n  ...makeTransitionProps({ transition: 'scale-rotate-transition' }),\n  ...makeDimensionProps(),\n}, 'VBadge')\n\nexport const VBadge = genericComponent<VBadgeSlots>()({\n  name: 'VBadge',\n\n  inheritAttrs: false,\n\n  props: makeVBadgeProps(),\n\n  setup (props, ctx) {\n    const { backgroundColorClasses, backgroundColorStyles } = useBackgroundColor(() => props.color)\n    const { roundedClasses } = useRounded(props)\n    const { t } = useLocale()\n    const { textColorClasses, textColorStyles } = useTextColor(() => props.textColor)\n    const { themeClasses } = useTheme()\n\n    const { locationStyles } = useLocation(props, true, side => {\n      const base = props.floating\n        ? (props.dot ? 2 : 4)\n        : (props.dot ? Number(props.dotSize ?? 8) : 12)\n\n      return base + (\n        ['top', 'bottom'].includes(side) ? Number(props.offsetY ?? 0)\n        : ['left', 'right'].includes(side) ? Number(props.offsetX ?? 0)\n        : 0\n      )\n    })\n\n    const { dimensionStyles } = useDimension(props)\n\n    useRender(() => {\n      const value = Number(props.content)\n      const content = (!props.max || isNaN(value)) ? props.content\n        : value <= Number(props.max) ? value\n        : `${props.max}+`\n\n      const [badgeAttrs, attrs] = pickWithRest(ctx.attrs as Record<string, any>, [\n        'aria-atomic',\n        'aria-label',\n        'aria-live',\n        'role',\n        'title',\n      ])\n\n      return (\n        <props.tag\n          class={[\n            'v-badge',\n            {\n              'v-badge--bordered': props.bordered,\n              'v-badge--dot': props.dot,\n              'v-badge--floating': props.floating,\n              'v-badge--inline': props.inline,\n            },\n            props.class,\n          ]}\n          { ...attrs }\n          style={ props.style }\n        >\n          <div class=\"v-badge__wrapper\">\n            { ctx.slots.default?.() }\n\n            <MaybeTransition transition={ props.transition }>\n              <span\n                v-show={ props.modelValue }\n                class={[\n                  'v-badge__badge',\n                  themeClasses.value,\n                  backgroundColorClasses.value,\n                  roundedClasses.value,\n                  textColorClasses.value,\n                ]}\n                style={[\n                  backgroundColorStyles.value,\n                  textColorStyles.value,\n                  dimensionStyles.value,\n                  props.inline ? {} : locationStyles.value,\n                  props.dot && props.dotSize ? {\n                    width: convertToUnit(props.dotSize),\n                    height: convertToUnit(props.dotSize),\n                  } : {},\n                ]}\n                aria-atomic=\"true\"\n                aria-label={ t(props.label, value) }\n                aria-live=\"polite\"\n                role=\"status\"\n                { ...badgeAttrs }\n              >\n                {\n                  props.dot ? undefined\n                  : ctx.slots.badge ? ctx.slots.badge?.()\n                  : props.icon ? <VIcon icon={ props.icon } />\n                  : content\n                }\n              </span>\n            </MaybeTransition>\n          </div>\n        </props.tag>\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VBadge = InstanceType<typeof VBadge>\n"
  },
  {
    "path": "packages/vuetify/src/components/VBadge/__tests__/VBadge.spec.browser.tsx",
    "content": "// Components\nimport { VBadge } from '..'\nimport { VBtn } from '@/components/VBtn'\n\n// Utilities\nimport { gridOn, render, screen, showcase } from '@test'\n\nconst defaultColors = ['success', 'info', 'warning', 'error', 'invalid']\nconst location = ['bottom start', 'bottom end', 'top start', 'top end']\nconst rounded = ['circle', 'pill', 'shaped', 'tr-xl', 'br-lg', 0] // TODO: fix pill\nconst offset = [8, -8, '4', '-4', undefined]\n\nconst props = {\n  bordered: true,\n  color: defaultColors,\n  content: ['content'],\n  dot: true,\n  icon: ['$vuetify'],\n  floating: true,\n  inline: true,\n  location,\n  modelValue: true,\n  rounded,\n}\n\nconst stories = {\n  'Default badge': <VBadge />,\n  'Icon badge': <VBadge icon=\"$vuetify\" />,\n  'Offset badge': gridOn(['offsetX', 'offsetY'], offset, (xy, offset) => (\n      <VBadge { ...{ [xy]: offset } } content=\"0\">\n        <VBtn variant=\"tonal\">\n          { String(offset) }\n        </VBtn>\n      </VBadge>\n  )),\n  Color: gridOn([null], defaultColors, (_, color) => (\n    <VBadge color={ color } content=\"0\">\n      <VBtn variant=\"tonal\">\n        { color }\n      </VBtn>\n    </VBadge>\n  )),\n  'Text color': gridOn([null], defaultColors, (_, color) => (\n    <VBadge color=\"surface-light\" textColor={ color } content=\"0\">\n      <VBtn variant=\"tonal\">\n        { color }\n      </VBtn>\n    </VBadge>\n  )),\n}\n\n// Tests\ndescribe('VBadge', () => {\n  describe('label', () => {\n    it('should have the designated aria label', async () => {\n      render(<VBadge label=\"label-badge\">label</VBadge>)\n      await expect(screen.findByLabelText('label-badge')).resolves.toBeDefined()\n    })\n  })\n\n  describe('max', () => {\n    it('should add a suffix if the content value is greater than the max value', () => {\n      const { container } = render(<VBadge content=\"1000\" max=\"999\" />)\n      expect(container).toHaveTextContent('+')\n    })\n  })\n\n  describe('tag', () => {\n    it('renders the proper tag instead of a div', () => {\n      const { wrapper } = render(<VBadge tag=\"custom-tag\">tag</VBadge>)\n      const el = wrapper.find('custom-tag').element\n      expect(el).toHaveTextContent('tag')\n    })\n  })\n\n  showcase({ stories, props, component: VBadge })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VBadge/_variables.scss",
    "content": "@use '../../styles/settings';\n@use '../../styles/tools';\n\n// VBadge\n$badge-background: rgb(var(--v-theme-surface-variant)) !default;\n$badge-color: tools.theme-color('on-surface-variant', var(--v-high-emphasis-opacity)) !default;\n$badge-border-color: rgb(var(--v-theme-background)) !default;\n$badge-border-radius: 10px !default;\n$badge-border-style: solid !default;\n$badge-border-transform: scale(1.05) !default;\n$badge-border-width: 2px !default;\n$badge-dot-border-radius: 50% !default;\n$badge-dot-border-width: 1.5px !default;\n$badge-dot-height: 9px !default;\n$badge-dot-width: 9px !default;\n$badge-font-family: settings.$body-font-family !default;\n$badge-font-size: .75rem !default;\n$badge-font-weight: 500 !default;\n$badge-height: 1.25rem !default;\n$badge-icon-margin: 0 -2px !default;\n$badge-icon-padding: 4px 6px !default;\n$badge-inline-vertical-align: middle !default;\n$badge-line-height: 1 !default;\n$badge-min-width: 20px !default;\n$badge-padding: 4px 6px !default;\n$badge-transition: .225s settings.$standard-easing !default;\n$badge-wrapper-margin: 0 4px !default;\n\n// Lists\n$badge-theme: (\n  $badge-background,\n  $badge-color\n) !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VBadge/index.ts",
    "content": "export { VBadge } from './VBadge'\n"
  },
  {
    "path": "packages/vuetify/src/components/VBanner/VBanner.sass",
    "content": "@use 'sass:math'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-banner\n    display: grid\n    flex: 1 1\n    font-size: $banner-font-size\n    grid-template-areas: \"prepend content actions\"\n    grid-template-columns: max-content auto max-content\n    grid-template-rows: max-content max-content\n    line-height: $banner-line-height\n    overflow: hidden\n    padding-inline: $banner-padding-inline-start $banner-padding-inline-end\n    padding-top: $banner-padding * 2\n    padding-bottom: $banner-padding * 2\n    position: relative\n    width: $banner-width\n\n    @include tools.border($banner-border...)\n    @include tools.elevation($banner-elevation)\n    @include tools.position($banner-positions)\n    @include tools.rounded($banner-border-radius)\n    @include tools.theme($banner-theme...)\n\n    &--rounded\n      @include tools.rounded($banner-rounded-border-radius)\n\n    &--stacked\n      &:not(.v-banner--one-line)\n        grid-template-areas: \"prepend content\" \". actions\"\n\n      .v-banner-text\n        padding-inline-end: $banner-stacked-padding-inline-end\n\n    @at-root\n      @include tools.density('v-banner', $banner-density) using ($modifier)\n        .v-banner-actions\n          margin-bottom: -($banner-padding + $modifier)\n\n        &.v-banner--one-line\n          padding-top: $banner-padding + $modifier\n          padding-bottom: $banner-padding + $modifier\n\n          .v-banner-actions\n            margin-bottom: 0\n\n        @if ($modifier == 0px)\n          &.v-banner--one-line\n            padding-top: $banner-padding + $modifier + 2\n\n        &.v-banner--two-line\n          padding-top: $banner-padding * 2 + $modifier\n          padding-bottom: $banner-padding * 2 + $modifier\n\n        &.v-banner--three-line\n          padding-top: $banner-padding * 3 + $modifier\n          padding-bottom: $banner-padding * 2 + $modifier\n\n        &:not(.v-banner--one-line),\n        &.v-banner--two-line,\n        &.v-banner--three-line\n          .v-banner-actions\n            margin-top: $banner-action-margin + $modifier\n\n    &--sticky\n      top: $banner-sticky-top\n      z-index: $banner-sticky-z-index\n\n  .v-banner__content\n    align-items: center\n    display: flex\n    grid-area: content\n\n  .v-banner__prepend\n    align-self: flex-start\n    grid-area: prepend\n    margin-inline-end: $banner-prepend-margin-end\n\n  .v-banner-actions\n    align-self: flex-end\n    display: flex\n    flex: 0 1\n    grid-area: actions\n    justify-content: flex-end\n\n    .v-banner--two-line &,\n    .v-banner--three-line &\n      margin-top: $banner-actions-line-margin-top\n\n  .v-banner-text\n    -webkit-box-orient: vertical\n    display: -webkit-box\n    padding-inline-end: $banner-text-padding-end\n    overflow: hidden\n\n    .v-banner--one-line &\n      -webkit-line-clamp: 1\n\n    .v-banner--two-line &\n      -webkit-line-clamp: 2\n\n    .v-banner--three-line &\n      -webkit-line-clamp: 3\n\n    .v-banner--two-line &,\n    .v-banner--three-line &\n      align-self: flex-start\n"
  },
  {
    "path": "packages/vuetify/src/components/VBanner/VBanner.tsx",
    "content": "// Styles\nimport './VBanner.sass'\n\n// Components\nimport { VBannerActions } from './VBannerActions'\nimport { VBannerText } from './VBannerText'\nimport { VAvatar } from '@/components/VAvatar'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\n\n// Composables\nimport { makeBorderProps, useBorder } from '@/composables/border'\nimport { useBackgroundColor } from '@/composables/color'\nimport { makeComponentProps } from '@/composables/component'\nimport { provideDefaults } from '@/composables/defaults'\nimport { makeDensityProps, useDensity } from '@/composables/density'\nimport { makeDimensionProps, useDimension } from '@/composables/dimensions'\nimport { makeDisplayProps, useDisplay } from '@/composables/display'\nimport { makeElevationProps, useElevation } from '@/composables/elevation'\nimport { IconValue } from '@/composables/icons'\nimport { makeLocationProps, useLocation } from '@/composables/location'\nimport { makePositionProps, usePosition } from '@/composables/position'\nimport { makeRoundedProps, useRounded } from '@/composables/rounded'\nimport { makeTagProps } from '@/composables/tag'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\n\n// Utilities\nimport { toRef } from 'vue'\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\nexport type VBannerSlots = {\n  default: never\n  prepend: never\n  text: never\n  actions: never\n}\n\nexport const makeVBannerProps = propsFactory({\n  avatar: String,\n  bgColor: String,\n  color: String,\n  icon: IconValue,\n  lines: String as PropType<'one' | 'two' | 'three'>,\n  stacked: Boolean,\n  sticky: Boolean,\n  text: String,\n\n  ...makeBorderProps(),\n  ...makeComponentProps(),\n  ...makeDensityProps(),\n  ...makeDimensionProps(),\n  ...makeDisplayProps({ mobile: null }),\n  ...makeElevationProps(),\n  ...makeLocationProps(),\n  ...makePositionProps(),\n  ...makeRoundedProps(),\n  ...makeTagProps(),\n  ...makeThemeProps(),\n}, 'VBanner')\n\nexport const VBanner = genericComponent<VBannerSlots>()({\n  name: 'VBanner',\n\n  props: makeVBannerProps(),\n\n  setup (props, { slots }) {\n    const { backgroundColorClasses, backgroundColorStyles } = useBackgroundColor(() => props.bgColor)\n    const { borderClasses } = useBorder(props)\n    const { densityClasses } = useDensity(props)\n    const { displayClasses, mobile } = useDisplay(props)\n    const { dimensionStyles } = useDimension(props)\n    const { elevationClasses } = useElevation(props)\n    const { locationStyles } = useLocation(props)\n    const { positionClasses } = usePosition(props)\n    const { roundedClasses } = useRounded(props)\n\n    const { themeClasses } = provideTheme(props)\n\n    const color = toRef(() => props.color)\n    const density = toRef(() => props.density)\n\n    provideDefaults({ VBannerActions: { color, density } })\n\n    useRender(() => {\n      const hasText = !!(props.text || slots.text)\n      const hasPrependMedia = !!(props.avatar || props.icon)\n      const hasPrepend = !!(hasPrependMedia || slots.prepend)\n\n      return (\n        <props.tag\n          class={[\n            'v-banner',\n            {\n              'v-banner--stacked': props.stacked || mobile.value,\n              'v-banner--sticky': props.sticky,\n              [`v-banner--${props.lines}-line`]: !!props.lines,\n            },\n            themeClasses.value,\n            backgroundColorClasses.value,\n            borderClasses.value,\n            densityClasses.value,\n            displayClasses.value,\n            elevationClasses.value,\n            positionClasses.value,\n            roundedClasses.value,\n            props.class,\n          ]}\n          style={[\n            backgroundColorStyles.value,\n            dimensionStyles.value,\n            locationStyles.value,\n            props.style,\n          ]}\n          role=\"banner\"\n        >\n          { hasPrepend && (\n            <div key=\"prepend\" class=\"v-banner__prepend\">\n              { !slots.prepend ? (\n                <VAvatar\n                  key=\"prepend-avatar\"\n                  color={ color.value }\n                  density={ density.value }\n                  icon={ props.icon }\n                  image={ props.avatar }\n                />\n              ) : (\n                <VDefaultsProvider\n                  key=\"prepend-defaults\"\n                  disabled={ !hasPrependMedia }\n                  defaults={{\n                    VAvatar: {\n                      color: color.value,\n                      density: density.value,\n                      icon: props.icon,\n                      image: props.avatar,\n                    },\n                  }}\n                  v-slots:default={ slots.prepend }\n                />\n              )}\n            </div>\n          )}\n\n          <div class=\"v-banner__content\">\n            { hasText && (\n              <VBannerText key=\"text\">\n                { slots.text?.() ?? props.text }\n              </VBannerText>\n            )}\n\n            { slots.default?.() }\n          </div>\n\n          { slots.actions && (\n            <VBannerActions key=\"actions\" v-slots:default={ slots.actions } />\n          )}\n        </props.tag>\n      )\n    })\n  },\n})\n\nexport type VBanner = InstanceType<typeof VBanner>\n"
  },
  {
    "path": "packages/vuetify/src/components/VBanner/VBannerActions.tsx",
    "content": "// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { provideDefaults } from '@/composables/defaults'\n\n// Utilities\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\nexport const makeVBannerActionsProps = propsFactory({\n  color: String,\n  density: String,\n\n  ...makeComponentProps(),\n}, 'VBannerActions')\n\nexport const VBannerActions = genericComponent()({\n  name: 'VBannerActions',\n\n  props: makeVBannerActionsProps(),\n\n  setup (props, { slots }) {\n    provideDefaults({\n      VBtn: {\n        color: props.color,\n        density: props.density,\n        slim: true,\n        variant: 'text',\n      },\n    })\n\n    useRender(() => (\n      <div\n        class={[\n          'v-banner-actions',\n          props.class,\n        ]}\n        style={ props.style }\n      >\n        { slots.default?.() }\n      </div>\n    ))\n\n    return {}\n  },\n})\n\nexport type VBannerActions = InstanceType<typeof VBannerActions>\n"
  },
  {
    "path": "packages/vuetify/src/components/VBanner/VBannerText.ts",
    "content": "// Utilities\nimport { createSimpleFunctional } from '@/util'\n\nexport const VBannerText = createSimpleFunctional('v-banner-text')\n\nexport type VBannerText = InstanceType<typeof VBannerText>\n"
  },
  {
    "path": "packages/vuetify/src/components/VBanner/_variables.scss",
    "content": "@use 'sass:map';\n@use '../../styles/settings';\n@use '../../styles/tools';\n\n// Defaults\n$banner-action-margin: 20px !default;\n$banner-actions-line-margin-top: 20px !default;\n$banner-background: rgb(var(--v-theme-surface)) !default;\n$banner-border-color: settings.$border-color-root !default;\n$banner-border-radius: map.get(settings.$rounded, 0) !default;\n$banner-border-style: settings.$border-style-root !default;\n$banner-border-thin-width: thin !default;\n$banner-border-width: 0 0 thin 0 !default;\n$banner-color: tools.theme-color('on-surface', var(--v-high-emphasis-opacity)) !default;\n$banner-density: ('default': 0, 'comfortable': -1, 'compact': -2) !default;\n$banner-elevation: 0 !default;\n$banner-font-size: tools.map-deep-get(settings.$typography, 'body-medium', 'size') !default;\n$banner-line-height: tools.map-deep-get(settings.$typography, 'label-large', 'line-height') !default;\n$banner-padding-inline-start: 16px !default;\n$banner-padding-inline-end: 8px !default;\n$banner-padding: 8px !default;\n$banner-positions: absolute fixed sticky !default;\n$banner-prepend-margin-end: 24px !default;\n$banner-rounded-border-radius: settings.$border-radius-root !default;\n$banner-stacked-padding-inline-end: 36px !default;\n$banner-sticky-top: 0 !default;\n$banner-sticky-z-index: 1 !default;\n$banner-text-padding-end: 90px !default;\n$banner-width: 100% !default;\n\n// Mobile\n$banner-mobile-avatar-margin-end: 16px !default;\n$banner-mobile-content-padding-end: 8px !default;\n$banner-mobile-padding-end: 8px !default;\n$banner-mobile-padding-start: 16px !default;\n\n$banner-border: (\n  $banner-border-color,\n  $banner-border-style,\n  $banner-border-width,\n  $banner-border-thin-width\n) !default;\n\n$banner-theme: (\n  $banner-background,\n  $banner-color\n) !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VBanner/index.ts",
    "content": "export { VBanner } from './VBanner'\nexport { VBannerActions } from './VBannerActions'\nexport { VBannerText } from './VBannerText'\n"
  },
  {
    "path": "packages/vuetify/src/components/VBottomNavigation/VBottomNavigation.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-bottom-navigation\n    display: flex\n    max-width: 100%\n    overflow: hidden\n    position: absolute\n    transition: $bottom-navigation-transition\n\n    @include tools.border($bottom-navigation-border...)\n    @include tools.rounded($bottom-navigation-border-radius)\n    @include tools.theme($bottom-navigation-theme...)\n\n    &--active\n      @include tools.elevation($bottom-navigation-elevation)\n\n  .v-bottom-navigation__content\n    display: flex\n    flex: none\n    font-size: $bottom-navigation-content-font-size\n    justify-content: center\n    transition: inherit\n    width: 100%\n\n    .v-bottom-navigation &\n      > .v-btn\n        font-size: inherit\n        height: $bottom-navigation-height\n        max-width: $bottom-navigation-max-width\n        min-width: $bottom-navigation-min-width\n        text-transform: $bottom-navigation-text-transform\n        transition: inherit\n        width: auto\n\n        @include tools.rounded(0)\n\n        .v-btn__content,\n        .v-btn__icon\n          transition: inherit\n\n        .v-btn__icon\n          font-size: $bottom-navigation-icon-font-size\n\n    .v-bottom-navigation--grow &\n      > .v-btn\n        flex-basis: 0\n        flex-grow: 1\n\n    .v-bottom-navigation--shift &\n      .v-btn\n        &:not(.v-btn--selected)\n          .v-btn__content > span\n            transition: inherit\n            opacity: 0\n\n          .v-btn__content\n            transform: $bottom-navigation-shift-icon-transform\n"
  },
  {
    "path": "packages/vuetify/src/components/VBottomNavigation/VBottomNavigation.tsx",
    "content": "// Styles\nimport './VBottomNavigation.sass'\n\n// Components\nimport { VBtnToggleSymbol } from '@/components/VBtnToggle/VBtnToggle'\n\n// Composables\nimport { makeBorderProps, useBorder } from '@/composables/border'\nimport { useBackgroundColor } from '@/composables/color'\nimport { makeComponentProps } from '@/composables/component'\nimport { provideDefaults } from '@/composables/defaults'\nimport { makeDensityProps, useDensity } from '@/composables/density'\nimport { makeElevationProps, useElevation } from '@/composables/elevation'\nimport { makeGroupProps, useGroup } from '@/composables/group'\nimport { makeLayoutItemProps, useLayoutItem } from '@/composables/layout'\nimport { useProxiedModel } from '@/composables/proxiedModel'\nimport { makeRoundedProps, useRounded } from '@/composables/rounded'\nimport { useSsrBoot } from '@/composables/ssrBoot'\nimport { makeTagProps } from '@/composables/tag'\nimport { makeThemeProps, useTheme } from '@/composables/theme'\n\n// Utilities\nimport { computed, toRef } from 'vue'\nimport { convertToUnit, genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { GenericProps } from '@/util'\n\nexport const makeVBottomNavigationProps = propsFactory({\n  baseColor: String,\n  bgColor: String,\n  color: String,\n  grow: Boolean,\n  mode: {\n    type: String,\n    validator: (v: any) => !v || ['horizontal', 'shift'].includes(v),\n  },\n  height: {\n    type: [Number, String],\n    default: 56,\n  },\n  active: {\n    type: Boolean,\n    default: true,\n  },\n\n  ...makeBorderProps(),\n  ...makeComponentProps(),\n  ...makeDensityProps(),\n  ...makeElevationProps(),\n  ...makeRoundedProps(),\n  ...makeLayoutItemProps({ name: 'bottom-navigation' }),\n  ...makeTagProps({ tag: 'header' }),\n  ...makeGroupProps({ selectedClass: 'v-btn--selected' }),\n  ...makeThemeProps(),\n}, 'VBottomNavigation')\n\nexport const VBottomNavigation = genericComponent<new <T>(\n  props: {\n    modelValue?: T\n    'onUpdate:modelValue'?: (value: T) => void\n  },\n  slots: { default: never },\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VBottomNavigation',\n\n  props: makeVBottomNavigationProps(),\n\n  emits: {\n    'update:active': (value: any) => true,\n    'update:modelValue': (value: any) => true,\n  },\n\n  setup (props, { slots }) {\n    const { themeClasses } = useTheme()\n    const { borderClasses } = useBorder(props)\n    const { backgroundColorClasses, backgroundColorStyles } = useBackgroundColor(() => props.bgColor)\n    const { densityClasses } = useDensity(props)\n    const { elevationClasses } = useElevation(props)\n    const { roundedClasses } = useRounded(props)\n    const { ssrBootStyles } = useSsrBoot()\n    const height = computed(() => (\n      Number(props.height) -\n      (props.density === 'comfortable' ? 8 : 0) -\n      (props.density === 'compact' ? 16 : 0)\n    ))\n    const isActive = useProxiedModel(props, 'active', props.active)\n    const { layoutItemStyles } = useLayoutItem({\n      id: props.name,\n      order: computed(() => parseInt(props.order, 10)),\n      position: toRef(() => 'bottom'),\n      layoutSize: toRef(() => isActive.value ? height.value : 0),\n      elementSize: height,\n      active: isActive,\n      absolute: toRef(() => props.absolute),\n    })\n\n    useGroup(props, VBtnToggleSymbol)\n\n    provideDefaults({\n      VBtn: {\n        baseColor: toRef(() => props.baseColor),\n        color: toRef(() => props.color),\n        density: toRef(() => props.density),\n        stacked: toRef(() => props.mode !== 'horizontal'),\n        variant: 'text',\n      },\n    }, { scoped: true })\n\n    useRender(() => {\n      return (\n        <props.tag\n          class={[\n            'v-bottom-navigation',\n            {\n              'v-bottom-navigation--active': isActive.value,\n              'v-bottom-navigation--grow': props.grow,\n              'v-bottom-navigation--shift': props.mode === 'shift',\n            },\n            themeClasses.value,\n            backgroundColorClasses.value,\n            borderClasses.value,\n            densityClasses.value,\n            elevationClasses.value,\n            roundedClasses.value,\n            props.class,\n          ]}\n          style={[\n            backgroundColorStyles.value,\n            layoutItemStyles.value,\n            {\n              height: convertToUnit(height.value),\n            },\n            ssrBootStyles.value,\n            props.style,\n          ]}\n        >\n          { slots.default && (\n            <div class=\"v-bottom-navigation__content\">\n              { slots.default() }\n            </div>\n          )}\n        </props.tag>\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VBottomNavigation = InstanceType<typeof VBottomNavigation>\n"
  },
  {
    "path": "packages/vuetify/src/components/VBottomNavigation/__tests__/VBottomNavigation.spec.browser.tsx",
    "content": "// Components\nimport { VBottomNavigation } from '../VBottomNavigation'\nimport { VLayout } from '@/components/VLayout'\n\n// Utilities\nimport { render, screen } from '@test'\nimport { ref } from 'vue'\n\ndescribe('VBottomNavigation', () => {\n  it('allows custom height', async () => {\n    const height = ref(200)\n    render(() => (\n      <VLayout>\n        <VBottomNavigation height={ height.value } />\n      </VLayout>\n    ))\n    const navigation = screen.getByCSS('.v-bottom-navigation')\n    await expect.element(navigation).toHaveStyle({ height: '200px' })\n    height.value = 150\n    await expect.element(navigation).toHaveStyle({ height: '150px' })\n  })\n\n  it('supports density', async () => {\n    const density = ref<any>('default')\n    render(() => (\n      <VLayout>\n        <VBottomNavigation density={ density.value } />\n      </VLayout>\n    ))\n    const navigation = screen.getByCSS('.v-bottom-navigation')\n    await expect.element(navigation).toHaveStyle({ height: '56px' })\n    density.value = 'comfortable'\n    await expect.element(navigation).toHaveStyle({ height: '48px' })\n    density.value = 'compact'\n    await expect.element(navigation).toHaveStyle({ height: '40px' })\n  })\n\n  it('is not visible when inactive', async () => {\n    const active = ref<boolean>(true)\n    render(() => (\n      <VLayout>\n        <VBottomNavigation active={ active.value } />\n      </VLayout>\n    ))\n    const navigation = screen.getByCSS('.v-bottom-navigation')\n    await expect.element(navigation).toHaveClass('v-bottom-navigation--active')\n    active.value = false\n    await expect.element(navigation).not.toHaveClass('v-bottom-navigation--active')\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VBottomNavigation/_variables.scss",
    "content": "@use 'sass:map';\n@use 'sass:math';\n@use '../../styles/settings';\n@use \"../../styles/settings/variables\";\n@use \"../../styles/tools/functions\";\n\n// VBottomNavigation\n$bottom-navigation-background: rgb(var(--v-theme-surface)) !default;\n$bottom-navigation-border-color: settings.$border-color-root !default;\n$bottom-navigation-border-radius: 0 !default;\n$bottom-navigation-border-radius: map.get(settings.$rounded, '0') !default;\n$bottom-navigation-border-style: settings.$border-style-root !default;\n$bottom-navigation-border-thin-width: thin !default;\n$bottom-navigation-border-width: 0 !default;\n$bottom-navigation-button-color: functions.theme-color('on-surface', var(--v-medium-emphasis-opacity)) !default;\n$bottom-navigation-color: functions.theme-color('on-surface', var(--v-high-emphasis-opacity)) !default;\n$bottom-navigation-content-font-size: functions.map-deep-get(variables.$typography, 'label-small', 'size') !default;\n$bottom-navigation-elevation: 2 !default;\n$bottom-navigation-flat-elevation: 0 !default;\n$bottom-navigation-height: 100% !default;\n$bottom-navigation-icon-font-size: 1.5rem !default;\n$bottom-navigation-max-width: 168px !default;\n$bottom-navigation-min-width: 80px !default;\n$bottom-navigation-opacity: var(--v-medium-emphasis-opacity) !default;\n$bottom-navigation-shift-content-color: functions.theme-color('on-surface', 0) !default;\n$bottom-navigation-shift-icon-top: math.div($bottom-navigation-icon-font-size, 3) !default;\n$bottom-navigation-shift-icon-transform: translateY($bottom-navigation-shift-icon-top) !default;\n$bottom-navigation-text-transform: none !default;\n$bottom-navigation-transition: transform, color, .2s, .1s settings.$standard-easing !default;\n\n// Lists\n$bottom-navigation-border: (\n  $bottom-navigation-border-color,\n  $bottom-navigation-border-style,\n  $bottom-navigation-border-width,\n  $bottom-navigation-border-thin-width\n) !default;\n\n$bottom-navigation-theme: (\n  $bottom-navigation-background,\n  $bottom-navigation-color\n) !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VBottomNavigation/index.ts",
    "content": "export { VBottomNavigation } from './VBottomNavigation'\n"
  },
  {
    "path": "packages/vuetify/src/components/VBottomSheet/VBottomSheet.sass",
    "content": "@use 'sass:map'\n@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n\n// Transition\n@include tools.layer('transitions')\n  .bottom-sheet-transition\n    &-enter-from\n      transform: translateY(100%)\n\n    &-leave-to\n      transform: translateY(100%)\n\n// Block\n@include tools.layer('components')\n  .v-bottom-sheet\n    > .v-bottom-sheet__content.v-overlay__content\n      align-self: flex-end\n      border-radius: 0\n      flex: 0 1 auto\n      left: 0\n      right: 0\n      margin-inline: auto\n      margin-bottom: 0\n      transition-duration: $bottom-sheet-transition-duration\n      width: 100%\n      max-width: 100%\n      overflow: visible\n\n      @include tools.elevation($bottom-sheet-elevation)\n\n      @media (prefers-reduced-motion: reduce)\n        transition: none\n\n      > .v-card,\n      > .v-sheet\n        border-radius: $bottom-sheet-border-radius\n\n    &.v-bottom-sheet--inset\n      max-width: none\n\n      @media #{map.get(settings.$display-breakpoints, 'sm-and-up')}\n        max-width: $bottom-sheet-inset-width\n"
  },
  {
    "path": "packages/vuetify/src/components/VBottomSheet/VBottomSheet.tsx",
    "content": "// Styles\nimport './VBottomSheet.sass'\n\n// Components\nimport { makeVDialogProps, VDialog } from '@/components/VDialog/VDialog'\n\n// Composables\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { OverlaySlots } from '@/components/VOverlay/VOverlay'\n\nexport const makeVBottomSheetProps = propsFactory({\n  inset: Boolean,\n\n  ...makeVDialogProps({\n    transition: 'bottom-sheet-transition',\n  }),\n}, 'VBottomSheet')\n\nexport const VBottomSheet = genericComponent<OverlaySlots>()({\n  name: 'VBottomSheet',\n\n  props: makeVBottomSheetProps(),\n\n  emits: {\n    'update:modelValue': (value: boolean) => true,\n  },\n\n  setup (props, { slots }) {\n    const isActive = useProxiedModel(props, 'modelValue')\n\n    useRender(() => {\n      const dialogProps = VDialog.filterProps(props)\n\n      return (\n        <VDialog\n          { ...dialogProps }\n          contentClass={[\n            'v-bottom-sheet__content',\n            props.contentClass,\n          ]}\n          v-model={ isActive.value }\n          class={[\n            'v-bottom-sheet',\n            {\n              'v-bottom-sheet--inset': props.inset,\n            },\n            props.class,\n          ]}\n          style={ props.style }\n          v-slots={ slots }\n        />\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VBottomSheet = InstanceType<typeof VBottomSheet>\n"
  },
  {
    "path": "packages/vuetify/src/components/VBottomSheet/__tests__/VBottomSheet.spec.browser.tsx",
    "content": "// Components\nimport { VBottomSheet } from '..'\n\n// Utilities\nimport { render, screen } from '@test'\nimport { ref } from 'vue'\n\ndescribe('VBottomSheet', () => {\n  it('renders properly with default props', async () => {\n    render(() => (\n      <VBottomSheet modelValue>\n        <div>Content inside bottom sheet</div>\n      </VBottomSheet>\n    ))\n\n    const bottomSheet = screen.getByCSS('.v-bottom-sheet')\n    await expect.element(bottomSheet).toBeInViewport()\n    await expect.element(bottomSheet).not.toHaveClass('v-bottom-sheet--inset')\n    await expect.element(bottomSheet).toHaveTextContent('Content inside bottom sheet')\n  })\n\n  it('applies inset class when inset prop is true', async () => {\n    const inset = ref<boolean>(false)\n\n    render(() => (\n      <VBottomSheet modelValue inset={ inset.value }>\n        <div>Content inside bottom sheet</div>\n      </VBottomSheet>\n    ))\n\n    const bottomSheet = screen.getByCSS('.v-bottom-sheet')\n    await expect.element(bottomSheet).not.toHaveClass('v-bottom-sheet--inset')\n\n    inset.value = true\n    await expect.element(bottomSheet).toHaveClass('v-bottom-sheet--inset')\n  })\n\n  it('applies custom styles and classes', async () => {\n    render(() => (\n      <VBottomSheet modelValue class=\"custom-class\" style=\"color: red;\">\n        <div>Custom styles</div>\n      </VBottomSheet>\n    ))\n    const bottomSheet = screen.getByCSS('.v-bottom-sheet')\n    await expect.element(bottomSheet).toHaveClass('custom-class')\n    await expect.element(bottomSheet).toHaveStyle({ color: 'rgb(255, 0, 0)' })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VBottomSheet/_variables.scss",
    "content": "@use '../../styles/settings';\n\n$bottom-sheet-elevation: 4 !default;\n$bottom-sheet-inset-width: 70% !default;\n$bottom-sheet-border-radius: 0 !default;\n$bottom-sheet-transition-duration: .2s !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VBottomSheet/index.ts",
    "content": "export { VBottomSheet } from './VBottomSheet'\n"
  },
  {
    "path": "packages/vuetify/src/components/VBreadcrumbs/VBreadcrumbs.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-breadcrumbs\n    display: flex\n    align-items: center\n    line-height: $breadcrumbs-line-height\n    padding: $breadcrumbs-padding-y $breadcrumbs-padding-x\n\n    &--rounded\n      @include tools.rounded($breadcrumbs-rounded-border-radius)\n\n    @at-root\n      @include tools.density('v-breadcrumbs', $breadcrumbs-density) using ($modifier)\n        padding-top: #{$breadcrumbs-padding-y + $modifier}\n        padding-bottom: #{$breadcrumbs-padding-y + $modifier}\n\n  .v-breadcrumbs__prepend\n    align-items: center\n    display: inline-flex\n\n  .v-breadcrumbs-item\n    align-items: center\n    color: inherit\n    display: inline-flex\n    padding: $breadcrumbs-item-padding\n    text-decoration: none\n    vertical-align: $breadcrumbs-vertical-align\n\n    &--disabled\n      opacity: $breadcrumbs-item-disabled-opacity\n      pointer-events: none\n\n    &--link\n      color: inherit\n      text-decoration: none\n\n    &--link:hover\n      text-decoration: $breadcrumbs-item-link-text-decoration\n\n    .v-icon\n      font-size: $breadcrumbs-item-icon-font-size\n      margin-inline: $breadcrumbs-item-icon-margin-inline-start $breadcrumbs-item-icon-margin-inline-end\n\n  .v-breadcrumbs-divider\n    display: inline-block\n    padding: $breadcrumbs-divider-padding\n    vertical-align: $breadcrumbs-vertical-align\n"
  },
  {
    "path": "packages/vuetify/src/components/VBreadcrumbs/VBreadcrumbs.tsx",
    "content": "// Styles\nimport './VBreadcrumbs.sass'\n\n// Components\nimport { VBreadcrumbsDivider } from './VBreadcrumbsDivider'\nimport { VBreadcrumbsItem } from './VBreadcrumbsItem'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\nimport { VIcon } from '@/components/VIcon'\n\n// Composables\nimport { useBackgroundColor } from '@/composables/color'\nimport { makeComponentProps } from '@/composables/component'\nimport { provideDefaults } from '@/composables/defaults'\nimport { makeDensityProps, useDensity } from '@/composables/density'\nimport { IconValue } from '@/composables/icons'\nimport { makeRoundedProps, useRounded } from '@/composables/rounded'\nimport { makeTagProps } from '@/composables/tag'\n\n// Utilities\nimport { computed, toRef } from 'vue'\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { LinkProps } from '@/composables/router'\nimport type { GenericProps } from '@/util'\n\nexport type InternalBreadcrumbItem = Partial<LinkProps> & {\n  title: string\n  disabled?: boolean\n}\n\nexport type BreadcrumbItem = string | InternalBreadcrumbItem\n\nexport const makeVBreadcrumbsProps = propsFactory({\n  activeClass: String,\n  activeColor: String,\n  bgColor: String,\n  color: String,\n  disabled: Boolean,\n  divider: {\n    type: String,\n    default: '/',\n  },\n  icon: IconValue,\n  items: {\n    type: Array as PropType<readonly BreadcrumbItem[]>,\n    default: () => ([]),\n  },\n\n  ...makeComponentProps(),\n  ...makeDensityProps(),\n  ...makeRoundedProps(),\n  ...makeTagProps({ tag: 'ul' }),\n}, 'VBreadcrumbs')\n\nexport const VBreadcrumbs = genericComponent<new <T extends BreadcrumbItem>(\n  props: {\n    items?: T[]\n  },\n  slots: {\n    prepend: never\n    title: { item: InternalBreadcrumbItem, index: number }\n    divider: { item: T, index: number }\n    item: { item: InternalBreadcrumbItem, index: number }\n    default: never\n  }\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VBreadcrumbs',\n\n  props: makeVBreadcrumbsProps(),\n\n  setup (props, { slots }) {\n    const { backgroundColorClasses, backgroundColorStyles } = useBackgroundColor(() => props.bgColor)\n    const { densityClasses } = useDensity(props)\n    const { roundedClasses } = useRounded(props)\n\n    provideDefaults({\n      VBreadcrumbsDivider: {\n        divider: toRef(() => props.divider),\n      },\n      VBreadcrumbsItem: {\n        activeClass: toRef(() => props.activeClass),\n        activeColor: toRef(() => props.activeColor),\n        color: toRef(() => props.color),\n        disabled: toRef(() => props.disabled),\n      },\n    })\n\n    const items = computed(() => props.items.map(item => {\n      return typeof item === 'string' ? { item: { title: item }, raw: item } : { item, raw: item }\n    }))\n\n    useRender(() => {\n      const hasPrepend = !!(slots.prepend || props.icon)\n\n      return (\n        <props.tag\n          class={[\n            'v-breadcrumbs',\n            backgroundColorClasses.value,\n            densityClasses.value,\n            roundedClasses.value,\n            props.class,\n          ]}\n          style={[\n            backgroundColorStyles.value,\n            props.style,\n          ]}\n        >\n          { hasPrepend && (\n            <li key=\"prepend\" class=\"v-breadcrumbs__prepend\">\n              { !slots.prepend ? (\n                <VIcon\n                  key=\"prepend-icon\"\n                  start\n                  icon={ props.icon }\n                />\n              ) : (\n                <VDefaultsProvider\n                  key=\"prepend-defaults\"\n                  disabled={ !props.icon }\n                  defaults={{\n                    VIcon: {\n                      icon: props.icon,\n                      start: true,\n                    },\n                  }}\n                  v-slots:default={ slots.prepend }\n                />\n              )}\n            </li>\n          )}\n\n          { items.value.map(({ item, raw }, index, array) => (\n            <>\n              { slots.item?.({ item, index }) ?? (\n                <VBreadcrumbsItem\n                  key={ index }\n                  disabled={ index >= array.length - 1 }\n                  { ...(typeof item === 'string' ? { title: item } : item) }\n                  v-slots={{\n                    default: slots.title ? () => slots.title?.({ item, index }) : undefined,\n                  }}\n                />\n              )}\n\n              { index < array.length - 1 && (\n                <VBreadcrumbsDivider\n                  v-slots={{\n                    default: slots.divider ? () => slots.divider?.({ item: raw, index }) : undefined,\n                  }}\n                />\n              )}\n            </>\n          ))}\n\n          { slots.default?.() }\n        </props.tag>\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VBreadcrumbs = InstanceType<typeof VBreadcrumbs>\n"
  },
  {
    "path": "packages/vuetify/src/components/VBreadcrumbs/VBreadcrumbsDivider.tsx",
    "content": "// Composables\nimport { makeComponentProps } from '@/composables/component'\n\n// Utilities\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\nexport const makeVBreadcrumbsDividerProps = propsFactory({\n  divider: [Number, String],\n\n  ...makeComponentProps(),\n}, 'VBreadcrumbsDivider')\n\nexport const VBreadcrumbsDivider = genericComponent()({\n  name: 'VBreadcrumbsDivider',\n\n  props: makeVBreadcrumbsDividerProps(),\n\n  setup (props, { slots }) {\n    useRender(() => (\n      <li\n        aria-hidden=\"true\"\n        class={[\n          'v-breadcrumbs-divider',\n          props.class,\n        ]}\n        style={ props.style }\n      >\n        { slots?.default?.() ?? props.divider }\n      </li>\n    ))\n\n    return {}\n  },\n})\n\nexport type VBreadcrumbsDivider = InstanceType<typeof VBreadcrumbsDivider>\n"
  },
  {
    "path": "packages/vuetify/src/components/VBreadcrumbs/VBreadcrumbsItem.tsx",
    "content": "// Composables\nimport { useTextColor } from '@/composables/color'\nimport { makeComponentProps } from '@/composables/component'\nimport { makeDimensionProps, useDimension } from '@/composables/dimensions'\nimport { makeRouterProps, useLink } from '@/composables/router'\nimport { makeTagProps } from '@/composables/tag'\n\n// Utilities\nimport { computed } from 'vue'\nimport { genericComponent, pick, propsFactory, useRender } from '@/util'\n\nexport const makeVBreadcrumbsItemProps = propsFactory({\n  active: Boolean,\n  activeClass: String,\n  activeColor: String,\n  color: String,\n  disabled: Boolean,\n  title: String,\n\n  ...makeComponentProps(),\n  ...pick(makeDimensionProps(), ['width', 'maxWidth']),\n  ...makeRouterProps(),\n  ...makeTagProps({ tag: 'li' }),\n}, 'VBreadcrumbsItem')\n\nexport const VBreadcrumbsItem = genericComponent()({\n  name: 'VBreadcrumbsItem',\n\n  props: makeVBreadcrumbsItemProps(),\n\n  setup (props, { slots, attrs }) {\n    const link = useLink(props, attrs)\n    const isActive = computed(() => props.active || link.isActive?.value)\n    const { dimensionStyles } = useDimension(props)\n\n    const { textColorClasses, textColorStyles } = useTextColor(\n      () => isActive.value ? props.activeColor : props.color\n    )\n\n    useRender(() => {\n      return (\n        <props.tag\n          class={[\n            'v-breadcrumbs-item',\n            {\n              'v-breadcrumbs-item--active': isActive.value,\n              'v-breadcrumbs-item--disabled': props.disabled,\n              [`${props.activeClass}`]: isActive.value && props.activeClass,\n            },\n            textColorClasses.value,\n            props.class,\n          ]}\n          style={[\n            textColorStyles.value,\n            dimensionStyles.value,\n            props.style,\n          ]}\n          aria-current={ isActive.value ? 'page' : undefined }\n        >\n          { !link.isLink.value ? slots.default?.() ?? props.title : (\n            <a\n              class=\"v-breadcrumbs-item--link\"\n              onClick={ link.navigate.value }\n              { ...link.linkProps }\n            >\n              { slots.default?.() ?? props.title }\n            </a>\n          )}\n        </props.tag>\n      )\n    })\n    return {}\n  },\n})\n\nexport type VBreadcrumbsItem = InstanceType<typeof VBreadcrumbsItem>\n"
  },
  {
    "path": "packages/vuetify/src/components/VBreadcrumbs/__tests__/VBreadcrumbs.spec.browser.tsx",
    "content": "// Components\nimport { VBreadcrumbs } from '../VBreadcrumbs'\nimport { VBreadcrumbsDivider } from '../VBreadcrumbsDivider'\nimport { VBreadcrumbsItem } from '../VBreadcrumbsItem'\n\n// Utilities\nimport { render, screen } from '@test'\n\ndescribe('VBreadcrumbs', () => {\n  it('should use item slot', async () => {\n    render(() => (\n      <VBreadcrumbs items={['hello', 'world']}>\n        {{\n          title: ({ item }: any) => `${item.title}!`,\n        }}\n      </VBreadcrumbs>\n    ))\n\n    const items = screen.getAllByText(/hello!|world!/i)\n    expect(items).toHaveLength(2)\n    await expect.element(items[0]).toHaveTextContent('hello!')\n  })\n\n  it('should use divider slot', () => {\n    render(() => (\n      <VBreadcrumbs items={['hello', 'world']}>\n        {{\n          divider: () => '-',\n        }}\n      </VBreadcrumbs>\n    ))\n\n    expect(screen.getByText('-')).toBeVisible()\n  })\n\n  it('should use bg-color', () => {\n    render(() => (\n      <VBreadcrumbs items={['hello', 'world']} bgColor=\"primary\"></VBreadcrumbs>\n    ))\n    expect(screen.getByCSS('.v-breadcrumbs')).toHaveClass('bg-primary')\n  })\n\n  it('should use color', () => {\n    render(() => (\n      <VBreadcrumbs items={['hello', 'world']} color=\"primary\"></VBreadcrumbs>\n    ))\n\n    const items = screen.getAllByCSS('.v-breadcrumbs-item')\n    items.forEach(item => expect(item).toHaveClass('text-primary'))\n  })\n\n  it('should render link if href is set', () => {\n    render(() => (\n      <VBreadcrumbs\n        items={[\n          { title: 'hello', href: '/hello' },\n          { title: 'world', href: '/world' },\n        ]}\n      ></VBreadcrumbs>\n    ))\n\n    const links = screen.getAllByCSS('a.v-breadcrumbs-item--link')\n    links.forEach(link => expect(link).toHaveAttribute('href'))\n  })\n\n  it('should apply active color', async () => {\n    render(() => (\n      <VBreadcrumbs activeColor=\"primary\">\n        <VBreadcrumbsItem active title=\"hello\"></VBreadcrumbsItem>\n        <VBreadcrumbsItem title=\"world\" to=\"/world\"></VBreadcrumbsItem>\n      </VBreadcrumbs>\n    ))\n    // Initial check for the active color class\n    expect(screen.getByCSS('.v-breadcrumbs-item.text-primary')).toBeVisible()\n\n    const items = screen.getAllByCSS('.v-breadcrumbs-item')\n    await expect.element(items[0]).toHaveClass('text-primary')\n  })\n  it('should disable last item by default if using items prop', async () => {\n    render(() => (\n      <VBreadcrumbs items={['foo', 'bar']}></VBreadcrumbs>\n    ))\n\n    const lastItem = screen.getByCSS('.v-breadcrumbs-item:last-child')\n    await expect.element(lastItem).toHaveClass('v-breadcrumbs-item--disabled')\n  })\n\n  it('should override last item disabled by default', async () => {\n    render(() => (\n      <VBreadcrumbs\n        items={['foo', { title: 'bar', disabled: false }]}\n      ></VBreadcrumbs>\n    ))\n\n    const lastItem = screen.getByCSS('.v-breadcrumbs-item:last-child')\n    await expect.element(lastItem).not.toHaveClass('v-breadcrumbs-item--disabled')\n  })\n\n  it('should provide default divider', () => {\n    render(() => (\n      <VBreadcrumbs>\n        <VBreadcrumbsItem title=\"foo\"></VBreadcrumbsItem>\n        <VBreadcrumbsDivider></VBreadcrumbsDivider>\n        <VBreadcrumbsItem title=\"bar\"></VBreadcrumbsItem>\n        <VBreadcrumbsDivider divider=\"-\"></VBreadcrumbsDivider>\n        <VBreadcrumbsItem title=\"fizz\"></VBreadcrumbsItem>\n      </VBreadcrumbs>\n    ))\n\n    expect(screen.getByText('/')).toBeVisible()\n    expect(screen.getByText('-')).toBeVisible()\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VBreadcrumbs/_variables.scss",
    "content": "@use '../../styles/settings';\n@use '../../styles/tools';\n\n// Defaults\n$breadcrumbs-density: ('default': 0, 'comfortable': -1, 'compact': -2) !default;\n$breadcrumbs-divider-padding: 0 8px !default;\n$breadcrumbs-item-disabled-opacity: var(--v-disabled-opacity) !default;\n$breadcrumbs-item-icon-font-size: tools.map-deep-get(settings.$typography, 'body-large', 'size') !default;\n$breadcrumbs-item-icon-margin-inline-end: 2px !default;\n$breadcrumbs-item-icon-margin-inline-start: -4px !default;\n$breadcrumbs-item-link-text-decoration: underline !default;\n$breadcrumbs-item-padding: 0 4px !default;\n$breadcrumbs-line-height: tools.map-deep-get(settings.$typography, 'body-large', 'line-height') !default;\n$breadcrumbs-padding-y: 16px !default;\n$breadcrumbs-padding-x: 12px !default;\n$breadcrumbs-rounded-border-radius: settings.$border-radius-root !default;\n$breadcrumbs-vertical-align: middle !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VBreadcrumbs/index.ts",
    "content": "export { VBreadcrumbs } from './VBreadcrumbs'\nexport { VBreadcrumbsItem } from './VBreadcrumbsItem'\nexport { VBreadcrumbsDivider } from './VBreadcrumbsDivider'\n"
  },
  {
    "path": "packages/vuetify/src/components/VBtn/VBtn.sass",
    "content": "@use 'sass:math'\n@use 'sass:map'\n@use 'sass:meta'\n@use '../../styles/settings'\n@use '../../styles/tools'\n@use './mixins' as *\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-btn\n    align-items: center\n    border-radius: $button-border-radius\n    display: inline-flex\n    flex-direction: row\n    font-weight: $button-font-weight\n    justify-content: center\n    letter-spacing: $button-text-letter-spacing\n    line-height: $button-line-height\n    max-width: $button-max-width\n    outline: none\n    position: relative\n    text-decoration: none\n    text-indent: $button-text-letter-spacing\n    text-transform: $button-text-transform\n    transition-property: $button-transition-property\n    transition-duration: 0.28s\n    transition-timing-function: settings.$standard-easing\n    user-select: none\n    vertical-align: $button-vertical-align\n    flex-shrink: 0\n\n    .v-locale--is-rtl &\n      @if meta.type-of($button-text-letter-spacing) == 'number'\n        text-indent: -1 * $button-text-letter-spacing\n\n    @at-root\n      @include button-sizes()\n      @include button-density('height', $button-density)\n\n    @include tools.border($button-border...)\n    @include tools.position($button-positions)\n    @include tools.states('.v-btn__overlay')\n    @include tools.variant($button-variants...)\n\n    @supports selector(:focus-visible)\n      &::after\n        pointer-events: none\n        border: 2px solid currentColor\n        border-radius: inherit\n        opacity: 0\n        transition: opacity .2s ease-in-out\n        @include tools.absolute(true)\n\n      &:focus-visible::after\n        opacity: calc(.25 * var(--v-theme-overlay-multiplier))\n\n    &--icon\n      border-radius: $button-icon-border-radius\n      min-width: 0\n      padding: 0\n\n      // ensure that default\n      // v-icon size is 24px\n      &.v-btn--size-default\n        --v-btn-size: #{$button-icon-font-size}\n\n      @at-root &\n        @include button-density(('width', 'height'), $button-icon-density)\n\n    &--elevated\n      &:hover,\n      &:focus\n        @include tools.elevation(map.get($button-elevation, 'hover'))\n\n      &:active\n        @include tools.elevation(map.get($button-elevation, 'active'))\n\n    &--flat\n      box-shadow: none\n\n    &--block\n      display: flex\n      flex: 1 0 auto\n      min-width: 100%\n\n    &--spaced\n      .v-btn__content\n        flex-grow: 1\n\n      &.v-btn--spaced-start > .v-btn__content\n        justify-content: end\n\n      &.v-btn--spaced-end > .v-btn__content\n        justify-content: start\n\n    &--disabled\n      pointer-events: none\n\n      @if ($button-colored-disabled)\n        opacity: $button-disabled-opacity\n        &:hover\n          opacity: $button-disabled-opacity\n      @else\n        opacity: 1\n        @include tools.layer('trumps')\n          color: tools.theme-color('on-surface', $button-disabled-opacity)\n\n      &.v-btn--variant-elevated,\n      &.v-btn--variant-flat\n        box-shadow: none\n\n        @if ($button-colored-disabled)\n          opacity: 1\n          color: tools.theme-color('on-surface', $button-disabled-opacity)\n          background: rgb(var(--v-theme-surface))\n        @else\n          @include tools.layer('trumps')\n            background: rgb(var(--v-theme-surface))\n\n        .v-btn__overlay\n          // __overlay uses currentColor, so we need to divide\n          // by the text opacity to get the correct value\n          opacity: math.div($button-disabled-overlay, $button-disabled-opacity)\n\n    &--loading\n      pointer-events: none\n\n      .v-btn__content,\n      .v-btn__prepend,\n      .v-btn__append\n        opacity: 0\n\n    &--stacked\n      align-items: center\n      flex-direction: column\n      justify-content: center\n      gap: $button-stacked-gap\n\n      .v-btn__content\n        flex-direction: column\n        line-height: $button-stacked-line-height\n\n      .v-btn__prepend,\n      .v-btn__append,\n      .v-btn__content > .v-icon--start,\n      .v-btn__content > .v-icon--end\n        margin-inline: 0\n\n      @at-root\n        @include button-sizes($button-stacked-sizes, true)\n        @include button-density('height', $button-stacked-density)\n\n    &--slim\n      padding: $button-slim-padding\n\n    &--readonly\n      pointer-events: none\n\n    &--rounded\n      @include tools.rounded($button-rounded-border-radius)\n\n      &.v-btn--icon\n        @include tools.rounded($button-border-radius)\n\n    .v-icon\n      --v-icon-size-multiplier: #{calc(18/21)}\n\n    &--icon\n      .v-icon\n        --v-icon-size-multiplier: 1\n\n    &--stacked\n      .v-icon\n        --v-icon-size-multiplier: #{calc(24/21)}\n\n      &.v-btn--block\n        min-width: 100%\n\n  .v-btn__loader\n    align-items: center\n    display: flex\n    height: 100%\n    justify-content: center\n    left: 0\n    position: absolute\n    top: 0\n    width: 100%\n\n    > .v-progress-circular\n      width: $button-loader-size\n      height: $button-loader-size\n\n  .v-btn__content,\n  .v-btn__prepend,\n  .v-btn__append\n    align-items: center\n    display: flex\n    transition: $button-content-transition\n\n  .v-btn__prepend\n    margin-inline: $button-margin-start $button-margin-end\n\n    .v-btn--slim &\n      margin-inline-start: 0\n\n  .v-btn__append\n    margin-inline: $button-margin-end $button-margin-start\n\n    .v-btn--slim &\n      margin-inline-end: 0\n\n  .v-btn__content\n    justify-content: center\n    white-space: $button-white-space\n\n    > .v-icon--start\n      margin-inline: $button-margin-start $button-margin-end\n\n    > .v-icon--end\n      margin-inline: $button-margin-end $button-margin-start\n\n    .v-btn--stacked &\n      white-space: normal\n\n  .v-btn__overlay\n    background-color: currentColor\n    border-radius: inherit\n    opacity: 0\n    transition: opacity .2s ease-in-out\n\n  .v-btn__overlay,\n  .v-btn__underlay\n    pointer-events: none\n    @include tools.absolute()\n\n  // VPagination\n  .v-pagination\n    .v-btn\n      width: auto\n      padding-inline: $button-pagination-padding-inline\n      @include button-density('min-width', $button-icon-density)\n      @include tools.rounded($button-pagination-border-radius)\n\n      &--rounded\n        @include tools.rounded($button-pagination-rounded-border-radius)\n\n      &__overlay\n        transition: none\n\n    &__prev,\n    &__next\n      .v-btn\n        padding-inline: 0\n        @include button-density('width', $button-icon-density)\n\n    .v-pagination__item--is-active .v-btn__overlay\n      opacity: $button-pagination-active-overlay-opacity\n\n  @media (forced-colors: active)\n    .v-btn\n      &:not(&--variant-text, &--variant-plain)\n        border: thin solid\n\n      &:focus-visible\n        outline: 2px solid\n        outline-offset: 2px\n"
  },
  {
    "path": "packages/vuetify/src/components/VBtn/VBtn.tsx",
    "content": "// Styles\nimport './VBtn.sass'\n\n// Components\nimport { VBtnToggleSymbol } from '@/components/VBtnToggle/VBtnToggle'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\nimport { VIcon } from '@/components/VIcon'\nimport { VProgressCircular } from '@/components/VProgressCircular'\n\n// Composables\nimport { makeBorderProps, useBorder } from '@/composables/border'\nimport { makeComponentProps } from '@/composables/component'\nimport { makeDensityProps, useDensity } from '@/composables/density'\nimport { makeDimensionProps, useDimension } from '@/composables/dimensions'\nimport { makeElevationProps, useElevation } from '@/composables/elevation'\nimport { makeGroupItemProps, useGroupItem } from '@/composables/group'\nimport { IconValue } from '@/composables/icons'\nimport { makeLoaderProps, useLoader } from '@/composables/loader'\nimport { makeLocationProps, useLocation } from '@/composables/location'\nimport { makePositionProps, usePosition } from '@/composables/position'\nimport { makeRoundedProps, useRounded } from '@/composables/rounded'\nimport { makeRouterProps, useLink } from '@/composables/router'\nimport { useSelectLink } from '@/composables/selectLink'\nimport { makeSizeProps, useSize } from '@/composables/size'\nimport { makeTagProps } from '@/composables/tag'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\nimport { genOverlays, makeVariantProps, useVariant } from '@/composables/variant'\n\n// Directives\nimport vRipple from '@/directives/ripple'\n\n// Utilities\nimport { computed, toDisplayString, toRef, withDirectives } from 'vue'\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { RippleDirectiveBinding } from '@/directives/ripple'\n\nexport type VBtnSlots = {\n  default: never\n  prepend: never\n  append: never\n  loader: never\n}\n\nexport const makeVBtnProps = propsFactory({\n  active: {\n    type: Boolean,\n    default: undefined,\n  },\n  activeColor: String,\n  baseColor: String,\n  symbol: {\n    type: null,\n    default: VBtnToggleSymbol,\n  },\n  flat: Boolean,\n  icon: [Boolean, String, Function, Object] as PropType<boolean | IconValue>,\n  prependIcon: IconValue,\n  appendIcon: IconValue,\n\n  block: Boolean,\n  readonly: Boolean,\n  slim: Boolean,\n  stacked: Boolean,\n  spaced: String as PropType<'start' | 'end' | 'both'>,\n\n  ripple: {\n    type: [Boolean, Object] as PropType<RippleDirectiveBinding['value']>,\n    default: true,\n  },\n\n  text: {\n    type: [String, Number, Boolean],\n    default: undefined,\n  },\n\n  ...makeBorderProps(),\n  ...makeComponentProps(),\n  ...makeDensityProps(),\n  ...makeDimensionProps(),\n  ...makeElevationProps(),\n  ...makeGroupItemProps(),\n  ...makeLoaderProps(),\n  ...makeLocationProps(),\n  ...makePositionProps(),\n  ...makeRoundedProps(),\n  ...makeRouterProps(),\n  ...makeSizeProps(),\n  ...makeTagProps({ tag: 'button' }),\n  ...makeThemeProps(),\n  ...makeVariantProps({ variant: 'elevated' } as const),\n}, 'VBtn')\n\nexport const VBtn = genericComponent<VBtnSlots>()({\n  name: 'VBtn',\n\n  props: makeVBtnProps(),\n\n  emits: {\n    'group:selected': (val: { value: boolean }) => true,\n  },\n\n  setup (props, { attrs, slots }) {\n    const { themeClasses } = provideTheme(props)\n    const { borderClasses } = useBorder(props)\n    const { densityClasses } = useDensity(props)\n    const { dimensionStyles } = useDimension(props)\n    const { elevationClasses } = useElevation(props)\n    const { loaderClasses } = useLoader(props)\n    const { locationStyles } = useLocation(props)\n    const { positionClasses } = usePosition(props)\n    const { roundedClasses } = useRounded(props)\n    const { sizeClasses, sizeStyles } = useSize(props)\n    const group = useGroupItem(props, props.symbol, false)\n    const link = useLink(props, attrs)\n\n    const isActive = computed(() => {\n      if (props.active !== undefined) {\n        return props.active\n      }\n\n      if (link.isRouterLink.value) {\n        return link.isActive?.value\n      }\n\n      return group?.isSelected.value\n    })\n\n    const color = toRef(() => isActive.value ? props.activeColor ?? props.color : props.color)\n    const variantProps = computed(() => {\n      const showColor = (\n        (group?.isSelected.value && (!link.isLink.value || link.isActive?.value)) ||\n        (!group || link.isActive?.value)\n      )\n      return ({\n        color: showColor ? color.value ?? props.baseColor : props.baseColor,\n        variant: props.variant,\n      })\n    })\n    const { colorClasses, colorStyles, variantClasses } = useVariant(variantProps)\n\n    const isDisabled = computed(() => group?.disabled.value || props.disabled)\n    const isElevated = toRef(() => {\n      return props.variant === 'elevated' && !(props.disabled || props.flat || props.border)\n    })\n    const valueAttr = computed(() => {\n      if (props.value === undefined || typeof props.value === 'symbol') return undefined\n\n      return Object(props.value) === props.value\n        ? JSON.stringify(props.value, null, 0)\n        : props.value\n    })\n\n    function onClick (e: MouseEvent) {\n      if (\n        isDisabled.value ||\n        (link.isLink.value && (\n          e.metaKey ||\n          e.ctrlKey ||\n          e.shiftKey ||\n          (e.button !== 0) ||\n          attrs.target === '_blank'\n        ))\n      ) return\n\n      if (link.isRouterLink.value) {\n        link.navigate.value?.(e)\n      } else {\n        // Group active state for links is handled by useSelectLink\n        group?.toggle()\n      }\n    }\n\n    useSelectLink(link, group?.select)\n\n    useRender(() => {\n      const Tag = (link.isLink.value) ? 'a' : props.tag\n      const hasPrepend = !!(props.prependIcon || slots.prepend)\n      const hasAppend = !!(props.appendIcon || slots.append)\n      const hasIcon = !!(props.icon && props.icon !== true)\n\n      return withDirectives(\n        <Tag\n          { ...link.linkProps }\n          type={ Tag === 'a' ? undefined : 'button' }\n          class={[\n            'v-btn',\n            group?.selectedClass.value,\n            {\n              'v-btn--active': isActive.value,\n              'v-btn--block': props.block,\n              'v-btn--disabled': isDisabled.value,\n              'v-btn--elevated': isElevated.value,\n              'v-btn--flat': props.flat,\n              'v-btn--icon': !!props.icon,\n              'v-btn--loading': props.loading,\n              'v-btn--readonly': props.readonly,\n              'v-btn--slim': props.slim,\n              'v-btn--stacked': props.stacked,\n            },\n            props.spaced\n              ? [\n                'v-btn--spaced',\n                `v-btn--spaced-${props.spaced}`,\n              ]\n              : [],\n            themeClasses.value,\n            borderClasses.value,\n            colorClasses.value,\n            densityClasses.value,\n            elevationClasses.value,\n            loaderClasses.value,\n            positionClasses.value,\n            roundedClasses.value,\n            sizeClasses.value,\n            variantClasses.value,\n            props.class,\n          ]}\n          style={[\n            colorStyles.value,\n            dimensionStyles.value,\n            locationStyles.value,\n            sizeStyles.value,\n            props.style,\n          ]}\n          aria-busy={ props.loading ? true : undefined }\n          disabled={ (isDisabled.value && Tag !== 'a') || undefined }\n          tabindex={ props.loading || props.readonly ? -1 : undefined }\n          onClick={ onClick }\n          value={ valueAttr.value }\n        >\n          { genOverlays(true, 'v-btn') }\n\n          { !props.icon && hasPrepend && (\n            <span key=\"prepend\" class=\"v-btn__prepend\">\n              { !slots.prepend ? (\n                <VIcon\n                  key=\"prepend-icon\"\n                  icon={ props.prependIcon }\n                />\n              ) : (\n                <VDefaultsProvider\n                  key=\"prepend-defaults\"\n                  disabled={ !props.prependIcon }\n                  defaults={{\n                    VIcon: {\n                      icon: props.prependIcon,\n                    },\n                  }}\n                  v-slots:default={ slots.prepend }\n                />\n              )}\n            </span>\n          )}\n\n          <span class=\"v-btn__content\" data-no-activator=\"\">\n            { (!slots.default && hasIcon) ? (\n              <VIcon\n                key=\"content-icon\"\n                icon={ props.icon }\n              />\n            ) : (\n              <VDefaultsProvider\n                key=\"content-defaults\"\n                disabled={ !hasIcon }\n                defaults={{\n                  VIcon: {\n                    icon: props.icon,\n                  },\n                }}\n              >\n                { slots.default?.() ?? toDisplayString(props.text) }\n              </VDefaultsProvider>\n            )}\n          </span>\n\n          { !props.icon && hasAppend && (\n            <span key=\"append\" class=\"v-btn__append\">\n              { !slots.append ? (\n                <VIcon\n                  key=\"append-icon\"\n                  icon={ props.appendIcon }\n                />\n              ) : (\n                <VDefaultsProvider\n                  key=\"append-defaults\"\n                  disabled={ !props.appendIcon }\n                  defaults={{\n                    VIcon: {\n                      icon: props.appendIcon,\n                    },\n                  }}\n                  v-slots:default={ slots.append }\n                />\n              )}\n            </span>\n          )}\n\n          { !!props.loading && (\n            <span key=\"loader\" class=\"v-btn__loader\">\n              { slots.loader?.() ?? (\n                <VProgressCircular\n                  color={ typeof props.loading === 'boolean' ? undefined : props.loading }\n                  indeterminate\n                  width=\"2\"\n                />\n              )}\n            </span>\n          )}\n        </Tag>,\n        [[\n          vRipple,\n          !isDisabled.value && props.ripple,\n          '',\n          { center: !!props.icon },\n        ]]\n      )\n    })\n\n    return { group }\n  },\n})\n\nexport type VBtn = InstanceType<typeof VBtn>\n"
  },
  {
    "path": "packages/vuetify/src/components/VBtn/__tests__/VBtn.spec.browser.tsx",
    "content": "import { VBtn } from '../VBtn'\n\n// Utilities\nimport { gridOn, render, screen, showcase, userEvent } from '@test'\nimport { ref } from 'vue'\nimport { createRouter, createWebHistory } from 'vue-router'\n\n// Types\nimport type { Variant } from '@/composables/variant'\n\n// TODO: generate these from types\nconst colors = ['success', 'info', 'warning', 'error', 'invalid']\nconst sizes = ['x-small', 'small', 'default', 'large', 'x-large'] as const\nconst densities = ['default', 'comfortable', 'compact'] as const\nconst variants = ['elevated', 'flat', 'tonal', 'outlined', 'text', 'plain'] as const\nconst spaced = ['start', 'both', 'end'] as const\nconst props = {\n  color: colors,\n  // variant: variants,\n  // disabled: false,\n  // loading: false,\n}\n\nconst stories = {\n  'Default button': <VBtn>Basic button</VBtn>,\n  'Small success button': <VBtn color=\"success\" size=\"small\">Completed!</VBtn>,\n  'Large, plain button w/ error': <VBtn color=\"error\" variant=\"plain\" size=\"large\">Whoops</VBtn>,\n  Loading: (\n    <div style={{ display: 'flex', gap: '1.2rem' }}>\n      <VBtn>{{ loader: () => <span>Loading...</span>, default: () => 'Default Content' }}</VBtn>\n      <VBtn loading>{{ loader: () => <span>Loading...</span>, default: () => 'Default Content' }}</VBtn>\n      <VBtn loading>{{ loader: () => <span>Loading...</span> }}</VBtn>\n      <VBtn loading>Default Content</VBtn>\n    </div>\n  ),\n  Icon: <VBtn icon=\"$vuetify\" color=\"pink\"></VBtn>,\n  'Density + size': gridOn(densities, sizes, (density, size) =>\n    <VBtn size={ size } density={ density }>{ size }</VBtn>\n  ),\n  Variants: gridOn(['no color', 'primary'], variants, (color, variant) =>\n    <VBtn color={ color } variant={ variant }>{ variant }</VBtn>\n  ),\n  'Disabled variants': gridOn(['no color', 'primary'], variants, (color, variant) =>\n    <VBtn disabled color={ color } variant={ variant }>{ variant }</VBtn>\n  ),\n  Stacked: gridOn([undefined], variants, (_, variant) =>\n    <VBtn stacked prependIcon=\"$vuetify\" variant={ variant }>{ variant }</VBtn>\n  ),\n  Spaced: gridOn([undefined], spaced, (_, spaced) =>\n    <VBtn spaced={ spaced } prependIcon=\"$prev\" appendIcon=\"$next\" width=\"200\">{ spaced }</VBtn>\n  ),\n  'Block + spaced': <VBtn block spaced=\"both\" prependIcon=\"$prev\" appendIcon=\"$next\">Spaced</VBtn>,\n}\n\n// Actual tests\ndescribe('VBtn', () => {\n  describe('color', () => {\n    it('supports default color props', async () => {\n      render(() => (\n        <>\n          { colors.map(color => (\n            <VBtn color={ color } class=\"text-capitalize\">\n              { color } button\n            </VBtn>\n          ))}\n        </>\n      ))\n\n      const buttons = screen.getAllByCSS('button')\n      expect(buttons).toHaveLength(colors.length)\n      buttons.forEach((button, idx) => {\n        expect(button).toHaveTextContent(colors[idx])\n      })\n    })\n  })\n\n  describe('tag', () => {\n    it('renders the proper tag instead of a button', async () => {\n      render(<VBtn tag=\"custom-tag\">Click me</VBtn>)\n      const customTag = screen.getByCSS('custom-tag')\n      expect(customTag).toHaveTextContent('Click me')\n    })\n  })\n\n  describe('elevation', () => {\n    it('should have the correct elevation', async () => {\n      render(<VBtn elevation={ 5 } />)\n      const button = screen.getByCSS('button')\n      expect(button).toHaveClass('elevation-5')\n    })\n  })\n\n  describe('events', () => {\n    it('emits native click events', async () => {\n      const click = vi.fn()\n\n      const { rerender } = render(() => (\n        <VBtn onClick={ click }>Click me</VBtn>\n      ))\n\n      await userEvent.click(screen.getByCSS('button'))\n      expect(click).toHaveBeenCalledTimes(1)\n\n      await rerender({ to: '#my-anchor' })\n\n      await userEvent.click(screen.getByCSS('button'))\n      expect(click).toHaveBeenCalledTimes(2)\n    })\n\n    // Pending test, is \"toggle\" even going to be emitted anymore?\n    it.todo('emits toggle when used within a button group', () => {\n      // const register = jest.fn()\n      // const unregister = jest.fn()\n      // const toggle = jest.fn()\n      // const wrapper = mountFunction({\n      //   provide: {\n      //     btnToggle: { register, unregister },\n      //   },\n      //   methods: { toggle },\n      // })\n\n      // wrapper.trigger('click')\n      // expect(toggle).toHaveBeenCalled()\n    })\n  })\n\n  // These tests were copied over from the previous Jest tests,\n  // but they are breaking because the features have not been implemented\n  describe.todo('activeClass', () => {\n    it('should use custom active-class', async () => {\n      const { wrapper } = render(<VBtn active activeClass=\"my-active-class\">Active Class</VBtn>)\n      expect(wrapper.element).toHaveClass('my-active-class')\n    })\n  })\n\n  describe('href', () => {\n    it.todo('should render an <a> tag when using href prop', async () => {\n      const anchor = { href: '#anchor', hash: 'anchor' }\n      render(<VBtn href={ anchor.href }>Click me</VBtn>)\n      const link = screen.getByCSS('a')\n\n      await userEvent.click(link)\n      expect(link).toHaveTextContent('Click me')\n      expect(link).toHaveFocus()\n      expect(window.location.hash).toContain(anchor.hash)\n    })\n\n    it('should change route when using to prop', async () => {\n      const router = createRouter({\n        history: createWebHistory(),\n        routes: [\n          { path: '/', component: { template: 'Home' } },\n          { path: '/about', component: { template: 'About' } },\n        ],\n      })\n\n      await router.replace('/')\n\n      const result = render(() => (\n        <VBtn to=\"/about\">Click me</VBtn>\n      ), { global: { plugins: [router] } })\n\n      const link = result.wrapper.element\n\n      await userEvent.click(link)\n      expect(link).toHaveFocus()\n      await result.findByText('Click me')\n      expect(window.location.pathname).toBe('/about')\n    })\n  })\n\n  describe('value', () => {\n    it('should pass string values', async () => {\n      const stringValue = 'Foobar'\n      const { wrapper } = render(() => (\n        <VBtn value={ stringValue }></VBtn>\n      ))\n      expect(wrapper.element).toHaveValue(stringValue)\n    })\n\n    it('should stringify object', async () => {\n      const objectValue = { value: {} }\n      const { wrapper } = render(() => (\n        <VBtn value={ objectValue }></VBtn>\n      ))\n      expect(wrapper.element).toHaveValue(JSON.stringify(objectValue, null, 0))\n    })\n\n    it('should stringify number', async () => {\n      const numberValue = 15\n      const { wrapper } = render(() => (\n        <VBtn value={ numberValue }></VBtn>\n      ))\n      expect(wrapper.element).toHaveValue(JSON.stringify(numberValue, null, 0))\n    })\n\n    it('should stringify array', async () => {\n      const arrayValue = ['foo', 'bar']\n      const { wrapper } = render(() => (\n        <VBtn value={ arrayValue }></VBtn>\n      ))\n      expect(wrapper.element).toHaveValue(JSON.stringify(arrayValue, null, 0))\n    })\n\n    it('should not generate a fallback value when not provided', async () => {\n      const { wrapper } = render(<VBtn></VBtn>)\n      expect(wrapper.element).not.toHaveValue()\n    })\n  })\n\n  describe('Reactivity', () => {\n    it('disabled', async () => {\n      const disabled = ref(true)\n      const { wrapper } = render(() => (\n        <VBtn color=\"success\" disabled={ disabled.value }></VBtn>\n      ))\n      expect(wrapper.element).toHaveClass('v-btn--disabled')\n\n      disabled.value = false\n      await expect.element(wrapper.element).not.toHaveClass('v-btn--disabled')\n    })\n\n    it.todo('activeClass', async () => {\n      const { rerender } = render(() => (\n        <VBtn activeClass=\"my-active-class\">Active Class</VBtn>\n      ))\n\n      await rerender({ activeClass: 'different-class' })\n\n      const activeClassElement = screen.queryByCSS('.different-class')\n      expect(activeClassElement).not.toBeVisible()\n    })\n\n    it('variant', async () => {\n      const variant = ref<Variant>('plain')\n      const { wrapper } = render(() => (\n        <VBtn variant={ variant.value }>Plain</VBtn>\n      ))\n\n      expect(wrapper.element).toHaveClass('v-btn--variant-plain')\n\n      variant.value = 'elevated'\n      await expect.element(wrapper.element).not.toHaveClass('v-btn--variant-plain')\n    })\n  })\n\n  showcase({ stories, props, component: VBtn })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VBtn/_mixins.scss",
    "content": "@use 'sass:math';\n@use 'sass:map';\n@use 'sass:meta';\n@use '../../styles/settings';\n@use '../../styles/tools';\n@use './variables' as *;\n\n@mixin button-sizes ($map: $button-sizes, $immediate: false) {\n  @each $sizeName, $multiplier in settings.$size-scales {\n    $size: map.get($map, 'font-size') + math.div(2 * $multiplier, 16);\n    $height: map.get($map, 'height') + (settings.$size-scale * $multiplier);\n    $selector: '.v-btn--size-#{$sizeName}';\n    @if $immediate {\n      $selector: '#{&}#{$selector}';\n    }\n\n    #{$selector} {\n      --v-btn-size: #{$size};\n      --v-btn-height: #{$height};\n      font-size: var(--v-btn-size);\n      min-width: tools.roundEven($height * map.get($map, 'width-ratio'));\n      padding: 0 tools.roundEven(math.div($height, map.get($map, 'padding-ratio')));\n    }\n  }\n}\n\n@mixin button-density ($properties, $densities) {\n  @each $density, $multiplier in $densities {\n    $value: calc(var(--v-btn-height) + #{$multiplier * settings.$spacer});\n\n    &.v-btn--density-#{$density} {\n      @if meta.type-of($properties) == \"list\" {\n        @each $property in $properties {\n          #{$property}: $value;\n        }\n      }\n      @else {\n        #{$properties}: $value;\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VBtn/_variables.scss",
    "content": "@use 'sass:math';\n@use 'sass:map';\n@use '../../styles/settings';\n@use '../../styles/tools';\n\n// Defaults\n// if false, disabled buttons will be greyed out\n$button-colored-disabled: true !default;\n\n$button-background: rgb(var(--v-theme-surface)) !default;\n$button-color: tools.theme-color('on-surface', var(--v-high-emphasis-opacity)) !default;\n$button-banner-actions-padding: 0 8px !default; // @deprecated\n$button-pagination-active-overlay-opacity: var(--v-border-opacity) !default;\n$button-pagination-border-radius: settings.$border-radius-root !default;\n$button-pagination-padding-inline: 5px !default;\n$button-pagination-rounded-border-radius: map.get(settings.$rounded, 'circle') !default;\n$button-border-color: settings.$border-color-root !default;\n$button-border-radius: settings.$border-radius-root !default;\n$button-border-style: settings.$border-style-root !default;\n$button-border-thin-width: thin !default;\n$button-border-width: 0 !default;\n$button-card-actions-padding: 0 8px !default; // @deprecated\n$button-content-transition: transform, opacity .2s settings.$standard-easing !default;\n$button-disabled-opacity: 0.26 !default;\n$button-disabled-overlay: 0.12 !default;\n$button-elevation: ('default': 1, 'hover': 2, 'active': 1) !default;\n$button-font-size: tools.map-deep-get(settings.$typography, 'label-large', 'size') !default;\n$button-font-weight: tools.map-deep-get(settings.$typography, 'label-large', 'weight') !default;\n$button-height: 36px !default;\n$button-stacked-height: 72px !default;\n$button-stacked-gap: 4px !default;\n$button-icon-border-radius: map.get(settings.$rounded, 'circle') !default;\n$button-icon-font-size: 1rem !default;\n$button-line-height: normal !default;\n$button-loader-size: 1.5em !default;\n$button-stacked-line-height: 1.25 !default;\n$button-plain-opacity: .62 !default;\n$button-padding-ratio: 2.25 !default;\n$button-stacked-padding-ratio: 4.5 !default;\n$button-margin-start-multiplier: -9 !default;\n$button-margin-end-multiplier: 4.5 !default;\n$button-margin-start: calc(var(--v-btn-height) / #{$button-margin-start-multiplier}) !default;\n$button-margin-end: calc(var(--v-btn-height) / #{$button-margin-end-multiplier}) !default;\n$button-max-width: 100% !default;\n$button-positions: absolute fixed !default;\n$button-text-letter-spacing: tools.map-deep-get(settings.$typography, 'label-large', 'letter-spacing') !default;\n$button-text-transform: none !default;\n$button-transition-property: box-shadow, transform, opacity, background !default;\n$button-vertical-align: middle !default;\n$button-width-ratio: math.div(16, 9) !default;\n$button-snackbar-action-padding: 0 8px !default; // @deprecated\n$button-slim-padding: 0 8px !default;\n$button-stacked-width-ratio: 1 !default;\n$button-rounded-border-radius: map.get(settings.$rounded, 'xl') !default;\n$button-white-space: nowrap !default;\n\n$button-density: ('default': 0, 'comfortable': -2, 'compact': -3) !default;\n$button-stacked-density: ('default': 0, 'comfortable': -4, 'compact': -6) !default;\n$button-icon-density: ('default': 3, 'comfortable': 0, 'compact': -2) !default;\n\n$button-border: (\n  $button-border-color,\n  $button-border-style,\n  $button-border-width,\n  $button-border-thin-width\n) !default;\n\n$button-sizes: () !default;\n$button-sizes: map.merge(\n  (\n    'height': $button-height,\n    'font-size': $button-font-size,\n    'width-ratio': $button-width-ratio,\n    'padding-ratio': $button-padding-ratio\n  ),\n  $button-sizes\n);\n\n$button-stacked-sizes: () !default;\n$button-stacked-sizes: map.merge(\n  (\n    'height': $button-stacked-height,\n    'font-size': $button-font-size,\n    'width-ratio': $button-stacked-width-ratio,\n    'padding-ratio': $button-stacked-padding-ratio\n  ),\n  $button-stacked-sizes\n);\n\n$button-variants: (\n  $button-background,\n  $button-color,\n  map.get($button-elevation, 'default'),\n  $button-plain-opacity,\n  'v-btn'\n) !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VBtn/index.ts",
    "content": "export { VBtn } from './VBtn'\n"
  },
  {
    "path": "packages/vuetify/src/components/VBtnGroup/VBtnGroup.sass",
    "content": "@use 'sass:selector'\n@use '../../styles/tools'\n@use '../VBtn/variables' as *\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-btn-group\n    display: inline-flex\n    flex-wrap: nowrap\n    max-width: 100%\n    min-width: 0\n    overflow-y: hidden\n    overflow-x: auto\n    vertical-align: middle\n\n    @include tools.border($btn-group-border...)\n    @include tools.elevation($btn-group-elevation)\n    @include tools.rounded($btn-group-border-radius)\n    @include tools.theme($btn-group-theme...)\n\n    .v-btn\n      border-radius: 0\n      border-color: inherit\n\n    &--tile\n      @include tools.rounded($btn-group-tile-border-radius)\n\n    &--horizontal\n      $root: &\n\n      @at-root\n        @include tools.density('v-btn-group', $button-density) using ($modifier)\n          @at-root #{selector.append(&, $root)}\n            height: $btn-group-height + $modifier\n\n      .v-btn\n        &:not(:last-child)\n          border-inline-end: none\n\n        &:not(:first-child)\n          border-inline-start: none\n\n        &:first-child\n          border-start-start-radius: inherit\n          border-end-start-radius: inherit\n\n        &:last-child\n          border-start-end-radius: inherit\n          border-end-end-radius: inherit\n\n      &.v-btn-group--divided\n        .v-btn:not(:last-child)\n          border-inline-end-width: $btn-group-border-thin-width\n          border-inline-end-style: $btn-group-border-style\n          border-inline-end-color: $btn-group-border-color\n\n    &--vertical\n      flex-direction: column\n\n      .v-btn\n        &:not(:last-child)\n          border-block-end: none\n\n        &:not(:first-child)\n          border-block-start: none\n\n        &:first-child\n          border-start-start-radius: inherit\n          border-start-end-radius: inherit\n\n        &:last-child\n          border-end-start-radius: inherit\n          border-end-end-radius: inherit\n\n      &.v-btn-group--divided\n        .v-btn:not(:last-child)\n          border-block-end-width: $btn-group-border-thin-width\n          border-block-end-style: $btn-group-border-style\n          border-block-end-color: $btn-group-border-color\n"
  },
  {
    "path": "packages/vuetify/src/components/VBtnGroup/VBtnGroup.tsx",
    "content": "// Styles\nimport './VBtnGroup.sass'\n\n// Composables\nimport { makeBorderProps, useBorder } from '@/composables/border'\nimport { makeComponentProps } from '@/composables/component'\nimport { provideDefaults } from '@/composables/defaults'\nimport { makeDensityProps, useDensity } from '@/composables/density'\nimport { makeElevationProps, useElevation } from '@/composables/elevation'\nimport { makeRoundedProps, useRounded } from '@/composables/rounded'\nimport { makeTagProps } from '@/composables/tag'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\nimport { makeVariantProps } from '@/composables/variant'\n\n// Utilities\nimport { toRef } from 'vue'\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\nexport const makeVBtnGroupProps = propsFactory({\n  baseColor: String,\n  divided: Boolean,\n  direction: {\n    type: String as PropType<'horizontal' | 'vertical'>,\n    default: 'horizontal',\n  },\n\n  ...makeBorderProps(),\n  ...makeComponentProps(),\n  ...makeDensityProps(),\n  ...makeElevationProps(),\n  ...makeRoundedProps(),\n  ...makeTagProps(),\n  ...makeThemeProps(),\n  ...makeVariantProps(),\n}, 'VBtnGroup')\n\nexport const VBtnGroup = genericComponent()({\n  name: 'VBtnGroup',\n\n  props: makeVBtnGroupProps(),\n\n  setup (props, { slots }) {\n    const { themeClasses } = provideTheme(props)\n    const { densityClasses } = useDensity(props)\n    const { borderClasses } = useBorder(props)\n    const { elevationClasses } = useElevation(props)\n    const { roundedClasses } = useRounded(props)\n\n    provideDefaults({\n      VBtn: {\n        height: toRef(() => props.direction === 'horizontal' ? 'auto' : null),\n        baseColor: toRef(() => props.baseColor),\n        color: toRef(() => props.color),\n        density: toRef(() => props.density),\n        flat: true,\n        variant: toRef(() => props.variant),\n      },\n    })\n\n    useRender(() => {\n      return (\n        <props.tag\n          class={[\n            'v-btn-group',\n            `v-btn-group--${props.direction}`,\n            {\n              'v-btn-group--divided': props.divided,\n            },\n            themeClasses.value,\n            borderClasses.value,\n            densityClasses.value,\n            elevationClasses.value,\n            roundedClasses.value,\n            props.class,\n          ]}\n          style={ props.style }\n          v-slots={ slots }\n        />\n      )\n    })\n  },\n})\n\nexport type VBtnGroup = InstanceType<typeof VBtnGroup>\n"
  },
  {
    "path": "packages/vuetify/src/components/VBtnGroup/_variables.scss",
    "content": "@use '../../styles/settings';\n@use '../../styles/tools';\n\n// VBtnGroup\n$btn-group-background: transparent !default;\n$btn-group-border-color: settings.$border-color-root !default;\n$btn-group-border-radius: settings.$border-radius-root !default;\n$btn-group-border-style: settings.$border-style-root !default;\n$btn-group-border-thin-width: thin !default;\n$btn-group-border-width: 0 !default;\n$btn-group-color: tools.theme-color('on-surface', var(--v-high-emphasis-opacity)) !default;\n$btn-group-height: 48px !default;\n$btn-group-elevation: 0 !default;\n$btn-group-tile-border-radius: 0 !default;\n\n// Lists\n$btn-group-border: (\n  $btn-group-border-color,\n  $btn-group-border-style,\n  $btn-group-border-width,\n  $btn-group-border-thin-width\n) !default;\n\n$btn-group-theme: (\n  $btn-group-background,\n  $btn-group-color\n) !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VBtnGroup/index.ts",
    "content": "export { VBtnGroup } from './VBtnGroup'\n"
  },
  {
    "path": "packages/vuetify/src/components/VBtnToggle/VBtnToggle.sass",
    "content": "@use './variables' as *\n@use '../../styles/tools'\n\n@include tools.layer('components')\n  .v-btn-toggle\n    > .v-btn.v-btn--active:not(.v-btn--disabled)\n      @include tools.active-states('> .v-btn__overlay', $btn-toggle-selected-opacity)\n\n      &.v-btn--variant-plain\n        opacity: 1\n\n@include tools.layer('trumps')\n  @media (forced-colors: active)\n    .v-btn-toggle\n      > .v-btn:not(.v-btn--disabled)\n        border-color: buttontext\n\n        &:focus-visible\n          outline: 0\n\n        &:not(.v-btn--active)\n          &:hover,\n          &:focus-visible\n            color: highlight\n            border-color: currentColor\n\n      > .v-btn--active\n        color: highlight\n        forced-color-adjust: preserve-parent-color\n\n        &:not(.v-btn--variant-text, .v-btn--variant-plain)\n          background-color: highlight\n          color: highlighttext\n          border-color: highlight\n"
  },
  {
    "path": "packages/vuetify/src/components/VBtnToggle/VBtnToggle.tsx",
    "content": "// Styles\nimport './VBtnToggle.sass'\n\n// Components\nimport { makeVBtnGroupProps, VBtnGroup } from '@/components/VBtnGroup/VBtnGroup'\n\n// Composables\nimport { makeGroupProps, useGroup } from '@/composables/group'\n\n// Utilities\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { InjectionKey } from 'vue'\nimport type { GroupProvide } from '@/composables/group'\nimport type { GenericProps } from '@/util'\n\nexport type BtnToggleSlotProps = 'isSelected' | 'select' | 'selected' | 'next' | 'prev'\nexport interface DefaultBtnToggleSlot extends Pick<GroupProvide, BtnToggleSlotProps> {}\n\nexport const VBtnToggleSymbol: InjectionKey<GroupProvide> = Symbol.for('vuetify:v-btn-toggle')\n\ntype VBtnToggleSlots = {\n  default: DefaultBtnToggleSlot\n}\n\nexport const makeVBtnToggleProps = propsFactory({\n  ...makeVBtnGroupProps(),\n  ...makeGroupProps(),\n}, 'VBtnToggle')\n\nexport const VBtnToggle = genericComponent<new <T>(\n  props: {\n    modelValue?: T\n    'onUpdate:modelValue'?: (value: T) => void\n  },\n  slots: VBtnToggleSlots,\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VBtnToggle',\n\n  props: makeVBtnToggleProps(),\n\n  emits: {\n    'update:modelValue': (value: any) => true,\n  },\n\n  setup (props, { slots }) {\n    const { isSelected, next, prev, select, selected } = useGroup(props, VBtnToggleSymbol)\n\n    useRender(() => {\n      const btnGroupProps = VBtnGroup.filterProps(props)\n\n      return (\n        <VBtnGroup\n          class={[\n            'v-btn-toggle',\n            props.class,\n          ]}\n          { ...btnGroupProps }\n          style={ props.style }\n        >\n          { slots.default?.({\n            isSelected,\n            next,\n            prev,\n            select,\n            selected,\n          })}\n        </VBtnGroup>\n      )\n    })\n\n    return {\n      next,\n      prev,\n      select,\n    }\n  },\n})\n\nexport type VBtnToggle = InstanceType<typeof VBtnToggle>\n"
  },
  {
    "path": "packages/vuetify/src/components/VBtnToggle/_variables.scss",
    "content": "@use 'sass:map';\n@use '../../styles/settings';\n@use '../../styles/tools';\n\n// VBtnToggle\n$btn-toggle-selected-opacity: map.get(settings.$states, 'activated') !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VBtnToggle/index.ts",
    "content": "export { VBtnToggle } from './VBtnToggle'\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/VCalendar.tsx",
    "content": "// Styles\nimport './VCalendarCategory.sass'\nimport './VCalendarDaily.sass'\nimport './VCalendarWeekly.sass'\n\n// Components\nimport { VCalendarCategory } from './VCalendarCategory'\nimport { VCalendarDaily } from './VCalendarDaily'\nimport { VCalendarWeekly } from './VCalendarWeekly'\n\n// Composables\nimport { makeCalendarBaseProps } from './composables/calendarBase'\nimport { makeCalendarWithEventsProps, useCalendarWithEvents } from './composables/calendarWithEvents'\nimport { forwardRefs } from '@/composables/forwardRefs'\n\n// Directives\nimport vResize from '@/directives/resize'\n\n// Utilities\nimport { computed, onMounted, onUpdated, ref, watch } from 'vue'\nimport { getParsedCategories } from './util/parser'\nimport {\n  copyTimestamp,\n  DAY_MIN,\n  DAYS_IN_MONTH_MAX,\n  DAYS_IN_WEEK,\n  getEndOfMonth,\n  getStartOfMonth,\n  nextDay,\n  prevDay,\n  relativeDays,\n  timestampToDate,\n  updateFormatted,\n  updateRelative,\n  updateWeekday,\n  validateTimestamp,\n} from './util/timestamp'\nimport { genericComponent, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type {\n  CalendarCategory, CalendarCategoryTextFunction,\n  CalendarDayBodySlotScope,\n  CalendarDaySlotScope, CalendarEvent, CalendarEventParsed,\n  CalendarTimestamp,\n} from './types'\nimport type { EventProp, GenericProps, JSXComponent } from '@/util'\n\n// Types\ninterface VCalendarRenderProps {\n  start: CalendarTimestamp\n  end: CalendarTimestamp\n  component: JSXComponent & { filterProps: <T>(props: T) => Partial<T> }\n  maxDays: number\n  categories: CalendarCategory[]\n}\n\ninterface EventSlotScope {\n  event: CalendarEvent\n  outside: boolean\n  singline: boolean\n  overlapsNoon: boolean\n  formatTime: (withTime: CalendarTimestamp, ampm: boolean) => string\n  timeSummary: () => string\n  eventSummary: () => JSX.Element\n  eventParsed: CalendarEventParsed\n  day: CalendarDaySlotScope\n  start: boolean\n  end: boolean\n  timed: boolean\n}\n\ninterface DaySlotScope extends CalendarTimestamp {\n  outside: boolean\n  index: number\n  week: CalendarTimestamp[]\n}\n\ninterface DayHeaderSlotScope extends CalendarTimestamp {\n  index: number\n  week: CalendarTimestamp[]\n}\n\ninterface CalendarDayCategorySlotScope extends CalendarDayBodySlotScope {\n  category: CalendarCategory\n}\n\nexport const VCalendar = genericComponent<new (\n  props: {\n    [key: `on${Capitalize<string>}:date`]: EventProp<[Event, CalendarTimestamp]>\n    [key: `on${Capitalize<string>}:dayCategory`]: EventProp<[Event, CalendarDayCategorySlotScope]>\n    [key: `on${Capitalize<string>}:day`]: EventProp<[Event, CalendarDayBodySlotScope]>\n    [key: `on${Capitalize<string>}:event`]: EventProp<[Event, EventSlotScope]>\n    [key: `on${Capitalize<string>}:interval`]: EventProp<[Event, CalendarTimestamp]>\n    [key: `on${Capitalize<string>}:more`]: EventProp<[Event, CalendarDaySlotScope]>\n    [key: `on${Capitalize<string>}:timeCategory`]: EventProp<[Event, CalendarDayCategorySlotScope]>\n    [key: `on${Capitalize<string>}:time`]: EventProp<[Event, CalendarDayBodySlotScope]>\n  },\n  slots: {\n    'category': CalendarDayCategorySlotScope\n    'day': DaySlotScope\n    'day-body': CalendarDayBodySlotScope\n    'day-header': DayHeaderSlotScope\n    'day-label': CalendarTimestamp\n    'day-label-header': CalendarTimestamp\n    'day-month': CalendarTimestamp\n    'event': EventSlotScope\n    'interval': CalendarDayCategorySlotScope\n    'interval-header': never\n  },\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VCalendar',\n\n  directives: { vResize },\n\n  props: {\n    modelValue: {\n      type: [String, Number, Date] as PropType<string | number | Date>,\n      validate: validateTimestamp,\n    },\n    categoryDays: {\n      type: [Number, String],\n      default: 1,\n      validate: (x: any) => isFinite(parseInt(x)) && parseInt(x) > 0,\n    },\n    categories: {\n      type: [Array, String] as PropType<CalendarCategory[] | string>,\n      default: '',\n    },\n    categoryText: {\n      type: [String, Function] as PropType<string | CalendarCategoryTextFunction>,\n    },\n    maxDays: {\n      type: Number,\n      default: 7,\n    },\n    categoryHideDynamic: {\n      type: Boolean,\n    },\n    categoryShowAll: {\n      type: Boolean,\n    },\n    categoryForInvalid: {\n      type: String,\n      default: '',\n    },\n\n    ...makeCalendarBaseProps(),\n    ...makeCalendarWithEventsProps(),\n  },\n\n  setup (props, { slots, attrs, emit }) {\n    const root = ref<VCalendarWeekly | VCalendarDaily | VCalendarCategory>()\n    const base = useCalendarWithEvents(props, slots, attrs)\n\n    const lastStart = ref<CalendarTimestamp | null>(null)\n    const lastEnd = ref<CalendarTimestamp | null>(null)\n\n    const parsedCategoryDays = computed((): number => {\n      return parseInt(String(props.categoryDays)) || 1\n    })\n\n    const parsedCategories = computed((): CalendarCategory[] => {\n      return getParsedCategories(props.categories, props.categoryText)\n    })\n\n    const renderProps = computed((): VCalendarRenderProps => {\n      const around = base.parsedValue.value\n      let component: any = null\n      let maxDays = props.maxDays\n      let categories = parsedCategories.value\n      let start = around\n      let end = around\n\n      switch (props.type) {\n        case 'month':\n          component = VCalendarWeekly\n          start = getStartOfMonth(around)\n          end = getEndOfMonth(around)\n          break\n        case 'week':\n          component = VCalendarDaily\n          start = base.getStartOfWeek(around)\n          end = base.getEndOfWeek(around)\n          maxDays = 7\n          break\n        case 'day':\n          component = VCalendarDaily\n          maxDays = 1\n          break\n        case '4day':\n          component = VCalendarDaily\n          end = relativeDays(copyTimestamp(end), nextDay, 3)\n          updateFormatted(end)\n          maxDays = 4\n          break\n        case 'custom-weekly':\n          component = VCalendarWeekly\n          start = base.parsedStart.value || around\n          end = base.parsedEnd.value\n          break\n        case 'custom-daily':\n          component = VCalendarDaily\n          start = base.parsedStart.value || around\n          end = base.parsedEnd.value\n          break\n        case 'category':\n          const days = parsedCategoryDays.value\n\n          component = VCalendarCategory\n          end = relativeDays(copyTimestamp(end), nextDay, days)\n          updateFormatted(end)\n          maxDays = days\n\n          categories = getCategoryList(categories)\n          break\n        default:\n          const type = props.type satisfies never\n          throw new Error(`${type} is not a valid Calendar type`)\n      }\n\n      return { component, start, end, maxDays, categories }\n    })\n\n    const eventWeekdays = computed((): number[] => {\n      return base.effectiveWeekdays.value\n    })\n\n    const categoryMode = computed((): boolean => {\n      return props.type === 'category'\n    })\n\n    const monthLongFormatter = computed(() => {\n      return base.getFormatter({\n        timeZone: 'UTC', month: 'long',\n      })\n    })\n\n    const monthShortFormatter = computed(() => {\n      return base.getFormatter({\n        timeZone: 'UTC', month: 'short',\n      })\n    })\n\n    const title = computed((): string => {\n      const { start, end } = renderProps.value\n      const spanYears = start.year !== end.year\n      const spanMonths = spanYears || start.month !== end.month\n\n      if (spanYears) {\n        return monthShortFormatter.value(start, true) + ' ' + start.year + ' - ' + monthShortFormatter.value(end, true) + ' ' + end.year\n      }\n\n      if (spanMonths) {\n        return monthShortFormatter.value(start, true) + ' - ' + monthShortFormatter.value(end, true) + ' ' + end.year\n      } else {\n        return monthLongFormatter.value(start, false) + ' ' + start.year\n      }\n    })\n\n    function checkChange (): void {\n      const { start, end } = renderProps.value\n      if (!lastStart.value || !lastEnd.value ||\n        start.date !== lastStart.value.date ||\n        end.date !== lastEnd.value.date) {\n        lastStart.value = start\n        lastEnd.value = end\n        emit('change', { start, end })\n      }\n    }\n\n    function move (amount = 1): void {\n      const moved = copyTimestamp(base.parsedValue.value)\n      const forward = amount > 0\n      const mover = forward ? nextDay : prevDay\n      const limit = forward ? DAYS_IN_MONTH_MAX : DAY_MIN\n      let times = forward ? amount : -amount\n\n      while (--times >= 0) {\n        switch (props.type) {\n          case 'month':\n            moved.day = limit\n            mover(moved)\n            break\n          case 'week':\n            relativeDays(moved, mover, DAYS_IN_WEEK)\n            break\n          case 'day':\n            relativeDays(moved, mover, 1)\n            break\n          case '4day':\n            relativeDays(moved, mover, 4)\n            break\n          case 'category':\n            relativeDays(moved, mover, parsedCategoryDays.value)\n            break\n        }\n      }\n\n      updateWeekday(moved)\n      updateFormatted(moved)\n      updateRelative(moved, base.times.now)\n\n      if (props.modelValue instanceof Date) {\n        emit('update:modelValue', timestampToDate(moved))\n      } else if (typeof props.modelValue === 'number') {\n        emit('update:modelValue', timestampToDate(moved).getTime())\n      } else {\n        emit('update:modelValue', moved.date)\n      }\n\n      emit('moved', moved)\n    }\n\n    function next (amount = 1): void {\n      move(amount)\n    }\n\n    function prev (amount = 1): void {\n      move(-amount)\n    }\n\n    function getCategoryList (categories: CalendarCategory[]): CalendarCategory[] {\n      if (!base.noEvents.value) {\n        const categoryMap: any = categories.reduce((map: any, category, index) => {\n          if (typeof category === 'object' && category.categoryName) map[category.categoryName] = { index, count: 0 }\n          else if (typeof category === 'string') map[category] = { index, count: 0 }\n          return map\n        }, {})\n\n        if (!props.categoryHideDynamic || !props.categoryShowAll) {\n          let categoryLength = categories.length\n\n          base.parsedEvents.value.forEach(ev => {\n            let category = ev.category\n\n            if (typeof category !== 'string') {\n              category = props.categoryForInvalid\n            }\n\n            if (!category) {\n              return\n            }\n\n            if (category in categoryMap) {\n              categoryMap[category].count++\n            } else if (!props.categoryHideDynamic) {\n              categoryMap[category] = {\n                index: categoryLength++,\n                count: 1,\n              }\n            }\n          })\n        }\n\n        if (!props.categoryShowAll) {\n          for (const category in categoryMap) {\n            if (categoryMap[category].count === 0) {\n              delete categoryMap[category]\n            }\n          }\n        }\n\n        categories = categories.filter((category: CalendarCategory) => {\n          if (typeof category === 'object' && category.categoryName) {\n            return categoryMap.hasOwnProperty(category.categoryName)\n          } else if (typeof category === 'string') {\n            return categoryMap.hasOwnProperty(category)\n          }\n          return false\n        })\n      }\n      return categories\n    }\n\n    watch(renderProps, checkChange)\n\n    onMounted(() => {\n      base.updateEventVisibility()\n      checkChange()\n    })\n\n    onUpdated(() => {\n      window.requestAnimationFrame(base.updateEventVisibility)\n    })\n\n    useRender(() => {\n      const { start, end, maxDays, component: Component, categories } = renderProps.value\n      return (\n        <Component\n          ref={ root }\n          class={['v-calendar', { 'v-calendar-events': !base.noEvents.value }]}\n          v-resize_quiet={ base.updateEventVisibility }\n          role=\"grid\"\n          { ...Component.filterProps(props) }\n          start={ start.date }\n          end={ end.date }\n          maxDays={ maxDays }\n          weekdays={ base.effectiveWeekdays.value }\n          categories={ categories }\n          onClick:date={ (e: MouseEvent, day: CalendarTimestamp) => {\n            if (attrs['onUpdate:modelValue']) emit('update:modelValue', day.date)\n          }}\n          v-slots={ base.getScopedSlots() }\n        />\n      )\n    })\n\n    return forwardRefs({\n      ...base,\n      lastStart,\n      lastEnd,\n      parsedCategoryDays,\n      renderProps,\n      eventWeekdays,\n      categoryMode,\n      title,\n      monthLongFormatter,\n      monthShortFormatter,\n      parsedCategories,\n      checkChange,\n      move,\n      next,\n      prev,\n      getCategoryList,\n    }, root)\n  },\n})\n\nexport type VCalendar = InstanceType<typeof VCalendar>\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/VCalendarCategory.sass",
    "content": "@use '../../styles/tools'\n@use '../../styles/settings'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-calendar-category\n    .v-calendar-category__column,\n    .v-calendar-category__column-header\n      border-right: $calendar-grid-color $calendar-line-width solid\n\n    .v-calendar-daily__head\n      background: $calendar-background\n      color: $calendar-on-background\n\n    .v-calendar-daily__intervals-head\n      background: $calendar-background\n      color: $calendar-on-background\n\n    .v-calendar-daily__intervals-body\n      background: $calendar-background\n      color: $calendar-on-background\n\n  .v-calendar-category\n    overflow: auto\n    position: relative\n\n    .v-calendar-category__category\n      text-align: center\n\n    .v-calendar-daily__day-container\n      width: min-content\n      .v-calendar-category__columns\n        position: absolute\n        height: 100%\n        width: 100%\n        top: 0\n\n    .v-calendar-daily__day-body\n      display: flex\n      flex: 1\n      width: 100%\n      height: 100%\n\n    .v-calendar-daily__head\n      flex-direction: row\n      width: min-content\n      min-width: 100%\n      position: sticky\n      top: 0\n      z-index: 2\n\n    .v-calendar-daily_head-day\n      width: auto\n      position: unset\n\n    .v-calendar-daily__intervals-head\n      position: sticky\n      left: 0\n      top: 0\n      z-index: 2\n\n    .v-calendar-daily_head-weekday\n      position: sticky\n      left: 50%\n      width: $calendar-daily-head-weekday-size\n\n    .v-calendar-daily_head-day-label\n      width: $calendar-daily-head-day-label-size\n      position: sticky\n      left: 50%\n\n    .v-calendar-daily__day\n      min-width: $calendar-category-column-min-width\n\n    .v-calendar-daily__intervals-body\n      position: sticky\n      left: 0\n      z-index: 1\n\n    .v-calendar-daily__interval\n      &:last-of-type::after\n        display: none\n\n    .v-calendar-daily__body\n      overflow: visible\n      .v-calendar-daily__scroll-area\n        overflow-y: visible\n        flex: none\n\n    .v-calendar-daily__pane\n      overflow-y: visible\n\n    .v-calendar-category__columns\n      display: flex\n      width: min-content\n      min-width: 100%\n\n      .v-calendar-category__column,\n      .v-calendar-category__column-header\n        flex: 1 1 auto\n        width: 0\n        position: relative\n\n      .v-calendar-category__column-header\n        min-width: $calendar-category-column-min-width\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/VCalendarCategory.tsx",
    "content": "// Components\nimport { VCalendarDaily } from './VCalendarDaily'\n\n// Composables\nimport { makeCalendarBaseProps } from './composables/calendarBase'\nimport { makeCalendarWithIntervalsProps, useCalendarWithIntervals } from './composables/calendarWithIntervals'\n\n// Utilities\nimport { computed } from 'vue'\nimport { getParsedCategories } from './util/parser'\nimport { convertToUnit, defineComponent, getPrefixedEventHandlers, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { CalendarCategory, CalendarCategoryTextFunction, CalendarTimestamp } from './types'\n\nexport const VCalendarCategory = defineComponent({\n  name: 'VCalendarCategory',\n\n  props: {\n    categories: {\n      type: [Array, String] as PropType<CalendarCategory[] | string>,\n      default: '',\n    },\n    categoryText: [String, Function] as PropType<string | CalendarCategoryTextFunction>,\n    categoryForInvalid: {\n      type: String,\n      default: '',\n    },\n\n    ...makeCalendarBaseProps(),\n    ...makeCalendarWithIntervalsProps(),\n  },\n\n  setup (props, { slots, attrs }) {\n    const base = useCalendarWithIntervals(props)\n\n    const parsedCategories = computed((): CalendarCategory[] => {\n      return getParsedCategories(props.categories, props.categoryText)\n    })\n\n    function getCategoryScope (scope: any, category: CalendarCategory) {\n      const cat = typeof category === 'object' && category &&\n          category.categoryName === props.categoryForInvalid ? null : category\n      return {\n        ...scope,\n        category: cat,\n      }\n    }\n\n    function genDayHeader (scope: CalendarTimestamp & { week: any, index: number }) {\n      return (\n        <div class=\"v-calendar-category__columns\">\n          { parsedCategories.value.map(category => {\n            return genDayHeaderCategory(scope, getCategoryScope(scope, category))\n          })}\n        </div>\n      )\n    }\n\n    function genDayHeaderCategory (day: CalendarTimestamp, scope: any) {\n      const headerTitle = typeof scope.category === 'object' ? scope.category.categoryName : scope.category\n      const events = getPrefixedEventHandlers(attrs, ':dayCategory', () => {\n        return getCategoryScope(base.getSlotScope(day) || day, scope.category)\n      })\n      return (\n        <div\n          class=\"v-calendar-category__column-header\"\n          { ...events }\n        >\n          { slots.category?.(scope) ?? genDayHeaderCategoryTitle(headerTitle) }\n          { slots['day-header']?.(scope) }\n        </div>\n      )\n    }\n\n    function genDayHeaderCategoryTitle (categoryName: string | null) {\n      return (\n        <div class=\"v-calendar-category__category\">\n          { categoryName === null ? props.categoryForInvalid : categoryName }\n        </div>\n      )\n    }\n\n    function genDays () {\n      const days: any[] = []\n      base.days.value.forEach((d: CalendarTimestamp, j: number) => {\n        const day = new Array(parsedCategories.value.length || 1)\n        day.fill(d)\n        days.push(...day.map((v: CalendarTimestamp, i: number) => genDay(v, j, i)))\n      })\n      return days\n    }\n\n    function genDay (day: CalendarTimestamp, index: number, categoryIndex: number) {\n      const category = parsedCategories.value[categoryIndex]\n      const events = getPrefixedEventHandlers(attrs, ':time', e => {\n        return base.getSlotScope(base.getTimestampAtEvent(e, day))\n      })\n      return (\n        <div\n          key={ day.date + '-' + categoryIndex }\n          class={['v-calendar-daily__day', base.getRelativeClasses(day)]}\n          { ...events }\n        >\n          { genDayIntervals(index, category) }\n          { genDayBody(day, category) }\n        </div>\n      )\n    }\n\n    function genDayIntervals (index: number, category: CalendarCategory) {\n      return base.intervals.value[index].map((v: CalendarTimestamp) => genDayInterval(v, category))\n    }\n\n    function genDayInterval (interval: CalendarTimestamp, category: CalendarCategory) {\n      const height: string | undefined = convertToUnit(props.intervalHeight)\n      const styler = props.intervalStyle || base.intervalStyleDefault\n\n      return (\n        <div\n          key={ interval.time }\n          class=\"v-calendar-daily__day-interval\"\n          style={[{ height }, styler({ ...interval, category })]}\n        >\n          { slots.interval?.(\n            getCategoryScope(base.getSlotScope(interval), category)\n          )}\n        </div>\n      )\n    }\n\n    function genDayBody (day: CalendarTimestamp, category: CalendarCategory) {\n      return (\n        <div class=\"v-calendar-category__columns\">\n          { genDayBodyCategory(day, category) }\n        </div>\n      )\n    }\n\n    function genDayBodyCategory (day: CalendarTimestamp, category: CalendarCategory) {\n      const events = getPrefixedEventHandlers(attrs, ':timeCategory', e => {\n        return getCategoryScope(\n          base.getSlotScope(base.getTimestampAtEvent(e, day)),\n          category\n        )\n      })\n\n      return (\n        <div class=\"v-calendar-category__column\" { ...events }>\n          { slots['day-body']?.(getCategoryScope(base.getSlotScope(day), category)) }\n        </div>\n      )\n    }\n\n    useRender(() => (\n      <VCalendarDaily\n        class={[\n          'v-calendar-daily',\n          'v-calendar-category',\n        ]}\n        { ...props }\n      >\n        {{\n          ...slots,\n          days: genDays,\n          'day-header': genDayHeader,\n        }}\n      </VCalendarDaily>\n    ))\n\n    return {\n      ...base,\n      parsedCategories,\n    }\n  },\n})\n\nexport type VCalendarCategory = InstanceType<typeof VCalendarCategory>\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/VCalendarDaily.sass",
    "content": "@use '../../styles/tools'\n@use '../../styles/settings'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-calendar-daily\n    background-color: $calendar-background\n    color: $calendar-on-background\n    border-left: $calendar-outline-color $calendar-line-width solid\n    border-top: $calendar-outline-color $calendar-line-width solid\n\n    .v-calendar-daily__intervals-head\n      border-right: $calendar-grid-color $calendar-line-width solid\n\n      &::after\n        background: $calendar-grid-color\n        background: linear-gradient(90deg, transparent, $calendar-grid-color)\n\n    .v-calendar-daily_head-day\n      border-right: $calendar-grid-color $calendar-line-width solid\n      border-bottom: $calendar-grid-color $calendar-line-width solid\n\n      &.v-past\n        .v-calendar-daily_head-weekday,\n        .v-calendar-daily_head-day-label\n          color: $calendar-past-color\n\n    .v-calendar-daily__intervals-body\n      border-right: $calendar-grid-color $calendar-line-width solid\n\n      .v-calendar-daily__interval-text\n        color: $calendar-interval-text-color\n\n    .v-calendar-daily__day\n      border-right: $calendar-grid-color $calendar-line-width solid\n      border-bottom: $calendar-grid-color $calendar-line-width solid\n\n    .v-calendar-daily__day-interval\n      border-top: $calendar-grid-color $calendar-line-width solid\n\n      &:first-child\n        border-top: none\n\n    .v-calendar-daily__interval::after\n      border-top: $calendar-grid-color $calendar-line-width solid\n\n  .v-calendar-daily\n    display: flex\n    flex-direction: column\n    overflow: hidden\n    height: 100%\n\n  .v-calendar-daily__head\n    flex: none\n    display: flex\n\n  .v-calendar-daily__intervals-head\n    flex: none\n    position: relative\n\n    &::after\n      position: absolute\n      bottom: 0px\n      height: $calendar-line-width\n      left: 0\n      right: 0\n      content: ''\n\n  .v-calendar-daily_head-day\n    flex: 1 1 auto\n    width: 0\n    position: relative\n\n  .v-calendar-daily_head-weekday\n    user-select: none\n    padding: $calendar-daily-weekday-padding\n    font-size: $calendar-daily-weekday-font-size\n    text-align: center\n    text-transform: uppercase\n\n  .v-calendar-daily_head-day-label\n    user-select: none\n    padding: $calendar-daily-day-padding\n    cursor: pointer\n    text-align: center\n\n  .v-calendar-daily__body\n    flex: 1 1 60%\n    overflow: hidden\n    display: flex\n    position: relative\n    flex-direction: column\n\n  .v-calendar-daily__scroll-area\n    overflow-y: scroll\n    flex: 1 1 auto\n    display: flex\n    align-items: flex-start\n\n  .v-calendar-daily__pane\n    width: 100%\n    overflow-y: hidden\n    flex: none\n    display: flex\n    align-items: flex-start\n\n  .v-calendar-daily__day-container\n    display: flex\n    flex: 1\n    width: 100%\n    height: 100%\n\n  .v-calendar-daily__intervals-body\n    flex: none\n    user-select: none\n\n  .v-calendar-daily__interval\n    text-align: $calendar-daily-interval-gutter-align\n    padding-right: $calendar-daily-interval-gutter-line-width\n    border-bottom: none\n    position: relative\n\n    &::after\n      width: $calendar-daily-interval-gutter-line-width\n      position: absolute\n      height: $calendar-line-width\n      display: block\n      content: ''\n      right: 0\n      bottom: -$calendar-line-width\n\n  .v-calendar-daily__interval-text\n    display: block\n    position: relative\n    top: $calendar-daily-interval-gutter-top\n    font-size: $calendar-daily-interval-gutter-font-size\n    padding-right: $calendar-daily-interval-gutter-width\n\n  .v-calendar-daily__day\n    flex: 1\n    width: 0\n    position: relative\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/VCalendarDaily.tsx",
    "content": "// Components\nimport { VIconBtn } from '@/labs/VIconBtn'\n\n// Composables\nimport { makeCalendarBaseProps } from './composables/calendarBase'\nimport { makeCalendarWithIntervalsProps, useCalendarWithIntervals } from './composables/calendarWithIntervals'\n\n// Directives\nimport vResize from '@/directives/resize'\n\n// Utilities\nimport { nextTick, onMounted, ref } from 'vue'\nimport { convertToUnit, defineComponent, getPrefixedEventHandlers, noop, useRender } from '@/util'\n\n// Types\nimport type { CalendarTimestamp } from './types'\n\nexport const VCalendarDaily = defineComponent({\n  name: 'VCalendarDaily',\n\n  directives: { vResize },\n\n  props: {\n    color: String,\n    shortWeekdays: {\n      type: Boolean,\n      default: true,\n    },\n    shortIntervals: {\n      type: Boolean,\n      default: true,\n    },\n    hideHeader: Boolean,\n\n    ...makeCalendarBaseProps(),\n    ...makeCalendarWithIntervalsProps(),\n  },\n\n  setup (props, { slots, attrs }) {\n    const scrollPush = ref(0)\n    const pane = ref<HTMLElement>()\n    const base = useCalendarWithIntervals(props)\n\n    function init () {\n      nextTick(onResize)\n    }\n\n    function onResize () {\n      scrollPush.value = getScrollPush()\n    }\n\n    function getScrollPush (): number {\n      return base.scrollAreaRef.value && pane.value\n        ? (base.scrollAreaRef.value.offsetWidth - pane.value.offsetWidth)\n        : 0\n    }\n\n    function genHead () {\n      return (\n        <div\n          class=\"v-calendar-daily__head\"\n          style={{ marginRight: scrollPush.value + 'px' }}\n        >\n          { genHeadIntervals() }\n          { genHeadDays() }\n        </div>\n      )\n    }\n\n    function genHeadIntervals () {\n      const width: string | undefined = convertToUnit(props.intervalWidth)\n      return (\n        <div\n          class=\"v-calendar-daily__intervals-head\"\n          style={{ width }}\n        >\n          { slots['interval-header']?.() }\n        </div>\n      )\n    }\n\n    function genHeadDays () {\n      return base.days.value.map(genHeadDay)\n    }\n\n    function genHeadDay (day: CalendarTimestamp, index: number) {\n      const events = getPrefixedEventHandlers(attrs, ':day', nativeEvent => ({\n        nativeEvent, ...base.getSlotScope(day),\n      }))\n      return (\n        <div\n          key={ day.date }\n          class={['v-calendar-daily_head-day', base.getRelativeClasses(day)]}\n          { ...events }\n        >\n          { genHeadWeekday(day) }\n          { genHeadDayLabel(day) }\n          { genDayHeader(day, index) }\n        </div>\n      )\n    }\n\n    function genDayHeader (day: CalendarTimestamp, index: number) {\n      return slots['day-header']?.({\n        week: base.days.value,\n        ...day,\n        index,\n      }) ?? []\n    }\n\n    function genHeadWeekday (day: CalendarTimestamp) {\n      const color = day.present ? props.color : undefined\n      return (\n        <div\n          { ...base.getColorProps({ text: color }) }\n          class=\"v-calendar-daily_head-weekday\"\n        >\n          { base.weekdayFormatter.value(day, props.shortWeekdays) }\n        </div>\n      )\n    }\n\n    function genHeadDayLabel (day: CalendarTimestamp) {\n      return (\n        <div class=\"v-calendar-daily_head-day-label\">\n          { slots['day-label-header']?.(day) ?? genHeadDayButton(day) }\n        </div>\n      )\n    }\n\n    function genHeadDayButton (day: CalendarTimestamp) {\n      const events = getPrefixedEventHandlers(attrs, ':date', nativeEvent => ({\n        nativeEvent, ...day,\n      }))\n      return (\n        <VIconBtn\n          active={ day.present }\n          activeColor={ props.color }\n          variant=\"outlined\"\n          baseVariant=\"text\"\n          onUpdate:active={ noop }\n          { ...events }\n        >\n          { base.dayFormatter.value(day, false) }\n        </VIconBtn>\n      )\n    }\n\n    function genBody () {\n      return (\n        <div class=\"v-calendar-daily__body\">\n          { genScrollArea() }\n        </div>\n      )\n    }\n\n    function genScrollArea () {\n      return (\n        <div ref={ base.scrollAreaRef } class=\"v-calendar-daily__scroll-area\">\n          { genPane() }\n        </div>\n      )\n    }\n\n    function genPane () {\n      return (\n        <div\n          ref={ pane }\n          class=\"v-calendar-daily__pane\"\n          style={{ height: convertToUnit(base.bodyHeight.value) }}\n        >\n          { genDayContainer() }\n        </div>\n      )\n    }\n\n    function genDayContainer () {\n      return (\n        <div class=\"v-calendar-daily__day-container\">\n          { genBodyIntervals() }\n          { slots.days?.() ?? genDays() }\n        </div>\n      )\n    }\n\n    function genDays () {\n      return base.days.value.map((day, index) => {\n        const events = getPrefixedEventHandlers(attrs, ':time', nativeEvent => ({\n          nativeEvent,\n          ...base.getSlotScope(base.getTimestampAtEvent(nativeEvent, day)),\n        }))\n        return (\n          <div\n            key={ day.date }\n            class={['v-calendar-daily__day', base.getRelativeClasses(day)]}\n            { ...events }\n          >\n            { genDayIntervals(index) }\n            { genDayBody(day) }\n          </div>\n        )\n      })\n    }\n\n    function genDayBody (day: CalendarTimestamp) {\n      return slots['day-body']?.(base.getSlotScope(day)) ?? []\n    }\n\n    function genDayIntervals (index: number) {\n      return base.intervals.value[index].map(genDayInterval)\n    }\n\n    function genDayInterval (interval: CalendarTimestamp) {\n      const height: string | undefined = convertToUnit(props.intervalHeight)\n      const styler = props.intervalStyle || base.intervalStyleDefault\n      return (\n        <div\n          class=\"v-calendar-daily__day-interval\"\n          key={ interval.time }\n          style={[{ height }, styler(interval)]}\n        >\n          { slots.interval?.(base.getSlotScope(interval)) }\n        </div>\n      )\n    }\n\n    function genBodyIntervals () {\n      const width: string | undefined = convertToUnit(props.intervalWidth)\n      const events = getPrefixedEventHandlers(attrs, ':interval', nativeEvent => ({\n        nativeEvent, ...base.getTimestampAtEvent(nativeEvent, base.parsedStart.value),\n      }))\n      return (\n        <div\n          class=\"v-calendar-daily__intervals-body\"\n          style={{ width }}\n          { ...events }\n        >\n          { genIntervalLabels() }\n        </div>\n      )\n    }\n\n    function genIntervalLabels () {\n      if (!base.intervals.value.length) return null\n      return base.intervals.value[0].map(genIntervalLabel)\n    }\n\n    function genIntervalLabel (interval: CalendarTimestamp) {\n      const height: string | undefined = convertToUnit(props.intervalHeight)\n      const short = props.shortIntervals\n      const shower = props.showIntervalLabel || base.showIntervalLabelDefault\n      const show = shower(interval)\n      const label = show ? base.intervalFormatter.value(interval, short) : undefined\n      return (\n        <div\n          key={ interval.time }\n          class=\"v-calendar-daily__interval\"\n          style={{ height }}\n        >\n          <div class=\"v-calendar-daily__interval-text\">\n            { label }\n          </div>\n        </div>\n      )\n    }\n\n    onMounted(init)\n\n    useRender(() => (\n      <div\n        class={['v-calendar-daily', attrs.class]}\n        onDragstart={ (e: MouseEvent) => e.preventDefault() }\n        v-resize_quiet={ onResize }\n      >\n        { !props.hideHeader ? genHead() : undefined }\n        { genBody() }\n      </div>\n    ))\n\n    return {\n      ...base,\n      scrollPush,\n      pane,\n      init,\n      onResize,\n      getScrollPush,\n    }\n  },\n})\n\nexport type VCalendarDaily = InstanceType<typeof VCalendarDaily>\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/VCalendarWeekly.sass",
    "content": "@use '../../styles/tools'\n@use '../../styles/settings'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-calendar-weekly\n    background-color: $calendar-background\n    color: $calendar-on-background\n    border-top: $calendar-outline-color $calendar-line-width solid\n    border-left: $calendar-outline-color $calendar-line-width solid\n\n    .v-calendar-weekly__head-weekday\n      border-right: $calendar-grid-color $calendar-line-width solid\n\n      &.v-past\n        color: $calendar-past-color\n\n      &.v-outside\n        background-color: $calendar-outside-background\n        color: $calendar-on-outside-background\n\n    .v-calendar-weekly__head-weeknumber\n      background-color: $calendar-weeknumber-background\n      color: $calendar-on-weeknumber-background\n      border-right: $calendar-grid-color $calendar-line-width solid\n\n    .v-calendar-weekly__day\n      border-right: $calendar-grid-color $calendar-line-width solid\n      border-bottom: $calendar-grid-color $calendar-line-width solid\n\n      &.v-outside\n        background-color: $calendar-outside-background\n        color: $calendar-on-outside-background\n\n    .v-calendar-weekly__weeknumber\n        background-color: $calendar-weeknumber-background\n        color: $calendar-on-weeknumber-background\n        border-right: $calendar-grid-color $calendar-line-width solid\n        border-bottom: $calendar-grid-color $calendar-line-width solid\n\n  .v-calendar-weekly\n    width: 100%\n    height: 100%\n    display: flex\n    flex-direction: column\n    // https://github.com/vuetifyjs/vuetify/issues/8319\n    min-height: 0\n\n  .v-calendar-weekly__head\n    display: flex\n    user-select: none\n\n  .v-calendar-weekly__head-weekday\n    flex: 1 0 20px\n    user-select: none\n    padding: $calendar-weekly-weekday-padding\n    font-size: $calendar-weekly-weekday-font-size\n    overflow: hidden\n    text-align: center\n    text-overflow: ellipsis\n    text-transform: uppercase\n    white-space: nowrap\n\n  .v-calendar-weekly__head-weeknumber\n    position: relative\n    flex: 0 0 $calendar-weekly-weeknumber-flex-basis\n\n  .v-calendar-weekly__week\n    display: flex\n    flex: 1\n    height: unset\n    // https://github.com/vuetifyjs/vuetify/issues/8319\n    min-height: 0\n\n  .v-calendar-weekly__weeknumber\n    display: flex\n    flex: 0 0 $calendar-weekly-weeknumber-flex-basis\n    height: unset\n    min-height: 0\n    padding-top: $calendar-weekly-weeknumber-padding-top\n    text-align: center\n\n    > small\n      width: 100%\n\n  .v-calendar-weekly__day\n    flex: 1\n    width: 0\n    overflow: hidden\n    user-select: none\n    position: relative\n    padding: $calendar-weekly-day-padding\n    // https://github.com/vuetifyjs/vuetify/issues/9058\n    // https://bugzilla.mozilla.org/show_bug.cgi?id=1114904\n    min-width: 0\n\n    &.v-present\n      .v-calendar-weekly__day-month\n        color: currentColor\n\n  .v-calendar-weekly__day-label\n    text-decoration: none\n    user-select: none\n    cursor: pointer\n    box-shadow: none\n    text-align: center\n    margin: $calendar-weekly-day-label-margin\n\n    .v-icon-btn\n      font-size: $calendar-weekly-day-label-font-size\n\n  .v-calendar-weekly__day-month\n    position: absolute\n    text-decoration: none\n    user-select: none\n    box-shadow: none\n    top: 0\n    left: $calendar-weekly-day-month-left\n    height: $calendar-weekly-day-label-size\n    line-height: $calendar-weekly-day-label-size\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/VCalendarWeekly.tsx",
    "content": "// Components\nimport { VIconBtn } from '@/labs/VIconBtn'\n\n// Composables\nimport { makeCalendarBaseProps, useCalendarBase } from './composables/calendarBase'\nimport { useTheme } from '@/composables'\n\n// Utilities\nimport { computed } from 'vue'\nimport {\n  createDayList,\n  createNativeLocaleFormatter,\n  getDayIdentifier,\n  validateNumber,\n} from './util/timestamp'\nimport { defineComponent, getPrefixedEventHandlers, noop, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { CalendarFormatter, CalendarTimestamp } from './types'\n\nexport const VCalendarWeekly = defineComponent({\n  name: 'VCalendarWeekly',\n\n  props: {\n    minWeeks: {\n      validate: validateNumber,\n      default: 1,\n    },\n    monthFormat: Function as PropType<CalendarFormatter>,\n    showWeek: Boolean,\n    color: String,\n    shortWeekdays: {\n      type: Boolean,\n      default: true,\n    },\n    showMonthOnFirst: {\n      type: Boolean,\n      default: true,\n    },\n    shortMonths: {\n      type: Boolean,\n      default: true,\n    },\n    hideHeader: Boolean,\n\n    ...makeCalendarBaseProps(),\n  },\n\n  setup (props, { slots, attrs }) {\n    const base = useCalendarBase(props)\n\n    const theme = useTheme()\n\n    const parsedMinWeeks = computed((): number => {\n      return parseInt(String(props.minWeeks))\n    })\n\n    const days = computed((): CalendarTimestamp[] => {\n      const minDays = parsedMinWeeks.value * base.parsedWeekdays.value.length\n      const start = base.getStartOfWeek(base.parsedStart.value)\n      const end = base.getEndOfWeek(base.parsedEnd.value)\n\n      return createDayList(\n        start,\n        end,\n        base.times.today,\n        base.weekdaySkips.value,\n        Number.MAX_SAFE_INTEGER,\n        minDays\n      )\n    })\n\n    const todayWeek = computed((): CalendarTimestamp[] => {\n      const today = base.times.today\n      const start = base.getStartOfWeek(today)\n      const end = base.getEndOfWeek(today)\n\n      return createDayList(\n        start,\n        end,\n        today,\n        base.weekdaySkips.value,\n        base.parsedWeekdays.value.length,\n        base.parsedWeekdays.value.length\n      )\n    })\n\n    const monthFormatter = computed((): CalendarFormatter => {\n      if (props.monthFormat) {\n        // TODO: what happens when this is a string?\n        return props.monthFormat as CalendarFormatter\n      }\n\n      return createNativeLocaleFormatter(\n        base.locale.current.value,\n        (_tms, short) => ({ timeZone: 'UTC', month: short ? 'short' : 'long' })\n      )\n    })\n\n    function isOutside (day: CalendarTimestamp): boolean {\n      const dayIdentifier = getDayIdentifier(day)\n\n      return dayIdentifier < getDayIdentifier(base.parsedStart.value) ||\n             dayIdentifier > getDayIdentifier(base.parsedEnd.value)\n    }\n\n    function genHead () {\n      return (\n        <div class=\"v-calendar-weekly__head\" role=\"row\">\n          { genHeadDays() }\n        </div>\n      )\n    }\n\n    function genHeadDays () {\n      const header = todayWeek.value.map(genHeadDay)\n\n      if (props.showWeek) {\n        header.unshift(\n          <div class=\"v-calendar-weekly__head-weeknumber\" />\n        )\n      }\n\n      return header\n    }\n\n    function genHeadDay (day: CalendarTimestamp, index: number) {\n      const outside = isOutside(days.value[index])\n      const color = day.present ? props.color : undefined\n\n      return (\n        <div\n          { ...base.getColorProps({ text: color }) }\n          key={ day.date }\n          class={['v-calendar-weekly__head-weekday', base.getRelativeClasses(day, outside)]}\n          role=\"columnheader\"\n        >\n          { base.weekdayFormatter.value(day, props.shortWeekdays) }\n        </div>\n      )\n    }\n\n    function genWeeks () {\n      const daysValue = days.value\n      const weekDays = base.parsedWeekdays.value.length\n      const weeks: any[] = []\n\n      for (let i = 0; i < daysValue.length; i += weekDays) {\n        weeks.push(genWeek(daysValue.slice(i, i + weekDays), getWeekNumber(daysValue[i])))\n      }\n\n      return weeks\n    }\n\n    function genWeek (week: CalendarTimestamp[], weekNumber: number) {\n      const weekNodes = week.map((day, index) => genDay(day, index, week))\n\n      if (props.showWeek) {\n        weekNodes.unshift(genWeekNumber(weekNumber))\n      }\n\n      return (\n        <div\n          key={ week[0].date }\n          class=\"v-calendar-weekly__week\"\n          role=\"row\"\n        >\n          { weekNodes }\n        </div>\n      )\n    }\n\n    function getWeekNumber (determineDay: CalendarTimestamp) {\n      return base.getWeekNumber(determineDay)\n    }\n\n    function genWeekNumber (weekNumber: number) {\n      return (\n        <div class=\"v-calendar-weekly__weeknumber\">\n          <small>{ String(weekNumber) }</small>\n        </div>\n      )\n    }\n\n    function genDay (day: CalendarTimestamp, index: number, week: CalendarTimestamp[]) {\n      const outside = isOutside(day)\n      const events = getPrefixedEventHandlers(attrs, ':day', nativeEvent => {\n        return { nativeEvent, ...day }\n      })\n\n      return (\n        <div\n          key={ day.date }\n          class={['v-calendar-weekly__day', base.getRelativeClasses(day, outside)]}\n          role=\"cell\"\n          { ...events }\n        >\n          { genDayLabel(day) }\n          { slots.day?.({ outside, index, week, ...day }) }\n        </div>\n      )\n    }\n\n    function genDayLabel (day: CalendarTimestamp) {\n      return (\n        <div class=\"v-calendar-weekly__day-label\">\n          { slots['day-label']?.(day) ?? genDayLabelButton(day) }\n        </div>\n      )\n    }\n\n    function genDayLabelButton (day: CalendarTimestamp) {\n      const hasMonth = day.day === 1 && props.showMonthOnFirst\n      const events = getPrefixedEventHandlers(attrs, ':date', nativeEvent => ({ nativeEvent, ...day }))\n\n      return (\n        <VIconBtn\n          active={ day.present }\n          activeColor={ props.color }\n          variant=\"outlined\"\n          baseVariant=\"text\"\n          onUpdate:active={ noop }\n          { ...events }\n        >\n          { hasMonth\n            ? monthFormatter.value(day, props.shortMonths) + ' ' + base.dayFormatter.value(day, false)\n            : base.dayFormatter.value(day, false)\n          }\n        </VIconBtn>\n      )\n    }\n\n    useRender(() => (\n      <div\n        class={['v-calendar-weekly', theme.themeClasses.value]}\n        onDragstart={ (e: MouseEvent) => e.preventDefault() }\n      >\n        { !props.hideHeader ? genHead() : undefined }\n        { genWeeks() }\n      </div>\n    ))\n\n    return {\n      ...base,\n      days,\n      todayWeek,\n      monthFormatter,\n      isOutside,\n    }\n  },\n})\n\nexport type VCalendarWeekly = InstanceType<typeof VCalendarWeekly>\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/_variables.scss",
    "content": "@use '../../styles/settings';\n\n$calendar-line-width: 1px !default;\n\n$calendar-daily-head-day-label-size: 56px !default;\n$calendar-daily-head-weekday-size: 50px !default;\n$calendar-daily-weekday-padding: 3px 0px 0px 0px !default;\n$calendar-daily-weekday-font-size: 11px !default;\n$calendar-daily-day-padding: 0px 0px 3px 0px !default;\n$calendar-daily-day-font-size: 40px !default;\n$calendar-daily-interval-gutter-top: -6px !default;\n$calendar-daily-interval-gutter-width: 4px !default;\n$calendar-daily-interval-gutter-align: right !default;\n$calendar-daily-interval-gutter-line-width: 8px !default;\n$calendar-daily-interval-gutter-font-size: 10px !default;\n\n$calendar-category-column-min-width: 200px !default;\n\n$calendar-weekly-weekday-padding: 0px 4px 0px 4px !default;\n$calendar-weekly-weekday-font-size: 11px !default;\n$calendar-weekly-day-padding: 0px 0px 0px 0px !default;\n$calendar-weekly-day-label-size: 32px !default;\n$calendar-weekly-day-label-font-size: 12px !default;\n$calendar-weekly-day-label-margin: 4px 0 0 0 !default;\n$calendar-weekly-day-month-left: 36px !default;\n$calendar-weekly-weeknumber-flex-basis: 24px !default;\n$calendar-weekly-weeknumber-padding-top: 14.5px !default;\n\n$calendar-event-bottom-space: 1px !default;\n$calendar-event-border-width: 1px !default;\n$calendar-event-border-radius: settings.$border-radius-root !default;\n$calendar-event-font-size: 12px !default;\n$calendar-event-line-height: 20px !default;\n$calendar-event-right-empty: 10px !default;\n\n$calendar-background: rgb(var(--v-theme-surface)) !default;\n$calendar-on-background: rgb(var(--v-theme-on-surface)) !default;\n$calendar-outside-background: rgb(var(--v-theme-surface-light)) !default;\n$calendar-on-outside-background: rgb(var(--v-theme-on-surface-light)) !default;\n$calendar-weeknumber-background: rgb(var(--v-theme-surface)) !default;\n$calendar-on-weeknumber-background: rgb(var(--v-theme-on-surface)) !default;\n$calendar-outline-color: rgba(var(--v-border-color), var(--v-border-opacity)) !default;\n$calendar-grid-color: rgba(var(--v-border-color), var(--v-border-opacity)) !default;\n$calendar-past-color: rgb(var(--v-theme-on-surface)) !default;\n$calendar-interval-text-color: rgb(var(--v-theme-on-surface)) !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/composables/__tests__/__snapshots__/calendar-base.spec.ts.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`calendar-base.ts should create a day list 1`] = `\nArray [\n  Object {\n    \"date\": \"2019-01-29\",\n    \"day\": 29,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 1,\n    \"past\": true,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 2,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-01-30\",\n    \"day\": 30,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 1,\n    \"past\": true,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 3,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-01-31\",\n    \"day\": 31,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 1,\n    \"past\": true,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 4,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-02-01\",\n    \"day\": 1,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": true,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 5,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-02-02\",\n    \"day\": 2,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": true,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 6,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-02-03\",\n    \"day\": 3,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": true,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 0,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-02-04\",\n    \"day\": 4,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": true,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 1,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-02-05\",\n    \"day\": 5,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": true,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 2,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-02-06\",\n    \"day\": 6,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": true,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 3,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-02-07\",\n    \"day\": 7,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": true,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 4,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-02-08\",\n    \"day\": 8,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": true,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 5,\n    \"year\": 2019,\n  },\n]\n`;\n\nexports[`calendar-base.ts should generate classes 1`] = `\nObject {\n  \"v-future\": false,\n  \"v-outside\": false,\n  \"v-past\": false,\n  \"v-present\": false,\n}\n`;\n\nexports[`calendar-base.ts should generate classes with outside 1`] = `\nObject {\n  \"v-future\": false,\n  \"v-outside\": true,\n  \"v-past\": false,\n  \"v-present\": false,\n}\n`;\n\nexports[`calendar-base.ts should parse start & end 1`] = `\nObject {\n  \"date\": \"2019-01-29\",\n  \"day\": 29,\n  \"future\": false,\n  \"hasDay\": true,\n  \"hasTime\": false,\n  \"hour\": 0,\n  \"minute\": 0,\n  \"month\": 1,\n  \"past\": false,\n  \"present\": false,\n  \"time\": \"\",\n  \"weekday\": 2,\n  \"year\": 2019,\n}\n`;\n\nexports[`calendar-base.ts should parse start & end 2`] = `\nObject {\n  \"date\": \"2019-02-08\",\n  \"day\": 8,\n  \"future\": false,\n  \"hasDay\": true,\n  \"hasTime\": false,\n  \"hour\": 0,\n  \"minute\": 0,\n  \"month\": 2,\n  \"past\": false,\n  \"present\": false,\n  \"time\": \"\",\n  \"weekday\": 5,\n  \"year\": 2019,\n}\n`;\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/composables/__tests__/__snapshots__/calendar-with-events.spec.ts.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`calendar-with-events.ts should get events map 1`] = `\nObject {\n  \"2019-02-12\": Object {\n    \"events\": Array [\n      <div\n        data-date=\"2019-02-12\"\n        data-event=\"test\"\n      />,\n    ],\n    \"more\": null,\n    \"parent\": <div>\n      <div\n        data-date=\"2019-02-12\"\n        data-event=\"test\"\n      />\n      <div\n        data-date=\"2019-02-13\"\n        data-event=\"test1\"\n      />\n      <div\n        data-date=\"2019-02-13\"\n        data-event=\"test2\"\n        data-more=\"123\"\n      />\n    </div>,\n  },\n  \"2019-02-13\": Object {\n    \"events\": Array [\n      <div\n        data-date=\"2019-02-13\"\n        data-event=\"test1\"\n      />,\n    ],\n    \"more\": <div\n      data-date=\"2019-02-13\"\n      data-event=\"test2\"\n      data-more=\"123\"\n    />,\n    \"parent\": <div>\n      <div\n        data-date=\"2019-02-12\"\n        data-event=\"test\"\n      />\n      <div\n        data-date=\"2019-02-13\"\n        data-event=\"test1\"\n      />\n      <div\n        data-date=\"2019-02-13\"\n        data-event=\"test2\"\n        data-more=\"123\"\n      />\n    </div>,\n  },\n}\n`;\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/composables/__tests__/__snapshots__/calendar-with-intervals.spec.ts.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`calendar-with-intervals.ts should generate days 1`] = `\nArray [\n  Object {\n    \"date\": \"2019-01-29\",\n    \"day\": 29,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 1,\n    \"past\": true,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 2,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-01-30\",\n    \"day\": 30,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 1,\n    \"past\": true,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 3,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-01-31\",\n    \"day\": 31,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 1,\n    \"past\": true,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 4,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-02-01\",\n    \"day\": 1,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": true,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 5,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-02-02\",\n    \"day\": 2,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": true,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 6,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-02-03\",\n    \"day\": 3,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": true,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 0,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-02-04\",\n    \"day\": 4,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": true,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 1,\n    \"year\": 2019,\n  },\n]\n`;\n\nexports[`calendar-with-intervals.ts should generate days 2`] = `\nArray [\n  Object {\n    \"date\": \"2019-01-29\",\n    \"day\": 29,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 1,\n    \"past\": true,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 2,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-01-30\",\n    \"day\": 30,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 1,\n    \"past\": true,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 3,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-01-31\",\n    \"day\": 31,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 1,\n    \"past\": true,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 4,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-02-01\",\n    \"day\": 1,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": true,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 5,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-02-02\",\n    \"day\": 2,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": true,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 6,\n    \"year\": 2019,\n  },\n]\n`;\n\nexports[`calendar-with-intervals.ts should generate intervals 1`] = `\nArray [\n  Array [\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 0,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"00:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 1,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"01:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 2,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"02:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 3,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"03:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 4,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"04:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 5,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"05:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 6,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"06:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 7,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"07:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 8,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"08:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 9,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"09:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 10,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"10:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 11,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"11:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 12,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"12:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 13,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"13:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 14,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"14:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 15,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"15:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 16,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"16:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 17,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"17:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 18,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"18:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 19,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"19:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 20,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"20:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 21,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"21:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 22,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"22:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 23,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"23:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n  ],\n  Array [\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 0,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"00:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 1,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"01:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 2,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"02:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 3,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"03:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 4,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"04:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 5,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"05:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 6,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"06:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 7,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"07:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 8,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"08:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 9,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"09:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 10,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"10:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 11,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"11:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 12,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"12:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 13,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"13:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 14,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"14:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 15,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"15:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 16,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"16:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 17,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"17:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 18,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"18:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 19,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"19:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 20,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"20:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 21,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"21:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 22,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"22:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 23,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"23:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n  ],\n  Array [\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 0,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"00:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 1,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"01:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 2,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"02:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 3,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"03:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 4,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"04:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 5,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"05:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 6,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"06:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 7,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"07:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 8,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"08:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 9,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"09:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 10,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"10:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 11,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"11:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 12,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"12:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 13,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"13:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 14,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"14:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 15,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"15:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 16,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"16:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 17,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"17:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 18,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"18:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 19,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"19:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 20,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"20:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 21,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"21:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 22,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"22:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 23,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"23:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n  ],\n  Array [\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 0,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"00:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 1,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"01:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 2,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"02:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 3,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"03:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 4,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"04:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 5,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"05:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 6,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"06:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 7,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"07:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 8,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"08:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 9,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"09:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 10,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"10:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 11,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"11:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 12,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"12:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 13,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"13:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 14,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"14:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 15,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"15:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 16,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"16:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 17,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"17:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 18,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"18:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 19,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"19:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 20,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"20:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 21,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"21:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 22,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"22:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 23,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"23:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n  ],\n  Array [\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 0,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"00:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 1,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"01:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 2,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"02:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 3,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"03:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 4,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"04:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 5,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"05:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 6,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"06:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 7,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"07:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 8,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"08:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 9,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"09:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 10,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"10:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 11,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"11:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 12,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"12:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 13,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"13:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 14,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"14:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 15,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"15:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 16,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"16:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 17,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"17:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 18,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"18:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 19,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"19:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 20,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"20:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 21,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"21:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 22,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"22:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 23,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"23:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n  ],\n  Array [\n    Object {\n      \"date\": \"2019-02-03\",\n      \"day\": 3,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 0,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"00:00\",\n      \"weekday\": 0,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-03\",\n      \"day\": 3,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 1,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"01:00\",\n      \"weekday\": 0,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-03\",\n      \"day\": 3,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 2,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"02:00\",\n      \"weekday\": 0,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-03\",\n      \"day\": 3,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 3,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"03:00\",\n      \"weekday\": 0,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-03\",\n      \"day\": 3,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 4,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"04:00\",\n      \"weekday\": 0,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-03\",\n      \"day\": 3,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 5,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"05:00\",\n      \"weekday\": 0,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-03\",\n      \"day\": 3,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 6,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"06:00\",\n      \"weekday\": 0,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-03\",\n      \"day\": 3,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 7,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"07:00\",\n      \"weekday\": 0,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-03\",\n      \"day\": 3,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 8,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"08:00\",\n      \"weekday\": 0,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-03\",\n      \"day\": 3,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 9,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"09:00\",\n      \"weekday\": 0,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-03\",\n      \"day\": 3,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 10,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"10:00\",\n      \"weekday\": 0,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-03\",\n      \"day\": 3,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 11,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"11:00\",\n      \"weekday\": 0,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-03\",\n      \"day\": 3,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 12,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"12:00\",\n      \"weekday\": 0,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-03\",\n      \"day\": 3,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 13,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"13:00\",\n      \"weekday\": 0,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-03\",\n      \"day\": 3,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 14,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"14:00\",\n      \"weekday\": 0,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-03\",\n      \"day\": 3,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 15,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"15:00\",\n      \"weekday\": 0,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-03\",\n      \"day\": 3,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 16,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"16:00\",\n      \"weekday\": 0,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-03\",\n      \"day\": 3,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 17,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"17:00\",\n      \"weekday\": 0,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-03\",\n      \"day\": 3,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 18,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"18:00\",\n      \"weekday\": 0,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-03\",\n      \"day\": 3,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 19,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"19:00\",\n      \"weekday\": 0,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-03\",\n      \"day\": 3,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 20,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"20:00\",\n      \"weekday\": 0,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-03\",\n      \"day\": 3,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 21,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"21:00\",\n      \"weekday\": 0,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-03\",\n      \"day\": 3,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 22,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"22:00\",\n      \"weekday\": 0,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-03\",\n      \"day\": 3,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 23,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"23:00\",\n      \"weekday\": 0,\n      \"year\": 2019,\n    },\n  ],\n  Array [\n    Object {\n      \"date\": \"2019-02-04\",\n      \"day\": 4,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 0,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"00:00\",\n      \"weekday\": 1,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-04\",\n      \"day\": 4,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 1,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"01:00\",\n      \"weekday\": 1,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-04\",\n      \"day\": 4,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 2,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"02:00\",\n      \"weekday\": 1,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-04\",\n      \"day\": 4,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 3,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"03:00\",\n      \"weekday\": 1,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-04\",\n      \"day\": 4,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 4,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"04:00\",\n      \"weekday\": 1,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-04\",\n      \"day\": 4,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 5,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"05:00\",\n      \"weekday\": 1,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-04\",\n      \"day\": 4,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 6,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"06:00\",\n      \"weekday\": 1,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-04\",\n      \"day\": 4,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 7,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"07:00\",\n      \"weekday\": 1,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-04\",\n      \"day\": 4,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 8,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"08:00\",\n      \"weekday\": 1,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-04\",\n      \"day\": 4,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 9,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"09:00\",\n      \"weekday\": 1,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-04\",\n      \"day\": 4,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 10,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"10:00\",\n      \"weekday\": 1,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-04\",\n      \"day\": 4,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 11,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"11:00\",\n      \"weekday\": 1,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-04\",\n      \"day\": 4,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 12,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"12:00\",\n      \"weekday\": 1,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-04\",\n      \"day\": 4,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 13,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"13:00\",\n      \"weekday\": 1,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-04\",\n      \"day\": 4,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 14,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"14:00\",\n      \"weekday\": 1,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-04\",\n      \"day\": 4,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 15,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"15:00\",\n      \"weekday\": 1,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-04\",\n      \"day\": 4,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 16,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"16:00\",\n      \"weekday\": 1,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-04\",\n      \"day\": 4,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 17,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"17:00\",\n      \"weekday\": 1,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-04\",\n      \"day\": 4,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 18,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"18:00\",\n      \"weekday\": 1,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-04\",\n      \"day\": 4,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 19,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"19:00\",\n      \"weekday\": 1,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-04\",\n      \"day\": 4,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 20,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"20:00\",\n      \"weekday\": 1,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-04\",\n      \"day\": 4,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 21,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"21:00\",\n      \"weekday\": 1,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-04\",\n      \"day\": 4,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 22,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"22:00\",\n      \"weekday\": 1,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-04\",\n      \"day\": 4,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 23,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"23:00\",\n      \"weekday\": 1,\n      \"year\": 2019,\n    },\n  ],\n]\n`;\n\nexports[`calendar-with-intervals.ts should generate intervals 2`] = `\nArray [\n  Array [\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 0,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"00:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 1,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"01:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 2,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"02:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 3,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"03:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 4,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"04:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 5,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"05:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 6,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"06:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 7,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"07:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 8,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"08:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 9,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"09:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 10,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"10:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 11,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"11:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 12,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"12:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 13,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"13:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 14,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"14:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 15,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"15:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 16,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"16:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 17,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"17:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 18,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"18:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 19,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"19:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 20,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"20:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 21,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"21:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 22,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"22:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-29\",\n      \"day\": 29,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 23,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"23:00\",\n      \"weekday\": 2,\n      \"year\": 2019,\n    },\n  ],\n  Array [\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 0,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"00:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 1,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"01:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 2,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"02:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 3,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"03:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 4,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"04:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 5,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"05:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 6,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"06:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 7,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"07:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 8,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"08:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 9,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"09:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 10,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"10:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 11,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"11:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 12,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"12:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 13,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"13:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 14,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"14:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 15,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"15:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 16,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"16:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 17,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"17:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 18,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"18:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 19,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"19:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 20,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"20:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 21,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"21:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 22,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"22:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-30\",\n      \"day\": 30,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 23,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"23:00\",\n      \"weekday\": 3,\n      \"year\": 2019,\n    },\n  ],\n  Array [\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 0,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"00:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 1,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"01:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 2,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"02:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 3,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"03:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 4,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"04:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 5,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"05:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 6,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"06:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 7,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"07:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 8,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"08:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 9,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"09:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 10,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"10:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 11,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"11:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 12,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"12:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 13,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"13:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 14,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"14:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 15,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"15:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 16,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"16:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 17,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"17:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 18,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"18:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 19,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"19:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 20,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"20:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 21,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"21:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 22,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"22:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-01-31\",\n      \"day\": 31,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 23,\n      \"minute\": 0,\n      \"month\": 1,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"23:00\",\n      \"weekday\": 4,\n      \"year\": 2019,\n    },\n  ],\n  Array [\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 0,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"00:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 1,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"01:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 2,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"02:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 3,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"03:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 4,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"04:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 5,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"05:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 6,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"06:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 7,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"07:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 8,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"08:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 9,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"09:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 10,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"10:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 11,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"11:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 12,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"12:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 13,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"13:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 14,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"14:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 15,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"15:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 16,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"16:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 17,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"17:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 18,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"18:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 19,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"19:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 20,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"20:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 21,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"21:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 22,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"22:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-01\",\n      \"day\": 1,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 23,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"23:00\",\n      \"weekday\": 5,\n      \"year\": 2019,\n    },\n  ],\n  Array [\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 0,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"00:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 1,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"01:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 2,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"02:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 3,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"03:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 4,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"04:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 5,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"05:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 6,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"06:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 7,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"07:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 8,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"08:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 9,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"09:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 10,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"10:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 11,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"11:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 12,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"12:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 13,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"13:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 14,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"14:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 15,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"15:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 16,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"16:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 17,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"17:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 18,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"18:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 19,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"19:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 20,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"20:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 21,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"21:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 22,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"22:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n    Object {\n      \"date\": \"2019-02-02\",\n      \"day\": 2,\n      \"future\": false,\n      \"hasDay\": true,\n      \"hasTime\": true,\n      \"hour\": 23,\n      \"minute\": 0,\n      \"month\": 2,\n      \"past\": true,\n      \"present\": false,\n      \"time\": \"23:00\",\n      \"weekday\": 6,\n      \"year\": 2019,\n    },\n  ],\n]\n`;\n\nexports[`calendar-with-intervals.ts should generate slot scope 1`] = `\nObject {\n  \"date\": \"2019-02-08\",\n  \"day\": 8,\n  \"future\": false,\n  \"hasDay\": true,\n  \"hasTime\": false,\n  \"hour\": 0,\n  \"minute\": 0,\n  \"minutesToPixels\": [Function],\n  \"month\": 2,\n  \"past\": false,\n  \"present\": false,\n  \"time\": \"\",\n  \"timeDelta\": [Function],\n  \"timeToY\": [Function],\n  \"weekday\": 5,\n  \"year\": 2019,\n}\n`;\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/composables/__tests__/__snapshots__/times.spec.ts.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`times.ts should parse timestamp 1`] = `\nObject {\n  \"date\": \"2019-02-08\",\n  \"day\": 8,\n  \"future\": false,\n  \"hasDay\": true,\n  \"hasTime\": false,\n  \"hour\": 0,\n  \"minute\": 0,\n  \"month\": 2,\n  \"past\": false,\n  \"present\": false,\n  \"time\": \"\",\n  \"weekday\": 5,\n  \"year\": 2019,\n}\n`;\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/composables/__tests__/calendar-base.spec.ts",
    "content": "// @ts-nocheck\n/* eslint-disable */\n\n// import CalendarBase from '../calendar-base'\n// import { parseTimestamp } from '../../util/timestamp'\n// import {\n//   mount,\n//   Wrapper,\n//   MountOptions,\n// } from '@vue/test-utils'\n// import { ExtractVue } from '../../../../util/mixins'\n\n// const Mock = CalendarBase.extend({\n//   render: h => h('div'),\n// })\n\ndescribe.skip('calendar-base.ts', () => {\n  type Instance = ExtractVue<typeof Mock>\n  let mountFunction: (options?: MountOptions<Instance>) => Wrapper<Instance>\n  beforeEach(() => {\n    mountFunction = (options?: MountOptions<Instance>) => {\n      return mount(Mock, {\n        ...options,\n        mocks: {\n          $vuetify: {\n            lang: {\n              current: 'en-US',\n            },\n          },\n        },\n      })\n    }\n  })\n\n  it('should parse start & end', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        start: '2019-01-29',\n        end: '2019-02-08',\n      },\n    })\n\n    expect(wrapper.vm.parsedStart).toBeDefined()\n    expect(wrapper.vm.parsedStart).toMatchSnapshot()\n    expect(wrapper.vm.parsedEnd).toBeDefined()\n    expect(wrapper.vm.parsedEnd).toMatchSnapshot()\n  })\n\n  it('should create a day list', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        start: '2019-01-29',\n        end: '2019-02-08',\n      },\n    })\n\n    expect(wrapper.vm.days).toBeDefined()\n    expect(wrapper.vm.days).toHaveLength(11)\n    expect(wrapper.vm.days).toMatchSnapshot()\n\n    expect(wrapper.vm.days[0].date).toBe('2019-01-29')\n    expect(wrapper.vm.days[10].date).toBe('2019-02-08')\n  })\n\n  it('should calculate weekday skips', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        start: '2019-01-29',\n        end: '2019-02-08',\n      },\n    })\n\n    expect(wrapper.vm.weekdaySkips).toBeDefined()\n    expect(wrapper.vm.weekdaySkips).toHaveLength(7)\n  })\n\n  it('should generate classes', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        start: '2019-01-29',\n        end: '2019-02-08',\n      },\n    })\n\n    expect(wrapper.vm.getRelativeClasses(parseTimestamp('2019-01-28'))).toBeDefined()\n    expect(wrapper.vm.getRelativeClasses(parseTimestamp('2019-01-28'))).toMatchSnapshot()\n  })\n\n  it('should generate classes with outside', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        start: '2019-01-29',\n        end: '2019-02-08',\n      },\n    })\n\n    expect(wrapper.vm.getRelativeClasses(parseTimestamp('2019-01-28'), true)).toBeDefined()\n    expect(wrapper.vm.getRelativeClasses(parseTimestamp('2019-01-28'), true)).toMatchSnapshot()\n  })\n\n  it('should return weekdayFormatter equal to weekdayFormat prop', async () => {\n    const weekdayFormat = x => x\n    const wrapper = mountFunction({\n      propsData: {\n        weekdayFormat,\n      },\n    })\n\n    expect(wrapper.vm.weekdayFormatter).toEqual(weekdayFormat)\n  })\n\n  it('should long-format weekday', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        start: '2019-01-29',\n        end: '2019-02-08',\n      },\n    })\n\n    expect(wrapper.vm.weekdayFormatter).toBeDefined()\n    expect(typeof wrapper.vm.weekdayFormatter).toEqual('function')\n\n    expect(wrapper.vm.weekdayFormatter(parseTimestamp('2019-01-28'), false)).toEqual('Monday')\n    expect(wrapper.vm.weekdayFormatter(parseTimestamp('2019-01-27'), false)).toEqual('Sunday')\n    expect(wrapper.vm.weekdayFormatter(parseTimestamp('2019-01-29'), false)).toEqual('Tuesday')\n  })\n\n  it('should short-format weekday', async () => {\n    const wrapper = mountFunction()\n\n    expect(wrapper.vm.weekdayFormatter).toBeDefined()\n    expect(typeof wrapper.vm.weekdayFormatter).toEqual('function')\n\n    expect(wrapper.vm.weekdayFormatter(parseTimestamp('2019-01-28'), true)).toEqual('Mon')\n    expect(wrapper.vm.weekdayFormatter(parseTimestamp('2019-01-27'), true)).toEqual('Sun')\n    expect(wrapper.vm.weekdayFormatter(parseTimestamp('2019-01-29'), true)).toEqual('Tue')\n  })\n\n  it('should get start of week', async () => {\n    const wrapper = mountFunction()\n\n    expect(wrapper.vm.getStartOfWeek(parseTimestamp('2019-01-28')).weekday).toEqual(0)\n    expect(wrapper.vm.getStartOfWeek(parseTimestamp('2019-01-03')).weekday).toEqual(0)\n  })\n\n  it('should get end of week', async () => {\n    const wrapper = mountFunction()\n\n    expect(wrapper.vm.getEndOfWeek(parseTimestamp('2019-03-28')).weekday).toEqual(6)\n    expect(wrapper.vm.getEndOfWeek(parseTimestamp('2019-12-31')).weekday).toEqual(6)\n  })\n\n  it('should return dayFormatter equal to dayFormat prop', async () => {\n    const dayFormat = x => x\n    const wrapper = mountFunction({\n      propsData: {\n        dayFormat,\n      },\n    })\n\n    expect(wrapper.vm.dayFormatter).toEqual(dayFormat)\n  })\n\n  it('should format day', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        start: '2019-01-29',\n        end: '2019-02-08',\n      },\n    })\n\n    expect(wrapper.vm.weekdayFormatter).toBeDefined()\n    expect(typeof wrapper.vm.weekdayFormatter).toEqual('function')\n\n    expect(wrapper.vm.dayFormatter(parseTimestamp('2019-01-28'), false)).toEqual('28')\n    expect(wrapper.vm.dayFormatter(parseTimestamp('2019-01-27'), false)).toEqual('27')\n    expect(wrapper.vm.dayFormatter(parseTimestamp('2019-01-29'), false)).toEqual('29')\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/composables/__tests__/calendar-with-events.spec.ts",
    "content": "// @ts-nocheck\n/* eslint-disable */\n\n// import {\n//   mount,\n//   Wrapper,\n//   MountOptions,\n// } from '@vue/test-utils'\n// import CalendarWithEvents from '../calendar-with-events'\n// import { parseTimestamp } from '../../util/timestamp'\n//\n// const Mock = CalendarWithEvents.extend({\n//   render: h => h('div'),\n// })\n\ndescribe.skip('calendar-with-events.ts', () => {\n  type Instance = InstanceType<typeof Mock>\n  let mountFunction: (options?: MountOptions<Instance>) => Wrapper<Instance>\n  beforeEach(() => {\n    mountFunction = (options?: MountOptions<Instance>) => {\n      return mount(Mock, options)\n    }\n  })\n\n  it('should check if there is no events', async () => {\n    const wrapper = mount(Mock)\n\n    expect(wrapper.vm.noEvents).toBeTruthy()\n\n    wrapper.setProps({\n      events: [\n        {\n          start: '2019-02-12',\n        },\n      ],\n    })\n\n    expect(wrapper.vm.noEvents).toBeFalsy()\n  })\n\n  it('should parse events', async () => {\n    const wrapper = mount(Mock, {\n      propsData: {\n        events: [\n          {\n            start: '2019-02-12',\n          },\n        ],\n      },\n    })\n\n    expect(wrapper.vm.parsedEvents).toBeDefined()\n    expect(wrapper.vm.parsedEvents).toHaveLength(1)\n    expect(wrapper.vm.parsedEvents[0]).toMatchObject({ start: { date: '2019-02-12' }, end: { date: '2019-02-12' } })\n  })\n\n  it('should work with event colors', async () => {\n    const wrapper = mount(Mock, {\n      propsData: {\n        eventColor: () => 'green',\n      },\n    })\n\n    expect(wrapper.vm.eventColorFunction).toBeDefined()\n    expect(typeof wrapper.vm.eventColorFunction).toBe('function')\n    expect(wrapper.vm.eventColorFunction({})).toBe('green')\n\n    wrapper.setProps({\n      eventColor: 'red',\n    })\n\n    expect(wrapper.vm.eventColorFunction).toBeDefined()\n    expect(typeof wrapper.vm.eventColorFunction).toBe('function')\n    expect(wrapper.vm.eventColorFunction({})).toBe('red')\n  })\n\n  it('should work with event text colors', async () => {\n    const wrapper = mount(Mock, {\n      propsData: {\n        eventTextColor: () => 'green',\n      },\n    })\n\n    expect(wrapper.vm.eventTextColorFunction).toBeDefined()\n    expect(typeof wrapper.vm.eventTextColorFunction).toBe('function')\n    expect(wrapper.vm.eventTextColorFunction({})).toBe('green')\n\n    wrapper.setProps({\n      eventTextColor: 'red',\n    })\n\n    expect(wrapper.vm.eventTextColorFunction).toBeDefined()\n    expect(typeof wrapper.vm.eventTextColorFunction).toBe('function')\n    expect(wrapper.vm.eventTextColorFunction({})).toBe('red')\n  })\n\n  it('should work with event names', async () => {\n    const wrapper = mount(Mock, {\n      propsData: {\n        eventName: () => 'Meetup',\n      },\n    })\n\n    expect(wrapper.vm.eventNameFunction).toBeDefined()\n    expect(typeof wrapper.vm.eventNameFunction).toBe('function')\n    expect(wrapper.vm.eventNameFunction({ start: { date: '2019-02-12' }, input: { Meetup: 'Meetup' } })).toBe('Meetup')\n    expect(wrapper.vm.eventNameFunction({ start: { date: '2019-02-12', hour: 8, minute: 30, hasTime: true }, input: { Meetup: 'Meetup' } })).toBe('Meetup')\n\n    wrapper.setProps({\n      eventName: 'x',\n    })\n\n    expect(wrapper.vm.eventNameFunction).toBeDefined()\n    expect(typeof wrapper.vm.eventNameFunction).toBe('function')\n    expect(wrapper.vm.eventNameFunction({ start: { date: '2019-02-12' }, input: { x: 'Conference' } })).toBe('Conference')\n    expect(wrapper.vm.eventNameFunction({ start: { date: '2019-02-12', hour: 8, minute: 30, hasTime: true }, input: { x: 'Conference' } })).toMatch('Conference') // will match 8:30 AM|| 08:30 AM || 8:30 || 08:30\n  })\n\n  it('should format time', async () => {\n    const testData1 = { date: '2019-01-01', hour: 8, minute: 30 }\n    const testData2 = { date: '2019-01-01', hour: 17, minute: 45 }\n    const testData3 = { date: '2019-01-01', hour: 9, minute: 5 }\n    const testData4 = { date: '2019-01-01', hour: 15, minute: 0 }\n\n    const wrapper = mount(Mock)\n\n    // Depending on the time format of the underlying system\n    // (12-hour with `h` || 12-hour with `hh` || 24-hour with `h` || 24-hour with `hh`),\n    // we expect the value passed to be-\n    expect(wrapper.vm.formatTime(testData1, true)).toMatch(/^0?8:30( AM)?$/i) // 8:30 AM || 08:30 AM || 8:30 || 08:30\n    expect(wrapper.vm.formatTime(testData2, true)).toMatch(/^(0?5:45 PM|17:45)$/i) // 5:45 PM || 05:45 PM || 17:45\n    expect(wrapper.vm.formatTime(testData3, true)).toMatch(/^0?9:05( AM)?$/i) // 9:05 AM || 09:05 AM || 9:05 || 09:45\n    expect(wrapper.vm.formatTime(testData4, true)).toMatch(/^(0?3 PM|15)$/i) // 3 AM || 03 AM || 15\n  })\n\n  it('should get events map', async () => {\n    const wrapper = mountFunction({\n      render: h => h('div', [\n        h('div', {\n          ref: 'events',\n          refInFor: true,\n          attrs: {\n            'data-event': 'test',\n            'data-date': '2019-02-12',\n          },\n        }),\n        h('div', {\n          ref: 'events',\n          refInFor: true,\n          attrs: {\n            'data-event': 'test1',\n            'data-date': '2019-02-13',\n          },\n        }),\n        h('div', {\n          ref: 'events',\n          refInFor: true,\n          attrs: {\n            'data-event': 'test2',\n            'data-date': '2019-02-13',\n            'data-more': '123',\n          },\n        }),\n      ]),\n    })\n\n    expect(wrapper.vm.getEventsMap()).toMatchSnapshot()\n  })\n\n  it('should get events for day', async () => {\n    const wrapper = mount(Mock, {\n      propsData: {\n        events: [\n          {\n            start: '2019-02-12 8:30',\n            end: '2019-02-12 12:00',\n          },\n          {\n            start: '2019-02-11',\n            end: '2019-02-13',\n          },\n        ],\n      },\n    })\n\n    expect(wrapper.vm.getEventsForDay(parseTimestamp('2019-02-10'))).toHaveLength(0)\n    expect(wrapper.vm.getEventsForDay(parseTimestamp('2019-02-11'))).toHaveLength(1)\n    expect(wrapper.vm.getEventsForDay(parseTimestamp('2019-02-12'))).toHaveLength(1)\n    expect(wrapper.vm.getEventsForDay(parseTimestamp('2019-02-13'))).toHaveLength(0)\n    expect(wrapper.vm.getEventsForDay(parseTimestamp('2019-02-14'))).toHaveLength(0)\n  })\n\n  it('should get events for all day', async () => {\n    const wrapper = mount(Mock, {\n      propsData: {\n        events: [\n          {\n            start: '2019-02-12 8:30',\n            end: '2019-02-12 12:00',\n          },\n          {\n            start: '2019-02-11',\n            end: '2019-02-13',\n          },\n        ],\n      },\n    })\n\n    expect(wrapper.vm.getEventsForDayAll(parseTimestamp('2019-02-10'))).toHaveLength(0)\n    expect(wrapper.vm.getEventsForDayAll(parseTimestamp('2019-02-11'))).toHaveLength(1)\n    expect(wrapper.vm.getEventsForDayAll(parseTimestamp('2019-02-12'))).toHaveLength(0)\n    expect(wrapper.vm.getEventsForDayAll(parseTimestamp('2019-02-13'))).toHaveLength(0)\n    expect(wrapper.vm.getEventsForDayAll(parseTimestamp('2019-02-14'))).toHaveLength(0)\n  })\n\n  it('should get timed events for day', async () => {\n    const wrapper = mount(Mock, {\n      propsData: {\n        events: [\n          {\n            start: '2019-02-12 8:30',\n            end: '2019-02-12 12:00',\n          },\n          {\n            start: '2019-02-11',\n            end: '2019-02-13',\n          },\n        ],\n      },\n    })\n\n    expect(wrapper.vm.getEventsForDayTimed(parseTimestamp('2019-02-10'))).toHaveLength(0)\n    expect(wrapper.vm.getEventsForDayTimed(parseTimestamp('2019-02-11'))).toHaveLength(0)\n    expect(wrapper.vm.getEventsForDayTimed(parseTimestamp('2019-02-12'))).toHaveLength(1)\n    expect(wrapper.vm.getEventsForDayTimed(parseTimestamp('2019-02-13'))).toHaveLength(0)\n    expect(wrapper.vm.getEventsForDayTimed(parseTimestamp('2019-02-14'))).toHaveLength(0)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/composables/__tests__/calendar-with-intervals.spec.ts",
    "content": "// @ts-nocheck\n/* eslint-disable */\n\n// import CalendarWithIntervals from '../calendar-with-intervals'\n// import { CalendarTimestamp } from 'vuetify/types'\n// import { parseTimestamp } from '../../util/timestamp'\n// import {\n//   mount,\n//   Wrapper,\n//   MountOptions,\n// } from '@vue/test-utils'\n// import { ExtractVue } from '../../../../util/mixins'\n\n// const Mock = CalendarWithIntervals.extend({\n//   render: h => h('div'),\n// })\n\nconst createMouseEvent = (x, y) => ({\n  clientX: x,\n  clientY: y,\n  currentTarget: document.body,\n})\nconst createTouchEvent = (x, y) => ({\n  touches: [{\n    clientX: x,\n    clientY: y,\n  }],\n  currentTarget: document.body,\n})\n\ndescribe.skip('calendar-with-intervals.ts', () => {\n  type Instance = ExtractVue<typeof Mock>\n  let mountFunction: (options?: MountOptions<Instance>) => Wrapper<Instance>\n  beforeEach(() => {\n    mountFunction = (options?: MountOptions<Instance>) => {\n      return mount(Mock, {\n        ...options,\n        mocks: {\n          $vuetify: {\n            lang: {\n              current: 'en-US',\n            },\n          },\n        },\n      })\n    }\n  })\n\n  it('should parse all data', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        firstInterval: '1',\n        intervalMinutes: '30',\n        intervalCount: '10',\n        intervalHeight: '20',\n      },\n    })\n\n    expect(wrapper.vm.parsedFirstInterval).toBeDefined()\n    expect(wrapper.vm.parsedFirstInterval).toBe(1)\n    expect(wrapper.vm.parsedIntervalMinutes).toBeDefined()\n    expect(wrapper.vm.parsedIntervalMinutes).toBe(30)\n    expect(wrapper.vm.parsedIntervalCount).toBeDefined()\n    expect(wrapper.vm.parsedIntervalCount).toBe(10)\n    expect(wrapper.vm.parsedIntervalHeight).toBeDefined()\n    expect(wrapper.vm.parsedIntervalHeight).toBe(20)\n  })\n\n  it('should generate firstMinute', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        firstInterval: '2',\n        intervalMinutes: '30',\n      },\n    })\n\n    expect(wrapper.vm.firstMinute).toBeDefined()\n    expect(wrapper.vm.firstMinute).toBe(60)\n  })\n\n  it('should generate bodyHeight', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        intervalCount: '10',\n        intervalHeight: '20',\n      },\n    })\n\n    expect(wrapper.vm.bodyHeight).toBeDefined()\n    expect(wrapper.vm.bodyHeight).toBe(200)\n  })\n\n  it('should generate days', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        start: '2019-01-29',\n        end: '2019-02-04',\n      },\n    })\n\n    expect(wrapper.vm.days).toBeDefined()\n    expect(wrapper.vm.days).toHaveLength(7)\n    expect(wrapper.vm.days[0].date).toBe('2019-01-29')\n    expect(wrapper.vm.days[6].date).toBe('2019-02-04')\n    expect(wrapper.vm.days).toMatchSnapshot()\n\n    wrapper.setProps({\n      start: '2019-01-29',\n      end: '2019-02-02',\n    })\n\n    expect(wrapper.vm.days).toBeDefined()\n    expect(wrapper.vm.days).toHaveLength(5)\n    expect(wrapper.vm.days[0].date).toBe('2019-01-29')\n    expect(wrapper.vm.days[4].date).toBe('2019-02-02')\n    expect(wrapper.vm.days).toMatchSnapshot()\n  })\n\n  it('should generate intervals', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        start: '2019-01-29',\n        end: '2019-02-04',\n      },\n    })\n\n    expect(wrapper.vm.intervals).toBeDefined()\n    expect(wrapper.vm.intervals).toHaveLength(7)\n    expect(wrapper.vm.intervals[0]).toHaveLength(24)\n    expect(wrapper.vm.intervals[0][0].date).toBe('2019-01-29')\n    expect(wrapper.vm.intervals[6][0].date).toBe('2019-02-04')\n    expect(wrapper.vm.intervals).toMatchSnapshot()\n\n    wrapper.setProps({\n      start: '2019-01-29',\n      end: '2019-02-02',\n    })\n\n    expect(wrapper.vm.intervals).toBeDefined()\n    expect(wrapper.vm.intervals).toHaveLength(5)\n    expect(wrapper.vm.intervals[0]).toHaveLength(24)\n    expect(wrapper.vm.intervals[0][0].date).toBe('2019-01-29')\n    expect(wrapper.vm.intervals[4][0].date).toBe('2019-02-02')\n    expect(wrapper.vm.intervals).toMatchSnapshot()\n  })\n\n  it('should generate intervalFormatter', async () => {\n    const wrapper = mountFunction()\n\n    expect(wrapper.vm.intervalFormatter).toBeDefined()\n    expect(typeof wrapper.vm.intervalFormatter).toBe('function')\n  })\n\n  // TODO: Re-enable when test doesn't break travis\n  it.skip('should format interval', async () => {\n    const wrapper = mountFunction()\n\n    expect(wrapper.vm.intervalFormatter({ date: '2019-02-08', hour: 8, minute: 30 } as CalendarTimestamp, false)).toBe('8:30 AM')\n    expect(wrapper.vm.intervalFormatter({ date: '2019-02-08', hour: 20, minute: 30 } as CalendarTimestamp, false)).toBe('8:30 PM')\n    expect(wrapper.vm.intervalFormatter({ date: '2019-02-08', hour: 0, minute: 30 } as CalendarTimestamp, false)).toBe('12:30 AM')\n    expect(wrapper.vm.intervalFormatter({ date: '2019-02-08', hour: 8, minute: 30 } as CalendarTimestamp, true)).toBe('8:30 AM')\n    expect(wrapper.vm.intervalFormatter({ date: '2019-02-08', hour: 20, minute: 30 } as CalendarTimestamp, true)).toBe('8:30 PM')\n    expect(wrapper.vm.intervalFormatter({ date: '2019-02-08', hour: 0, minute: 30 } as CalendarTimestamp, true)).toBe('12:30 AM')\n  })\n\n  it('should return intervalFormat if has one', async () => {\n    const intervalFormat = x => x\n    const wrapper = mountFunction({\n      propsData: {\n        intervalFormat,\n      },\n    })\n\n    expect(wrapper.vm.intervalFormatter).toBeDefined()\n    expect(typeof wrapper.vm.intervalFormatter).toBe('function')\n    expect(wrapper.vm.intervalFormatter).toBe(intervalFormat)\n  })\n\n  it('should generate slot scope', async () => {\n    const wrapper = mountFunction()\n\n    expect(wrapper.vm.getSlotScope(parseTimestamp('2019-02-08'))).toBeDefined()\n    expect(wrapper.vm.getSlotScope(parseTimestamp('2019-02-08')).date).toBe('2019-02-08')\n\n    const scope = wrapper.vm.getSlotScope(parseTimestamp('2019-02-08'))\n    delete scope.week\n\n    expect(scope).toMatchSnapshot()\n    expect(typeof wrapper.vm.getSlotScope(parseTimestamp('2019-02-08')).timeToY).toBe('function')\n    expect(typeof wrapper.vm.getSlotScope(parseTimestamp('2019-02-08')).timeDelta).toBe('function')\n    expect(typeof wrapper.vm.getSlotScope(parseTimestamp('2019-02-08')).minutesToPixels).toBe('function')\n  })\n\n  it('should convert time to Y', async () => {\n    const wrapper = mountFunction()\n\n    expect(typeof wrapper.vm.timeToY).toBe('function')\n    expect(wrapper.vm.timeToY('08:30')).toBeDefined()\n    expect(wrapper.vm.timeToY('08:30')).toBe(408)\n    expect(wrapper.vm.timeToY('09:30')).toBe(456)\n    expect(Math.round(wrapper.vm.timeToY('23:50') || 0)).toBe(1144)\n\n    wrapper.setProps({\n      firstInterval: 5,\n      intervalCount: 5,\n      intervalMinutes: 10,\n      bodyHeight: 400,\n    })\n\n    expect(wrapper.vm.timeToY('08:30')).toBe(240)\n    expect(wrapper.vm.timeToY('09:30')).toBe(240)\n    expect(wrapper.vm.timeToY('23:50')).toBe(240)\n\n    expect(wrapper.vm.timeToY('00:05')).toBe(0)\n    expect(Math.round(wrapper.vm.timeToY('08:30', false) || 0)).toBe(2208)\n    expect(wrapper.vm.timeToY('09:30', false)).toBe(2496)\n    expect(wrapper.vm.timeToY('23:50', false)).toBe(6624)\n\n    expect(wrapper.vm.timeToY('bad')).toBe(false)\n  })\n\n  it('should convert time delta', async () => {\n    const wrapper = mountFunction()\n\n    expect(typeof wrapper.vm.timeDelta).toBe('function')\n    expect(wrapper.vm.timeDelta('08:30')).toBeDefined()\n    expect(wrapper.vm.timeDelta('08:30')).toBe((8 * 60 + 30) / 1440)\n    expect(wrapper.vm.timeDelta('09:30')).toBe((9 * 60 + 30) / 1440)\n    expect(Math.round(wrapper.vm.timeDelta('23:50') || 0)).toBe(1)\n\n    wrapper.setProps({\n      firstInterval: 5,\n      intervalCount: 5,\n      intervalMinutes: 10,\n      bodyHeight: 400,\n    })\n\n    expect(wrapper.vm.timeDelta('08:30')).toBe((8 * 60 + 30 - 50) / 50)\n    expect(wrapper.vm.timeDelta('09:30')).toBe((9 * 60 + 30 - 50) / 50)\n    expect(wrapper.vm.timeDelta('23:50')).toBe((23 * 60 + 50 - 50) / 50)\n\n    expect(wrapper.vm.timeDelta('00:50')).toBe(0)\n\n    expect(wrapper.vm.timeDelta('bad')).toBe(false)\n  })\n\n  it('should convert minutes to pixels', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        intervalMinutes: 5,\n        bodyHeight: 200,\n      },\n    })\n\n    expect(wrapper.vm.minutesToPixels).toBeDefined()\n    expect(typeof wrapper.vm.minutesToPixels).toBe('function')\n    expect(wrapper.vm.minutesToPixels(5)).toBeDefined()\n\n    expect(wrapper.vm.minutesToPixels(5)).toBe(48)\n    expect(wrapper.vm.minutesToPixels(10)).toBe(96)\n    expect(wrapper.vm.minutesToPixels(50)).toBe(480)\n\n    wrapper.setProps({\n      intervalMinutes: 10,\n      bodyHeight: 400,\n    })\n\n    expect(wrapper.vm.minutesToPixels(5)).toBe(24)\n    expect(wrapper.vm.minutesToPixels(10)).toBe(48)\n    expect(wrapper.vm.minutesToPixels(50)).toBe(240)\n  })\n\n  it('should scroll to time', async () => {\n    const wrapper = mountFunction({\n      render: h => h('div', [\n        h('div', {\n          ref: 'scrollArea',\n        }),\n      ]),\n    })\n\n    wrapper.vm.scrollToTime('8:30')\n    expect((wrapper.vm.$refs.scrollArea as any).scrollTop).toBe(408)\n    wrapper.vm.scrollToTime('12:30')\n    expect(Math.round((wrapper.vm.$refs.scrollArea as any).scrollTop)).toBe(600)\n    wrapper.vm.scrollToTime('20:00')\n    expect((wrapper.vm.$refs.scrollArea as any).scrollTop).toBe(960)\n\n    wrapper.setProps({\n      intervalMinutes: 5,\n      bodyHeight: 200,\n    })\n\n    wrapper.vm.scrollToTime('8:30')\n    expect((wrapper.vm.$refs.scrollArea as any).scrollTop).toBe(1152)\n    wrapper.vm.scrollToTime('12:30')\n    expect((wrapper.vm.$refs.scrollArea as any).scrollTop).toBe(1152)\n    wrapper.vm.scrollToTime('20:30')\n    expect((wrapper.vm.$refs.scrollArea as any).scrollTop).toBe(1152)\n\n    wrapper.setProps({\n      intervalMinutes: 30,\n      bodyHeight: 1700,\n    })\n\n    wrapper.vm.scrollToTime('8:30')\n    expect((wrapper.vm.$refs.scrollArea as any).scrollTop).toBe(816)\n    wrapper.vm.scrollToTime('12:30')\n    expect((wrapper.vm.$refs.scrollArea as any).scrollTop).toBe(1152)\n    wrapper.vm.scrollToTime('20:30')\n    expect((wrapper.vm.$refs.scrollArea as any).scrollTop).toBe(1152)\n\n    expect(wrapper.vm.scrollToTime('20:19')).toBe(true)\n    expect(wrapper.vm.scrollToTime('bad')).toBe(false)\n  })\n\n  it('should get timestamp at mouse event', async () => {\n    const wrapper = mountFunction()\n\n    expect(typeof wrapper.vm.getTimestampAtEvent).toBe('function')\n\n    expect(wrapper.vm.getTimestampAtEvent(createMouseEvent(0, 100) as unknown as MouseEvent, { time: '20:00' } as CalendarTimestamp)).toMatchObject({ hour: 2, minute: 5 })\n    expect(wrapper.vm.getTimestampAtEvent(createMouseEvent(0, 150) as unknown as MouseEvent, { time: '20:00' } as CalendarTimestamp)).toMatchObject({ hour: 3, minute: 7 })\n    expect(wrapper.vm.getTimestampAtEvent(createMouseEvent(0, 200) as unknown as MouseEvent, { time: '20:00' } as CalendarTimestamp)).toMatchObject({ hour: 4, minute: 10 })\n  })\n\n  it('should get timestamp at touch event', async () => {\n    const wrapper = mountFunction()\n\n    expect(typeof wrapper.vm.getTimestampAtEvent).toBe('function')\n\n    expect(wrapper.vm.getTimestampAtEvent(createTouchEvent(0, 100) as unknown as TouchEvent, { time: '20:00' } as CalendarTimestamp)).toMatchObject({ hour: 2, minute: 5 })\n    expect(wrapper.vm.getTimestampAtEvent(createTouchEvent(0, 150) as unknown as TouchEvent, { time: '20:00' } as CalendarTimestamp)).toMatchObject({ hour: 3, minute: 7 })\n    expect(wrapper.vm.getTimestampAtEvent(createTouchEvent(0, 200) as unknown as TouchEvent, { time: '20:00' } as CalendarTimestamp)).toMatchObject({ hour: 4, minute: 10 })\n  })\n\n  it('should get style', async () => {\n    const wrapper = mountFunction()\n\n    expect(typeof wrapper.vm.intervalStyleDefault).toBe('function')\n    expect(wrapper.vm.intervalStyleDefault({} as CalendarTimestamp)).toBeUndefined()\n  })\n\n  it('should show interval label', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        start: '2019-01-29',\n        end: '2019-02-04',\n        firstInterval: 5,\n      },\n    })\n    expect(typeof wrapper.vm.showIntervalLabelDefault).toBe('function')\n    expect(wrapper.vm.showIntervalLabelDefault({})).toBeTruthy()\n\n    expect(wrapper.vm.showIntervalLabelDefault({ hour: 0, minute: 5 } as CalendarTimestamp)).toBeTruthy()\n    expect(wrapper.vm.showIntervalLabelDefault({ hour: 12, minute: 30 } as CalendarTimestamp)).toBeTruthy()\n    expect(wrapper.vm.showIntervalLabelDefault({ hour: 13, minute: 0 } as CalendarTimestamp)).toBeTruthy()\n    expect(wrapper.vm.showIntervalLabelDefault({ hour: 13, minute: 30 } as CalendarTimestamp)).toBeTruthy()\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/composables/__tests__/times.spec.ts",
    "content": "// @ts-nocheck\n/* eslint-disable */\n\n// import Times from '../times'\n// import {\n//   mount,\n//   Wrapper,\n//   MountOptions,\n// } from '@vue/test-utils'\n// import { ExtractVue } from '../../../../util/mixins'\n// import { CalendarTimestamp } from 'vuetify/types'\n\n// const Mock = Times.extend({\n//   render: h => h('div'),\n// })\n\ndescribe.skip('times.ts', () => {\n  type Instance = ExtractVue<typeof Mock>\n  let mountFunction: (options?: MountOptions<Instance>) => Wrapper<Instance>\n  beforeEach(() => {\n    mountFunction = (options?: MountOptions<Instance>) => {\n      return mount(Mock, options)\n    }\n  })\n\n  it('should parse timestamp', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        now: '2019-02-08',\n      },\n    })\n\n    expect(wrapper.vm.parsedNow).toBeDefined()\n    expect(wrapper.vm.parsedNow).toMatchSnapshot()\n  })\n\n  it('should update day', async () => {\n    const wrapper = mountFunction()\n\n    expect(typeof wrapper.vm.updateDay).toBe('function')\n    const target = {}\n    const now = {\n      date: '2019-02-08',\n      year: '2019',\n      month: '2',\n      day: '8',\n      weekday: '4',\n    }\n    wrapper.vm.updateDay(now as unknown as CalendarTimestamp, target as unknown as CalendarTimestamp)\n    expect(target).toEqual(now)\n  })\n\n  it('should not update day if dates are equal', async () => {\n    const wrapper = mountFunction()\n\n    expect(typeof wrapper.vm.updateDay).toBe('function')\n    const target = { date: '2019-02-08' }\n    const now = {\n      date: '2019-02-08',\n      year: '2019',\n      month: '2',\n      day: '8',\n      weekday: '4',\n    }\n    wrapper.vm.updateDay(now as unknown as CalendarTimestamp, target as unknown as CalendarTimestamp)\n    expect(target).not.toEqual(now)\n  })\n\n  it('should not update time if times are equal', async () => {\n    const wrapper = mountFunction()\n\n    expect(typeof wrapper.vm.updateTime).toBe('function')\n    const target = { time: '08:30' }\n    const now = {\n      time: '08:30',\n      hour: '8',\n      minute: '30',\n    }\n    wrapper.vm.updateTime(now as unknown as CalendarTimestamp, target as unknown as CalendarTimestamp)\n    expect(target).not.toEqual(now)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/composables/calendarBase.ts",
    "content": "// Composables\nimport { useTimes } from './times'\nimport { computeColor } from '@/composables/color'\nimport { useDate } from '@/composables/date'\nimport { provideLocale } from '@/composables/locale'\n\n// Utilities\nimport { computed } from 'vue'\nimport {\n  createDayList,\n  createNativeLocaleFormatter,\n  getEndOfMonth,\n  getEndOfWeek,\n  getStartOfMonth,\n  getStartOfWeek,\n  getTimestampIdentifier,\n  getWeekdaySkips,\n  parseDate,\n  parseTimestamp,\n  validateTimestamp,\n  validateWeekdays,\n} from '../util/timestamp'\nimport { propsFactory } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { CalendarFormatter, CalendarTimestamp } from '../types'\nimport type { ColorValue } from '@/composables/color'\n\nexport const makeCalendarBaseProps = propsFactory({\n  start: {\n    type: [String, Number, Date],\n    validate: validateTimestamp,\n    default: () => parseDate(new Date()).date,\n  },\n  end: {\n    type: [String, Number, Date],\n    validate: validateTimestamp,\n  },\n  weekdays: {\n    type: [Array, String] as PropType<number[] | string>,\n    default: () => [0, 1, 2, 3, 4, 5, 6],\n    validate: validateWeekdays,\n  },\n  firstDayOfWeek: [Number, String],\n  firstDayOfYear: [Number, String],\n  weekdayFormat: {\n    type: Function as PropType<CalendarFormatter>,\n    default: null,\n  },\n  dayFormat: {\n    type: Function as PropType<CalendarFormatter>,\n    default: null,\n  },\n  locale: String,\n  now: {\n    type: String,\n    validator: validateTimestamp,\n  },\n  type: {\n    type: String as PropType<'month' | 'week' | 'day' | '4day' | 'custom-weekly' | 'custom-daily' | 'category'>,\n    default: 'month',\n  },\n}, 'VCalendar-base')\n\nexport interface CalendarBaseProps {\n  modelValue?: string | number | Date\n  categoryDays?: string | number\n  start: string | number | Date\n  end: string | number | Date | undefined\n  weekdays: string | number[]\n  firstDayOfWeek: number | string | undefined\n  firstDayOfYear: number | string | undefined\n  weekdayFormat: CalendarFormatter | string | undefined\n  dayFormat: CalendarFormatter | string | undefined\n  locale: string | undefined\n  now: string | undefined\n  type: 'month' | 'week' | 'day' | '4day' | 'custom-weekly' | 'custom-daily' | 'category'\n}\n\nexport function useCalendarBase (props: CalendarBaseProps) {\n  const { times, updateTimes } = useTimes({ now: props.now })\n  const locale = provideLocale(props)\n\n  const adapter = useDate()\n\n  const parsedStart = computed((): CalendarTimestamp => {\n    if (props.type === 'month') {\n      return getStartOfMonth(parseTimestamp(props.start, true))\n    }\n    return parseTimestamp(props.start, true)\n  })\n\n  const parsedEnd = computed((): CalendarTimestamp => {\n    const start = parsedStart.value\n    const end: CalendarTimestamp = props.end ? parseTimestamp(props.end) || start : start\n    const value = getTimestampIdentifier(end) < getTimestampIdentifier(start) ? start : end\n\n    if (props.type === 'month') {\n      return getEndOfMonth(value)\n    }\n    return value\n  })\n\n  const parsedValue = computed((): CalendarTimestamp => {\n    return (validateTimestamp(props.modelValue)\n      ? parseTimestamp(props.modelValue, true)\n      : (parsedStart.value || times.today))\n  })\n\n  const parsedWeekdays = computed((): number[] => {\n    const weekdays = Array.isArray(props.weekdays)\n      ? props.weekdays\n      : (props.weekdays || '').split(',').map(x => parseInt(x, 10))\n\n    const first = adapter.toJsDate(adapter.startOfWeek(adapter.date(), props.firstDayOfWeek)).getDay()\n    return [\n      ...weekdays.toSorted().filter(v => v >= first),\n      ...weekdays.toSorted().filter(v => v < first),\n    ]\n  })\n\n  const effectiveWeekdays = computed((): number[] => {\n    const start = parsedValue.value\n    const days = parseInt(String(props.categoryDays)) || 1\n\n    switch (props.type) {\n      case 'day': return [start.weekday]\n      case '4day': return [\n        start.weekday,\n        (start.weekday + 1) % 7,\n        (start.weekday + 2) % 7,\n        (start.weekday + 3) % 7,\n      ]\n      case 'category': return Array.from({ length: days }, (_, i) => (start.weekday + i) % 7)\n      default: return parsedWeekdays.value\n    }\n  })\n\n  const weekdaySkips = computed((): number[] => {\n    return getWeekdaySkips(parsedWeekdays.value)\n  })\n\n  const days = computed((): CalendarTimestamp[] => {\n    return createDayList(\n      parsedStart.value,\n      parsedEnd.value,\n      times.today,\n      weekdaySkips.value,\n    )\n  })\n\n  const dayFormatter = computed((): CalendarFormatter => {\n    if (props.dayFormat) {\n      return props.dayFormat as CalendarFormatter\n    }\n\n    return createNativeLocaleFormatter(\n      locale.current.value,\n      () => ({ timeZone: 'UTC', day: 'numeric' })\n    )\n  })\n\n  const weekdayFormatter = computed((): CalendarFormatter => {\n    if (props.weekdayFormat) {\n      return props.weekdayFormat as CalendarFormatter\n    }\n\n    return createNativeLocaleFormatter(\n      locale.current.value,\n      (_tms, short) => ({ timeZone: 'UTC', weekday: short ? 'short' : 'long' })\n    )\n  })\n\n  function getColorProps (colors: { background?: ColorValue, text?: ColorValue }) {\n    return computeColor(colors)\n  }\n\n  function getRelativeClasses (timestamp: CalendarTimestamp, outside = false) {\n    return {\n      'v-present': timestamp.present,\n      'v-past': timestamp.past,\n      'v-future': timestamp.future,\n      'v-outside': outside,\n    }\n  }\n\n  function getWeekNumber (timestamp: CalendarTimestamp): number {\n    return adapter.getWeek(\n      adapter.date(timestamp.date),\n      props.firstDayOfWeek,\n      props.firstDayOfYear,\n    )\n  }\n\n  function _getStartOfWeek (timestamp: CalendarTimestamp): CalendarTimestamp {\n    return getStartOfWeek(timestamp, parsedWeekdays.value, times.today)\n  }\n\n  function _getEndOfWeek (timestamp: CalendarTimestamp): CalendarTimestamp {\n    return getEndOfWeek(timestamp, parsedWeekdays.value, times.today)\n  }\n\n  function getFormatter (options: Intl.DateTimeFormatOptions): CalendarFormatter {\n    return createNativeLocaleFormatter(locale.current.value, () => options)\n  }\n\n  return {\n    times,\n    locale,\n    parsedValue,\n    parsedWeekdays,\n    effectiveWeekdays,\n    weekdaySkips,\n    parsedStart,\n    parsedEnd,\n    days,\n    dayFormatter,\n    weekdayFormatter,\n    getColorProps,\n    getRelativeClasses,\n    getWeekNumber,\n    getStartOfWeek: _getStartOfWeek,\n    getEndOfWeek: _getEndOfWeek,\n    getFormatter,\n    updateTimes,\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/composables/calendarWithEvents.sass",
    "content": "@use '../../../styles/tools'\n@use '../../../styles/settings'\n@use '../variables' as *\n\n@include tools.layer('components')\n  .v-calendar-events\n    .v-event-more\n      background-color: $calendar-background\n      color: $calendar-on-background\n\n      &.v-outside\n        background-color: $calendar-outside-background\n        color: $calendar-on-outside-background\n\n  .v-calendar\n    .v-event\n      position: relative\n      overflow: hidden\n      text-overflow: ellipsis\n      white-space: nowrap\n      font-size: $calendar-event-font-size\n      cursor: pointer\n      line-height: $calendar-event-line-height\n      margin-right: -$calendar-line-width\n      z-index: 1\n      border-radius: $calendar-event-border-radius\n\n    .v-event-more\n      overflow: hidden\n      text-overflow: ellipsis\n      white-space: nowrap\n      font-size: $calendar-event-font-size\n      cursor: pointer\n      font-weight: bold\n      z-index: 1\n      position: relative\n\n    .v-event-timed-container\n      position: absolute\n      top: 0\n      bottom: 0\n      left: 0\n      right: 0\n      margin-right: $calendar-event-right-empty\n      pointer-events: none\n\n    .v-event-timed\n      position: absolute\n      white-space: nowrap\n      text-overflow: ellipsis\n      font-size: $calendar-event-font-size\n      cursor: pointer\n      border: $calendar-event-border-width solid $calendar-background\n      border-radius: $calendar-event-border-radius\n      pointer-events: all\n\n    .v-event-summary\n      display: inline-block\n      overflow: hidden\n      text-overflow: ellipsis\n      width: 100%\n      white-space: nowrap\n\n    &.v-calendar-events\n      .v-calendar-weekly__head-weekday\n        margin-right: -$calendar-line-width\n      .v-calendar-weekly__day\n        overflow: visible\n        margin-right: -$calendar-line-width\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/composables/calendarWithEvents.tsx",
    "content": "// Styles\nimport './calendarWithEvents.sass'\n\n// Composables\nimport { useCalendarBase } from './calendarBase'\n\n// Directives\nimport vRipple from '@/directives/ripple'\n\n// Utilities\nimport { computed, ref } from 'vue'\nimport { CalendarEventOverlapModes } from '../modes'\nimport {\n  isEventHiddenOn,\n  isEventOn,\n  isEventOnDay,\n  isEventOverlapping,\n  isEventStart,\n  parseEvent,\n} from '../util/events'\nimport { diffMinutes, getDayIdentifier } from '../util/timestamp'\nimport { getPrefixedEventHandlers, propsFactory } from '@/util'\n\n// Types\nimport type { PropType, VNode } from 'vue'\nimport type { CalendarBaseProps } from './calendarBase'\nimport type {\n  CalendarCategory,\n  CalendarDayBodySlotScope,\n  CalendarDaySlotScope,\n  CalendarEvent,\n  CalendarEventCategoryFunction,\n  CalendarEventColorFunction,\n  CalendarEventNameFunction,\n  CalendarEventOverlapMode,\n  CalendarEventParsed,\n  CalendarEventTimedFunction,\n  CalendarEventVisual,\n  CalendarTimestamp,\n} from '../types'\n\n// Constants\nconst WIDTH_FULL = 100\nconst WIDTH_START = 95\n// const MINUTES_IN_DAY = 1440\n\ntype VEventGetter<D> = (day: D) => CalendarEventParsed[]\ntype VEventVisualToNode<D> = (visual: CalendarEventVisual, day: D) => VNode | false\ntype VEventsToNodes = <D extends CalendarDaySlotScope>(\n  day: D,\n  getter: VEventGetter<D>,\n  mapper: VEventVisualToNode<D>,\n  timed: boolean) => VNode[] | undefined\n\ntype VDailyEventsMap = {\n  [date: string]: {\n    parent: HTMLElement\n    more: HTMLElement | null\n    events: HTMLElement[]\n  }\n}\n\nexport interface VEventScopeInput {\n  eventParsed: CalendarEventParsed\n  day: CalendarDaySlotScope\n  start: boolean\n  end: boolean\n  timed: boolean\n}\n\n// Prevent import from being erased\nvoid vRipple\n\nexport const makeCalendarWithEventsProps = propsFactory({\n  events: {\n    type: Array as PropType<CalendarEvent[]>,\n    default: () => [],\n  },\n  eventStart: {\n    type: String,\n    default: 'start',\n  },\n  eventEnd: {\n    type: String,\n    default: 'end',\n  },\n  eventTimed: {\n    type: [String, Function] as PropType<string | CalendarEventTimedFunction>,\n    default: 'timed',\n  },\n  eventCategory: {\n    type: [String, Function] as PropType<string | CalendarEventCategoryFunction>,\n    default: 'category',\n  },\n  eventHeight: {\n    type: Number,\n    default: 20,\n  },\n  eventColor: {\n    type: [String, Function] as PropType<string | CalendarEventColorFunction>,\n    default: 'primary',\n  },\n  eventTextColor: {\n    type: [String, Function] as PropType<string | CalendarEventColorFunction>,\n  },\n  eventName: {\n    type: [String, Function] as PropType<string | CalendarEventNameFunction>,\n    default: 'name',\n  },\n  eventOverlapThreshold: {\n    type: [String, Number],\n    default: 60,\n  },\n  eventOverlapMode: {\n    type: [String, Function] as PropType<'stack' | 'column' | CalendarEventOverlapMode>,\n    default: 'stack',\n    validate: (mode: any) => mode in CalendarEventOverlapModes || typeof mode === 'function',\n  },\n  eventMore: {\n    type: Boolean,\n    default: true,\n  },\n  eventMoreText: {\n    type: String,\n    default: '$vuetify.calendar.moreEvents',\n  },\n  eventRipple: {\n    type: [Boolean, Object],\n    default: null,\n  },\n  eventMarginBottom: {\n    type: Number,\n    default: 1,\n  },\n}, 'VCalendar-events')\n\ninterface CalendarWithEventsProps extends CalendarBaseProps {\n  events: CalendarEvent[]\n  eventStart: string\n  eventEnd: string\n  eventTimed: string | CalendarEventTimedFunction\n  eventCategory: string | CalendarEventCategoryFunction\n  eventHeight: number\n  eventColor: string | CalendarEventColorFunction\n  eventTextColor: string | CalendarEventColorFunction | undefined\n  eventName: string | CalendarEventNameFunction\n  eventOverlapThreshold: string | number\n  eventOverlapMode: string | CalendarEventOverlapMode\n  eventMore: boolean\n  eventMoreText: string\n  eventRipple: boolean | object | null | undefined\n  eventMarginBottom: number\n  type: 'month' | 'week' | 'day' | '4day' | 'custom-weekly' | 'custom-daily' | 'category'\n}\n\nexport function useCalendarWithEvents (props: CalendarWithEventsProps, slots: any, attrs: any) {\n  const base = useCalendarBase(props)\n\n  const noEvents = computed((): boolean => {\n    return !Array.isArray(props.events) || props.events.length === 0\n  })\n\n  const categoryMode = computed((): boolean => {\n    return props.type === 'category'\n  })\n\n  const eventTimedFunction = computed((): CalendarEventTimedFunction => {\n    return typeof props.eventTimed === 'function'\n      ? props.eventTimed\n      : event => !!event[props.eventTimed as string]\n  })\n\n  const eventCategoryFunction = computed((): CalendarEventCategoryFunction => {\n    return typeof props.eventCategory === 'function'\n      ? props.eventCategory\n      : event => event[props.eventCategory as string]\n  })\n\n  const parsedEvents = computed((): CalendarEventParsed[] => {\n    if (!props.events) return []\n    return props.events.map((event, index) => parseEvent(\n      event,\n      index,\n      props.eventStart || '',\n      props.eventEnd || '',\n      eventTimedFunction.value(event),\n      categoryMode.value ? eventCategoryFunction.value(event) : false,\n    ))\n  })\n\n  const parsedEventOverlapThreshold = computed((): number => {\n    return parseInt(String(props.eventOverlapThreshold || 0))\n  })\n\n  const eventTextColorFunction = computed((): CalendarEventColorFunction => {\n    return typeof props.eventTextColor === 'function'\n      ? props.eventTextColor\n      : () => props.eventTextColor as string\n  })\n\n  const eventNameFunction = computed((): CalendarEventNameFunction => {\n    return typeof props.eventName === 'function'\n      ? props.eventName\n      : (event, timedEvent) => event.input[props.eventName as string] as string || ''\n  })\n\n  const eventModeFunction = computed((): CalendarEventOverlapMode => {\n    return typeof props.eventOverlapMode === 'function'\n      ? props.eventOverlapMode\n      : CalendarEventOverlapModes[props.eventOverlapMode as keyof typeof CalendarEventOverlapModes]\n  })\n\n  const eventWeekdays = computed((): number[] => {\n    return base.effectiveWeekdays.value\n  })\n\n  function eventColorFunction (e: CalendarEvent): string | undefined {\n    return typeof props.eventColor === 'function'\n      ? props.eventColor(e)\n      : e.color || props.eventColor\n  }\n\n  const eventsRef = ref<HTMLElement[]>([])\n\n  function updateEventVisibility () {\n    if (noEvents.value || !props.eventMore) {\n      return\n    }\n\n    const eventHeight = props.eventHeight || 0\n    const eventsMap = getEventsMap()\n\n    for (const date in eventsMap) {\n      const { parent, events, more } = eventsMap[date]\n      if (!more) {\n        break\n      }\n\n      const parentBounds = parent.getBoundingClientRect()\n      const last = events.length - 1\n      const eventsSorted = events.map(event => ({\n        event,\n        bottom: event.getBoundingClientRect().bottom,\n      })).sort((a, b) => a.bottom - b.bottom)\n      let hidden = 0\n\n      for (let i = 0; i <= last; i++) {\n        const bottom = eventsSorted[i].bottom\n        const hide = i === last\n          ? (bottom > parentBounds.bottom)\n          : (bottom + eventHeight > parentBounds.bottom)\n\n        if (hide) {\n          eventsSorted[i].event.style.display = 'none'\n          hidden++\n        }\n      }\n\n      // TODO: avoid direct DOM manipulation\n      if (hidden) {\n        more.style.display = ''\n        more.innerHTML = base.locale.t(props.eventMoreText, hidden)\n      } else {\n        more.style.display = 'none'\n      }\n    }\n  }\n\n  function getEventsMap (): VDailyEventsMap {\n    const eventsMap: VDailyEventsMap = {}\n    const elements = eventsRef.value\n\n    if (!elements || !elements.length) {\n      return eventsMap\n    }\n\n    elements.forEach(el => {\n      const date = el.getAttribute('data-date')\n      if (el.parentElement && date) {\n        if (!(date in eventsMap)) {\n          eventsMap[date] = {\n            parent: el.parentElement,\n            more: null,\n            events: [],\n          }\n        }\n        if (el.getAttribute('data-more')) {\n          eventsMap[date].more = el\n        } else {\n          eventsMap[date].events.push(el)\n          el.style.display = ''\n        }\n      }\n    })\n\n    return eventsMap\n  }\n\n  function genDayEvent ({ event }: CalendarEventVisual, day: CalendarDaySlotScope): VNode {\n    const eventHeight = props.eventHeight || 0\n    const eventMarginBottom = props.eventMarginBottom || 0\n    const dayIdentifier = getDayIdentifier(day)\n    const week = day.week\n    const start = dayIdentifier === event.startIdentifier\n    let end = dayIdentifier === event.endIdentifier\n    let width = WIDTH_START\n\n    if (!categoryMode.value) {\n      for (let i = day.index + 1; i < week.length; i++) {\n        const weekdayIdentifier = getDayIdentifier(week[i])\n        if (event.endIdentifier >= weekdayIdentifier) {\n          width += WIDTH_FULL\n          end = end || weekdayIdentifier === event.endIdentifier\n        } else {\n          end = true\n          break\n        }\n      }\n    }\n    const scope = { eventParsed: event, day, start, end, timed: false }\n\n    return genEvent(event, scope, false, {\n      class: [\n        'v-event',\n        { 'v-event-start': start, 'v-event-end': end },\n      ],\n      style: {\n        height: `${eventHeight}px`,\n        width: `${width}%`,\n        marginBottom: `${eventMarginBottom}px`,\n      },\n      'data-date': day.date,\n    })\n  }\n\n  function genTimedEvent ({ event, left, width }: CalendarEventVisual, day: CalendarDayBodySlotScope): VNode | false {\n    const startDelta = day.timeDelta(event.start, day)\n    const endDelta = day.timeDelta(event.end, day)\n    if (\n      endDelta === false ||\n      startDelta === false ||\n      endDelta < 0 ||\n      startDelta >= 1 ||\n      isEventHiddenOn(event, day)\n    ) {\n      return false\n    }\n\n    const dayIdentifier = getDayIdentifier(day)\n    const start = event.startIdentifier >= dayIdentifier\n    const end = event.endIdentifier > dayIdentifier\n    const top = day.timeToY(event.start, day)\n    const bottom = day.timeToY(event.end, day)\n    const height = Math.max(props.eventHeight || 0, bottom - top)\n    const scope = { eventParsed: event, day, start, end, timed: true }\n\n    return genEvent(event, scope, true, {\n      class: 'v-event-timed',\n      style: {\n        top: `${top}px`,\n        height: `${height}px`,\n        left: `${left}%`,\n        width: `${width}%`,\n      },\n    })\n  }\n\n  function genEvent (\n    event: CalendarEventParsed,\n    scopeInput: VEventScopeInput,\n    timedEvent: boolean,\n    data: Record<string, unknown>\n  ): VNode {\n    const slot = slots.event\n    const text = eventTextColorFunction.value(event.input)\n    const background = eventColorFunction(event.input)\n    const overlapsNoon = event.start.hour < 12 && event.end.hour >= 12\n    const singline = diffMinutes(event.start, event.end) <= parsedEventOverlapThreshold.value\n    const formatTime = (withTime: CalendarTimestamp, ampm: boolean): string => {\n      const formatter = base.getFormatter({\n        timeZone: 'UTC',\n        hour: 'numeric',\n        minute: withTime.minute > 0 ? 'numeric' : undefined,\n      })\n      return formatter(withTime, true)\n    }\n\n    const timeSummary = () => formatTime(event.start, overlapsNoon) + ' - ' + formatTime(event.end, true)\n\n    const eventSummary = () => {\n      const name = eventNameFunction.value(event, timedEvent)\n      if (event.start.hasTime) {\n        if (timedEvent) {\n          const time = timeSummary()\n          const delimiter = singline ? ', ' : <br />\n\n          return (\n            <span class=\"v-event-summary\">\n              <strong>{ name }</strong>\n              { delimiter }\n              { time }\n            </span>\n          )\n        } else {\n          const time = formatTime(event.start, true)\n\n          return (\n            <span class=\"v-event-summary\">\n              <strong>{ time }</strong> { name }\n            </span>\n          )\n        }\n      }\n\n      return <span class=\"v-event-summary\">{ name }</span>\n    }\n\n    const scope = {\n      ...scopeInput,\n      event: event.input,\n      outside: scopeInput.day.outside,\n      singline,\n      overlapsNoon,\n      formatTime,\n      timeSummary,\n      eventSummary,\n    }\n\n    const events = getPrefixedEventHandlers(attrs, ':event', (nativeEvent: Event) => ({ ...scope, nativeEvent }))\n\n    return (\n      <div\n        { ...base.getColorProps({ text, background }) }\n        { ...events }\n        { ...data }\n        ref_for\n        ref={ eventsRef }\n        v-ripple={ props.eventRipple ?? true }\n      >\n        { slot?.(scope) ?? genName(eventSummary) }\n      </div>\n    )\n  }\n\n  function genName (eventSummary: () => string | VNode): VNode {\n    return (\n      <div class=\"pl-1\">\n        { eventSummary() }\n      </div>\n    )\n  }\n\n  function genPlaceholder (day: CalendarTimestamp): VNode {\n    const height = (props.eventHeight || 0) + (props.eventMarginBottom || 0)\n    return (\n      <div\n        style={{ height: `${height}px` }}\n        data-date={ day.date }\n        ref_for\n        ref={ eventsRef }\n      />\n    )\n  }\n\n  function genMore (day: CalendarDaySlotScope): VNode {\n    const eventHeight = props.eventHeight || 0\n    const eventMarginBottom = props.eventMarginBottom || 0\n    const events = getPrefixedEventHandlers(attrs, ':more', (nativeEvent: Event) => ({ nativeEvent, ...day }))\n\n    return (\n      <div\n        class={['v-event-more pl-1', { 'v-outside': day.outside }]}\n        data-date={ day.date }\n        data-more=\"1\"\n        style={{\n          display: 'none',\n          height: `${eventHeight}px`,\n          marginBottom: `${eventMarginBottom}px`,\n        }}\n        ref_for\n        ref={ eventsRef }\n        v-ripple={ props.eventRipple ?? true }\n        { ...events }\n      />\n    )\n  }\n\n  function getVisibleEvents (): CalendarEventParsed[] {\n    const days = base.days.value\n    const start = getDayIdentifier(days[0])\n    const end = getDayIdentifier(days[days.length - 1])\n\n    return parsedEvents.value.filter(\n      event => isEventOverlapping(event, start, end)\n    )\n  }\n\n  function isEventForCategory (event: CalendarEventParsed, category: CalendarCategory): boolean {\n    return !categoryMode.value ||\n      (typeof category === 'object' && category.categoryName &&\n      category.categoryName === event.category) ||\n      (typeof event.category === 'string' && category === event.category) ||\n      (typeof event.category !== 'string' && category === null)\n  }\n\n  function getEventsForDay (day: CalendarDaySlotScope): CalendarEventParsed[] {\n    const identifier = getDayIdentifier(day)\n    const firstWeekday = eventWeekdays.value[0]\n\n    return parsedEvents.value.filter(\n      event => isEventStart(event, day, identifier, firstWeekday)\n    )\n  }\n\n  function getEventsForDayAll (day: CalendarDaySlotScope): CalendarEventParsed[] {\n    const identifier = getDayIdentifier(day)\n    const firstWeekday = eventWeekdays.value[0]\n\n    return parsedEvents.value.filter(\n      event => event.allDay &&\n        (categoryMode.value ? isEventOn(event, identifier) : isEventStart(event, day, identifier, firstWeekday)) &&\n        isEventForCategory(event, day.category)\n    )\n  }\n\n  function getEventsForDayTimed (day: CalendarDaySlotScope): CalendarEventParsed[] {\n    return parsedEvents.value.filter(\n      event => !event.allDay &&\n        isEventOnDay(event, day, day.intervalRange) &&\n        isEventForCategory(event, day.category)\n    )\n  }\n\n  function getScopedSlots () {\n    if (noEvents.value) {\n      return { ...slots }\n    }\n\n    const mode = eventModeFunction.value(\n      parsedEvents.value,\n      eventWeekdays.value[0],\n      parsedEventOverlapThreshold.value\n    )\n\n    const isNode = (input: VNode | false): input is VNode => !!input\n    const getSlotChildren: VEventsToNodes = (day, getter, mapper, timed) => {\n      const events = getter(day)\n      const visuals = mode(day, events, timed, categoryMode.value)\n\n      if (timed) {\n        return visuals.map(visual => mapper(visual, day)).filter(isNode)\n      }\n\n      const children: VNode[] = []\n\n      visuals.forEach((visual, index) => {\n        while (children.length < visual.column) {\n          children.push(genPlaceholder(day) as VNode)\n        }\n\n        const mapped = mapper(visual, day)\n        if (mapped) {\n          children.push(mapped)\n        }\n      })\n\n      return children\n    }\n\n    return {\n      ...slots,\n      day: (day: CalendarDaySlotScope) => {\n        let children = getSlotChildren(day, getEventsForDay, genDayEvent, false)\n        if (children && children.length > 0 && props.eventMore) {\n          children.push(genMore(day) as VNode)\n        }\n        if (slots.day) {\n          const slot = slots.day(day)\n          if (slot) {\n            children = children ? children.concat(slot) : slot\n          }\n        }\n        return children\n      },\n      'day-header': (day: CalendarDaySlotScope) => {\n        let children = getSlotChildren(day, getEventsForDayAll, genDayEvent, false)\n\n        if (slots['day-header']) {\n          const slot = slots['day-header'](day)\n          if (slot) {\n            children = children ? children.concat(slot) : slot\n          }\n        }\n        return children\n      },\n      'day-body': (day: CalendarDayBodySlotScope) => {\n        const events = getSlotChildren(day, getEventsForDayTimed, genTimedEvent, true)\n        let children: VNode[] = [\n          <div class=\"v-event-timed-container\">{ events }</div>,\n        ]\n\n        if (slots['day-body']) {\n          const slot = slots['day-body'](day)\n          if (slot) {\n            children = children.concat(slot)\n          }\n        }\n        return children\n      },\n    }\n  }\n\n  return {\n    ...base,\n    noEvents,\n    parsedEvents,\n    parsedEventOverlapThreshold,\n    eventTimedFunction,\n    eventCategoryFunction,\n    eventTextColorFunction,\n    eventNameFunction,\n    eventModeFunction,\n    eventWeekdays,\n    categoryMode,\n    eventColorFunction,\n    eventsRef,\n    updateEventVisibility,\n    getEventsMap,\n    genDayEvent,\n    genTimedEvent,\n    genEvent,\n    genName,\n    genPlaceholder,\n    genMore,\n    getVisibleEvents,\n    isEventForCategory,\n    getEventsForDay,\n    getEventsForDayAll,\n    getEventsForDayTimed,\n    getScopedSlots,\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/composables/calendarWithIntervals.ts",
    "content": "// Composables\nimport { useCalendarBase } from './calendarBase'\n\n// Utilities\nimport { computed, shallowRef } from 'vue'\nimport {\n  copyTimestamp,\n  createDayList,\n  createIntervalList,\n  createNativeLocaleFormatter,\n  getDayIdentifier,\n  MINUTES_IN_DAY,\n  parseTime,\n  updateMinutes,\n  validateNumber,\n  validateTime,\n} from '../util/timestamp'\nimport { propsFactory } from '@/util'\n\n// Types\nimport type { PropType, StyleValue } from 'vue'\nimport type { CalendarBaseProps } from './calendarBase'\nimport type { CalendarDayBodySlotScope, CalendarFormatter, CalendarTimestamp } from '../types'\nimport type { VTime } from '../util/timestamp'\n\nexport const makeCalendarWithIntervalsProps = propsFactory({\n  maxDays: {\n    type: Number,\n    default: 7,\n  },\n  intervalHeight: {\n    type: [Number, String],\n    default: 48,\n    validate: validateNumber,\n  },\n  intervalWidth: {\n    type: [Number, String],\n    default: 60,\n    validate: validateNumber,\n  },\n  intervalMinutes: {\n    type: [Number, String],\n    default: 60,\n    validate: validateNumber,\n  },\n  firstInterval: {\n    type: [Number, String],\n    default: 0,\n    validate: validateNumber,\n  },\n  firstTime: {\n    type: [Number, String, Object] as PropType<VTime>,\n    validate: validateTime,\n  },\n  intervalCount: {\n    type: [Number, String],\n    default: 24,\n    validate: validateNumber,\n  },\n  intervalFormat: {\n    type: Function as PropType<CalendarFormatter>,\n    default: null,\n  },\n  intervalStyle: {\n    type: Function as PropType<(interval: CalendarTimestamp) => StyleValue>,\n    default: null,\n  },\n  showIntervalLabel: {\n    type: Function as PropType<(interval: CalendarTimestamp) => boolean>,\n    default: null,\n  },\n}, 'VCalendar-intervals')\n\ninterface CalendarWithIntervalsProps extends CalendarBaseProps {\n  maxDays: number\n  intervalHeight: string | number\n  intervalMinutes: string | number\n  firstInterval: string | number\n  firstTime: VTime | undefined\n  intervalCount: string | number\n  intervalFormat: CalendarFormatter | string | undefined\n}\n\nexport function useCalendarWithIntervals (props: CalendarWithIntervalsProps) {\n  const base = useCalendarBase(props)\n\n  const scrollAreaRef = shallowRef<HTMLElement>()\n\n  const parsedFirstInterval = computed((): number => {\n    return parseInt(String(props.firstInterval || 0))\n  })\n\n  const parsedIntervalMinutes = computed((): number => {\n    return parseInt(String(props.intervalMinutes || 60))\n  })\n\n  const parsedIntervalCount = computed((): number => {\n    return parseInt(String(props.intervalCount || 24))\n  })\n\n  const parsedIntervalHeight = computed((): number => {\n    return parseFloat(String(props.intervalHeight || 48))\n  })\n\n  const parsedFirstTime = computed((): number | false => {\n    return parseTime(props.firstTime)\n  })\n\n  const firstMinute = computed((): number => {\n    const time = parsedFirstTime.value\n\n    return time !== false && time >= 0 && time <= MINUTES_IN_DAY\n      ? time\n      : parsedFirstInterval.value * parsedIntervalMinutes.value\n  })\n\n  const bodyHeight = computed((): number => {\n    return parsedIntervalCount.value * parsedIntervalHeight.value\n  })\n\n  const days = computed((): CalendarTimestamp[] => {\n    return createDayList(\n      base.parsedStart.value,\n      base.parsedEnd.value,\n      base.times.today,\n      base.weekdaySkips.value,\n      props.maxDays\n    )\n  })\n\n  const intervals = computed((): CalendarTimestamp[][] => {\n    const daysValue = days.value\n    const first: number = firstMinute.value\n    const minutes: number = parsedIntervalMinutes.value\n    const count: number = parsedIntervalCount.value\n    const now: CalendarTimestamp = base.times.now\n\n    return daysValue.map(d => createIntervalList(d, first, minutes, count, now))\n  })\n\n  const intervalFormatter = computed((): CalendarFormatter => {\n    if (props.intervalFormat) {\n      return props.intervalFormat as CalendarFormatter\n    }\n\n    return createNativeLocaleFormatter(\n      base.locale.current.value,\n      (tms, short) => (\n        !short ? { timeZone: 'UTC', hour: '2-digit', minute: '2-digit' }\n        : tms.minute === 0 ? { timeZone: 'UTC', hour: 'numeric' }\n        : { timeZone: 'UTC', hour: 'numeric', minute: '2-digit' }\n      )\n    )\n  })\n\n  function showIntervalLabelDefault (interval: CalendarTimestamp): boolean {\n    const first: CalendarTimestamp = intervals.value[0][0]\n    const isFirst: boolean = first.hour === interval.hour && first.minute === interval.minute\n    return !isFirst\n  }\n\n  function intervalStyleDefault (_interval: CalendarTimestamp): StyleValue {\n    return undefined\n  }\n\n  function getTimestampAtEvent (e: Event, day: CalendarTimestamp): CalendarTimestamp {\n    const timestamp: CalendarTimestamp = copyTimestamp(day)\n    const bounds = (e.currentTarget as HTMLElement).getBoundingClientRect()\n    const baseMinutes: number = firstMinute.value\n    const touchEvent: TouchEvent = e as TouchEvent\n    const mouseEvent: MouseEvent = e as MouseEvent\n    const touches: TouchList = touchEvent.changedTouches || touchEvent.touches\n    const clientY: number = touches && touches[0] ? touches[0].clientY : mouseEvent.clientY\n    const addIntervals: number = (clientY - bounds.top) / parsedIntervalHeight.value\n    const addMinutes: number = Math.floor(addIntervals * parsedIntervalMinutes.value)\n    const minutes: number = baseMinutes + addMinutes\n\n    return updateMinutes(timestamp, minutes, base.times.now)\n  }\n\n  function getSlotScope (timestamp: CalendarTimestamp): CalendarDayBodySlotScope {\n    const scope = copyTimestamp(timestamp) as any\n    scope.timeToY = timeToY\n    scope.timeDelta = timeDelta\n    scope.minutesToPixels = minutesToPixels\n    scope.week = days.value\n    scope.intervalRange = [\n      firstMinute.value,\n      firstMinute.value + parsedIntervalCount.value * parsedIntervalMinutes.value,\n    ]\n    return scope\n  }\n\n  function scrollToTime (time: VTime): boolean {\n    const y = timeToY(time)\n\n    const pane = scrollAreaRef.value\n\n    if (y === false || !pane) {\n      return false\n    }\n\n    pane.scrollTop = y\n\n    return true\n  }\n\n  function minutesToPixels (minutes: number): number {\n    return minutes / parsedIntervalMinutes.value * parsedIntervalHeight.value\n  }\n\n  function timeToY (\n    time: VTime | CalendarTimestamp,\n    targetDateOrClamp: CalendarTimestamp | boolean = false\n  ): number | false {\n    const clamp = targetDateOrClamp !== false\n    const targetDate = typeof targetDateOrClamp !== 'boolean' ? targetDateOrClamp : undefined\n\n    let y = timeDelta(time, targetDate)\n    if (y === false) return y\n\n    y *= bodyHeight.value\n\n    if (clamp) {\n      if (y < 0) {\n        y = 0\n      } else if (y > bodyHeight.value) {\n        y = bodyHeight.value\n      }\n    } else {\n      if (y < 0) {\n        y = y + bodyHeight.value\n      } else if (y > bodyHeight.value) {\n        y = y - bodyHeight.value\n      }\n    }\n\n    return y\n  }\n\n  function timeDelta (time: VTime | CalendarTimestamp, targetDate?: CalendarTimestamp): number | false {\n    let minutes = parseTime(time)\n\n    if (minutes === false) {\n      return false\n    }\n\n    const gap: number = parsedIntervalCount.value * parsedIntervalMinutes.value\n\n    if (targetDate && typeof time === 'object' && 'day' in time) {\n      const a = getDayIdentifier(time)\n      const b = getDayIdentifier(targetDate)\n      minutes += (a - b) * gap\n    }\n\n    const min: number = firstMinute.value\n\n    return (minutes - min) / gap\n  }\n\n  return {\n    ...base,\n    scrollAreaRef,\n    parsedFirstInterval,\n    parsedIntervalMinutes,\n    parsedIntervalCount,\n    parsedIntervalHeight,\n    parsedFirstTime,\n    firstMinute,\n    bodyHeight,\n    days,\n    intervals,\n    intervalFormatter,\n    showIntervalLabelDefault,\n    intervalStyleDefault,\n    getTimestampAtEvent,\n    getSlotScope,\n    scrollToTime,\n    minutesToPixels,\n    timeToY,\n    timeDelta,\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/composables/times.ts",
    "content": "// Utilities\nimport { computed, reactive, watch } from 'vue'\nimport {\n  parseDate,\n  parseTimestamp,\n  validateTimestamp,\n} from '../util/timestamp'\n\n// Types\nimport type { CalendarTimestamp } from '../types'\n\nexport function useTimes (props: { now: string | undefined }) {\n  const times = reactive({\n    now: parseTimestamp('0000-00-00 00:00', true),\n    today: parseTimestamp('0000-00-00', true),\n  })\n\n  const parsedNow = computed((): CalendarTimestamp | null => {\n    return props.now && validateTimestamp(props.now) ? parseTimestamp(props.now, true) : null\n  })\n\n  function setPresent (): void {\n    times.now.present = times.today.present = true\n    times.now.past = times.today.past = false\n    times.now.future = times.today.future = false\n  }\n\n  function getNow (): CalendarTimestamp {\n    return parseDate(new Date())\n  }\n\n  function updateDay (now: CalendarTimestamp, target: CalendarTimestamp): void {\n    if (now.date !== target.date) {\n      target.year = now.year\n      target.month = now.month\n      target.day = now.day\n      target.weekday = now.weekday\n      target.date = now.date\n    }\n  }\n\n  function updateTime (now: CalendarTimestamp, target: CalendarTimestamp): void {\n    if (now.time !== target.time) {\n      target.hour = now.hour\n      target.minute = now.minute\n      target.time = now.time\n    }\n  }\n\n  function updateTimes (): void {\n    const now: CalendarTimestamp = parsedNow.value || getNow()\n    updateDay(now, times.now)\n    updateTime(now, times.now)\n    updateDay(now, times.today)\n  }\n\n  watch(parsedNow, updateTimes)\n\n  updateTimes()\n  setPresent()\n\n  return {\n    times,\n    parsedNow,\n    updateTimes,\n    setPresent,\n    getNow,\n    updateDay,\n    updateTime,\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/index.ts",
    "content": "export { VCalendar } from './VCalendar'\n// export { VCalendarCategory as VCalendarCategory } from './VCalendarDaily'\n// export { VCalendarDaily as VCalendarDaily } from './VCalendarWeekly'\n// export { VCalendarWeekly as VCalendarWeekly } from './VCalendarMonthly'\n// export { VCalendarMonthly as VCalendarMonthly } from './VCalendarCategory'\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/modes/__tests__/__snapshots__/common.spec.ts.snap",
    "content": "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html\n\nexports[`common.ts > should get visuals 1 1`] = `\n{\n  \"allDay\": true,\n  \"category\": false,\n  \"end\": {\n    \"date\": \"2019-02-14\",\n    \"day\": 14,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 4,\n    \"year\": 2019,\n  },\n  \"endIdentifier\": 20190214,\n  \"endTimestampIdentifier\": 201902142359,\n  \"index\": 0,\n  \"input\": {\n    \"end\": \"2019-02-14\",\n    \"start\": \"2019-02-13\",\n  },\n  \"start\": {\n    \"date\": \"2019-02-13\",\n    \"day\": 13,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 3,\n    \"year\": 2019,\n  },\n  \"startIdentifier\": 20190213,\n  \"startTimestampIdentifier\": 201902130000,\n}\n`;\n\nexports[`common.ts > should get visuals 1 2`] = `\n{\n  \"allDay\": true,\n  \"category\": false,\n  \"end\": {\n    \"date\": \"2019-02-14\",\n    \"day\": 14,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 4,\n    \"year\": 2019,\n  },\n  \"endIdentifier\": 20190214,\n  \"endTimestampIdentifier\": 201902142359,\n  \"index\": 0,\n  \"input\": {\n    \"a\": \"2019-02-13\",\n    \"b\": \"2019-02-14\",\n  },\n  \"start\": {\n    \"date\": \"2019-02-13\",\n    \"day\": 13,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 3,\n    \"year\": 2019,\n  },\n  \"startIdentifier\": 20190213,\n  \"startTimestampIdentifier\": 201902130000,\n}\n`;\n\nexports[`common.ts > should get visuals 1 3`] = `\n{\n  \"allDay\": true,\n  \"category\": false,\n  \"end\": {\n    \"date\": \"2019-02-14\",\n    \"day\": 14,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 4,\n    \"year\": 2019,\n  },\n  \"endIdentifier\": 20190214,\n  \"endTimestampIdentifier\": 201902142359,\n  \"index\": 1,\n  \"input\": {\n    \"end\": \"2019-02-14\",\n    \"start\": \"2019-02-13\",\n  },\n  \"start\": {\n    \"date\": \"2019-02-13\",\n    \"day\": 13,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 3,\n    \"year\": 2019,\n  },\n  \"startIdentifier\": 20190213,\n  \"startTimestampIdentifier\": 201902130000,\n}\n`;\n\nexports[`common.ts > should get visuals 1 4`] = `\n{\n  \"allDay\": true,\n  \"category\": false,\n  \"end\": {\n    \"date\": \"2019-02-14\",\n    \"day\": 14,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 4,\n    \"year\": 2019,\n  },\n  \"endIdentifier\": 20190214,\n  \"endTimestampIdentifier\": 201902142359,\n  \"index\": 1,\n  \"input\": {\n    \"a\": \"2019-02-13\",\n    \"b\": \"2019-02-14\",\n  },\n  \"start\": {\n    \"date\": \"2019-02-13\",\n    \"day\": 13,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 3,\n    \"year\": 2019,\n  },\n  \"startIdentifier\": 20190213,\n  \"startTimestampIdentifier\": 201902130000,\n}\n`;\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/modes/__tests__/common.spec.ts",
    "content": "import { parseEvent } from '../../util/events'\nimport {\n  getVisuals, hasOverlap,\n} from '../common'\n\ndescribe('common.ts', () => {\n  it('should get visuals 1', () => {\n    expect(getVisuals([])).toEqual([])\n    expect(parseEvent({\n      start: '2019-02-13',\n      end: '2019-02-14',\n    }, 0, 'start', 'end')).toMatchSnapshot()\n    expect(parseEvent({\n      a: '2019-02-13',\n      b: '2019-02-14',\n    }, 0, 'a', 'b')).toMatchSnapshot()\n    expect(parseEvent({\n      start: '2019-02-13',\n      end: '2019-02-14',\n    }, 1, 'start', 'end')).toMatchSnapshot()\n    expect(parseEvent({\n      a: '2019-02-13',\n      b: '2019-02-14',\n    }, 1, 'a', 'b')).toMatchSnapshot()\n  })\n  it('should get visuals 2', () => {\n    const p0 = parseEvent({\n      start: '2019-02-13',\n      end: '2019-02-14',\n    }, 0, 'start', 'end')\n    const p1 = parseEvent({\n      start: '2019-02-13',\n      end: '2019-02-15',\n    }, 0, 'start', 'end')\n    const p2 = parseEvent({\n      start: '2019-02-13 08:00',\n      end: '2019-02-13 09:00',\n    }, 0, 'start', 'end')\n    const p3 = parseEvent({\n      start: '2019-02-13 07:30',\n      end: '2019-02-13 08:30',\n    }, 0, 'start', 'end')\n    const p4 = parseEvent({\n      start: '2019-02-13 08:00',\n      end: '2019-02-13 10:00',\n    }, 0, 'start', 'end')\n    const visualDefaults = {\n      columnCount: 0,\n      column: 0,\n      left: 0,\n      width: 100,\n    }\n\n    expect(getVisuals([p0, p1, p2, p3, p4])).toEqual([\n      { event: p1, ...visualDefaults },\n      { event: p0, ...visualDefaults },\n      { event: p3, ...visualDefaults },\n      { event: p4, ...visualDefaults },\n      { event: p2, ...visualDefaults },\n    ])\n  })\n  it('should overlap', () => {\n    expect(hasOverlap(0, 1, 1, 2)).toBeFalsy()\n    expect(hasOverlap(0, 1, 1, 2, false)).toBeTruthy()\n    expect(hasOverlap(1, 2, 0, 1)).toBeFalsy()\n    expect(hasOverlap(1, 2, 0, 1, false)).toBeTruthy()\n    expect(hasOverlap(0, 1, 2, 3)).toBeFalsy()\n    expect(hasOverlap(2, 3, 0, 1)).toBeFalsy()\n    expect(hasOverlap(1, 4, 1, 4)).toBeTruthy()\n    expect(hasOverlap(1, 4, 1, 3)).toBeTruthy()\n    expect(hasOverlap(1, 3, 1, 4)).toBeTruthy()\n    expect(hasOverlap(1, 4, 2, 3)).toBeTruthy()\n    expect(hasOverlap(2, 3, 1, 4)).toBeTruthy()\n    expect(hasOverlap(1, 4, 3, 5)).toBeTruthy()\n    expect(hasOverlap(3, 5, 1, 4)).toBeTruthy()\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/modes/column.ts",
    "content": "// Types\nimport { getOverlapGroupHandler } from './common'\nimport type { CalendarEventOverlapMode } from '../types'\n\nconst FULL_WIDTH = 100\n\nexport const column: CalendarEventOverlapMode = (events, firstWeekday, overlapThreshold) => {\n  const handler = getOverlapGroupHandler(firstWeekday)\n\n  return (day, dayEvents, timed, reset) => {\n    const visuals = handler.getVisuals(day, dayEvents, timed, reset)\n\n    if (timed) {\n      visuals.forEach(visual => {\n        visual.left = visual.column * FULL_WIDTH / visual.columnCount\n        visual.width = FULL_WIDTH / visual.columnCount\n      })\n    }\n\n    return visuals\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/modes/common.ts",
    "content": "// Types\nimport type { CalendarEventParsed, CalendarEventVisual, CalendarTimestamp } from '../types'\nimport { getTimestampIdentifier } from '../util/timestamp'\n\nconst MILLIS_IN_DAY = 86400000\n\nexport type GetRange = (event: CalendarEventParsed) => [number, number]\n\nexport function getVisuals (events: CalendarEventParsed[], minStart = 0): CalendarEventVisual[] {\n  const visuals = events.map(event => ({\n    event,\n    columnCount: 0,\n    column: 0,\n    left: 0,\n    width: 100,\n  }))\n\n  visuals.sort((a, b) => {\n    return (\n      Math.max(minStart, a.event.startTimestampIdentifier) - Math.max(minStart, b.event.startTimestampIdentifier)\n    ) || (b.event.endTimestampIdentifier - a.event.endTimestampIdentifier)\n  })\n\n  return visuals\n}\n\nexport interface ColumnGroup {\n  start: number\n  end: number\n  visuals: CalendarEventVisual[]\n}\n\nexport function hasOverlap (s0: number, e0: number, s1: number, e1: number, exclude = true): boolean {\n  return exclude ? !(s0 >= e1 || e0 <= s1) : !(s0 > e1 || e0 < s1)\n}\n\nexport function setColumnCount (groups: ColumnGroup[]) {\n  groups.forEach(group => {\n    group.visuals.forEach(groupVisual => {\n      groupVisual.columnCount = groups.length\n    })\n  })\n}\n\nexport function getRange (event: CalendarEventParsed): [number, number] {\n  return [event.startTimestampIdentifier, event.endTimestampIdentifier]\n}\n\nexport function getDayRange (event: CalendarEventParsed): [number, number] {\n  return [event.startIdentifier, event.endIdentifier]\n}\n\nexport function getNormalizedRange (event: CalendarEventParsed, dayStart: number): [number, number] {\n  return [Math.max(dayStart, event.startTimestampIdentifier), Math.min(dayStart + MILLIS_IN_DAY, event.endTimestampIdentifier)]\n}\n\nexport function getOpenGroup (groups: ColumnGroup[], start: number, end: number, timed: boolean) {\n  for (let i = 0; i < groups.length; i++) {\n    const group = groups[i]\n    let intersected = false\n\n    if (hasOverlap(start, end, group.start, group.end, timed)) {\n      for (let k = 0; k < group.visuals.length; k++) {\n        const groupVisual = group.visuals[k]\n        const [groupStart, groupEnd] = timed ? getRange(groupVisual.event) : getDayRange(groupVisual.event)\n\n        if (hasOverlap(start, end, groupStart, groupEnd, timed)) {\n          intersected = true\n          break\n        }\n      }\n    }\n\n    if (!intersected) {\n      return i\n    }\n  }\n\n  return -1\n}\n\nexport function getOverlapGroupHandler (firstWeekday: number) {\n  const handler = {\n    groups: [] as ColumnGroup[],\n    min: -1,\n    max: -1,\n    reset: () => {\n      handler.groups = []\n      handler.min = handler.max = -1\n    },\n    getVisuals: (day: CalendarTimestamp, dayEvents: CalendarEventParsed[], timed: boolean, reset = false) => {\n      if (day.weekday === firstWeekday || reset) {\n        handler.reset()\n      }\n\n      const dayStart = getTimestampIdentifier(day)\n      const visuals = getVisuals(dayEvents, dayStart)\n\n      visuals.forEach(visual => {\n        const [start, end] = timed ? getRange(visual.event) : getDayRange(visual.event)\n\n        if (handler.groups.length > 0 && !hasOverlap(start, end, handler.min, handler.max, timed)) {\n          setColumnCount(handler.groups)\n          handler.reset()\n        }\n\n        let targetGroup = getOpenGroup(handler.groups, start, end, timed)\n\n        if (targetGroup === -1) {\n          targetGroup = handler.groups.length\n\n          handler.groups.push({ start, end, visuals: [] })\n        }\n\n        const target = handler.groups[targetGroup]\n        target.visuals.push(visual)\n        target.start = Math.min(target.start, start)\n        target.end = Math.max(target.end, end)\n\n        visual.column = targetGroup\n\n        if (handler.min === -1) {\n          handler.min = start\n          handler.max = end\n        } else {\n          handler.min = Math.min(handler.min, start)\n          handler.max = Math.max(handler.max, end)\n        }\n      })\n\n      setColumnCount(handler.groups)\n\n      if (timed) {\n        handler.reset()\n      }\n\n      return visuals\n    },\n  }\n\n  return handler\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/modes/index.ts",
    "content": "// Types\nimport { column } from './column'\nimport { stack } from './stack'\nimport type { CalendarEventOverlapMode } from '../types'\n\nexport const CalendarEventOverlapModes: Record<string, CalendarEventOverlapMode> = {\n  stack,\n  column,\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/modes/stack.ts",
    "content": "// Types\nimport { getNormalizedRange, getOverlapGroupHandler, getVisuals, hasOverlap } from './common'\nimport type { CalendarEventOverlapMode, CalendarEventVisual } from '../types'\nimport { getTimestampIdentifier } from '../util/timestamp'\n\ninterface Group {\n  start: number\n  end: number\n  visuals: CalendarEventVisual[]\n}\n\ninterface Node {\n  parent: Node | null\n  sibling: boolean\n  index: number\n  visual: CalendarEventVisual\n  start: number\n  end: number\n  children: Node[]\n}\n\nconst FULL_WIDTH = 100\n\nconst DEFAULT_OFFSET = 5\n\nconst WIDTH_MULTIPLIER = 1.7\n\n/**\n * Variation of column mode where events can be stacked. The priority of this\n * mode is to stack events together taking up the least amount of space while\n * trying to ensure the content of the event is always visible as well as its\n * start and end. A sibling column has intersecting event content and must be\n * placed beside each other. Non-sibling columns are offset by 5% from the\n * previous column. The width is scaled by 1.7 so the events overlap and\n * whitespace is reduced. If there is a hole in columns the event width is\n * scaled up so it intersects with the next column. The columns have equal\n * width in the space they are given. If the event doesn't have any to the\n * right of it that intersect with it's content it's right side is extended\n * to the right side.\n */\n\nexport const stack: CalendarEventOverlapMode = (events, firstWeekday, overlapThreshold) => {\n  const handler = getOverlapGroupHandler(firstWeekday)\n\n  // eslint-disable-next-line max-statements\n  return (day, dayEvents, timed, reset) => {\n    if (!timed) {\n      return handler.getVisuals(day, dayEvents, timed, reset)\n    }\n\n    const dayStart = getTimestampIdentifier(day)\n    const visuals = getVisuals(dayEvents, dayStart)\n    const groups = getGroups(visuals, dayStart)\n\n    for (const group of groups) {\n      const nodes: Node[] = []\n\n      for (const visual of group.visuals) {\n        const child = getNode(visual, dayStart)\n        const index = getNextIndex(child, nodes)\n\n        if (index === false) {\n          const parent = getParent(child, nodes)\n          if (parent) {\n            child.parent = parent\n            child.sibling = hasOverlap(child.start, child.end, parent.start, addTime(parent.start, overlapThreshold))\n            child.index = parent.index + 1\n            parent.children.push(child)\n          }\n        } else {\n          const [parent] = getOverlappingRange(child, nodes, index - 1, index - 1)\n          const children = getOverlappingRange(child, nodes, index + 1, index + nodes.length, true)\n\n          child.children = children\n          child.index = index\n\n          if (parent) {\n            child.parent = parent\n            child.sibling = hasOverlap(child.start, child.end, parent.start, addTime(parent.start, overlapThreshold))\n            parent.children.push(child)\n          }\n\n          for (const grand of children) {\n            if (grand.parent === parent) {\n              grand.parent = child\n            }\n\n            const grandNext = grand.index - child.index <= 1\n            if (grandNext && child.sibling &&\n              hasOverlap(child.start, addTime(child.start, overlapThreshold), grand.start, grand.end)) {\n              grand.sibling = true\n            }\n          }\n        }\n\n        nodes.push(child)\n      }\n\n      calculateBounds(nodes, overlapThreshold)\n    }\n\n    visuals.sort((a, b) => (a.left - b.left) || (a.event.startTimestampIdentifier - b.event.startTimestampIdentifier))\n\n    return visuals\n  }\n}\n\nfunction calculateBounds (nodes: Node[], overlapThreshold: number) {\n  for (const node of nodes) {\n    const { visual, parent } = node\n    const columns = getMaxChildIndex(node) + 1\n    const spaceLeft = parent ? parent.visual.left : 0\n    const spaceWidth = FULL_WIDTH - spaceLeft\n    const offset = Math.min(DEFAULT_OFFSET, FULL_WIDTH / columns)\n    const columnWidthMultiplier = getColumnWidthMultiplier(node, nodes)\n    const columnOffset = spaceWidth / (columns - node.index + 1)\n    const columnWidth = spaceWidth / (columns - node.index + (node.sibling ? 1 : 0)) * columnWidthMultiplier\n\n    if (parent) {\n      visual.left = node.sibling\n        ? spaceLeft + columnOffset\n        : spaceLeft + offset\n    }\n\n    visual.width = hasFullWidth(node, nodes, overlapThreshold)\n      ? FULL_WIDTH - visual.left\n      : Math.min(FULL_WIDTH - visual.left, columnWidth * WIDTH_MULTIPLIER)\n  }\n}\n\nfunction getColumnWidthMultiplier (node: Node, nodes: Node[]): number {\n  if (!node.children.length) {\n    return 1\n  }\n\n  const maxColumn = node.index + nodes.length\n  const minColumn = node.children.reduce((min, c) => Math.min(min, c.index), maxColumn)\n\n  return minColumn - node.index\n}\n\nfunction getOverlappingIndices (node: Node, nodes: Node[]): number[] {\n  const indices: number[] = []\n  for (const other of nodes) {\n    if (hasOverlap(node.start, node.end, other.start, other.end)) {\n      indices.push(other.index)\n    }\n  }\n  return indices\n}\n\nfunction getNextIndex (node: Node, nodes: Node[]): number | false {\n  const indices = getOverlappingIndices(node, nodes)\n  indices.sort()\n\n  for (let i = 0; i < indices.length; i++) {\n    if (i < indices[i]) {\n      return i\n    }\n  }\n  return false\n}\n\nfunction getOverlappingRange (node: Node, nodes: Node[], indexMin: number, indexMax: number, returnFirstColumn = false): Node[] {\n  const overlapping: Node[] = []\n  for (const other of nodes) {\n    if (other.index >= indexMin && other.index <= indexMax && hasOverlap(node.start, node.end, other.start, other.end)) {\n      overlapping.push(other)\n    }\n  }\n  if (returnFirstColumn && overlapping.length > 0) {\n    const first = overlapping.reduce((min, n) => Math.min(min, n.index), overlapping[0].index)\n    return overlapping.filter(n => n.index === first)\n  }\n  return overlapping\n}\n\nfunction getParent (node: Node, nodes: Node[]): Node | null {\n  let parent: Node | null = null\n  for (const other of nodes) {\n    if (hasOverlap(node.start, node.end, other.start, other.end) && (parent === null || other.index > parent.index)) {\n      parent = other\n    }\n  }\n  return parent\n}\n\nfunction hasFullWidth (node: Node, nodes: Node[], overlapThreshold: number): boolean {\n  for (const other of nodes) {\n    if (other !== node &&\n      other.index > node.index &&\n      hasOverlap(node.start, addTime(node.start, overlapThreshold), other.start, other.end)) {\n      return false\n    }\n  }\n\n  return true\n}\n\nfunction getGroups (visuals: CalendarEventVisual[], dayStart: number): Group[] {\n  const groups: Group[] = []\n\n  for (const visual of visuals) {\n    const [start, end] = getNormalizedRange(visual.event, dayStart)\n    let added = false\n\n    for (const group of groups) {\n      if (hasOverlap(start, end, group.start, group.end)) {\n        group.visuals.push(visual)\n        group.end = Math.max(group.end, end)\n        added = true\n        break\n      }\n    }\n\n    if (!added) {\n      groups.push({ start, end, visuals: [visual] })\n    }\n  }\n\n  return groups\n}\n\nfunction getNode (visual: CalendarEventVisual, dayStart: number): Node {\n  const [start, end] = getNormalizedRange(visual.event, dayStart)\n\n  return {\n    parent: null,\n    sibling: true,\n    index: 0,\n    visual,\n    start,\n    end,\n    children: [],\n  }\n}\n\nfunction getMaxChildIndex (node: Node): number {\n  let max = node.index\n  for (const child of node.children) {\n    const childMax = getMaxChildIndex(child)\n    if (childMax > max) {\n      max = childMax\n    }\n  }\n  return max\n}\n\nfunction addTime (identifier: number, minutes: number): number {\n  const removeMinutes = identifier % 100\n  const totalMinutes = removeMinutes + minutes\n  const addHours = Math.floor(totalMinutes / 60)\n  const addMinutes = totalMinutes % 60\n\n  return identifier - removeMinutes + addHours * 100 + addMinutes\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/types.ts",
    "content": "// Types\nimport type { VNode } from 'vue'\n\nexport type CalendarCategory =\n  | string\n  | {\n    [key: string]: any\n    name?: string\n    categoryName?: string\n  }\n\nexport type CalendarCategoryTextFunction = (\n  category: CalendarCategory\n) => string\n\nexport interface CalendarTimestamp {\n  date: string\n  time: string\n  year: number\n  month: number\n  day: number\n  weekday: number\n  hour: number\n  minute: number\n  hasDay: boolean\n  hasTime: boolean\n  past: boolean\n  present: boolean\n  future: boolean\n  category?: CalendarCategory\n}\n\nexport type CalendarFormatter = (timestamp: CalendarTimestamp, short: boolean) => string\n\nexport interface CalendarEvent {\n  [prop: string]: any\n}\n\nexport interface CalendarEventParsed {\n  input: CalendarEvent\n  start: CalendarTimestamp\n  startIdentifier: number\n  startTimestampIdentifier: number\n  end: CalendarTimestamp\n  endIdentifier: number\n  endTimestampIdentifier: number\n  allDay: boolean\n  index: number\n  category: string | false\n}\n\nexport interface CalendarEventVisual {\n  event: CalendarEventParsed\n  columnCount: number\n  column: number\n  left: number\n  width: number\n}\n\nexport interface CalendarDaySlotScope extends CalendarTimestamp {\n  outside: boolean\n  index: number\n  week: CalendarTimestamp[]\n  category: CalendarCategory\n  intervalRange?: [number, number]\n}\n\nexport type CalendarTimeToY = (\n  time: CalendarTimestamp | number | string,\n  targetDateOrClamp?: CalendarTimestamp | boolean\n) => number\n\nexport type CalendarTimeDelta = (\n  time: CalendarTimestamp | number | string,\n  targetDate?: CalendarTimestamp\n) => number | false\n\nexport interface CalendarDayBodySlotScope extends CalendarDaySlotScope {\n  timeToY: CalendarTimeToY\n  timeDelta: CalendarTimeDelta\n}\n\nexport type CalendarEventOverlapMode = (\n  events: CalendarEventParsed[],\n  firstWeekday: number,\n  overlapThreshold: number\n) => (\n  day: CalendarDaySlotScope,\n  dayEvents: CalendarEventParsed[],\n  timed: boolean,\n  reset: boolean\n) => CalendarEventVisual[]\n\nexport type CalendarEventColorFunction = (event: CalendarEvent) => string | undefined\n\nexport type CalendarEventTimedFunction = (event: CalendarEvent) => boolean\n\nexport type CalendarEventCategoryFunction = (event: CalendarEvent) => string\n\nexport type CalendarEventNameFunction = (event: CalendarEventParsed, timedEvent: boolean) => string | VNode\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/util/__tests__/__snapshots__/events.spec.ts.snap",
    "content": "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html\n\nexports[`events.ts > should parse events 1`] = `\n{\n  \"allDay\": true,\n  \"category\": false,\n  \"end\": {\n    \"date\": \"2019-02-14\",\n    \"day\": 14,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 4,\n    \"year\": 2019,\n  },\n  \"endIdentifier\": 20190214,\n  \"endTimestampIdentifier\": 201902142359,\n  \"index\": 0,\n  \"input\": {\n    \"end\": \"2019-02-14\",\n    \"start\": \"2019-02-13\",\n  },\n  \"start\": {\n    \"date\": \"2019-02-13\",\n    \"day\": 13,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 3,\n    \"year\": 2019,\n  },\n  \"startIdentifier\": 20190213,\n  \"startTimestampIdentifier\": 201902130000,\n}\n`;\n\nexports[`events.ts > should parse events 2`] = `\n{\n  \"allDay\": true,\n  \"category\": false,\n  \"end\": {\n    \"date\": \"2019-02-14\",\n    \"day\": 14,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 4,\n    \"year\": 2019,\n  },\n  \"endIdentifier\": 20190214,\n  \"endTimestampIdentifier\": 201902142359,\n  \"index\": 0,\n  \"input\": {\n    \"a\": \"2019-02-13\",\n    \"b\": \"2019-02-14\",\n  },\n  \"start\": {\n    \"date\": \"2019-02-13\",\n    \"day\": 13,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 3,\n    \"year\": 2019,\n  },\n  \"startIdentifier\": 20190213,\n  \"startTimestampIdentifier\": 201902130000,\n}\n`;\n\nexports[`events.ts > should parse events 3`] = `\n{\n  \"allDay\": true,\n  \"category\": false,\n  \"end\": {\n    \"date\": \"2019-02-14\",\n    \"day\": 14,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 4,\n    \"year\": 2019,\n  },\n  \"endIdentifier\": 20190214,\n  \"endTimestampIdentifier\": 201902142359,\n  \"index\": 1,\n  \"input\": {\n    \"end\": \"2019-02-14\",\n    \"start\": \"2019-02-13\",\n  },\n  \"start\": {\n    \"date\": \"2019-02-13\",\n    \"day\": 13,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 3,\n    \"year\": 2019,\n  },\n  \"startIdentifier\": 20190213,\n  \"startTimestampIdentifier\": 201902130000,\n}\n`;\n\nexports[`events.ts > should parse events 4`] = `\n{\n  \"allDay\": true,\n  \"category\": false,\n  \"end\": {\n    \"date\": \"2019-02-14\",\n    \"day\": 14,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 4,\n    \"year\": 2019,\n  },\n  \"endIdentifier\": 20190214,\n  \"endTimestampIdentifier\": 201902142359,\n  \"index\": 1,\n  \"input\": {\n    \"a\": \"2019-02-13\",\n    \"b\": \"2019-02-14\",\n  },\n  \"start\": {\n    \"date\": \"2019-02-13\",\n    \"day\": 13,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 3,\n    \"year\": 2019,\n  },\n  \"startIdentifier\": 20190213,\n  \"startTimestampIdentifier\": 201902130000,\n}\n`;\n\nexports[`events.ts > should parse timed events 1`] = `\n{\n  \"allDay\": false,\n  \"category\": false,\n  \"end\": {\n    \"date\": \"2019-02-14\",\n    \"day\": 14,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 4,\n    \"year\": 2019,\n  },\n  \"endIdentifier\": 20190214,\n  \"endTimestampIdentifier\": 201902140000,\n  \"index\": 0,\n  \"input\": {\n    \"end\": \"2019-02-14\",\n    \"start\": \"2019-02-13 8:30\",\n  },\n  \"start\": {\n    \"date\": \"2019-02-13\",\n    \"day\": 13,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": true,\n    \"hour\": 8,\n    \"minute\": 30,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"08:30\",\n    \"weekday\": 3,\n    \"year\": 2019,\n  },\n  \"startIdentifier\": 20190213,\n  \"startTimestampIdentifier\": 201902130830,\n}\n`;\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/util/__tests__/__snapshots__/timestamp.spec.ts.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`VCalendar/util/timestamp.ts createDayList should handle skips equal to zero 1`] = `\nArray [\n  Object {\n    \"date\": \"2019-04-22\",\n    \"day\": 22,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 4,\n    \"past\": true,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 1,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-04-24\",\n    \"day\": 24,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 4,\n    \"past\": true,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 3,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-04-26\",\n    \"day\": 26,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": false,\n    \"hour\": 0,\n    \"minute\": 0,\n    \"month\": 4,\n    \"past\": true,\n    \"present\": false,\n    \"time\": \"\",\n    \"weekday\": 5,\n    \"year\": 2019,\n  },\n]\n`;\n\nexports[`VCalendar/util/timestamp.ts should create interval list 1`] = `\nArray [\n  Object {\n    \"date\": \"2019-02-08\",\n    \"day\": 8,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": true,\n    \"hour\": 0,\n    \"minute\": 30,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"00:30\",\n    \"weekday\": 5,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-02-08\",\n    \"day\": 8,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": true,\n    \"hour\": 0,\n    \"minute\": 45,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"00:45\",\n    \"weekday\": 5,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-02-08\",\n    \"day\": 8,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": true,\n    \"hour\": 1,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"01:00\",\n    \"weekday\": 5,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-02-08\",\n    \"day\": 8,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": true,\n    \"hour\": 1,\n    \"minute\": 15,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"01:15\",\n    \"weekday\": 5,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-02-08\",\n    \"day\": 8,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": true,\n    \"hour\": 1,\n    \"minute\": 30,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"01:30\",\n    \"weekday\": 5,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-02-08\",\n    \"day\": 8,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": true,\n    \"hour\": 1,\n    \"minute\": 45,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"01:45\",\n    \"weekday\": 5,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-02-08\",\n    \"day\": 8,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": true,\n    \"hour\": 2,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"02:00\",\n    \"weekday\": 5,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-02-08\",\n    \"day\": 8,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": true,\n    \"hour\": 2,\n    \"minute\": 15,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"02:15\",\n    \"weekday\": 5,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-02-08\",\n    \"day\": 8,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": true,\n    \"hour\": 2,\n    \"minute\": 30,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"02:30\",\n    \"weekday\": 5,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-02-08\",\n    \"day\": 8,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": true,\n    \"hour\": 2,\n    \"minute\": 45,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"02:45\",\n    \"weekday\": 5,\n    \"year\": 2019,\n  },\n]\n`;\n\nexports[`VCalendar/util/timestamp.ts should create interval list 2`] = `\nArray [\n  Object {\n    \"date\": \"2019-02-08\",\n    \"day\": 8,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": true,\n    \"hour\": 0,\n    \"minute\": 15,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"00:15\",\n    \"weekday\": 5,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-02-08\",\n    \"day\": 8,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": true,\n    \"hour\": 0,\n    \"minute\": 30,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"00:30\",\n    \"weekday\": 5,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-02-08\",\n    \"day\": 8,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": true,\n    \"hour\": 0,\n    \"minute\": 45,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"00:45\",\n    \"weekday\": 5,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-02-08\",\n    \"day\": 8,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": true,\n    \"hour\": 1,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"01:00\",\n    \"weekday\": 5,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-02-08\",\n    \"day\": 8,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": true,\n    \"hour\": 1,\n    \"minute\": 15,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"01:15\",\n    \"weekday\": 5,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-02-08\",\n    \"day\": 8,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": true,\n    \"hour\": 1,\n    \"minute\": 30,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"01:30\",\n    \"weekday\": 5,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-02-08\",\n    \"day\": 8,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": true,\n    \"hour\": 1,\n    \"minute\": 45,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"01:45\",\n    \"weekday\": 5,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-02-08\",\n    \"day\": 8,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": true,\n    \"hour\": 2,\n    \"minute\": 0,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"02:00\",\n    \"weekday\": 5,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-02-08\",\n    \"day\": 8,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": true,\n    \"hour\": 2,\n    \"minute\": 15,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"02:15\",\n    \"weekday\": 5,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-02-08\",\n    \"day\": 8,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": true,\n    \"hour\": 2,\n    \"minute\": 30,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"02:30\",\n    \"weekday\": 5,\n    \"year\": 2019,\n  },\n]\n`;\n\nexports[`VCalendar/util/timestamp.ts should create interval list 3`] = `\nArray [\n  Object {\n    \"date\": \"2019-02-08\",\n    \"day\": 8,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": true,\n    \"hour\": 0,\n    \"minute\": 10,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"00:10\",\n    \"weekday\": 5,\n    \"year\": 2019,\n  },\n  Object {\n    \"date\": \"2019-02-08\",\n    \"day\": 8,\n    \"future\": false,\n    \"hasDay\": true,\n    \"hasTime\": true,\n    \"hour\": 0,\n    \"minute\": 15,\n    \"month\": 2,\n    \"past\": false,\n    \"present\": false,\n    \"time\": \"00:15\",\n    \"weekday\": 5,\n    \"year\": 2019,\n  },\n]\n`;\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/util/__tests__/events.spec.ts",
    "content": "/* eslint-disable max-len */\n\nimport { getDayIdentifier, parseTimestamp } from '../timestamp'\nimport { isEventHiddenOn, isEventOn, isEventOverlapping, parseEvent } from '../events'\n\ndescribe('events.ts', () => {\n  it('should parse events', () => {\n    expect(parseEvent({\n      start: '2019-02-13',\n      end: '2019-02-14',\n    }, 0, 'start', 'end')).toMatchSnapshot()\n    expect(parseEvent({\n      a: '2019-02-13',\n      b: '2019-02-14',\n    }, 0, 'a', 'b')).toMatchSnapshot()\n    expect(parseEvent({\n      start: '2019-02-13',\n      end: '2019-02-14',\n    }, 1, 'start', 'end')).toMatchSnapshot()\n    expect(parseEvent({\n      a: '2019-02-13',\n      b: '2019-02-14',\n    }, 1, 'a', 'b')).toMatchSnapshot()\n  })\n\n  it('should parse timed events', () => {\n    expect(parseEvent({\n      start: '2019-02-13 8:30',\n      end: '2019-02-14',\n    }, 0, 'start', 'end')).toMatchSnapshot()\n  })\n\n  it('should check if event is on', () => {\n    const parsed = parseEvent({\n      start: '2019-02-13 8:30',\n      end: '2019-02-15',\n    }, 0, 'start', 'end')\n\n    expect(isEventOn(parsed, getDayIdentifier(parseTimestamp('2019-02-12')!))).toBeFalsy()\n    expect(isEventOn(parsed, getDayIdentifier(parseTimestamp('2019-02-13')!))).toBeTruthy()\n    expect(isEventOn(parsed, getDayIdentifier(parseTimestamp('2019-02-14')!))).toBeTruthy()\n    expect(isEventOn(parsed, getDayIdentifier(parseTimestamp('2019-02-15')!))).toBeTruthy()\n    expect(isEventOn(parsed, getDayIdentifier(parseTimestamp('2019-02-16')!))).toBeFalsy()\n  })\n\n  it('should check if event is hidden if ending but not starting at midnight', () => {\n    const parsed = parseEvent({\n      start: '2021-05-17 10:30',\n      end: '2021-05-18 00:00',\n    }, 0, 'start', 'end')\n\n    expect(isEventHiddenOn(parsed, parseTimestamp('2021-05-16')!)).toBeFalsy()\n    expect(isEventHiddenOn(parsed, parseTimestamp('2021-05-17')!)).toBeFalsy()\n    expect(isEventHiddenOn(parsed, parseTimestamp('2021-05-18')!)).toBeTruthy()\n    expect(isEventHiddenOn(parsed, parseTimestamp('2021-05-16')!)).toBeFalsy()\n  })\n\n  it('should check if event is hidden if starting and ending at midnight', () => {\n    const parsed = parseEvent({\n      start: '2021-05-18 00:00',\n      end: '2021-05-18 00:00',\n    }, 0, 'start', 'end')\n\n    expect(isEventHiddenOn(parsed, parseTimestamp('2021-05-17')!)).toBeFalsy()\n    expect(isEventHiddenOn(parsed, parseTimestamp('2021-05-18')!)).toBeFalsy()\n    expect(isEventHiddenOn(parsed, parseTimestamp('2021-05-16')!)).toBeFalsy()\n  })\n\n  it('should check if event is overlapping', () => {\n    const parsed = parseEvent({\n      start: '2019-02-13 8:30',\n      end: '2019-02-15',\n    }, 0, 'start', 'end')\n\n    expect(isEventOverlapping(parsed, getDayIdentifier(parseTimestamp('2019-02-10')!), getDayIdentifier(parseTimestamp('2019-02-12')!))).toBeFalsy()\n    expect(isEventOverlapping(parsed, getDayIdentifier(parseTimestamp('2019-02-12')!), getDayIdentifier(parseTimestamp('2019-02-18')!))).toBeTruthy()\n    expect(isEventOverlapping(parsed, getDayIdentifier(parseTimestamp('2019-02-16')!), getDayIdentifier(parseTimestamp('2019-02-18')!))).toBeFalsy()\n  })\n\n  it(`should throw an error if start isn't defined`, () => {\n    const fn = () => parseEvent({\n      end: '2019-02-15',\n    }, 0, 'start', 'end')\n\n    expect(fn).toThrow('undefined is not a valid timestamp. It must be a Date, number of milliseconds since Epoch, or a string in the format of YYYY-MM-DD or YYYY-MM-DD hh:mm. Zero-padding is optional and seconds are ignored.')\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/util/__tests__/timestamp.spec.ts",
    "content": "// @ts-nocheck\n/* eslint-disable max-len */\n\nimport {\n  copyTimestamp,\n  createDayList,\n  createIntervalList,\n  createNativeLocaleFormatter,\n  findWeekday,\n  getDayIdentifier,\n  getEndOfMonth,\n  getEndOfWeek,\n  getStartOfMonth,\n  getStartOfWeek,\n  getTimeIdentifier,\n  getWeekdaySkips,\n  nextDay,\n  nextMinutes,\n  parseDate,\n  parseTime,\n  parseTimestamp,\n  prevDay,\n  relativeDays,\n  updateMinutes,\n  updateRelative,\n  validateNumber,\n  validateTimestamp,\n} from '../timestamp'\n\ndescribe.skip('VCalendar/util/timestamp.ts', () => { // eslint-disable-line max-statements\n  it('should parse time number', () => {\n    expect(parseTime(0)).toBe(0)\n    expect(parseTime(120)).toBe(120)\n  })\n\n  it('should parse time string', () => {\n    expect(parseTime('00:00')).toBe(0)\n    expect(parseTime('00:30')).toBe(30)\n    expect(parseTime('08:00')).toBe(8 * 60)\n    expect(parseTime('08:30')).toBe(8 * 60 + 30)\n    expect(parseTime('15:13')).toBe(15 * 60 + 13)\n    expect(parseTime('23:59')).toBe(23 * 60 + 59)\n    expect(parseTime('7')).toBe(7 * 60)\n    expect(parseTime('04:23:11')).toBe(4 * 60 + 23)\n  })\n\n  it('should parse time object', () => {\n    expect(parseTime({ hour: 0, minute: 0 })).toBe(0)\n    expect(parseTime({ hour: 0, minute: 30 })).toBe(30)\n    expect(parseTime({ hour: 8, minute: 0 })).toBe(8 * 60)\n    expect(parseTime({ hour: 8, minute: 30 })).toBe(8 * 60 + 30)\n    expect(parseTime({ hour: 15, minute: 13 })).toBe(15 * 60 + 13)\n    expect(parseTime({ hour: 23, minute: 59 })).toBe(23 * 60 + 59)\n  })\n\n  it('should not parse time', () => {\n    expect(parseTime('nopes')).toBe(false)\n    expect(parseTime({ hour: 23 })).toBe(false)\n    expect(parseTime([23])).toBe(false)\n    expect(parseTime(false)).toBe(false)\n    expect(parseTime(true)).toBe(false)\n  })\n\n  it('should validate timestamp', () => {\n    expect(validateTimestamp('2019-01')).toBe(true)\n    expect(validateTimestamp('2019-01-03')).toBe(true)\n    expect(validateTimestamp('2019-01-03 12')).toBe(true)\n    expect(validateTimestamp('2019-01-03 12:30')).toBe(true)\n    expect(validateTimestamp('2019-01-03 12:30:45')).toBe(true)\n  })\n\n  it('should not validate timestamp', () => {\n    expect(validateTimestamp('2019-01-03 x')).toBe(false)\n    expect(validateTimestamp('20-01-03 12')).toBe(false)\n    expect(validateTimestamp('not a timestamp')).toBe(false)\n    expect(validateTimestamp([])).toBe(false)\n    expect(validateTimestamp({})).toBe(false)\n    expect(validateTimestamp(new Date())).toBe(true)\n    expect(validateTimestamp(2345)).toBe(true)\n  })\n\n  it('should parse timestamp', () => {\n    expect(parseTimestamp('2019-04')).toEqual({\n      date: '2019-04',\n      time: '',\n      year: 2019,\n      month: 4,\n      day: 1,\n      hour: 0,\n      minute: 0,\n      weekday: 0,\n      hasDay: false,\n      hasTime: false,\n      past: false,\n      present: false,\n      future: false,\n    })\n    expect(parseTimestamp('2019-01-03')).toEqual({\n      date: '2019-01-03',\n      time: '',\n      year: 2019,\n      month: 1,\n      day: 3,\n      hour: 0,\n      minute: 0,\n      weekday: 4,\n      hasDay: true,\n      hasTime: false,\n      past: false,\n      present: false,\n      future: false,\n    })\n    expect(parseTimestamp('2019-01-03 12')).toEqual({\n      date: '2019-01-03',\n      time: '',\n      year: 2019,\n      month: 1,\n      day: 3,\n      hour: 12,\n      minute: 0,\n      weekday: 4,\n      hasDay: true,\n      hasTime: false,\n      past: false,\n      present: false,\n      future: false,\n    })\n    expect(parseTimestamp('2019-01-03 12:30')).toEqual({\n      date: '2019-01-03',\n      time: '12:30',\n      year: 2019,\n      month: 1,\n      day: 3,\n      hour: 12,\n      minute: 30,\n      weekday: 4,\n      hasDay: true,\n      hasTime: true,\n      past: false,\n      present: false,\n      future: false,\n    })\n    expect(parseTimestamp('2019-01-03 07:00')).toEqual({\n      date: '2019-01-03',\n      time: '07:00',\n      year: 2019,\n      month: 1,\n      day: 3,\n      hour: 7,\n      minute: 0,\n      weekday: 4,\n      hasDay: true,\n      hasTime: true,\n      past: false,\n      present: false,\n      future: false,\n    })\n    expect(parseTimestamp('2019-01-03 07:00:45')).toEqual({\n      date: '2019-01-03',\n      time: '07:00',\n      year: 2019,\n      month: 1,\n      day: 3,\n      hour: 7,\n      minute: 0,\n      weekday: 4,\n      hasDay: true,\n      hasTime: true,\n      past: false,\n      present: false,\n      future: false,\n    })\n    expect(parseTimestamp('bad')).toBeNull()\n  })\n\n  it('should parse timestamp and update relative flags', () => {\n    expect(parseTimestamp('2019-01-03', true, parseTimestamp('2019-02-08'))).toMatchObject({\n      past: true,\n      present: false,\n      future: false,\n    })\n    expect(parseTimestamp('2019-01-03 07:00', true, parseTimestamp('2019-01-03 07:00'))).toMatchObject({\n      past: false,\n      present: true,\n      future: false,\n    })\n  })\n\n  it('should parse date', () => {\n    expect(parseDate(new Date(2019, 2, 18, 20, 30, 40))).toEqual({\n      date: '2019-03-18',\n      time: '20:30',\n      year: 2019,\n      month: 3,\n      day: 18,\n      hour: 20,\n      minute: 30,\n      weekday: 1,\n      hasDay: true,\n      hasTime: true,\n      past: false,\n      present: true,\n      future: false,\n    })\n  })\n\n  it('should generate day identifiers', () => {\n    expect(getDayIdentifier({\n      year: 2019,\n      month: 9,\n      day: 11,\n    })).toBe(20190911)\n\n    expect(getDayIdentifier({\n      year: 1989,\n      month: 1,\n      day: 1,\n    })).toBe(19890101)\n\n    expect(getDayIdentifier({\n      year: 2020,\n      month: 12,\n      day: 31,\n    })).toBe(20201231)\n  })\n\n  it('should generate time identifiers', () => {\n    expect(getTimeIdentifier({\n      hour: 0,\n      minute: 0,\n    })).toBe(0)\n\n    expect(getTimeIdentifier({\n      hour: 0,\n      minute: 23,\n    })).toBe(23)\n\n    expect(getTimeIdentifier({\n      hour: 11,\n      minute: 6,\n    })).toBe(1106)\n  })\n\n  it('should copy timestamp', () => {\n    const a = {\n      date: '1989-01-03',\n      time: '18:23',\n      year: 1989,\n      month: 1,\n      day: 3,\n      hour: 18,\n      minute: 23,\n      hasTime: true,\n      hasDay: true,\n      past: false,\n      present: false,\n      future: true,\n    }\n    const b = copyTimestamp(a)\n    expect(a).not.toBe(b)\n    expect(a).toEqual(b)\n  })\n\n  it('should update relative flags without time', () => {\n    const now = parseTimestamp('2019-02-04 09:30')!\n    const a = parseTimestamp('2019-02-04')!\n    const b = parseTimestamp('2019-02-06')!\n    const c = parseTimestamp('2019-02-01')!\n\n    const aa = copyTimestamp(a)\n    const bb = copyTimestamp(b)\n    const cc = copyTimestamp(c)\n\n    updateRelative(aa, now)\n    expect(aa.past).toBe(false)\n    expect(aa.present).toBe(true)\n    expect(aa.future).toBe(false)\n\n    updateRelative(bb, now)\n    expect(bb.past).toBe(false)\n    expect(bb.present).toBe(false)\n    expect(bb.future).toBe(true)\n\n    updateRelative(cc, now)\n    expect(cc.past).toBe(true)\n    expect(cc.present).toBe(false)\n    expect(cc.future).toBe(false)\n  })\n\n  it('should update relative flags with time', () => {\n    const now = parseTimestamp('2019-02-04 09:30')!\n    const a = parseTimestamp('2019-02-04 09:30')!\n    const b = parseTimestamp('2019-02-04 12:30')!\n    const c = parseTimestamp('2019-02-04 05:10')!\n\n    const aa = copyTimestamp(a)\n    const bb = copyTimestamp(b)\n    const cc = copyTimestamp(c)\n\n    updateRelative(aa, now, true)\n    expect(aa.past).toBe(false)\n    expect(aa.present).toBe(true)\n    expect(aa.future).toBe(false)\n\n    updateRelative(bb, now, true)\n    expect(bb.past).toBe(false)\n    expect(bb.present).toBe(false)\n    expect(bb.future).toBe(true)\n\n    updateRelative(cc, now, true)\n    expect(cc.past).toBe(true)\n    expect(cc.present).toBe(false)\n    expect(cc.future).toBe(false)\n  })\n\n  it('should calculate weekday', () => { // eslint-disable-line max-statements\n    expect(parseTimestamp('2019-01-01')!.weekday).toBe(2)\n    expect(parseTimestamp('2019-01-02')!.weekday).toBe(3)\n    expect(parseTimestamp('2019-01-03')!.weekday).toBe(4)\n    expect(parseTimestamp('2019-01-04')!.weekday).toBe(5)\n    expect(parseTimestamp('2019-01-05')!.weekday).toBe(6)\n    expect(parseTimestamp('2019-01-06')!.weekday).toBe(0)\n    expect(parseTimestamp('2019-01-07')!.weekday).toBe(1)\n    expect(parseTimestamp('2019-01-08')!.weekday).toBe(2)\n    expect(parseTimestamp('2019-01-09')!.weekday).toBe(3)\n    expect(parseTimestamp('2019-01-10')!.weekday).toBe(4)\n    expect(parseTimestamp('2019-01-11')!.weekday).toBe(5)\n    expect(parseTimestamp('2019-01-12')!.weekday).toBe(6)\n    expect(parseTimestamp('2019-01-13')!.weekday).toBe(0)\n    expect(parseTimestamp('2019-01-14')!.weekday).toBe(1)\n    expect(parseTimestamp('2019-01-15')!.weekday).toBe(2)\n    expect(parseTimestamp('2019-01-16')!.weekday).toBe(3)\n    expect(parseTimestamp('2019-01-17')!.weekday).toBe(4)\n    expect(parseTimestamp('2019-01-18')!.weekday).toBe(5)\n    expect(parseTimestamp('2019-01-19')!.weekday).toBe(6)\n    expect(parseTimestamp('2019-01-20')!.weekday).toBe(0)\n    expect(parseTimestamp('2019-01-21')!.weekday).toBe(1)\n    expect(parseTimestamp('2019-01-22')!.weekday).toBe(2)\n    expect(parseTimestamp('2019-01-23')!.weekday).toBe(3)\n    expect(parseTimestamp('2019-01-24')!.weekday).toBe(4)\n    expect(parseTimestamp('2019-01-25')!.weekday).toBe(5)\n    expect(parseTimestamp('2019-01-26')!.weekday).toBe(6)\n    expect(parseTimestamp('2019-01-27')!.weekday).toBe(0)\n    expect(parseTimestamp('2019-01-28')!.weekday).toBe(1)\n    expect(parseTimestamp('2019-01-29')!.weekday).toBe(2)\n    expect(parseTimestamp('2019-01-30')!.weekday).toBe(3)\n    expect(parseTimestamp('2019-01-31')!.weekday).toBe(4)\n    expect(parseTimestamp('2019-02-01')!.weekday).toBe(5)\n    expect(parseTimestamp('2019-02-02')!.weekday).toBe(6)\n    expect(parseTimestamp('2019-02-03')!.weekday).toBe(0)\n    expect(parseTimestamp('2019-02-04')!.weekday).toBe(1)\n    expect(parseTimestamp('2019-02-05')!.weekday).toBe(2)\n    expect(parseTimestamp('2019-02-06')!.weekday).toBe(3)\n    expect(parseTimestamp('2019-02-07')!.weekday).toBe(4)\n    expect(parseTimestamp('2019-02-08')!.weekday).toBe(5)\n    expect(parseTimestamp('2019-02-09')!.weekday).toBe(6)\n    expect(parseTimestamp('2019-02-10')!.weekday).toBe(0)\n    expect(parseTimestamp('2019-02-11')!.weekday).toBe(1)\n    expect(parseTimestamp('2019-02-12')!.weekday).toBe(2)\n    expect(parseTimestamp('2019-02-13')!.weekday).toBe(3)\n    expect(parseTimestamp('2019-02-14')!.weekday).toBe(4)\n    expect(parseTimestamp('2019-02-15')!.weekday).toBe(5)\n    expect(parseTimestamp('2019-02-16')!.weekday).toBe(6)\n    expect(parseTimestamp('2019-02-17')!.weekday).toBe(0)\n    expect(parseTimestamp('2019-02-18')!.weekday).toBe(1)\n    expect(parseTimestamp('2019-02-19')!.weekday).toBe(2)\n    expect(parseTimestamp('2019-02-20')!.weekday).toBe(3)\n    expect(parseTimestamp('2019-02-21')!.weekday).toBe(4)\n    expect(parseTimestamp('2019-02-22')!.weekday).toBe(5)\n    expect(parseTimestamp('2019-02-23')!.weekday).toBe(6)\n    expect(parseTimestamp('2019-02-24')!.weekday).toBe(0)\n    expect(parseTimestamp('2019-02-25')!.weekday).toBe(1)\n    expect(parseTimestamp('2019-02-26')!.weekday).toBe(2)\n    expect(parseTimestamp('2019-02-27')!.weekday).toBe(3)\n    expect(parseTimestamp('2019-02-28')!.weekday).toBe(4)\n    expect(parseTimestamp('2019-03-01')!.weekday).toBe(5)\n  })\n\n  it('should create interval list', () => {\n    expect(createIntervalList(parseTimestamp('2019-02-08')!, 30, 15, 10)).toMatchSnapshot()\n    expect(createIntervalList(parseTimestamp('2019-02-08')!, 15, 15, 10)).toMatchSnapshot()\n    expect(createIntervalList(parseTimestamp('2019-02-08')!, 10, 5, 2)).toMatchSnapshot()\n  })\n\n  // TODO Create a test that doesn't fail when\n  // the day changes or ignore the code it\n  // covers\n  it.todo('should create native locale formatter')\n\n  it.todo(`should return emptyFormatter if Intl isn't defined`)\n\n  it.todo('should return emptyFormatter if Intl throws error')\n\n  it('should get month start', () => {\n    expect(getStartOfMonth(parseTimestamp('2019-02-08')!).date).toBe('2019-02-01')\n    expect(getStartOfMonth(parseTimestamp('2019-03-08')!).date).toBe('2019-03-01')\n    expect(getStartOfMonth(parseTimestamp('2019-06-08')!).date).toBe('2019-06-01')\n  })\n\n  it('should get month end', () => {\n    expect(getEndOfMonth(parseTimestamp('2019-02-08')!).date).toBe('2019-02-28')\n    expect(getEndOfMonth(parseTimestamp('2019-03-08')!).date).toBe('2019-03-31')\n    expect(getEndOfMonth(parseTimestamp('2019-06-08')!).date).toBe('2019-06-30')\n  })\n\n  it('should get next minutes', () => {\n    expect(nextMinutes({ hour: 8, minute: 30 }, 40)).toEqual({ hour: 9, minute: 10 })\n    expect(nextMinutes({ hour: 8, minute: 10 }, 90)).toEqual({ hour: 9, minute: 40 })\n    expect(nextMinutes({ hour: 8, minute: 0 }, 40)).toEqual({ hour: 8, minute: 40 })\n    expect(nextMinutes({ day: 1, weekday: 1, hour: 23, minute: 50 }, 40)).toEqual({ hour: 0, minute: 30, day: 2, weekday: 2 })\n  })\n\n  it('should update minutes', () => {\n    expect(updateMinutes({}, 40)).toMatchObject({ hour: 0, minute: 40 })\n    expect(updateMinutes({}, 90)).toMatchObject({ hour: 1, minute: 30 })\n    expect(updateMinutes({}, 40, {})).toMatchObject({ hour: 0, minute: 40 })\n    expect(updateMinutes({}, 90, {})).toMatchObject({ hour: 1, minute: 30 })\n  })\n\n  it('should get weekday skips', () => {\n    expect(getWeekdaySkips([0, 1, 2, 3, 4, 5, 6])).toEqual([1, 1, 1, 1, 1, 1, 1])\n    expect(getWeekdaySkips([1, 5, 0, 3, 4, 2, 6])).toEqual([1, 1, 1, 1, 1, 1, 1])\n    expect(getWeekdaySkips([1, 5, 1, 3, 4, 2, 6])).toEqual([0, 1, 1, 1, 1, 1, 2])\n  })\n\n  describe('createDayList', () => {\n    it('should create day list', () => {\n      const skips = getWeekdaySkips([0, 1, 2, 3, 4, 5, 6])\n      const skips1 = getWeekdaySkips([1, 1, 1, 1, 1, 1, 0])\n      expect(() => createDayList(parseTimestamp('2019-02-02'), parseTimestamp('2019-02-01'), parseTimestamp('2019-02-02'), skips)).toThrow('End date is earlier than start date')\n      expect(createDayList(parseTimestamp('2019-02-01'), parseTimestamp('2019-02-10'), parseTimestamp('2019-02-02'), skips)).toHaveLength(10)\n      expect(createDayList(parseTimestamp('2019-02-01'), parseTimestamp('2019-02-10'), parseTimestamp('2019-02-02'), skips1)).toHaveLength(3)\n    })\n\n    it('should allow first day of week', () => {\n      const weekdays = [1, 2, 3, 4, 5, 6, 0]\n      const skips = getWeekdaySkips(weekdays)\n      const today = parseTimestamp('2019-05-03')\n      const date = parseTimestamp('2019-04-30')\n      const start = getStartOfWeek(date, weekdays, today)\n      const end = getEndOfWeek(date, weekdays, today)\n\n      const days = createDayList(\n        start,\n        end,\n        today,\n        skips,\n        Number.MAX_SAFE_INTEGER\n      )\n\n      expect(days).toEqual([\n        { date: '2019-04-29', day: 29, future: false, hasDay: true, hasTime: false, hour: 0, minute: 0, month: 4, past: true, present: false, time: '', weekday: 1, year: 2019 },\n        { date: '2019-04-30', day: 30, future: false, hasDay: true, hasTime: false, hour: 0, minute: 0, month: 4, past: true, present: false, time: '', weekday: 2, year: 2019 },\n        { date: '2019-05-01', day: 1, future: false, hasDay: true, hasTime: false, hour: 0, minute: 0, month: 5, past: true, present: false, time: '', weekday: 3, year: 2019 },\n        { date: '2019-05-02', day: 2, future: false, hasDay: true, hasTime: false, hour: 0, minute: 0, month: 5, past: true, present: false, time: '', weekday: 4, year: 2019 },\n        { date: '2019-05-03', day: 3, future: false, hasDay: true, hasTime: false, hour: 0, minute: 0, month: 5, past: false, present: true, time: '', weekday: 5, year: 2019 },\n        { date: '2019-05-04', day: 4, future: true, hasDay: true, hasTime: false, hour: 0, minute: 0, month: 5, past: false, present: false, time: '', weekday: 6, year: 2019 },\n        { date: '2019-05-05', day: 5, future: true, hasDay: true, hasTime: false, hour: 0, minute: 0, month: 5, past: false, present: false, time: '', weekday: 0, year: 2019 },\n      ])\n    })\n\n    it('should handle skips equal to zero', () => {\n      const weekdays = [1, 2, 3, 4, 5, 6, 0]\n      const skips = [0, 1, 0, 1, 0, 1, 0]\n      const today = parseTimestamp('2019-04-30')\n      const date = parseTimestamp('2019-04-27')\n      const start = getStartOfWeek(date, weekdays, today)\n      const end = getEndOfWeek(date, weekdays, today)\n\n      const days = createDayList(\n        start,\n        end,\n        today,\n        skips,\n        Number.MAX_SAFE_INTEGER\n      )\n\n      expect(days).toMatchSnapshot()\n    })\n\n    it('should throw error if no days are available given specified weekday skips (#7155)', () => {\n      const skips = getWeekdaySkips([1, 2, 3, 4, 5])\n      // 2019-01-12 is a saturday (weekday 6)\n      expect(() => createDayList(parseTimestamp('2019-01-12'), parseTimestamp('2019-01-12'), parseTimestamp('2019-02-01'), skips))\n        .toThrow('No dates found using specified start date, end date, and weekdays.')\n    })\n  })\n\n  it('should find weekday', () => {\n    expect(findWeekday(parseTimestamp('2019-02-03'), 5, nextDay, 100)).toMatchObject({ weekday: 5 })\n    expect(findWeekday(parseTimestamp('2019-01-03'), 1, nextDay, 100)).toMatchObject({ weekday: 1 })\n    expect(findWeekday(parseTimestamp('2019-01-03'), 5, prevDay, 100)).toMatchObject({ weekday: 5 })\n    expect(findWeekday(parseTimestamp('2019-01-03'), 1, prevDay, 100)).toMatchObject({ weekday: 1 })\n  })\n\n  it('should calculate relative days', () => {\n    expect(relativeDays(parseTimestamp('2019-02-03'), nextDay, 1)).toMatchObject({ day: 4 })\n    expect(relativeDays(parseTimestamp('2019-01-03'), nextDay, 10)).toMatchObject({ day: 13 })\n    expect(relativeDays(parseTimestamp('2019-01-03'), nextDay, 1000)).toMatchObject({ day: 29, month: 9, year: 2021 })\n    expect(relativeDays(parseTimestamp('2019-01-03'), prevDay, 1)).toMatchObject({ day: 2 })\n    expect(relativeDays(parseTimestamp('2019-01-03'), prevDay, 10)).toMatchObject({ day: 24 })\n    expect(relativeDays(parseTimestamp('2019-01-03'), prevDay, 1000)).toMatchObject({ day: 8, month: 4, year: 2016 })\n  })\n\n  describe('validateNumber', () => {\n    it('should return true if number is valid', () => {\n      expect(validateNumber(1)).toBe(true)\n      expect(validateNumber(1000000)).toBe(true)\n      expect(validateNumber('1234')).toBe(true)\n    })\n\n    it('should return false if number is bad', () => {\n      expect(validateNumber(Infinity)).toBe(false)\n      expect(validateNumber(NaN)).toBe(false)\n      expect(validateNumber('bad')).toBe(false)\n    })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/util/dateTimeUtils.ts",
    "content": "export function isLeapYear (year: number): boolean {\n  return ((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0)\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/util/events.ts",
    "content": "import {\n  copyTimestamp,\n  getDayIdentifier,\n  getTimestampIdentifier,\n  isTimedless,\n  nextMinutes,\n  parseTimestamp,\n  updateHasTime,\n} from './timestamp'\n\n// Types\nimport type { CalendarEvent, CalendarEventParsed, CalendarTimestamp } from '../types'\n\nexport function parseEvent (\n  input: CalendarEvent,\n  index: number,\n  startProperty: string,\n  endProperty: string,\n  timed = false,\n  category: string | false = false,\n): CalendarEventParsed {\n  const startInput = input[startProperty]\n  const endInput = input[endProperty]\n  const startParsed: CalendarTimestamp = parseTimestamp(startInput, true)\n  const endParsed: CalendarTimestamp = (endInput ? parseTimestamp(endInput, true) : startParsed)\n  const start: CalendarTimestamp = isTimedless(startInput)\n    ? updateHasTime(startParsed, timed)\n    : startParsed\n  const end: CalendarTimestamp = isTimedless(endInput)\n    ? updateHasTime(endParsed, timed)\n    : endParsed\n  const startIdentifier: number = getDayIdentifier(start)\n  const startTimestampIdentifier: number = getTimestampIdentifier(start)\n  const endIdentifier: number = getDayIdentifier(end)\n  const endOffset: number = start.hasTime ? 0 : 2359\n  const endTimestampIdentifier: number = getTimestampIdentifier(end) + endOffset\n  const allDay = !start.hasTime\n\n  return { input, start, startIdentifier, startTimestampIdentifier, end, endIdentifier, endTimestampIdentifier, allDay, index, category }\n}\n\nexport function isEventOn (event: CalendarEventParsed, dayIdentifier: number): boolean {\n  return dayIdentifier >= event.startIdentifier && dayIdentifier <= event.endIdentifier\n}\n\nexport function isEventOnDay (\n  event: CalendarEventParsed,\n  day: CalendarTimestamp,\n  inRange?: [number, number]\n): boolean {\n  if (inRange) {\n    const dayStart = nextMinutes(copyTimestamp(day), inRange[0])\n    const dayEnd = nextMinutes(copyTimestamp(day), inRange[1])\n\n    const starts = event.startTimestampIdentifier < getTimestampIdentifier(dayEnd)\n    const ends = event.endTimestampIdentifier > getTimestampIdentifier(dayStart)\n\n    return starts && ends\n  }\n\n  return isEventOn(event, getDayIdentifier(day))\n}\n\nexport function isEventHiddenOn (event: CalendarEventParsed, day: CalendarTimestamp): boolean {\n  return event.end.time === '00:00' && event.end.date === day.date && event.start.date !== day.date\n}\n\nexport function isEventStart (\n  event: CalendarEventParsed,\n  day: CalendarTimestamp,\n  dayIdentifier: number,\n  firstWeekday: number\n): boolean {\n  return dayIdentifier === event.startIdentifier || (firstWeekday === day.weekday && isEventOn(event, dayIdentifier))\n}\n\nexport function isEventOverlapping (\n  event: CalendarEventParsed,\n  startIdentifier: number,\n  endIdentifier: number\n): boolean {\n  return startIdentifier <= event.endIdentifier && endIdentifier >= event.startIdentifier\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/util/parser.ts",
    "content": "// Types\nimport type { CalendarCategory, CalendarCategoryTextFunction } from '../types'\n\nexport function parsedCategoryText (\n  category: CalendarCategory,\n  categoryText: string | CalendarCategoryTextFunction | undefined\n): string {\n  return typeof categoryText === 'function' ? categoryText(category)\n    : typeof categoryText === 'string' && typeof category === 'object' && category ? category[categoryText]\n    : typeof category === 'string' ? category\n    : ''\n}\n\nexport function getParsedCategories (\n  categories: CalendarCategory | CalendarCategory[],\n  categoryText: string | CalendarCategoryTextFunction | undefined\n): CalendarCategory[] {\n  if (typeof categories === 'string') return categories.split(/\\s*,\\s/)\n  if (Array.isArray(categories)) {\n    return categories.map((category: CalendarCategory) => {\n      if (typeof category === 'string') return category\n\n      const categoryName = typeof category.categoryName === 'string'\n        ? category.categoryName\n        : parsedCategoryText(category, categoryText)\n      return { ...category, categoryName }\n    })\n  }\n  return []\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VCalendar/util/timestamp.ts",
    "content": "import { isLeapYear } from './dateTimeUtils'\n\n// Types\nimport type { CalendarFormatter, CalendarTimestamp } from '../types'\n\nexport const PARSE_REGEX = /^(\\d{4})-(\\d{1,2})(-(\\d{1,2}))?([^\\d]+(\\d{1,2}))?(:(\\d{1,2}))?(:(\\d{1,2}))?$/\nexport const PARSE_TIME = /(\\d\\d?)(:(\\d\\d?)|)(:(\\d\\d?)|)/\n\nexport const DAYS_IN_MONTH: number[] = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]\nexport const DAYS_IN_MONTH_LEAP: number[] = [0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]\nexport const DAYS_IN_MONTH_MIN = 28\nexport const DAYS_IN_MONTH_MAX = 31\nexport const MONTH_MAX = 12\nexport const MONTH_MIN = 1\nexport const DAY_MIN = 1\nexport const DAYS_IN_WEEK = 7\nexport const MINUTES_IN_HOUR = 60\nexport const MINUTE_MAX = 59\nexport const MINUTES_IN_DAY = 24 * 60\nexport const HOURS_IN_DAY = 24\nexport const HOUR_MAX = 23\nexport const FIRST_HOUR = 0\nexport const OFFSET_YEAR = 10000\nexport const OFFSET_MONTH = 100\nexport const OFFSET_HOUR = 100\nexport const OFFSET_TIME = 10000\n\ntype CalendarTimestampFormatOptions = (timestamp: CalendarTimestamp, short: boolean) => Intl.DateTimeFormatOptions\ntype CalendarTimestampOperation = (timestamp: CalendarTimestamp) => CalendarTimestamp\nexport type VTime = number | string | {\n  hour: number\n  minute: number\n}\n\nexport type VTimestampInput = number | string | Date;\n\nexport function getStartOfWeek (timestamp: CalendarTimestamp, weekdays: number[], today?: CalendarTimestamp): CalendarTimestamp {\n  const start = copyTimestamp(timestamp)\n  findWeekday(start, weekdays[0], prevDay)\n  updateFormatted(start)\n  if (today) {\n    updateRelative(start, today, start.hasTime)\n  }\n\n  return start\n}\n\nexport function getEndOfWeek (timestamp: CalendarTimestamp, weekdays: number[], today?: CalendarTimestamp): CalendarTimestamp {\n  const end = copyTimestamp(timestamp)\n  findWeekday(end, weekdays[weekdays.length - 1])\n  updateFormatted(end)\n  if (today) {\n    updateRelative(end, today, end.hasTime)\n  }\n\n  return end\n}\n\nexport function getStartOfMonth (timestamp: CalendarTimestamp): CalendarTimestamp {\n  const start = copyTimestamp(timestamp)\n  start.day = DAY_MIN\n  updateWeekday(start)\n  updateFormatted(start)\n\n  return start\n}\n\nexport function getEndOfMonth (timestamp: CalendarTimestamp): CalendarTimestamp {\n  const end = copyTimestamp(timestamp)\n  end.day = daysInMonth(end.year, end.month)\n  updateWeekday(end)\n  updateFormatted(end)\n\n  return end\n}\n\nexport function validateNumber (input: any): boolean {\n  return isFinite(parseInt(input))\n}\n\nexport function validateTime (input: any): input is VTime {\n  return (typeof input === 'number' && isFinite(input)) ||\n    (!!PARSE_TIME.exec(input)) ||\n    (typeof input === 'object' && isFinite(input.hour) && isFinite(input.minute))\n}\n\nexport function parseTime (input: any): number | false {\n  if (typeof input === 'number') {\n    // when a number is given, it's minutes since 12:00am\n    return input\n  } else if (typeof input === 'string') {\n    // when a string is given, it's a hh:mm:ss format where seconds are optional\n    const parts = PARSE_TIME.exec(input)\n    if (!parts) {\n      return false\n    }\n\n    return parseInt(parts[1]) * 60 + parseInt(parts[3] || 0)\n  } else if (typeof input === 'object') {\n    // when an object is given, it must have hour and minute\n    if (typeof input.hour !== 'number' || typeof input.minute !== 'number') {\n      return false\n    }\n\n    return input.hour * 60 + input.minute\n  } else {\n    // unsupported type\n    return false\n  }\n}\n\nexport function validateTimestamp (input: any): input is VTimestampInput {\n  return (typeof input === 'number' && isFinite(input)) ||\n    (typeof input === 'string' && !!PARSE_REGEX.exec(input)) ||\n    (input instanceof Date)\n}\n\nexport function parseTimestamp (input: VTimestampInput | null, required?: false, now?: CalendarTimestamp | null): CalendarTimestamp | null\nexport function parseTimestamp (input: VTimestampInput, required: true, now?: CalendarTimestamp): CalendarTimestamp\nexport function parseTimestamp (input: VTimestampInput | null, required = false, now?: CalendarTimestamp | null): CalendarTimestamp | null {\n  if (typeof input === 'number' && isFinite(input)) {\n    input = new Date(input)\n  }\n\n  if (input instanceof Date) {\n    const date: CalendarTimestamp = parseDate(input)\n\n    if (now) {\n      updateRelative(date, now, date.hasTime)\n    }\n\n    return date\n  }\n\n  if (typeof input !== 'string') {\n    if (required) {\n      throw new Error(`${input} is not a valid timestamp. It must be a Date, number of milliseconds since Epoch, or a string in the format of YYYY-MM-DD or YYYY-MM-DD hh:mm. Zero-padding is optional and seconds are ignored.`)\n    }\n    return null\n  }\n\n  // YYYY-MM-DD hh:mm:ss\n  const parts = PARSE_REGEX.exec(input)\n\n  if (!parts) {\n    if (required) {\n      throw new Error(`${input} is not a valid timestamp. It must be a Date, number of milliseconds since Epoch, or a string in the format of YYYY-MM-DD or YYYY-MM-DD hh:mm. Zero-padding is optional and seconds are ignored.`)\n    }\n\n    return null\n  }\n\n  const timestamp: CalendarTimestamp = {\n    date: input,\n    time: '',\n    year: parseInt(parts[1]),\n    month: parseInt(parts[2]),\n    day: parseInt(parts[4]) || 1,\n    hour: parseInt(parts[6]) || 0,\n    minute: parseInt(parts[8]) || 0,\n    weekday: 0,\n    hasDay: !!parts[4],\n    hasTime: !!(parts[6] && parts[8]),\n    past: false,\n    present: false,\n    future: false,\n  }\n\n  updateWeekday(timestamp)\n  updateFormatted(timestamp)\n\n  if (now) {\n    updateRelative(timestamp, now, timestamp.hasTime)\n  }\n\n  return timestamp\n}\n\nexport function parseDate (date: Date): CalendarTimestamp {\n  return updateFormatted({\n    date: '',\n    time: '',\n    year: date.getFullYear(),\n    month: date.getMonth() + 1,\n    day: date.getDate(),\n    weekday: date.getDay(),\n    hour: date.getHours(),\n    minute: date.getMinutes(),\n    hasDay: true,\n    hasTime: true,\n    past: false,\n    present: true,\n    future: false,\n  })\n}\n\nexport function getDayIdentifier (timestamp: { year: number, month: number, day: number }): number {\n  return timestamp.year * OFFSET_YEAR + timestamp.month * OFFSET_MONTH + timestamp.day\n}\n\nexport function getTimeIdentifier (timestamp: { hour: number, minute: number }): number {\n  return timestamp.hour * OFFSET_HOUR + timestamp.minute\n}\n\nexport function getTimestampIdentifier (timestamp: CalendarTimestamp): number {\n  return getDayIdentifier(timestamp) * OFFSET_TIME + getTimeIdentifier(timestamp)\n}\n\nexport function updateRelative (timestamp: CalendarTimestamp, now: CalendarTimestamp, time = false): CalendarTimestamp {\n  let a = getDayIdentifier(now)\n  let b = getDayIdentifier(timestamp)\n  let present = a === b\n\n  if (timestamp.hasTime && time && present) {\n    a = getTimeIdentifier(now)\n    b = getTimeIdentifier(timestamp)\n    present = a === b\n  }\n\n  timestamp.past = b < a\n  timestamp.present = present\n  timestamp.future = b > a\n\n  return timestamp\n}\n\nexport function isTimedless (input: VTimestampInput): input is (Date | number) {\n  return (input instanceof Date) || (typeof input === 'number' && isFinite(input))\n}\n\nexport function updateHasTime (timestamp: CalendarTimestamp, hasTime: boolean, now?: CalendarTimestamp): CalendarTimestamp {\n  if (timestamp.hasTime !== hasTime) {\n    timestamp.hasTime = hasTime\n    if (!hasTime) {\n      timestamp.hour = HOUR_MAX\n      timestamp.minute = MINUTE_MAX\n      timestamp.time = getTime(timestamp)\n    }\n    if (now) {\n      updateRelative(timestamp, now, timestamp.hasTime)\n    }\n  }\n\n  return timestamp\n}\n\nexport function updateMinutes (timestamp: CalendarTimestamp, minutes: number, now?: CalendarTimestamp): CalendarTimestamp {\n  timestamp.hasTime = true\n  timestamp.hour = 0\n  timestamp.minute = 0\n  nextMinutes(timestamp, minutes)\n  updateFormatted(timestamp)\n  if (now) {\n    updateRelative(timestamp, now, true)\n  }\n\n  return timestamp\n}\n\nexport function updateWeekday (timestamp: CalendarTimestamp): CalendarTimestamp {\n  timestamp.weekday = getWeekday(timestamp)\n\n  return timestamp\n}\n\nexport function updateFormatted (timestamp: CalendarTimestamp): CalendarTimestamp {\n  timestamp.time = getTime(timestamp)\n  timestamp.date = getDate(timestamp)\n\n  return timestamp\n}\n\nexport function getWeekday (timestamp: CalendarTimestamp): number {\n  if (timestamp.hasDay) {\n    const _ = Math.floor\n    const k = timestamp.day\n    const m = ((timestamp.month + 9) % MONTH_MAX) + 1\n    const C = _(timestamp.year / 100)\n    const Y = (timestamp.year % 100) - (timestamp.month <= 2 ? 1 : 0)\n\n    return (((k + _(2.6 * m - 0.2) - 2 * C + Y + _(Y / 4) + _(C / 4)) % 7) + 7) % 7\n  }\n\n  return timestamp.weekday\n}\n\nexport function daysInMonth (year: number, month: number) {\n  return isLeapYear(year) ? DAYS_IN_MONTH_LEAP[month] : DAYS_IN_MONTH[month]\n}\n\nexport function copyTimestamp (timestamp: null): null\nexport function copyTimestamp (timestamp: CalendarTimestamp): CalendarTimestamp\nexport function copyTimestamp (timestamp: CalendarTimestamp | null): CalendarTimestamp | null {\n  if (timestamp == null) return null\n\n  const { date, time, year, month, day, weekday, hour, minute, hasDay, hasTime, past, present, future } = timestamp\n\n  return { date, time, year, month, day, weekday, hour, minute, hasDay, hasTime, past, present, future }\n}\n\nexport function padNumber (x: number, length: number): string {\n  let padded = String(x)\n  while (padded.length < length) {\n    padded = '0' + padded\n  }\n\n  return padded\n}\n\nexport function getDate (timestamp: CalendarTimestamp): string {\n  let str = `${padNumber(timestamp.year, 4)}-${padNumber(timestamp.month, 2)}`\n\n  if (timestamp.hasDay) str += `-${padNumber(timestamp.day, 2)}`\n\n  return str\n}\n\nexport function getTime (timestamp: CalendarTimestamp): string {\n  if (!timestamp.hasTime) {\n    return ''\n  }\n\n  return `${padNumber(timestamp.hour, 2)}:${padNumber(timestamp.minute, 2)}`\n}\n\nexport function nextMinutes (timestamp: CalendarTimestamp, minutes: number): CalendarTimestamp {\n  timestamp.minute += minutes\n  while (timestamp.minute >= MINUTES_IN_HOUR) {\n    timestamp.minute -= MINUTES_IN_HOUR\n    timestamp.hour++\n    if (timestamp.hour >= HOURS_IN_DAY) {\n      nextDay(timestamp)\n      timestamp.hour = FIRST_HOUR\n    }\n  }\n\n  return timestamp\n}\n\nexport function nextDay (timestamp: CalendarTimestamp): CalendarTimestamp {\n  timestamp.day++\n  timestamp.weekday = (timestamp.weekday + 1) % DAYS_IN_WEEK\n  if (timestamp.day > DAYS_IN_MONTH_MIN && timestamp.day > daysInMonth(timestamp.year, timestamp.month)) {\n    timestamp.day = DAY_MIN\n    timestamp.month++\n    if (timestamp.month > MONTH_MAX) {\n      timestamp.month = MONTH_MIN\n      timestamp.year++\n    }\n  }\n\n  return timestamp\n}\n\nexport function prevDay (timestamp: CalendarTimestamp): CalendarTimestamp {\n  timestamp.day--\n  timestamp.weekday = (timestamp.weekday + 6) % DAYS_IN_WEEK\n  if (timestamp.day < DAY_MIN) {\n    timestamp.month--\n    if (timestamp.month < MONTH_MIN) {\n      timestamp.year--\n      timestamp.month = MONTH_MAX\n    }\n    timestamp.day = daysInMonth(timestamp.year, timestamp.month)\n  }\n\n  return timestamp\n}\n\nexport function relativeDays (\n  timestamp: CalendarTimestamp,\n  mover: CalendarTimestampOperation = nextDay,\n  days = 1\n): CalendarTimestamp {\n  while (--days >= 0) mover(timestamp)\n\n  return timestamp\n}\n\nexport function diffMinutes (min: CalendarTimestamp, max: CalendarTimestamp) {\n  const Y = (max.year - min.year) * 525600\n  const M = (max.month - min.month) * 43800\n  const D = (max.day - min.day) * 1440\n  const h = (max.hour - min.hour) * 60\n  const m = (max.minute - min.minute)\n\n  return Y + M + D + h + m\n}\n\nexport function findWeekday (timestamp: CalendarTimestamp, weekday: number,\n  mover: CalendarTimestampOperation = nextDay, maxDays = 6): CalendarTimestamp {\n  while (timestamp.weekday !== weekday && --maxDays >= 0) mover(timestamp)\n\n  return timestamp\n}\n\nexport function getWeekdaySkips (weekdays: number[]): number[] {\n  const skips: number[] = [1, 1, 1, 1, 1, 1, 1]\n  const filled: number[] = [0, 0, 0, 0, 0, 0, 0]\n  for (let i = 0; i < weekdays.length; i++) {\n    filled[weekdays[i]] = 1\n  }\n  for (let k = 0; k < DAYS_IN_WEEK; k++) {\n    let skip = 1\n    for (let j = 1; j < DAYS_IN_WEEK; j++) {\n      const next = (k + j) % DAYS_IN_WEEK\n      if (filled[next]) {\n        break\n      }\n      skip++\n    }\n    skips[k] = filled[k] * skip\n  }\n\n  return skips\n}\n\nexport function timestampToDate (timestamp: CalendarTimestamp): Date {\n  const time = `${padNumber(timestamp.hour, 2)}:${padNumber(timestamp.minute, 2)}`\n  const date = timestamp.date\n\n  return new Date(`${date}T${time}:00+00:00`)\n}\n\nexport function createDayList (\n  start: CalendarTimestamp,\n  end: CalendarTimestamp,\n  now: CalendarTimestamp,\n  weekdaySkips: number[],\n  max = 42,\n  min = 0\n): CalendarTimestamp[] {\n  const stop = getDayIdentifier(end)\n  const days: CalendarTimestamp[] = []\n  let current = copyTimestamp(start)\n  let currentIdentifier = 0\n  let stopped = currentIdentifier === stop\n\n  if (stop < getDayIdentifier(start)) {\n    throw new Error('End date is earlier than start date.')\n  }\n\n  while ((!stopped || days.length < min) && days.length < max) {\n    currentIdentifier = getDayIdentifier(current)\n    stopped = stopped || currentIdentifier === stop\n    if (weekdaySkips[current.weekday] === 0) {\n      current = nextDay(current)\n      continue\n    }\n    const day = copyTimestamp(current)\n    updateFormatted(day)\n    updateRelative(day, now)\n    days.push(day)\n    current = relativeDays(current, nextDay, weekdaySkips[current.weekday])\n  }\n\n  if (!days.length) throw new Error('No dates found using specified start date, end date, and weekdays.')\n\n  return days\n}\n\nexport function createIntervalList (\n  timestamp: CalendarTimestamp,\n  first: number,\n  minutes: number,\n  count: number,\n  now?: CalendarTimestamp\n): CalendarTimestamp[] {\n  const intervals: CalendarTimestamp[] = []\n\n  for (let i = 0; i < count; i++) {\n    const mins = first + (i * minutes)\n    const int = copyTimestamp(timestamp)\n    intervals.push(updateMinutes(int, mins, now))\n  }\n\n  return intervals\n}\n\nexport function createNativeLocaleFormatter (locale: string, getOptions: CalendarTimestampFormatOptions): CalendarFormatter {\n  const emptyFormatter: CalendarFormatter = (_t, _s) => ''\n\n  if (typeof Intl === 'undefined' || typeof Intl.DateTimeFormat === 'undefined') {\n    return emptyFormatter\n  }\n\n  return (timestamp, short) => {\n    try {\n      const intlFormatter = new Intl.DateTimeFormat(locale || undefined, getOptions(timestamp, short))\n\n      return intlFormatter.format(timestampToDate(timestamp))\n    } catch (e) {\n      return ''\n    }\n  }\n}\n\nexport function validateWeekdays (input: string | (number | string)[]): boolean {\n  if (typeof input === 'string') {\n    input = input.split(',')\n  }\n\n  if (Array.isArray(input)) {\n    const ints = input.map(x => parseInt(x))\n\n    if (ints.length > DAYS_IN_WEEK || ints.length === 0) {\n      return false\n    }\n\n    const visited: Record<number, boolean> = {}\n    let wrapped = false\n\n    for (let i = 0; i < ints.length; i++) {\n      const x = ints[i]\n\n      if (!isFinite(x) || x < 0 || x >= DAYS_IN_WEEK) {\n        return false\n      }\n\n      if (i > 0) {\n        const d = x - ints[i - 1]\n        if (d < 0) {\n          if (wrapped) {\n            return false\n          }\n          wrapped = true\n        } else if (d === 0) {\n          return false\n        }\n      }\n\n      if (visited[x]) {\n        return false\n      }\n      visited[x] = true\n    }\n\n    return true\n  }\n\n  return false\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VCard/VCard.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n@use './mixins' as *\n\n@include tools.layer('components')\n  .v-card\n    display: block\n    overflow: hidden\n    overflow-wrap: $card-overflow-wrap\n    position: relative\n    padding: $card-padding\n    text-decoration: none\n    transition-duration: $card-transition-duration\n    transition-property: $card-transition-property\n    transition-timing-function: $card-transition-timing-function\n    z-index: 0\n\n    @include tools.border($card-border...)\n    @include tools.position($card-positions)\n    @include tools.rounded($card-border-radius)\n    @include tools.states('.v-card__overlay')\n    @include tools.variant($card-variants...)\n\n    &--disabled\n      pointer-events: none\n      user-select: none\n\n      >:not(.v-card__loader)\n        opacity: $card-disabled-opacity\n\n    &--flat\n      box-shadow: none\n\n    &--hover\n      cursor: pointer\n\n      &::before,\n      &::after\n        border-radius: inherit\n        bottom: 0\n        content: ''\n        display: block\n        left: 0\n        pointer-events: none\n        position: absolute\n        right: 0\n        top: 0\n        transition: inherit\n\n      &::before\n        opacity: 1\n        z-index: -1\n\n        @include tools.elevation($card-elevation)\n\n      &::after\n        z-index: 1\n        opacity: 0\n\n        @include tools.elevation($card-hover-elevation)\n\n      &:hover::after\n        opacity: 1\n\n      &:hover::before\n        opacity: 0\n\n      &:hover\n        @include tools.elevation($card-hover-elevation)\n\n    &--link\n      cursor: pointer\n\n  .v-card-actions\n    align-items: center\n    display: flex\n    flex: $card-actions-flex\n    min-height: $card-actions-min-height\n    padding: $card-actions-padding\n    gap: $card-actions-gap\n\n  .v-card-item\n    align-items: $card-item-align-items\n    display: grid\n    flex: $card-header-flex\n    grid-template-areas: \"prepend content append\"\n    grid-template-columns: max-content auto max-content\n    padding: $card-item-padding\n\n    + .v-card-text\n      padding-top: 0\n\n    &__prepend,\n    &__append\n      align-items: center\n      display: flex\n\n    &__prepend\n      grid-area: prepend\n      padding-inline-end: $card-prepend-padding-inline-end\n\n    &__append\n      grid-area: append\n      padding-inline-start: $card-append-padding-inline-start\n\n  .v-card-item__content\n    align-self: center\n    grid-area: content\n    overflow: hidden\n\n  .v-card-title\n    display: block\n    flex: $card-title-flex\n    font-size: $card-title-font-size\n    font-weight: $card-title-font-weight\n    hyphens: $card-title-hyphens\n    letter-spacing: $card-title-letter-spacing\n    min-width: 0\n    overflow-wrap: $card-title-overflow-wrap\n    overflow: $card-title-overflow\n    padding: $card-title-padding\n    text-overflow: $card-title-text-overflow\n    text-transform: $card-title-text-transform\n    white-space: $card-title-white-space\n    word-break: $card-title-word-break\n    word-wrap: $card-title-word-wrap\n\n    @include card-line-height-densities($card-title-densities)\n\n    .v-card-item &\n      padding: $card-title-header-padding\n\n    + .v-card-text,\n    + .v-card-actions\n      padding-top: 0\n\n  .v-card-subtitle\n    display: block\n    flex: $card-subtitle-flex\n    font-size: $card-subtitle-font-size\n    font-weight: $card-subtitle-font-weight\n    letter-spacing: $card-subtitle-letter-spacing\n    opacity: $card-subtitle-opacity\n    overflow: $card-subtitle-overflow\n    padding: $card-subtitle-padding\n    text-overflow: $card-subtitle-text-overflow\n    text-transform: $card-subtitle-text-transform\n    white-space: $card-subtitle-white-space\n\n    @include card-line-height-densities($card-subtitle-density-line-height)\n\n    .v-card-item &\n      padding: $card-subtitle-header-padding\n\n  .v-card-text\n    flex: $card-text-flex\n    font-size: $card-text-font-size\n    font-weight: $card-text-font-weight\n    letter-spacing: $card-text-letter-spacing\n    opacity: $card-text-opacity\n    padding: $card-text-padding\n    text-transform: $card-text-text-transform\n\n    @include card-line-height-densities($card-text-density-line-height)\n\n  .v-card__image\n    display: flex\n    height: 100%\n    flex: $card-img-flex\n    left: 0\n    overflow: hidden\n    position: absolute\n    top: 0\n    width: 100%\n    z-index: -1\n\n  .v-card__content\n    border-radius: inherit\n    overflow: hidden\n    position: relative\n\n  .v-card__loader\n    bottom: $card-loader-bottom\n    top: $card-loader-top\n    left: 0\n    position: absolute\n    right: 0\n    width: 100%\n    z-index: 1\n\n    @media (forced-colors: active)\n      .v-progress-linear\n        border: none\n\n  .v-card__overlay\n    background-color: currentColor\n    border-radius: inherit\n    position: absolute\n    top: 0\n    right: 0\n    bottom: 0\n    left: 0\n    pointer-events: none\n    opacity: 0\n    transition: opacity 0.2s ease-in-out\n\n  @media (forced-colors: active)\n    .v-card\n      &:not(&--variant-text, &--variant-plain)\n        border: thin solid\n"
  },
  {
    "path": "packages/vuetify/src/components/VCard/VCard.tsx",
    "content": "/* eslint-disable complexity */\n\n// Styles\nimport './VCard.sass'\n\n// Components\nimport { VCardActions } from './VCardActions'\nimport { VCardItem } from './VCardItem'\nimport { VCardText } from './VCardText'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\nimport { VImg } from '@/components/VImg'\n\n// Composables\nimport { makeBorderProps, useBorder } from '@/composables/border'\nimport { makeComponentProps } from '@/composables/component'\nimport { makeDensityProps, useDensity } from '@/composables/density'\nimport { makeDimensionProps, useDimension } from '@/composables/dimensions'\nimport { makeElevationProps, useElevation } from '@/composables/elevation'\nimport { IconValue } from '@/composables/icons'\nimport { LoaderSlot, makeLoaderProps, useLoader } from '@/composables/loader'\nimport { makeLocationProps, useLocation } from '@/composables/location'\nimport { makePositionProps, usePosition } from '@/composables/position'\nimport { makeRoundedProps, useRounded } from '@/composables/rounded'\nimport { makeRouterProps, useLink } from '@/composables/router'\nimport { makeTagProps } from '@/composables/tag'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\nimport { genOverlays, makeVariantProps, useVariant } from '@/composables/variant'\n\n// Directives\nimport vRipple from '@/directives/ripple'\n\n// Utilities\nimport { shallowRef, watch } from 'vue'\nimport { convertToUnit, genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { VCardItemSlots } from './VCardItem'\nimport type { LoaderSlotProps } from '@/composables/loader'\nimport type { RippleDirectiveBinding } from '@/directives/ripple'\n\nexport const makeVCardProps = propsFactory({\n  appendAvatar: String,\n  appendIcon: IconValue,\n  disabled: Boolean,\n  flat: Boolean,\n  hover: Boolean,\n  image: String,\n  link: {\n    type: Boolean,\n    default: undefined,\n  },\n  prependAvatar: String,\n  prependIcon: IconValue,\n  ripple: {\n    type: [Boolean, Object] as PropType<RippleDirectiveBinding['value']>,\n    default: true,\n  },\n  subtitle: {\n    type: [String, Number, Boolean],\n    default: undefined,\n  },\n  text: {\n    type: [String, Number, Boolean],\n    default: undefined,\n  },\n  title: {\n    type: [String, Number, Boolean],\n    default: undefined,\n  },\n\n  ...makeBorderProps(),\n  ...makeComponentProps(),\n  ...makeDensityProps(),\n  ...makeDimensionProps(),\n  ...makeElevationProps(),\n  ...makeLoaderProps(),\n  ...makeLocationProps(),\n  ...makePositionProps(),\n  ...makeRoundedProps(),\n  ...makeRouterProps(),\n  ...makeTagProps(),\n  ...makeThemeProps(),\n  ...makeVariantProps({ variant: 'elevated' } as const),\n}, 'VCard')\n\nexport type VCardSlots = VCardItemSlots & {\n  default: never\n  actions: never\n  text: never\n  loader: LoaderSlotProps\n  image: never\n  item: never\n}\n\nexport const VCard = genericComponent<VCardSlots>()({\n  name: 'VCard',\n\n  directives: { vRipple },\n\n  props: makeVCardProps(),\n\n  setup (props, { attrs, slots }) {\n    const { themeClasses } = provideTheme(props)\n    const { borderClasses } = useBorder(props)\n    const { colorClasses, colorStyles, variantClasses } = useVariant(props)\n    const { densityClasses } = useDensity(props)\n    const { dimensionStyles } = useDimension(props)\n    const { elevationClasses } = useElevation(props)\n    const { loaderClasses } = useLoader(props)\n    const { locationStyles } = useLocation(props)\n    const { positionClasses } = usePosition(props)\n    const { roundedClasses } = useRounded(props)\n    const link = useLink(props, attrs)\n    const loadingColor = shallowRef<string | undefined>(undefined)\n\n    watch(() => props.loading, (val, old) => {\n      loadingColor.value = !val && typeof old === 'string'\n        ? old\n        : typeof val === 'boolean'\n          ? undefined\n          : val\n    }, { immediate: true })\n\n    useRender(() => {\n      const isLink = props.link !== false && link.isLink.value\n      const isClickable = (\n        !props.disabled &&\n        props.link !== false &&\n        (props.link || link.isClickable.value)\n      )\n      const Tag = isLink ? 'a' : props.tag\n      const hasTitle = !!(slots.title || props.title != null)\n      const hasSubtitle = !!(slots.subtitle || props.subtitle != null)\n      const hasHeader = hasTitle || hasSubtitle\n      const hasAppend = !!(slots.append || props.appendAvatar || props.appendIcon)\n      const hasPrepend = !!(slots.prepend || props.prependAvatar || props.prependIcon)\n      const hasImage = !!(slots.image || props.image)\n      const hasCardItem = hasHeader || hasPrepend || hasAppend\n      const hasText = !!(slots.text || props.text != null)\n\n      return (\n        <Tag\n          { ...link.linkProps }\n          class={[\n            'v-card',\n            {\n              'v-card--disabled': props.disabled,\n              'v-card--flat': props.flat,\n              'v-card--hover': props.hover && !(props.disabled || props.flat),\n              'v-card--link': isClickable,\n            },\n            themeClasses.value,\n            borderClasses.value,\n            colorClasses.value,\n            densityClasses.value,\n            elevationClasses.value,\n            loaderClasses.value,\n            positionClasses.value,\n            roundedClasses.value,\n            variantClasses.value,\n            props.class,\n          ]}\n          style={[\n            colorStyles.value,\n            dimensionStyles.value,\n            locationStyles.value,\n            {\n              '--v-card-height': convertToUnit(props.height),\n            },\n            props.style,\n          ]}\n          onClick={ isClickable && link.navigate.value }\n          v-ripple={ isClickable && props.ripple }\n          tabindex={ props.disabled ? -1 : undefined }\n        >\n          { hasImage && (\n            <div key=\"image\" class=\"v-card__image\">\n              { !slots.image ? (\n                <VImg\n                  key=\"image-img\"\n                  cover\n                  src={ props.image }\n                />\n              ) : (\n                <VDefaultsProvider\n                  key=\"image-defaults\"\n                  disabled={ !props.image }\n                  defaults={{\n                    VImg: {\n                      cover: true,\n                      src: props.image,\n                    },\n                  }}\n                  v-slots:default={ slots.image }\n                />\n              )}\n            </div>\n          )}\n\n          <LoaderSlot\n            name=\"v-card\"\n            active={ !!props.loading }\n            color={ loadingColor.value }\n            v-slots={{ default: slots.loader }}\n          />\n\n          { hasCardItem && (\n            <VCardItem\n              key=\"item\"\n              prependAvatar={ props.prependAvatar }\n              prependIcon={ props.prependIcon }\n              title={ props.title }\n              subtitle={ props.subtitle }\n              appendAvatar={ props.appendAvatar }\n              appendIcon={ props.appendIcon }\n            >\n              {{\n                default: slots.item,\n                prepend: slots.prepend,\n                title: slots.title,\n                subtitle: slots.subtitle,\n                append: slots.append,\n              }}\n            </VCardItem>\n          )}\n\n          { hasText && (\n            <VCardText key=\"text\">\n              { slots.text?.() ?? props.text }\n            </VCardText>\n          )}\n\n          { slots.default?.() }\n\n          { slots.actions && (\n            <VCardActions v-slots={{ default: slots.actions }} />\n          )}\n\n          { genOverlays(isClickable, 'v-card') }\n        </Tag>\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VCard = InstanceType<typeof VCard>\n"
  },
  {
    "path": "packages/vuetify/src/components/VCard/VCardActions.tsx",
    "content": "// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { provideDefaults } from '@/composables/defaults'\nimport { makeTagProps } from '@/composables/tag'\n\n// Utilities\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\nexport const makeVCardActionsProps = propsFactory({\n  ...makeComponentProps(),\n  ...makeTagProps(),\n}, 'VCardActions')\n\nexport const VCardActions = genericComponent()({\n  name: 'VCardActions',\n\n  props: makeVCardActionsProps(),\n\n  setup (props, { slots }) {\n    provideDefaults({\n      VBtn: {\n        slim: true,\n        variant: 'text',\n      },\n    })\n\n    useRender(() => (\n      <props.tag\n        class={[\n          'v-card-actions',\n          props.class,\n        ]}\n        style={ props.style }\n        v-slots={ slots }\n      />\n    ))\n\n    return {}\n  },\n})\n\nexport type VCardActions = InstanceType<typeof VCardActions>\n"
  },
  {
    "path": "packages/vuetify/src/components/VCard/VCardItem.tsx",
    "content": "// Components\nimport { VCardSubtitle } from './VCardSubtitle'\nimport { VCardTitle } from './VCardTitle'\nimport { VAvatar } from '@/components/VAvatar'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\nimport { VIcon } from '@/components/VIcon'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { makeDensityProps } from '@/composables/density'\nimport { IconValue } from '@/composables/icons'\nimport { makeTagProps } from '@/composables/tag'\n\n// Utilities\nimport { toDisplayString } from 'vue'\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\nexport type VCardItemSlots = {\n  default: never\n  prepend: never\n  append: never\n  title: never\n  subtitle: never\n}\n\nexport const makeCardItemProps = propsFactory({\n  appendAvatar: String,\n  appendIcon: IconValue,\n  prependAvatar: String,\n  prependIcon: IconValue,\n  subtitle: {\n    type: [String, Number, Boolean],\n    default: undefined,\n  },\n  title: {\n    type: [String, Number, Boolean],\n    default: undefined,\n  },\n\n  ...makeComponentProps(),\n  ...makeDensityProps(),\n  ...makeTagProps(),\n}, 'VCardItem')\n\nexport const VCardItem = genericComponent<VCardItemSlots>()({\n  name: 'VCardItem',\n\n  props: makeCardItemProps(),\n\n  setup (props, { slots }) {\n    useRender(() => {\n      const hasPrependMedia = !!(props.prependAvatar || props.prependIcon)\n      const hasPrepend = !!(hasPrependMedia || slots.prepend)\n      const hasAppendMedia = !!(props.appendAvatar || props.appendIcon)\n      const hasAppend = !!(hasAppendMedia || slots.append)\n      const hasTitle = !!(props.title != null || slots.title)\n      const hasSubtitle = !!(props.subtitle != null || slots.subtitle)\n\n      return (\n        <props.tag\n          class={[\n            'v-card-item',\n            props.class,\n          ]}\n          style={ props.style }\n        >\n          { hasPrepend && (\n            <div key=\"prepend\" class=\"v-card-item__prepend\">\n              { !slots.prepend ? (\n                <>\n                  { props.prependAvatar && (\n                    <VAvatar\n                      key=\"prepend-avatar\"\n                      density={ props.density }\n                      image={ props.prependAvatar }\n                    />\n                  )}\n\n                  { props.prependIcon && (\n                    <VIcon\n                      key=\"prepend-icon\"\n                      density={ props.density }\n                      icon={ props.prependIcon }\n                    />\n                  )}\n                </>\n              ) : (\n                <VDefaultsProvider\n                  key=\"prepend-defaults\"\n                  disabled={ !hasPrependMedia }\n                  defaults={{\n                    VAvatar: {\n                      density: props.density,\n                      image: props.prependAvatar,\n                    },\n                    VIcon: {\n                      density: props.density,\n                      icon: props.prependIcon,\n                    },\n                  }}\n                  v-slots:default={ slots.prepend }\n                />\n              )}\n            </div>\n          )}\n\n          <div class=\"v-card-item__content\">\n            { hasTitle && (\n              <VCardTitle key=\"title\">\n                { slots.title?.() ?? toDisplayString(props.title) }\n              </VCardTitle>\n            )}\n\n            { hasSubtitle && (\n              <VCardSubtitle key=\"subtitle\">\n                { slots.subtitle?.() ?? toDisplayString(props.subtitle) }\n              </VCardSubtitle>\n            )}\n\n            { slots.default?.() }\n          </div>\n\n          { hasAppend && (\n            <div key=\"append\" class=\"v-card-item__append\">\n              { !slots.append ? (\n                <>\n                  { props.appendIcon && (\n                    <VIcon\n                      key=\"append-icon\"\n                      density={ props.density }\n                      icon={ props.appendIcon }\n                    />\n                  )}\n\n                  { props.appendAvatar && (\n                    <VAvatar\n                      key=\"append-avatar\"\n                      density={ props.density }\n                      image={ props.appendAvatar }\n                    />\n                  )}\n                </>\n              ) : (\n                <VDefaultsProvider\n                  key=\"append-defaults\"\n                  disabled={ !hasAppendMedia }\n                  defaults={{\n                    VAvatar: {\n                      density: props.density,\n                      image: props.appendAvatar,\n                    },\n                    VIcon: {\n                      density: props.density,\n                      icon: props.appendIcon,\n                    },\n                  }}\n                  v-slots:default={ slots.append }\n                />\n              )}\n           </div>\n          )}\n        </props.tag>\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VCardItem = InstanceType<typeof VCardItem>\n"
  },
  {
    "path": "packages/vuetify/src/components/VCard/VCardSubtitle.tsx",
    "content": "// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { makeTagProps } from '@/composables/tag'\n\n// Utilities\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\nexport const makeVCardSubtitleProps = propsFactory({\n  opacity: [Number, String],\n\n  ...makeComponentProps(),\n  ...makeTagProps(),\n}, 'VCardSubtitle')\n\nexport const VCardSubtitle = genericComponent()({\n  name: 'VCardSubtitle',\n\n  props: makeVCardSubtitleProps(),\n\n  setup (props, { slots }) {\n    useRender(() => (\n      <props.tag\n        class={[\n          'v-card-subtitle',\n          props.class,\n        ]}\n        style={[\n          { '--v-card-subtitle-opacity': props.opacity },\n          props.style,\n        ]}\n        v-slots={ slots }\n      />\n    ))\n\n    return {}\n  },\n})\n\nexport type VCardSubtitle = InstanceType<typeof VCardSubtitle>\n"
  },
  {
    "path": "packages/vuetify/src/components/VCard/VCardText.tsx",
    "content": "// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { makeTagProps } from '@/composables/tag'\n\n// Utilities\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\nexport const makeVCardTextProps = propsFactory({\n  opacity: [Number, String],\n\n  ...makeComponentProps(),\n  ...makeTagProps(),\n}, 'VCardText')\n\nexport const VCardText = genericComponent()({\n  name: 'VCardText',\n\n  props: makeVCardTextProps(),\n\n  setup (props, { slots }) {\n    useRender(() => (\n      <props.tag\n        class={[\n          'v-card-text',\n          props.class,\n        ]}\n        style={[\n          { '--v-card-text-opacity': props.opacity },\n          props.style,\n        ]}\n        v-slots={ slots }\n      />\n    ))\n\n    return {}\n  },\n})\n\nexport type VCardText = InstanceType<typeof VCardText>\n"
  },
  {
    "path": "packages/vuetify/src/components/VCard/VCardTitle.ts",
    "content": "// Utilities\nimport { createSimpleFunctional } from '@/util'\n\nexport const VCardTitle = createSimpleFunctional('v-card-title')\n\nexport type VCardTitle = InstanceType<typeof VCardTitle>\n"
  },
  {
    "path": "packages/vuetify/src/components/VCard/_mixins.scss",
    "content": "@mixin card-line-height-densities ($map) {\n  @each $density, $lineHeight in $map {\n    @if $density == null {\n      .v-card & {\n        line-height: $lineHeight;\n      }\n    } @else {\n      .v-card--density-#{$density} & {\n        line-height: $lineHeight;\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VCard/_variables.scss",
    "content": "@use 'sass:map';\n@use '../../styles/settings';\n@use '../../styles/tools';\n\n// VCard\n$card-append-padding-inline-start: .5rem !default;\n$card-background: rgb(var(--v-theme-surface)) !default;\n$card-border-color: settings.$border-color-root !default;\n$card-border-radius: settings.$border-radius-root !default;\n$card-border-style: settings.$border-style-root !default;\n$card-border-thin-width: thin !default;\n$card-border-width: 0 !default;\n$card-color: tools.theme-color('on-surface', var(--v-high-emphasis-opacity)) !default;\n$card-disabled-opacity: 0.6 !default;\n$card-elevation: 1 !default;\n$card-loader-top: 0 !default;\n$card-loader-bottom: auto !default;\n$card-hover-elevation: 3 !default;\n$card-img-flex: 1 1 auto !default;\n$card-item-align-items: center !default;\n$card-item-padding: .625rem 1rem !default;\n$card-overflow-wrap: break-word !default;\n$card-padding: 0 !default;\n$card-plain-opacity: .62 !default;\n$card-positions: absolute fixed !default;\n$card-prepend-padding-inline-end: .5rem !default;\n$card-transition-duration: 0.28s !default;\n$card-transition-property: box-shadow, opacity, background, --v-elevation-overlay !default;\n$card-transition-timing-function: settings.$standard-easing !default;\n\n// VCardActions\n$card-actions-flex: none !default;\n$card-actions-min-height: 52px !default;\n$card-actions-padding: .5rem !default;\n$button-card-actions-margin: .5rem !default; // deprecated\n$card-actions-gap: $button-card-actions-margin !default;\n\n// VCardHeader\n$card-header-flex: none !default;\n\n// VCardTitle\n$card-title-comfortable-line-height: 1.75rem !default;\n$card-title-compact-line-height: 1.55rem !default;\n$card-title-flex: none !default;\n$card-title-font-size: tools.map-deep-get(settings.$typography, 'title-large', 'size') !default;\n$card-title-font-weight: tools.map-deep-get(settings.$typography, 'title-large', 'weight') !default;\n$card-title-header-padding: 0 !default;\n$card-title-hyphens: auto !default;\n$card-title-letter-spacing: tools.map-deep-get(settings.$typography, 'title-large', 'letter-spacing') !default;\n$card-title-line-height: tools.map-deep-get(settings.$typography, 'title-large', 'line-height') !default;\n$card-title-overflow-wrap: normal !default;\n$card-title-overflow: hidden !default;\n$card-title-padding: .5rem 1rem !default;\n$card-title-text-overflow: ellipsis !default;\n$card-title-text-transform: none !default;\n$card-title-white-space: nowrap !default;\n$card-title-word-break: normal !default;\n$card-title-word-wrap: break-word !default;\n\n// VCardSubtitle\n$card-subtitle-color: tools.theme-color('on-surface', var(--v-medium-emphasis-opacity)) !default;\n$card-subtitle-comfortable-line-height: 1.125rem !default;\n$card-subtitle-compact-line-height: 1rem !default;\n$card-subtitle-flex: none !default;\n$card-subtitle-font-size: tools.map-deep-get(settings.$typography, 'body-medium', 'size') !default;\n$card-subtitle-font-weight: tools.map-deep-get(settings.$typography, 'body-medium', 'weight') !default;\n$card-subtitle-header-padding: 0 0 .25rem !default;\n$card-subtitle-letter-spacing: tools.map-deep-get(settings.$typography, 'body-medium', 'letter-spacing') !default;\n$card-subtitle-line-height: tools.map-deep-get(settings.$typography, 'body-medium', 'line-height') !default;\n$card-subtitle-opacity: var(--v-card-subtitle-opacity, var(--v-medium-emphasis-opacity)) !default;\n$card-subtitle-overflow: hidden !default;\n$card-subtitle-padding: 0 1rem !default;\n$card-subtitle-text-overflow: ellipsis !default;\n$card-subtitle-text-transform: none !default;\n$card-subtitle-white-space: nowrap !default;\n\n// VCardText\n$card-text-comfortable-line-height: 1.2rem !default;\n$card-text-compact-line-height: 1.15rem !default;\n$card-text-flex: 1 1 auto !default;\n$card-text-font-size: tools.map-deep-get(settings.$typography, 'body-medium', 'size') !default;\n$card-text-font-weight: tools.map-deep-get(settings.$typography, 'body-medium', 'weight') !default;\n$card-text-opacity: var(--v-card-text-opacity, 1) !default;\n$card-text-letter-spacing: tools.map-deep-get(settings.$typography, 'body-medium', 'letter-spacing') !default;\n$card-text-line-height: tools.map-deep-get(settings.$typography, 'body-medium', 'line-height') !default;\n$card-text-padding: 1rem !default;\n$card-text-text-transform: none !default;\n\n// Lists\n$card-border: (\n  $card-border-color,\n  $card-border-style,\n  $card-border-width,\n  $card-border-thin-width\n) !default;\n\n$card-title-densities: () !default;\n$card-title-densities: map.merge((\n  null: $card-title-line-height,\n  'comfortable': $card-title-comfortable-line-height,\n  'compact': $card-title-compact-line-height\n), $card-title-densities);\n\n$card-subtitle-density-line-height: () !default;\n$card-subtitle-density-line-height: map.merge((\n  null: $card-subtitle-line-height,\n  'comfortable': $card-subtitle-comfortable-line-height,\n  'compact': $card-subtitle-compact-line-height\n), $card-subtitle-density-line-height);\n\n$card-text-density-line-height: () !default;\n$card-text-density-line-height: map.merge((\n  null: $card-text-line-height,\n  'comfortable': $card-text-comfortable-line-height,\n  'compact': $card-text-compact-line-height\n), $card-text-density-line-height);\n\n$card-variants: (\n  $card-background,\n  $card-color,\n  $card-elevation,\n  $card-plain-opacity,\n  'v-card'\n) !default;\n\n// Deprecated\n$card-avatar-align-self: flex-start !default;\n$card-avatar-header-padding: 0 !default;\n$card-avatar-padding: .5rem 1rem !default;\n$card-title-padding-top: 1rem !default;\n$card-text-padding-bottom: 1rem !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VCard/index.ts",
    "content": "export { VCard } from './VCard'\nexport { VCardActions } from './VCardActions'\nexport { VCardItem } from './VCardItem'\nexport { VCardSubtitle } from './VCardSubtitle'\nexport { VCardText } from './VCardText'\nexport { VCardTitle } from './VCardTitle'\n"
  },
  {
    "path": "packages/vuetify/src/components/VCarousel/VCarousel.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-carousel\n    overflow: hidden\n    position: relative\n    width: 100%\n\n    &__controls\n      align-items: center\n      bottom: 0\n      display: flex\n      height: $carousel-controls-size\n      justify-content: center\n      list-style-type: none\n      position: absolute\n      width: 100%\n      z-index: 1\n\n      @include tools.theme($carousel-controls-theme...)\n\n      > .v-item-group\n        flex: 0 1 auto\n\n      &__item\n        margin: $carousel-dot-margin\n\n        .v-icon\n          opacity: $carousel-dot-inactive-opacity\n\n        &--active\n          .v-icon\n            opacity: $carousel-dot-active-opacity\n            vertical-align: middle\n\n        &:hover\n          background: none\n\n          .v-icon\n            opacity: $carousel-dot-hover-opacity\n\n  // Element\n  .v-carousel__progress\n    margin: 0\n    bottom: 0\n    left: 0\n    right: 0\n\n  .v-carousel-item\n    display: block\n    height: inherit\n    text-decoration: none\n\n    & > .v-img\n      height: inherit\n\n  // Modifier\n  .v-carousel--hide-delimiter-background\n    .v-carousel__controls\n      background: transparent\n\n  .v-carousel--vertical-delimiters\n    .v-carousel__controls\n      flex-direction: column\n      height: 100%\n      width: $carousel-controls-size\n"
  },
  {
    "path": "packages/vuetify/src/components/VCarousel/VCarousel.tsx",
    "content": "// Styles\nimport './VCarousel.sass'\n\n// Components\nimport { VBtn } from '@/components/VBtn'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\nimport { VProgressLinear } from '@/components/VProgressLinear'\nimport { makeVWindowProps, VWindow } from '@/components/VWindow/VWindow'\n\n// Composables\nimport { IconValue } from '@/composables/icons'\nimport { useLocale } from '@/composables/locale'\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { nextTick, onMounted, ref, watch } from 'vue'\nimport { convertToUnit, genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { VWindowSlots } from '@/components/VWindow/VWindow'\nimport type { GroupProvide } from '@/composables/group'\nimport type { GenericProps } from '@/util'\n\nexport const makeVCarouselProps = propsFactory({\n  color: String,\n  cycle: Boolean,\n  delimiterIcon: {\n    type: IconValue,\n    default: '$delimiter',\n  },\n  height: {\n    type: [Number, String],\n    default: 500,\n  },\n  hideDelimiters: Boolean,\n  hideDelimiterBackground: Boolean,\n  interval: {\n    type: [Number, String],\n    default: 6000,\n    validator: (value: string | number) => Number(value) > 0,\n  },\n  progress: [Boolean, String],\n  verticalDelimiters: [Boolean, String] as PropType<boolean | 'left' | 'right'>,\n\n  ...makeVWindowProps({\n    continuous: true,\n    mandatory: 'force' as const,\n    showArrows: true,\n  }),\n}, 'VCarousel')\n\ntype VCarouselSlots = Omit<VWindowSlots, 'additional'> & {\n  item: {\n    props: Record<string, any>\n    item: {\n      id: string\n      value: unknown\n      disabled: boolean | undefined\n    }\n  }\n}\n\nexport const VCarousel = genericComponent<new <T>(\n  props: {\n    modelValue?: T\n    'onUpdate:modelValue'?: (value: T) => void\n  },\n  slots: VCarouselSlots,\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VCarousel',\n\n  props: makeVCarouselProps(),\n\n  emits: {\n    'update:modelValue': (value: any) => true,\n  },\n\n  setup (props, { slots }) {\n    const model = useProxiedModel(props, 'modelValue')\n    const { t } = useLocale()\n    const windowRef = ref<VWindow>()\n\n    let slideTimeout = -1\n    watch(model, restartTimeout)\n    watch(() => props.interval, restartTimeout)\n    watch(() => props.cycle, val => {\n      if (val) restartTimeout()\n      else window.clearTimeout(slideTimeout)\n    })\n\n    onMounted(startTimeout)\n\n    function startTimeout () {\n      if (!props.cycle || !windowRef.value) return\n\n      slideTimeout = window.setTimeout(\n        windowRef.value.group.next,\n        Number(props.interval) > 0 ? Number(props.interval) : 6000\n      )\n    }\n\n    function restartTimeout () {\n      window.clearTimeout(slideTimeout)\n      window.requestAnimationFrame(startTimeout)\n    }\n\n    function onDelimiterKeyDown (e: KeyboardEvent, group: GroupProvide) {\n      if (\n        (props.direction === 'horizontal' && e.key === 'ArrowLeft') ||\n        (props.direction === 'vertical' && e.key === 'ArrowUp')\n      ) {\n        e.preventDefault()\n        group.prev()\n        nextTick(() => windowRef.value?.$el.querySelector('.v-btn--active')?.focus())\n      }\n\n      if (\n        (props.direction === 'horizontal' && e.key === 'ArrowRight') ||\n        (props.direction === 'vertical' && e.key === 'ArrowDown')\n      ) {\n        e.preventDefault()\n        group.next()\n        nextTick(() => windowRef.value?.$el.querySelector('.v-btn--active')?.focus())\n      }\n    }\n\n    useRender(() => {\n      const windowProps = VWindow.filterProps(props)\n\n      return (\n        <VWindow\n          ref={ windowRef }\n          { ...windowProps }\n          v-model={ model.value }\n          class={[\n            'v-carousel',\n            {\n              'v-carousel--hide-delimiter-background': props.hideDelimiterBackground,\n              'v-carousel--vertical-delimiters': props.verticalDelimiters,\n            },\n            props.class,\n          ]}\n          style={[\n            { height: convertToUnit(props.height) },\n            props.style,\n          ]}\n        >\n          {{\n            default: slots.default,\n            additional: ({ group }: { group: GroupProvide }) => (\n              <>\n                { !props.hideDelimiters && (\n                  <div\n                    class=\"v-carousel__controls\"\n                    style={{\n                      left: props.verticalDelimiters === 'left' && props.verticalDelimiters ? 0 : 'auto',\n                      right: props.verticalDelimiters === 'right' ? 0 : 'auto',\n                    }}\n                  >\n                    { group.items.value.length > 0 && (\n                      <VDefaultsProvider\n                        defaults={{\n                          VBtn: {\n                            color: props.color,\n                            icon: props.delimiterIcon,\n                            size: 'x-small',\n                            variant: 'text',\n                          },\n                        }}\n                        scoped\n                      >\n                        { group.items.value.map((item, index) => {\n                          const props = {\n                            id: `carousel-item-${item.id}`,\n                            'aria-label': t('$vuetify.carousel.ariaLabel.delimiter', index + 1, group.items.value.length),\n                            class: [\n                              'v-carousel__controls__item',\n                              group.isSelected(item.id) && 'v-btn--active',\n                            ],\n                            onClick: () => group.select(item.id, true),\n                            onKeydown: (e: KeyboardEvent) => onDelimiterKeyDown(e, group),\n                          }\n\n                          return slots.item\n                            ? slots.item({ props, item })\n                            : (<VBtn { ...item } { ...props } />)\n                        })}\n                      </VDefaultsProvider>\n                    )}\n                  </div>\n                )}\n\n                { props.progress && (\n                  <VProgressLinear\n                    absolute\n                    class=\"v-carousel__progress\"\n                    color={ typeof props.progress === 'string' ? props.progress : undefined }\n                    modelValue={ (group.getItemIndex(model.value) + 1) / group.items.value.length * 100 }\n                  />\n                )}\n              </>\n            ),\n            prev: slots.prev,\n            next: slots.next,\n          }}\n        </VWindow>\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VCarousel = InstanceType<typeof VCarousel>\n"
  },
  {
    "path": "packages/vuetify/src/components/VCarousel/VCarouselItem.tsx",
    "content": "// Components\nimport { makeVImgProps, VImg } from '@/components/VImg/VImg'\nimport { makeVWindowItemProps, VWindowItem } from '@/components/VWindow/VWindowItem'\n\n// Utilities\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { VImgSlots } from '@/components/VImg/VImg'\n\nexport const makeVCarouselItemProps = propsFactory({\n  ...makeVImgProps(),\n  ...makeVWindowItemProps(),\n}, 'VCarouselItem')\n\nexport const VCarouselItem = genericComponent<VImgSlots>()({\n  name: 'VCarouselItem',\n\n  inheritAttrs: false,\n\n  props: makeVCarouselItemProps(),\n\n  setup (props, { slots, attrs }) {\n    useRender(() => {\n      const imgProps = VImg.filterProps(props)\n      const windowItemProps = VWindowItem.filterProps(props)\n\n      return (\n        <VWindowItem\n          class={[\n            'v-carousel-item',\n            props.class,\n          ]}\n          { ...windowItemProps }\n        >\n          <VImg\n            { ...attrs }\n            { ...imgProps }\n            v-slots={ slots }\n          />\n        </VWindowItem>\n      )\n    })\n  },\n})\n\nexport type VCarouselItem = InstanceType<typeof VCarouselItem>\n"
  },
  {
    "path": "packages/vuetify/src/components/VCarousel/__tests__/VCarousel.spec.browser.tsx",
    "content": "// Components\nimport { VCarousel } from '../VCarousel'\nimport { VCarouselItem } from '../VCarouselItem'\n\n// Utilities\nimport { commands, render, screen, userEvent } from '@test'\nimport { ref } from 'vue'\n\ndescribe('VCarousel', () => {\n  describe('keyboard controls', () => {\n    it('should support horizontal keyboard navigation on delimiters', async () => {\n      const model = ref(1)\n\n      render(() => (\n        <VCarousel v-model={ model.value }>\n          <VCarouselItem value={ 1 }>\n            <h1>1</h1>\n          </VCarouselItem>\n          <VCarouselItem value={ 2 }>\n            <h1>2</h1>\n          </VCarouselItem>\n          <VCarouselItem value={ 3 }>\n            <h1>3</h1>\n          </VCarouselItem>\n        </VCarousel>\n      ))\n\n      await commands.waitStable('.v-carousel')\n      const delimiters = screen.getAllByCSS('.v-carousel__controls__item')\n      await delimiters[0].focus()\n\n      await userEvent.keyboard('{ArrowUp}')\n      expect(model.value).toBe(1)\n      await userEvent.keyboard('{ArrowRight}')\n      expect(model.value).toBe(2)\n      await userEvent.keyboard('{ArrowLeft}')\n      expect(model.value).toBe(1)\n      await userEvent.keyboard('{ArrowLeft}')\n      expect(model.value).toBe(3)\n      await userEvent.keyboard('{ArrowRight}')\n      expect(model.value).toBe(1)\n    })\n\n    it('should support vertical keyboard navigation on delimiters', async () => {\n      const model = ref(1)\n\n      render(() => (\n        <VCarousel v-model={ model.value } direction=\"vertical\">\n          <VCarouselItem value={ 1 }>\n            <h1>1</h1>\n          </VCarouselItem>\n          <VCarouselItem value={ 2 }>\n            <h1>2</h1>\n          </VCarouselItem>\n          <VCarouselItem value={ 3 }>\n            <h1>3</h1>\n          </VCarouselItem>\n        </VCarousel>\n      ))\n\n      await commands.waitStable('.v-carousel')\n      const delimiters = screen.getAllByCSS('.v-carousel__controls__item')\n      await delimiters[0].focus()\n\n      await userEvent.keyboard('{ArrowLeft}')\n      expect(model.value).toBe(1)\n      await userEvent.keyboard('{ArrowDown}')\n      expect(model.value).toBe(2)\n      await userEvent.keyboard('{ArrowUp}')\n      expect(model.value).toBe(1)\n      await userEvent.keyboard('{ArrowUp}')\n      expect(model.value).toBe(3)\n      await userEvent.keyboard('{ArrowDown}')\n      expect(model.value).toBe(1)\n    })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VCarousel/_variables.scss",
    "content": "@use '../../styles/tools';\n\n// VCarousel\n$carousel-controls-bg: tools.theme-color('surface-variant', .3) !default;\n$carousel-controls-color: rgb(var(--v-theme-on-surface-variant)) !default;\n$carousel-controls-size: 50px !default;\n$carousel-dot-margin: 0 8px !default;\n$carousel-dot-inactive-opacity: .5 !default;\n$carousel-dot-active-opacity: 1 !default;\n$carousel-dot-hover-opacity: .8 !default;\n\n$carousel-controls-theme: (\n  $carousel-controls-bg,\n  $carousel-controls-color\n) !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VCarousel/index.ts",
    "content": "export { VCarousel } from './VCarousel'\nexport { VCarouselItem } from './VCarouselItem'\n"
  },
  {
    "path": "packages/vuetify/src/components/VCheckbox/VCheckbox.sass",
    "content": "@use 'sass:map'\n@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-checkbox\n    &.v-input\n      flex: $checkbox-flex\n\n    .v-selection-control\n      min-height: var(--v-input-control-height)\n"
  },
  {
    "path": "packages/vuetify/src/components/VCheckbox/VCheckbox.tsx",
    "content": "// Styles\nimport './VCheckbox.sass'\n\n// Components\nimport { makeVCheckboxBtnProps, VCheckboxBtn } from './VCheckboxBtn'\nimport { makeVInputProps, VInput } from '@/components/VInput/VInput'\n\n// Composables\nimport { useFocus } from '@/composables/focus'\nimport { forwardRefs } from '@/composables/forwardRefs'\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { ref, useId } from 'vue'\nimport { filterInputAttrs, genericComponent, omit, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { VSelectionControlSlots } from '../VSelectionControl/VSelectionControl'\nimport type { VInputSlots } from '@/components/VInput/VInput'\nimport type { GenericProps } from '@/util'\n\nexport type VCheckboxSlots = Omit<VInputSlots, 'default'> & VSelectionControlSlots\n\nexport const makeVCheckboxProps = propsFactory({\n  ...omit(makeVInputProps(), ['direction']),\n  ...omit(makeVCheckboxBtnProps(), ['inline']),\n}, 'VCheckbox')\n\nexport const VCheckbox = genericComponent<new <T>(\n  props: {\n    modelValue?: T | null\n    'onUpdate:modelValue'?: (value: T | null) => void\n  },\n  slots: VCheckboxSlots,\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VCheckbox',\n\n  inheritAttrs: false,\n\n  props: makeVCheckboxProps(),\n\n  emits: {\n    'update:modelValue': (value: any) => true,\n    'update:focused': (focused: boolean) => true,\n  },\n\n  setup (props, { attrs, slots }) {\n    const model = useProxiedModel(props, 'modelValue')\n    const { isFocused, focus, blur } = useFocus(props)\n    const inputRef = ref<VInput>()\n\n    const uid = useId()\n\n    useRender(() => {\n      const [rootAttrs, controlAttrs] = filterInputAttrs(attrs)\n      const inputProps = VInput.filterProps(props)\n      const checkboxProps = VCheckboxBtn.filterProps(props)\n\n      return (\n        <VInput\n          ref={ inputRef }\n          class={[\n            'v-checkbox',\n            props.class,\n          ]}\n          { ...rootAttrs }\n          { ...inputProps }\n          v-model={ model.value }\n          id={ props.id || `checkbox-${uid}` }\n          focused={ isFocused.value }\n          style={ props.style }\n        >\n          {{\n            ...slots,\n            default: ({\n              id,\n              messagesId,\n              isDisabled,\n              isReadonly,\n              isValid,\n            }) => (\n              <VCheckboxBtn\n                { ...checkboxProps }\n                id={ id.value }\n                aria-describedby={ messagesId.value }\n                disabled={ isDisabled.value }\n                readonly={ isReadonly.value }\n                { ...controlAttrs }\n                error={ isValid.value === false }\n                v-model={ model.value }\n                onFocus={ focus }\n                onBlur={ blur }\n                v-slots={ slots }\n              />\n            ),\n          }}\n        </VInput>\n      )\n    })\n\n    return forwardRefs({}, inputRef)\n  },\n})\n\nexport type VCheckbox = InstanceType<typeof VCheckbox>\n"
  },
  {
    "path": "packages/vuetify/src/components/VCheckbox/VCheckboxBtn.tsx",
    "content": "// Components\nimport { makeVSelectionControlProps, VSelectionControl } from '@/components/VSelectionControl/VSelectionControl'\n\n// Composables\nimport { IconValue } from '@/composables/icons'\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { toRef } from 'vue'\nimport { genericComponent, omit, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { VSelectionControlSlots } from '@/components/VSelectionControl/VSelectionControl'\nimport type { GenericProps } from '@/util'\n\nexport const makeVCheckboxBtnProps = propsFactory({\n  indeterminate: Boolean,\n  indeterminateIcon: {\n    type: IconValue,\n    default: '$checkboxIndeterminate',\n  },\n\n  ...makeVSelectionControlProps({\n    falseIcon: '$checkboxOff',\n    trueIcon: '$checkboxOn',\n  }),\n}, 'VCheckboxBtn')\n\nexport const VCheckboxBtn = genericComponent<new <T>(\n  props: {\n    modelValue?: T\n    'onUpdate:modelValue'?: (value: T) => void\n  },\n  slots: VSelectionControlSlots,\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VCheckboxBtn',\n\n  props: makeVCheckboxBtnProps(),\n\n  emits: {\n    'update:modelValue': (value: any) => true,\n    'update:indeterminate': (value: boolean) => true,\n  },\n\n  setup (props, { slots }) {\n    const indeterminate = useProxiedModel(props, 'indeterminate')\n    const model = useProxiedModel(props, 'modelValue')\n\n    function onChange (v: any) {\n      if (indeterminate.value) {\n        indeterminate.value = false\n      }\n    }\n\n    const falseIcon = toRef(() => {\n      return indeterminate.value\n        ? props.indeterminateIcon\n        : props.falseIcon\n    })\n\n    const trueIcon = toRef(() => {\n      return indeterminate.value\n        ? props.indeterminateIcon\n        : props.trueIcon\n    })\n\n    useRender(() => {\n      const controlProps = omit(VSelectionControl.filterProps(props), ['modelValue'])\n      return (\n        <VSelectionControl\n          { ...controlProps }\n          v-model={ model.value }\n          class={[\n            'v-checkbox-btn',\n            props.class,\n          ]}\n          style={ props.style }\n          type=\"checkbox\"\n          onUpdate:modelValue={ onChange }\n          falseIcon={ falseIcon.value }\n          trueIcon={ trueIcon.value }\n          aria-checked={ indeterminate.value ? 'mixed' : undefined }\n          v-slots={ slots }\n        />\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VCheckboxBtn = InstanceType<typeof VCheckboxBtn>\n"
  },
  {
    "path": "packages/vuetify/src/components/VCheckbox/__tests__/VCheckbox.spec.tsx",
    "content": "import { VCheckbox } from '../VCheckbox'\n\n// Utilities\nimport { mount } from '@vue/test-utils'\nimport { createVuetify } from '@/framework'\n\ndescribe('VCheckbox', () => {\n  const vuetify = createVuetify()\n\n  function mountFunction (component: any, options = {}) {\n    return mount(component, {\n      global: {\n        plugins: [vuetify],\n      },\n      ...options,\n    })\n  }\n\n  describe('hide-details behavior', () => {\n    it('should not have aria-describedby when hide-details is true', () => {\n      const wrapper = mountFunction(\n        <VCheckbox hideDetails />\n      )\n\n      const input = wrapper.find('input')\n      expect(input.attributes('aria-describedby')).toBeUndefined()\n\n      // Should not have details section\n      const details = wrapper.find('.v-input__details')\n      expect(details.exists()).toBe(false)\n    })\n\n    it('should have aria-describedby when hide-details is false or undefined', () => {\n      const wrapper = mountFunction(\n        <VCheckbox id=\"input-1\" />\n      )\n\n      const input = wrapper.find('input')\n      expect(input.attributes('aria-describedby')).toBe('input-1-messages')\n\n      // Should have details section\n      const details = wrapper.find('.v-input__details')\n      expect(details.exists()).toBe(true)\n      expect(details.attributes('id')).toBe('input-1-messages')\n    })\n\n    it('should have aria-describedby when hide-details is \"auto\" and has messages', () => {\n      const wrapper = mountFunction(\n        <VCheckbox\n          id=\"input-2\"\n          messages={['Hello World!']}\n          hideDetails=\"auto\"\n        />\n      )\n\n      const input = wrapper.find('input')\n      expect(input.attributes('aria-describedby')).toBe('input-2-messages')\n\n      // Should have details section with messages\n      const details = wrapper.find('.v-input__details')\n      expect(details.exists()).toBe(true)\n      expect(details.attributes('id')).toBe('input-2-messages')\n\n      const messages = wrapper.find('.v-messages')\n      expect(messages.exists()).toBe(true)\n    })\n\n    it('should not have aria-describedby when hide-details is \"auto\" and no messages', () => {\n      const wrapper = mountFunction(\n        <VCheckbox\n          id=\"input-3\"\n          hideDetails=\"auto\"\n        />\n      )\n\n      const input = wrapper.find('input')\n      expect(input.attributes('aria-describedby')).toBeUndefined()\n\n      // Should not have details section\n      const details = wrapper.find('.v-input__details')\n      expect(details.exists()).toBe(false)\n    })\n\n    it('should have aria-describedby when hide-details is \"auto\" and has error messages', () => {\n      const wrapper = mountFunction(\n        <VCheckbox\n          id=\"input-4\"\n          errorMessages={['This field is required']}\n          hideDetails=\"auto\"\n        />\n      )\n\n      const input = wrapper.find('input')\n      expect(input.attributes('aria-describedby')).toBe('input-4-messages')\n\n      // Should have details section with error messages\n      const details = wrapper.find('.v-input__details')\n      expect(details.exists()).toBe(true)\n      expect(details.attributes('id')).toBe('input-4-messages')\n    })\n\n    it('should have aria-describedby when hide-details is \"auto\" and has details slot', () => {\n      const wrapper = mountFunction(\n        <VCheckbox\n          id=\"input-5\"\n          hideDetails=\"auto\"\n          v-slots={{\n            details: () => <div>Custom details</div>,\n          }}\n        />\n      )\n\n      const input = wrapper.find('input')\n      expect(input.attributes('aria-describedby')).toBe('input-5-messages')\n\n      // Should have details section with custom content\n      const details = wrapper.find('.v-input__details')\n      expect(details.exists()).toBe(true)\n      expect(details.attributes('id')).toBe('input-5-messages')\n      expect(details.text()).toContain('Custom details')\n    })\n\n    it('should handle persistent hint correctly', () => {\n      const wrapper = mountFunction(\n        <VCheckbox\n          id=\"input-8\"\n          hint=\"Persistent hint\"\n          persistentHint\n        />\n      )\n\n      const input = wrapper.find('input')\n      expect(input.attributes('aria-describedby')).toBe('input-8-messages')\n\n      const details = wrapper.find('.v-input__details')\n      expect(details.exists()).toBe(true)\n      expect(details.text()).toContain('Persistent hint')\n    })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VCheckbox/__tests__/VCheckboxBtn.spec.browser.tsx",
    "content": "import { VCheckboxBtn } from '../'\n\n// Utilities\nimport { render, screen, userEvent } from '@test'\nimport { ref } from 'vue'\n\ndescribe('VCheckboxBtn', () => {\n  it('should function without v-model', async () => {\n    render(() => (\n      <VCheckboxBtn />\n    ))\n\n    const input = screen.getByCSS('input')\n\n    await userEvent.click(input)\n    expect(input).toBeChecked()\n\n    await userEvent.click(input)\n    expect(input).not.toBeChecked()\n  })\n\n  it('should function with v-model', async () => {\n    const model = ref(false)\n    render(() => (\n      <VCheckboxBtn v-model={ model.value } />\n    ))\n\n    const input = screen.getByCSS('input')\n\n    await userEvent.click(input)\n    expect(input).toBeChecked()\n    expect(model.value).toBe(true)\n\n    await userEvent.click(input)\n    expect(input).not.toBeChecked()\n    expect(model.value).toBe(false)\n  })\n\n  it('should display indeterminate status', async () => {\n    render(() => (\n      <VCheckboxBtn modelValue={ false } indeterminate />\n    ))\n\n    const input = screen.getByCSS('input')\n    expect(input).toBePartiallyChecked()\n  })\n\n  it('should not update input checked state when it is readonly', async () => {\n    const model = ref(false)\n    render(() => (\n      <VCheckboxBtn v-model={ model.value } readonly />\n    ))\n\n    const input = screen.getByCSS('input')\n\n    await userEvent.click(input!)\n    expect(input).not.toBeChecked()\n    expect(model.value).toBe(false)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VCheckbox/_variables.scss",
    "content": "@use '../../styles/settings';\n@use '../../styles/tools';\n\n$checkbox-flex: 0 1 auto !default;\n$checkbox-disabled-color: tools.theme-color('on-surface', var(--v-disabled-opacity)) !default;\n$checkbox-error-color: rgb(var(--v-theme-error)) !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VCheckbox/index.ts",
    "content": "export { VCheckbox } from './VCheckbox'\nexport { VCheckboxBtn } from './VCheckboxBtn'\n"
  },
  {
    "path": "packages/vuetify/src/components/VChip/VChip.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n@use './mixins' as *\n\n@include tools.layer('components')\n  .v-chip\n    align-items: center\n    display: inline-flex\n    font-weight: $chip-font-weight\n    max-width: $chip-max-width\n    min-width: 0\n    overflow: hidden\n    position: relative\n    text-decoration: none\n    white-space: $chip-white-space\n    vertical-align: middle\n\n    .v-icon\n      --v-icon-size-multiplier: #{$chip-icon-size-multiplier}\n\n    @at-root\n      @include chip-sizes()\n      @include chip-density('height', $chip-density)\n\n    @include tools.border($chip-border...)\n    @include tools.states('.v-chip__overlay')\n    @include tools.rounded($chip-border-radius)\n    @include tools.variant($chip-variants...)\n\n    &--border\n      border-width: $chip-border-thin-width\n\n    &--link\n      cursor: pointer\n\n    &--link,\n    &--filter\n      user-select: none\n\n    &--label\n      @include tools.rounded($chip-label-border-radius)\n\n  // Elements\n  .v-chip__content\n    align-items: center\n    display: inline-flex\n\n    .v-autocomplete__selection &,\n    .v-combobox__selection &,\n    .v-select__selection &\n      overflow: hidden\n\n  .v-chip__filter,\n  .v-chip__prepend,\n  .v-chip__append,\n  .v-chip__close\n    align-items: center\n    display: inline-flex\n\n  .v-chip__close\n    padding: 0\n    margin: 0\n    font: inherit\n    overflow: visible\n    text-transform: none\n    background-color: transparent\n    border-style: none\n    color: inherit\n    cursor: pointer\n    flex: 0 1 auto\n    font-size: $chip-close-size\n    max-height: $chip-close-size\n    max-width: $chip-close-size\n    user-select: none\n\n    .v-icon\n      font-size: inherit\n\n  .v-chip__filter\n    transition: $chip-filter-transition\n\n  .v-chip__overlay\n    background-color: currentColor\n    border-radius: inherit\n    pointer-events: none\n    opacity: 0\n    transition: opacity .2s ease-in-out\n    @include tools.absolute()\n\n  .v-chip--disabled\n    opacity: $chip-disabled-opacity\n    pointer-events: none\n    user-select: none\n\n  .v-chip--label\n    border-radius: $chip-label-border-radius\n\n  @media (forced-colors: active)\n    .v-chip\n      &:not(&--variant-text, &--variant-plain)\n        border: thin solid\n"
  },
  {
    "path": "packages/vuetify/src/components/VChip/VChip.tsx",
    "content": "/* eslint-disable complexity */\n// Styles\nimport './VChip.sass'\n\n// Components\nimport { VExpandXTransition } from '@/components/transitions'\nimport { VAvatar } from '@/components/VAvatar'\nimport { VChipGroupSymbol } from '@/components/VChipGroup/VChipGroup'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\nimport { VIcon } from '@/components/VIcon'\nimport { VSlideGroupSymbol } from '@/components/VSlideGroup/VSlideGroup'\n\n// Composables\nimport { makeBorderProps, useBorder } from '@/composables/border'\nimport { makeComponentProps } from '@/composables/component'\nimport { makeDensityProps, useDensity } from '@/composables/density'\nimport { makeElevationProps, useElevation } from '@/composables/elevation'\nimport { makeGroupItemProps, useGroupItem } from '@/composables/group'\nimport { IconValue } from '@/composables/icons'\nimport { useLocale } from '@/composables/locale'\nimport { useProxiedModel } from '@/composables/proxiedModel'\nimport { makeRoundedProps, useRounded } from '@/composables/rounded'\nimport { makeRouterProps, useLink } from '@/composables/router'\nimport { makeSizeProps, useSize } from '@/composables/size'\nimport { makeTagProps } from '@/composables/tag'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\nimport { genOverlays, makeVariantProps, useVariant } from '@/composables/variant'\n\n// Directives\nimport vRipple from '@/directives/ripple'\n\n// Utilities\nimport { computed, toDisplayString, toRef, watch } from 'vue'\nimport { EventProp, genericComponent, propsFactory } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { RippleDirectiveBinding } from '@/directives/ripple'\n\nexport type VChipSlots = {\n  default: {\n    isSelected: boolean | undefined\n    selectedClass: boolean | (string | undefined)[] | undefined\n    select: ((value: boolean) => void) | undefined\n    toggle: (() => void) | undefined\n    value: unknown\n    disabled: boolean\n  }\n  label: never\n  prepend: never\n  append: never\n  close: never\n  filter: never\n}\n\nexport const makeVChipProps = propsFactory({\n  activeClass: String,\n  appendAvatar: String,\n  appendIcon: IconValue,\n  baseColor: String,\n  closable: Boolean,\n  closeIcon: {\n    type: IconValue,\n    default: '$delete',\n  },\n  closeLabel: {\n    type: String,\n    default: '$vuetify.close',\n  },\n  draggable: Boolean,\n  filter: Boolean,\n  filterIcon: {\n    type: IconValue,\n    default: '$complete',\n  },\n  label: Boolean,\n  link: {\n    type: Boolean,\n    default: undefined,\n  },\n  pill: Boolean,\n  prependAvatar: String,\n  prependIcon: IconValue,\n  ripple: {\n    type: [Boolean, Object] as PropType<RippleDirectiveBinding['value']>,\n    default: true,\n  },\n  text: {\n    type: [String, Number, Boolean],\n    default: undefined,\n  },\n  modelValue: {\n    type: Boolean,\n    default: true,\n  },\n\n  onClick: EventProp<[MouseEvent]>(),\n  onClickOnce: EventProp<[MouseEvent]>(),\n\n  ...makeBorderProps(),\n  ...makeComponentProps(),\n  ...makeDensityProps(),\n  ...makeElevationProps(),\n  ...makeGroupItemProps(),\n  ...makeRoundedProps(),\n  ...makeRouterProps(),\n  ...makeSizeProps(),\n  ...makeTagProps({ tag: 'span' }),\n  ...makeThemeProps(),\n  ...makeVariantProps({ variant: 'tonal' } as const),\n}, 'VChip')\n\nexport const VChip = genericComponent<VChipSlots>()({\n  name: 'VChip',\n\n  directives: { vRipple },\n\n  props: makeVChipProps(),\n\n  emits: {\n    'click:close': (e: MouseEvent) => true,\n    'update:modelValue': (value: boolean) => true,\n    'group:selected': (val: { value: boolean }) => true,\n    click: (e: MouseEvent | KeyboardEvent) => true,\n  },\n\n  setup (props, { attrs, emit, slots }) {\n    const { t } = useLocale()\n    const { borderClasses } = useBorder(props)\n    const { densityClasses } = useDensity(props)\n    const { elevationClasses } = useElevation(props)\n    const { roundedClasses } = useRounded(props)\n    const { sizeClasses } = useSize(props)\n    const { themeClasses } = provideTheme(props)\n\n    const isActive = useProxiedModel(props, 'modelValue')\n\n    const group = useGroupItem(props, VChipGroupSymbol, false)\n    const slideGroup = useGroupItem(props, VSlideGroupSymbol, false)\n\n    const link = useLink(props, attrs)\n    const isLink = toRef(() => props.link !== false && link.isLink.value)\n    const isClickable = computed(() =>\n      !props.disabled &&\n      props.link !== false &&\n      (!!group || props.link || link.isClickable.value)\n    )\n    const closeProps = toRef(() => ({\n      'aria-label': t(props.closeLabel),\n      disabled: props.disabled,\n      onClick (e: MouseEvent) {\n        e.preventDefault()\n        e.stopPropagation()\n\n        isActive.value = false\n\n        emit('click:close', e)\n      },\n    }))\n\n    watch(isActive, val => {\n      if (val) {\n        group?.register()\n        slideGroup?.register()\n      } else {\n        group?.unregister()\n        slideGroup?.unregister()\n      }\n    })\n\n    const { colorClasses, colorStyles, variantClasses } = useVariant(() => {\n      const showColor = !group || group.isSelected.value\n      return ({\n        color: showColor ? props.color ?? props.baseColor : props.baseColor,\n        variant: props.variant,\n      })\n    })\n\n    function onClick (e: MouseEvent) {\n      emit('click', e)\n\n      if (!isClickable.value) return\n\n      link.navigate.value?.(e)\n      group?.toggle()\n    }\n\n    function onKeyDown (e: KeyboardEvent) {\n      if (e.key === 'Enter' || e.key === ' ') {\n        e.preventDefault()\n        onClick(e as any as MouseEvent)\n      }\n    }\n\n    return () => {\n      const Tag = (link.isLink.value) ? 'a' : props.tag\n      const hasAppendMedia = !!(props.appendIcon || props.appendAvatar)\n      const hasAppend = !!(hasAppendMedia || slots.append)\n      const hasClose = !!(slots.close || props.closable)\n      const hasFilter = !!(slots.filter || props.filter) && group\n      const hasPrependMedia = !!(props.prependIcon || props.prependAvatar)\n      const hasPrepend = !!(hasPrependMedia || slots.prepend)\n\n      return isActive.value && (\n        <Tag\n          { ...link.linkProps }\n          class={[\n            'v-chip',\n            {\n              'v-chip--disabled': props.disabled,\n              'v-chip--label': props.label,\n              'v-chip--link': isClickable.value,\n              'v-chip--filter': hasFilter,\n              'v-chip--pill': props.pill,\n              [`${props.activeClass}`]: props.activeClass && link.isActive?.value,\n            },\n            themeClasses.value,\n            borderClasses.value,\n            colorClasses.value,\n            densityClasses.value,\n            elevationClasses.value,\n            roundedClasses.value,\n            sizeClasses.value,\n            variantClasses.value,\n            group?.selectedClass.value,\n            props.class,\n          ]}\n          style={[\n            colorStyles.value,\n            props.style,\n          ]}\n          disabled={ props.disabled || undefined }\n          draggable={ props.draggable }\n          tabindex={ isClickable.value ? 0 : undefined }\n          onClick={ onClick }\n          onKeydown={ isClickable.value && !isLink.value && onKeyDown }\n          v-ripple={[isClickable.value && props.ripple, null]}\n        >\n          { genOverlays(isClickable.value, 'v-chip') }\n\n          { hasFilter && (\n            <VExpandXTransition key=\"filter\">\n              <div\n                class=\"v-chip__filter\"\n                v-show={ group.isSelected.value }\n              >\n                { !slots.filter ? (\n                  <VIcon\n                    key=\"filter-icon\"\n                    icon={ props.filterIcon }\n                  />\n                ) : (\n                  <VDefaultsProvider\n                    key=\"filter-defaults\"\n                    disabled={ !props.filterIcon }\n                    defaults={{\n                      VIcon: { icon: props.filterIcon },\n                    }}\n                    v-slots:default={ slots.filter }\n                  />\n                )}\n              </div>\n            </VExpandXTransition>\n          )}\n\n          { hasPrepend && (\n            <div key=\"prepend\" class=\"v-chip__prepend\">\n              { !slots.prepend ? (\n                <>\n                  { props.prependIcon && (\n                    <VIcon\n                      key=\"prepend-icon\"\n                      icon={ props.prependIcon }\n                      start\n                    />\n                  )}\n\n                  { props.prependAvatar && (\n                    <VAvatar\n                      key=\"prepend-avatar\"\n                      image={ props.prependAvatar }\n                      start\n                    />\n                  )}\n                </>\n              ) : (\n                <VDefaultsProvider\n                  key=\"prepend-defaults\"\n                  disabled={ !hasPrependMedia }\n                  defaults={{\n                    VAvatar: {\n                      image: props.prependAvatar,\n                      start: true,\n                    },\n                    VIcon: {\n                      icon: props.prependIcon,\n                      start: true,\n                    },\n                  }}\n                  v-slots:default={ slots.prepend }\n                />\n              )}\n            </div>\n          )}\n\n          <div class=\"v-chip__content\" data-no-activator=\"\">\n            { slots.default?.({\n              isSelected: group?.isSelected.value,\n              selectedClass: group?.selectedClass.value,\n              select: group?.select,\n              toggle: group?.toggle,\n              value: group?.value.value,\n              disabled: props.disabled,\n            }) ?? toDisplayString(props.text)}\n          </div>\n\n          { hasAppend && (\n            <div key=\"append\" class=\"v-chip__append\">\n              { !slots.append ? (\n                <>\n                  { props.appendIcon && (\n                    <VIcon\n                      key=\"append-icon\"\n                      end\n                      icon={ props.appendIcon }\n                    />\n                  )}\n\n                  { props.appendAvatar && (\n                    <VAvatar\n                      key=\"append-avatar\"\n                      end\n                      image={ props.appendAvatar }\n                    />\n                  )}\n                </>\n              ) : (\n                <VDefaultsProvider\n                  key=\"append-defaults\"\n                  disabled={ !hasAppendMedia }\n                  defaults={{\n                    VAvatar: {\n                      end: true,\n                      image: props.appendAvatar,\n                    },\n                    VIcon: {\n                      end: true,\n                      icon: props.appendIcon,\n                    },\n                  }}\n                  v-slots:default={ slots.append }\n                />\n              )}\n            </div>\n          )}\n\n          { hasClose && (\n            <button\n              key=\"close\"\n              class=\"v-chip__close\"\n              type=\"button\"\n              data-testid=\"close-chip\"\n              { ...closeProps.value }\n            >\n              { !slots.close ? (\n                <VIcon\n                  key=\"close-icon\"\n                  icon={ props.closeIcon }\n                  size=\"x-small\"\n                />\n              ) : (\n                <VDefaultsProvider\n                  key=\"close-defaults\"\n                  defaults={{\n                    VIcon: {\n                      icon: props.closeIcon,\n                      size: 'x-small',\n                    },\n                  }}\n                  v-slots:default={ slots.close }\n                />\n              )}\n            </button>\n          )}\n        </Tag>\n      )\n    }\n  },\n})\n\nexport type VChip = InstanceType<typeof VChip>\n"
  },
  {
    "path": "packages/vuetify/src/components/VChip/__tests__/VChip.spec.browser.tsx",
    "content": "import { VChip } from '../VChip'\n\n// Utilities\nimport { render, screen, userEvent } from '@test'\nimport { nextTick, shallowRef } from 'vue'\n\ndescribe('VChip', () => {\n  it('should emit events when closed', async () => {\n    const close = vi.fn()\n    const update = vi.fn()\n\n    render(() => (\n      <VChip\n        closable\n        onUpdate:modelValue={ update }\n        onClick:close={ close }\n        text=\"Chip\"\n      />\n    ))\n\n    await userEvent.click(screen.getByTestId('close-chip'))\n    expect(close).toHaveBeenCalledTimes(1)\n    expect(update).toHaveBeenCalledTimes(1)\n  })\n\n  it('should have aria-label', async () => {\n    const closeLabel = shallowRef<string | undefined>('Foo')\n\n    render(() => (\n      <VChip\n        closable\n        closeLabel={ closeLabel.value }\n        text=\"Chip\"\n      />\n    ))\n\n    const button = screen.getByTestId('close-chip')\n\n    expect(button).toHaveAttribute('aria-label', 'Foo')\n\n    closeLabel.value = 'Bar'\n    await nextTick()\n    expect(button).toHaveAttribute('aria-label', 'Bar')\n\n    closeLabel.value = undefined\n    await nextTick()\n    expect(button).toHaveAttribute('aria-label', 'Close')\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VChip/_mixins.scss",
    "content": "@use 'sass:map';\n@use 'sass:math';\n@use 'sass:meta';\n@use 'sass:selector';\n@use '../../styles/settings';\n@use './variables' as *;\n\n@mixin chip-sizes {\n  @each $sizeName, $multiplier in settings.$size-scales {\n    $size: map.get($chip-sizes, \"font-size\") + math.div(2 * $multiplier, 16);\n    $height: map.get($chip-sizes, \"height\") + (6 * $multiplier);\n    $padding: math.round(math.div($height, $chip-padding-ratio));\n\n    .v-chip.v-chip--size-#{$sizeName} {\n      --v-chip-size: #{$size};\n      --v-chip-height: #{$height};\n      font-size: $size;\n      padding: 0 $padding;\n\n      .v-avatar {\n        --v-avatar-height: #{$height - 6};\n\n        @at-root #{selector.append('.v-chip--pill', &)} {\n          --v-avatar-height: #{$height};\n        }\n      }\n\n      .v-avatar--start {\n        margin-inline-start: -$padding * .7;\n        margin-inline-end: $padding * .5;\n\n        @at-root #{selector.append('.v-chip--pill', &)} {\n          margin-inline-start: -$padding;\n        }\n      }\n\n      .v-avatar--end {\n        margin-inline-start: $padding * .5;\n        margin-inline-end: -$padding * .7;\n\n        @at-root #{selector.append('.v-chip--pill', &)} {\n          margin-inline-end: -$padding;\n        }\n\n        + .v-chip__close {\n          @at-root #{selector.append('.v-chip--pill', &)} {\n            margin-inline-start: $padding * 1.5;\n          }\n        }\n      }\n\n      .v-icon--start,\n      .v-chip__filter {\n        margin-inline-start: -$padding * .5;\n        margin-inline-end: $padding * .5;\n      }\n\n      .v-icon--end,\n      .v-chip__close {\n        margin-inline-start: $padding * .5;\n        margin-inline-end: -$padding * .5;\n      }\n\n      .v-icon--end,\n      .v-avatar--end,\n      .v-chip__append {\n        + .v-chip__close {\n          margin-inline-start: $padding;\n        }\n      }\n    }\n  }\n}\n\n@mixin chip-density($properties, $densities) {\n  @each $density, $multiplier in $densities {\n    $value: calc(var(--v-chip-height) + #{$multiplier * settings.$spacer});\n\n    &.v-chip--density-#{$density} {\n      @if meta.type-of($properties) == \"list\" {\n        @each $property in $properties {\n          #{$property}: $value;\n        }\n      } @else {\n        #{$properties}: $value;\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VChip/_variables.scss",
    "content": "@use 'sass:math';\n@use 'sass:map';\n@use '../../styles/settings';\n@use '../../styles/tools';\n\n// Defaults\n$chip-background: rgb(var(--v-theme-surface-variant)) !default;\n$chip-border-color: settings.$border-color-root !default;\n$chip-border-radius: map.get(settings.$rounded, \"pill\") !default;\n$chip-border-style: settings.$border-style-root !default;\n$chip-border-thin-width: thin !default;\n$chip-border-width: 0 !default;\n$chip-close-size: 18px !default;\n$chip-color: rgb(var(--v-theme-on-surface-variant)) !default;\n$chip-density: (\"default\": 0, \"comfortable\": -1, \"compact\": -2) !default;\n$chip-disabled-opacity: 0.3 !default;\n$chip-elevation: 1 !default;\n$chip-font-size: tools.map-deep-get(settings.$typography, \"label-large\", \"size\") !default;\n$chip-font-weight: 400 !default;\n$chip-height: 32px !default;\n$chip-icon-size-multiplier: calc(18/21) !default;\n$chip-label-border-radius: settings.$border-radius-root !default;\n$chip-max-width: 100% !default;\n$chip-overflow: hidden !default;\n$chip-padding-ratio: 2 + math.div(2, 3) !default;\n$chip-plain-opacity: .62 !default;\n$chip-filter-transition: .15s settings.$standard-easing !default;\n$chip-white-space: nowrap !default;\n\n$chip-sizes: (\n  \"height\": $chip-height,\n  \"font-size\": $chip-font-size,\n) !default;\n\n$chip-border: (\n  $chip-border-color,\n  $chip-border-style,\n  $chip-border-width\n) !default;\n\n$chip-variants: (\n  $chip-background,\n  $chip-color,\n  $chip-elevation,\n  $chip-plain-opacity,\n  'v-chip'\n) !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VChip/index.ts",
    "content": "export { VChip } from './VChip'\n"
  },
  {
    "path": "packages/vuetify/src/components/VChipGroup/VChipGroup.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  // Block\n  .v-chip-group\n    display: flex\n    max-width: 100%\n    min-width: 0\n    overflow-x: auto\n    padding: $chip-group-padding\n\n    .v-chip\n      margin: $chip-group-margin\n\n      @include tools.layer('trumps')\n        @media (forced-colors: active)\n          background-color: buttonface\n          color: buttontext\n\n          &:hover\n            color: highlight\n\n      &.v-chip--selected:not(.v-chip--disabled)\n        .v-chip__overlay\n          opacity: $chip-group-selected-opacity\n\n        @include tools.layer('trumps')\n          @media (forced-colors: active)\n            color: highlight\n            forced-color-adjust: preserve-parent-color\n\n            &:focus-visible\n              outline-offset: 2px\n\n            &.v-chip--variant-elevated,\n            &.v-chip--variant-flat\n              background-color: highlight\n              color: highlighttext\n\n            &.v-chip--variant-outlined,\n            &.v-chip--variant-tonal\n              border-width: medium\n\n  // Modifiers\n  .v-chip-group--column\n    .v-slide-group__content\n      white-space: normal\n      flex-wrap: wrap\n      max-width: 100%\n"
  },
  {
    "path": "packages/vuetify/src/components/VChipGroup/VChipGroup.tsx",
    "content": "// Styles\nimport './VChipGroup.sass'\n\n// Components\nimport { makeVSlideGroupProps, VSlideGroup } from '@/components/VSlideGroup/VSlideGroup'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { provideDefaults } from '@/composables/defaults'\nimport { makeGroupProps, useGroup } from '@/composables/group'\nimport { makeTagProps } from '@/composables/tag'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\nimport { makeVariantProps } from '@/composables/variant'\n\n// Utilities\nimport { toRef } from 'vue'\nimport { deepEqual, genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { GenericProps, ValueComparator } from '@/util'\n\nexport const VChipGroupSymbol = Symbol.for('vuetify:v-chip-group')\n\nexport const makeVChipGroupProps = propsFactory({\n  baseColor: String,\n  column: Boolean,\n  filter: Boolean,\n  valueComparator: {\n    type: Function as PropType<ValueComparator>,\n    default: deepEqual,\n  },\n\n  ...makeVSlideGroupProps({ scrollToActive: false }),\n  ...makeComponentProps(),\n  ...makeGroupProps({ selectedClass: 'v-chip--selected' }),\n  ...makeTagProps(),\n  ...makeThemeProps(),\n  ...makeVariantProps({ variant: 'tonal' } as const),\n}, 'VChipGroup')\n\ntype VChipGroupSlots = {\n  default: {\n    isSelected: (id: string) => boolean\n    select: (id: string, value: boolean) => void\n    next: () => void\n    prev: () => void\n    selected: readonly string[]\n  }\n}\n\nexport const VChipGroup = genericComponent<new <T>(\n  props: {\n    modelValue?: T\n    'onUpdate:modelValue'?: (value: T) => void\n  },\n  slots: VChipGroupSlots,\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VChipGroup',\n\n  props: makeVChipGroupProps(),\n\n  emits: {\n    'update:modelValue': (value: any) => true,\n  },\n\n  setup (props, { slots }) {\n    const { themeClasses } = provideTheme(props)\n    const { isSelected, select, next, prev, selected } = useGroup(props, VChipGroupSymbol)\n\n    provideDefaults({\n      VChip: {\n        baseColor: toRef(() => props.baseColor),\n        color: toRef(() => props.color),\n        disabled: toRef(() => props.disabled),\n        filter: toRef(() => props.filter),\n        variant: toRef(() => props.variant),\n      },\n    })\n\n    useRender(() => {\n      const slideGroupProps = VSlideGroup.filterProps(props)\n\n      return (\n        <VSlideGroup\n          { ...slideGroupProps }\n          class={[\n            'v-chip-group',\n            {\n              'v-chip-group--column': props.column,\n            },\n            themeClasses.value,\n            props.class,\n          ]}\n          style={ props.style }\n        >\n          { slots.default?.({\n            isSelected,\n            select,\n            next,\n            prev,\n            selected: selected.value,\n          })}\n        </VSlideGroup>\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VChipGroup = InstanceType<typeof VChipGroup>\n"
  },
  {
    "path": "packages/vuetify/src/components/VChipGroup/_variables.scss",
    "content": "// VChipGroup\n$chip-group-selected-opacity: var(--v-activated-opacity) !default;\n$chip-group-padding: 4px 0 !default;\n$chip-group-margin: 4px 8px 4px 0 !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VChipGroup/index.ts",
    "content": "export { VChipGroup } from './VChipGroup'\n"
  },
  {
    "path": "packages/vuetify/src/components/VCode/VCode.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-code\n    background-color: $code-background-color\n    color: $code-color\n    border-radius: $code-border-radius\n    line-height: $code-line-height\n    font-size: $code-font-size\n    font-weight: $code-font-weight\n    padding: $code-padding\n\n    &:has(> pre)\n      display: inline-block\n"
  },
  {
    "path": "packages/vuetify/src/components/VCode/_variables.scss",
    "content": "$code-background-color: rgb(var(--v-theme-code)) !default;\n$code-color: rgb(var(--v-theme-on-code)) !default;\n$code-border-radius: 4px !default;\n$code-line-height: 1.8 !default;\n$code-font-size: 0.9em !default;\n$code-font-weight: normal !default;\n$code-padding: .2em .4em !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VCode/index.ts",
    "content": "// Styles\nimport './VCode.sass'\n\n// Utilities\nimport { createSimpleFunctional } from '@/util'\n\nexport const VCode = createSimpleFunctional('v-code', 'code')\n\nexport type VCode = InstanceType<typeof VCode>\n"
  },
  {
    "path": "packages/vuetify/src/components/VColorPicker/VColorPicker.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  // Block\n  .v-color-picker\n    align-self: flex-start\n    contain: content\n    width: $color-picker-width\n\n    &.v-sheet.v-picker\n      @include tools.elevation($color-picker-elevation)\n      @include tools.rounded($color-picker-border-radius)\n\n  // Element\n  .v-color-picker__controls\n    display: flex\n    flex-direction: column\n    padding: $color-picker-controls-padding\n    width: 100%\n\n  // Modifier\n  .v-color-picker--flat\n    @include tools.elevation(0)\n\n    .v-color-picker__track:not(.v-input--is-disabled) .v-slider__thumb // High specificity\n      @include tools.elevation(0)\n"
  },
  {
    "path": "packages/vuetify/src/components/VColorPicker/VColorPicker.tsx",
    "content": "// Styles\nimport './VColorPicker.sass'\n\n// Components\nimport { VColorPickerCanvas } from './VColorPickerCanvas'\nimport { VColorPickerEdit } from './VColorPickerEdit'\nimport { makeVColorPickerPreviewProps, VColorPickerPreview } from './VColorPickerPreview'\nimport { VColorPickerSwatches } from './VColorPickerSwatches'\nimport { makeVPickerProps, VPicker } from '@/labs/VPicker/VPicker'\n\n// Composables\nimport { useRtl } from '@/composables'\nimport { provideDefaults } from '@/composables/defaults'\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { computed, onBeforeMount, ref, watch } from 'vue'\nimport { extractColor, modes, nullColor } from './util'\nimport { consoleWarn, defineComponent, HSVtoCSS, parseColor, pick, propsFactory, RGBtoHSV, useRender } from '@/util'\n\n// Types\nimport type { DeepReadonly, PropType } from 'vue'\nimport type { Color, HSV } from '@/util'\n\nexport const makeVColorPickerProps = propsFactory({\n  canvasHeight: {\n    type: [String, Number],\n    default: 150,\n  },\n  disabled: Boolean,\n  dotSize: {\n    type: [Number, String],\n    default: 10,\n  },\n  hideCanvas: Boolean,\n  hideSliders: Boolean,\n  hideInputs: Boolean,\n  mode: {\n    type: String as PropType<keyof typeof modes>,\n    default: 'rgba',\n    validator: (v: string) => Object.keys(modes).includes(v),\n  },\n  modes: {\n    type: Array as PropType<readonly (keyof typeof modes)[]>,\n    default: () => Object.keys(modes),\n    validator: (v: any) => Array.isArray(v) && v.every(m => Object.keys(modes).includes(m)),\n  },\n  showSwatches: Boolean,\n  readonly: Boolean,\n  swatches: Array as PropType<DeepReadonly<Color[][]>>,\n  swatchesMaxHeight: {\n    type: [Number, String],\n    default: 150,\n  },\n  modelValue: {\n    type: [Object, String] as PropType<Record<string, unknown> | string | undefined | null>,\n  },\n\n  ...makeVPickerProps({ hideHeader: true }),\n  ...pick(makeVColorPickerPreviewProps(), ['hideEyeDropper', 'eyeDropperIcon']),\n}, 'VColorPicker')\n\nexport const VColorPicker = defineComponent({\n  name: 'VColorPicker',\n\n  props: makeVColorPickerProps(),\n\n  emits: {\n    'update:modelValue': (color: any) => true,\n    'update:mode': (mode: keyof typeof modes) => true,\n  },\n\n  setup (props, { slots }) {\n    const mode = useProxiedModel(props, 'mode')\n    const hue = ref<number | null>(null)\n    const model = useProxiedModel(\n      props,\n      'modelValue',\n      undefined,\n      v => {\n        if (v == null || v === '') return null\n\n        let c: HSV\n        try {\n          c = RGBtoHSV(parseColor(v as any))\n        } catch (err) {\n          consoleWarn(err as any)\n          return null\n        }\n\n        return c\n      },\n      v => {\n        if (!v) return null\n\n        return extractColor(v, props.modelValue)\n      }\n    )\n    const currentColor = computed(() => {\n      return model.value\n        ? { ...model.value, h: hue.value ?? model.value.h }\n        : null\n    })\n    const { rtlClasses } = useRtl()\n\n    let externalChange = true\n    watch(model, v => {\n      if (!externalChange) {\n        // prevent hue shift from rgb conversion inaccuracy\n        externalChange = true\n        return\n      }\n      if (!v) return\n      hue.value = v.h\n    }, { immediate: true })\n\n    const updateColor = (hsva: HSV) => {\n      externalChange = false\n      hue.value = hsva.h\n      model.value = hsva\n    }\n\n    onBeforeMount(() => {\n      if (!props.modes.includes(mode.value)) mode.value = props.modes[0]\n    })\n\n    provideDefaults({\n      VSlider: {\n        color: null,\n        trackColor: null,\n        trackFillColor: null,\n      },\n    })\n\n    useRender(() => {\n      const pickerProps = VPicker.filterProps(props)\n\n      return (\n        <VPicker\n          { ...pickerProps }\n          class={[\n            'v-color-picker',\n            rtlClasses.value,\n            props.class,\n          ]}\n          style={[\n            {\n              '--v-color-picker-color-hsv': HSVtoCSS({ ...(currentColor.value ?? nullColor), a: 1 }),\n            },\n            props.style,\n          ]}\n          v-slots={{\n            ...slots,\n            default: () => (\n              <>\n                { !props.hideCanvas && (\n                  <VColorPickerCanvas\n                    key=\"canvas\"\n                    color={ currentColor.value }\n                    onUpdate:color={ updateColor }\n                    disabled={ props.disabled }\n                    readonly={ props.readonly }\n                    dotSize={ props.dotSize }\n                    width={ props.width }\n                    height={ props.canvasHeight }\n                  />\n                )}\n\n                { (!props.hideSliders || !props.hideInputs) && (\n                  <div key=\"controls\" class=\"v-color-picker__controls\">\n                    { !props.hideSliders && (\n                      <VColorPickerPreview\n                        key=\"preview\"\n                        color={ currentColor.value }\n                        onUpdate:color={ updateColor }\n                        hideAlpha={ !mode.value.endsWith('a') }\n                        disabled={ props.disabled }\n                        readonly={ props.readonly }\n                        hideEyeDropper={ props.hideEyeDropper }\n                        eyeDropperIcon={ props.eyeDropperIcon }\n                      />\n                    )}\n\n                    { !props.hideInputs && (\n                      <VColorPickerEdit\n                        key=\"edit\"\n                        modes={ props.modes }\n                        mode={ mode.value }\n                        onUpdate:mode={ m => mode.value = m }\n                        color={ currentColor.value }\n                        onUpdate:color={ updateColor }\n                        disabled={ props.disabled }\n                        readonly={ props.readonly }\n                      />\n                    )}\n                  </div>\n                )}\n\n                { props.showSwatches && (\n                  <VColorPickerSwatches\n                    key=\"swatches\"\n                    color={ currentColor.value }\n                    onUpdate:color={ updateColor }\n                    maxHeight={ props.swatchesMaxHeight }\n                    swatches={ props.swatches }\n                    disabled={ props.disabled }\n                    readonly={ props.readonly }\n                  />\n                )}\n              </>\n            ),\n          }}\n        />\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VColorPicker = InstanceType<typeof VColorPicker>\n"
  },
  {
    "path": "packages/vuetify/src/components/VColorPicker/VColorPickerCanvas.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-color-picker-canvas\n    $root: &\n    display: flex\n    position: relative\n    overflow: hidden\n    contain: content\n    touch-action: none\n    width: 100%\n\n    &__dot\n      position: absolute\n      top: 0\n      left: 0\n      width: $color-picker-canvas-dot-size\n      height: $color-picker-canvas-dot-size\n      background: transparent\n      border-radius: 50%\n      box-shadow: $color-picker-canvas-dot-box-shadow\n      \n      @media (forced-colors: active)\n        border-style: solid\n        outline: 2px solid highlight\n\n      &--disabled\n        box-shadow: $color-picker-canvas-dot-disabled-box-shadow\n\n      #{$root}:hover &\n        will-change: transform\n"
  },
  {
    "path": "packages/vuetify/src/components/VColorPicker/VColorPickerCanvas.tsx",
    "content": "// Styles\nimport './VColorPickerCanvas.sass'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { useResizeObserver } from '@/composables/resizeObserver'\n\n// Utilities\nimport { computed, onMounted, ref, shallowRef, toRef, watch } from 'vue'\nimport { clamp, convertToUnit, defineComponent, getEventCoordinates, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { HSV } from '@/util'\n\nexport const makeVColorPickerCanvasProps = propsFactory({\n  color: {\n    type: Object as PropType<HSV | null>,\n  },\n  disabled: Boolean,\n  readonly: Boolean,\n  dotSize: {\n    type: [Number, String],\n    default: 10,\n  },\n  height: {\n    type: [Number, String],\n    default: 150,\n  },\n  width: {\n    type: [Number, String],\n    default: 300,\n  },\n\n  ...makeComponentProps(),\n}, 'VColorPickerCanvas')\n\nexport const VColorPickerCanvas = defineComponent({\n  name: 'VColorPickerCanvas',\n\n  props: makeVColorPickerCanvasProps(),\n\n  emits: {\n    'update:color': (color: HSV) => true,\n    'update:position': (hue: any) => true,\n  },\n\n  setup (props, { emit }) {\n    const isInteracting = shallowRef(false)\n    const canvasRef = ref<HTMLCanvasElement | null>()\n    const canvasWidth = shallowRef(parseFloat(props.width))\n    const canvasHeight = shallowRef(parseFloat(props.height))\n\n    const _dotPosition = ref({ x: 0, y: 0 })\n    const isInteractive = toRef(() => !props.disabled && !props.readonly)\n\n    const dotPosition = computed({\n      get: () => _dotPosition.value,\n      set (val) {\n        if (!canvasRef.value) return\n\n        const { x, y } = val\n        _dotPosition.value = val\n\n        emit('update:color', {\n          h: props.color?.h ?? 0,\n          s: clamp(x, 0, canvasWidth.value) / canvasWidth.value,\n          v: 1 - clamp(y, 0, canvasHeight.value) / canvasHeight.value,\n          a: props.color?.a ?? 1,\n        })\n      },\n    })\n\n    const dotStyles = computed(() => {\n      const { x, y } = dotPosition.value\n      const radius = parseInt(props.dotSize, 10) / 2\n\n      return {\n        width: convertToUnit(props.dotSize),\n        height: convertToUnit(props.dotSize),\n        transform: `translate(${convertToUnit(x - radius)}, ${convertToUnit(y - radius)})`,\n      }\n    })\n\n    const { resizeRef } = useResizeObserver(entries => {\n      if (!resizeRef.el?.offsetParent) return\n\n      const { width, height } = entries[0].contentRect\n\n      canvasWidth.value = Math.round(width)\n      canvasHeight.value = Math.round(height)\n    })\n\n    function updateDotPosition (x: number, y: number, rect: DOMRect) {\n      const { left, top, width, height } = rect\n      dotPosition.value = {\n        x: clamp(x - left, 0, width),\n        y: clamp(y - top, 0, height),\n      }\n    }\n\n    function handleMouseDown (e: MouseEvent | TouchEvent) {\n      if (e.type === 'mousedown') {\n        // Prevent text selection while dragging\n        e.preventDefault()\n      }\n\n      if (!isInteractive.value) return\n\n      handleMouseMove(e)\n\n      window.addEventListener('mousemove', handleMouseMove)\n      window.addEventListener('mouseup', handleMouseUp)\n      window.addEventListener('touchmove', handleMouseMove)\n      window.addEventListener('touchend', handleMouseUp)\n    }\n\n    function handleMouseMove (e: MouseEvent | TouchEvent) {\n      if (!isInteractive.value || !canvasRef.value) return\n\n      isInteracting.value = true\n\n      const coords = getEventCoordinates(e)\n\n      updateDotPosition(coords.clientX, coords.clientY, canvasRef.value.getBoundingClientRect())\n    }\n\n    function handleMouseUp () {\n      window.removeEventListener('mousemove', handleMouseMove)\n      window.removeEventListener('mouseup', handleMouseUp)\n      window.removeEventListener('touchmove', handleMouseMove)\n      window.removeEventListener('touchend', handleMouseUp)\n    }\n\n    function updateCanvas () {\n      if (!canvasRef.value) return\n\n      const canvas = canvasRef.value\n      const ctx = canvas.getContext('2d')\n\n      if (!ctx) return\n\n      const saturationGradient = ctx.createLinearGradient(0, 0, canvas.width, 0)\n      saturationGradient.addColorStop(0, 'hsla(0, 0%, 100%, 1)') // white\n      saturationGradient.addColorStop(1, `hsla(${props.color?.h ?? 0}, 100%, 50%, 1)`)\n      ctx.fillStyle = saturationGradient\n      ctx.fillRect(0, 0, canvas.width, canvas.height)\n\n      const valueGradient = ctx.createLinearGradient(0, 0, 0, canvas.height)\n      valueGradient.addColorStop(0, 'hsla(0, 0%, 0%, 0)') // transparent\n      valueGradient.addColorStop(1, 'hsla(0, 0%, 0%, 1)') // black\n      ctx.fillStyle = valueGradient\n      ctx.fillRect(0, 0, canvas.width, canvas.height)\n    }\n\n    watch(() => props.color?.h, updateCanvas, { immediate: true })\n    watch(() => [canvasWidth.value, canvasHeight.value], (newVal, oldVal) => {\n      updateCanvas()\n      _dotPosition.value = {\n        x: dotPosition.value.x * newVal[0] / oldVal[0],\n        y: dotPosition.value.y * newVal[1] / oldVal[1],\n      }\n    }, { flush: 'post' })\n\n    watch(() => props.color, () => {\n      if (isInteracting.value) {\n        isInteracting.value = false\n        return\n      }\n\n      _dotPosition.value = props.color ? {\n        x: props.color.s * canvasWidth.value,\n        y: (1 - props.color.v) * canvasHeight.value,\n      } : { x: 0, y: 0 }\n    }, { deep: true, immediate: true })\n\n    onMounted(() => updateCanvas())\n\n    useRender(() => (\n      <div\n        ref={ resizeRef }\n        class={[\n          'v-color-picker-canvas',\n          props.class,\n        ]}\n        style={ props.style }\n        onMousedown={ handleMouseDown }\n        onTouchstartPassive={ handleMouseDown }\n      >\n        <canvas\n          ref={ canvasRef }\n          width={ canvasWidth.value }\n          height={ canvasHeight.value }\n        />\n        { props.color && (\n          <div\n            class={[\n              'v-color-picker-canvas__dot',\n              {\n                'v-color-picker-canvas__dot--disabled': props.disabled,\n              },\n            ]}\n            style={ dotStyles.value }\n          />\n        )}\n      </div>\n    ))\n\n    return {}\n  },\n})\n\nexport type VColorPickerCanvas = InstanceType<typeof VColorPickerCanvas>\n"
  },
  {
    "path": "packages/vuetify/src/components/VColorPicker/VColorPickerEdit.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-color-picker-edit\n    display: flex\n    margin-top: $color-picker-input-margin-top\n\n  .v-color-picker-edit__input\n    width: 100%\n    display: flex\n    flex-wrap: wrap\n    justify-content: center\n    text-align: center\n\n    > input::-webkit-outer-spin-button,\n    > input::-webkit-inner-spin-button\n      -webkit-appearance: none\n      margin: 0\n\n    &:not(:last-child)\n      margin-inline-end: $color-picker-input-margin\n\n    input\n      padding: 0\n      font: inherit\n      border-style: none\n      border-radius: $color-picker-border-radius\n      margin: 0 0 $color-picker-input-margin-bottom\n      min-width: 0\n      outline: none\n      text-align: center\n      width: 100%\n      height: $color-picker-input-height\n      background: tools.theme-color('surface-variant', .2)\n      color: rgba(var(--v-theme-on-surface))\n      -moz-appearance: textfield\n\n      @media (forced-colors: active)\n        border-style: solid\n\n    span\n      font-size: $color-picker-input-font-size\n"
  },
  {
    "path": "packages/vuetify/src/components/VColorPicker/VColorPickerEdit.tsx",
    "content": "// Styles\nimport './VColorPickerEdit.sass'\n\n// Components\nimport { VBtn } from '@/components/VBtn'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { useLocale } from '@/composables/locale'\n\n// Utilities\nimport { computed } from 'vue'\nimport { modes, nullColor } from './util'\nimport { defineComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { HSV } from '@/util/colorUtils'\n\nconst VColorPickerInput = ({ label, ...rest }: any) => {\n  return (\n    <div\n      class=\"v-color-picker-edit__input\"\n    >\n      <input { ...rest } />\n      <span>{ label }</span>\n    </div>\n  )\n}\n\nexport const makeVColorPickerEditProps = propsFactory({\n  color: Object as PropType<HSV | null>,\n  disabled: Boolean,\n  readonly: Boolean,\n  mode: {\n    type: String as PropType<keyof typeof modes>,\n    default: 'rgba',\n    validator: (v: string) => Object.keys(modes).includes(v),\n  },\n  modes: {\n    type: Array as PropType<readonly (keyof typeof modes)[]>,\n    default: () => Object.keys(modes),\n    validator: (v: any) => Array.isArray(v) && v.every(m => Object.keys(modes).includes(m)),\n  },\n\n  ...makeComponentProps(),\n}, 'VColorPickerEdit')\n\nexport const VColorPickerEdit = defineComponent({\n  name: 'VColorPickerEdit',\n\n  props: makeVColorPickerEditProps(),\n\n  emits: {\n    'update:color': (color: HSV) => true,\n    'update:mode': (mode: keyof typeof modes) => true,\n  },\n\n  setup (props, { emit }) {\n    const { t } = useLocale()\n    const enabledModes = computed(() => {\n      return props.modes.map(key => ({ ...modes[key], name: key }))\n    })\n\n    const inputs = computed(() => {\n      const mode = enabledModes.value.find(m => m.name === props.mode)\n\n      if (!mode) return []\n\n      const color = props.color ? mode.to(props.color) : null\n\n      return mode.inputs?.map(({ getValue, getColor, localeKey, ...inputProps }) => {\n        return {\n          ...mode.inputProps,\n          ...inputProps,\n          ariaLabel: t(`$vuetify.colorPicker.ariaLabel.${localeKey}`),\n          disabled: props.disabled,\n          readonly: props.readonly,\n          value: color && getValue(color),\n          onChange: (e: InputEvent) => {\n            const target = e.target as HTMLInputElement | null\n\n            if (!target) return\n\n            emit('update:color', mode.from(getColor(color ?? mode.to(nullColor), target.value)))\n          },\n        }\n      })\n    })\n\n    useRender(() => (\n      <div\n        class={[\n          'v-color-picker-edit',\n          props.class,\n        ]}\n        style={ props.style }\n      >\n        { inputs.value?.map(props => (\n          <VColorPickerInput { ...props } />\n        ))}\n        { enabledModes.value.length > 1 && (\n          <VBtn\n            icon=\"$unfold\"\n            size=\"x-small\"\n            variant=\"plain\"\n            aria-label={ t('$vuetify.colorPicker.ariaLabel.changeFormat') }\n            onClick={ () => {\n              const mi = enabledModes.value.findIndex(m => m.name === props.mode)\n\n              emit('update:mode', enabledModes.value[(mi + 1) % enabledModes.value.length].name)\n            }}\n          />\n        )}\n      </div>\n    ))\n\n    return {}\n  },\n})\n\nexport type VColorPickerEdit = InstanceType<typeof VColorPickerEdit>\n"
  },
  {
    "path": "packages/vuetify/src/components/VColorPicker/VColorPickerPreview.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-color-picker-preview__alpha\n    .v-slider-track__background\n      @include tools.layer('overrides')\n        background-color: transparent\n\n      @include tools.ltr()\n        background-image: linear-gradient(to right, transparent, var(--v-color-picker-color-hsv))\n      @include tools.rtl()\n        background-image: linear-gradient(to left, transparent, var(--v-color-picker-color-hsv))\n\n      &::after\n        content: ''\n        z-index: -1\n        left: 0\n        top: 0\n        width: 100%\n        height: 100%\n        position: absolute\n        background: $color-picker-checkerboard\n        border-radius: inherit\n\n  .v-color-picker-preview__sliders\n    display: flex\n    flex: 1 0 auto\n    flex-direction: column\n    padding-inline-end: $color-picker-preview-sliders-padding\n\n  .v-color-picker-preview__dot\n    position: relative\n    height: $color-picker-preview-dot-size\n    width: $color-picker-preview-dot-size\n    background: $color-picker-checkerboard\n    border-radius: 50%\n    overflow: hidden\n    margin-inline-end: $color-picker-preview-dot-margin\n\n    > div\n      width: 100%\n      height: 100%\n\n  .v-color-picker-preview__hue\n    &:not(.v-input--is-disabled)\n      .v-slider-track__background\n        @include tools.ltr()\n          background: linear-gradient(to right, #F00 0%, #FF0 16.66%, #0F0 33.33%, #0FF 50%, #00F 66.66%, #F0F 83.33%, #F00 100%)\n\n        @include tools.rtl()\n          background: linear-gradient(to left, #F00 0%, #FF0 16.66%, #0F0 33.33%, #0FF 50%, #00F 66.66%, #F0F 83.33%, #F00 100%)\n\n  .v-color-picker-preview__track\n    position: relative\n    width: 100%\n\n    @include tools.layer('overrides')\n      margin: 0\n\n    .v-slider-track__fill\n      display: none\n\n  .v-color-picker-preview\n    align-items: center\n    display: flex\n    margin-bottom: $color-picker-preview-margin-bottom\n\n  .v-color-picker-preview__eye-dropper\n    position: relative\n    margin-right: $color-picker-preview-dropper-margin\n\n  @media (forced-colors: active)\n    .v-color-picker-preview\n\n      &__dot\n        border-style: solid\n        \n        > div\n          forced-color-adjust: preserve-parent-color\n      \n      &__sliders\n        forced-color-adjust: preserve-parent-color\n\n      .v-slider-thumb__surface\n        background: transparent\n        border: solid canvastext\n"
  },
  {
    "path": "packages/vuetify/src/components/VColorPicker/VColorPickerPreview.tsx",
    "content": "// Styles\nimport './VColorPickerPreview.sass'\n\n// Components\nimport { VBtn } from '@/components/VBtn'\nimport { VSlider } from '@/components/VSlider'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { IconValue } from '@/composables/icons'\nimport { useLocale } from '@/composables/locale'\n\n// Utilities\nimport { onUnmounted, toRef } from 'vue'\nimport { nullColor } from './util'\nimport {\n  defineComponent,\n  HSVtoCSS,\n  parseColor,\n  propsFactory,\n  RGBtoHSV,\n  SUPPORTS_EYE_DROPPER,\n  useRender,\n} from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { HSV } from '@/util'\n\nexport const makeVColorPickerPreviewProps = propsFactory({\n  color: {\n    type: Object as PropType<HSV | null>,\n  },\n  disabled: Boolean,\n  readonly: Boolean,\n  hideAlpha: Boolean,\n  hideEyeDropper: Boolean,\n  eyeDropperIcon: {\n    type: IconValue,\n    default: '$eyeDropper',\n  },\n\n  ...makeComponentProps(),\n}, 'VColorPickerPreview')\n\nexport const VColorPickerPreview = defineComponent({\n  name: 'VColorPickerPreview',\n\n  props: makeVColorPickerPreviewProps(),\n\n  emits: {\n    'update:color': (color: HSV) => true,\n  },\n\n  setup (props, { emit }) {\n    const { t } = useLocale()\n\n    const abortController = new AbortController()\n\n    const isInteractive = toRef(() => !props.disabled && !props.readonly)\n\n    onUnmounted(() => abortController.abort())\n\n    async function openEyeDropper () {\n      if (!SUPPORTS_EYE_DROPPER || !isInteractive.value) return\n\n      const eyeDropper = new window.EyeDropper()\n      try {\n        const result = await eyeDropper.open({ signal: abortController.signal })\n        const colorHexValue = RGBtoHSV(parseColor(result.sRGBHex))\n        emit('update:color', { ...(props.color ?? nullColor), ...colorHexValue })\n      } catch (e) {}\n    }\n\n    useRender(() => (\n      <div\n        class={[\n          'v-color-picker-preview',\n          {\n            'v-color-picker-preview--hide-alpha': props.hideAlpha,\n          },\n          props.class,\n        ]}\n        style={ props.style }\n      >\n        { SUPPORTS_EYE_DROPPER && !props.hideEyeDropper && (\n          <div class=\"v-color-picker-preview__eye-dropper\" key=\"eyeDropper\">\n            <VBtn\n              aria-label={ t('$vuetify.colorPicker.ariaLabel.eyedropper') }\n              density=\"comfortable\"\n              disabled={ props.disabled }\n              readonly={ props.readonly }\n              icon={ props.eyeDropperIcon }\n              variant=\"plain\"\n              onClick={ openEyeDropper }\n            />\n          </div>\n        )}\n\n        <div class=\"v-color-picker-preview__dot\">\n          <div style={{ background: HSVtoCSS(props.color ?? nullColor) }} />\n        </div>\n\n        <div class=\"v-color-picker-preview__sliders\">\n          <VSlider\n            class=\"v-color-picker-preview__track v-color-picker-preview__hue\"\n            aria-label={ t('$vuetify.colorPicker.ariaLabel.hueSlider') }\n            modelValue={ props.color?.h }\n            onUpdate:modelValue={ h => emit('update:color', { ...(props.color ?? nullColor), h }) }\n            step={ 1 }\n            min={ 0 }\n            max={ 360 }\n            disabled={ props.disabled }\n            readonly={ props.readonly }\n            thumbSize={ 14 }\n            trackSize={ 8 }\n            trackFillColor=\"white\"\n            hideDetails\n          />\n\n          { !props.hideAlpha && (\n            <VSlider\n              class=\"v-color-picker-preview__track v-color-picker-preview__alpha\"\n              aria-label={ t('$vuetify.colorPicker.ariaLabel.alphaSlider') }\n              modelValue={ props.color?.a ?? 1 }\n              onUpdate:modelValue={ a => emit('update:color', { ...(props.color ?? nullColor), a }) }\n              step={ 0.01 }\n              min={ 0 }\n              max={ 1 }\n              disabled={ props.disabled }\n              readonly={ props.readonly }\n              thumbSize={ 14 }\n              trackSize={ 8 }\n              trackFillColor=\"white\"\n              hideDetails\n            />\n          )}\n        </div>\n      </div>\n    ))\n\n    return {}\n  },\n})\n\nexport type VColorPickerPreview = InstanceType<typeof VColorPickerPreview>\n"
  },
  {
    "path": "packages/vuetify/src/components/VColorPicker/VColorPickerSwatches.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-color-picker-swatches\n    overflow-y: auto\n\n    > div\n      display: flex\n      flex-wrap: wrap\n      justify-content: center\n      padding: $color-picker-swatches-border-radius\n\n  .v-color-picker-swatches__swatch\n    display: flex\n    flex-direction: column\n    margin-bottom: $color-picker-swatch-margin-bottom\n\n  .v-color-picker-swatches__color\n    position: relative\n    height: $color-picker-swatch-color-height\n    max-height: $color-picker-swatch-color-height\n    width: $color-picker-swatch-color-width\n    margin: $color-picker-swatch-color-margin\n    border-radius: $color-picker-swatch-color-border-radius\n    user-select: none\n    overflow: hidden\n    background: $color-picker-checkerboard\n    cursor: pointer\n\n    &--disabled\n      opacity: var(--v-disabled-opacity)\n      pointer-events: none\n\n    > div\n      display: flex\n      align-items: center\n      justify-content: center\n      width: 100%\n      height: 100%\n\n  @media (forced-colors: active)\n    .v-color-picker-swatches > div\n      forced-color-adjust: preserve-parent-color\n"
  },
  {
    "path": "packages/vuetify/src/components/VColorPicker/VColorPickerSwatches.tsx",
    "content": "// Styles\nimport './VColorPickerSwatches.sass'\n\n// Components\nimport { VIcon } from '@/components/VIcon'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\n\n// Utilities\nimport { toRef } from 'vue'\nimport {\n  convertToUnit,\n  deepEqual,\n  defineComponent,\n  getContrast,\n  parseColor,\n  propsFactory,\n  RGBtoCSS,\n  RGBtoHSV,\n  useRender,\n} from '@/util'\nimport colors from '@/util/colors'\n\n// Types\nimport type { DeepReadonly, PropType } from 'vue'\nimport type { Color, HSV } from '@/util'\n\nexport const makeVColorPickerSwatchesProps = propsFactory({\n  swatches: {\n    type: Array as PropType<DeepReadonly<Color[][]>>,\n    default: () => parseDefaultColors(colors),\n  },\n  disabled: Boolean,\n  readonly: Boolean,\n  color: Object as PropType<HSV | null>,\n  maxHeight: [Number, String],\n\n  ...makeComponentProps(),\n}, 'VColorPickerSwatches')\n\nfunction parseDefaultColors (colors: Record<string, Record<string, string>>) {\n  return Object.keys(colors).map(key => {\n    const color = colors[key]\n    return color.base ? [\n      color.base,\n      color.darken4,\n      color.darken3,\n      color.darken2,\n      color.darken1,\n      color.lighten1,\n      color.lighten2,\n      color.lighten3,\n      color.lighten4,\n      color.lighten5,\n    ] : [\n      color.black,\n      color.white,\n      color.transparent,\n    ]\n  })\n}\n\nexport const VColorPickerSwatches = defineComponent({\n  name: 'VColorPickerSwatches',\n\n  props: makeVColorPickerSwatchesProps(),\n\n  emits: {\n    'update:color': (color: HSV) => true,\n  },\n\n  setup (props, { emit }) {\n    const isInteractive = toRef(() => !props.disabled && !props.readonly)\n\n    function onSwatchClick (hsva: HSV) {\n      if (!isInteractive.value || !hsva) {\n        return\n      }\n\n      emit('update:color', hsva)\n    }\n\n    useRender(() => (\n      <div\n        class={[\n          'v-color-picker-swatches',\n          props.class,\n        ]}\n        style={[\n          { maxHeight: convertToUnit(props.maxHeight) },\n          props.style,\n        ]}\n      >\n        <div>\n          { props.swatches.map(swatch => (\n            <div class=\"v-color-picker-swatches__swatch\">\n              { swatch.map(color => {\n                const rgba = parseColor(color)\n                const hsva = RGBtoHSV(rgba)\n                const background = RGBtoCSS(rgba)\n\n                return (\n                  <div\n                    class={[\n                      'v-color-picker-swatches__color',\n                      {\n                        'v-color-picker-swatches__color--disabled': props.disabled,\n                      },\n                    ]}\n                    onClick={ () => onSwatchClick(hsva) }\n                  >\n                    <div style={{ background }}>\n                      { props.color && deepEqual(props.color, hsva)\n                        ? <VIcon size=\"x-small\" icon=\"$success\" color={ getContrast(color, '#FFFFFF') > 2 ? 'white' : 'black' } />\n                        : undefined\n                      }\n                    </div>\n                  </div>\n                )\n              })}\n            </div>\n          ))}\n        </div>\n      </div>\n    ))\n\n    return {}\n  },\n})\n\nexport type VColorPickerSwatches = InstanceType<typeof VColorPickerSwatches>\n"
  },
  {
    "path": "packages/vuetify/src/components/VColorPicker/__tests__/VColorPicker.spec.browser.tsx",
    "content": "import { VColorPicker } from '../VColorPicker'\n\n// Utilities\nimport { render, screen, showcase, userEvent } from '@test'\nimport { within } from '@testing-library/vue'\n\nconst stories = {\n  'Without canvas': <VColorPicker hideCanvas />,\n  'Without inputs': <VColorPicker hideInputs />,\n  'Without sliders': <VColorPicker hideSliders />,\n  Swatches: <VColorPicker showSwatches />,\n  'Without eyedropper': <VColorPicker hideEyeDropper />,\n}\n\ndescribe('VColorPicker', () => {\n  it('should default to emitting hex value if no value is provided', async () => {\n    const update = vi.fn()\n    render(() => (\n      <VColorPicker onUpdate:modelValue={ update } />\n    ))\n\n    const canvas = screen.getByCSS('canvas')\n    await userEvent.click(canvas)\n    expect(update).toHaveBeenCalledTimes(1)\n    expect(update).toHaveBeenCalledWith(expect.stringMatching(/^#[A-F0-9]{6}$/))\n  })\n\n  it('should emit hexa value if hexa value is provided', async () => {\n    const update = vi.fn()\n    render(() => (\n      <VColorPicker modelValue=\"#ff00ff00\" onUpdate:modelValue={ update } />\n    ))\n\n    const canvas = screen.getByCSS('canvas')\n    await userEvent.click(canvas)\n    expect(update).toHaveBeenCalledTimes(1)\n    expect(update).toHaveBeenCalledWith(expect.stringMatching(/^#[A-F0-9]{8}$/))\n  })\n\n  it('should emit hex value if hex value is provided', async () => {\n    const update = vi.fn()\n    render(() => (\n      <VColorPicker modelValue=\"#ff00ff\" onUpdate:modelValue={ update } />\n    ))\n\n    const canvas = screen.getByCSS('canvas')\n    await userEvent.click(canvas)\n    expect(update).toHaveBeenCalledTimes(1)\n    expect(update).toHaveBeenCalledWith(expect.stringMatching(/^#[A-F0-9]{6}$/))\n  })\n\n  it('should emit hsla value if hsla value is provided', async () => {\n    const update = vi.fn()\n    render(() => (\n      <VColorPicker modelValue={{ h: 100, s: 0, l: 1, a: 1 }} onUpdate:modelValue={ update } />\n    ))\n\n    const canvas = screen.getByCSS('canvas')\n    await userEvent.click(canvas)\n    expect(update).toHaveBeenCalledTimes(1)\n    expect(update).toHaveBeenCalledWith(expect.objectContaining({\n      h: expect.any(Number),\n      s: expect.any(Number),\n      l: expect.any(Number),\n      a: expect.any(Number),\n    }))\n  })\n\n  it('should emit rgba value if rgba value is provided', async () => {\n    const update = vi.fn()\n    render(() => (\n      <VColorPicker modelValue={{ r: 100, g: 20, b: 100, a: 1 }} onUpdate:modelValue={ update } />\n    ))\n\n    const canvas = screen.getByCSS('canvas')\n    await userEvent.click(canvas)\n    expect(update).toHaveBeenCalledTimes(1)\n    expect(update).toHaveBeenCalledWith(expect.objectContaining({\n      r: expect.any(Number),\n      g: expect.any(Number),\n      b: expect.any(Number),\n      a: expect.any(Number),\n    }))\n  })\n\n  it('should hide mode switch if only one mode is enabled', () => {\n    render(() => (\n      <VColorPicker modes={['rgba']} />\n    ))\n    expect(screen.queryByCSS('.v-color-picker-edit > .v-btn')).toBeNull()\n  })\n\n  it('should hide alpha slider if mode does not include alpha', () => {\n    render(() => (\n      <VColorPicker modes={['rgb']} modelValue=\"#ff00ff\" />\n    ))\n    expect(screen.queryByCSS('.v-color-picker-preview__alpha')).toBeNull()\n  })\n\n  it('should emit value when changing hue slider', async () => {\n    const update = vi.fn()\n    render(() => (\n      <VColorPicker modelValue=\"#0000ff\" onUpdate:modelValue={ update } />\n    ))\n\n    await userEvent.click(screen.getByCSS('.v-color-picker-preview__hue'))\n    expect(update).toHaveBeenCalledTimes(1)\n    expect(update).not.toHaveBeenCalledWith('#0000ff')\n  })\n\n  it('should emit value when changing alpha slider', async () => {\n    const update = vi.fn()\n    render(() => (\n      <VColorPicker modelValue=\"#0000ff\" onUpdate:modelValue={ update } />\n    ))\n\n    await userEvent.click(screen.getByCSS('.v-color-picker-preview__alpha'))\n    // expect(update).toHaveBeenCalledTimes(1) // TODO: fix double update\n    expect(update).not.toHaveBeenCalledWith('#0000ff')\n  })\n\n  it('should emit value when clicking on swatch', async () => {\n    const update = vi.fn()\n    render(() => (\n      <VColorPicker showSwatches onUpdate:modelValue={ update } />\n    ))\n\n    const color = screen.getByCSS(\n      '.v-color-picker-swatches__swatch:nth-of-type(5) .v-color-picker-swatches__color:nth-of-type(1)'\n    )\n    await userEvent.click(color)\n    within(color).findByCSS('.v-icon')\n    expect(update).toHaveBeenCalledTimes(1)\n  })\n\n  it('should not use global defaults for slider color', async () => {\n    render(VColorPicker, null, {\n      defaults: {\n        VSlider: {\n          color: 'primary',\n          trackColor: 'primary',\n          trackFillColor: 'primary',\n        },\n      },\n    })\n\n    expect(screen.queryByCSS('.bg-primary')).toBeNull()\n    expect(screen.queryByCSS('.text-primary')).toBeNull()\n  })\n\n  it('should not show dot or input values if no color is set', async () => {\n    render(VColorPicker)\n\n    expect(screen.queryByCSS('.v-color-picker-canvas__dot')).toBeNull()\n    screen.getAllByCSS('.v-color-picker-edit__input input').forEach(el => {\n      expect(el).not.toHaveValue()\n    })\n\n    await userEvent.click(screen.getByCSS('canvas'))\n    expect(screen.getByCSS('.v-color-picker-canvas__dot')).toBeVisible()\n    screen.getAllByCSS('.v-color-picker-edit__input input').forEach(el => {\n      expect(el).toHaveValue()\n    })\n  })\n\n  it('should emit correct color when typing in hex field', async () => {\n    const update = vi.fn()\n    render(() => (\n      <VColorPicker mode=\"hexa\" onUpdate:modelValue={ update } />\n    ))\n\n    const input = screen.getByCSS('.v-color-picker-edit__input input')\n    await userEvent.type(input, 'FF00CC')\n    await userEvent.click(document.body)\n    expect(update).toHaveBeenCalledTimes(1)\n    expect(update).toHaveBeenCalledWith('#FF00CC')\n  })\n\n  showcase({ stories })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VColorPicker/_variables.scss",
    "content": "// VColorPicker\n$color-picker-border-radius: 4px !default;\n$color-picker-checkerboard: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAAXNSR0IArs4c6QAAACRJREFUKFNjPHTo0H8GJGBnZ8eIzGekgwJk+0BsdCtRHEQbBQBbbh0dIGKknQAAAABJRU5ErkJggg==) repeat !default;\n$color-picker-controls-padding: 16px !default;\n$color-picker-elevation: 1 !default;\n$color-picker-input-font-size: 0.75rem !default;\n$color-picker-input-height: 32px !default;\n$color-picker-input-margin: 8px !default;\n$color-picker-preview-margin-bottom: 0 !default;\n$color-picker-input-margin-bottom: 8px !default;\n$color-picker-input-margin-top: 24px !default;\n$color-picker-width: 300px !default;\n\n// VColorPickerSwatch\n$color-picker-swatch-color-border-radius: 2px !default;\n$color-picker-swatch-color-height: 18px !default;\n$color-picker-swatch-color-margin: 2px 4px !default;\n$color-picker-swatch-color-width: 45px !default;\n$color-picker-swatch-margin-bottom: 10px !default;\n$color-picker-swatches-border-radius: 8px !default;\n\n// VColorCanvas\n$color-picker-canvas-dot-box-shadow: 0px 0px 0px 1.5px rgba(255, 255, 255, 1), inset 0px 0px 1px 1.5px rgba(0, 0, 0, 0.3) !default;\n$color-picker-canvas-dot-disabled-box-shadow: 0px 0px 0px 1.5px rgba(255, 255, 255, 0.7), inset 0px 0px 1px 1.5px rgba(0, 0, 0, 0.3) !default;\n$color-picker-canvas-dot-size: 15px !default;\n\n// VColorPickerPreview\n$color-picker-preview-dot-size: 30px !default;\n$color-picker-preview-dot-margin: 24px !default;\n$color-picker-preview-dropper-margin: 12px !default;\n$color-picker-preview-sliders-padding: 8px !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VColorPicker/index.ts",
    "content": "export { VColorPicker } from './VColorPicker'\n"
  },
  {
    "path": "packages/vuetify/src/components/VColorPicker/util/__tests__/index.spec.ts",
    "content": "// Utilities\nimport { extractColor } from '../'\n\nconst red = { h: 0, s: 1, v: 1, a: 1 }\n\ndescribe('VColorPicker Utils', () => {\n  describe('Extract color', () => {\n    const cases = [\n      [red, null, '#FF0000'],\n      [red, '#FF0000', '#FF0000'],\n      [red, '#FF0000FF', '#FF0000'],\n      [{ ...red, a: 0.5 }, '#FF000000', '#FF000080'],\n      [red, { r: 255, g: 0, b: 0 }, { r: 255, g: 0, b: 0 }],\n      [red, { r: 255, g: 0, b: 0, a: 0 }, { r: 255, g: 0, b: 0, a: 1 }],\n      [red, { h: 0, s: 1, l: 0.5 }, { h: 0, s: 1, l: 0.5 }],\n      [red, { h: 0, s: 1, l: 0.5, a: 1 }, { h: 0, s: 1, l: 0.5, a: 1 }],\n      [red, { h: 0, s: 1, v: 1 }, { h: 0, s: 1, v: 1 }],\n      [red, { h: 0, s: 1, v: 1, a: 0.5 }, { h: 0, s: 1, v: 1, a: 1 }],\n      [red, undefined, '#FF0000'],\n      [red, 'hsl(0 0 0 / 1)', 'hsl(0 100 50)'],\n      [{ ...red, a: 0.5 }, 'hsl(0 0 0 / 1)', 'hsl(0 100 50 / 0.5)'],\n    ] as const\n\n    it.each(cases)('When given %p and %p, extractColor util should return %p', (...args) => {\n      const [color, input, result] = args\n      expect(extractColor(color, input)).toEqual(result)\n    })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VColorPicker/util/index.ts",
    "content": "// Utilities\nimport {\n  HexToHSV,\n  HSLtoHSV,\n  HSVtoHex,\n  HSVtoHSL,\n  HSVtoRGB,\n  RGBtoHSV,\n} from '@/util/colorUtils'\nimport { has } from '@/util/helpers'\n\n// Types\nimport type { HSL, HSV, RGB } from '@/util/colorUtils'\n\nfunction stripAlpha (color: any, stripAlpha: boolean) {\n  if (stripAlpha) {\n    const { a, ...rest } = color\n\n    return rest\n  }\n\n  return color\n}\n\nexport function extractColor (color: HSV, input: any) {\n  if (input == null || typeof input === 'string') {\n    const hasA = typeof color.a === 'number' && color.a < 1\n    if (input?.startsWith('rgb(')) {\n      const { r, g, b, a } = HSVtoRGB(color)\n      return `rgb(${r} ${g} ${b}` + (hasA ? ` / ${a})` : ')')\n    } else if (input?.startsWith('hsl(')) {\n      const { h, s, l, a } = HSVtoHSL(color)\n      return `hsl(${h} ${Math.round(s * 100)} ${Math.round(l * 100)}` + (hasA ? ` / ${a})` : ')')\n    }\n\n    const hex = HSVtoHex(color)\n\n    if (color.a === 1) return hex.slice(0, 7)\n    else return hex\n  }\n\n  if (typeof input === 'object') {\n    let converted\n\n    if (has(input, ['r', 'g', 'b'])) converted = HSVtoRGB(color)\n    else if (has(input, ['h', 's', 'l'])) converted = HSVtoHSL(color)\n    else if (has(input, ['h', 's', 'v'])) converted = color\n\n    return stripAlpha(converted, !has(input, ['a']) && color.a === 1)\n  }\n\n  return color\n}\n\nexport function hasAlpha (color: any) {\n  if (!color) return false\n\n  if (typeof color === 'string') {\n    return color.length > 7\n  }\n\n  if (typeof color === 'object') {\n    return has(color, ['a']) || has(color, ['alpha'])\n  }\n\n  return false\n}\n\nexport const nullColor = { h: 0, s: 0, v: 0, a: 1 }\n\nexport type ColorPickerMode = {\n  inputProps: Record<string, unknown>\n  inputs: {\n    [key: string]: any\n    getValue: (color: any) => number | string\n    getColor: (color: any, v: string) => any\n  }[]\n  from: (color: any) => HSV\n  to: (color: HSV) => any\n}\n\nconst rgba: ColorPickerMode = {\n  inputProps: {\n    type: 'number',\n    min: 0,\n  },\n  inputs: [\n    {\n      label: 'R',\n      max: 255,\n      step: 1,\n      getValue: (c: RGB) => Math.round(c.r),\n      getColor: (c: RGB, v: string): RGB => ({ ...c, r: Number(v) }),\n      localeKey: 'redInput',\n    },\n    {\n      label: 'G',\n      max: 255,\n      step: 1,\n      getValue: (c: RGB) => Math.round(c.g),\n      getColor: (c: RGB, v: string): RGB => ({ ...c, g: Number(v) }),\n      localeKey: 'greenInput',\n    },\n    {\n      label: 'B',\n      max: 255,\n      step: 1,\n      getValue: (c: RGB) => Math.round(c.b),\n      getColor: (c: RGB, v: string): RGB => ({ ...c, b: Number(v) }),\n      localeKey: 'blueInput',\n    },\n    {\n      label: 'A',\n      max: 1,\n      step: 0.01,\n      getValue: ({ a }: RGB) => a != null ? Math.round(a * 100) / 100 : 1,\n      getColor: (c: RGB, v: string): RGB => ({ ...c, a: Number(v) }),\n      localeKey: 'alphaInput',\n    },\n  ],\n  to: HSVtoRGB,\n  from: RGBtoHSV,\n}\n\nconst rgb = {\n  ...rgba,\n  inputs: rgba.inputs?.slice(0, 3),\n}\n\nconst hsla: ColorPickerMode = {\n  inputProps: {\n    type: 'number',\n    min: 0,\n  },\n  inputs: [\n    {\n      label: 'H',\n      max: 360,\n      step: 1,\n      getValue: (c: HSL) => Math.round(c.h),\n      getColor: (c: HSL, v: string): HSL => ({ ...c, h: Number(v) }),\n      localeKey: 'hueInput',\n    },\n    {\n      label: 'S',\n      max: 1,\n      step: 0.01,\n      getValue: (c: HSL) => Math.round(c.s * 100) / 100,\n      getColor: (c: HSL, v: string): HSL => ({ ...c, s: Number(v) }),\n      localeKey: 'saturationInput',\n    },\n    {\n      label: 'L',\n      max: 1,\n      step: 0.01,\n      getValue: (c: HSL) => Math.round(c.l * 100) / 100,\n      getColor: (c: HSL, v: string): HSL => ({ ...c, l: Number(v) }),\n      localeKey: 'lightnessInput',\n    },\n    {\n      label: 'A',\n      max: 1,\n      step: 0.01,\n      getValue: ({ a }: HSL) => a != null ? Math.round(a * 100) / 100 : 1,\n      getColor: (c: HSL, v: string): HSL => ({ ...c, a: Number(v) }),\n      localeKey: 'alphaInput',\n    },\n  ],\n  to: HSVtoHSL,\n  from: HSLtoHSV,\n}\n\nconst hsl = {\n  ...hsla,\n  inputs: hsla.inputs.slice(0, 3),\n}\n\nconst hexa: ColorPickerMode = {\n  inputProps: {\n    type: 'text',\n  },\n  inputs: [\n    {\n      label: 'HEXA',\n      getValue: (c: string) => c,\n      getColor: (c: string, v: string) => v,\n      localeKey: 'hexaInput',\n    },\n  ],\n  to: HSVtoHex,\n  from: HexToHSV,\n}\n\nconst hex = {\n  ...hexa,\n  inputs: [\n    {\n      label: 'HEX',\n      getValue: (c: string) => c.slice(0, 7),\n      getColor: (c: string, v: string) => v,\n      localeKey: 'hexInput',\n    },\n  ],\n}\n\nexport const modes = {\n  rgb,\n  rgba,\n  hsl,\n  hsla,\n  hex,\n  hexa,\n} satisfies Record<string, ColorPickerMode>\n"
  },
  {
    "path": "packages/vuetify/src/components/VCombobox/VCombobox.sass",
    "content": "@use 'sass:selector'\n@use 'sass:math'\n@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n@use '../VSelect/mixins' as *\n\n@include tools.layer('components')\n  .v-combobox\n    @include select-compact-chip-label\n\n    .v-field\n      .v-text-field__prefix,\n      .v-text-field__suffix,\n      .v-field__input,\n      .v-field__input > input,\n      &.v-field\n        cursor: text\n\n    .v-field\n      .v-field__input\n        > input\n          flex: 1 1\n\n    .v-field\n      input\n        min-width: $combobox-focused-input\n\n      &:not(.v-field--focused)\n        input\n          min-width: 0\n\n    .v-field--dirty\n      .v-combobox__selection\n        margin-inline-end: $combobox-selection-gap\n\n    .v-combobox__selection-text\n      overflow: hidden\n      text-overflow: ellipsis\n      white-space: nowrap\n\n  .v-combobox\n    &__content\n      overflow: hidden\n      @include tools.elevation($combobox-content-elevation)\n\n      @at-root #{selector.append('.v-menu > .v-overlay__content', &)}\n        @include tools.rounded($combobox-content-border-radius)\n\n      > .v-sheet\n        display: flex\n        flex-direction: column\n\n    &__mask\n      background: rgb(var(--v-theme-surface-light))\n\n    &__selection\n      display: inline-flex\n      align-items: center\n      height: calc($input-font-size * $input-line-height)\n      letter-spacing: inherit\n      line-height: inherit\n      max-width: calc(100% - $combobox-selection-gap - $combobox-input-buffer)\n\n    &__selection\n      &:first-child\n        margin-inline-start: 0\n\n    &--selecting-index\n      .v-combobox__selection\n        opacity: var(--v-medium-emphasis-opacity)\n\n        &--selected\n          opacity: 1\n\n      .v-field__input > input\n        caret-color: transparent\n\n    &--single:not(.v-combobox--selection-slot)\n      &.v-text-field input\n        flex: 1 1\n        position: absolute\n        left: 0\n        right: 0\n        width: 100%\n        padding-inline: inherit\n\n      .v-field--active\n        input\n          transition: none\n\n      .v-field--dirty:not(.v-field--focused)\n        input\n          opacity: 0\n\n      .v-field--focused\n        .v-combobox__selection\n          opacity: 0\n\n    &__menu-icon\n      margin-inline-start: 4px\n      transition: $combobox-transition\n\n      .v-combobox--active-menu &\n        transform: rotate(180deg)\n"
  },
  {
    "path": "packages/vuetify/src/components/VCombobox/VCombobox.tsx",
    "content": "// Styles\nimport './VCombobox.sass'\n\n// Components\nimport { VAvatar } from '@/components/VAvatar'\nimport { VCheckboxBtn } from '@/components/VCheckbox'\nimport { VChip } from '@/components/VChip'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\nimport { VDivider } from '@/components/VDivider'\nimport { VIcon } from '@/components/VIcon'\nimport { useInputIcon } from '@/components/VInput/InputIcon'\nimport { VList, VListItem, VListSubheader } from '@/components/VList'\nimport { VMenu } from '@/components/VMenu'\nimport { makeSelectProps } from '@/components/VSelect/VSelect'\nimport { VSheet } from '@/components/VSheet'\nimport { VTextField } from '@/components/VTextField'\nimport { makeVTextFieldProps } from '@/components/VTextField/VTextField'\nimport { VVirtualScroll } from '@/components/VVirtualScroll'\n\n// Composables\nimport { useScrolling } from '../VSelect/useScrolling'\nimport { useTextColor } from '@/composables/color'\nimport { highlightResult, makeFilterProps, useFilter } from '@/composables/filter'\nimport { useFocusGroups } from '@/composables/focusGroups'\nimport { useForm } from '@/composables/form'\nimport { forwardRefs } from '@/composables/forwardRefs'\nimport { transformItem, useItems } from '@/composables/list-items'\nimport { useLocale } from '@/composables/locale'\nimport { useMenuActivator } from '@/composables/menuActivator'\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { computed, mergeProps, nextTick, ref, shallowRef, toRef, watch } from 'vue'\nimport {\n  checkPrintable,\n  deepEqual,\n  ensureValidVNode,\n  escapeForRegex,\n  genericComponent,\n  IN_BROWSER,\n  isComposingIgnoreKey,\n  noop,\n  omit,\n  propsFactory,\n  useRender,\n  wrapInArray,\n} from '@/util'\n\n// Types\nimport type { PropType, Ref } from 'vue'\nimport type { VFieldSlots } from '@/components/VField/VField'\nimport type { VInputSlots } from '@/components/VInput/VInput'\nimport type { ListItem } from '@/composables/list-items'\nimport type { GenericProps, SelectItemKey } from '@/util'\n\ntype Primitive = string | number | boolean | symbol\n\ntype Val <T, ReturnObject extends boolean> = string | ([T] extends [Primitive]\n  ? T\n  : (ReturnObject extends true ? T : any))\n\ntype Value <T, ReturnObject extends boolean, Multiple extends boolean> =\n  Multiple extends true\n    ? readonly Val<T, ReturnObject>[]\n    : Val<T, ReturnObject> | null\n\nexport const makeVComboboxProps = propsFactory({\n  alwaysFilter: Boolean,\n  autoSelectFirst: {\n    type: [Boolean, String] as PropType<boolean | 'exact'>,\n  },\n  clearOnSelect: {\n    type: Boolean,\n    default: true,\n  },\n  delimiters: Array as PropType<readonly string[]>,\n\n  ...makeFilterProps({ filterKeys: ['title'] }),\n  ...makeSelectProps({ hideNoData: true, returnObject: true }),\n  ...omit(makeVTextFieldProps({\n    modelValue: null,\n    role: 'combobox',\n  }), ['validationValue', 'dirty']),\n}, 'VCombobox')\n\ntype ItemType<T> = T extends readonly (infer U)[] ? U : never\n\nexport const VCombobox = genericComponent<new <\n  T extends readonly any[],\n  Item = ItemType<T>,\n  ReturnObject extends boolean = true,\n  Multiple extends boolean = false,\n  V extends Value<Item, ReturnObject, Multiple> = Value<Item, ReturnObject, Multiple>\n>(\n  props: {\n    items?: T\n    itemTitle?: SelectItemKey<ItemType<T>>\n    itemValue?: SelectItemKey<ItemType<T>>\n    itemProps?: SelectItemKey<ItemType<T>>\n    returnObject?: ReturnObject\n    multiple?: Multiple\n    modelValue?: V | null\n    'onUpdate:modelValue'?: (value: V) => void\n  },\n  slots: Omit<VInputSlots & VFieldSlots, 'default'> & {\n    item: { item: Item, internalItem: ListItem<Item>, index: number, props: Record<string, unknown> }\n    chip: { item: Item, internalItem: ListItem<Item>, index: number, props: Record<string, unknown> }\n    selection: { item: Item, internalItem: ListItem<Item>, index: number }\n    subheader: { props: Record<string, unknown>, index: number }\n    divider: { props: Record<string, unknown>, index: number }\n    'prepend-item': never\n    'append-item': never\n    'no-data': never\n    'menu-header': { search: Ref<string | undefined>, filteredItems: ListItem<Item>[] }\n    'menu-footer': { search: Ref<string | undefined>, filteredItems: ListItem<Item>[] }\n  }\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VCombobox',\n\n  props: makeVComboboxProps(),\n\n  emits: {\n    'update:focused': (focused: boolean) => true,\n    'update:modelValue': (value: any) => true,\n    'update:search': (value: string) => true,\n    'update:menu': (value: boolean) => true,\n  },\n\n  setup (props, { emit, slots }) {\n    const { t } = useLocale()\n    const vTextFieldRef = ref<VTextField>()\n    const isFocused = shallowRef(false)\n    const isPristine = shallowRef(true)\n    const listHasFocus = shallowRef(false)\n    const vMenuRef = ref<VMenu>()\n    const vVirtualScrollRef = ref<VVirtualScroll>()\n    const selectionIndex = shallowRef(-1)\n    let cleared = false\n    const { items, transformIn, transformOut } = useItems(props)\n    const { textColorClasses, textColorStyles } = useTextColor(() => vTextFieldRef.value?.color)\n    const { InputIcon } = useInputIcon(props)\n    const model = useProxiedModel(\n      props,\n      'modelValue',\n      [],\n      v => transformIn(wrapInArray(v)),\n      v => {\n        const transformed = transformOut(v)\n        return props.multiple ? transformed : (transformed[0] ?? null)\n      }\n    )\n    const form = useForm(props)\n\n    const closableChips = toRef(() => props.closableChips && !form.isReadonly.value && !form.isDisabled.value)\n    const hasChips = computed(() => !!(props.chips || slots.chip))\n    const hasSelectionSlot = computed(() => hasChips.value || !!slots.selection)\n\n    const _search = shallowRef(!props.multiple && !hasSelectionSlot.value ? model.value[0]?.title ?? '' : '')\n    const _searchLock = shallowRef<string | null>(null)\n\n    const search = computed<string>({\n      get: () => {\n        return _search.value\n      },\n      set: async (val: string | null) => {\n        _search.value = val ?? ''\n        if (val === null || (val === '' && !props.multiple && !hasSelectionSlot.value)) {\n          model.value = []\n        } else if (!props.multiple && !hasSelectionSlot.value) {\n          model.value = [transformItem(props, val)]\n          nextTick(() => vVirtualScrollRef.value?.scrollToIndex(0))\n        }\n\n        if (val && props.multiple && props.delimiters?.length) {\n          const values = splitByDelimiters(val)\n          if (values.length > 1) {\n            selectMultiple(values)\n            _search.value = ''\n          }\n        }\n\n        if (!val) selectionIndex.value = -1\n\n        isPristine.value = !val\n      },\n    })\n\n    const counterValue = computed(() => {\n      return typeof props.counterValue === 'function' ? props.counterValue(model.value)\n        : typeof props.counterValue === 'number' ? props.counterValue\n        : (props.multiple ? model.value.length : search.value.length)\n    })\n\n    const { filteredItems, getMatches } = useFilter(\n      props,\n      items,\n      () => _searchLock.value ?? (props.alwaysFilter || !isPristine.value ? search.value : '')\n    )\n\n    const displayItems = computed(() => {\n      if (props.hideSelected && _searchLock.value === null) {\n        return filteredItems.value.filter(filteredItem => !model.value.some(s => s.value === filteredItem.value))\n      }\n      return filteredItems.value\n    })\n\n    const menuDisabled = computed(() => (\n      (props.hideNoData && !displayItems.value.length) ||\n      form.isReadonly.value || form.isDisabled.value\n    ))\n    const _menu = useProxiedModel(props, 'menu')\n    const menu = computed({\n      get: () => _menu.value,\n      set: v => {\n        if (_menu.value && !v && vMenuRef.value?.ΨopenChildren.size) return\n        if (v && menuDisabled.value) return\n        _menu.value = v\n      },\n    })\n\n    const { menuId, ariaExpanded, ariaControls } = useMenuActivator(props, menu)\n\n    watch(_search, value => {\n      if (cleared) {\n        // wait for clear to finish, VTextField sets _search to null\n        // then search computed triggers and updates _search to ''\n        nextTick(() => (cleared = false))\n      } else if (isFocused.value && !menu.value) {\n        menu.value = true\n      }\n\n      emit('update:search', value)\n    })\n\n    watch(model, value => {\n      if (!props.multiple && !hasSelectionSlot.value) {\n        _search.value = value[0]?.title ?? ''\n      }\n    })\n\n    const selectedValues = computed(() => model.value.map(selection => selection.value))\n\n    const firstSelectableItem = computed(() => displayItems.value.find(x => x.type === 'item' && !x.props.disabled))\n\n    const highlightFirst = computed(() => {\n      const selectFirst = props.autoSelectFirst === true ||\n        (props.autoSelectFirst === 'exact' && search.value === firstSelectableItem.value?.title)\n      return selectFirst &&\n        displayItems.value.length > 0 &&\n        !isPristine.value &&\n        !listHasFocus.value\n    })\n\n    const listRef = ref<VList>()\n    const headerRef = ref<HTMLElement>()\n    const footerRef = ref<HTMLElement>()\n    const listEvents = useScrolling(listRef, vTextFieldRef)\n    const { onTabKeydown } = useFocusGroups({\n      groups: [\n        { type: 'element' as const, contentRef: headerRef },\n        { type: 'list' as const, contentRef: listRef, displayItemsCount: () => displayItems.value.length },\n        { type: 'element' as const, contentRef: footerRef },\n      ],\n      onLeave: () => {\n        menu.value = false\n        vTextFieldRef.value?.focus()\n      },\n    })\n    function onClear (e: MouseEvent) {\n      cleared = true\n      nextTick(() => (cleared = false))\n\n      if (props.openOnClear) {\n        menu.value = true\n      }\n    }\n    function onMousedownControl () {\n      if (menuDisabled.value) return\n\n      menu.value = true\n    }\n    function onMousedownMenuIcon (e: MouseEvent) {\n      if (menuDisabled.value) return\n\n      if (isFocused.value) {\n        e.preventDefault()\n        e.stopPropagation()\n      }\n      menu.value = !menu.value\n    }\n    function onMenuKeydown (e: KeyboardEvent) {\n      if (e.key === 'Tab') {\n        onTabKeydown(e)\n      }\n\n      if (listRef.value?.$el.contains(e.target) && (checkPrintable(e) || e.key === 'Backspace')) {\n        vTextFieldRef.value?.focus()\n      }\n    }\n\n    // eslint-disable-next-line complexity\n    function onKeydown (e: KeyboardEvent) {\n      if (isComposingIgnoreKey(e) || form.isReadonly.value) return\n\n      const selectionStart = vTextFieldRef.value?.selectionStart\n      const length = model.value.length\n\n      if (['Enter', 'ArrowDown', 'ArrowUp'].includes(e.key)) {\n        e.preventDefault()\n      }\n\n      if (['Enter', 'ArrowDown'].includes(e.key)) {\n        menu.value = true\n      }\n\n      if (['Escape'].includes(e.key)) {\n        menu.value = false\n      }\n\n      if (\n        highlightFirst.value &&\n        ['Enter', 'Tab'].includes(e.key) &&\n        firstSelectableItem.value &&\n        !model.value.some(({ value }) => value === firstSelectableItem.value!.value)\n      ) {\n        select(firstSelectableItem.value)\n      }\n\n      if (e.key === 'ArrowDown' && highlightFirst.value) {\n        listRef.value?.focus('next')\n      }\n\n      if (e.key === 'Enter' && search.value) {\n        select(transformItem(props, search.value), true, true)\n        if (hasSelectionSlot.value) _search.value = ''\n      }\n\n      if (['Backspace', 'Delete'].includes(e.key)) {\n        if (\n          !props.multiple &&\n          hasSelectionSlot.value &&\n          model.value.length > 0 &&\n          !search.value\n        ) return select(model.value[0], false)\n\n        if (~selectionIndex.value) {\n          e.preventDefault()\n          const originalSelectionIndex = selectionIndex.value\n          select(model.value[selectionIndex.value], false)\n\n          selectionIndex.value = originalSelectionIndex >= length - 1 ? (length - 2) : originalSelectionIndex\n        } else if (e.key === 'Backspace' && !search.value) {\n          selectionIndex.value = length - 1\n        }\n\n        return\n      }\n\n      if (!props.multiple) return\n\n      if (e.key === 'ArrowLeft') {\n        if (selectionIndex.value < 0 && selectionStart && selectionStart > 0) return\n\n        const prev = selectionIndex.value > -1\n          ? selectionIndex.value - 1\n          : length - 1\n\n        if (model.value[prev]) {\n          selectionIndex.value = prev\n        } else {\n          selectionIndex.value = -1\n          vTextFieldRef.value?.setSelectionRange(search.value.length, search.value.length)\n        }\n      } else if (e.key === 'ArrowRight') {\n        if (selectionIndex.value < 0) return\n\n        const next = selectionIndex.value + 1\n\n        if (model.value[next]) {\n          selectionIndex.value = next\n        } else {\n          selectionIndex.value = -1\n          vTextFieldRef.value?.setSelectionRange(0, 0)\n        }\n      } else if (~selectionIndex.value && checkPrintable(e)) {\n        selectionIndex.value = -1\n      }\n    }\n    function onPaste (e: ClipboardEvent) {\n      const clipboardText = e?.clipboardData?.getData('Text') ?? ''\n      const values = splitByDelimiters(clipboardText)\n\n      if (values.length > 1 && props.multiple) {\n        e.preventDefault()\n        selectMultiple(values)\n      }\n    }\n    function onAfterEnter () {\n      if (props.eager) {\n        vVirtualScrollRef.value?.calculateVisibleItems()\n      }\n    }\n    function onAfterLeave () {\n      if (isFocused.value) {\n        vTextFieldRef.value?.focus()\n      }\n      isPristine.value = true\n      _searchLock.value = null\n    }\n    /** @param set - null means toggle */\n    function select (item: ListItem | undefined, set: boolean | null = true, keepMenu = false) {\n      if (!item || item.props.disabled) return\n\n      if (props.multiple) {\n        const index = model.value.findIndex(selection => (props.valueComparator || deepEqual)(selection.value, item.value))\n        const add = set == null ? !~index : set\n\n        if (~index) {\n          const value = add ? [...model.value, item] : [...model.value]\n          value.splice(index, 1)\n          model.value = value\n        } else if (add) {\n          model.value = [...model.value, item]\n        }\n\n        if (props.clearOnSelect) {\n          search.value = ''\n        }\n      } else {\n        const add = set !== false\n        model.value = add ? [item] : []\n        if ((!isPristine.value || props.alwaysFilter) && _search.value) {\n          _searchLock.value = _search.value\n        }\n        _search.value = add && !hasSelectionSlot.value ? item.title : ''\n\n        // watch for search watcher to trigger\n        nextTick(() => {\n          menu.value = keepMenu\n          isPristine.value = true\n        })\n      }\n    }\n    function splitByDelimiters (val: string) {\n      const effectiveDelimiters = ['\\n', ...props.delimiters ?? []]\n      const signsToMatch = effectiveDelimiters.map(escapeForRegex).join('|')\n      return val.split(new RegExp(`(?:${signsToMatch})+`))\n    }\n    async function selectMultiple (values: string[]) {\n      for (let value of values) {\n        value = value.trim()\n        if (value) {\n          select(transformItem(props, value))\n          await nextTick()\n        }\n      }\n    }\n    function onFocusin (e: FocusEvent) {\n      isFocused.value = true\n      setTimeout(() => {\n        listHasFocus.value = true\n      })\n    }\n    function onFocusout (e: FocusEvent) {\n      listHasFocus.value = false\n      if (!vTextFieldRef.value?.$el.contains(e.relatedTarget as Node)) {\n        isFocused.value = false\n      }\n    }\n\n    function onBlur (e: FocusEvent) {\n      const menuContent = vMenuRef.value?.contentEl\n      if (menuContent?.contains(e.relatedTarget as Node)) {\n        isFocused.value = true\n      }\n    }\n\n    watch(isFocused, (val, oldVal) => {\n      if (val || val === oldVal) return\n\n      selectionIndex.value = -1\n      menu.value = false\n\n      if (search.value) {\n        if (props.multiple) {\n          select(transformItem(props, search.value))\n          return\n        }\n\n        if (!hasSelectionSlot.value) return\n\n        if (model.value.some(({ title }) => title === search.value)) {\n          _search.value = ''\n        } else {\n          select(transformItem(props, search.value))\n        }\n      }\n    })\n\n    watch(menu, val => {\n      if (!props.hideSelected && val && model.value.length && isPristine.value) {\n        const index = displayItems.value.findIndex(\n          item => model.value.some(s => (props.valueComparator || deepEqual)(s.value, item.value))\n        )\n        IN_BROWSER && window.requestAnimationFrame(() => {\n          index >= 0 && vVirtualScrollRef.value?.scrollToIndex(index)\n        })\n      }\n\n      if (val) _searchLock.value = null\n    })\n\n    watch(items, (newVal, oldVal) => {\n      if (menu.value) return\n\n      if (isFocused.value && !oldVal.length && newVal.length) {\n        menu.value = true\n      }\n    })\n\n    useRender(() => {\n      const hasList = !!(\n        (!props.hideNoData || displayItems.value.length) ||\n        slots['prepend-item'] ||\n        slots['append-item'] ||\n        slots['no-data']\n      )\n      const isDirty = model.value.length > 0\n      const textFieldProps = VTextField.filterProps(props)\n\n      const menuSlotProps = {\n        search,\n        filteredItems: filteredItems.value,\n      }\n\n      return (\n        <VTextField\n          ref={ vTextFieldRef }\n          { ...textFieldProps }\n          v-model={ search.value }\n          v-model:focused={ isFocused.value }\n          validationValue={ model.externalValue }\n          counterValue={ counterValue.value }\n          dirty={ isDirty }\n          class={[\n            'v-combobox',\n            {\n              'v-combobox--active-menu': menu.value,\n              'v-combobox--chips': !!props.chips,\n              'v-combobox--selection-slot': !!hasSelectionSlot.value,\n              'v-combobox--selecting-index': selectionIndex.value > -1,\n              [`v-combobox--${props.multiple ? 'multiple' : 'single'}`]: true,\n            },\n            props.class,\n          ]}\n          style={ props.style }\n          readonly={ form.isReadonly.value }\n          placeholder={ isDirty ? undefined : props.placeholder }\n          onClick:clear={ onClear }\n          onMousedown:control={ onMousedownControl }\n          onKeydown={ onKeydown }\n          onPaste={ onPaste }\n          onBlur={ onBlur }\n          aria-expanded={ ariaExpanded.value }\n          aria-controls={ ariaControls.value }\n        >\n          {{\n            ...slots,\n            default: ({ id }) => (\n              <>\n                <VMenu\n                  id={ menuId.value }\n                  ref={ vMenuRef }\n                  v-model={ menu.value }\n                  activator=\"parent\"\n                  contentClass=\"v-combobox__content\"\n                  disabled={ menuDisabled.value }\n                  eager={ props.eager }\n                  maxHeight={ 310 }\n                  openOnClick={ false }\n                  closeOnContentClick={ false }\n                  onAfterEnter={ onAfterEnter }\n                  onAfterLeave={ onAfterLeave }\n                  { ...props.menuProps }\n                >\n                  <VSheet\n                    elevation={ props.menuElevation }\n                    onFocusin={ onFocusin }\n                    onKeydown={ onMenuKeydown }\n                  >\n                    { slots['menu-header'] && (\n                      <header ref={ headerRef }>\n                        { slots['menu-header'](menuSlotProps) }\n                      </header>\n                    )}\n\n                    { hasList && (\n                      <VList\n                        key=\"combobox-list\"\n                        ref={ listRef }\n                        filterable\n                        selected={ selectedValues.value }\n                        selectStrategy={ props.multiple ? 'independent' : 'single-independent' }\n                        onMousedown={ (e: MouseEvent) => e.preventDefault() }\n                        selectable={ !!displayItems.value.length }\n                        onFocusout={ onFocusout }\n                        tabindex=\"-1\"\n                        aria-live=\"polite\"\n                        aria-labelledby={ `${id.value}-label` }\n                        aria-multiselectable={ props.multiple }\n                        color={ props.itemColor ?? props.color }\n                        { ...listEvents }\n                        { ...props.listProps }\n                      >\n                      { slots['prepend-item']?.() }\n\n                      { !displayItems.value.length && !props.hideNoData && (slots['no-data']?.() ?? (\n                        <VListItem key=\"no-data\" title={ t(props.noDataText) } />\n                      ))}\n\n                      <VVirtualScroll ref={ vVirtualScrollRef } renderless items={ displayItems.value } itemKey=\"value\">\n                        { ({ item, index, itemRef }) => {\n                          const itemProps = mergeProps(item.props, {\n                            ref: itemRef,\n                            key: item.value,\n                            active: (highlightFirst.value && item === firstSelectableItem.value) ? true : undefined,\n                            onClick: () => select(item, null),\n                            'aria-posinset': index + 1,\n                            'aria-setsize': displayItems.value.length,\n                          })\n\n                          if (item.type === 'divider') {\n                            return slots.divider?.({ props: item.raw, index }) ?? (\n                              <VDivider { ...item.props } key={ `divider-${index}` } />\n                            )\n                          }\n\n                          if (item.type === 'subheader') {\n                            return slots.subheader?.({ props: item.raw, index }) ?? (\n                              <VListSubheader { ...item.props } key={ `subheader-${index}` } />\n                            )\n                          }\n\n                          return slots.item?.({\n                            item: item.raw,\n                            internalItem: item,\n                            index,\n                            props: itemProps,\n                          }) ?? (\n                            <VListItem { ...itemProps } role=\"option\">\n                            {{\n                              prepend: ({ isSelected }) => (\n                                <>\n                                  { props.multiple && !props.hideSelected ? (\n                                    <VCheckboxBtn\n                                      key={ item.value }\n                                      modelValue={ isSelected }\n                                      ripple={ false }\n                                      tabindex=\"-1\"\n                                      aria-hidden\n                                      onClick={ (event: MouseEvent) => event.preventDefault() }\n                                    />\n                                  ) : undefined }\n\n                                  { item.props.prependAvatar && (\n                                    <VAvatar image={ item.props.prependAvatar } />\n                                  )}\n\n                                  { item.props.prependIcon && (\n                                    <VIcon icon={ item.props.prependIcon } />\n                                  )}\n                                </>\n                              ),\n                              title: () => {\n                                return isPristine.value\n                                  ? item.title\n                                  : highlightResult('v-combobox', item.title, getMatches(item)?.title)\n                              },\n                            }}\n                          </VListItem>\n                          )\n                        }}\n                      </VVirtualScroll>\n\n                      { slots['append-item']?.() }\n                    </VList>\n                    )}\n\n                    { slots['menu-footer'] && (\n                      <footer ref={ footerRef }>\n                        { slots['menu-footer'](menuSlotProps) }\n                      </footer>\n                    )}\n                  </VSheet>\n                </VMenu>\n\n                { model.value.map((item, index) => {\n                  function onChipClose (e: Event) {\n                    e.stopPropagation()\n                    e.preventDefault()\n\n                    select(item, false)\n                  }\n\n                  const slotProps = mergeProps(VChip.filterProps(item.props), {\n                    'onClick:close': onChipClose,\n                    onKeydown (e: KeyboardEvent) {\n                      if (e.key !== 'Enter' && e.key !== ' ') return\n\n                      e.preventDefault()\n                      e.stopPropagation()\n\n                      onChipClose(e)\n                    },\n                    onMousedown (e: MouseEvent) {\n                      e.preventDefault()\n                      e.stopPropagation()\n                    },\n                    modelValue: true,\n                    'onUpdate:modelValue': undefined,\n                  })\n\n                  const hasSlot = hasChips.value ? !!slots.chip : !!slots.selection\n                  const slotContent = hasSlot\n                    ? ensureValidVNode(\n                      hasChips.value\n                        ? slots.chip!({ item: item.raw, internalItem: item, index, props: slotProps })\n                        : slots.selection!({ item: item.raw, internalItem: item, index })\n                    )\n                    : undefined\n\n                  if (hasSlot && !slotContent) return undefined\n\n                  return (\n                    <div\n                      key={ item.value }\n                      class={[\n                        'v-combobox__selection',\n                        index === selectionIndex.value && [\n                          'v-combobox__selection--selected',\n                          textColorClasses.value,\n                        ],\n                      ]}\n                      style={ index === selectionIndex.value ? textColorStyles.value : {} }\n                    >\n                      { hasChips.value ? (\n                        !slots.chip ? (\n                          <VChip\n                            key=\"chip\"\n                            closable={ closableChips.value }\n                            size=\"small\"\n                            text={ item.title }\n                            disabled={ item.props.disabled }\n                            { ...slotProps }\n                          />\n                        ) : (\n                          <VDefaultsProvider\n                            key=\"chip-defaults\"\n                            defaults={{\n                              VChip: {\n                                closable: closableChips.value,\n                                size: 'small',\n                                text: item.title,\n                              },\n                            }}\n                          >\n                            { slotContent }\n                          </VDefaultsProvider>\n                        )\n                      ) : (\n                        slotContent ?? (\n                          <span class=\"v-combobox__selection-text\">\n                            { item.title }\n                            { props.multiple && (index < model.value.length - 1) && (\n                              <span class=\"v-combobox__selection-comma\">,</span>\n                            )}\n                          </span>\n                        )\n                      )}\n                    </div>\n                  )\n                })}\n              </>\n            ),\n            'append-inner': (...args) => (\n              <>\n                { slots['append-inner']?.(...args) }\n                { (!props.hideNoData || props.items.length) && props.menuIcon ? (\n                  <VIcon\n                    class=\"v-combobox__menu-icon\"\n                    color={ vTextFieldRef.value?.fieldIconColor }\n                    icon={ props.menuIcon }\n                    onMousedown={ onMousedownMenuIcon }\n                    onClick={ noop }\n                    aria-hidden\n                    tabindex=\"-1\"\n                  />\n                ) : undefined }\n                { props.appendInnerIcon && (\n                  <InputIcon\n                    key=\"append-icon\"\n                    name=\"appendInner\"\n                    color={ args[0].iconColor.value }\n                  />\n                )}\n              </>\n            ),\n          }}\n        </VTextField>\n      )\n    })\n\n    return forwardRefs({\n      isFocused,\n      isPristine,\n      menu,\n      search,\n      selectionIndex,\n      filteredItems,\n      select,\n    }, vTextFieldRef)\n  },\n})\n\nexport type VCombobox = InstanceType<typeof VCombobox>\n"
  },
  {
    "path": "packages/vuetify/src/components/VCombobox/__tests__/VCombobox-multiple.spec.ts",
    "content": "// @ts-nocheck\n/* eslint-disable */\n\n// Components\n// import VCombobox from '../VCombobox'\n\n// Utilities\nimport {\n  mount,\n  Wrapper,\n} from '@vue/test-utils'\n// import { keyCodes } from '../../../util/helpers'\n\ndescribe.skip('VCombobox.ts', () => {\n  type Instance = InstanceType<typeof VCombobox>\n  let mountFunction: (options?: object) => Wrapper<Instance>\n\n  beforeEach(() => {\n    document.body.setAttribute('data-app', 'true')\n\n    mountFunction = (options = {}) => {\n      return mount(VCombobox, {\n        // https://github.com/vuejs/vue-test-utils/issues/1130\n        sync: false,\n        mocks: {\n          $vuetify: {\n            lang: {\n              t: (val: string) => val,\n            },\n            theme: {\n              dark: false,\n            },\n          },\n        },\n        ...options,\n      })\n    }\n  })\n\n  function createMultipleCombobox (propsData) {\n    const change = jest.fn()\n    const wrapper = mountFunction({\n      attachToDocument: true,\n      propsData: Object.assign({\n        multiple: true,\n        value: [],\n      }, propsData),\n    })\n\n    wrapper.vm.$on('input', change)\n    return { wrapper, change }\n  }\n\n  it('should create new values when tagging', async () => {\n    const { wrapper, change } = createMultipleCombobox({})\n\n    const input = wrapper.find('input')\n    const element = input.element as HTMLInputElement\n\n    input.trigger('focus')\n    element.value = 'foo'\n    input.trigger('input')\n    input.trigger('keydown.enter')\n\n    await wrapper.vm.$nextTick()\n\n    expect(change).toHaveBeenCalledWith(['foo'])\n  })\n\n  it('should change selectedIndex with keyboard', async () => {\n    const { wrapper } = createMultipleCombobox({\n      value: ['foo', 'bar'],\n    })\n\n    const input = wrapper.find('input')\n\n    input.trigger('focus')\n    await wrapper.vm.$nextTick()\n\n    for (const index of [1, 0, -1]) {\n      input.trigger('keydown.left')\n      await wrapper.vm.$nextTick()\n      expect(wrapper.vm.selectedIndex).toBe(index)\n    }\n  })\n\n  it('should delete a tagged item when selected and backspace/delete is pressed', async () => {\n    const { wrapper, change } = createMultipleCombobox({\n      value: ['foo', 'bar'],\n    })\n\n    const input = wrapper.find('input')\n\n    input.trigger('focus')\n    input.trigger('keydown.left')\n    expect(wrapper.vm.selectedIndex).toBe(1)\n\n    input.trigger('keydown.delete')\n    await wrapper.vm.$nextTick()\n    expect(change).toHaveBeenCalledWith(['foo'])\n    expect(wrapper.vm.selectedIndex).toBe(0)\n\n    const backspace = new Event('keydown')\n    backspace.keyCode = keyCodes.delete\n\n    input.element.dispatchEvent(backspace) // Avoriaz doesn't wrap keydown.backspace\n    await wrapper.vm.$nextTick()\n    expect(change).toHaveBeenCalledWith([])\n    expect(wrapper.vm.selectedIndex).toBe(-1)\n  })\n\n  it('should add a tag on enter using the current searchValue', async () => {\n    const { wrapper, change } = createMultipleCombobox({\n      items: ['bar'],\n    })\n\n    const input = wrapper.find('input')\n    const element = input.element as HTMLInputElement\n\n    input.trigger('focus')\n    await wrapper.vm.$nextTick()\n\n    element.value = 'ba'\n    input.trigger('input')\n    await wrapper.vm.$nextTick()\n    input.trigger('keydown.enter')\n    await wrapper.vm.$nextTick()\n\n    expect(change).toHaveBeenCalledWith(['ba'])\n  })\n\n  it.skip('should add a tag on left arrow and select the previous tag', async () => {\n    const { wrapper, change } = createMultipleCombobox({\n      value: ['foo'],\n      items: ['foo', 'bar'],\n    })\n\n    const input = wrapper.find('input')\n    const element = input.element as HTMLInputElement\n\n    input.trigger('focus')\n    element.value = 'b'\n    input.trigger('input')\n    input.trigger('keydown.left')\n\n    expect(change).toHaveBeenCalledWith(['foo', 'b'])\n    expect(wrapper.vm.selectedIndex).toBe(0)\n  })\n\n  it('should remove a duplicate tag and add it to the end', async () => {\n    const { wrapper, change } = createMultipleCombobox({\n      value: ['foo', 'bar'],\n    })\n\n    const input = wrapper.find('input')\n    const element = input.element as HTMLInputElement\n\n    input.trigger('focus')\n    await wrapper.vm.$nextTick()\n\n    element.value = 'foo'\n    input.trigger('input')\n    input.trigger('keydown.enter')\n    await wrapper.vm.$nextTick()\n\n    expect(change).toHaveBeenCalledWith(['bar', 'foo'])\n  })\n\n  it('should add tag with valid search value on blur', async () => {\n    const { wrapper, change } = createMultipleCombobox({})\n\n    const input = wrapper.find('input')\n    const element = input.element as HTMLInputElement\n\n    input.trigger('focus')\n    element.value = 'bar'\n    input.trigger('input')\n    input.trigger('keydown.enter')\n\n    await wrapper.vm.$nextTick()\n\n    expect(change).toHaveBeenCalledWith(['bar'])\n  })\n\n  it('should be able to add a tag from user input after deleting a tag with delete', async () => {\n    const { wrapper, change } = createMultipleCombobox({\n      multiple: true,\n      value: ['foo', 'bar'],\n    })\n\n    const input = wrapper.find('input')\n    const element = input.element as HTMLInputElement\n\n    input.trigger('focus')\n    input.trigger('keydown.left')\n    expect(wrapper.vm.selectedIndex).toBe(1)\n    input.trigger('keydown.delete')\n    expect(change).toHaveBeenCalledWith(['foo'])\n    expect(wrapper.vm.selectedIndex).toBe(0)\n\n    // Must be reset for input to update\n    wrapper.vm.selectedIndex = -1\n    await wrapper.vm.$nextTick()\n\n    element.value = 'baz'\n\n    input.trigger('input')\n    input.trigger('keydown.enter')\n\n    await wrapper.vm.$nextTick()\n\n    expect(change).toHaveBeenCalledWith(['foo', 'baz'])\n    expect(wrapper.vm.selectedIndex).toBe(-1)\n  })\n\n  it('should be able to add a tag from user input after clicking a deletable chip', async () => {\n    const { wrapper, change } = createMultipleCombobox({\n      chips: true,\n      clearable: true,\n      deletableChips: true,\n      multiple: true,\n      value: ['foo', 'bar'],\n    })\n\n    const input = wrapper.find('input')\n    const element = input.element as HTMLInputElement\n    const chip = wrapper.findAll('.v-chip').at(1)\n    const close = chip.find('.v-chip__close')\n\n    input.trigger('focus')\n    chip.trigger('click')\n    close.trigger('click')\n    expect(change).toHaveBeenCalledWith(['foo'])\n    expect(wrapper.vm.selectedIndex).toBe(-1)\n\n    element.value = 'baz'\n    input.trigger('input')\n    expect(wrapper.vm.internalSearch).toBe('baz')\n    input.trigger('keydown.enter')\n\n    await wrapper.vm.$nextTick()\n\n    expect(change).toHaveBeenCalledWith(['foo', 'baz'])\n    expect(wrapper.vm.selectedIndex).toBe(-1)\n  })\n\n  // This test is actually almost useless\n  it('should not change search when selecting an index', () => {\n    const { wrapper } = createMultipleCombobox({\n      chips: true,\n      multiple: true,\n      value: ['foo', 'bar'],\n    })\n\n    const input = wrapper.find('input')\n    const element = input.element as HTMLInputElement\n\n    input.trigger('focus')\n    expect(wrapper.vm.selectedIndex).toBe(-1)\n\n    input.trigger('keydown.left')\n    expect(wrapper.vm.selectedIndex).toBe(1)\n\n    expect(wrapper.vm.internalSearch).toBeUndefined()\n    input.trigger('keydown.right')\n    element.value = 'fizz'\n    input.trigger('input')\n\n    expect(wrapper.vm.internalSearch).toBe('fizz')\n    expect(wrapper.vm.selectedIndex).toBe(-1)\n  })\n\n  // eslint-disable-next-line max-statements\n  it('should create new items when a delimiter is entered', async () => {\n    const { wrapper, change } = createMultipleCombobox({\n      delimiters: [', ', 'baz'],\n    })\n\n    await wrapper.vm.$nextTick()\n\n    const input = wrapper.find('input')\n    const element = input.element as HTMLInputElement\n    input.trigger('focus')\n\n    element.value = 'foo,'\n    input.trigger('input')\n\n    await wrapper.vm.$nextTick()\n    expect(change).toHaveBeenCalledTimes(0)\n\n    element.value += ' '\n    input.trigger('input')\n\n    await wrapper.vm.$nextTick()\n    expect(change).toHaveBeenCalledTimes(1)\n    expect(change).toHaveBeenCalledWith(['foo'])\n    expect(element.value).toBe('')\n\n    element.value = 'foo,barba'\n    input.trigger('input')\n\n    await wrapper.vm.$nextTick()\n    expect(change).toHaveBeenCalledTimes(1)\n\n    element.value += 'z'\n    input.trigger('input')\n\n    await wrapper.vm.$nextTick()\n    expect(change).toHaveBeenCalledTimes(2)\n    expect(change).toHaveBeenCalledWith(['foo', 'foo,bar'])\n    expect(element.value).toBe('')\n  })\n\n  it('should allow the editing of an existing value', async () => {\n    const { wrapper } = createMultipleCombobox({\n      chips: true,\n      value: ['foo'],\n    })\n\n    const change = jest.fn()\n    const internal = jest.fn()\n    const chip = wrapper.find('.v-chip')\n    const input = wrapper.find('input')\n    const element = input.element as HTMLInputElement\n\n    wrapper.vm.$on('change', change)\n    wrapper.vm.$watch('internalValue', internal)\n\n    expect(wrapper.vm.editingIndex).toBe(-1)\n    expect(wrapper.vm.internalSearch).toBeUndefined()\n\n    chip.trigger('dblclick')\n\n    expect(wrapper.vm.editingIndex).toBe(0)\n    expect(wrapper.vm.internalSearch).toBe('foo')\n\n    element.value = 'foobar'\n    input.trigger('input')\n    input.trigger('keydown.enter')\n\n    await wrapper.vm.$nextTick()\n\n    expect(change).toHaveBeenCalledWith(['foobar'])\n    expect(internal).toHaveBeenCalledWith(['foobar'], ['foo'])\n  })\n\n  it('should paste as item if source of pasted text is item in another v-combobox/v-autocomplete', async () => {\n    const { wrapper, change } = createMultipleCombobox({\n      items: ['aaa', 'bbb'],\n    })\n\n    const input = wrapper.find('input')\n    const getData = jest.fn(mimeType => 'ccc')\n    const event = {\n      clipboardData: {\n        getData,\n      },\n    }\n\n    input.trigger('focus')\n    input.trigger('paste', event)\n\n    expect(getData).toHaveBeenCalledTimes(1)\n    expect(getData).toHaveBeenCalledWith('text/vnd.vuetify.autocomplete.item+plain')\n    expect(change).toHaveBeenCalledWith(['ccc'])\n  })\n\n  it('should paste as text if source of pasted text is not item in another v-combobox/v-autocomplete', async () => {\n    const { wrapper, change } = createMultipleCombobox({\n      items: ['aaa', 'bbb'],\n    })\n\n    const input = wrapper.find('input')\n    const getData = jest.fn(mimeType => mimeType === 'text/plain' ? 'ccc' : '')\n    const event = {\n      clipboardData: {\n        getData,\n      },\n    }\n\n    input.trigger('focus')\n    input.trigger('paste', event)\n\n    expect(change).not.toHaveBeenCalled()\n    // expect(input.element.value).toBe('ccc')  // can be checked only in browser environment\n  })\n\n  it('should not add search to list when selecting items with keyboard', async () => {\n    const { wrapper, change } = createMultipleCombobox({\n      chips: true,\n      multiple: true,\n      items: ['aaa', 'bbb'],\n    })\n\n    const input = wrapper.find('input')\n    const element = input.element as HTMLInputElement\n\n    input.trigger('focus')\n    element.value = 'a'\n    input.trigger('input')\n    input.trigger('keydown.down')\n\n    await wrapper.vm.$nextTick()\n\n    input.trigger('keydown.enter')\n\n    await wrapper.vm.$nextTick()\n\n    expect(wrapper.vm.internalSearch).toBeNull()\n    expect(change).toHaveBeenCalledWith(['aaa'])\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/12781\n  // eslint-disable-next-line max-statements\n  it('should correctly add items after deletion and blur', async () => {\n    const { wrapper, change } = createMultipleCombobox({\n      multiple: true,\n      chips: true,\n      value: ['foo', 'bar'],\n      items: ['foo', 'bar'],\n    })\n\n    const input = wrapper.find('input')\n    const element = input.element as HTMLInputElement\n\n    // delete 'bar'\n    input.trigger('focus')\n    input.trigger('keydown.left')\n    expect(wrapper.vm.selectedIndex).toBe(1)\n    input.trigger('keydown.delete')\n    await wrapper.vm.$nextTick()\n    expect(change).toHaveBeenCalledWith(['foo'])\n    expect(wrapper.vm.selectedIndex).toBe(0)\n\n    // Lose focus\n    input.trigger('keydown.tab')\n    await wrapper.vm.$nextTick()\n    expect(change).toHaveBeenCalledWith(['foo'])\n\n    // Add 'bar' again\n    input.trigger('focus')\n    element.value = 'bar'\n    input.trigger('input')\n    input.trigger('keydown.down')\n    await wrapper.vm.$nextTick()\n    input.trigger('keydown.enter')\n    await wrapper.vm.$nextTick()\n    expect(change).toHaveBeenLastCalledWith(['foo', 'bar'])\n\n    // Set 'bar' as search input\n    element.value = 'bar'\n    input.trigger('input')\n    await wrapper.vm.$nextTick()\n    expect(wrapper.vm.internalSearch).toBe('bar')\n\n    // Lose focus\n    input.trigger('keydown.tab')\n    await wrapper.vm.$nextTick()\n    expect(change).toHaveBeenLastCalledWith(['foo', 'bar'])\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/13274\n  it('should not add empty values', async () => {\n    const { wrapper, change } = createMultipleCombobox({\n      chips: true,\n      multiple: true,\n      items: ['foo'],\n      value: ['foo'],\n    })\n\n    const input = wrapper.find('input')\n    const element = input.element as HTMLInputElement\n\n    // Add a value and then remove it\n    input.trigger('focus')\n    element.value = 'a'\n    input.trigger('input')\n    await wrapper.vm.$nextTick()\n    element.value = ''\n    input.trigger('input')\n    await wrapper.vm.$nextTick()\n\n    // Lose focus\n    input.trigger('keydown.tab')\n    await wrapper.vm.$nextTick()\n\n    expect(change).not.toHaveBeenCalled()\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/10827\n  it('should not add empty chips after clear and re-select', async () => {\n    const { wrapper, change } = createMultipleCombobox({\n      chips: true,\n      multiple: true,\n      clearable: true,\n      items: ['foo', 'bar'],\n      value: ['foo', 'bar'],\n    })\n\n    const input = wrapper.find('input')\n    const element = input.element as HTMLInputElement\n\n    // Dbl click chip at index 1\n    const chip = wrapper.findAll('.v-chip').at(1)\n    chip.trigger('dblclick')\n    expect(wrapper.vm.editingIndex).toBe(1)\n    expect(wrapper.vm.internalSearch).toBe('bar')\n\n    // Click clear button\n    const clear = wrapper.find('.v-input__icon--clear .v-icon')\n    clear.trigger('click')\n    await wrapper.vm.$nextTick()\n    expect(change).toHaveBeenCalledWith([])\n    await wrapper.vm.$nextTick()\n\n    // Add 'foo'\n    input.trigger('focus')\n    element.value = 'foo'\n    input.trigger('input')\n    await wrapper.vm.$nextTick()\n    input.trigger('keydown.enter')\n    await wrapper.vm.$nextTick()\n\n    expect(change).toHaveBeenLastCalledWith(['foo'])\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/12351\n  it('should correctly handle duplicate items', async () => {\n    const { wrapper, change } = createMultipleCombobox({\n      chips: true,\n      multiple: true,\n      items: [\n        { text: 'foo', value: 'foo' },\n        { text: 'bar', value: 'bar' },\n      ],\n      value: [\n        { text: 'foo', value: 'foo' },\n      ],\n    })\n\n    const input = wrapper.find('input')\n    const element = input.element as HTMLInputElement\n\n    input.trigger('focus')\n    element.value = 'foo'\n    input.trigger('input')\n    await wrapper.vm.$nextTick()\n\n    input.trigger('keydown.tab')\n    await wrapper.vm.$nextTick()\n\n    expect(change).toHaveBeenLastCalledWith([{ text: 'foo', value: 'foo' }])\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/6364\n  it('should not add duplicate chip after edit', async () => {\n    const { wrapper, change } = createMultipleCombobox({\n      chips: true,\n      multiple: true,\n      clearable: true,\n      items: ['foo', 'bar'],\n      value: ['foo', 'bar'],\n    })\n\n    const input = wrapper.find('input')\n    const element = input.element as HTMLInputElement\n\n    // Dbl click chip at index 1\n    const chip = wrapper.findAll('.v-chip').at(1)\n    chip.trigger('dblclick')\n    expect(wrapper.vm.editingIndex).toBe(1)\n    expect(wrapper.vm.internalSearch).toBe('bar')\n\n    // Add a duplicate value - 'foo'\n    input.trigger('focus')\n    element.value = 'foo'\n    input.trigger('input')\n    await wrapper.vm.$nextTick()\n    input.trigger('keydown.enter')\n    await wrapper.vm.$nextTick()\n\n    expect(change).toHaveBeenLastCalledWith(['bar', 'foo'])\n  })\n\n  // example 1 in https://github.com/vuetifyjs/vuetify/issues/14194\n  it('should not point to a result that does not exist as in example 1', async () => {\n    const { wrapper } = createMultipleCombobox({\n      items: ['a', 'aa', 'aaa', 'bar'],\n    })\n\n    const input = wrapper.find('input')\n    const element = input.element as HTMLInputElement\n\n    const listIndexUpdate = jest.fn()\n    wrapper.vm.$on('update:list-index', listIndexUpdate)\n\n    input.trigger('focus')\n    await wrapper.vm.$nextTick()\n    element.value = 'a'\n    input.trigger('input')\n    await wrapper.vm.$nextTick()\n\n    input.trigger('keydown.down')\n    await wrapper.vm.$nextTick()\n\n    input.trigger('keydown.down')\n    await wrapper.vm.$nextTick()\n\n    input.trigger('keydown.down')\n    await wrapper.vm.$nextTick()\n\n    input.trigger('keydown.down')\n    await wrapper.vm.$nextTick()\n\n    element.value = 'aa'\n    input.trigger('input')\n    await wrapper.vm.$nextTick()\n    expect(listIndexUpdate.mock.calls.length === 6).toBe(true)\n    expect(listIndexUpdate.mock.calls[0][0]).toBe(-1)\n    expect(listIndexUpdate.mock.calls[1][0]).toBe(0)\n    expect(listIndexUpdate.mock.calls[2][0]).toBe(1)\n    expect(listIndexUpdate.mock.calls[3][0]).toBe(2)\n    expect(listIndexUpdate.mock.calls[4][0]).toBe(3)\n    expect(listIndexUpdate.mock.calls[5][0]).toBe(-1)\n  })\n\n  // example 2 in https://github.com/vuetifyjs/vuetify/issues/14194\n  it('should not change selection on search input as in example 2', async () => {\n    const { wrapper } = createMultipleCombobox({\n      items: ['a', 'aa', 'aaa', 'bar'],\n    })\n\n    const input = wrapper.find('input')\n    const element = input.element as HTMLInputElement\n\n    const listIndexUpdate = jest.fn()\n    wrapper.vm.$on('update:list-index', listIndexUpdate)\n\n    input.trigger('focus')\n    await wrapper.vm.$nextTick()\n    element.value = 'a'\n    input.trigger('input')\n    await wrapper.vm.$nextTick()\n\n    input.trigger('keydown.down')\n    await wrapper.vm.$nextTick()\n\n    input.trigger('keydown.down')\n    await wrapper.vm.$nextTick()\n\n    input.trigger('keydown.down')\n    await wrapper.vm.$nextTick()\n\n    element.value = 'aa'\n    input.trigger('input')\n    await wrapper.vm.$nextTick()\n\n    expect(listIndexUpdate.mock.calls.length === 5).toBe(true)\n    expect(listIndexUpdate.mock.calls[0][0]).toBe(-1)\n    expect(listIndexUpdate.mock.calls[1][0]).toBe(0)\n    expect(listIndexUpdate.mock.calls[2][0]).toBe(1)\n    expect(listIndexUpdate.mock.calls[3][0]).toBe(2)\n    expect(listIndexUpdate.mock.calls[4][0]).toBe(1)\n  })\n\n  // example 3 in https://github.com/vuetifyjs/vuetify/issues/14194\n  it('should not point to a result that does not exist as in example 3', async () => {\n    const { wrapper } = createMultipleCombobox({\n      items: ['a', 'aa', 'aaa', 'bar'],\n    })\n\n    const input = wrapper.find('input')\n    const element = input.element as HTMLInputElement\n\n    const listIndexUpdate = jest.fn()\n    wrapper.vm.$on('update:list-index', listIndexUpdate)\n\n    input.trigger('focus')\n    await wrapper.vm.$nextTick()\n    element.value = 'a'\n    input.trigger('input')\n    await wrapper.vm.$nextTick()\n\n    input.trigger('keydown.down')\n    await wrapper.vm.$nextTick()\n\n    element.value = 'aaaa'\n    input.trigger('input')\n    await wrapper.vm.$nextTick()\n\n    expect(listIndexUpdate.mock.calls.length === 3).toBe(true)\n    expect(listIndexUpdate.mock.calls[0][0]).toBe(-1)\n    expect(listIndexUpdate.mock.calls[1][0]).toBe(0)\n    expect(listIndexUpdate.mock.calls[2][0]).toBe(-1)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VCombobox/__tests__/VCombobox.spec.browser.tsx",
    "content": "// Components\nimport { VCombobox } from '../VCombobox'\nimport { VForm } from '@/components/VForm'\n\n// Utilities\nimport { render, screen, showcase, userEvent, waitAnimationFrame, waitIdle } from '@test'\nimport { commands } from 'vitest/browser'\nimport { cloneVNode, ref } from 'vue'\n\nconst variants = ['underlined', 'outlined', 'filled', 'solo', 'plain'] as const\nconst densities = ['default', 'comfortable', 'compact'] as const\nconst items = ['California', 'Colorado', 'Florida', 'Georgia', 'Texas', 'Wyoming'] as const\n\nconst stories = Object.fromEntries(Object.entries({\n  'Default input': <VCombobox />,\n  Disabled: <VCombobox items={ items } disabled />,\n  Affixes: <VCombobox items={ items } prefix=\"prefix\" suffix=\"suffix\" />,\n  'Prepend/append': <VCombobox items={ items } prependIcon=\"$vuetify\" appendIcon=\"$vuetify\" />,\n  'Prepend/append inner': <VCombobox items={ items } prependInnerIcon=\"$vuetify\" appendInnerIcon=\"$vuetify\" />,\n  Placeholder: <VCombobox items={ items } placeholder=\"placeholder\" persistentPlaceholder />,\n}).map(([k, v]) => [k, (\n  <div class=\"d-flex flex-column flex-grow-1\">\n    { variants.map(variant => (\n      densities.map(density => (\n        <div class=\"d-flex align-start\" style=\"gap: 0.4rem; height: 100px;\">\n          { cloneVNode(v, { variant, density, label: `${variant} ${density}` }) }\n          { cloneVNode(v, { variant, density, label: `with value`, modelValue: ['California'] }) }\n          { cloneVNode(v, { variant, density, label: `chips`, chips: true, modelValue: ['California'] }) }\n          <VCombobox\n            variant={ variant }\n            density={ density }\n            modelValue={['California']}\n            label=\"selection slot\"\n            { ...v.props }\n          >{{\n            selection: ({ item }) => {\n              return item\n            },\n          }}\n          </VCombobox>\n        </div>\n      ))\n    )).flat()}\n  </div>\n)]))\n\ndescribe('VCombobox', () => {\n  describe('closableChips', () => {\n    it('should close only first chip', async () => {\n      const items = [\n        'Item 1',\n        'Item 2',\n        'Item 3',\n        'Item 4',\n      ]\n\n      const selectedItems = [\n        'Item 1',\n        'Item 2',\n        'Item 3',\n      ]\n\n      render(() => (\n        <VCombobox items={ items } modelValue={ selectedItems } multiple closableChips chips />\n      ))\n\n      await userEvent.click(screen.getAllByTestId('close-chip')[0])\n      await expect.poll(() => screen.getAllByCSS('.v-chip')).toHaveLength(2)\n    })\n  })\n\n  describe('complex objects', () => {\n    it('single', async () => {\n      const items = [\n        { title: 'Item 1', value: 'item1' },\n        { title: 'Item 2', value: 'item2' },\n        { title: 'Item 3', value: 'item3' },\n        { title: 'Item 4', value: 'item4' },\n      ]\n      const model = ref()\n      const search = ref()\n      const updateModel = vi.fn(val => model.value = val)\n      const updateSearch = vi.fn(val => search.value = val)\n\n      const { element } = render(() => (\n        <VCombobox\n          modelValue={ model.value }\n          search={ search.value }\n          onUpdate:modelValue={ updateModel }\n          onUpdate:search={ updateSearch }\n          items={ items }\n        />\n      ))\n\n      await userEvent.click(element)\n      await commands.waitStable('.v-list')\n      await userEvent.click((await screen.findAllByRole('option'))[0])\n      expect(model.value).toStrictEqual(items[0])\n      await expect.poll(() => search.value).toBe(items[0].title)\n      expect(screen.getByCSS('input')).toHaveValue(items[0].title)\n      expect(screen.getByCSS('.v-combobox__selection')).toHaveTextContent(items[0].title)\n\n      await userEvent.click(element)\n      await userEvent.keyboard('{ControlOrMeta>}a{/ControlOrMeta}{Backspace}')\n      await userEvent.keyboard('Item 2')\n      expect(model.value).toBe('Item 2')\n      expect(search.value).toBe('Item 2')\n      expect(screen.getByCSS('input')).toHaveValue('Item 2')\n      expect(screen.getByCSS('.v-combobox__selection')).toHaveTextContent('Item 2')\n\n      await userEvent.click(element)\n      await userEvent.keyboard('{ControlOrMeta>}a{/ControlOrMeta}{Backspace}')\n      await userEvent.keyboard('item3')\n      expect(model.value).toBe('item3')\n      expect(search.value).toBe('item3')\n      expect(screen.getByCSS('input')).toHaveValue('item3')\n      expect(screen.getByCSS('.v-combobox__selection')).toHaveTextContent('item3')\n    })\n\n    it('multiple', async () => {\n      const items = [\n        { title: 'Item 1', value: 'item1' },\n        { title: 'Item 2', value: 'item2' },\n        { title: 'Item 3', value: 'item3' },\n        { title: 'Item 4', value: 'item4' },\n      ]\n      const model = ref<(string | typeof items[number])[]>([])\n      const search = ref()\n      const updateModel = vi.fn(val => model.value = val)\n      const updateSearch = vi.fn(val => search.value = val)\n\n      const { element } = render(() => (\n        <VCombobox\n          modelValue={ model.value }\n          search={ search.value }\n          onUpdate:modelValue={ updateModel }\n          onUpdate:search={ updateSearch }\n          multiple\n          items={ items }\n        />\n      ))\n\n      const input = screen.getByCSS('input')\n\n      await userEvent.click(element)\n      await commands.waitStable('.v-list')\n      await userEvent.click(screen.getAllByRole('option')[0])\n      expect(model.value).toStrictEqual([items[0]])\n      expect(search.value).toBeUndefined()\n      expect(input).toHaveValue('')\n      expect(screen.getByCSS('.v-combobox__selection')).toHaveTextContent(items[0].title)\n\n      await userEvent.click(element)\n      await userEvent.keyboard('Item 2{tab}')\n      expect(model.value).toStrictEqual([items[0], 'Item 2'])\n      expect(search.value).toBe('')\n      expect(input).toHaveValue('')\n      expect(screen.getAllByCSS('.v-combobox__selection').at(-1)).toHaveTextContent('Item 2')\n\n      await userEvent.click(element)\n      await userEvent.keyboard('item3{tab}')\n      expect(model.value).toStrictEqual([items[0], 'Item 2', 'item3'])\n      expect(search.value).toBe('')\n      expect(input).toHaveValue('')\n      expect(screen.getAllByCSS('.v-combobox__selection').at(-1)).toHaveTextContent('item3')\n    })\n  })\n\n  describe('search', () => {\n    it('should filter items', async () => {\n      const items = [\n        'Item 1',\n        'Item 1a',\n        'Item 2',\n        'Item 2a',\n      ]\n\n      const { element } = render(() => (\n        <VCombobox items={ items } />\n      ))\n\n      await userEvent.click(element)\n      await userEvent.keyboard('Item')\n      await expect(screen.findAllByRole('option')).resolves.toHaveLength(4)\n      await userEvent.keyboard('{ControlOrMeta>}a{/ControlOrMeta}{Backspace}')\n      await userEvent.keyboard('Item 1')\n      await expect(screen.findAllByRole('option')).resolves.toHaveLength(2)\n      await userEvent.keyboard('{ControlOrMeta>}a{/ControlOrMeta}{Backspace}')\n      await userEvent.keyboard('Item 3')\n      expect(screen.queryAllByRole('option')).toHaveLength(0)\n    })\n\n    it('should filter items when using multiple', async () => {\n      const items = [\n        'Item 1',\n        'Item 1a',\n        'Item 2',\n        'Item 2a',\n      ]\n\n      const { element } = render(() => (\n        <VCombobox items={ items } multiple />\n      ))\n\n      await userEvent.click(element)\n      await userEvent.keyboard('Item')\n      await expect(screen.findAllByRole('option')).resolves.toHaveLength(4)\n      await userEvent.keyboard('{ControlOrMeta>}a{/ControlOrMeta}{Backspace}')\n      await userEvent.keyboard('Item 1')\n      await expect(screen.findAllByRole('option')).resolves.toHaveLength(2)\n      await userEvent.keyboard('{ControlOrMeta>}a{/ControlOrMeta}{Backspace}')\n      await userEvent.keyboard('Item 3')\n      expect(screen.queryAllByRole('option')).toHaveLength(0)\n    })\n\n    it('should filter with custom item shape', async () => {\n      const items = [\n        {\n          id: 1,\n          name: 'Test1',\n        },\n        {\n          id: 2,\n          name: 'Antonsen PK',\n        },\n      ]\n\n      const { element } = render(() => (\n        <VCombobox\n          items={ items }\n          itemValue=\"id\"\n          itemTitle=\"name\"\n        />\n      ))\n\n      await userEvent.click(element)\n      await userEvent.keyboard('test')\n      await expect(screen.findByRole('option')).resolves.toHaveTextContent('Test1')\n\n      await userEvent.keyboard('{ControlOrMeta>}a{/ControlOrMeta}{Backspace}')\n      await userEvent.keyboard('antonsen')\n      await expect(screen.findByRole('option')).resolves.toHaveTextContent('Antonsen PK')\n    })\n  })\n\n  describe('prefilled data', () => {\n    it('should work with array of strings when using multiple', async () => {\n      const items = ref(['California', 'Colorado', 'Florida'])\n\n      const selectedItems = ref(['California', 'Colorado'])\n\n      const { element } = render(() => (\n        <VCombobox\n          v-model={ selectedItems.value }\n          items={ items.value }\n          multiple\n          chips\n          closableChips\n        />\n      ))\n\n      const input = screen.getByCSS('input')\n\n      await userEvent.click(element)\n\n      await expect(screen.findAllByRole('option', { selected: true })).resolves.toHaveLength(2)\n      expect(screen.getAllByCSS('.v-chip')).toHaveLength(2)\n\n      await userEvent.click(screen.getAllByTestId('close-chip')[0])\n      await expect(input).toBeVisible()\n      expect(screen.getAllByCSS('.v-chip')).toHaveLength(1)\n      expect(selectedItems.value).toStrictEqual(['Colorado'])\n    })\n\n    it('should work with objects when using multiple', async () => {\n      const items = ref([\n        {\n          title: 'Item 1',\n          value: 'item1',\n        },\n        {\n          title: 'Item 2',\n          value: 'item2',\n        },\n        {\n          title: 'Item 3',\n          value: 'item3',\n        },\n      ])\n\n      const selectedItems = ref(\n        [\n          {\n            title: 'Item 1',\n            value: 'item1',\n          },\n          {\n            title: 'Item 2',\n            value: 'item2',\n          },\n        ]\n      )\n\n      const { element } = render(() => (\n        <VCombobox\n          v-model={ selectedItems.value }\n          items={ items.value }\n          multiple\n          chips\n          closableChips\n          returnObject\n        />\n      ))\n\n      const input = screen.getByCSS('input')\n\n      await userEvent.click(element)\n\n      await expect(screen.findAllByRole('option', { selected: true })).resolves.toHaveLength(2)\n      expect(screen.getAllByCSS('.v-chip')).toHaveLength(2)\n\n      await userEvent.click(screen.getAllByTestId('close-chip')[0])\n      await expect(input).toBeVisible()\n      expect(screen.getAllByCSS('.v-chip')).toHaveLength(1)\n      expect(selectedItems.value).toStrictEqual([{\n        title: 'Item 2',\n        value: 'item2',\n      }])\n    })\n\n    it('should work with objects when using multiple and item-value', async () => {\n      const items = ref([\n        {\n          text: 'Item 1',\n          id: 'item1',\n        },\n        {\n          text: 'Item 2',\n          id: 'item2',\n        },\n        {\n          text: 'Item 3',\n          id: 'item3',\n        },\n      ])\n\n      const selectedItems = ref(\n        [\n          {\n            text: 'Item 1',\n            id: 'item1',\n          },\n          {\n            text: 'Item 2',\n            id: 'item2',\n          },\n        ]\n      )\n\n      const { element } = render(() => (\n        <VCombobox\n          v-model={ selectedItems.value }\n          items={ items.value }\n          multiple\n          itemTitle=\"text\"\n          itemValue=\"value\"\n          returnObject\n        />\n      ))\n\n      await userEvent.click(element)\n      await commands.waitStable('.v-list')\n\n      const options = await screen.findAllByRole('option', { selected: true })\n      expect(options).toHaveLength(2)\n      const inputField = screen.getByCSS('.v-field')\n      expect(inputField).toHaveTextContent('Item 1')\n      expect(inputField).toHaveTextContent('Item 2')\n\n      await userEvent.click(options[0])\n\n      expect(selectedItems.value).toStrictEqual([{\n        text: 'Item 2',\n        id: 'item2',\n      }])\n    })\n  })\n\n  describe('readonly', () => {\n    it('should not be clickable when in readonly', async () => {\n      const items = ['Item 1', 'Item 2', 'Item 3', 'Item 4']\n\n      const selectedItems = 'Item 1'\n\n      const { element } = render(() => (\n        <VCombobox\n          items={ items }\n          modelValue={ selectedItems }\n          readonly\n        />\n      ))\n\n      await userEvent.click(element)\n\n      expect(screen.queryAllByRole('option')).toHaveLength(0)\n      expect(screen.queryAllByRole('listbox')).toHaveLength(0)\n\n      await userEvent.keyboard('{ArrowDown}')\n      expect(screen.queryAllByRole('option')).toHaveLength(0)\n      expect(screen.queryAllByRole('listbox')).toHaveLength(0)\n    })\n\n    it('should not be clickable when in readonly form', async () => {\n      const items = ['Item 1', 'Item 2', 'Item 3', 'Item 4']\n\n      const selectedItems = 'Item 1'\n\n      const { element } = render(() => (\n        <VForm readonly>\n          <VCombobox\n            items={ items }\n            modelValue={ selectedItems }\n            readonly\n          />\n        </VForm>\n      ))\n\n      await userEvent.click(element)\n\n      expect(screen.queryAllByRole('option')).toHaveLength(0)\n      expect(screen.queryAllByRole('listbox')).toHaveLength(0)\n\n      await userEvent.keyboard('{ArrowDown}')\n      expect(screen.queryAllByRole('option')).toHaveLength(0)\n      expect(screen.queryAllByRole('listbox')).toHaveLength(0)\n    })\n  })\n\n  describe('hide-selected', () => {\n    it('should hide selected item(s)', async () => {\n      const items = [\n        'Item 1',\n        'Item 2',\n        'Item 3',\n        'Item 4',\n      ]\n\n      const selectedItems = [\n        'Item 1',\n        'Item 2',\n      ]\n\n      const { element } = render(() => (\n        <VCombobox items={ items } modelValue={ selectedItems } multiple hideSelected />\n      ))\n\n      await userEvent.click(element)\n\n      const listItems = await screen.findAllByRole('option')\n      expect(listItems).toHaveLength(2)\n      expect(listItems[0]).toHaveTextContent('Item 3')\n      expect(listItems[1]).toHaveTextContent('Item 4')\n    })\n  })\n\n  // // https://github.com/vuetifyjs/vuetify/issues/17120\n  it('should display 0 when selected', async () => {\n    const items = [0, 1, 2, 3, 4]\n\n    const selectedItems = ref(undefined)\n\n    const { element } = render(() => (\n      <VCombobox\n        items={ items }\n        v-model={ selectedItems.value }\n      />\n    ))\n\n    await userEvent.click(element)\n    await commands.waitStable('.v-list')\n\n    await userEvent.click(screen.getAllByRole('option')[0])\n\n    await expect.poll(() => screen.getByCSS('input')).toHaveValue('0')\n  })\n\n  it('should conditionally show placeholder', async () => {\n    const { rerender } = render(VCombobox, {\n      props: { placeholder: 'Placeholder' },\n    })\n\n    const input = screen.getByCSS('input')\n    await expect.element(input).toHaveAttribute('placeholder', 'Placeholder')\n\n    await rerender({ label: 'Label' })\n    await expect.element(input).toBeVisible()\n    expect(Number(window.getComputedStyle(input, '::placeholder').opacity)).toBe(0)\n\n    await userEvent.click(input)\n    await expect.element(input).toHaveAttribute('placeholder', 'Placeholder')\n    await expect.element(input).toBeVisible()\n    expect(Number(window.getComputedStyle(input, '::placeholder').opacity)).toBeGreaterThan(0.2)\n\n    await userEvent.tab()\n    await rerender({ persistentPlaceholder: true })\n    await expect.element(input).toHaveAttribute('placeholder', 'Placeholder')\n    await expect.element(input).toBeVisible()\n    expect(Number(window.getComputedStyle(input, '::placeholder').opacity)).toBeGreaterThan(0.2)\n\n    await rerender({ modelValue: 'Foobar' })\n    await expect.element(input).not.toHaveAttribute('placeholder')\n\n    await rerender({ multiple: true, modelValue: ['Foobar'] })\n    await expect.element(input).not.toHaveAttribute('placeholder')\n  })\n\n  it('should keep TextField focused while selecting items from open menu', async () => {\n    const { element } = render(() => (\n      <VCombobox\n        multiple\n        items={['California', 'Colorado', 'Florida', 'Georgia', 'Texas', 'Wyoming']}\n      />\n    ))\n\n    await userEvent.click(element)\n\n    await userEvent.keyboard('{ArrowDown}')\n    await userEvent.keyboard('{ArrowDown}')\n    await userEvent.keyboard('{ArrowDown}')\n\n    expect(screen.getByCSS('.v-field')).toHaveClass('v-field--focused')\n  })\n\n  it('should not open menu when closing a chip', async () => {\n    const { element } = render(() => (\n      <VCombobox\n        chips\n        closableChips\n        items={['foo', 'bar']}\n        label=\"Select\"\n        modelValue={['foo', 'bar']}\n        multiple\n      />\n    ))\n\n    expect(screen.queryAllByRole('listbox')).toHaveLength(0)\n\n    await userEvent.click(screen.getAllByTestId('close-chip')[1])\n    expect(screen.queryAllByRole('listbox')).toHaveLength(0)\n\n    await userEvent.click(screen.getByTestId('close-chip'))\n    expect(screen.queryAllByRole('listbox')).toHaveLength(0)\n\n    await userEvent.click(element)\n    await commands.waitStable('.v-list')\n\n    expect(screen.queryAllByRole('listbox')).toHaveLength(1)\n    await userEvent.keyboard('{Escape}')\n    await expect.poll(() => screen.queryAllByRole('listbox')).toHaveLength(0)\n  })\n\n  describe('auto-select-first', () => {\n    it('should auto-select-first item when pressing enter', async () => {\n      const selectedItems = ref([])\n\n      const { element } = render(() => (\n        <VCombobox\n          v-model={ selectedItems.value }\n          items={['California', 'Colorado', 'Florida', 'Georgia', 'Texas', 'Wyoming']}\n          multiple\n          autoSelectFirst\n        />\n      ))\n\n      await userEvent.click(element)\n      await commands.waitStable('.v-list')\n\n      expect(screen.getAllByRole('option')).toHaveLength(6)\n\n      await userEvent.keyboard('Cal')\n      await expect(screen.findByRole('option')).resolves.toHaveClass('v-list-item--active')\n      await userEvent.keyboard('{Enter}')\n      await expect.poll(() => screen.queryAllByRole('option')).toHaveLength(6)\n      expect(selectedItems.value).toStrictEqual(['California'])\n    })\n\n    it('should auto-select-first item when pressing tab', async () => {\n      const selectedItems = ref([])\n\n      const { element } = render(() => (\n        <VCombobox\n          v-model={ selectedItems.value }\n          items={['California', 'Colorado', 'Florida', 'Georgia', 'Texas', 'Wyoming']}\n          multiple\n          autoSelectFirst\n        />\n      ))\n\n      await userEvent.click(element)\n      await commands.waitStable('.v-list')\n\n      expect(screen.getAllByRole('option')).toHaveLength(6)\n\n      await userEvent.keyboard('Cal')\n      await expect(screen.findByRole('option')).resolves.toHaveClass('v-list-item--active')\n      await userEvent.keyboard('{Tab}')\n      await expect.poll(() => screen.queryAllByRole('option')).toHaveLength(0)\n      expect(selectedItems.value).toStrictEqual(['California'])\n    })\n\n    it('should not auto-select-first item when blur', async () => {\n      const selectedItems = ref([])\n\n      const { element } = render(() => (\n        <VCombobox\n          v-model={ selectedItems.value }\n          items={['California', 'Colorado', 'Florida', 'Georgia', 'Texas', 'Wyoming']}\n          multiple\n          autoSelectFirst\n        />\n      ))\n\n      await userEvent.click(element)\n      await commands.waitStable('.v-list')\n\n      expect(screen.getAllByRole('option')).toHaveLength(6)\n\n      await userEvent.keyboard('Cal')\n      await expect(screen.findByRole('option')).resolves.toHaveClass('v-list-item--active')\n      await userEvent.click(document.body)\n      await expect.poll(() => screen.queryAllByRole('option')).toHaveLength(0)\n      expect(selectedItems.value).toStrictEqual(['Cal'])\n    })\n  })\n\n  it(`doesn't add duplicate values`, async () => {\n    const selection = ref([])\n    const { element } = render(() => (\n      <VCombobox v-model={ selection.value } multiple />\n    ))\n\n    await userEvent.click(element)\n    await userEvent.keyboard('foo{Enter}')\n    await userEvent.keyboard('bar{Enter}')\n    expect(selection.value).toHaveLength(2)\n\n    await userEvent.keyboard('foo{Enter}')\n    expect(selection.value).toHaveLength(2)\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/18796\n  it('should allow deleting selection via closable-chips', async () => {\n    const selectedItem = ref('California')\n\n    render(() => (\n      <VCombobox\n        chips\n        v-model={ selectedItem.value }\n        closableChips\n        items={['California', 'Colorado', 'Florida', 'Georgia', 'Texas', 'Wyoming']}\n      />\n    ))\n\n    await userEvent.click(screen.getByTestId('close-chip'))\n    expect(selectedItem.value).toBeNull()\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/18556\n  it('should show menu if focused and items are added', async () => {\n    const { rerender } = render(VCombobox)\n\n    await userEvent.keyboard('{Tab}')\n    await waitAnimationFrame()\n    expect(screen.queryByRole('listbox')).toBeNull()\n\n    await rerender({ items: ['Foo', 'Bar'] })\n    await expect(screen.findByRole('listbox')).resolves.toBeVisible()\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/19346\n  it('should not show menu when focused and existing non-empty items are changed', async () => {\n    const { element, rerender } = render(VCombobox, {\n      props: { items: ['Foo', 'Bar'] },\n    })\n\n    await userEvent.click(element)\n    await commands.waitStable('.v-list')\n    await expect(screen.findByRole('listbox')).resolves.toBeVisible()\n\n    await userEvent.click(screen.getAllByRole('option')[0])\n    await rerender({ items: ['Foo', 'Bar', 'test'] })\n    await waitIdle()\n    await expect.poll(() => screen.queryByRole('listbox')).toBeNull()\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/17573\n  // When using selection slot or chips, input displayed next to chip/selection slot should be always empty\n  it('should always have empty input value when it is unfocused and when using selection slot or chips', async () => {\n    const items = ['Item 1', 'Item 2', 'Item 3', 'Item 4']\n    const selectedItem = ref('Item 1')\n\n    const { element, getByCSS } = render(() => (\n      <VCombobox\n        items={ items }\n        chips\n        v-model={ selectedItem.value }\n      />\n    ))\n\n    await userEvent.click(element)\n    const input = getByCSS('input')\n    expect(input).toHaveValue('')\n\n    // Blur input with a custom search input value\n    await userEvent.keyboard('test')\n    input.blur()\n    await expect.poll(() => selectedItem.value).toBe('test')\n    expect(input).toHaveValue('')\n\n    // Press enter key with a custom search input value\n    await userEvent.click(element)\n    await userEvent.keyboard('test 2{Enter}')\n    await expect.poll(() => selectedItem.value).toBe('test 2')\n    expect(input).toHaveValue('')\n\n    // Search existing item and click to select\n    await userEvent.click(element)\n    expect(input).toHaveValue('')\n    await userEvent.keyboard('Item 1')\n    await commands.waitStable('.v-list')\n    await userEvent.click(await screen.findByRole('option'))\n    await expect.poll(() => selectedItem.value).toBe('Item 1')\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/19319\n  it('should respect return-object when blurring', async () => {\n    const items = [\n      { title: 'Item 1', value: 'item1' },\n      { title: 'Item 2', value: 'item2' },\n      { title: 'Item 3', value: 'item3' },\n      { title: 'Item 4', value: 'item4' },\n    ]\n    const model = ref()\n    const search = ref()\n\n    const { element } = render(() => (\n      <VCombobox\n        search={ search.value }\n        v-model={ model.value }\n        items={ items }\n      />\n    ))\n\n    await userEvent.click(element)\n    await commands.waitStable('.v-list')\n    await userEvent.click(screen.getAllByRole('option')[0])\n    await expect.poll(() => model.value).toStrictEqual({ title: 'Item 1', value: 'item1' })\n\n    await userEvent.click(document.body)\n    expect(model.value).toStrictEqual({ title: 'Item 1', value: 'item1' })\n  })\n\n  it('should not fire @update:focus twice when clicking bottom of input', async () => {\n    const onFocus = vi.fn()\n    const { element } = render(() => (\n      <VCombobox onUpdate:focused={ onFocus } />\n    ))\n\n    await userEvent.click(element, { position: { x: 10, y: 55 } })\n\n    expect(onFocus).toHaveBeenCalledTimes(1)\n  })\n\n  it.each([\n    { delimiters: [','], text: 'abc,foo, baz', expected: ['abc', 'foo', 'baz'] },\n    { delimiters: [':'], text: '012:2,32:0:1', expected: ['012', '2,32', '0', '1'] },\n    { delimiters: [':', '.', '-'], text: '(1) 231:13 - 123.', expected: ['(1) 231', '13', '123'] },\n  ])('should ingest new items when a delimited text is pasted', async ({ delimiters, text, expected }) => {\n    const model = ref(null)\n    render(() => (\n      <VCombobox\n        v-model={ model.value }\n        delimiters={ delimiters }\n        multiple\n      />\n    ))\n    await userEvent.tab()\n    const lock = await commands.getLock()\n    await navigator.clipboard.writeText(text)\n    await userEvent.paste()\n    await commands.releaseLock(lock)\n    expect(model.value).toEqual(expected)\n  })\n\n  it('should show only matching items when reopening the menu if alwaysFilter is true', async () => {\n    const { element } = render(() => (\n      <VCombobox alwaysFilter items={['California', 'Colorado', 'Florida', 'Georgia', 'Texas', 'Wyoming']} />\n    ))\n\n    await userEvent.click(element)\n    await userEvent.keyboard('c')\n    await expect(screen.findAllByRole('option')).resolves.toHaveLength(2)\n    await userEvent.keyboard('al')\n    await expect(screen.findAllByRole('option')).resolves.toHaveLength(1)\n    await userEvent.click(document.body)\n    await expect.poll(() => screen.queryAllByRole('option')).toHaveLength(0)\n    await userEvent.click(element)\n    await expect.poll(() => screen.queryAllByRole('option')).toHaveLength(1)\n  })\n\n  it('should create new items when pasting with line break characters', async () => {\n    const model = ref(null)\n    render(() => (\n      <VCombobox\n        v-model={ model.value }\n        multiple\n        delimiters={[',']}\n      />\n    ))\n\n    await userEvent.tab()\n    const lock = await commands.getLock()\n    await navigator.clipboard.writeText('foo,\\nbar')\n    await userEvent.paste()\n    await commands.releaseLock(lock)\n    expect(model.value).toEqual(['foo', 'bar'])\n  })\n\n  describe('menu-header and menu-footer slots', () => {\n    it('should render menu-header and menu-footer slots', async () => {\n      const { element } = render(() => (\n        <VCombobox menu items={['Item #1', 'Item #2']}>\n          {{\n            'menu-header': () => (\n              <div data-testid=\"header-content\">My Header</div>\n            ),\n            'menu-footer': () => (\n              <div data-testid=\"footer-content\">My Footer</div>\n            ),\n          }}\n        </VCombobox>\n      ))\n\n      await userEvent.click(element)\n      await commands.waitStable('.v-list')\n\n      expect(screen.getByTestId('header-content')).toHaveTextContent('My Header')\n      expect(screen.getByTestId('footer-content')).toHaveTextContent('My Footer')\n    })\n\n    it('should navigate between header, list, and footer with Tab', async () => {\n      const { element } = render(() => (\n        <VCombobox menu items={['Item #1', 'Item #2', 'Item #3']}>\n          {{\n            'menu-header': () => (\n              <div>\n                <button data-testid=\"header-btn\">Header Button</button>\n              </div>\n            ),\n            'menu-footer': () => (\n              <div>\n                <button data-testid=\"footer-btn\">Footer Button</button>\n              </div>\n            ),\n          }}\n        </VCombobox>\n      ))\n\n      await userEvent.click(element)\n      await commands.waitStable('.v-list')\n\n      // Navigate to list first\n      await userEvent.keyboard('{ArrowDown}')\n      await expect.poll(() => screen.getByTestId('header-btn')).toHaveFocus()\n\n      // Tab to list\n      await userEvent.keyboard('{Tab}')\n      expect(screen.getAllByRole('option').at(0)).toHaveFocus()\n\n      // Tab to footer\n      await userEvent.keyboard('{Tab}')\n      expect(screen.getByTestId('footer-btn')).toHaveFocus()\n\n      // Shift+Tab back to list\n      await userEvent.keyboard('{Shift>}{Tab}{/Shift}')\n      await expect.poll(() => screen.getAllByRole('option').at(0)).toHaveFocus()\n\n      // Shift+Tab back to header\n      await userEvent.keyboard('{Shift>}{Tab}{/Shift}')\n      expect(screen.getByTestId('header-btn')).toHaveFocus()\n    })\n  })\n\n  showcase({ stories })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VCombobox/__tests__/VCombobox.spec.ts",
    "content": "// @ts-nocheck\n/* eslint-disable */\n\n// Components\n// import VCombobox from '../VCombobox'\n\n// Utilities\nimport {\n  mount,\n  Wrapper,\n} from '@vue/test-utils'\n\ndescribe.skip('VCombobox.ts', () => {\n  type Instance = InstanceType<typeof VCombobox>\n  let mountFunction: (options?: object) => Wrapper<Instance>\n\n  beforeEach(() => {\n    document.body.setAttribute('data-app', 'true')\n\n    mountFunction = (options = {}) => {\n      return mount(VCombobox, {\n        // https://github.com/vuejs/vue-test-utils/issues/1130\n        sync: false,\n        mocks: {\n          $vuetify: {\n            lang: {\n              t: (val: string) => val,\n            },\n            theme: {\n              dark: false,\n            },\n          },\n        },\n        ...options,\n      })\n    }\n  })\n\n  // TODO: this fails without sync, nextTick doesn't help\n  // https://github.com/vuejs/vue-test-utils/issues/1130\n  it.skip('should evaluate the range of an integer', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: 11,\n      },\n    })\n\n    await wrapper.vm.$nextTick()\n    expect(wrapper.vm.currentRange).toBe(2)\n\n    wrapper.setProps({ value: 0 })\n    await wrapper.vm.$nextTick()\n    expect(wrapper.vm.currentRange).toBe(1)\n  })\n\n  it('should not use search input when blurring', async () => {\n    const wrapper = mountFunction({\n      attachToDocument: true,\n      propsData: {\n        eager: true,\n        items: [1, 12],\n      },\n    })\n\n    const event = jest.fn()\n    wrapper.vm.$on('input', event)\n\n    const input = wrapper.find('input')\n    input.trigger('focus')\n    await wrapper.vm.$nextTick()\n\n    wrapper.setProps({ searchInput: '1' })\n    await wrapper.vm.$nextTick()\n\n    expect(wrapper.vm.internalSearch).toBe('1')\n\n    const list = wrapper.findAll('.v-list-item').at(1)\n    list.trigger('click')\n    await wrapper.vm.$nextTick()\n    expect(event).toHaveBeenCalledWith(12)\n  })\n\n  it('should not use search input if an option is selected from the menu', async () => {\n    const item = { value: 123, text: 'Foo' }\n    const wrapper = mountFunction({\n      propsData: {\n        items: [item],\n      },\n    })\n\n    const event = jest.fn()\n    wrapper.vm.$on('input', event)\n\n    wrapper.setData({ isMenuActive: true })\n    await wrapper.vm.$nextTick()\n\n    wrapper.vm.selectItem(item)\n    await wrapper.vm.$nextTick()\n\n    wrapper.setData({ isMenuActive: false })\n    await wrapper.vm.$nextTick()\n\n    expect(event).toHaveBeenCalledWith(item)\n  })\n\n  it('should not populate search field if value is falsy', async () => {\n    const wrapper = mountFunction()\n\n    const event = jest.fn()\n    wrapper.vm.$on('input', event)\n\n    wrapper.setData({ isMenuActive: true })\n    await wrapper.vm.$nextTick()\n\n    wrapper.setProps({ searchInput: '' })\n    await wrapper.vm.$nextTick()\n\n    wrapper.setData({ isMenuActive: false })\n    await wrapper.vm.$nextTick()\n\n    expect(event).not.toHaveBeenCalled()\n  })\n\n  // TODO: fails with TS 3.9\n  it.skip('should clear value', async () => {\n    const wrapper = mountFunction({\n      attachToDocument: true,\n    })\n    await wrapper.vm.$nextTick()\n\n    const change = jest.fn()\n    const input = wrapper.find('input')\n    const element = input.element as HTMLInputElement\n\n    wrapper.vm.$on('change', change)\n    wrapper.vm.$on('input', change)\n\n    input.trigger('focus')\n    element.value = 'foo'\n    input.trigger('input')\n    input.trigger('keydown.enter')\n\n    await wrapper.vm.$nextTick()\n\n    expect(change).toHaveBeenCalledWith('foo')\n    expect(change).toHaveBeenCalledTimes(2)\n    expect(wrapper.vm.internalValue).toBe('foo')\n\n    element.value = ''\n    input.trigger('input')\n    input.trigger('keydown.enter')\n\n    await wrapper.vm.$nextTick()\n\n    expect(wrapper.vm.internalValue).toBe('')\n    expect(change).toHaveBeenCalledTimes(4)\n  })\n\n  it('should call methods on blur', async () => {\n    const updateCombobox = jest.fn()\n    const wrapper = mountFunction({\n      attachToDocument: true,\n      methods: {\n        updateCombobox,\n      },\n    })\n\n    const e = { preventDefault: jest.fn() }\n    wrapper.vm.onEnterDown(e)\n\n    await wrapper.vm.$nextTick()\n\n    // https://github.com/vuetifyjs/vuetify/issues/4974\n    expect(e.preventDefault).toHaveBeenCalled()\n    expect(updateCombobox).toHaveBeenCalledTimes(1)\n  })\n\n  it('should emit custom value on blur', async () => {\n    const wrapper = mountFunction()\n\n    const input = wrapper.find('input')\n    const element = input.element as HTMLInputElement\n\n    const change = jest.fn()\n    wrapper.vm.$on('change', change)\n\n    input.trigger('focus')\n    await wrapper.vm.$nextTick()\n\n    element.value = 'foo'\n    input.trigger('input')\n\n    input.trigger('keydown.enter')\n    await wrapper.vm.$nextTick()\n    expect(change).toHaveBeenCalledWith('foo')\n\n    input.trigger('keydown.esc')\n    expect(wrapper.vm.isMenuActive).toBe(false)\n\n    element.value = ''\n    input.trigger('input')\n\n    await wrapper.vm.$nextTick()\n    expect(wrapper.vm.isMenuActive).toBe(false)\n  })\n\n  it('should conditionally show the menu', async () => {\n    const wrapper = mountFunction({\n      attachToDocument: true,\n      propsData: {\n        items: ['foo', 'bar', 'fizz'],\n        searchInput: 'foobar',\n      },\n    })\n\n    const slot = wrapper.find('.v-input__slot')\n    const input = wrapper.find('input')\n\n    // Focus input should only focus\n    input.trigger('focus')\n\n    expect(wrapper.vm.isFocused).toBe(true)\n    expect(wrapper.vm.$_menuProps.value).toBe(false)\n\n    slot.trigger('click')\n\n    expect(wrapper.vm.$_menuProps.value).toBe(false)\n\n    // TODO: Add expects for tags when impl\n  })\n\n  it('should return an object', () => {\n    const items = [\n      { text: 'Programming', value: 0 },\n      { text: 'Design', value: 1 },\n      { text: 'Vue', value: 2 },\n      { text: 'Vuetify', value: 3 },\n    ]\n    const wrapper = mountFunction({\n      attachToDocument: true,\n      propsData: {\n        items,\n      },\n    })\n\n    const input = wrapper.find('input')\n    const element = input.element as HTMLInputElement\n\n    const event = jest.fn()\n    wrapper.vm.$on('input', event)\n\n    input.trigger('focus')\n    element.value = 'Programming'\n    input.trigger('input')\n    wrapper.vm.selectItem(items[0])\n\n    expect(wrapper.vm.isFocused).toBe(true)\n    expect(event).toHaveBeenCalledWith(items[0])\n\n    input.trigger('keydown.tab')\n\n    expect(wrapper.vm.isFocused).toBe(false)\n    expect(wrapper.vm.internalValue).toEqual(items[0])\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/5008\n  // TODO: this fails without sync, nextTick doesn't help\n  // https://github.com/vuejs/vue-test-utils/issues/1130\n  it.skip('should select item if menu index is greater than -1', async () => {\n    const selectItem = jest.fn()\n    const wrapper = mountFunction({\n      propsData: {\n        items: ['foo'],\n      },\n      methods: { selectItem },\n    })\n\n    const input = wrapper.find('input')\n\n    input.trigger('focus')\n    input.trigger('keydown.enter')\n    input.trigger('keydown.down')\n\n    await wrapper.vm.$nextTick()\n\n    expect(wrapper.vm.getMenuIndex()).toBe(0)\n\n    input.trigger('keydown.enter')\n\n    expect(selectItem).toHaveBeenCalledWith('foo')\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/8476\n  it('should properly compare falsy values when setting', async () => {\n    const wrapper = mountFunction()\n\n    wrapper.vm.setValue(0)\n    expect(wrapper.vm.internalValue).toBe(0)\n\n    wrapper.vm.setValue('')\n    expect(wrapper.vm.internalValue).toBe('')\n\n    wrapper.vm.setValue(null)\n    expect(wrapper.vm.internalValue).toBeNull()\n\n    wrapper.vm.setValue(undefined)\n    expect(wrapper.vm.internalValue).toBeUndefined()\n\n    wrapper.setData({ lazySearch: 'foo' })\n\n    wrapper.vm.setValue(null)\n    expect(wrapper.vm.internalValue).toBeNull()\n\n    wrapper.vm.setValue(undefined)\n    expect(wrapper.vm.internalValue).toBe('foo')\n  })\n\n  it('should change autocomplete attribute', () => {\n    const wrapper = mountFunction({\n      attrs: {\n        autocomplete: 'on',\n      },\n    })\n\n    expect(wrapper.vm.$attrs.autocomplete).toBe('on')\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/6607\n  it('should select first row when autoSelectFirst true is applied', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        autoSelectFirst: true,\n        items: [\n          { text: 'Learn JavaScript', done: false },\n          { text: 'Learn Vue', done: false },\n          { text: 'Play around in JSFiddle', done: true },\n          { text: 'Build something awesome', done: true },\n        ],\n      },\n    })\n\n    const input = wrapper.find('input')\n    const element = input.element as HTMLInputElement\n\n    const listIndexUpdate = jest.fn()\n    wrapper.vm.$on('update:list-index', listIndexUpdate)\n\n    input.trigger('focus')\n    await wrapper.vm.$nextTick()\n    element.value = 'L'\n    input.trigger('input')\n    await wrapper.vm.$nextTick()\n\n    expect(listIndexUpdate.mock.calls.length === 1).toBe(true)\n    expect(listIndexUpdate.mock.calls[0][0]).toBe(0)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VCombobox/_variables.scss",
    "content": "@forward '../VInput/variables';\n@use '../../styles/settings';\n\n// Defaults\n$combobox-content-border-radius: 4px !default;\n$combobox-content-elevation: 2 !default;\n$combobox-focused-input: 64px !default;\n$combobox-input-buffer: 2px !default;\n$combobox-line-height: 1.75 !default;\n$combobox-selection-gap: 2px !default;\n$combobox-transition: .2s settings.$standard-easing !default;\n$combobox-chips-control-min-height: null !default;\n$combobox-chips-margin-top: null !default;\n$combobox-chips-margin-bottom: null !default;"
  },
  {
    "path": "packages/vuetify/src/components/VCombobox/index.ts",
    "content": "export { VCombobox } from './VCombobox'\n"
  },
  {
    "path": "packages/vuetify/src/components/VConfirmEdit/VConfirmEdit.tsx",
    "content": "// Components\nimport { VBtn } from '@/components/VBtn'\n\n// Composables\nimport { useLocale } from '@/composables/locale'\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { computed, ref, watchEffect } from 'vue'\nimport { deepEqual, deepToRaw, genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType, Ref, VNode } from 'vue'\nimport type { GenericProps } from '@/util'\n\nexport type VConfirmEditSlots<T> = {\n  default: {\n    model: Ref<T>\n    save: () => void\n    cancel: () => void\n    isPristine: boolean\n    get actions (): (props?: {}) => VNode\n  }\n}\n\nexport const makeVConfirmEditProps = propsFactory({\n  modelValue: null,\n  color: String,\n  cancelText: {\n    type: String,\n    default: '$vuetify.confirmEdit.cancel',\n  },\n  okText: {\n    type: String,\n    default: '$vuetify.confirmEdit.ok',\n  },\n  disabled: {\n    type: [Boolean, Array] as PropType<boolean | ('save' | 'cancel')[]>,\n    default: undefined,\n  },\n  hideActions: Boolean,\n}, 'VConfirmEdit')\n\nexport const VConfirmEdit = genericComponent<new <T> (\n  props: {\n    modelValue?: T\n    'onUpdate:modelValue'?: (value: T) => void\n    'onSave'?: (value: T) => void\n  },\n  slots: VConfirmEditSlots<T>\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VConfirmEdit',\n\n  props: makeVConfirmEditProps(),\n\n  emits: {\n    cancel: () => true,\n    save: (value: any) => true,\n    'update:modelValue': (value: any) => true,\n  },\n\n  setup (props, { emit, slots }) {\n    const model = useProxiedModel(props, 'modelValue')\n    const internalModel = ref()\n    watchEffect(() => {\n      internalModel.value = structuredClone(deepToRaw(model.value))\n    })\n\n    const { t } = useLocale()\n\n    const isPristine = computed(() => {\n      return deepEqual(model.value, internalModel.value)\n    })\n\n    function isActionDisabled (action: 'save' | 'cancel') {\n      if (typeof props.disabled === 'boolean') {\n        return props.disabled\n      }\n\n      if (Array.isArray(props.disabled)) {\n        return props.disabled.includes(action)\n      }\n\n      return isPristine.value\n    }\n\n    const isSaveDisabled = computed(() => isActionDisabled('save'))\n    const isCancelDisabled = computed(() => isActionDisabled('cancel'))\n\n    function save () {\n      model.value = internalModel.value\n      emit('save', internalModel.value)\n    }\n\n    function cancel () {\n      internalModel.value = structuredClone(deepToRaw(model.value))\n      emit('cancel')\n    }\n\n    function actions (actionsProps?: {}) {\n      return (\n        <>\n          <VBtn\n            disabled={ isCancelDisabled.value }\n            variant=\"text\"\n            color={ props.color }\n            onClick={ cancel }\n            text={ t(props.cancelText) }\n            { ...actionsProps }\n          />\n\n          <VBtn\n            disabled={ isSaveDisabled.value }\n            variant=\"text\"\n            color={ props.color }\n            onClick={ save }\n            text={ t(props.okText) }\n            { ...actionsProps }\n          />\n        </>\n      )\n    }\n\n    let actionsUsed = false\n    useRender(() => {\n      return (\n        <>\n          {\n            slots.default?.({\n              model: internalModel,\n              save,\n              cancel,\n              isPristine: isPristine.value,\n              get actions () {\n                actionsUsed = true\n                return actions\n              },\n            })\n          }\n\n          { !props.hideActions && !actionsUsed && actions() }\n        </>\n      )\n    })\n\n    return {\n      save,\n      cancel,\n      isPristine,\n    }\n  },\n})\n\nexport type VConfirmEdit = InstanceType<typeof VConfirmEdit>\n"
  },
  {
    "path": "packages/vuetify/src/components/VConfirmEdit/__test__/VConfirmEdit.spec.browser.tsx",
    "content": "// Components\nimport { VConfirmEdit } from '../'\n\n// Utilities\nimport { render, screen, userEvent } from '@test'\nimport { nextTick, shallowRef } from 'vue'\n\ndescribe('VConfirmEdit', () => {\n  it('mirrors external updates', async () => {\n    const externalModel = shallowRef('foo')\n\n    render(() => (\n      <VConfirmEdit modelValue={ externalModel.value }>\n        { ({ model }) => (\n          <p>{ model.value }</p>\n        )}\n      </VConfirmEdit>\n    ))\n\n    expect(screen.getByText('foo')).toBeVisible()\n\n    externalModel.value = 'bar'\n    await nextTick()\n    expect(screen.getByText('bar')).toBeVisible()\n  })\n\n  it(\"doesn't mutate the original value\", async () => {\n    const externalModel = shallowRef(['foo'])\n\n    render(() => (\n      <VConfirmEdit v-model={ externalModel.value } modelValue={ externalModel.value }>\n        { ({ model }) => (\n          <>\n            <p>{ model.value.join(',') }</p>\n            <button data-testid=\"push\" onClick={ () => model.value.push('bar') }>Push</button>\n          </>\n        )}\n      </VConfirmEdit>\n    ))\n\n    expect(screen.getByText('foo')).toBeVisible()\n\n    await userEvent.click(screen.getByTestId('push'))\n    expect(screen.getByText('foo,bar')).toBeVisible()\n    expect(externalModel.value).toEqual(['foo'])\n\n    await userEvent.click(screen.getByText('OK'))\n    expect(externalModel.value).toEqual(['foo', 'bar'])\n  })\n\n  describe('hides actions if used from the slot', () => {\n    it('nothing', () => {\n      render(() => <VConfirmEdit />)\n      expect(screen.getAllByCSS('button')).toHaveLength(2)\n    })\n\n    it('consume model', () => {\n      render(() => (\n        <VConfirmEdit>\n          { ({ model }) => {\n            void model\n          }}\n        </VConfirmEdit>\n      ))\n      expect(screen.getAllByCSS('button')).toHaveLength(2)\n    })\n\n    it('consume actions', () => {\n      render(() => (\n        <VConfirmEdit>\n          { ({ actions }) => {\n            void actions\n          }}\n        </VConfirmEdit>\n      ))\n      expect(screen.queryAllByCSS('button')).toHaveLength(0)\n    })\n\n    it('render actions', () => {\n      render(() => (\n        <VConfirmEdit>\n          { ({ actions }) => actions() }\n        </VConfirmEdit>\n      ))\n      expect(screen.getAllByCSS('button')).toHaveLength(2)\n    })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VConfirmEdit/index.ts",
    "content": "export { VConfirmEdit } from './VConfirmEdit'\n"
  },
  {
    "path": "packages/vuetify/src/components/VCounter/VCounter.sass",
    "content": "@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-counter\n    opacity: var(--v-medium-emphasis-opacity)\n    flex: $counter-flex\n    font-size: $counter-font-size\n    transition-duration: $counter-transition-duration\n    white-space: nowrap\n"
  },
  {
    "path": "packages/vuetify/src/components/VCounter/VCounter.tsx",
    "content": "// Styles\nimport './VCounter.sass'\n\n// Components\nimport { VSlideYTransition } from '@/components/transitions'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { makeTransitionProps, MaybeTransition } from '@/composables/transition'\n\n// Utilities\nimport { toRef } from 'vue'\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { Component } from 'vue'\n\nexport const makeVCounterProps = propsFactory({\n  active: Boolean,\n  disabled: Boolean,\n  max: [Number, String],\n  value: {\n    type: [Number, String],\n    default: 0,\n  },\n\n  ...makeComponentProps(),\n  ...makeTransitionProps({\n    transition: { component: VSlideYTransition as Component },\n  }),\n}, 'VCounter')\n\nexport type VCounterSlot = {\n  counter: string\n  max: string | number | undefined\n  value: string | number | undefined\n}\n\ntype VCounterSlots = {\n  default: VCounterSlot\n}\n\nexport const VCounter = genericComponent<VCounterSlots>()({\n  name: 'VCounter',\n\n  functional: true,\n\n  props: makeVCounterProps(),\n\n  setup (props, { slots }) {\n    const counter = toRef(() => {\n      return props.max ? `${props.value} / ${props.max}` : String(props.value)\n    })\n\n    useRender(() => (\n      <MaybeTransition transition={ props.transition }>\n        <div\n          v-show={ props.active }\n          class={[\n            'v-counter',\n            {\n              'text-error': props.max && !props.disabled &&\n                parseFloat(props.value) > parseFloat(props.max),\n            },\n            props.class,\n          ]}\n          style={ props.style }\n        >\n          { slots.default\n            ? slots.default({\n              counter: counter.value,\n              max: props.max,\n              value: props.value,\n            })\n            : counter.value\n          }\n        </div>\n      </MaybeTransition>\n    ))\n\n    return {}\n  },\n})\n\nexport type VCounter = InstanceType<typeof VCounter>\n"
  },
  {
    "path": "packages/vuetify/src/components/VCounter/_variables.scss",
    "content": "// VCounter\n$counter-flex: 0 1 auto !default;\n$counter-font-size: 12px !default;\n$counter-line-height: $counter-font-size !default;\n$counter-min-height: 12px !default;\n$counter-transition-duration: 150ms !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VCounter/index.ts",
    "content": "export { VCounter } from './VCounter'\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataIterator/VDataIterator.tsx",
    "content": "// Components\nimport { VFadeTransition } from '@/components/transitions'\nimport { makeDataTableExpandProps, provideExpanded } from '@/components/VDataTable/composables/expand'\nimport { makeDataTableGroupProps, provideGroupBy, useGroupedItems } from '@/components/VDataTable/composables/group'\nimport { useOptions } from '@/components/VDataTable/composables/options'\nimport {\n  createPagination,\n  makeDataTablePaginateProps,\n  providePagination,\n  usePaginatedItems,\n} from '@/components/VDataTable/composables/paginate'\nimport { makeDataTableSelectProps, provideSelection } from '@/components/VDataTable/composables/select'\nimport { createSort, makeDataTableSortProps, provideSort, useSortedItems } from '@/components/VDataTable/composables/sort'\n\n// Composables\nimport { makeDataIteratorItemsProps, useDataIteratorItems } from './composables/items'\nimport { makeComponentProps } from '@/composables/component'\nimport { makeFilterProps, useFilter } from '@/composables/filter'\nimport { LoaderSlot } from '@/composables/loader'\nimport { useProxiedModel } from '@/composables/proxiedModel'\nimport { makeTagProps } from '@/composables/tag'\nimport { useToggleScope } from '@/composables/toggleScope'\nimport { makeTransitionProps, MaybeTransition } from '@/composables/transition'\n\n// Utilities\nimport { computed, shallowRef, toRef, watchEffect } from 'vue'\nimport { genericComponent, isEmpty, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { Component } from 'vue'\nimport type { DataIteratorItem } from './composables/items'\nimport type { Group, GroupSummary } from '@/components/VDataTable/composables/group'\nimport type { SortItem } from '@/components/VDataTable/composables/sort'\nimport type { LoaderSlotProps } from '@/composables/loader'\nimport type { GenericProps } from '@/util'\n\ntype VDataIteratorSlotProps<T> = {\n  page: number\n  itemsPerPage: number\n  sortBy: readonly SortItem[]\n  pageCount: number\n  toggleSort: ReturnType<typeof provideSort>['toggleSort']\n  prevPage: ReturnType<typeof providePagination>['prevPage']\n  nextPage: ReturnType<typeof providePagination>['nextPage']\n  setPage: ReturnType<typeof providePagination>['setPage']\n  setItemsPerPage: ReturnType<typeof providePagination>['setItemsPerPage']\n  isSelected: ReturnType<typeof provideSelection>['isSelected']\n  select: ReturnType<typeof provideSelection>['select']\n  selectAll: ReturnType<typeof provideSelection>['selectAll']\n  toggleSelect: ReturnType<typeof provideSelection>['toggleSelect']\n  isExpanded: ReturnType<typeof provideExpanded>['isExpanded']\n  toggleExpand: ReturnType<typeof provideExpanded>['toggleExpand']\n  isGroupOpen: ReturnType<typeof provideGroupBy>['isGroupOpen']\n  toggleGroup: ReturnType<typeof provideGroupBy>['toggleGroup']\n  items: readonly DataIteratorItem<T>[]\n  itemsCount: number\n  groupedItems: readonly (DataIteratorItem<T> | Group<DataIteratorItem<T>> | GroupSummary<DataIteratorItem<T>>)[]\n}\n\nexport type VDataIteratorSlots<T> = {\n  default: VDataIteratorSlotProps<T>\n  header: VDataIteratorSlotProps<T>\n  footer: VDataIteratorSlotProps<T>\n  loader: LoaderSlotProps\n  'no-data': never\n}\n\nexport const makeVDataIteratorProps = propsFactory({\n  search: String,\n  loading: Boolean,\n  itemsLength: [Number, String],\n\n  ...makeComponentProps(),\n  ...makeDataIteratorItemsProps(),\n  ...makeDataTableSelectProps(),\n  ...makeDataTableSortProps(),\n  ...makeDataTablePaginateProps({ itemsPerPage: 5 }),\n  ...makeDataTableExpandProps(),\n  ...makeDataTableGroupProps(),\n  ...makeFilterProps(),\n  ...makeTagProps(),\n  ...makeTransitionProps({\n    transition: {\n      component: VFadeTransition as Component,\n      hideOnLeave: true,\n    },\n  }),\n}, 'VDataIterator')\n\nexport const VDataIterator = genericComponent<new <T> (\n  props: {\n    items?: readonly T[]\n  },\n  slots: VDataIteratorSlots<T>,\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VDataIterator',\n\n  props: makeVDataIteratorProps(),\n\n  emits: {\n    'update:modelValue': (value: any[]) => true,\n    'update:groupBy': (value: any) => true,\n    'update:page': (value: number) => true,\n    'update:itemsPerPage': (value: number) => true,\n    'update:sortBy': (value: any) => true,\n    'update:options': (value: any) => true,\n    'update:expanded': (value: any) => true,\n    'update:currentItems': (value: any) => true,\n  },\n\n  setup (props, { slots }) {\n    const groupBy = useProxiedModel(props, 'groupBy')\n    const search = toRef(() => props.search)\n\n    const { items } = useDataIteratorItems(props)\n    const { filteredItems } = useFilter(props, items, search, { transform: item => item.raw })\n\n    const { initialSortOrder, sortBy, multiSort, mustSort } = createSort(props)\n    const { page, itemsPerPage } = createPagination(props)\n\n    const { toggleSort } = provideSort({ initialSortOrder, sortBy, multiSort, mustSort, page })\n    const { sortByWithGroups, opened, extractRows, isGroupOpen, toggleGroup } = provideGroupBy({ groupBy, sortBy })\n\n    const { sortedItems } = useSortedItems(props, filteredItems, sortByWithGroups, { transform: item => item.raw })\n    const { flatItems } = useGroupedItems(sortedItems, groupBy, opened, false)\n\n    const manualPagination = toRef(() => !isEmpty(props.itemsLength))\n    const itemsLength = toRef(() => manualPagination.value ? Number(props.itemsLength) : flatItems.value.length)\n\n    const {\n      startIndex,\n      stopIndex,\n      pageCount,\n      prevPage,\n      nextPage,\n      setItemsPerPage,\n      setPage,\n    } = providePagination({ page, itemsPerPage, itemsLength })\n\n    const paginatedItems = shallowRef<typeof flatItems.value>([])\n    const currentItems = computed(() => manualPagination.value ? flatItems.value : paginatedItems.value)\n\n    useToggleScope(() => !manualPagination.value, () => {\n      const { paginatedItems: items } = usePaginatedItems({ items: flatItems, startIndex, stopIndex, itemsPerPage })\n\n      watchEffect(() => {\n        paginatedItems.value = items.value\n      })\n    })\n\n    const currentItemsWithoutGroups = computed(() => extractRows(currentItems.value))\n\n    const {\n      isSelected,\n      select,\n      selectAll,\n      toggleSelect,\n    } = provideSelection(props, { allItems: items, currentPage: currentItemsWithoutGroups })\n    const { isExpanded, toggleExpand } = provideExpanded(props)\n\n    useOptions({\n      page,\n      itemsPerPage,\n      sortBy,\n      groupBy,\n      search,\n    })\n\n    const slotProps = computed(() => ({\n      page: page.value,\n      itemsPerPage: itemsPerPage.value,\n      sortBy: sortBy.value,\n      pageCount: pageCount.value,\n      toggleSort,\n      prevPage,\n      nextPage,\n      setPage,\n      setItemsPerPage,\n      isSelected,\n      select,\n      selectAll,\n      toggleSelect,\n      isExpanded,\n      toggleExpand,\n      isGroupOpen,\n      toggleGroup,\n      items: currentItemsWithoutGroups.value,\n      itemsCount: filteredItems.value.length,\n      groupedItems: currentItems.value,\n    }))\n\n    useRender(() => (\n      <props.tag\n        class={[\n          'v-data-iterator',\n          {\n            'v-data-iterator--loading': props.loading,\n          },\n          props.class,\n        ]}\n        style={ props.style }\n      >\n        { slots.header?.(slotProps.value) }\n\n        <MaybeTransition transition={ props.transition }>\n          { props.loading ? (\n            <LoaderSlot key=\"loader\" name=\"v-data-iterator\" active>\n              { slotProps => slots.loader?.(slotProps) }\n            </LoaderSlot>\n          ) : (\n            <div key=\"items\">\n              { !currentItems.value.length\n                ? slots['no-data']?.()\n                : slots.default?.(slotProps.value)\n              }\n            </div>\n          )}\n        </MaybeTransition>\n\n        { slots.footer?.(slotProps.value) }\n      </props.tag>\n    ))\n\n    return {}\n  },\n})\n\nexport type VDataIterator = InstanceType<typeof VDataIterator>\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataIterator/__tests__/VDataIterator.spec.browser.tsx",
    "content": "// Utilities\nimport { render, screen } from '@test'\nimport { VDataIterator } from '../VDataIterator'\n\nconst DESSERT_ITEMS = [\n  { name: 'Frozen Yogurt', calories: 159 },\n  { name: 'Ice cream sandwich', calories: 237 },\n  { name: 'Eclair', calories: 262 },\n  { name: 'Cupcake', calories: 305 },\n  { name: 'Gingerbread', calories: 356 },\n  { name: 'Jelly bean', calories: 375 },\n  { name: 'Lollipop', calories: 392 },\n  { name: 'Honeycomb', calories: 408 },\n  { name: 'Donut', calories: 452 },\n  { name: 'KitKat', calories: 518 },\n]\n\ndescribe('VDataIterator', () => {\n  it('should render items in the default slot', async () => {\n    render(() => (\n      <VDataIterator items={ DESSERT_ITEMS } itemsPerPage={ 5 }>\n        { ({ groupedItems }) => {\n          return groupedItems.map(item => {\n            const dataItem = item as {\n              raw: { name: string, calories: number }\n            }\n            return (\n              <li>\n                { dataItem.raw.name } - { dataItem.raw.calories } calories\n              </li>\n            )\n          })\n        }}\n      </VDataIterator>\n    ))\n\n    const listItems = screen.getAllByRole('listitem')\n    expect(listItems).toHaveLength(5)\n    await expect.element(listItems[0]).toHaveTextContent('Frozen Yogurt - 159 calories')\n    await expect.element(listItems[4]).toHaveTextContent('Gingerbread - 356 calories')\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataIterator/composables/items.ts",
    "content": "// Utilities\nimport { computed } from 'vue'\nimport { getPropertyFromItem, propsFactory } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { GroupableItem } from '@/components/VDataTable/composables/group'\nimport type { SelectableItem } from '@/components/VDataTable/composables/select'\nimport type { InternalItem } from '@/composables/filter'\nimport type { SelectItemKey } from '@/util'\n\nexport interface DataIteratorItemProps {\n  items: any[]\n  itemValue: SelectItemKey\n  itemSelectable: SelectItemKey\n  returnObject: boolean\n}\n\nexport interface DataIteratorItem<T = any> extends Omit<InternalItem<T>, 'type'>, GroupableItem<T>, SelectableItem {\n  value: unknown\n}\n\n// Composables\nexport const makeDataIteratorItemsProps = propsFactory({\n  items: {\n    type: Array as PropType<DataIteratorItemProps['items']>,\n    default: () => ([]),\n  },\n  itemValue: {\n    type: [String, Array, Function] as PropType<SelectItemKey>,\n    default: 'id',\n  },\n  itemSelectable: {\n    type: [String, Array, Function] as PropType<SelectItemKey>,\n    default: null,\n  },\n  returnObject: Boolean,\n}, 'DataIterator-items')\n\nexport function transformItem (\n  props: Omit<DataIteratorItemProps, 'items'>,\n  item: any\n): DataIteratorItem {\n  const value = props.returnObject ? item : getPropertyFromItem(item, props.itemValue)\n  const selectable = getPropertyFromItem(item, props.itemSelectable, true)\n\n  return {\n    type: 'item',\n    value,\n    selectable,\n    raw: item,\n  }\n}\n\nexport function transformItems (\n  props: Omit<DataIteratorItemProps, 'items'>,\n  items: DataIteratorItemProps['items']\n) {\n  const array: DataIteratorItem[] = []\n\n  for (const item of items) {\n    array.push(transformItem(props, item))\n  }\n\n  return array\n}\n\nexport function useDataIteratorItems (props: DataIteratorItemProps) {\n  const items = computed(() => transformItems(props, props.items))\n\n  return { items }\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataIterator/index.ts",
    "content": "export { VDataIterator } from './VDataIterator'\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/VDataTable.sass",
    "content": "@use '../../styles/settings'\n@use '../../styles/tools'\n@use '../../components/VTable/variables' as *\n@use './variables' as *\n@use '../VTable/variables' as VTable\n\n@include tools.layer('components')\n  .v-data-table\n    width: 100%\n\n  .v-data-table__table\n    width: 100%\n    border-collapse: separate\n    border-spacing: 0\n\n  .v-data-table__tr\n    &--focus\n      border: 1px dotted black\n\n    &--clickable\n      cursor: pointer\n\n  .v-data-table\n    .v-table__wrapper\n      > table\n        > thead,\n          tbody\n          > tr\n            > td,\n              th\n\n              &.v-data-table-column--align-end\n                text-align: end\n\n                .v-data-table-header__content\n                  flex-direction: row-reverse\n\n              &.v-data-table-column--align-center\n                text-align: center\n\n                .v-data-table-header__content\n                  justify-content: center\n\n              &.v-data-table-column--no-padding\n                padding: 0 8px\n\n              &.v-data-table-column--empty\n                padding: 0\n\n              &.v-data-table-column--nowrap\n                text-overflow: ellipsis\n                text-wrap: nowrap\n                overflow: hidden\n\n                & .v-data-table-header__content\n                  display: contents\n\n            > th\n              align-items: center\n\n            > th.v-data-table__th--fixed\n              position: sticky\n\n            > th.v-data-table__th--sortable:hover,\n            > th.v-data-table__th--sortable:focus\n                cursor: pointer\n                color: tools.theme-color('on-surface', var(--v-high-emphasis-opacity))\n\n            > th:not(.v-data-table__th--sorted)\n                .v-data-table-header__sort-icon\n                  opacity: $data-table-header-sort-icon-default-opacity\n\n                &:hover,\n                &:focus-visible\n                  .v-data-table-header__sort-icon\n                    opacity: $data-table-header-sort-icon-hover-opacity\n\n            &.v-data-table__tr--mobile\n              > td\n                height: fit-content\n\n  .v-data-table-column--fixed,\n  .v-data-table-column--fixed-end,\n  .v-data-table__th--sticky\n    background-color: $table-background\n    background-image: inherit\n    left: 0\n    z-index: 1\n\n    @include tools.layer('overrides')\n      // Beat out relative on table > tbody > tr > td\n      // TODO: Use :where() for all those child combinators\n      // @scope would probably be even better but\n      // doesn't seem to be getting here any time soon\n      position: sticky\n\n  .v-data-table-column--fixed-end\n    left: unset\n    right: 0\n\n  .v-data-table-column--last-fixed\n    border-right: 1px solid rgba(var(--v-border-color), var(--v-border-opacity))\n\n  .v-data-table-column--first-fixed-end\n    border-left: 1px solid rgba(var(--v-border-color), var(--v-border-opacity))\n\n  .v-data-table.v-table--fixed-header > .v-table__wrapper > table > thead > tr\n    > th.v-data-table-column--fixed,\n    > th.v-data-table-column--fixed-end\n      z-index: 2\n\n  .v-data-table-group-header-row\n    td\n      background: rgba(var(--v-theme-surface))\n      color: rgba(var(--v-theme-on-surface))\n\n      > span\n        padding-left: 5px\n\n  .v-data-table--loading\n    &:not(.v-table--fixed-header) > .v-table__wrapper > table > thead,\n    &:not(.v-table--fixed-footer) > .v-table__wrapper > table > tfoot,\n    > .v-table__wrapper > table > tbody\n      > tr > .v-data-table__td\n        &:not(.v-data-table-column--fixed),\n        &:not(.v-data-table-column--fixed-end)\n          opacity: $data-table-loading-opacity\n\n  @include tools.layer('overrides')\n    // Again, needs to beat all the child combinators\n    .v-data-table-group-header-row__column\n      padding-inline-start: calc(var(--v-data-table-group-header-row-depth) * 16px)\n\n  .v-data-table-header__content\n    display: flex\n    align-items: center\n\n  .v-data-table-header__sort-icon\n    margin-inline: $data-table-header-sort-icon-margin-inline\n\n  .v-data-table-header__sort-badge\n    display: inline-flex\n    justify-content: center\n    align-items: center\n    font-size: 0.875rem\n    padding: 4px\n    border-radius: 50%\n    background: $data-table-header-sort-badge-color\n    min-width: $data-table-header-sort-badge-size\n    min-height: $data-table-header-sort-badge-size\n    width: $data-table-header-sort-badge-size\n    height: $data-table-header-sort-badge-size\n\n  @include tools.layer('overrides')\n    .v-data-table-progress\n      > th\n        border: none\n        height: auto\n        padding: 0\n\n  .v-data-table-progress__loader\n    position: relative\n\n  .v-data-table-rows-loading,\n  .v-data-table-rows-no-data\n    text-align: center\n\n  .v-data-table__tr--mobile\n    > .v-data-table__td--expanded-row\n      grid-template-columns: auto\n      justify-content: center\n\n    > .v-data-table__td--select-row\n      grid-template-columns: 0\n      justify-content: end\n\n    > td\n      align-items: center\n      column-gap: 4px\n      display: grid\n      grid-template-columns: repeat(2, 1fr)\n      min-height: var(--v-table-row-height)\n\n      @include tools.layer('overrides')\n        &:not(:last-child)\n          border-bottom: 0\n\n  .v-data-table__td-title\n    font-weight: VTable.$table-header-font-weight\n    text-align: start\n\n  .v-data-table__td-value\n    text-align: end\n\n  .v-data-table__td\n    &-sort-icon\n      color: $data-table-header-mobile-chip-icon-color\n\n      &-active\n        color: $data-table-header-mobile-chip-icon-color-active\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/VDataTable.tsx",
    "content": "// Styles\nimport './VDataTable.sass'\n\n// Components\nimport { makeVDataTableFooterProps, VDataTableFooter } from './VDataTableFooter'\nimport { makeVDataTableHeadersProps, VDataTableHeaders } from './VDataTableHeaders'\nimport { makeVDataTableRowsProps, VDataTableRows } from './VDataTableRows'\nimport { VDivider } from '@/components/VDivider'\nimport { makeVTableProps, VTable } from '@/components/VTable/VTable'\n\n// Composables\nimport { makeDataTableExpandProps, provideExpanded } from './composables/expand'\nimport { createGroupBy, makeDataTableGroupProps, provideGroupBy, useGroupedItems } from './composables/group'\nimport { createHeaders, makeDataTableHeaderProps } from './composables/headers'\nimport { makeDataTableItemsProps, useDataTableItems } from './composables/items'\nimport { useOptions } from './composables/options'\nimport {\n  createPagination,\n  makeDataTablePaginateProps,\n  providePagination,\n  usePaginatedGroups,\n  usePaginatedItems,\n} from './composables/paginate'\nimport { makeDataTableSelectProps, provideSelection } from './composables/select'\nimport { createSort, makeDataTableSortProps, provideSort, useSortedItems } from './composables/sort'\nimport { provideDefaults } from '@/composables/defaults'\nimport { makeFilterProps, useFilter } from '@/composables/filter'\n\n// Utilities\nimport { computed, toRef, toRefs, toValue } from 'vue'\nimport { genericComponent, omit, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { DeepReadonly, UnwrapRef } from 'vue'\nimport type { Group, GroupSummary } from './composables/group'\nimport type { CellProps, DataTableHeader, DataTableItem, InternalDataTableHeader, RowProps } from './types'\nimport type { VDataTableHeadersSlots } from './VDataTableHeaders'\nimport type { VDataTableRowsSlots } from './VDataTableRows'\nimport type { GenericProps, SelectItemKey } from '@/util'\n\nexport type VDataTableSlotProps<T> = {\n  page: number\n  itemsPerPage: number\n  sortBy: UnwrapRef<ReturnType<typeof provideSort>['sortBy']>\n  pageCount: number\n  toggleSort: ReturnType<typeof provideSort>['toggleSort']\n  setItemsPerPage: (value: number) => void\n  prevPage: () => void\n  nextPage: () => void\n  setPage: (value: number) => void\n  someSelected: boolean\n  allSelected: boolean\n  isSelected: ReturnType<typeof provideSelection>['isSelected']\n  select: ReturnType<typeof provideSelection>['select']\n  selectAll: ReturnType<typeof provideSelection>['selectAll']\n  toggleSelect: ReturnType<typeof provideSelection>['toggleSelect']\n  isExpanded: ReturnType<typeof provideExpanded>['isExpanded']\n  toggleExpand: ReturnType<typeof provideExpanded>['toggleExpand']\n  isGroupOpen: ReturnType<typeof provideGroupBy>['isGroupOpen']\n  toggleGroup: ReturnType<typeof provideGroupBy>['toggleGroup']\n  items: readonly T[]\n  internalItems: readonly DataTableItem[]\n  groupedItems: readonly (DataTableItem<T> | Group<DataTableItem<T>> | GroupSummary<DataTableItem<T>>)[]\n  columns: InternalDataTableHeader[]\n  headers: InternalDataTableHeader[][]\n}\n\nexport type VDataTableSlots<T> = VDataTableRowsSlots<T> & VDataTableHeadersSlots & {\n  default: VDataTableSlotProps<T>\n  colgroup: VDataTableSlotProps<T>\n  top: VDataTableSlotProps<T>\n  body: VDataTableSlotProps<T>\n  tbody: VDataTableSlotProps<T>\n  thead: VDataTableSlotProps<T>\n  tfoot: VDataTableSlotProps<T>\n  bottom: VDataTableSlotProps<T>\n  'body.prepend': VDataTableSlotProps<T>\n  'body.append': VDataTableSlotProps<T>\n  'footer.prepend': never\n}\n\nexport const makeDataTableProps = propsFactory({\n  ...makeVDataTableRowsProps(),\n\n  hideDefaultBody: Boolean,\n  hideDefaultFooter: Boolean,\n  hideDefaultHeader: Boolean,\n  width: [String, Number],\n  search: String,\n\n  ...makeDataTableExpandProps(),\n  ...makeDataTableGroupProps(),\n  ...makeDataTableHeaderProps(),\n  ...makeDataTableItemsProps(),\n  ...makeDataTableSelectProps(),\n  ...makeDataTableSortProps(),\n  ...omit(makeVDataTableHeadersProps(), ['multiSort', 'initialSortOrder']),\n  ...makeVTableProps(),\n}, 'DataTable')\n\nexport const makeVDataTableProps = propsFactory({\n  ...makeDataTablePaginateProps(),\n  ...makeDataTableProps(),\n  ...makeFilterProps(),\n  ...makeVDataTableFooterProps(),\n}, 'VDataTable')\n\ntype ItemType<T> = T extends readonly (infer U)[] ? U : never\n\nexport const VDataTable = genericComponent<new <T extends readonly any[], V>(\n  props: {\n    items?: T\n    itemValue?: SelectItemKey<ItemType<T>>\n    rowProps?: RowProps<ItemType<T>>\n    cellProps?: CellProps<ItemType<T>>\n    itemSelectable?: SelectItemKey<ItemType<T>>\n    headers?: DeepReadonly<DataTableHeader<ItemType<T>>[]>\n    modelValue?: V\n    'onUpdate:modelValue'?: (value: V) => void\n  },\n  slots: VDataTableSlots<ItemType<T>>,\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VDataTable',\n\n  props: makeVDataTableProps(),\n\n  emits: {\n    'update:modelValue': (value: any[]) => true,\n    'update:page': (value: number) => true,\n    'update:itemsPerPage': (value: number) => true,\n    'update:sortBy': (value: any) => true,\n    'update:options': (value: any) => true,\n    'update:groupBy': (value: any) => true,\n    'update:expanded': (value: any) => true,\n    'update:currentItems': (value: any) => true,\n  },\n\n  setup (props, { attrs, slots }) {\n    const { groupBy } = createGroupBy(props)\n    const { initialSortOrder, sortBy, multiSort, mustSort } = createSort(props)\n    const { page, itemsPerPage } = createPagination(props)\n    const { disableSort } = toRefs(props)\n\n    const {\n      columns,\n      headers,\n      sortFunctions,\n      sortRawFunctions,\n      filterFunctions,\n    } = createHeaders(props, {\n      groupBy,\n      showSelect: toRef(() => props.showSelect),\n      showExpand: toRef(() => props.showExpand),\n    })\n\n    const { items } = useDataTableItems(props, columns)\n\n    const search = toRef(() => props.search)\n    const { filteredItems } = useFilter(props, items, search, {\n      transform: item => item.columns,\n      customKeyFilter: filterFunctions,\n    })\n\n    const { toggleSort } = provideSort({ initialSortOrder, sortBy, multiSort, mustSort, page })\n    const { sortByWithGroups, opened, extractRows, isGroupOpen, toggleGroup } = provideGroupBy({ groupBy, sortBy, disableSort })\n\n    const { sortedItems } = useSortedItems(props, filteredItems, sortByWithGroups, {\n      transform: item => ({ ...item.raw, ...item.columns }),\n      sortFunctions,\n      sortRawFunctions,\n    })\n\n    const pageBy = computed(() => {\n      if (props.pageBy === 'auto') {\n        return props.groupBy.length ? 'group' : 'item'\n      }\n      return props.pageBy\n    })\n\n    const {\n      pageCount,\n      setItemsPerPage,\n      prevPage,\n      nextPage,\n      setPage,\n      paginatedItems,\n    } = usePaginatedGroups({\n      pageBy,\n      sortedItems,\n      paginate: items => {\n        const itemsLength = computed(() => toValue(items).length)\n        const {\n          startIndex, stopIndex, pageCount, setItemsPerPage, prevPage, nextPage, setPage,\n        } = providePagination({ page, itemsPerPage, itemsLength })\n        const { paginatedItems } = usePaginatedItems({ items, startIndex, stopIndex, itemsPerPage })\n        return { paginatedItems, pageCount, setItemsPerPage, prevPage, nextPage, setPage }\n      },\n      group: items => useGroupedItems(items, groupBy, opened, () => !!slots['group-summary']),\n    })\n\n    const paginatedItemsWithoutGroups = computed(() => extractRows(paginatedItems.value))\n\n    const {\n      isSelected,\n      select,\n      selectAll,\n      toggleSelect,\n      someSelected,\n      allSelected,\n    } = provideSelection(props, { allItems: items, currentPage: paginatedItemsWithoutGroups })\n\n    const { isExpanded, toggleExpand } = provideExpanded(props)\n\n    useOptions({\n      page,\n      itemsPerPage,\n      sortBy,\n      groupBy,\n      search,\n    })\n\n    provideDefaults({\n      VDataTableRows: {\n        hideNoData: toRef(() => props.hideNoData),\n        noDataText: toRef(() => props.noDataText),\n        loading: toRef(() => props.loading),\n        loadingText: toRef(() => props.loadingText),\n      },\n    })\n\n    const slotProps = computed<VDataTableSlotProps<any>>(() => ({\n      page: page.value,\n      itemsPerPage: itemsPerPage.value,\n      sortBy: sortBy.value,\n      pageCount: pageCount.value,\n      toggleSort,\n      setItemsPerPage,\n      prevPage,\n      nextPage,\n      setPage,\n      someSelected: someSelected.value,\n      allSelected: allSelected.value,\n      isSelected,\n      select,\n      selectAll,\n      toggleSelect,\n      isExpanded,\n      toggleExpand,\n      isGroupOpen,\n      toggleGroup,\n      items: paginatedItemsWithoutGroups.value.map(item => item.raw),\n      internalItems: paginatedItemsWithoutGroups.value,\n      groupedItems: paginatedItems.value,\n      columns: columns.value,\n      headers: headers.value,\n    }))\n\n    useRender(() => {\n      const dataTableFooterProps = VDataTableFooter.filterProps(props)\n      const dataTableHeadersProps = VDataTableHeaders.filterProps(omit(props, ['multiSort']))\n      const dataTableRowsProps = VDataTableRows.filterProps(props)\n      const tableProps = VTable.filterProps(props)\n\n      return (\n        <VTable\n          class={[\n            'v-data-table',\n            {\n              'v-data-table--show-select': props.showSelect,\n              'v-data-table--loading': props.loading,\n            },\n            props.class,\n          ]}\n          style={ props.style }\n          { ...tableProps }\n          fixedHeader={ props.fixedHeader || props.sticky }\n        >\n          {{\n            top: () => slots.top?.(slotProps.value),\n            default: () => slots.default ? slots.default(slotProps.value) : (\n              <>\n                { slots.colgroup?.(slotProps.value) }\n                { !props.hideDefaultHeader && (\n                  <thead key=\"thead\">\n                    <VDataTableHeaders\n                      { ...dataTableHeadersProps }\n                      multiSort={ !!props.multiSort }\n                      v-slots={ slots }\n                    />\n                  </thead>\n                )}\n                { slots.thead?.(slotProps.value) }\n                { !props.hideDefaultBody && (\n                  <tbody>\n                    { slots['body.prepend']?.(slotProps.value) }\n                    { slots.body ? slots.body(slotProps.value) : (\n                      <VDataTableRows\n                        { ...attrs }\n                        { ...dataTableRowsProps }\n                        items={ paginatedItems.value }\n                        v-slots={ slots }\n                      />\n                    )}\n                    { slots['body.append']?.(slotProps.value) }\n                  </tbody>\n                )}\n                { slots.tbody?.(slotProps.value) }\n                { slots.tfoot?.(slotProps.value) }\n              </>\n            ),\n            bottom: () => slots.bottom ? slots.bottom(slotProps.value) : !props.hideDefaultFooter && (\n              <>\n                <VDivider />\n\n                <VDataTableFooter\n                  { ...dataTableFooterProps }\n                  v-slots={{\n                    prepend: slots['footer.prepend'],\n                  }}\n                />\n              </>\n            ),\n          }}\n        </VTable>\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VDataTable = InstanceType<typeof VDataTable>\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/VDataTableColumn.tsx",
    "content": "// Utilities\nimport { convertToUnit, defineFunctionalComponent } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\nexport const VDataTableColumn = defineFunctionalComponent({\n  align: {\n    type: String as PropType<'start' | 'center' | 'end'>,\n    default: 'start',\n  },\n  fixed: {\n    type: [Boolean, String] as PropType<boolean | 'start' | 'end'>,\n    default: false,\n  },\n  fixedOffset: [Number, String],\n  fixedEndOffset: [Number, String],\n  height: [Number, String],\n  lastFixed: Boolean,\n  firstFixedEnd: Boolean,\n\n  noPadding: Boolean,\n  indent: [Number, String],\n  empty: Boolean,\n\n  tag: String,\n  width: [Number, String],\n  maxWidth: [Number, String],\n  nowrap: Boolean,\n}, (props, { slots }) => {\n  const Tag = props.tag ?? 'td'\n\n  const fixedSide = typeof props.fixed === 'string' ? props.fixed\n    : props.fixed ? 'start'\n    : 'none'\n\n  return (\n    <Tag\n      class={[\n        'v-data-table__td',\n        {\n          'v-data-table-column--fixed': fixedSide === 'start',\n          'v-data-table-column--fixed-end': fixedSide === 'end',\n          'v-data-table-column--last-fixed': props.lastFixed,\n          'v-data-table-column--first-fixed-end': props.firstFixedEnd,\n          'v-data-table-column--no-padding': props.noPadding,\n          'v-data-table-column--nowrap': props.nowrap,\n          'v-data-table-column--empty': props.empty,\n        },\n        `v-data-table-column--align-${props.align}`,\n      ]}\n      style={{\n        height: convertToUnit(props.height),\n        width: convertToUnit(props.width),\n        maxWidth: convertToUnit(props.maxWidth),\n        left: fixedSide === 'start' ? convertToUnit(props.fixedOffset || null) : undefined,\n        right: fixedSide === 'end' ? convertToUnit(props.fixedEndOffset || null) : undefined,\n        paddingInlineStart: props.indent ? convertToUnit(props.indent) : undefined,\n      }}\n    >\n      { slots.default?.() }\n    </Tag>\n  )\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/VDataTableFooter.sass",
    "content": "@forward './variables'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-data-table-footer\n    align-items: center\n    display: flex\n    flex-wrap: wrap\n    justify-content: flex-end\n    padding: $data-table-footer-padding\n\n    &__items-per-page\n      align-items: center\n      display: flex\n      justify-content: center\n\n      > span\n        padding-inline-end: $data-table-footer-items-per-page-padding\n\n      > .v-select\n        width: $data-table-footer-select-width\n\n    &__info\n      display: flex\n      justify-content: flex-end\n      min-width: $data-table-footer-info-min-width\n      padding: $data-table-footer-info-padding\n\n    &__paginationz\n      align-items: center\n      display: flex\n      margin-inline-start: $data-table-footer-pagination-margin-inline-start\n\n    &__page\n      padding: 0 8px\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/VDataTableFooter.tsx",
    "content": "// Styles\nimport './VDataTableFooter.sass'\n\n// Components\nimport { VPagination } from '@/components/VPagination'\nimport { VSelect } from '@/components/VSelect'\n\n// Composables\nimport { usePagination } from './composables/paginate'\nimport { IconValue } from '@/composables/icons'\nimport { useLocale } from '@/composables/locale'\n\n// Utilities\nimport { computed } from 'vue'\nimport { genericComponent, omit, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\nexport const makeVDataTableFooterProps = propsFactory({\n  color: String,\n  prevIcon: {\n    type: IconValue,\n    default: '$prev',\n  },\n  nextIcon: {\n    type: IconValue,\n    default: '$next',\n  },\n  firstIcon: {\n    type: IconValue,\n    default: '$first',\n  },\n  lastIcon: {\n    type: IconValue,\n    default: '$last',\n  },\n  itemsPerPageText: {\n    type: String,\n    default: '$vuetify.dataFooter.itemsPerPageText',\n  },\n  pageText: {\n    type: String,\n    default: '$vuetify.dataFooter.pageText',\n  },\n  firstPageLabel: {\n    type: String,\n    default: '$vuetify.dataFooter.firstPage',\n  },\n  prevPageLabel: {\n    type: String,\n    default: '$vuetify.dataFooter.prevPage',\n  },\n  nextPageLabel: {\n    type: String,\n    default: '$vuetify.dataFooter.nextPage',\n  },\n  lastPageLabel: {\n    type: String,\n    default: '$vuetify.dataFooter.lastPage',\n  },\n  itemsPerPageOptions: {\n    type: Array as PropType<readonly (number | { title: string, value: number })[]>,\n    default: () => ([\n      { value: 10, title: '10' },\n      { value: 25, title: '25' },\n      { value: 50, title: '50' },\n      { value: 100, title: '100' },\n      { value: -1, title: '$vuetify.dataFooter.itemsPerPageAll' },\n    ]),\n  },\n  showCurrentPage: Boolean,\n}, 'VDataTableFooter')\n\nexport const VDataTableFooter = genericComponent<{ prepend: never }>()({\n  name: 'VDataTableFooter',\n\n  props: makeVDataTableFooterProps(),\n\n  setup (props, { slots }) {\n    const { t } = useLocale()\n    const { page, pageCount, startIndex, stopIndex, itemsLength, itemsPerPage, setItemsPerPage } = usePagination()\n\n    const itemsPerPageOptions = computed(() => (\n      props.itemsPerPageOptions.map(option => {\n        if (typeof option === 'number') {\n          return {\n            value: option,\n            title: option === -1\n              ? t('$vuetify.dataFooter.itemsPerPageAll')\n              : String(option),\n          }\n        }\n\n        return {\n          ...option,\n          title: !isNaN(Number(option.title)) ? option.title : t(option.title),\n        }\n      })\n    ))\n\n    useRender(() => {\n      const paginationProps = VPagination.filterProps(props)\n\n      return (\n        <div class=\"v-data-table-footer\">\n          { slots.prepend?.() }\n\n          <div class=\"v-data-table-footer__items-per-page\">\n            <span>{ t(props.itemsPerPageText) }</span>\n\n            <VSelect\n              items={ itemsPerPageOptions.value }\n              itemColor={ props.color }\n              modelValue={ itemsPerPage.value }\n              onUpdate:modelValue={ v => setItemsPerPage(Number(v)) }\n              density=\"compact\"\n              variant=\"outlined\"\n              aria-label={ t(props.itemsPerPageText) }\n              hideDetails\n            />\n          </div>\n\n          <div class=\"v-data-table-footer__info\">\n            <div>\n              { t(props.pageText, !itemsLength.value ? 0 : startIndex.value + 1, stopIndex.value, itemsLength.value) }\n            </div>\n          </div>\n\n          <div class=\"v-data-table-footer__pagination\">\n            <VPagination\n              v-model={ page.value }\n              density=\"comfortable\"\n              firstAriaLabel={ props.firstPageLabel }\n              lastAriaLabel={ props.lastPageLabel }\n              length={ pageCount.value }\n              nextAriaLabel={ props.nextPageLabel }\n              previousAriaLabel={ props.prevPageLabel }\n              rounded\n              showFirstLastPage\n              totalVisible={ props.showCurrentPage ? 1 : 0 }\n              variant=\"plain\"\n              { ...omit(paginationProps, ['color']) }\n            ></VPagination>\n          </div>\n        </div>\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VDataTableFooter = InstanceType<typeof VDataTableFooter>\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/VDataTableGroupHeaderRow.tsx",
    "content": "// Components\nimport { VDataTableColumn } from './VDataTableColumn'\nimport { VBtn } from '@/components/VBtn'\nimport { VCheckboxBtn } from '@/components/VCheckbox'\n\n// Composables\nimport { useGroupBy } from './composables/group'\nimport { useHeaders } from './composables/headers'\nimport { useSelection } from './composables/select'\nimport { makeDensityProps } from '@/composables/density'\nimport { IconValue } from '@/composables/icons'\n\n// Utilities\nimport { computed, toRef } from 'vue'\nimport { genericComponent, propsFactory } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { Group } from './composables/group'\n\nexport type VDataTableGroupHeaderRowSlots = {\n  'data-table-group': { item: Group, count: number, props: Record<string, unknown> }\n  'data-table-select': { props: Record<string, unknown> }\n}\n\nexport const makeVDataTableGroupHeaderRowProps = propsFactory({\n  item: {\n    type: Object as PropType<Group>,\n    required: true,\n  },\n  groupCollapseIcon: {\n    type: IconValue,\n    default: '$tableGroupCollapse',\n  },\n  groupExpandIcon: {\n    type: IconValue,\n    default: '$tableGroupExpand',\n  },\n  ...makeDensityProps(),\n}, 'VDataTableGroupHeaderRow')\n\nexport const VDataTableGroupHeaderRow = genericComponent<VDataTableGroupHeaderRowSlots>()({\n  name: 'VDataTableGroupHeaderRow',\n\n  props: makeVDataTableGroupHeaderRowProps(),\n\n  setup (props, { slots }) {\n    const { isGroupOpen, toggleGroup, extractRows } = useGroupBy()\n    const { isSelected, isSomeSelected, select } = useSelection()\n    const { columns } = useHeaders()\n\n    const rows = computed(() => {\n      return extractRows([props.item])\n    })\n\n    const colspan = toRef(() => columns.value.length - (columns.value.some(c => c.key === 'data-table-select') ? 1 : 0))\n\n    return () => (\n      <tr\n        class=\"v-data-table-group-header-row\"\n        style={{\n          '--v-data-table-group-header-row-depth': props.item.depth,\n        }}\n      >\n        { columns.value.map(column => {\n          if (column.key === 'data-table-group') {\n            const icon = isGroupOpen(props.item) ? props.groupCollapseIcon : props.groupExpandIcon\n            const onClick = () => toggleGroup(props.item)\n\n            return slots['data-table-group']?.({ item: props.item, count: rows.value.length, props: { icon, onClick } }) ?? (\n              <VDataTableColumn\n                class=\"v-data-table-group-header-row__column\"\n                colspan={ colspan.value }\n              >\n                <VBtn\n                  size=\"small\"\n                  variant=\"text\"\n                  icon={ icon }\n                  onClick={ onClick }\n                />\n                <span>{ props.item.value }</span>\n                <span>({ rows.value.length })</span>\n              </VDataTableColumn>\n            )\n          } else if (column.key === 'data-table-select') {\n            const selectableRows = rows.value.filter(x => x.selectable)\n            const modelValue = selectableRows.length > 0 && isSelected(selectableRows)\n            const indeterminate = isSomeSelected(selectableRows) && !modelValue\n            const selectGroup = (v: boolean) => select(selectableRows, v)\n            return slots['data-table-select']?.({ props: { modelValue, indeterminate, 'onUpdate:modelValue': selectGroup } }) ?? (\n              <VDataTableColumn class=\"v-data-table__td--select-row\" noPadding>\n                <VCheckboxBtn\n                  density={ props.density }\n                  disabled={ selectableRows.length === 0 }\n                  modelValue={ modelValue }\n                  indeterminate={ indeterminate }\n                  onUpdate:modelValue={ selectGroup }\n                />\n              </VDataTableColumn>\n            )\n          }\n\n          return ''\n        })}\n      </tr>\n    )\n  },\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/VDataTableHeaders.tsx",
    "content": "// Components\nimport { VDataTableColumn } from './VDataTableColumn'\nimport { VCheckboxBtn } from '@/components/VCheckbox'\nimport { VChip } from '@/components/VChip'\nimport { VIcon } from '@/components/VIcon'\nimport { VSelect } from '@/components/VSelect'\n\n// Composables\nimport { useHeaders } from './composables/headers'\nimport { useSelection } from './composables/select'\nimport { useSort } from './composables/sort'\nimport { useBackgroundColor } from '@/composables/color'\nimport { makeDensityProps } from '@/composables/density'\nimport { makeDisplayProps, useDisplay } from '@/composables/display'\nimport { IconValue } from '@/composables/icons'\nimport { LoaderSlot, makeLoaderProps, useLoader } from '@/composables/loader'\nimport { useLocale } from '@/composables/locale'\n\n// Utilities\nimport { computed, mergeProps, nextTick } from 'vue'\nimport { convertToUnit, genericComponent, propsFactory, useRender, wrapInArray } from '@/util'\n\n// Types\nimport type { CSSProperties, PropType, UnwrapRef } from 'vue'\nimport type { provideSelection } from './composables/select'\nimport type { provideSort } from './composables/sort'\nimport type { InternalDataTableHeader } from './types'\nimport type { ItemProps } from '@/composables/list-items'\nimport type { LoaderSlotProps } from '@/composables/loader'\n\nexport type HeadersSlotProps = {\n  headers: InternalDataTableHeader[][]\n  columns: InternalDataTableHeader[]\n  sortBy: UnwrapRef<ReturnType<typeof provideSort>['sortBy']>\n  someSelected: UnwrapRef<ReturnType<typeof provideSelection>['someSelected']>\n  allSelected: UnwrapRef<ReturnType<typeof provideSelection>['allSelected']>\n  toggleSort: ReturnType<typeof provideSort>['toggleSort']\n  selectAll: ReturnType<typeof provideSelection>['selectAll']\n  getSortIcon: (column: InternalDataTableHeader) => IconValue\n  isSorted: ReturnType<typeof provideSort>['isSorted']\n}\n\nexport type VDataTableHeaderCellColumnSlotProps = {\n  column: InternalDataTableHeader\n  selectAll: ReturnType<typeof provideSelection>['selectAll']\n  isSorted: ReturnType<typeof provideSort>['isSorted']\n  toggleSort: ReturnType<typeof provideSort>['toggleSort']\n  sortBy: UnwrapRef<ReturnType<typeof provideSort>['sortBy']>\n  someSelected: UnwrapRef<ReturnType<typeof provideSelection>['someSelected']>\n  allSelected: UnwrapRef<ReturnType<typeof provideSelection>['allSelected']>\n  getSortIcon: (column: InternalDataTableHeader) => IconValue\n}\n\nexport type VDataTableHeadersSlots = {\n  headers: HeadersSlotProps\n  loader: LoaderSlotProps\n  'header.data-table-select': VDataTableHeaderCellColumnSlotProps\n  'header.data-table-expand': VDataTableHeaderCellColumnSlotProps\n} & { [key: `header.${string}`]: VDataTableHeaderCellColumnSlotProps }\n\nexport const makeVDataTableHeadersProps = propsFactory({\n  color: String,\n  disableSort: Boolean,\n  fixedHeader: Boolean,\n  multiSort: Boolean,\n  initialSortOrder: String as PropType<'asc' | 'desc'>,\n  sortIcon: {\n    type: IconValue,\n    // default: '$sort', // maybe in v4\n  },\n  sortAscIcon: {\n    type: IconValue,\n    default: '$sortAsc',\n  },\n  sortDescIcon: {\n    type: IconValue,\n    default: '$sortDesc',\n  },\n  headerProps: {\n    type: Object as PropType<Record<string, any>>,\n  },\n\n  /** @deprecated */\n  sticky: Boolean,\n\n  ...makeDensityProps(),\n  ...makeDisplayProps(),\n  ...makeLoaderProps(),\n}, 'VDataTableHeaders')\n\nexport const VDataTableHeaders = genericComponent<VDataTableHeadersSlots>()({\n  name: 'VDataTableHeaders',\n\n  props: makeVDataTableHeadersProps(),\n\n  setup (props, { slots }) {\n    const { t } = useLocale()\n    const { toggleSort, sortBy, isSorted } = useSort()\n    const { someSelected, allSelected, selectAll, showSelectAll } = useSelection()\n    const { columns, headers } = useHeaders()\n    const { loaderClasses } = useLoader(props)\n\n    function getFixedStyles (column: InternalDataTableHeader, y: number): CSSProperties | undefined {\n      if (!(props.sticky || props.fixedHeader) && !column.fixed) return undefined\n\n      const fixedSide = typeof column.fixed === 'string' ? column.fixed\n        : column.fixed ? 'start'\n        : 'none'\n\n      return {\n        position: 'sticky',\n        left: fixedSide === 'start' ? convertToUnit(column.fixedOffset) : undefined,\n        right: fixedSide === 'end' ? convertToUnit(column.fixedEndOffset) : undefined,\n        top: (props.sticky || props.fixedHeader) ? `calc(var(--v-table-header-height) * ${y})` : undefined,\n      }\n    }\n    function handleEnterKeyPress (event: KeyboardEvent, column: InternalDataTableHeader) {\n      if (event.key === 'Enter' && !props.disableSort) {\n        toggleSort(column, event)\n      }\n    }\n    function getSortIcon (column: InternalDataTableHeader) {\n      const item = sortBy.value.find(item => item.key === column.key)\n\n      switch (item?.order) {\n        case 'asc': return props.sortAscIcon\n        case 'desc': return props.sortDescIcon\n        default: return props.sortIcon ||\n          (\n            props.initialSortOrder === 'asc'\n              ? props.sortAscIcon\n              : props.sortDescIcon\n          )\n      }\n    }\n\n    const { backgroundColorClasses, backgroundColorStyles } = useBackgroundColor(() => props.color)\n\n    const { displayClasses, mobile } = useDisplay(props)\n\n    const slotProps = computed(() => ({\n      headers: headers.value,\n      columns: columns.value,\n      toggleSort,\n      isSorted,\n      sortBy: sortBy.value,\n      someSelected: someSelected.value,\n      allSelected: allSelected.value,\n      selectAll,\n      getSortIcon,\n    } satisfies HeadersSlotProps))\n\n    const headerCellClasses = computed(() => ([\n      'v-data-table__th',\n      {\n        'v-data-table__th--sticky': (props.sticky || props.fixedHeader),\n      },\n      displayClasses.value,\n      loaderClasses.value,\n    ]))\n\n    const VDataTableHeaderCell = ({ column, x, y }: { column: InternalDataTableHeader, x: number, y: number }) => {\n      const noPadding = column.key === 'data-table-select' || column.key === 'data-table-expand'\n      const isEmpty = column.key === 'data-table-group' && column.width === 0 && !column.title\n      const headerProps = mergeProps(props.headerProps ?? {}, column.headerProps ?? {})\n      const isSortable = column.sortable && !props.disableSort\n\n      return (\n        <VDataTableColumn\n          tag=\"th\"\n          align={ column.align }\n          class={[\n            {\n              'v-data-table__th--sortable': isSortable,\n              'v-data-table__th--sorted': isSorted(column),\n              'v-data-table__th--fixed': column.fixed,\n            },\n            ...headerCellClasses.value,\n          ]}\n          style={{\n            width: convertToUnit(column.width),\n            minWidth: convertToUnit(column.minWidth),\n            maxWidth: convertToUnit(column.maxWidth),\n            ...getFixedStyles(column, y),\n          }}\n          colspan={ column.colspan }\n          rowspan={ column.rowspan }\n          fixed={ column.fixed }\n          nowrap={ column.nowrap }\n          lastFixed={ column.lastFixed }\n          firstFixedEnd={ column.firstFixedEnd }\n          noPadding={ noPadding }\n          empty={ isEmpty }\n          tabindex={ isSortable ? 0 : undefined }\n          onClick={ isSortable ? (event: PointerEvent) => toggleSort(column, event) : undefined }\n          onKeydown={ isSortable ? (event: KeyboardEvent) => handleEnterKeyPress(event, column) : undefined }\n          { ...headerProps }\n        >\n          {{\n            default: () => {\n              const columnSlotName = `header.${column.key}` as const\n              const columnSlotProps: VDataTableHeaderCellColumnSlotProps = {\n                column,\n                selectAll,\n                isSorted,\n                toggleSort,\n                sortBy: sortBy.value,\n                someSelected: someSelected.value,\n                allSelected: allSelected.value,\n                getSortIcon,\n              }\n\n              if (slots[columnSlotName]) return slots[columnSlotName]!(columnSlotProps)\n\n              if (isEmpty) return ''\n\n              if (column.key === 'data-table-select') {\n                return slots['header.data-table-select']?.(columnSlotProps) ?? (showSelectAll.value && (\n                  <VCheckboxBtn\n                    color={ props.color }\n                    density={ props.density }\n                    modelValue={ allSelected.value }\n                    indeterminate={ someSelected.value && !allSelected.value }\n                    onUpdate:modelValue={ selectAll }\n                  />\n                ))\n              }\n\n              return (\n                <div class=\"v-data-table-header__content\">\n                  <span>{ column.title }</span>\n                  { column.sortable && !props.disableSort && (\n                    <VIcon\n                      key=\"icon\"\n                      class=\"v-data-table-header__sort-icon\"\n                      icon={ getSortIcon(column) }\n                    />\n                  )}\n                  { props.multiSort && isSorted(column) && (\n                    <div\n                      key=\"badge\"\n                      class={[\n                        'v-data-table-header__sort-badge',\n                        ...backgroundColorClasses.value,\n                      ]}\n                      style={ backgroundColorStyles.value }\n                    >\n                      { sortBy.value.findIndex(x => x.key === column.key) + 1 }\n                    </div>\n                  )}\n                </div>\n              )\n            },\n          }}\n        </VDataTableColumn>\n      )\n    }\n\n    const VDataTableMobileHeaderCell = () => {\n      const sortableColumns = computed<ItemProps['items']>(() => {\n        return columns.value.filter(column => column?.sortable && !props.disableSort)\n      })\n      const showSelectColumn = columns.value.find(column => column.key === 'data-table-select')\n      const sortingChips = computed<InternalDataTableHeader | InternalDataTableHeader[] | null>({\n        get: () => sortableColumns.value.filter(({ key }) => sortBy.value.some(v => v.key === key)),\n        set: val => {\n          const sortedColumns = wrapInArray(val)\n          const activeSortKeys = sortBy.value.map(v => v.key)\n          const newColumnsToSort = sortedColumns.filter(({ key }) => !activeSortKeys.includes(key!))\n          newColumnsToSort.forEach(column => toggleSort(column))\n          // sortBy is proxied model, needs nextTick after toggleSort\n          nextTick(() => sortBy.value = sortBy.value.filter(({ key }) => sortedColumns.some(c => c.key === key)))\n        },\n      })\n\n      return (\n        <VDataTableColumn\n          tag=\"th\"\n          class={[\n            ...headerCellClasses.value,\n          ]}\n          colspan={ headers.value.length + 1 }\n          { ...props.headerProps }\n        >\n          <div class=\"v-data-table-header__content\">\n            <VSelect\n              v-model={ sortingChips.value }\n              chips\n              color={ props.color }\n              class=\"v-data-table__td-sort-select\"\n              clearable\n              density=\"default\"\n              items={ sortableColumns.value }\n              label={ t('$vuetify.dataTable.sortBy') }\n              multiple={ props.multiSort }\n              variant=\"underlined\"\n              returnObject\n              onClick:clear={ () => sortBy.value = [] }\n            >\n              {{\n                append: showSelectColumn ? () => (\n                  <VCheckboxBtn\n                    color={ props.color }\n                    density=\"compact\"\n                    modelValue={ allSelected.value }\n                    indeterminate={ someSelected.value && !allSelected.value }\n                    onUpdate:modelValue={ () => selectAll(!allSelected.value) }\n                  />\n                ) : undefined,\n                chip: ({ internalItem }) => (\n                  <VChip\n                    onClick={ internalItem.raw.sortable ? () => toggleSort(internalItem.raw, undefined, true) : undefined }\n                    onMousedown={ (e: MouseEvent) => {\n                      e.preventDefault()\n                      e.stopPropagation()\n                    }}\n                  >\n                    { internalItem.title }\n                    <VIcon\n                      class={[\n                        'v-data-table__td-sort-icon',\n                        isSorted(internalItem.raw) && 'v-data-table__td-sort-icon-active',\n                      ]}\n                      icon={ getSortIcon(internalItem.raw) }\n                      size=\"small\"\n                    />\n                  </VChip>\n                ),\n              }}\n            </VSelect>\n          </div>\n        </VDataTableColumn>\n      )\n    }\n\n    useRender(() => {\n      return mobile.value ? (\n        <tr>\n          <VDataTableMobileHeaderCell />\n        </tr>\n      ) : (\n        <>\n          { slots.headers\n            ? slots.headers(slotProps.value)\n            : headers.value.map((row, y) => (\n              <tr>\n                { row.map((column, x) => (\n                  <VDataTableHeaderCell column={ column } x={ x } y={ y } />\n                ))}\n              </tr>\n            ))}\n\n          { props.loading && (\n            <tr class=\"v-data-table-progress\">\n              <th colspan={ columns.value.length }>\n                <LoaderSlot\n                  name=\"v-data-table-progress\"\n                  absolute\n                  active\n                  color={ typeof props.loading === 'boolean' || props.loading === 'true'\n                    ? props.color\n                    : props.loading }\n                  indeterminate\n                  v-slots={{ default: slots.loader }}\n                />\n              </th>\n            </tr>\n          )}\n        </>\n      )\n    })\n  },\n})\n\nexport type VDataTableHeaders = InstanceType<typeof VDataTableHeaders>\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/VDataTableRow.tsx",
    "content": "// Components\nimport { VDataTableColumn } from './VDataTableColumn'\nimport { VBtn } from '@/components/VBtn'\nimport { VCheckboxBtn } from '@/components/VCheckbox'\n\n// Composables\nimport { useExpanded } from './composables/expand'\nimport { useHeaders } from './composables/headers'\nimport { useSelection } from './composables/select'\nimport { useSort } from './composables/sort'\nimport { makeDensityProps } from '@/composables/density'\nimport { makeDisplayProps, useDisplay } from '@/composables/display'\nimport { IconValue } from '@/composables/icons'\n\n// Utilities\nimport { toDisplayString, withModifiers } from 'vue'\nimport { EventProp, genericComponent, getObjectValueByPath, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { CellProps, DataTableItem, ItemKeySlot } from './types'\nimport type { VDataTableHeaderCellColumnSlotProps } from './VDataTableHeaders'\nimport type { GenericProps } from '@/util'\n\nexport type VDataTableItemCellColumnSlotProps<T> = Omit<ItemKeySlot<T>, 'value'> & {\n  props: Record<string, unknown>\n}\n\nexport type VDataTableRowSlots<T> = {\n  'item.data-table-select': VDataTableItemCellColumnSlotProps<T>\n  'item.data-table-expand': VDataTableItemCellColumnSlotProps<T>\n  'header.data-table-select': VDataTableHeaderCellColumnSlotProps\n  'header.data-table-expand': VDataTableHeaderCellColumnSlotProps\n} & {\n  [key: `item.${string}`]: ItemKeySlot<T>\n  [key: `header.${string}`]: VDataTableHeaderCellColumnSlotProps\n}\n\nexport const makeVDataTableRowProps = propsFactory({\n  color: String,\n  index: Number,\n  item: Object as PropType<DataTableItem>,\n  cellProps: [Object, Function] as PropType<CellProps<any>>,\n  collapseIcon: {\n    type: IconValue,\n    default: '$collapse',\n  },\n  expandIcon: {\n    type: IconValue,\n    default: '$expand',\n  },\n\n  onClick: EventProp<[MouseEvent]>(),\n  onContextmenu: EventProp<[MouseEvent]>(),\n  onDblclick: EventProp<[MouseEvent]>(),\n\n  ...makeDensityProps(),\n  ...makeDisplayProps(),\n}, 'VDataTableRow')\n\nexport const VDataTableRow = genericComponent<new <T>(\n  props: {\n    item?: DataTableItem<T>\n    cellProps?: CellProps<T>\n  },\n  slots: VDataTableRowSlots<T>,\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VDataTableRow',\n\n  props: makeVDataTableRowProps(),\n\n  setup (props, { slots }) {\n    const { displayClasses, mobile } = useDisplay(props, 'v-data-table__tr')\n    const { isSelected, toggleSelect, someSelected, allSelected, selectAll } = useSelection()\n    const { isExpanded, toggleExpand } = useExpanded()\n    const { toggleSort, sortBy, isSorted } = useSort()\n    const { columns } = useHeaders()\n\n    useRender(() => (\n      <tr\n        class={[\n          'v-data-table__tr',\n          {\n            'v-data-table__tr--clickable': !!(props.onClick || props.onContextmenu || props.onDblclick),\n          },\n          displayClasses.value,\n        ]}\n        onClick={ props.onClick as any }\n        onContextmenu={ props.onContextmenu as any }\n        onDblclick={ props.onDblclick as any }\n      >\n        { props.item && columns.value.map((column, i) => {\n          const item = props.item!\n          const slotName = `item.${column.key}` as const\n          const headerSlotName = `header.${column.key}` as const\n          const slotProps = {\n            index: props.index!,\n            item: item.raw,\n            internalItem: item,\n            value: getObjectValueByPath(item.columns, column.key),\n            column,\n            isSelected,\n            toggleSelect,\n            isExpanded,\n            toggleExpand,\n          } satisfies ItemKeySlot<any>\n\n          const columnSlotProps: VDataTableHeaderCellColumnSlotProps = {\n            column,\n            selectAll,\n            isSorted,\n            toggleSort,\n            sortBy: sortBy.value,\n            someSelected: someSelected.value,\n            allSelected: allSelected.value,\n            getSortIcon: () => '',\n          }\n\n          const cellProps = typeof props.cellProps === 'function'\n            ? props.cellProps({\n              index: slotProps.index,\n              item: slotProps.item,\n              internalItem: slotProps.internalItem,\n              value: slotProps.value,\n              column,\n            })\n            : props.cellProps\n          const columnCellProps = typeof column.cellProps === 'function'\n            ? column.cellProps({\n              index: slotProps.index,\n              item: slotProps.item,\n              internalItem: slotProps.internalItem,\n              value: slotProps.value,\n            })\n            : column.cellProps\n\n          const noPadding = column.key === 'data-table-select' || column.key === 'data-table-expand'\n          const isEmpty = column.key === 'data-table-group' && column.width === 0 && !column.title\n\n          return (\n            <VDataTableColumn\n              align={ column.align }\n              indent={ column.indent }\n              class={{\n                'v-data-table__td--expanded-row': column.key === 'data-table-expand',\n                'v-data-table__td--select-row': column.key === 'data-table-select',\n              }}\n              fixed={ column.fixed }\n              fixedOffset={ column.fixedOffset }\n              fixedEndOffset={ column.fixedEndOffset }\n              lastFixed={ column.lastFixed }\n              firstFixedEnd={ column.firstFixedEnd }\n              maxWidth={ !mobile.value ? column.maxWidth : undefined }\n              noPadding={ noPadding }\n              empty={ isEmpty }\n              nowrap={ column.nowrap }\n              width={ !mobile.value ? column.width : undefined }\n              { ...cellProps }\n              { ...columnCellProps }\n            >\n              {{\n                default: () => {\n                  if (column.key === 'data-table-select') {\n                    return slots['item.data-table-select']?.({\n                      ...slotProps,\n                      props: {\n                        color: props.color,\n                        disabled: !item.selectable,\n                        modelValue: isSelected([item]),\n                        onClick: withModifiers(() => toggleSelect(item), ['stop']),\n                      },\n                    }) ?? (\n                      <VCheckboxBtn\n                        color={ props.color }\n                        disabled={ !item.selectable }\n                        density={ props.density }\n                        modelValue={ isSelected([item]) }\n                        onClick={ withModifiers(\n                          (event: Event) => toggleSelect(item, props.index, event as PointerEvent),\n                          ['stop']\n                        )}\n                      />\n                    )\n                  }\n\n                  if (column.key === 'data-table-expand') {\n                    return slots['item.data-table-expand']?.({\n                      ...slotProps,\n                      props: {\n                        icon: isExpanded(item) ? props.collapseIcon : props.expandIcon,\n                        size: 'small',\n                        variant: 'text',\n                        onClick: withModifiers(() => toggleExpand(item), ['stop']),\n                      },\n                    }) ?? (\n                      <VBtn\n                        icon={ isExpanded(item) ? props.collapseIcon : props.expandIcon }\n                        size=\"small\"\n                        variant=\"text\"\n                        onClick={ withModifiers(() => toggleExpand(item), ['stop']) }\n                      />\n                    )\n                  }\n\n                  if (slots[slotName] && !mobile.value) return slots[slotName](slotProps)\n\n                  const displayValue = toDisplayString(slotProps.value)\n\n                  return !mobile.value ? displayValue : (\n                    <>\n                      <div class=\"v-data-table__td-title\">\n                        { slots[headerSlotName]?.(columnSlotProps) ?? column.title }\n                      </div>\n\n                      <div class=\"v-data-table__td-value\">\n                        { slots[slotName]?.(slotProps) ?? displayValue }\n                      </div>\n                    </>\n                  )\n                },\n              }}\n            </VDataTableColumn>\n          )\n        })}\n      </tr>\n    ))\n  },\n})\n\nexport type VDataTableRow = InstanceType<typeof VDataTableRow>\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/VDataTableRows.tsx",
    "content": "// Components\nimport { makeVDataTableGroupHeaderRowProps, VDataTableGroupHeaderRow } from './VDataTableGroupHeaderRow'\nimport { makeVDataTableRowProps, VDataTableRow } from './VDataTableRow'\n\n// Composables\nimport { useExpanded } from './composables/expand'\nimport { useGroupBy } from './composables/group'\nimport { useHeaders } from './composables/headers'\nimport { useSelection } from './composables/select'\nimport { makeDisplayProps, useDisplay } from '@/composables/display'\nimport { useLocale } from '@/composables/locale'\n\n// Utilities\nimport { Fragment, mergeProps } from 'vue'\nimport { genericComponent, getPrefixedEventHandlers, pick, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { Group, GroupSummary } from './composables/group'\nimport type { CellProps, DataTableItem, GroupHeaderSlot, GroupSummarySlot, ItemSlot, RowProps } from './types'\nimport type { VDataTableGroupHeaderRowSlots } from './VDataTableGroupHeaderRow'\nimport type { VDataTableRowSlots } from './VDataTableRow'\nimport type { GenericProps } from '@/util'\n\nexport type VDataTableRowsSlots<T> = VDataTableGroupHeaderRowSlots & VDataTableRowSlots<T> & {\n  item: ItemSlot<T> & { props: Record<string, any> }\n  loading: never\n  'group-header': GroupHeaderSlot\n  'group-summary': GroupSummarySlot\n  'no-data': never\n  'expanded-row': ItemSlot<T>\n}\n\nexport const makeVDataTableRowsProps = propsFactory({\n  color: String,\n  loading: [Boolean, String],\n  loadingText: {\n    type: String,\n    default: '$vuetify.dataIterator.loadingText',\n  },\n  hideNoData: Boolean,\n  items: {\n    type: Array as PropType<readonly (DataTableItem | Group | GroupSummary)[]>,\n    default: () => ([]),\n  },\n  noDataText: {\n    type: String,\n    default: '$vuetify.noDataText',\n  },\n  rowProps: [Object, Function] as PropType<RowProps<any>>,\n  cellProps: [Object, Function] as PropType<CellProps<any>>,\n\n  ...pick(makeVDataTableRowProps(), ['collapseIcon', 'expandIcon', 'density']),\n  ...pick(makeVDataTableGroupHeaderRowProps(), ['groupCollapseIcon', 'groupExpandIcon', 'density']),\n  ...makeDisplayProps(),\n}, 'VDataTableRows')\n\nexport const VDataTableRows = genericComponent<new <T>(\n  props: {\n    items?: readonly (DataTableItem<T> | Group<T> | GroupSummary<T>)[]\n  },\n  slots: VDataTableRowsSlots<T>,\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VDataTableRows',\n\n  inheritAttrs: false,\n\n  props: makeVDataTableRowsProps(),\n\n  setup (props, { attrs, slots }) {\n    const { columns } = useHeaders()\n    const { expandOnClick, toggleExpand, isExpanded } = useExpanded()\n    const { isSelected, toggleSelect } = useSelection()\n    const { toggleGroup, isGroupOpen } = useGroupBy()\n    const { t } = useLocale()\n    const { mobile } = useDisplay(props)\n\n    useRender(() => {\n      const groupHeaderRowProps = pick(props, ['groupCollapseIcon', 'groupExpandIcon', 'density'])\n\n      if (props.loading && (!props.items.length || slots.loading)) {\n        return (\n          <tr\n            class=\"v-data-table-rows-loading\"\n            key=\"loading\"\n          >\n            <td colspan={ columns.value.length }>\n              { slots.loading?.() ?? t(props.loadingText) }\n            </td>\n          </tr>\n        )\n      }\n\n      if (!props.loading && !props.items.length && !props.hideNoData) {\n        return (\n          <tr\n            class=\"v-data-table-rows-no-data\"\n            key=\"no-data\"\n          >\n            <td colspan={ columns.value.length }>\n              { slots['no-data']?.() ?? t(props.noDataText) }\n            </td>\n          </tr>\n        )\n      }\n\n      return (\n        <>\n          { props.items.map((item, index) => {\n            if (item.type === 'group') {\n              const slotProps = {\n                index,\n                item,\n                columns: columns.value,\n                isExpanded,\n                toggleExpand,\n                isSelected,\n                toggleSelect,\n                toggleGroup,\n                isGroupOpen,\n              } satisfies GroupHeaderSlot\n\n              return slots['group-header'] ? slots['group-header'](slotProps) : (\n                <VDataTableGroupHeaderRow\n                  key={ `group-header_${item.id}` }\n                  item={ item }\n                  { ...getPrefixedEventHandlers(attrs, ':groupHeader', () => slotProps) }\n                  { ...groupHeaderRowProps }\n                  v-slots={ slots }\n                />\n              )\n            }\n\n            if (item.type === 'group-summary') {\n              const slotProps = {\n                index,\n                item,\n                columns: columns.value,\n                toggleGroup,\n              } satisfies GroupSummarySlot\n\n              return slots['group-summary']?.(slotProps) ?? ''\n            }\n\n            const slotProps = {\n              index: item.virtualIndex ?? index,\n              item: item.raw,\n              internalItem: item,\n              columns: columns.value,\n              isExpanded,\n              toggleExpand,\n              isSelected,\n              toggleSelect,\n            } satisfies ItemSlot<any>\n\n            const itemSlotProps = {\n              ...slotProps,\n              props: mergeProps(\n                {\n                  key: `item_${item.key ?? item.index}`,\n                  onClick: expandOnClick.value ? () => {\n                    toggleExpand(item)\n                  } : undefined,\n                  index,\n                  item,\n                  color: props.color,\n                  cellProps: props.cellProps,\n                  collapseIcon: props.collapseIcon,\n                  expandIcon: props.expandIcon,\n                  density: props.density,\n                  mobile: mobile.value,\n                },\n                getPrefixedEventHandlers(attrs, ':row', () => slotProps),\n                typeof props.rowProps === 'function'\n                  ? props.rowProps({\n                    item: slotProps.item,\n                    index: slotProps.index,\n                    internalItem: slotProps.internalItem,\n                  })\n                  : props.rowProps,\n              ),\n            }\n\n            return (\n              <Fragment key={ itemSlotProps.props.key as string }>\n                { slots.item ? slots.item(itemSlotProps) : (\n                  <VDataTableRow\n                    { ...itemSlotProps.props }\n                    v-slots={ slots }\n                  />\n                )}\n\n                { isExpanded(item) && slots['expanded-row']?.(slotProps) }\n              </Fragment>\n            )\n          })}\n        </>\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VDataTableRows = InstanceType<typeof VDataTableRows>\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/VDataTableServer.tsx",
    "content": "// Components\nimport { makeDataTableProps } from './VDataTable'\nimport { makeVDataTableFooterProps, VDataTableFooter } from './VDataTableFooter'\nimport { VDataTableHeaders } from './VDataTableHeaders'\nimport { VDataTableRows } from './VDataTableRows'\nimport { VDivider } from '@/components/VDivider'\nimport { VTable } from '@/components/VTable'\n\n// Composables\nimport { provideExpanded } from './composables/expand'\nimport { createGroupBy, provideGroupBy, useGroupedItems } from './composables/group'\nimport { createHeaders } from './composables/headers'\nimport { useDataTableItems } from './composables/items'\nimport { useOptions } from './composables/options'\nimport { createPagination, makeDataTablePaginateProps, providePagination } from './composables/paginate'\nimport { provideSelection } from './composables/select'\nimport { createSort, provideSort } from './composables/sort'\nimport { provideDefaults } from '@/composables/defaults'\n\n// Utilities\nimport { computed, provide, toRef, toRefs } from 'vue'\nimport { genericComponent, omit, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { DeepReadonly } from 'vue'\nimport type { VDataTableSlotProps, VDataTableSlots } from './VDataTable'\nimport type { CellProps, DataTableHeader, RowProps } from '@/components/VDataTable/types'\nimport type { GenericProps, SelectItemKey } from '@/util'\n\nexport const makeVDataTableServerProps = propsFactory({\n  itemsLength: {\n    type: [Number, String],\n    required: true,\n  },\n\n  ...makeDataTablePaginateProps(),\n  ...makeDataTableProps(),\n  ...makeVDataTableFooterProps(),\n}, 'VDataTableServer')\n\ntype ItemType<T> = T extends readonly (infer U)[] ? U : never\n\nexport const VDataTableServer = genericComponent<new <T extends readonly any[], V>(\n  props: {\n    items?: T\n    itemValue?: SelectItemKey<ItemType<T>>\n    rowProps?: RowProps<ItemType<T>>\n    cellProps?: CellProps<ItemType<T>>\n    itemSelectable?: SelectItemKey<ItemType<T>>\n    headers?: DeepReadonly<DataTableHeader<ItemType<T>>[]>\n    modelValue?: V\n    'onUpdate:modelValue'?: (value: V) => void\n  },\n  slots: VDataTableSlots<ItemType<T>>,\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VDataTableServer',\n\n  props: makeVDataTableServerProps(),\n\n  emits: {\n    'update:modelValue': (value: any[]) => true,\n    'update:page': (page: number) => true,\n    'update:itemsPerPage': (page: number) => true,\n    'update:sortBy': (sortBy: any) => true,\n    'update:options': (options: any) => true,\n    'update:expanded': (options: any) => true,\n    'update:groupBy': (value: any) => true,\n  },\n\n  setup (props, { attrs, slots }) {\n    const { groupBy } = createGroupBy(props)\n    const { initialSortOrder, sortBy, multiSort, mustSort } = createSort(props)\n    const { page, itemsPerPage } = createPagination(props)\n    const { disableSort } = toRefs(props)\n    const itemsLength = computed(() => parseInt(props.itemsLength, 10))\n\n    const { columns, headers } = createHeaders(props, {\n      groupBy,\n      showSelect: toRef(() => props.showSelect),\n      showExpand: toRef(() => props.showExpand),\n    })\n\n    const { items } = useDataTableItems(props, columns)\n\n    const { toggleSort } = provideSort({ initialSortOrder, sortBy, multiSort, mustSort, page })\n\n    const { opened, isGroupOpen, toggleGroup, extractRows } = provideGroupBy({ groupBy, sortBy, disableSort })\n\n    const { pageCount, setItemsPerPage, prevPage, nextPage, setPage } = providePagination({ page, itemsPerPage, itemsLength })\n\n    const { flatItems } = useGroupedItems(items, groupBy, opened, () => !!slots['group-summary'])\n\n    const { isSelected, select, selectAll, toggleSelect, someSelected, allSelected } = provideSelection(props, {\n      allItems: items,\n      currentPage: items,\n    })\n\n    const { isExpanded, toggleExpand } = provideExpanded(props)\n\n    const itemsWithoutGroups = computed(() => extractRows(items.value))\n\n    useOptions({\n      page,\n      itemsPerPage,\n      sortBy,\n      groupBy,\n      search: toRef(() => props.search),\n    })\n\n    provide('v-data-table', {\n      toggleSort,\n      sortBy,\n    })\n\n    provideDefaults({\n      VDataTableRows: {\n        hideNoData: toRef(() => props.hideNoData),\n        noDataText: toRef(() => props.noDataText),\n        loading: toRef(() => props.loading),\n        loadingText: toRef(() => props.loadingText),\n      },\n    })\n\n    const slotProps = computed<VDataTableSlotProps<any>>(() => ({\n      page: page.value,\n      itemsPerPage: itemsPerPage.value,\n      sortBy: sortBy.value,\n      pageCount: pageCount.value,\n      toggleSort,\n      setItemsPerPage,\n      prevPage,\n      nextPage,\n      setPage,\n      someSelected: someSelected.value,\n      allSelected: allSelected.value,\n      isSelected,\n      select,\n      selectAll,\n      toggleSelect,\n      isExpanded,\n      toggleExpand,\n      isGroupOpen,\n      toggleGroup,\n      items: itemsWithoutGroups.value.map(item => item.raw),\n      internalItems: itemsWithoutGroups.value,\n      groupedItems: flatItems.value,\n      columns: columns.value,\n      headers: headers.value,\n    }))\n\n    useRender(() => {\n      const dataTableFooterProps = VDataTableFooter.filterProps(props)\n      const dataTableHeadersProps = VDataTableHeaders.filterProps(omit(props, ['multiSort']))\n      const dataTableRowsProps = VDataTableRows.filterProps(props)\n      const tableProps = VTable.filterProps(props)\n\n      return (\n        <VTable\n          class={[\n            'v-data-table',\n            {\n              'v-data-table--loading': props.loading,\n            },\n            props.class,\n          ]}\n          style={ props.style }\n          { ...tableProps }\n          fixedHeader={ props.fixedHeader || props.sticky }\n        >\n          {{\n            top: () => slots.top?.(slotProps.value),\n            default: () => slots.default ? slots.default(slotProps.value) : (\n              <>\n                { slots.colgroup?.(slotProps.value) }\n                { !props.hideDefaultHeader && (\n                  <thead key=\"thead\" class=\"v-data-table__thead\" role=\"rowgroup\">\n                    <VDataTableHeaders\n                      { ...dataTableHeadersProps }\n                      multiSort={ !!props.multiSort }\n                      v-slots={ slots }\n                    />\n                  </thead>\n                )}\n                { slots.thead?.(slotProps.value) }\n                { !props.hideDefaultBody && (\n                  <tbody class=\"v-data-table__tbody\" role=\"rowgroup\">\n                    { slots['body.prepend']?.(slotProps.value) }\n                    { slots.body ? slots.body(slotProps.value) : (\n                      <VDataTableRows\n                        { ...attrs }\n                        { ...dataTableRowsProps }\n                        items={ flatItems.value }\n                        v-slots={ slots }\n                      />\n                    )}\n                    { slots['body.append']?.(slotProps.value) }\n                  </tbody>\n                )}\n                { slots.tbody?.(slotProps.value) }\n                { slots.tfoot?.(slotProps.value) }\n              </>\n            ),\n            bottom: () => slots.bottom ? slots.bottom(slotProps.value) : !props.hideDefaultFooter && (\n              <>\n                <VDivider />\n\n                <VDataTableFooter\n                  { ...dataTableFooterProps }\n                  v-slots={{\n                    prepend: slots['footer.prepend'],\n                  }}\n                />\n              </>\n            ),\n          }}\n        </VTable>\n      )\n    })\n  },\n})\n\nexport type VDataTableServer = InstanceType<typeof VDataTableServer>\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/VDataTableVirtual.tsx",
    "content": "// Components\nimport { makeDataTableProps } from './VDataTable'\nimport { VDataTableHeaders } from './VDataTableHeaders'\nimport { VDataTableRow } from './VDataTableRow'\nimport { VDataTableRows } from './VDataTableRows'\nimport { VTable } from '@/components/VTable'\nimport { VVirtualScrollItem } from '@/components/VVirtualScroll/VVirtualScrollItem'\n\n// Composables\nimport { provideExpanded } from './composables/expand'\nimport { createGroupBy, makeDataTableGroupProps, provideGroupBy, useGroupedItems } from './composables/group'\nimport { createHeaders } from './composables/headers'\nimport { useDataTableItems } from './composables/items'\nimport { useOptions } from './composables/options'\nimport { provideSelection } from './composables/select'\nimport { createSort, provideSort, useSortedItems } from './composables/sort'\nimport { provideDefaults } from '@/composables/defaults'\nimport { makeFilterProps, useFilter } from '@/composables/filter'\nimport { makeVirtualProps, useVirtual } from '@/composables/virtual'\n\n// Utilities\nimport { computed, shallowRef, toRef, toRefs } from 'vue'\nimport { convertToUnit, genericComponent, omit, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { DeepReadonly } from 'vue'\nimport type { VDataTableSlotProps } from './VDataTable'\nimport type { VDataTableHeadersSlots } from './VDataTableHeaders'\nimport type { VDataTableRowsSlots } from './VDataTableRows'\nimport type { CellProps, DataTableHeader, RowProps } from '@/components/VDataTable/types'\nimport type { GenericProps, SelectItemKey, TemplateRef } from '@/util'\n\ntype VDataTableVirtualSlotProps<T> = Omit<\n  VDataTableSlotProps<T>,\n  | 'setItemsPerPage'\n  | 'page'\n  | 'pageCount'\n  | 'itemsPerPage'\n  | 'prevPage'\n  | 'nextPage'\n  | 'setPage'\n>\n\nexport type VDataTableVirtualSlots<T> = VDataTableRowsSlots<T> & VDataTableHeadersSlots & {\n  colgroup: VDataTableVirtualSlotProps<T>\n  top: VDataTableVirtualSlotProps<T>\n  headers: VDataTableHeadersSlots['headers']\n  tbody: VDataTableVirtualSlotProps<T>\n  thead: VDataTableVirtualSlotProps<T>\n  tfoot: VDataTableVirtualSlotProps<T>\n  bottom: VDataTableVirtualSlotProps<T>\n  'body.prepend': VDataTableVirtualSlotProps<T>\n  'body.append': VDataTableVirtualSlotProps<T>\n  item: {\n    itemRef: TemplateRef\n  }\n}\n\nexport const makeVDataTableVirtualProps = propsFactory({\n  ...omit(makeDataTableProps(), ['hideDefaultFooter']),\n  ...makeDataTableGroupProps(),\n  ...makeVirtualProps(),\n  ...makeFilterProps(),\n}, 'VDataTableVirtual')\n\ntype ItemType<T> = T extends readonly (infer U)[] ? U : never\n\nexport const VDataTableVirtual = genericComponent<new <T extends readonly any[], V>(\n  props: {\n    items?: T\n    itemValue?: SelectItemKey<ItemType<T>>\n    rowProps?: RowProps<ItemType<T>>\n    cellProps?: CellProps<ItemType<T>>\n    itemSelectable?: SelectItemKey<ItemType<T>>\n    headers?: DeepReadonly<DataTableHeader<ItemType<T>>[]>\n    modelValue?: V\n    'onUpdate:modelValue'?: (value: V) => void\n  },\n  slots: VDataTableVirtualSlots<ItemType<T>>,\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VDataTableVirtual',\n\n  props: makeVDataTableVirtualProps(),\n\n  emits: {\n    'update:modelValue': (value: any[]) => true,\n    'update:sortBy': (value: any) => true,\n    'update:options': (value: any) => true,\n    'update:groupBy': (value: any) => true,\n    'update:expanded': (value: any) => true,\n  },\n\n  setup (props, { attrs, slots }) {\n    const { groupBy } = createGroupBy(props)\n    const { initialSortOrder, sortBy, multiSort, mustSort } = createSort(props)\n    const { disableSort } = toRefs(props)\n\n    const {\n      columns,\n      headers,\n      filterFunctions,\n      sortFunctions,\n      sortRawFunctions,\n    } = createHeaders(props, {\n      groupBy,\n      showSelect: toRef(() => props.showSelect),\n      showExpand: toRef(() => props.showExpand),\n    })\n    const { items } = useDataTableItems(props, columns)\n\n    const search = toRef(() => props.search)\n    const { filteredItems } = useFilter(props, items, search, {\n      transform: item => item.columns,\n      customKeyFilter: filterFunctions,\n    })\n\n    const { toggleSort } = provideSort({ initialSortOrder, sortBy, multiSort, mustSort })\n    const { sortByWithGroups, opened, extractRows, isGroupOpen, toggleGroup } = provideGroupBy({ groupBy, sortBy, disableSort })\n\n    const { sortedItems } = useSortedItems(props, filteredItems, sortByWithGroups, {\n      transform: item => ({ ...item.raw, ...item.columns }),\n      sortFunctions,\n      sortRawFunctions,\n    })\n    const { flatItems } = useGroupedItems(sortedItems, groupBy, opened, () => !!slots['group-summary'])\n\n    const allItems = computed(() => extractRows(flatItems.value))\n\n    const { isSelected, select, selectAll, toggleSelect, someSelected, allSelected } = provideSelection(props, {\n      allItems,\n      currentPage: allItems,\n    })\n    const { isExpanded, toggleExpand } = provideExpanded(props)\n\n    const {\n      containerRef,\n      markerRef,\n      paddingTop,\n      paddingBottom,\n      computedItems,\n      handleItemResize,\n      handleScroll,\n      handleScrollend,\n      calculateVisibleItems,\n      scrollToIndex,\n    } = useVirtual(props, flatItems)\n\n    const displayItems = computed(() =>\n      computedItems.value\n        .map(item => ({\n          ...item.raw,\n          virtualIndex: item.index,\n        }))\n    )\n\n    useOptions({\n      sortBy,\n      page: shallowRef(1),\n      itemsPerPage: shallowRef(-1),\n      groupBy,\n      search,\n    })\n\n    provideDefaults({\n      VDataTableRows: {\n        hideNoData: toRef(() => props.hideNoData),\n        noDataText: toRef(() => props.noDataText),\n        loading: toRef(() => props.loading),\n        loadingText: toRef(() => props.loadingText),\n      },\n    })\n\n    const slotProps = computed<VDataTableVirtualSlotProps<any>>(() => ({\n      sortBy: sortBy.value,\n      toggleSort,\n      someSelected: someSelected.value,\n      allSelected: allSelected.value,\n      isSelected,\n      select,\n      selectAll,\n      toggleSelect,\n      isExpanded,\n      toggleExpand,\n      isGroupOpen,\n      toggleGroup,\n      items: allItems.value.map(item => item.raw),\n      internalItems: allItems.value,\n      groupedItems: flatItems.value,\n      columns: columns.value,\n      headers: headers.value,\n    }))\n\n    useRender(() => {\n      const dataTableHeadersProps = VDataTableHeaders.filterProps(omit(props, ['multiSort']))\n      const dataTableRowsProps = VDataTableRows.filterProps(props)\n      const tableProps = VTable.filterProps(props)\n\n      return (\n        <VTable\n          class={[\n            'v-data-table',\n            {\n              'v-data-table--loading': props.loading,\n            },\n            props.class,\n          ]}\n          style={ props.style }\n          { ...tableProps }\n          fixedHeader={ props.fixedHeader || props.sticky }\n        >\n          {{\n            top: () => slots.top?.(slotProps.value),\n            wrapper: () => (\n              <div\n                ref={ containerRef }\n                onScrollPassive={ handleScroll }\n                onScrollend={ handleScrollend }\n                class=\"v-table__wrapper\"\n                style={{\n                  height: convertToUnit(props.height),\n                }}\n              >\n                <table>\n                  { slots.colgroup?.(slotProps.value) }\n                  { !props.hideDefaultHeader && (\n                    <thead key=\"thead\">\n                      <VDataTableHeaders\n                        { ...dataTableHeadersProps }\n                        multiSort={ !!props.multiSort }\n                        v-slots={ slots }\n                      />\n                    </thead>\n                  )}\n                  { slots.thead?.(slotProps.value) }\n                  { !props.hideDefaultBody && (\n                    <tbody key=\"tbody\">\n                      <tr ref={ markerRef } style={{ height: convertToUnit(paddingTop.value), border: 0 }}>\n                        <td colspan={ columns.value.length } style={{ height: 0, border: 0 }}></td>\n                      </tr>\n\n                      { slots['body.prepend']?.(slotProps.value) }\n\n                      <VDataTableRows\n                        { ...attrs }\n                        { ...dataTableRowsProps }\n                        items={ displayItems.value }\n                      >\n                        {{\n                          ...slots,\n                          item: itemSlotProps => (\n                            <VVirtualScrollItem\n                              key={ itemSlotProps.internalItem.index }\n                              renderless\n                              onUpdate:height={ height => handleItemResize(itemSlotProps.internalItem.index, height) }\n                            >\n                              { ({ itemRef }) => (\n                                slots.item?.({ ...itemSlotProps, itemRef }) ?? (\n                                  <VDataTableRow\n                                    { ...itemSlotProps.props }\n                                    ref={ itemRef }\n                                    key={ itemSlotProps.internalItem.index }\n                                    index={ itemSlotProps.index }\n                                    v-slots={ slots }\n                                  />\n                                )\n                              )}\n                            </VVirtualScrollItem>\n                          ),\n                        }}\n                      </VDataTableRows>\n\n                      { slots['body.append']?.(slotProps.value) }\n\n                      <tr style={{ height: convertToUnit(paddingBottom.value), border: 0 }}>\n                        <td colspan={ columns.value.length } style={{ height: 0, border: 0 }}></td>\n                      </tr>\n                    </tbody>\n                  )}\n                  { slots.tbody?.(slotProps.value) }\n                  { slots.tfoot?.(slotProps.value) }\n                </table>\n              </div>\n            ),\n            bottom: () => slots.bottom?.(slotProps.value),\n          }}\n        </VTable>\n      )\n    })\n\n    return {\n      calculateVisibleItems,\n      scrollToIndex,\n    }\n  },\n})\n\nexport type VDataTableVirtual = InstanceType<typeof VDataTableVirtual>\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/__tests__/MobileRow.spec.ts",
    "content": "// @ts-nocheck\n/* eslint-disable */\n\n// import MobileRow from '../MobileRow'\nimport {\n  mount,\n  Wrapper,\n  MountOptions,\n} from '@vue/test-utils'\n// import Vue from 'vue'\n\ndescribe.skip('MobileRow', () => {\n  type Instance = InstanceType<typeof MobileRow>\n  let mountFunction: (options?: MountOptions<Instance>) => Wrapper<Instance>\n  beforeEach(() => {\n    mountFunction = (options?: MountOptions<Instance>) => {\n      return mount(MobileRow, options)\n    }\n  })\n\n  it('should render without slots', () => {\n    const wrapper = mountFunction({\n      context: {\n        props: {\n          headers: [\n            { text: 'Petrol', value: 'petrol' },\n            { text: 'Diesel', value: 'diesel' },\n          ],\n          item: {\n            petrol: 0.68,\n            diesel: 0.65,\n          },\n        },\n      },\n    })\n\n    expect(wrapper.findAll('tr')).toHaveLength(1)\n    expect(wrapper.findAll('td')).toHaveLength(2)\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render non-string values', () => {\n    const wrapper = mountFunction({\n      context: {\n        props: {\n          headers: [\n            { value: 'string' },\n            { value: 'number' },\n            { value: 'array' },\n            { value: 'boolean' },\n            { value: 'object' },\n            { value: 'undefined' },\n            { value: 'null' },\n          ],\n          item: {\n            string: 'string',\n            number: 12.34,\n            array: [1, 2],\n            boolean: false,\n            object: { foo: 'bar' },\n            null: null,\n          },\n        },\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render with regular slots', () => {\n    const wrapper = mountFunction({\n      context: {\n        props: {\n          headers: [\n            { text: 'Petrol', value: 'petrol' },\n            { text: 'Diesel', value: 'diesel' },\n          ],\n        },\n      },\n      slots: {\n        petrol: '<p class=\"test\">$0.68</p>',\n        diesel: '<p class=\"test\">$0.65</p>',\n      },\n    })\n\n    expect(wrapper.findAll('tr')).toHaveLength(1)\n    expect(wrapper.findAll('td')).toHaveLength(2)\n    expect(wrapper.findAll('p.test')).toHaveLength(2)\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render with scoped slots', () => {\n    const vm = new Vue()\n    const wrapper = mountFunction({\n      context: {\n        props: {\n          headers: [\n            { text: 'Petrol', value: 'petrol' },\n            { text: 'Diesel', value: 'diesel' },\n          ],\n          item: {\n            petrol: 0.68,\n            diesel: 0.65,\n          },\n        },\n      },\n      scopedSlots: {\n        petrol: props => vm.$createElement('p', { staticClass: `test ${props.header.value}` }, [props.value]),\n        diesel: props => vm.$createElement('p', { staticClass: `test ${props.header.value}` }, [props.value]),\n      },\n    })\n\n    expect(wrapper.findAll('tr')).toHaveLength(1)\n    expect(wrapper.findAll('td')).toHaveLength(2)\n    expect(wrapper.findAll('p.test')).toHaveLength(2)\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render without header when hideDefaultHeader: true', () => {\n    const wrapper = mountFunction({\n      context: {\n        props: {\n          headers: [\n            { text: 'Petrol', value: 'petrol' },\n            { text: 'Diesel', value: 'diesel' },\n          ],\n          hideDefaultHeader: true,\n          item: {\n            petrol: 0.68,\n            diesel: 0.65,\n          },\n        },\n      },\n    })\n\n    expect(wrapper.findAll('tr')).toHaveLength(1)\n    expect(wrapper.findAll('td')).toHaveLength(2)\n    expect(wrapper.findAll('.v-data-table__mobile-row__header')).toHaveLength(0)\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/__tests__/Row.spec.ts",
    "content": "// @ts-nocheck\n/* eslint-disable */\n\n// import Row from '../Row'\nimport {\n  mount,\n  Wrapper,\n  MountOptions,\n} from '@vue/test-utils'\n// import Vue from 'vue'\n\ndescribe.skip('Table Row', () => {\n  type Instance = InstanceType<typeof Row>\n  let mountFunction: (options?: MountOptions<Instance>) => Wrapper<Instance>\n  beforeEach(() => {\n    mountFunction = (options?: MountOptions<Instance>) => {\n      return mount(Row, options)\n    }\n  })\n\n  it('should render without slots', () => {\n    const wrapper = mountFunction({\n      context: {\n        props: {\n          headers: [\n            { text: 'Petrol', value: 'petrol' },\n            { text: 'Diesel', value: 'diesel' },\n          ],\n          item: {\n            petrol: 0.68,\n            diesel: 0.65,\n          },\n        },\n      },\n    })\n\n    expect(wrapper.findAll('tr')).toHaveLength(1)\n    expect(wrapper.findAll('td')).toHaveLength(2)\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render non-string values', () => {\n    const wrapper = mountFunction({\n      context: {\n        props: {\n          headers: [\n            { value: 'string' },\n            { value: 'number' },\n            { value: 'array' },\n            { value: 'boolean' },\n            { value: 'object' },\n            { value: 'undefined' },\n            { value: 'null' },\n          ],\n          item: {\n            string: 'string',\n            number: 12.34,\n            array: [1, 2],\n            boolean: false,\n            object: { foo: 'bar' },\n            null: null,\n          },\n        },\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render with cellClass', () => {\n    const wrapper = mountFunction({\n      context: {\n        props: {\n          headers: [\n            { text: 'Petrol', value: 'petrol', cellClass: 'a' },\n            { text: 'Diesel', value: 'diesel', cellClass: ['b', 'c'] },\n          ],\n          item: {\n            petrol: 0.68,\n            diesel: 0.65,\n          },\n        },\n      },\n    })\n\n    const tds = wrapper.findAll('td')\n    expect(tds.at(0).classes()).toContain('a')\n    expect(tds.at(1).classes()).toContain('b')\n    expect(tds.at(1).classes()).toContain('c')\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it.skip('should render with regular slots', () => {\n    const wrapper = mountFunction({\n      context: {\n        props: {\n          headers: [\n            { text: 'Petrol', value: 'petrol' },\n            { text: 'Diesel', value: 'diesel' },\n          ],\n        },\n      },\n      slots: {\n        'column.petrol': '<p class=\"test\">$0.68</p>',\n        'column.diesel': '<p class=\"test\">$0.65</p>',\n      },\n    })\n\n    expect(wrapper.findAll('tr')).toHaveLength(1)\n    expect(wrapper.findAll('td')).toHaveLength(2)\n    expect(wrapper.findAll('p.test')).toHaveLength(2)\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it.skip('should render with scoped slots', () => {\n    const vm = new Vue()\n    const wrapper = mountFunction({\n      context: {\n        props: {\n          headers: [\n            { text: 'Petrol', value: 'petrol' },\n            { text: 'Diesel', value: 'diesel' },\n          ],\n          item: {\n            petrol: 0.68,\n            diesel: 0.65,\n          },\n        },\n      },\n      scopedSlots: {\n        'column.petrol': props => vm.$createElement('p', { staticClass: `test ${props.header.value}` }, [props.value]),\n        'column.diesel': props => vm.$createElement('p', { staticClass: `test ${props.header.value}` }, [props.value]),\n      },\n    })\n\n    expect(wrapper.findAll('tr')).toHaveLength(1)\n    expect(wrapper.findAll('td')).toHaveLength(2)\n    expect(wrapper.findAll('p.test')).toHaveLength(2)\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/__tests__/RowGroup.spec.ts",
    "content": "// @ts-nocheck\n/* eslint-disable */\n\n// import RowGroup from '../RowGroup'\nimport {\n  mount,\n  Wrapper,\n  MountOptions,\n} from '@vue/test-utils'\n\ndescribe.skip('Table RowGroup', () => {\n  type Instance = InstanceType<typeof RowGroup>\n  let mountFunction: (options?: MountOptions<Instance>) => Wrapper<Instance>\n  beforeEach(() => {\n    mountFunction = (options?: MountOptions<Instance>) => {\n      return mount(RowGroup, options)\n    }\n  })\n\n  it('should render with \"column.summary\" slot', () => {\n    const wrapper = mountFunction({\n      slots: {\n        'column.summary': '<div></div>',\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render with \"row.summary\" slot', () => {\n    const wrapper = mountFunction({\n      slots: {\n        'row.summary': '<div></div>',\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/__tests__/VDataTable.spec.cy.tsx",
    "content": "/// <reference types=\"../../../../types/cypress\" />\n\n// Components\nimport { VDataTable } from '..'\nimport { Application } from '../../../../cypress/templates'\n\n// Utilities\nimport { ref } from 'vue'\n\nconst DESSERT_HEADERS = [\n  { title: 'Dessert (100g serving)', key: 'name' },\n  { title: 'Calories', key: 'calories' },\n  { title: 'Fat (g)', key: 'fat' },\n  { title: 'Carbs (g)', key: 'carbs' },\n  { title: 'Protein (g)', key: 'protein' },\n  { title: 'Iron (%)', key: 'iron' },\n  { title: 'Group', key: 'group' },\n]\n\nconst DESSERT_ITEMS = [\n  {\n    name: 'Frozen Yogurt',\n    calories: 159,\n    fat: 6.0,\n    carbs: 24,\n    protein: 4.0,\n    iron: '1%',\n    group: 1,\n  },\n  {\n    name: 'Ice cream sandwich',\n    calories: 237,\n    fat: 9.0,\n    carbs: 37,\n    protein: 4.3,\n    iron: '1%',\n    group: 3,\n  },\n  {\n    name: 'Eclair',\n    calories: 262,\n    fat: 16.0,\n    carbs: 23,\n    protein: 6.0,\n    iron: '7%',\n    group: 2,\n  },\n  {\n    name: 'Cupcake',\n    calories: 305,\n    fat: 3.7,\n    carbs: 67,\n    protein: 4.3,\n    iron: '8%',\n    group: 2,\n  },\n  {\n    name: 'Gingerbread',\n    calories: 356,\n    fat: 16.0,\n    carbs: 49,\n    protein: 3.9,\n    iron: '16%',\n    group: 3,\n  },\n  {\n    name: 'Jelly bean',\n    calories: 375,\n    fat: 0.0,\n    carbs: 94,\n    protein: 0.0,\n    iron: '0%',\n    group: 1,\n  },\n  {\n    name: 'Lollipop',\n    calories: 392,\n    fat: 0.2,\n    carbs: 98,\n    protein: 0,\n    iron: '2%',\n    group: 2,\n  },\n  {\n    name: 'Honeycomb',\n    calories: 408,\n    fat: 3.2,\n    carbs: 87,\n    protein: 6.5,\n    iron: '45%',\n    group: 3,\n  },\n  {\n    name: 'Donut',\n    calories: 452,\n    fat: 25.0,\n    carbs: 51,\n    protein: 4.9,\n    iron: '22%',\n    group: 3,\n  },\n  {\n    name: 'KitKat',\n    calories: 518,\n    fat: 26.0,\n    carbs: 65,\n    protein: 7,\n    iron: '6%',\n    group: 1,\n  },\n]\n\ndescribe('VDataTable', () => {\n  it('should reset page when searching', () => {\n    cy.mount(({ search }: { search: string }) => (\n      <Application>\n        <VDataTable items={ DESSERT_ITEMS } headers={ DESSERT_HEADERS } search={ search } items-per-page={ 5 } />\n      </Application>\n    ))\n\n    cy.get('.v-btn[aria-label=\"Next page\"]')\n      .click()\n    cy.setProps({ search: 'a' })\n    cy.emitted(VDataTable, 'update:page')\n      .should('deep.equal', [[2], [1]])\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/16999\n  it('should search in nested keys', () => {\n    const nestedItems = [\n      {\n        foo: {\n          bar: 'hello',\n        },\n      },\n      {\n        foo: {\n          bar: 'world',\n        },\n      },\n    ]\n\n    const headers = [\n      {\n        key: 'unique',\n        value: 'foo.bar',\n        title: 'Column',\n      },\n    ]\n\n    cy.mount(props => (\n      <Application>\n        <VDataTable items={ nestedItems } headers={ headers } { ...props } />\n      </Application>\n    ))\n\n    cy.get('tbody tr')\n      .should('have.length', 2)\n      .invoke('text')\n      .should('equal', 'helloworld')\n      .setProps({\n        search: 'hello',\n      })\n      .get('tbody tr')\n      .should('have.length', 1)\n      .invoke('text')\n      .should('equal', 'hello')\n  })\n\n  it('should not emit click:row event when clicking select or expand', () => {\n    const onClick = cy.stub()\n    cy.mount(() => (\n      <Application>\n        <VDataTable showSelect showExpand items={ DESSERT_ITEMS } headers={ DESSERT_HEADERS } onClick:row={ onClick } />\n      </Application>\n    ))\n\n    cy.get('tbody tr')\n      .eq(2)\n      .find('.v-checkbox-btn')\n      .click()\n\n    cy.get('tbody tr')\n      .eq(3)\n      .find('.v-btn')\n      .click()\n      .then(() => {\n        expect(onClick).not.to.be.called\n      })\n\n    cy.get('tbody tr')\n      .eq(1)\n      .click()\n      .then(() => {\n        expect(onClick).to.be.calledOnce\n      })\n  })\n\n  it('should show no-data-text if there are no items', () => {\n    cy.mount(() => (\n      <Application>\n        <VDataTable items={[]} headers={ DESSERT_HEADERS } />\n      </Application>\n    ))\n\n    cy.get('.v-data-table tbody tr').should('have.text', 'No data available')\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/17226\n  it('should change page if we are trying to display a page beyond current page count', () => {\n    const items = ref(DESSERT_ITEMS.slice())\n    cy.mount(() => (\n      <Application>\n        <VDataTable items={ items.value } headers={ DESSERT_HEADERS } itemsPerPage={ 5 }></VDataTable>\n      </Application>\n    ))\n\n    cy.get('[aria-label=\"Next page\"]')\n      .click()\n      .then(() => {\n        items.value = DESSERT_ITEMS.slice(0, 5)\n      })\n      .emitted(VDataTable, 'update:page')\n      .should('deep.equal', [[2], [1]])\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/19069\n  it('should update the select all checkbox when changing the select-strategy', () => {\n    const strategy = ref('single')\n    cy.mount(() => (\n      <Application>\n        <VDataTable select-strategy={ strategy.value } items={ DESSERT_ITEMS } headers={ DESSERT_HEADERS } showSelect />\n      </Application>\n    )).get('thead .v-selection-control').should('not.exist')\n      .then(() => strategy.value = 'all')\n      .get('thead .v-selection-control').should('exist')\n      .then(() => strategy.value = 'page')\n      .get('thead .v-selection-control').should('exist')\n  })\n\n  describe('slots', () => {\n    it('should have top slot', () => {\n      cy.mount(() => (\n        <Application>\n          <VDataTable>\n            {{\n              top: _ => <div id=\"top\">TOP</div>,\n            }}\n          </VDataTable>\n        </Application>\n      ))\n\n      cy.get('.v-data-table').find('#top').should('have.text', 'TOP')\n    })\n\n    it('should have bottom slot (and should overwrite footer)', () => {\n      cy.mount(() => (\n        <Application>\n          <VDataTable>\n            {{\n              bottom: _ => <div id=\"bottom\">BOTTOM</div>,\n            }}\n          </VDataTable>\n        </Application>\n      ))\n\n      cy.get('.v-data-table').find('#bottom').should('have.text', 'BOTTOM')\n      cy.get('.v-data-table-footer').should('not.exist')\n    })\n\n    it('should have headers slot (and overwrite default headers)', () => {\n      cy.mount(() => (\n        <Application>\n          <VDataTable>\n            {{\n              headers: _ => <div id=\"headers\">headers</div>,\n            }}\n          </VDataTable>\n        </Application>\n      ))\n\n      cy.get('.v-data-table').find('#headers').should('have.text', 'headers')\n      cy.get('.v-data-table__th').should('not.exist')\n    })\n\n    it('should have colgroup slot', () => {\n      cy.mount(() => (\n        <Application>\n          <VDataTable items={ DESSERT_ITEMS } headers={ DESSERT_HEADERS }>\n            {{\n              colgroup: ({ columns }) => (\n                <colgroup>\n                  { columns.map(column => (\n                    <col id={ column.key! }></col>\n                  ))}\n                </colgroup>\n              ),\n            }}\n          </VDataTable>\n        </Application>\n      ))\n\n      cy.get('colgroup').should('exist')\n    })\n\n    it('should have header.* slots', () => {\n      cy.mount(() => (\n        <Application>\n          <VDataTable items={ DESSERT_ITEMS } headers={ DESSERT_HEADERS } showSelect showExpand>\n            {{\n              'header.data-table-expand': () => <h1>expand</h1>,\n              'header.data-table-select': () => <h2>select</h2>,\n              'header.name': ({ column }) => (\n                <h3>{ column.title }</h3>\n              ),\n            }}\n          </VDataTable>\n        </Application>\n      ))\n\n      cy.get('.v-data-table__th').find('h1').should('exist')\n      cy.get('.v-data-table__th').find('h2').should('exist')\n      cy.get('.v-data-table__th').find('h3').should('exist')\n    })\n\n    it('should have item slot', () => {\n      cy.mount(() => (\n        <Application>\n          <VDataTable items={ DESSERT_ITEMS } headers={ DESSERT_HEADERS } itemsPerPage={ 10 }>\n            {{\n              item: ({ columns, internalItem }) => (\n                <tr class=\"custom-row\">\n                  { columns.map(column => (\n                    column.key != null ? (\n                      <td>\n                        <h1>{ internalItem.columns[column.key] }</h1>\n                      </td>\n                    ) : null\n                  ))}\n                </tr>\n              ),\n            }}\n          </VDataTable>\n        </Application>\n      ))\n\n      cy.get('.custom-row').should('have.length', 10)\n    })\n\n    it('should have item.* slots', () => {\n      cy.mount(() => (\n        <Application>\n          <VDataTable items={ DESSERT_ITEMS } headers={ DESSERT_HEADERS } showSelect showExpand>\n            {{\n              'item.data-table-expand': () => <h1>expand</h1>,\n              'item.data-table-select': () => <h2>select</h2>,\n              'item.name': ({ value }) => (\n                <h3>{ value }</h3>\n              ),\n            }}\n          </VDataTable>\n        </Application>\n      ))\n\n      cy.get('.v-data-table').find('h1').should('exist')\n      cy.get('.v-data-table').find('h2').should('exist')\n      cy.get('.v-data-table').find('h3').should('exist')\n    })\n\n    it('should have body slot and slot prop should show correct item count after group is expanded', () => {\n      cy.mount(() => (\n        <Application>\n          <VDataTable\n            items={ DESSERT_ITEMS }\n            headers={ DESSERT_HEADERS }\n            itemsPerPage={ -1 }\n            groupBy={[{ key: 'group', order: 'desc' }]}\n          >\n            {{\n              'body.append': ({ items }) => <div id=\"body-append\">{ items.length }</div>,\n            }}\n          </VDataTable>\n        </Application>\n      ))\n\n      cy.get('.v-data-table').find('div#body-append').should('have.text', DESSERT_ITEMS.length)\n      cy.get(':nth-child(1) > .v-data-table__td > .v-btn').click()\n      cy.get('.v-data-table').find('div#body-append').should('have.text', DESSERT_ITEMS.length)\n    })\n  })\n\n  describe('sort', () => {\n    it('should sort by sortBy', () => {\n      cy.mount(() => (\n        <Application>\n          <VDataTable\n          items={ DESSERT_ITEMS }\n          headers={ DESSERT_HEADERS }\n          itemsPerPage={ 10 }\n          sortBy={[{ key: 'fat', order: 'asc' }]}\n          />\n        </Application>\n      ))\n      cy.get('thead .v-data-table__td').eq(2).should('have.class', 'v-data-table__th--sorted')\n        .get('tbody td:nth-child(3)').then(rows => {\n          const actualFat = Array.from(rows).map(row => {\n            return Number(row.textContent)\n          })\n          const expectedFat = DESSERT_ITEMS.map(d => d.fat).sort((a, b) => a - b)\n          expect(actualFat).to.deep.equal(expectedFat)\n        })\n      cy.get('thead .v-data-table__td').eq(2).click()\n        .get('thead .v-data-table__td').eq(2).should('have.class', 'v-data-table__th--sorted')\n        .get('tbody td:nth-child(3)').then(rows => {\n          const actualFat = Array.from(rows).map(row => {\n            return Number(row.textContent)\n          })\n          const expectedFat = DESSERT_ITEMS.map(d => d.fat).sort((a, b) => b - a)\n          expect(actualFat).to.deep.equal(expectedFat)\n        })\n    })\n\n    it('should sort by groupBy and sortBy', () => {\n      cy.mount(() => (\n        <Application>\n          <VDataTable\n          items={ DESSERT_ITEMS }\n          headers={ DESSERT_HEADERS }\n          itemsPerPage={ 10 }\n          groupBy={[{ key: 'group', order: 'desc' }]}\n          sortBy={[{ key: 'calories', order: 'desc' }]}\n          />\n        </Application>\n      )).get('tr.v-data-table-group-header-row .v-data-table__td button + span').then(rows => {\n        const actualGroup = Array.from(rows).map(row => {\n          return Number(row.textContent)\n        })\n        const expectedGroup = [...new Set(DESSERT_ITEMS.map(d => d.group))].sort((a, b) => b - a)\n        expect(actualGroup).to.deep.equal(expectedGroup)\n      }).get('.v-data-table-group-header-row button').eq(0).click()\n        .get('.v-data-table__tr td:nth-child(3)').then(rows => {\n          const actualCalories = Array.from(rows).map(row => {\n            return Number(row.textContent)\n          })\n          const expectedCalories = DESSERT_ITEMS.filter(d => d.group === 3).map(d => d.calories).sort((a, b) => b - a)\n          expect(actualCalories).to.deep.equal(expectedCalories)\n        })\n    })\n\n    // https://github.com/vuetifyjs/vuetify/issues/20046\n    it('should sort by groupBy while sort is disabled', () => {\n      cy.mount(() => (\n        <Application>\n          <VDataTable\n          items={ DESSERT_ITEMS }\n          headers={ DESSERT_HEADERS }\n          itemsPerPage={ 10 }\n          groupBy={[{ key: 'group', order: 'desc' }]}\n          sortBy={[{ key: 'calories', order: 'desc' }]}\n          disableSort\n          />\n        </Application>\n      )).get('tr.v-data-table-group-header-row .v-data-table__td button + span').then(rows => {\n        const actualGroup = Array.from(rows).map(row => {\n          return Number(row.textContent)\n        })\n        const expectedGroup = [...new Set(DESSERT_ITEMS.map(d => d.group))].sort((a, b) => b - a)\n        expect(actualGroup).to.deep.equal(expectedGroup)\n      }).get('.v-data-table-group-header-row button').eq(0).click()\n        .get('.v-data-table__tr td:nth-child(3)').then(rows => {\n          const actualCalories = Array.from(rows).map(row => {\n            return Number(row.textContent)\n          })\n          const expectedCalories = DESSERT_ITEMS.filter(d => d.group === 3).map(d => d.calories)\n          expect(actualCalories).to.deep.equal(expectedCalories)\n        })\n    })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/__tests__/VDataTable.spec.ts",
    "content": "// @ts-nocheck\n/* eslint-disable */\n\n// import VDataTable from '../VDataTable'\nimport {\n  mount,\n  Wrapper,\n  MountOptions,\n} from '@vue/test-utils'\n// import { Breakpoint } from '../../../services/breakpoint'\n// import ripple from '../../../directives/ripple/index'\n// import Vue from 'vue'\n// import { Lang } from '../../../services/lang'\n// import { preset } from '../../../presets/default'\n// import { resizeWindow } from '@/../test'\n\n// Vue.prototype.$vuetify = {\n//   icons: {},\n//   rtl: false,\n//   lang: new Lang(preset),\n// }\n// Vue.directive('ripple', ripple)\n\nconst testHeaders = [\n  {\n    text: 'Dessert (100g serving)',\n    align: 'left',\n    sortable: false,\n    value: 'name',\n  },\n  { text: 'Calories', value: 'calories' },\n  { text: 'Fat (g)', value: 'fat' },\n  { text: 'Carbs (g)', value: 'carbs' },\n  { text: 'Protein (g)', value: 'protein' },\n  { text: 'Iron (%)', value: 'iron' },\n]\n\nconst testItems = [\n  {\n    name: 'Frozen Yogurt',\n    calories: 159,\n    fat: 6.0,\n    carbs: 24,\n    protein: 4.0,\n    iron: '1%',\n    class: 'test',\n  },\n  {\n    name: 'Ice cream sandwich',\n    calories: 237,\n    fat: 9.0,\n    carbs: 37,\n    protein: 4.3,\n    iron: '1%',\n    class: ['test', 'second'],\n  },\n  {\n    name: 'Eclair',\n    calories: 262,\n    fat: 16.0,\n    carbs: 23,\n    protein: 6.0,\n    iron: '7%',\n    class: { test: true, second: false },\n  },\n  {\n    name: 'Cupcake',\n    calories: 305,\n    fat: 3.7,\n    carbs: 67,\n    protein: 4.3,\n    iron: '8%',\n  },\n  {\n    name: 'Gingerbread',\n    calories: 356,\n    fat: 16.0,\n    carbs: 49,\n    protein: 3.9,\n    iron: '16%',\n  },\n  {\n    name: 'Jelly bean',\n    calories: 375,\n    fat: 0.0,\n    carbs: 94,\n    protein: 0.0,\n    iron: '0%',\n  },\n  {\n    name: 'Lollipop',\n    calories: 392,\n    fat: 0.2,\n    carbs: 98,\n    protein: 0,\n    iron: '2%',\n  },\n  {\n    name: 'Honeycomb',\n    calories: 408,\n    fat: 3.2,\n    carbs: 87,\n    protein: 6.5,\n    iron: '45%',\n  },\n  {\n    name: 'Donut',\n    calories: 452,\n    fat: 25.0,\n    carbs: 51,\n    protein: 4.9,\n    iron: '22%',\n  },\n  {\n    name: 'KitKat',\n    calories: 518,\n    fat: 26.0,\n    carbs: 65,\n    protein: 7,\n    iron: '6%',\n  },\n]\n\n/* eslint-disable max-statements */\ndescribe.skip('VDataTable.ts', () => {\n  type Instance = InstanceType<typeof VDataTable>\n  let mountFunction: (options?: MountOptions<Instance>) => Wrapper<Instance>\n  beforeEach(() => {\n    document.body.setAttribute('data-app', 'true')\n\n    mountFunction = (options?: MountOptions<Instance>) => {\n      return mount(VDataTable, {\n        mocks: {\n          $vuetify: {\n            breakpoint: new Breakpoint(preset),\n            lang: new Lang(preset),\n            theme: {\n              dark: false,\n            },\n          },\n        },\n        sync: false,\n        ...options,\n      })\n    }\n\n    return resizeWindow(0)\n  })\n\n  it('should render', () => {\n    const wrapper = mountFunction()\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render with data', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        headers: testHeaders,\n        items: testItems,\n        itemsPerPage: 5,\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render with body slot', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        headers: testHeaders,\n        items: testItems,\n        itemsPerPage: 5,\n      },\n      scopedSlots: {\n        body (props) {\n          return this.$createElement('div', [props.items.length])\n        },\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render with foot slot', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        headers: testHeaders,\n        items: testItems,\n        itemsPerPage: 5,\n      },\n      scopedSlots: {\n        foot (props) {\n          return this.$createElement('tfoot', [props.items.length])\n        },\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it.skip('should render virtual table', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        headers: testHeaders,\n        items: testItems,\n        itemsPerPage: 5,\n        virtualRows: true,\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render with showExpand', async () => {\n    const expand = jest.fn()\n    const wrapper = mountFunction({\n      propsData: {\n        headers: testHeaders,\n        itemKey: 'name',\n        items: testItems,\n        itemsPerPage: 5,\n        showExpand: true,\n      },\n      listeners: {\n        'update:expanded': expand,\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n    const expandIcon = wrapper.findAll('.v-data-table__expand-icon').at(0)\n    expandIcon.trigger('click')\n\n    await wrapper.vm.$nextTick()\n    expect(expand).toHaveBeenCalledWith(testItems.slice(0, 1))\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render with showSelect', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        headers: testHeaders,\n        items: testItems,\n        itemsPerPage: 5,\n        showSelect: true,\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render with item.expanded scoped slot', async () => {\n    const vm = new Vue()\n\n    const wrapper = mountFunction({\n      propsData: {\n        headers: testHeaders,\n        items: testItems,\n        itemsPerPage: 5,\n        expanded: testItems,\n      },\n      scopedSlots: {\n        'expanded-item': props => vm.$createElement('div', ['expanded']),\n      },\n    })\n\n    await wrapper.vm.$nextTick()\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render with group.summary scoped slot', () => {\n    const vm = new Vue()\n\n    const wrapper = mountFunction({\n      propsData: {\n        headers: testHeaders,\n        items: testItems,\n        itemsPerPage: 5,\n        groupBy: 'calories',\n      },\n      scopedSlots: {\n        'group.summary': props => vm.$createElement('div', ['summary']),\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render with item scoped slot', () => {\n    const vm = new Vue()\n\n    const wrapper = mountFunction({\n      propsData: {\n        headers: testHeaders,\n        items: testItems,\n        itemsPerPage: 5,\n      },\n      scopedSlots: {\n        item: props => vm.$createElement('div', [JSON.stringify(props)]),\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render with grouped rows', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        headers: testHeaders,\n        items: testItems,\n        itemsPerPage: 5,\n        groupBy: ['protein'],\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render with group scoped slot', () => {\n    const vm = new Vue()\n\n    const wrapper = mountFunction({\n      propsData: {\n        headers: testHeaders,\n        items: testItems,\n        itemsPerPage: 5,\n        groupBy: ['protein'],\n      },\n      scopedSlots: {\n        group: props => vm.$createElement('div', [JSON.stringify(props)]),\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render loading state', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        loading: true,\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n\n    const wrapper2 = mountFunction({\n      propsData: {\n        headers: testHeaders,\n        loading: true,\n      },\n      slots: {\n        progress: '<div class=\"progress\">50%</div>',\n      },\n    })\n\n    expect(wrapper2.html()).toMatchSnapshot()\n  })\n\n  it.each([\n    'click',\n    'contextmenu',\n    'dblclick',\n  ])('should emit event when %sing on internally created row', async event => {\n    const eventToEmit = event + ':row'\n    const fn = jest.fn()\n    const wrapper = mountFunction({\n      propsData: {\n        headers: testHeaders,\n        items: testItems,\n      },\n      listeners: {\n        [eventToEmit]: fn,\n      },\n    })\n\n    wrapper.find('tbody tr').trigger(event)\n    await wrapper.vm.$nextTick()\n\n    expect(fn).toHaveBeenCalled()\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/8254\n  it('should pass kebab-case footer props correctly', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        headers: [],\n        items: [],\n        footerProps: {\n          'items-per-page-text': 'Foo:',\n        },\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/8266\n  it('should use options prop for initial values', () => {\n    const fn = jest.fn()\n    const wrapper = mountFunction({\n      propsData: {\n        headers: testHeaders,\n        items: testItems,\n        options: {\n          page: 2,\n          itemsPerPage: 5,\n        },\n      },\n      listeners: {\n        'update:options': fn,\n      },\n    })\n\n    expect(fn).toHaveBeenCalledWith(expect.objectContaining({\n      page: 2,\n    }))\n  })\n\n  it('should render footer.prepend slot content', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        headers: [],\n        items: [{}],\n      },\n      scopedSlots: {\n        'footer.prepend' () {\n          return this.$createElement('div', ['footer.prepend slot content'])\n        },\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render footer.page-text slot content', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        headers: [],\n        items: [{}],\n      },\n      scopedSlots: {\n        'footer.page-text' ({ pageStart, pageStop }) {\n          return this.$createElement('div', [`foo ${pageStart} bar ${pageStop}`])\n        },\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/8359\n  it('should not limit page to current item count when using server-items-length', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        headers: testHeaders,\n        items: [],\n        page: 2,\n        itemsPerPage: 5,\n        serverItemsLength: 0,\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n\n    wrapper.setProps({\n      items: testItems.slice(5),\n      serverItemsLength: 20,\n    })\n    await wrapper.vm.$nextTick()\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should not search column with filterable set to false', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        items: testItems,\n        headers: [\n          {\n            text: 'Dessert (100g serving)',\n            align: 'left',\n            filterable: false,\n            value: 'name',\n          },\n          { text: 'Calories', value: 'calories' },\n          { text: 'Fat (g)', value: 'fat' },\n          { text: 'Carbs (g)', value: 'carbs' },\n          { text: 'Protein (g)', value: 'protein' },\n          { text: 'Iron (%)', value: 'iron' },\n        ],\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n\n    wrapper.setProps({\n      search: 'cup',\n    })\n    await wrapper.vm.$nextTick()\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should not search column with filterable set to false and has filter function', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        items: testItems,\n        headers: [\n          {\n            text: 'Dessert (100g serving)',\n            align: 'left',\n            value: 'name',\n          },\n          { text: 'Calories', value: 'calories', filter: v => v > 400 },\n          { text: 'Fat (g)', value: 'fat' },\n          { text: 'Carbs (g)', value: 'carbs' },\n          { text: 'Protein (g)', value: 'protein' },\n          { text: 'Iron (%)', value: 'iron' },\n        ],\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n\n    wrapper.setProps({\n      headers: [\n        {\n          text: 'Dessert (100g serving)',\n          align: 'left',\n          value: 'name',\n        },\n        { text: 'Calories', value: 'calories', filter: v => v > 400, filterable: false },\n        { text: 'Fat (g)', value: 'fat' },\n        { text: 'Carbs (g)', value: 'carbs' },\n        { text: 'Protein (g)', value: 'protein' },\n        { text: 'Iron (%)', value: 'iron' },\n      ],\n    })\n    await wrapper.vm.$nextTick()\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/8359\n  it('should limit page to current page count if not using server-items-length', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        headers: testHeaders,\n        items: testItems,\n        page: 3,\n        itemsPerPage: 5,\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/8184\n  it('should default to first option in itemsPerPageOptions if it does not include itemsPerPage', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        headers: testHeaders,\n        items: testItems,\n        footerProps: {\n          itemsPerPageOptions: [6, 7],\n        },\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/8817\n  it('should handle object when checking if it should default to first option in itemsPerPageOptions', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        headers: testHeaders,\n        items: testItems,\n        itemsPerPage: -1,\n        footerProps: {\n          itemsPerPageOptions: [6, { text: 'All', value: -1 }],\n        },\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/9599\n  it('should not immediately emit items-per-page', async () => {\n    const itemsPerPage = jest.fn()\n    const wrapper = mountFunction({\n      propsData: {\n        headers: testHeaders,\n        items: testItems,\n        footerProps: {\n          itemsPerPageOptions: [6, 7],\n        },\n      },\n      listeners: {\n        'update:itemsPerPage': itemsPerPage,\n      },\n    })\n\n    expect(itemsPerPage).not.toHaveBeenCalled()\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/9010\n  it('should change page if item count decreases below page start', async () => {\n    const page = jest.fn()\n    const wrapper = mountFunction({\n      propsData: {\n        headers: testHeaders,\n        items: testItems.slice(0, 4),\n        itemsPerPage: 2,\n        footerProps: {\n          itemsPerPageOptions: [2],\n        },\n        page: 2,\n      },\n      listeners: {\n        'update:page': page,\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n\n    wrapper.setProps({ items: testItems.slice(0, 2) })\n    await wrapper.vm.$nextTick()\n\n    expect(page).toHaveBeenCalledWith(1)\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/8477\n  it('should emit two item-selected events when using single-select prop and selecting new item', async () => {\n    const itemSelected = jest.fn()\n    const wrapper = mountFunction({\n      propsData: {\n        headers: testHeaders,\n        itemKey: 'name',\n        items: testItems.slice(0, 2),\n        value: [testItems[0]],\n        showSelect: true,\n        singleSelect: true,\n      },\n      listeners: {\n        'item-selected': itemSelected,\n      },\n    })\n\n    const checkbox = wrapper.findAll('.v-data-table__checkbox').at(1)\n    checkbox.trigger('click')\n    await wrapper.vm.$nextTick()\n\n    expect(itemSelected).toHaveBeenCalledTimes(2)\n    expect(itemSelected).toHaveBeenCalledWith({ item: testItems[0], value: false })\n    expect(itemSelected).toHaveBeenCalledWith({ item: testItems[1], value: true })\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/8915\n  it('should not select item that is not selectable', async () => {\n    const items = [\n      { ...testItems[0], isSelectable: false },\n      { ...testItems[1] },\n    ]\n    const input = jest.fn()\n    const wrapper = mountFunction({\n      propsData: {\n        headers: testHeaders,\n        items,\n        showSelect: true,\n      },\n      listeners: {\n        input,\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n\n    const selectAll = wrapper.findAll('.v-simple-checkbox').at(0)\n    selectAll.trigger('click')\n    await wrapper.vm.$nextTick()\n\n    expect(input).toHaveBeenNthCalledWith(1, [testItems[1]])\n\n    const single = wrapper.findAll('.v-simple-checkbox').at(1)\n    single.trigger('click')\n    await wrapper.vm.$nextTick()\n\n    expect(input.mock.calls).toHaveLength(1)\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/8915\n  it('should toggle all selectable items', async () => {\n    const items = [\n      { ...testItems[0], isSelectable: false },\n      { ...testItems[1] },\n    ]\n    const input = jest.fn()\n    const wrapper = mountFunction({\n      propsData: {\n        headers: testHeaders,\n        items,\n        showSelect: true,\n      },\n      listeners: {\n        input,\n      },\n    })\n\n    const selectAll = wrapper.findAll('.v-simple-checkbox').at(0)\n    selectAll.trigger('click')\n    await wrapper.vm.$nextTick()\n\n    expect(input).toHaveBeenNthCalledWith(1, [testItems[1]])\n\n    selectAll.trigger('click')\n    await wrapper.vm.$nextTick()\n\n    expect(input).toHaveBeenNthCalledWith(2, [])\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/10392\n  it('should search group-by column', async () => {\n    const headers = [\n      {\n        text: 'Name',\n        value: 'name',\n      },\n      {\n        text: 'ID',\n        value: 'id',\n      },\n    ]\n\n    const items = [\n      {\n        name: 'Assistance',\n        id: 1,\n      },\n      {\n        name: 'Candidat',\n        id: 2,\n      },\n    ]\n\n    const wrapper = mountFunction({\n      propsData: {\n        headers,\n        items,\n        itemKey: 'id',\n        groupBy: 'name',\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n\n    wrapper.setProps({ search: 'candidat' })\n    await wrapper.vm.$nextTick()\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/10289\n  it('should render item slot when using group-by function', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        headers: testHeaders,\n        itemKey: 'name',\n        items: testItems.slice(0, 2),\n        groupBy: 'name',\n      },\n      scopedSlots: {\n        item () {\n          return this.$createElement('div', ['scoped'])\n        },\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/10392\n  it('should emit pagination event when filtering', async () => {\n    const headers = [\n      {\n        text: 'Name',\n        value: 'name',\n      },\n      {\n        text: 'ID',\n        value: 'id',\n      },\n    ]\n\n    const items = [\n      {\n        name: 'Assistance',\n        id: 1,\n      },\n      {\n        name: 'Candidat',\n        id: 2,\n      },\n    ]\n\n    const pagination = jest.fn()\n\n    const wrapper = mountFunction({\n      propsData: {\n        headers,\n        items,\n        itemKey: 'id',\n      },\n      listeners: {\n        pagination,\n      },\n    })\n\n    expect(pagination).toHaveBeenLastCalledWith({\n      itemsLength: 2,\n      itemsPerPage: 10,\n      page: 1,\n      pageCount: 1,\n      pageStart: 0,\n      pageStop: 2,\n    })\n\n    wrapper.setProps({ search: 'candidat' })\n    await wrapper.vm.$nextTick()\n\n    expect(pagination).toHaveBeenLastCalledWith({\n      itemsLength: 1,\n      itemsPerPage: 10,\n      page: 1,\n      pageCount: 1,\n      pageStart: 0,\n      pageStop: 1,\n    })\n\n    expect(pagination).toHaveBeenCalledTimes(2)\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/10715\n  // NOTE: This test currently succeeds regardless of fix\n  // It seems like the test environment does not double\n  // fire the events in the same way the browser does\n  it('should not emit too many pagination events', async () => {\n    const headers = [\n      {\n        text: 'Name',\n        value: 'name',\n      },\n      {\n        text: 'ID',\n        value: 'id',\n      },\n    ]\n\n    const items = [\n      {\n        name: 'Assistance',\n        id: 1,\n      },\n      {\n        name: 'Candidat',\n        id: 2,\n      },\n    ]\n\n    const wrapper = mountFunction({\n      propsData: {\n        headers,\n        itemKey: 'id',\n        serverItemsLength: 0,\n      },\n    })\n\n    wrapper.setProps({ items, serverItemsLength: items.length })\n    await wrapper.vm.$nextTick()\n\n    expect(wrapper.emitted().pagination).toHaveLength(2)\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/4975\n  it('should show correct aria-labels when sorting', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        headers: testHeaders,\n        itemKey: 'name',\n        items: testItems.slice(0, 5),\n        sortBy: 'calories',\n      },\n    })\n\n    wrapper.setProps({ sortDesc: true })\n    await wrapper.vm.$nextTick()\n\n    expect(wrapper.html()).toMatchSnapshot()\n\n    wrapper.setProps({ mustSort: true })\n    await wrapper.vm.$nextTick()\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should apply class list to rows', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        headers: testHeaders,\n        items: testItems,\n        itemsPerPage: 5,\n        itemClass: () => ['my-class', 'my-other-class'],\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should apply class unique to rows', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        headers: testHeaders,\n        items: testItems,\n        itemsPerPage: 5,\n        itemClass: () => 'my-unique-class',\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should apply class function to rows', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        headers: testHeaders,\n        items: testItems,\n        itemsPerPage: 5,\n        itemClass: (item: Object) => ({\n          'first-class': item.fat < 10,\n          'second-class': item.protein > 4.0,\n        }),\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should apply class from item to rows', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        headers: testHeaders,\n        items: testItems,\n        itemsPerPage: 5,\n        itemClass: 'class',\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/11179\n  it('should return rows from columns that exclusively match custom filters', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        items: testItems,\n        headers: [\n          { text: 'Dessert (100g serving)', align: 'left', value: 'name' },\n          { text: 'Calories', value: 'calories', filter: value => value === 159 },\n          { text: 'Fat (g)', value: 'fat' },\n          { text: 'Carbs (g)', value: 'carbs' },\n          { text: 'Protein (g)', value: 'protein' },\n          { text: 'Iron (%)', value: 'iron' },\n        ],\n      },\n    })\n\n    await wrapper.vm.$nextTick()\n    expect(wrapper.vm.internalCurrentItems).toHaveLength(1)\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/10244\n  it('should respect mustSort property on options', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        items: testItems,\n        headers: [\n          { text: 'Dessert (100g serving)', value: 'name' },\n        ],\n        options: {\n          mustSort: true,\n        },\n      },\n    })\n\n    wrapper.find('th').trigger('click')\n    await wrapper.vm.$nextTick()\n\n    wrapper.find('th').trigger('click')\n    await wrapper.vm.$nextTick()\n\n    wrapper.find('th').trigger('click')\n    await wrapper.vm.$nextTick()\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should hide group button when column is not groupable', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        showGroupBy: true,\n        items: testItems,\n        headers: [\n          {\n            text: 'Dessert (100g serving)',\n            align: 'left',\n            value: 'name',\n            groupable: false,\n          },\n          { text: 'Calories', value: 'calories' },\n          { text: 'Fat (g)', value: 'fat' },\n          { text: 'Carbs (g)', value: 'carbs' },\n          { text: 'Protein (g)', value: 'protein' },\n          { text: 'Iron (%)', value: 'iron' },\n        ],\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should return rows matching search term if specified', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        items: testItems,\n        headers: [\n          { text: 'Dessert (100g serving)', align: 'left', value: 'name' },\n          { text: 'Calories', value: 'calories' },\n          { text: 'Fat (g)', value: 'fat' },\n          { text: 'Carbs (g)', value: 'carbs' },\n          { text: 'Protein (g)', value: 'protein' },\n          { text: 'Iron (%)', value: 'iron' },\n        ],\n      },\n    })\n\n    wrapper.setProps({ search: 'unknown-term' })\n    await wrapper.vm.$nextTick()\n    expect(wrapper.vm.internalCurrentItems).toHaveLength(0)\n\n    wrapper.setProps({ search: 'Eclair' })\n    await wrapper.vm.$nextTick()\n    expect(wrapper.vm.internalCurrentItems).toHaveLength(1)\n  })\n\n  it('should return results which match both search term and column filters if both specified', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        items: testItems,\n        headers: [\n          { text: 'Dessert (100g serving)', align: 'left', value: 'name' },\n          { text: 'Calories', value: 'calories', filter: value => value < 300 },\n          { text: 'Fat (g)', value: 'fat' },\n          { text: 'Carbs (g)', value: 'carbs' },\n          { text: 'Protein (g)', value: 'protein' },\n          { text: 'Iron (%)', value: 'iron' },\n        ],\n      },\n    })\n\n    wrapper.setProps({ search: 'EA' })\n    await wrapper.vm.$nextTick()\n    expect(wrapper.vm.internalCurrentItems).toHaveLength(1)\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/14006\n  it('should allow selection on second page when using numbers as item key', async () => {\n    const input = jest.fn()\n    const items = testItems.map((item, index) => ({ ...item, name: index + 1 })).slice(0, 8)\n    const wrapper = mountFunction({\n      propsData: {\n        items,\n        itemKey: 'name',\n        itemsPerPage: 5,\n        showSelect: true,\n        headers: testHeaders,\n        mobileBreakpoint: 0,\n      },\n      listeners: {\n        input,\n      },\n    })\n\n    let checkbox = wrapper.findAll('td > .v-data-table__checkbox').at(4)\n\n    checkbox.trigger('click')\n    await wrapper.vm.$nextTick()\n\n    wrapper.setProps({ page: 2 })\n    await wrapper.vm.$nextTick()\n\n    checkbox = wrapper.findAll('td > .v-data-table__checkbox').at(0)\n\n    checkbox.trigger('click')\n    await wrapper.vm.$nextTick()\n\n    expect(input).toHaveBeenCalledWith([items[4], items[5]])\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/__tests__/VDataTableHeader.spec.ts",
    "content": "// @ts-nocheck\n/* eslint-disable */\n\n// import VDataTableHeader from '../VDataTableHeader'\n// import { Lang } from '../../../services/lang'\n// import ripple from '../../../directives/ripple'\n// import VSelect from '../../VSelect/VSelect'\n// import { preset } from '../../../presets/default'\n\nimport {\n  mount,\n  MountOptions,\n  Wrapper,\n} from '@vue/test-utils'\n// import Vue from 'vue'\n\nconst testHeaders = [\n  {\n    text: 'Dessert (100g serving)',\n    align: 'left',\n    sortable: false,\n    value: 'name',\n  },\n  { text: 'Calories', width: 50, value: 'calories' },\n  { text: 'Fat (g)', width: '50em', value: 'fat' },\n  { text: 'Carbs (g)', value: 'carbs' },\n  { text: 'Protein (g)', value: 'protein' },\n  { text: 'Iron (%)', value: 'iron' },\n]\n\n// Vue.prototype.$vuetify = {\n//   icons: {},\n//   rtl: false,\n//   lang: new Lang(preset),\n//   theme: {\n//     dark: false,\n//   },\n// }\n// Vue.directive('ripple', ripple)\n\ndescribe.skip('VDataTableHeader.ts', () => {\n  type Instance = InstanceType<typeof VDataTableHeader>\n  let mountFunction: (options?: MountOptions<Instance>, isMobile?: boolean) => Wrapper<Instance>\n\n  ;[false, true].forEach(isMobile => {\n    describe(isMobile ? 'mobile' : 'desktop', () => { // eslint-disable-line jest/valid-title\n      beforeEach(() => {\n        document.body.setAttribute('data-app', 'true')\n\n        mountFunction = (options?: MountOptions<Instance>) => {\n          return mount(VDataTableHeader, {\n            ...options,\n            // https://github.com/vuejs/vue-test-utils/issues/1130\n            sync: false,\n            propsData: {\n              headers: testHeaders,\n              mobile: isMobile,\n              ...(options || {}).propsData,\n            },\n          })\n        }\n      })\n\n      it('should render', () => {\n        const wrapper = mountFunction()\n\n        expect(wrapper.html()).toMatchSnapshot()\n      })\n      it('should work with showGroupBy', () => {\n        const wrapper = mountFunction({\n          propsData: {\n            showGroupBy: true,\n          },\n        })\n\n        expect(wrapper.html()).toMatchSnapshot()\n      })\n\n      it('should work with multiSort', () => {\n        const wrapper = mountFunction({\n          propsData: {\n            options: {\n              multiSort: true,\n              sortBy: ['iron'],\n              sortDesc: [true],\n            },\n          },\n        })\n\n        expect(wrapper.html()).toMatchSnapshot()\n      })\n\n      it('should work with sortBy correctly', () => {\n        const wrapper = mountFunction({\n          propsData: {\n            options: {\n              sortBy: ['iron'],\n              sortDesc: [true],\n            },\n          },\n        })\n\n        expect(wrapper.html()).toMatchSnapshot()\n      })\n\n      it('should work with sortDesc correctly', () => {\n        const wrapper = mountFunction({\n          propsData: {\n            options: {\n              sortBy: ['iron', 'carbs'],\n              sortDesc: [false, true],\n            },\n          },\n        })\n\n        expect(wrapper.html()).toMatchSnapshot()\n      })\n\n      if (isMobile) {\n        it('should render with data-table-select header', () => {\n          const wrapper = mountFunction({\n            propsData: {\n              headers: [...testHeaders, { text: 'test', value: 'data-table-select' }],\n            },\n          })\n\n          expect(wrapper.html()).toMatchSnapshot()\n        })\n\n        it('should sort when select changes', () => {\n          const sort = jest.fn()\n          const wrapper = mountFunction({\n            listeners: {\n              sort,\n            },\n          })\n          const select = wrapper.find(VSelect)\n\n          select.vm.$emit('change', 'test')\n          expect(sort).toHaveBeenLastCalledWith('test')\n        })\n\n        it('should apply header class and width for select-all column', () => {\n          const wrapper = mount(VDataTableHeader, {\n            propsData: {\n              mobile: isMobile,\n              headers: [\n                {\n                  value: 'data-table-select',\n                  width: '100px',\n                  class: 'foo',\n                },\n              ],\n            },\n          })\n\n          const foo = wrapper.find('.foo')\n          expect(foo.exists()).toBe(true)\n          expect(foo.attributes().width).toBe('100px')\n        })\n      }\n    })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/__tests__/VDataTableServer.spec.cy.tsx",
    "content": "/// <reference types=\"../../../../types/cypress\" />\n\nimport { Application } from '../../../../cypress/templates'\n\n// Utilities\nimport { ref } from 'vue'\nimport { VDataTableServer } from '..'\n\nconst DESSERT_HEADERS = [\n  { title: 'Dessert (100g serving)', key: 'name' },\n  { title: 'Calories', key: 'calories' },\n  { title: 'Fat (g)', key: 'fat' },\n  { title: 'Carbs (g)', key: 'carbs' },\n  { title: 'Protein (g)', key: 'protein' },\n  { title: 'Iron (%)', key: 'iron' },\n]\n\nconst DESSERT_ITEMS = [\n  {\n    name: 'Frozen Yogurt',\n    calories: 159,\n    fat: 6.0,\n    carbs: 24,\n    protein: 4.0,\n    iron: '1%',\n  },\n  {\n    name: 'Ice cream sandwich',\n    calories: 237,\n    fat: 9.0,\n    carbs: 37,\n    protein: 4.3,\n    iron: '1%',\n  },\n  {\n    name: 'Eclair',\n    calories: 262,\n    fat: 16.0,\n    carbs: 23,\n    protein: 6.0,\n    iron: '7%',\n  },\n  {\n    name: 'Cupcake',\n    calories: 305,\n    fat: 3.7,\n    carbs: 67,\n    protein: 4.3,\n    iron: '8%',\n  },\n  {\n    name: 'Gingerbread',\n    calories: 356,\n    fat: 16.0,\n    carbs: 49,\n    protein: 3.9,\n    iron: '16%',\n  },\n  {\n    name: 'Jelly bean',\n    calories: 375,\n    fat: 0.0,\n    carbs: 94,\n    protein: 0.0,\n    iron: '0%',\n  },\n  {\n    name: 'Lollipop',\n    calories: 392,\n    fat: 0.2,\n    carbs: 98,\n    protein: 0,\n    iron: '2%',\n  },\n  {\n    name: 'Honeycomb',\n    calories: 408,\n    fat: 3.2,\n    carbs: 87,\n    protein: 6.5,\n    iron: '45%',\n  },\n  {\n    name: 'Donut',\n    calories: 452,\n    fat: 25.0,\n    carbs: 51,\n    protein: 4.9,\n    iron: '22%',\n  },\n  {\n    name: 'KitKat',\n    calories: 518,\n    fat: 26.0,\n    carbs: 65,\n    protein: 7,\n    iron: '6%',\n  },\n]\n\ndescribe('VDataTableServer', () => {\n  it('should render table', () => {\n    const itemsLength = 2\n\n    cy.mount(() => (\n      <VDataTableServer\n        headers={ DESSERT_HEADERS }\n        items={ DESSERT_ITEMS.slice(0, itemsLength) }\n        itemsLength={ itemsLength }\n      ></VDataTableServer>\n    ))\n\n    cy.get('.v-data-table thead th').should('have.length', DESSERT_HEADERS.length)\n    cy.get('.v-data-table tbody tr').should('have.length', itemsLength)\n  })\n\n  it('should only trigger update event once on mount', () => {\n    const items = ref<any[]>([])\n    const options = ref({\n      itemsLength: 0,\n      page: 1,\n      itemsPerPage: 2,\n    })\n\n    function load (opts: { page: number, itemsPerPage: number }) {\n      setTimeout(() => {\n        const start = (opts.page - 1) * opts.itemsPerPage\n        const end = start + opts.itemsPerPage\n        items.value = DESSERT_ITEMS.slice(start, end)\n        options.value = {\n          ...options.value,\n          ...opts,\n        }\n      }, 10)\n    }\n\n    cy.mount(() => (\n      <VDataTableServer\n        headers={ DESSERT_HEADERS }\n        items={ items.value }\n        { ...options.value }\n        onUpdate:options={ load }\n      ></VDataTableServer>\n    ))\n\n    cy.get('.v-data-table tbody tr')\n      .emitted(VDataTableServer, 'update:options')\n      .should('have.length', 1)\n  })\n\n  it('should only trigger update event once when changing itemsPerPage', () => {\n    const items = ref<any[]>([])\n    const options = ref({\n      itemsLength: DESSERT_ITEMS.length,\n      page: 1,\n      itemsPerPage: 2,\n    })\n\n    // eslint-disable-next-line sonarjs/no-identical-functions\n    function load (opts: { page: number, itemsPerPage: number }) {\n      setTimeout(() => {\n        const start = (opts.page - 1) * opts.itemsPerPage\n        const end = start + opts.itemsPerPage\n        items.value = DESSERT_ITEMS.slice(start, end)\n        options.value = {\n          ...options.value,\n          ...opts,\n        }\n      }, 10)\n    }\n\n    cy.mount(() => (\n      <Application>\n        <VDataTableServer\n          headers={ DESSERT_HEADERS }\n          items={ items.value }\n          { ...options.value }\n          onUpdate:options={ load }\n        ></VDataTableServer>\n      </Application>\n    ))\n\n    cy.get('.v-btn[aria-label=\"Next page\"]')\n      .click()\n    cy.get('.v-select')\n      .click()\n    cy.get('.v-list-item')\n      .eq(0)\n      .click()\n    cy.emitted(VDataTableServer, 'update:options')\n      .should('deep.equal', [\n        [{ page: 1, itemsPerPage: 2, sortBy: [], groupBy: [], search: undefined }],\n        [{ page: 2, itemsPerPage: 2, sortBy: [], groupBy: [], search: undefined }],\n        [{ page: 1, itemsPerPage: 10, sortBy: [], groupBy: [], search: undefined }],\n      ])\n  })\n\n  it('should only trigger update event once when changing sort', () => {\n    const items = ref<any[]>([])\n    const options = ref({\n      itemsLength: DESSERT_ITEMS.length,\n      page: 1,\n      itemsPerPage: 2,\n    })\n\n    // eslint-disable-next-line sonarjs/no-identical-functions\n    function load (opts: { page: number, itemsPerPage: number }) {\n      setTimeout(() => {\n        const start = (opts.page - 1) * opts.itemsPerPage\n        const end = start + opts.itemsPerPage\n        items.value = DESSERT_ITEMS.slice(start, end)\n        options.value = {\n          ...options.value,\n          ...opts,\n        }\n      }, 10)\n    }\n\n    cy.mount(() => (\n      <Application>\n        <VDataTableServer\n          headers={ DESSERT_HEADERS }\n          items={ items.value }\n          { ...options.value }\n          onUpdate:options={ load }\n        ></VDataTableServer>\n      </Application>\n    ))\n\n    cy.get('.v-btn[aria-label=\"Next page\"]')\n      .click()\n    cy.get('th')\n      .eq(0)\n      .click()\n    cy.emitted(VDataTableServer, 'update:options')\n      .should('deep.equal', [\n        [{ page: 1, itemsPerPage: 2, sortBy: [], groupBy: [], search: undefined }],\n        [{ page: 2, itemsPerPage: 2, sortBy: [], groupBy: [], search: undefined }],\n        [{ page: 1, itemsPerPage: 2, sortBy: [{ key: 'name', order: 'asc' }], groupBy: [], search: undefined }],\n      ])\n  })\n\n  it('should only trigger update event once when search changes', () => {\n    const items = ref<any[]>([])\n    const options = ref({\n      itemsLength: DESSERT_ITEMS.length,\n      page: 1,\n      itemsPerPage: 2,\n      search: '',\n    })\n\n    // eslint-disable-next-line sonarjs/no-identical-functions\n    function load (opts: { page: number, itemsPerPage: number, search: string }) {\n      setTimeout(() => {\n        const start = (opts.page - 1) * opts.itemsPerPage\n        const end = start + opts.itemsPerPage\n        items.value = DESSERT_ITEMS\n          .filter(item => !opts.search || item.name.toLowerCase().includes(opts.search.toLowerCase()))\n          .slice(start, end)\n        options.value = {\n          ...options.value,\n          ...opts,\n        }\n      }, 10)\n    }\n\n    cy.mount(() => (\n      <Application>\n        <VDataTableServer\n          headers={ DESSERT_HEADERS }\n          items={ items.value }\n          { ...options.value }\n          onUpdate:options={ load }\n        ></VDataTableServer>\n      </Application>\n    ))\n\n    cy\n      .get('.v-btn[aria-label=\"Next page\"]')\n      .click()\n\n    cy.then(() => {\n      options.value = {\n        ...options.value,\n        search: 'frozen',\n      }\n    })\n      .emitted(VDataTableServer, 'update:options')\n      .should('deep.equal', [\n        [{ page: 1, itemsPerPage: 2, sortBy: [], groupBy: [], search: '' }],\n        [{ page: 2, itemsPerPage: 2, sortBy: [], groupBy: [], search: '' }],\n        [{ page: 1, itemsPerPage: 2, sortBy: [], groupBy: [], search: 'frozen' }],\n      ])\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/__tests__/VDataTableVirtual.spec.browser.tsx",
    "content": "// Utilities\nimport { render, screen } from '@test'\nimport { VDataTableVirtual } from '..'\n\nconst DESSERT_HEADERS = [\n  { title: 'Dessert (100g serving)', key: 'name' },\n  { title: 'Calories', key: 'calories' },\n  { title: 'Fat (g)', key: 'fat' },\n  { title: 'Carbs (g)', key: 'carbs' },\n  { title: 'Protein (g)', key: 'protein' },\n  { title: 'Iron (%)', key: 'iron' },\n]\n\nconst DESSERT_ITEMS = [\n  { name: 'Frozen Yogurt', calories: 159, fat: 6.0, carbs: 24, protein: 4.0, iron: '1%' },\n  { name: 'Ice cream sandwich', calories: 237, fat: 9.0, carbs: 37, protein: 4.3, iron: '1%' },\n  { name: 'Eclair', calories: 262, fat: 16.0, carbs: 23, protein: 6.0, iron: '7%' },\n  { name: 'Cupcake', calories: 305, fat: 3.7, carbs: 67, protein: 4.3, iron: '8%' },\n  { name: 'Gingerbread', calories: 356, fat: 16.0, carbs: 49, protein: 3.9, iron: '16%' },\n  { name: 'Jelly bean', calories: 375, fat: 0.0, carbs: 94, protein: 0.0, iron: '0%' },\n  { name: 'Lollipop', calories: 392, fat: 0.2, carbs: 98, protein: 0, iron: '2%' },\n  { name: 'Honeycomb', calories: 408, fat: 3.2, carbs: 87, protein: 6.5, iron: '45%' },\n  { name: 'Donut', calories: 452, fat: 25.0, carbs: 51, protein: 4.9, iron: '22%' },\n  { name: 'KitKat', calories: 518, fat: 26.0, carbs: 65, protein: 7, iron: '6%' },\n]\n\ndescribe('VDataTableVirtual', () => {\n  it('should render only visible items', async () => {\n    const items = [...new Array(10)].reduce(curr => {\n      curr.push(...DESSERT_ITEMS)\n      return curr\n    }, [])\n\n    render(() => (\n      <VDataTableVirtual items={ items } headers={ DESSERT_HEADERS } height={ 500 } />\n    ))\n\n    const rows = screen.getAllByRole('row')\n    expect(rows.length).toBeLessThan(items.length)\n    await expect.element(rows[0]).not.toHaveStyle({ height: '0px' })\n    await expect.element(rows[rows.length - 1]).toHaveStyle({ height: '0px' })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/__tests__/VEditDialog.spec.ts",
    "content": "// @ts-nocheck\n/* eslint-disable */\n\n// import VEditDialog from '../VEditDialog'\n// import VMenu from '../../VMenu'\n\nimport {\n  mount,\n  Wrapper,\n  MountOptions,\n} from '@vue/test-utils'\n// import { keyCodes } from '../../../util/helpers'\n// import mixins from '../../../util/mixins'\n\ndescribe.skip('VEditDialog.ts', () => {\n  type Instance = InstanceType<typeof VEditDialog>\n  let mountFunction: (options?: MountOptions<Instance>) => Wrapper<Instance>\n  beforeEach(() => {\n    document.body.setAttribute('data-app', 'true')\n\n    mountFunction = (options?: MountOptions<Instance>) => {\n      return mount(VEditDialog, {\n        // https://github.com/vuejs/vue-test-utils/issues/1130\n        sync: false,\n        mocks: {\n          $vuetify: {\n            theme: {\n              dark: false,\n            },\n          },\n        },\n        ...options,\n      })\n    }\n  })\n\n  it('should render', () => {\n    const wrapper = mountFunction()\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render custom button texts', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        cancelText: `I don't want to modify that!`,\n        saveText: 'Save it!',\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should open and close', async () => {\n    jest.useFakeTimers()\n\n    const open = jest.fn()\n    const close = jest.fn()\n\n    const wrapper = mountFunction({\n      listeners: {\n        open,\n        close,\n      },\n    })\n\n    wrapper.vm.isActive = true\n    await wrapper.vm.$nextTick()\n    expect(open).toHaveBeenCalledTimes(1)\n    expect(setTimeout).toHaveBeenLastCalledWith(wrapper.vm.focus, 50)\n\n    wrapper.vm.isActive = false\n    await wrapper.vm.$nextTick()\n    expect(close).toHaveBeenCalledTimes(1)\n\n    jest.useRealTimers()\n  })\n\n  it('should react to menu', async () => {\n    const open = jest.fn()\n    const close = jest.fn()\n\n    const wrapper = mountFunction({\n      listeners: {\n        open,\n        close,\n      },\n    })\n\n    const menu = wrapper.find(VMenu)\n\n    menu.vm.$emit('input', true)\n    await wrapper.vm.$nextTick()\n    expect(open).toHaveBeenCalledTimes(1)\n\n    menu.vm.$emit('input', false)\n    await wrapper.vm.$nextTick()\n    expect(close).toHaveBeenCalledTimes(1)\n  })\n\n  it('should react to input', async () => {\n    jest.useFakeTimers()\n\n    const parentWrapper = mount({\n      template: `\n        <v-edit-dialog :return-value.sync=\"val\">\n          <template v-slot:input>\n            <input v-model=\"val\" class=\"test\"/>\n          </template>\n        </v-edit-dialog>\n      `,\n      components: {\n        'v-edit-dialog': mixins(VEditDialog).extend({\n          render () {\n            return this.genContent()\n          },\n        }),\n      },\n      data () {\n        return {\n          val: '',\n        }\n      },\n    })\n\n    const wrapper = parentWrapper.find(VEditDialog)\n    const field = parentWrapper.find('input.test')\n    const input = wrapper.vm.$refs.content as HTMLElement\n\n    // Make sure originalValue gets set\n    wrapper.vm.isActive = true\n    field.setValue('test')\n    input.dispatchEvent(new KeyboardEvent('keydown', { keyCode: keyCodes.esc } as KeyboardEventInit))\n    expect(wrapper.emitted('cancel')).toBeTruthy()\n    expect(wrapper.emitted('update:return-value')[0]).toEqual([''])\n    expect(wrapper.props('returnValue')).toBe('')\n\n    wrapper.vm.isActive = true\n    field.setValue('test')\n    input.dispatchEvent(new KeyboardEvent('keydown', { keyCode: keyCodes.enter } as KeyboardEventInit))\n    expect(wrapper.emitted('save')).toBeTruthy()\n    expect(setTimeout).toHaveBeenLastCalledWith(expect.any(Function))\n    jest.advanceTimersByTime(0)\n    expect(wrapper.emitted('update:return-value')[1]).toEqual(['test'])\n    expect(wrapper.props('returnValue')).toBe('test')\n\n    jest.useRealTimers()\n  })\n\n  it('should render button', () => {\n    const fn = jest.fn()\n\n    const wrapper = mountFunction({\n      render () {\n        return this.genButton(fn, 'test')\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n\n    const btn = wrapper.find('.v-btn')\n    btn.trigger('click')\n    expect(fn).toHaveBeenCalledTimes(1)\n  })\n\n  it('should focus', () => {\n    const wrapper = mountFunction({\n      render () {\n        return this.genContent()\n      },\n      slots: {\n        input: '<input class=\"test\" />',\n      },\n    })\n\n    const input = wrapper.find('input.test')\n\n    expect(document.activeElement).not.toEqual(input.element as HTMLInputElement)\n    wrapper.vm.focus()\n    expect(document.activeElement).toEqual(input.element as HTMLInputElement)\n  })\n\n  it('should render actions', () => {\n    const save = jest.fn()\n    const saveEvent = jest.fn()\n\n    const wrapper = mountFunction({\n      methods: {\n        save,\n      },\n      render () {\n        return this.genActions()\n      },\n      listeners: {\n        save: saveEvent,\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n\n    const btn = wrapper.find('.v-btn:last-child')\n    btn.trigger('click')\n    expect(save).toHaveBeenCalledTimes(1)\n    expect(saveEvent).toHaveBeenCalledTimes(1)\n  })\n\n  it('should cancel', () => {\n    const cancel = jest.fn()\n    const wrapper = mountFunction({\n      listeners: {\n        cancel,\n      },\n      data: () => ({\n        isActive: true,\n      }),\n    })\n\n    wrapper.vm.cancel()\n    expect(wrapper.vm.isActive).toBeFalsy()\n    expect(cancel).toHaveBeenCalledTimes(1)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/__tests__/VSimpleTable.spec.ts",
    "content": "// @ts-nocheck\n/* eslint-disable */\n\n// import VSimpleTable from '../VSimpleTable'\nimport {\n  mount,\n  Wrapper,\n  MountOptions,\n} from '@vue/test-utils'\n\ndescribe.skip('VSimpleTable.ts', () => {\n  type Instance = InstanceType<typeof VSimpleTable>\n  let mountFunction: (options?: MountOptions<Instance>) => Wrapper<Instance>\n  beforeEach(() => {\n    mountFunction = (options?: MountOptions<Instance>) => {\n      return mount(VSimpleTable, options)\n    }\n  })\n\n  it('should render', () => {\n    const wrapper = mountFunction({\n      slots: {\n        default: `\n          <tr><th>Foo</th><th>Bar</th></tr>\n          <tr><td>baz</td><td>qux</td></tr>\n        `,\n      },\n    })\n\n    expect(wrapper.findAll('.v-data-table')).toHaveLength(1)\n    expect(wrapper.findAll('.v-data-table .v-data-table__wrapper')).toHaveLength(1)\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render with custom wrapper', () => {\n    const wrapper = mountFunction({\n      slots: {\n        wrapper: `\n          <table>\n            <tr><th>Foo</th><th>Bar</th></tr>\n            <tr><td>baz</td><td>qux</td></tr>\n          </table>\n        `,\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render with top & bottom slots', () => {\n    const wrapper = mountFunction({\n      slots: {\n        top: '<div class=\"top\">Header</div>',\n        bottom: '<div class=\"bottom\">Footer</div>',\n      },\n    })\n\n    expect(wrapper.findAll('.top')).toHaveLength(1)\n    expect(wrapper.findAll('.bottom')).toHaveLength(1)\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render with custom height', () => {\n    const wrapper = mountFunction({\n      slots: {\n        default: `\n          <tr><th>Foo</th><th>Bar</th></tr>\n          <tr><td>baz</td><td>qux</td></tr>\n        `,\n      },\n      propsData: {\n        height: 1000,\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should compute classes', () => {\n    const wrapper = mountFunction()\n\n    wrapper.setProps({\n      dense: true,\n    })\n    expect(wrapper.vm.classes).toMatchObject({\n      'v-data-table--dense': true,\n    })\n    wrapper.setProps({\n      dark: true,\n    })\n    expect(wrapper.vm.classes).toMatchObject({\n      'theme--dark': true,\n      'theme--light': false,\n    })\n    wrapper.setProps({\n      fixedHeader: true,\n    })\n    expect(wrapper.vm.classes).toMatchObject({\n      'v-data-table--fixed-header': true,\n    })\n    wrapper.setProps({\n      fixedHeader: false,\n      height: 1000,\n    })\n    expect(wrapper.vm.classes).toMatchObject({\n      'v-data-table--fixed-height': true,\n    })\n  })\n\n  it('should compute classes with top & bottom slots', () => {\n    const wrapper = mountFunction({\n      slots: {\n        top: '<div class=\"top\">Header</div>',\n        bottom: '<div class=\"bottom\">Footer</div>',\n      },\n    })\n\n    expect(wrapper.vm.classes).toMatchObject({\n      'v-data-table--has-top': true,\n      'v-data-table--has-bottom': true,\n    })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/__tests__/VVirtualTable.spec.ts",
    "content": "// @ts-nocheck\n/* eslint-disable */\n\n// import VVirtualTable from '../VVirtualTable'\nimport {\n  mount,\n  Wrapper,\n  MountOptions,\n} from '@vue/test-utils'\n// import Vue from 'vue'\n\ndescribe.skip('VVirtualTable.ts', () => {\n  type Instance = InstanceType<typeof VVirtualTable>\n  let mountFunction: (options?: MountOptions<Instance>) => Wrapper<Instance>\n  beforeEach(() => {\n    mountFunction = (options?: MountOptions<Instance>) => {\n      return mount(VVirtualTable, options)\n    }\n  })\n\n  it('should render', () => {\n    const vm = new Vue()\n\n    const wrapper = mountFunction({\n      propsData: {\n        items: ['a', 'b', 'c'],\n      },\n      scopedSlots: {\n        items: props => vm.$createElement('div', { staticClass: 'test' }, [JSON.stringify(props)]),\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should re-render when items change', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        items: ['a', 'b', 'c'],\n      },\n      scopedSlots: {\n        items (props) {\n          return this.$createElement('div', props.items.map(i => this.$createElement('div', [i])))\n        },\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n\n    wrapper.setProps({\n      items: ['d', 'e', 'f'],\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/__tests__/__snapshots__/MobileRow.spec.ts.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`MobileRow should render non-string values 1`] = `\n<tr class=\"v-data-table__mobile-table-row\">\n  <td class=\"v-data-table__mobile-row\">\n    <div class=\"v-data-table__mobile-row__header\">\n    </div>\n    <div class=\"v-data-table__mobile-row__cell\">\n      string\n    </div>\n  </td>\n  <td class=\"v-data-table__mobile-row\">\n    <div class=\"v-data-table__mobile-row__header\">\n    </div>\n    <div class=\"v-data-table__mobile-row__cell\">\n      12.34\n    </div>\n  </td>\n  <td class=\"v-data-table__mobile-row\">\n    <div class=\"v-data-table__mobile-row__header\">\n    </div>\n    <div class=\"v-data-table__mobile-row__cell\">\n      1,2\n    </div>\n  </td>\n  <td class=\"v-data-table__mobile-row\">\n    <div class=\"v-data-table__mobile-row__header\">\n    </div>\n    <div class=\"v-data-table__mobile-row__cell\">\n      false\n    </div>\n  </td>\n  <td class=\"v-data-table__mobile-row\">\n    <div class=\"v-data-table__mobile-row__header\">\n    </div>\n    <div class=\"v-data-table__mobile-row__cell\">\n      [object Object]\n    </div>\n  </td>\n  <td class=\"v-data-table__mobile-row\">\n    <div class=\"v-data-table__mobile-row__header\">\n    </div>\n    <div class=\"v-data-table__mobile-row__cell\">\n    </div>\n  </td>\n  <td class=\"v-data-table__mobile-row\">\n    <div class=\"v-data-table__mobile-row__header\">\n    </div>\n    <div class=\"v-data-table__mobile-row__cell\">\n    </div>\n  </td>\n</tr>\n`;\n\nexports[`MobileRow should render with regular slots 1`] = `\n<tr class=\"v-data-table__mobile-table-row\">\n  <td class=\"v-data-table__mobile-row\">\n    <div class=\"v-data-table__mobile-row__header\">\n      Petrol\n    </div>\n    <div class=\"v-data-table__mobile-row__cell\">\n      <p class=\"test\">\n        $0.68\n      </p>\n    </div>\n  </td>\n  <td class=\"v-data-table__mobile-row\">\n    <div class=\"v-data-table__mobile-row__header\">\n      Diesel\n    </div>\n    <div class=\"v-data-table__mobile-row__cell\">\n      <p class=\"test\">\n        $0.65\n      </p>\n    </div>\n  </td>\n</tr>\n`;\n\nexports[`MobileRow should render with scoped slots 1`] = `\n<tr class=\"v-data-table__mobile-table-row\">\n  <td class=\"v-data-table__mobile-row\">\n    <div class=\"v-data-table__mobile-row__header\">\n      Petrol\n    </div>\n    <div class=\"v-data-table__mobile-row__cell\">\n      <p class=\"test petrol\">\n        0.68\n      </p>\n    </div>\n  </td>\n  <td class=\"v-data-table__mobile-row\">\n    <div class=\"v-data-table__mobile-row__header\">\n      Diesel\n    </div>\n    <div class=\"v-data-table__mobile-row__cell\">\n      <p class=\"test diesel\">\n        0.65\n      </p>\n    </div>\n  </td>\n</tr>\n`;\n\nexports[`MobileRow should render without header when hideDefaultHeader: true 1`] = `\n<tr class=\"v-data-table__mobile-table-row\">\n  <td class=\"v-data-table__mobile-row\">\n    <div class=\"v-data-table__mobile-row__cell\">\n      0.68\n    </div>\n  </td>\n  <td class=\"v-data-table__mobile-row\">\n    <div class=\"v-data-table__mobile-row__cell\">\n      0.65\n    </div>\n  </td>\n</tr>\n`;\n\nexports[`MobileRow should render without slots 1`] = `\n<tr class=\"v-data-table__mobile-table-row\">\n  <td class=\"v-data-table__mobile-row\">\n    <div class=\"v-data-table__mobile-row__header\">\n      Petrol\n    </div>\n    <div class=\"v-data-table__mobile-row__cell\">\n      0.68\n    </div>\n  </td>\n  <td class=\"v-data-table__mobile-row\">\n    <div class=\"v-data-table__mobile-row__header\">\n      Diesel\n    </div>\n    <div class=\"v-data-table__mobile-row__cell\">\n      0.65\n    </div>\n  </td>\n</tr>\n`;\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/__tests__/__snapshots__/Row.spec.ts.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`Table Row should render non-string values 1`] = `\n<tr>\n  <td class=\"text-start\">\n    string\n  </td>\n  <td class=\"text-start\">\n    12.34\n  </td>\n  <td class=\"text-start\">\n    1,2\n  </td>\n  <td class=\"text-start\">\n    false\n  </td>\n  <td class=\"text-start\">\n    [object Object]\n  </td>\n  <td class=\"text-start\">\n  </td>\n  <td class=\"text-start\">\n  </td>\n</tr>\n`;\n\nexports[`Table Row should render with cellClass 1`] = `\n<tr>\n  <td class=\"text-start a\">\n    0.68\n  </td>\n  <td class=\"text-start b c\">\n    0.65\n  </td>\n</tr>\n`;\n\nexports[`Table Row should render without slots 1`] = `\n<tr>\n  <td class=\"text-start\">\n    0.68\n  </td>\n  <td class=\"text-start\">\n    0.65\n  </td>\n</tr>\n`;\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/__tests__/__snapshots__/RowGroup.spec.ts.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`Table RowGroup should render with \"column.summary\" slot 1`] = `\n<tr class=\"v-row-group__summary\">\n  <div>\n  </div>\n</tr>\n`;\n\nexports[`Table RowGroup should render with \"row.summary\" slot 1`] = `\n<div>\n</div>\n`;\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/__tests__/__snapshots__/VDataTable.spec.ts.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`VDataTable.ts should apply class from item to rows 1`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n          <th>\n            <div class=\"v-data-table-header-mobile__wrapper\">\n              <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n                <div class=\"v-input__control\">\n                  <div role=\"button\"\n                       aria-haspopup=\"listbox\"\n                       aria-expanded=\"false\"\n                       aria-owns=\"list-699\"\n                       class=\"v-input__slot\"\n                  >\n                    <div class=\"v-select__slot\">\n                      <label for=\"input-699\"\n                             class=\"v-label theme--light\"\n                             style=\"left: 0px; position: absolute;\"\n                      >\n                        Sort by\n                      </label>\n                      <div class=\"v-select__selections\">\n                        <input id=\"input-699\"\n                               readonly=\"readonly\"\n                               type=\"text\"\n                               aria-readonly=\"false\"\n                               autocomplete=\"off\"\n                        >\n                      </div>\n                      <div class=\"v-input__append-inner\">\n                        <div class=\"v-input__icon v-input__icon--append\">\n                          <i aria-hidden=\"true\"\n                             class=\"v-icon notranslate material-icons theme--light\"\n                          >\n                            $dropdown\n                          </i>\n                        </div>\n                      </div>\n                      <input type=\"hidden\">\n                    </div>\n                    <div class=\"v-menu\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-data-table__mobile-table-row test\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Frozen Yogurt\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              159\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              24\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row test second\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Ice cream sandwich\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              237\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              37\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row test\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Eclair\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              262\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              23\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              7%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Cupcake\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              305\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.7\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              67\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              8%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Gingerbread\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              356\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              49\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16%\n            </div>\n          </td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-703\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  5\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-703\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"5\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      1-5 of 10\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              class=\"v-btn v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should apply class function to rows 1`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n          <th>\n            <div class=\"v-data-table-header-mobile__wrapper\">\n              <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n                <div class=\"v-input__control\">\n                  <div role=\"button\"\n                       aria-haspopup=\"listbox\"\n                       aria-expanded=\"false\"\n                       aria-owns=\"list-683\"\n                       class=\"v-input__slot\"\n                  >\n                    <div class=\"v-select__slot\">\n                      <label for=\"input-683\"\n                             class=\"v-label theme--light\"\n                             style=\"left: 0px; position: absolute;\"\n                      >\n                        Sort by\n                      </label>\n                      <div class=\"v-select__selections\">\n                        <input id=\"input-683\"\n                               readonly=\"readonly\"\n                               type=\"text\"\n                               aria-readonly=\"false\"\n                               autocomplete=\"off\"\n                        >\n                      </div>\n                      <div class=\"v-input__append-inner\">\n                        <div class=\"v-input__icon v-input__icon--append\">\n                          <i aria-hidden=\"true\"\n                             class=\"v-icon notranslate material-icons theme--light\"\n                          >\n                            $dropdown\n                          </i>\n                        </div>\n                      </div>\n                      <input type=\"hidden\">\n                    </div>\n                    <div class=\"v-menu\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-data-table__mobile-table-row first-class\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Frozen Yogurt\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              159\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              24\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row first-class second-class\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Ice cream sandwich\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              237\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              37\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row second-class\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Eclair\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              262\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              23\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              7%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row first-class second-class\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Cupcake\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              305\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.7\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              67\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              8%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Gingerbread\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              356\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              49\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16%\n            </div>\n          </td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-687\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  5\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-687\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"5\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      1-5 of 10\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              class=\"v-btn v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should apply class list to rows 1`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n          <th>\n            <div class=\"v-data-table-header-mobile__wrapper\">\n              <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n                <div class=\"v-input__control\">\n                  <div role=\"button\"\n                       aria-haspopup=\"listbox\"\n                       aria-expanded=\"false\"\n                       aria-owns=\"list-651\"\n                       class=\"v-input__slot\"\n                  >\n                    <div class=\"v-select__slot\">\n                      <label for=\"input-651\"\n                             class=\"v-label theme--light\"\n                             style=\"left: 0px; position: absolute;\"\n                      >\n                        Sort by\n                      </label>\n                      <div class=\"v-select__selections\">\n                        <input id=\"input-651\"\n                               readonly=\"readonly\"\n                               type=\"text\"\n                               aria-readonly=\"false\"\n                               autocomplete=\"off\"\n                        >\n                      </div>\n                      <div class=\"v-input__append-inner\">\n                        <div class=\"v-input__icon v-input__icon--append\">\n                          <i aria-hidden=\"true\"\n                             class=\"v-icon notranslate material-icons theme--light\"\n                          >\n                            $dropdown\n                          </i>\n                        </div>\n                      </div>\n                      <input type=\"hidden\">\n                    </div>\n                    <div class=\"v-menu\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-data-table__mobile-table-row my-class my-other-class\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Frozen Yogurt\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              159\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              24\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row my-class my-other-class\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Ice cream sandwich\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              237\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              37\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row my-class my-other-class\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Eclair\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              262\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              23\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              7%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row my-class my-other-class\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Cupcake\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              305\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.7\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              67\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              8%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row my-class my-other-class\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Gingerbread\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              356\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              49\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16%\n            </div>\n          </td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-655\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  5\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-655\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"5\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      1-5 of 10\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              class=\"v-btn v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should apply class unique to rows 1`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n          <th>\n            <div class=\"v-data-table-header-mobile__wrapper\">\n              <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n                <div class=\"v-input__control\">\n                  <div role=\"button\"\n                       aria-haspopup=\"listbox\"\n                       aria-expanded=\"false\"\n                       aria-owns=\"list-667\"\n                       class=\"v-input__slot\"\n                  >\n                    <div class=\"v-select__slot\">\n                      <label for=\"input-667\"\n                             class=\"v-label theme--light\"\n                             style=\"left: 0px; position: absolute;\"\n                      >\n                        Sort by\n                      </label>\n                      <div class=\"v-select__selections\">\n                        <input id=\"input-667\"\n                               readonly=\"readonly\"\n                               type=\"text\"\n                               aria-readonly=\"false\"\n                               autocomplete=\"off\"\n                        >\n                      </div>\n                      <div class=\"v-input__append-inner\">\n                        <div class=\"v-input__icon v-input__icon--append\">\n                          <i aria-hidden=\"true\"\n                             class=\"v-icon notranslate material-icons theme--light\"\n                          >\n                            $dropdown\n                          </i>\n                        </div>\n                      </div>\n                      <input type=\"hidden\">\n                    </div>\n                    <div class=\"v-menu\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-data-table__mobile-table-row my-unique-class\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Frozen Yogurt\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              159\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              24\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row my-unique-class\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Ice cream sandwich\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              237\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              37\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row my-unique-class\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Eclair\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              262\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              23\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              7%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row my-unique-class\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Cupcake\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              305\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.7\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              67\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              8%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row my-unique-class\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Gingerbread\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              356\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              49\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16%\n            </div>\n          </td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-671\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  5\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-671\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"5\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      1-5 of 10\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              class=\"v-btn v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should change page if item count decreases below page start 1`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n          <th>\n            <div class=\"v-data-table-header-mobile__wrapper\">\n              <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n                <div class=\"v-input__control\">\n                  <div role=\"button\"\n                       aria-haspopup=\"listbox\"\n                       aria-expanded=\"false\"\n                       aria-owns=\"list-483\"\n                       class=\"v-input__slot\"\n                  >\n                    <div class=\"v-select__slot\">\n                      <label for=\"input-483\"\n                             class=\"v-label theme--light\"\n                             style=\"left: 0px; position: absolute;\"\n                      >\n                        Sort by\n                      </label>\n                      <div class=\"v-select__selections\">\n                        <input id=\"input-483\"\n                               readonly=\"readonly\"\n                               type=\"text\"\n                               aria-readonly=\"false\"\n                               autocomplete=\"off\"\n                        >\n                      </div>\n                      <div class=\"v-input__append-inner\">\n                        <div class=\"v-input__icon v-input__icon--append\">\n                          <i aria-hidden=\"true\"\n                             class=\"v-icon notranslate material-icons theme--light\"\n                          >\n                            $dropdown\n                          </i>\n                        </div>\n                      </div>\n                      <input type=\"hidden\">\n                    </div>\n                    <div class=\"v-menu\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Eclair\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              262\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              23\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              7%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Cupcake\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              305\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.7\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              67\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              8%\n            </div>\n          </td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__pagination\">\n      3-4 of 4\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              class=\"v-btn v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should default to first option in itemsPerPageOptions if it does not include itemsPerPage 1`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n          <th>\n            <div class=\"v-data-table-header-mobile__wrapper\">\n              <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n                <div class=\"v-input__control\">\n                  <div role=\"button\"\n                       aria-haspopup=\"listbox\"\n                       aria-expanded=\"false\"\n                       aria-owns=\"list-435\"\n                       class=\"v-input__slot\"\n                  >\n                    <div class=\"v-select__slot\">\n                      <label for=\"input-435\"\n                             class=\"v-label theme--light\"\n                             style=\"left: 0px; position: absolute;\"\n                      >\n                        Sort by\n                      </label>\n                      <div class=\"v-select__selections\">\n                        <input id=\"input-435\"\n                               readonly=\"readonly\"\n                               type=\"text\"\n                               aria-readonly=\"false\"\n                               autocomplete=\"off\"\n                        >\n                      </div>\n                      <div class=\"v-input__append-inner\">\n                        <div class=\"v-input__icon v-input__icon--append\">\n                          <i aria-hidden=\"true\"\n                             class=\"v-icon notranslate material-icons theme--light\"\n                          >\n                            $dropdown\n                          </i>\n                        </div>\n                      </div>\n                      <input type=\"hidden\">\n                    </div>\n                    <div class=\"v-menu\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Frozen Yogurt\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              159\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              24\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Ice cream sandwich\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              237\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              37\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Eclair\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              262\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              23\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              7%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Cupcake\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              305\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.7\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              67\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              8%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Gingerbread\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              356\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              49\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Jelly bean\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              375\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              94\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0%\n            </div>\n          </td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-439\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  6\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-439\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"6\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      1-6 of 10\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              class=\"v-btn v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should handle object when checking if it should default to first option in itemsPerPageOptions 1`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n          <th>\n            <div class=\"v-data-table-header-mobile__wrapper\">\n              <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n                <div class=\"v-input__control\">\n                  <div role=\"button\"\n                       aria-haspopup=\"listbox\"\n                       aria-expanded=\"false\"\n                       aria-owns=\"list-451\"\n                       class=\"v-input__slot\"\n                  >\n                    <div class=\"v-select__slot\">\n                      <label for=\"input-451\"\n                             class=\"v-label theme--light\"\n                             style=\"left: 0px; position: absolute;\"\n                      >\n                        Sort by\n                      </label>\n                      <div class=\"v-select__selections\">\n                        <input id=\"input-451\"\n                               readonly=\"readonly\"\n                               type=\"text\"\n                               aria-readonly=\"false\"\n                               autocomplete=\"off\"\n                        >\n                      </div>\n                      <div class=\"v-input__append-inner\">\n                        <div class=\"v-input__icon v-input__icon--append\">\n                          <i aria-hidden=\"true\"\n                             class=\"v-icon notranslate material-icons theme--light\"\n                          >\n                            $dropdown\n                          </i>\n                        </div>\n                      </div>\n                      <input type=\"hidden\">\n                    </div>\n                    <div class=\"v-menu\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Frozen Yogurt\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              159\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              24\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Ice cream sandwich\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              237\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              37\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Eclair\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              262\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              23\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              7%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Cupcake\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              305\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.7\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              67\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              8%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Gingerbread\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              356\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              49\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Jelly bean\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              375\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              94\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Lollipop\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              392\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0.2\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              98\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              2%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Honeycomb\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              408\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.2\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              87\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6.5\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              45%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Donut\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              452\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              25\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              51\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              22%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              KitKat\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              518\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              26\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              65\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              7\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6%\n            </div>\n          </td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-455\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  All\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-455\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"-1\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      1-10 of 10\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should hide group button when column is not groupable 1`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n          <th>\n            <div class=\"v-data-table-header-mobile__wrapper\">\n              <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n                <div class=\"v-input__control\">\n                  <div role=\"button\"\n                       aria-haspopup=\"listbox\"\n                       aria-expanded=\"false\"\n                       aria-owns=\"list-747\"\n                       class=\"v-input__slot\"\n                  >\n                    <div class=\"v-select__slot\">\n                      <label for=\"input-747\"\n                             class=\"v-label theme--light\"\n                             style=\"left: 0px; position: absolute;\"\n                      >\n                        Sort by\n                      </label>\n                      <div class=\"v-select__selections\">\n                        <input id=\"input-747\"\n                               readonly=\"readonly\"\n                               type=\"text\"\n                               aria-readonly=\"false\"\n                               autocomplete=\"off\"\n                        >\n                      </div>\n                      <div class=\"v-input__append-inner\">\n                        <div class=\"v-input__icon v-input__icon--append\">\n                          <i aria-hidden=\"true\"\n                             class=\"v-icon notranslate material-icons theme--light\"\n                          >\n                            $dropdown\n                          </i>\n                        </div>\n                      </div>\n                      <input type=\"hidden\">\n                    </div>\n                    <div class=\"v-menu\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Frozen Yogurt\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              159\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              24\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Ice cream sandwich\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              237\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              37\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Eclair\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              262\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              23\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              7%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Cupcake\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              305\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.7\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              67\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              8%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Gingerbread\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              356\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              49\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Jelly bean\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              375\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              94\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Lollipop\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              392\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0.2\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              98\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              2%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Honeycomb\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              408\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.2\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              87\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6.5\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              45%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Donut\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              452\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              25\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              51\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              22%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              KitKat\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              518\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              26\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              65\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              7\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6%\n            </div>\n          </td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-751\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  10\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-751\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"10\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      1-10 of 10\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should limit page to current page count if not using server-items-length 1`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n          <th>\n            <div class=\"v-data-table-header-mobile__wrapper\">\n              <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n                <div class=\"v-input__control\">\n                  <div role=\"button\"\n                       aria-haspopup=\"listbox\"\n                       aria-expanded=\"false\"\n                       aria-owns=\"list-419\"\n                       class=\"v-input__slot\"\n                  >\n                    <div class=\"v-select__slot\">\n                      <label for=\"input-419\"\n                             class=\"v-label theme--light\"\n                             style=\"left: 0px; position: absolute;\"\n                      >\n                        Sort by\n                      </label>\n                      <div class=\"v-select__selections\">\n                        <input id=\"input-419\"\n                               readonly=\"readonly\"\n                               type=\"text\"\n                               aria-readonly=\"false\"\n                               autocomplete=\"off\"\n                        >\n                      </div>\n                      <div class=\"v-input__append-inner\">\n                        <div class=\"v-input__icon v-input__icon--append\">\n                          <i aria-hidden=\"true\"\n                             class=\"v-icon notranslate material-icons theme--light\"\n                          >\n                            $dropdown\n                          </i>\n                        </div>\n                      </div>\n                      <input type=\"hidden\">\n                    </div>\n                    <div class=\"v-menu\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Jelly bean\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              375\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              94\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Lollipop\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              392\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0.2\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              98\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              2%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Honeycomb\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              408\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.2\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              87\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6.5\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              45%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Donut\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              452\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              25\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              51\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              22%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              KitKat\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              518\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              26\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              65\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              7\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6%\n            </div>\n          </td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-423\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  5\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-423\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"5\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      6-10 of 10\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              class=\"v-btn v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should not limit page to current item count when using server-items-length 1`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n          <th>\n            <div class=\"v-data-table-header-mobile__wrapper\">\n              <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n                <div class=\"v-input__control\">\n                  <div role=\"button\"\n                       aria-haspopup=\"listbox\"\n                       aria-expanded=\"false\"\n                       aria-owns=\"list-371\"\n                       class=\"v-input__slot\"\n                  >\n                    <div class=\"v-select__slot\">\n                      <label for=\"input-371\"\n                             class=\"v-label theme--light\"\n                             style=\"left: 0px; position: absolute;\"\n                      >\n                        Sort by\n                      </label>\n                      <div class=\"v-select__selections\">\n                        <input id=\"input-371\"\n                               readonly=\"readonly\"\n                               type=\"text\"\n                               aria-readonly=\"false\"\n                               autocomplete=\"off\"\n                        >\n                      </div>\n                      <div class=\"v-input__append-inner\">\n                        <div class=\"v-input__icon v-input__icon--append\">\n                          <i aria-hidden=\"true\"\n                             class=\"v-icon notranslate material-icons theme--light\"\n                          >\n                            $dropdown\n                          </i>\n                        </div>\n                      </div>\n                      <input type=\"hidden\">\n                    </div>\n                    <div class=\"v-menu\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-data-table__empty-wrapper\">\n          <td>\n            No data available\n          </td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-375\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  5\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-375\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"5\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      –\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              class=\"v-btn v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should not limit page to current item count when using server-items-length 2`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n          <th>\n            <div class=\"v-data-table-header-mobile__wrapper\">\n              <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n                <div class=\"v-input__control\">\n                  <div role=\"button\"\n                       aria-haspopup=\"listbox\"\n                       aria-expanded=\"false\"\n                       aria-owns=\"list-371\"\n                       class=\"v-input__slot\"\n                  >\n                    <div class=\"v-select__slot\">\n                      <label for=\"input-371\"\n                             class=\"v-label theme--light\"\n                             style=\"left: 0px; position: absolute;\"\n                      >\n                        Sort by\n                      </label>\n                      <div class=\"v-select__selections\">\n                        <input id=\"input-371\"\n                               readonly=\"readonly\"\n                               type=\"text\"\n                               aria-readonly=\"false\"\n                               autocomplete=\"off\"\n                        >\n                      </div>\n                      <div class=\"v-input__append-inner\">\n                        <div class=\"v-input__icon v-input__icon--append\">\n                          <i aria-hidden=\"true\"\n                             class=\"v-icon notranslate material-icons theme--light\"\n                          >\n                            $dropdown\n                          </i>\n                        </div>\n                      </div>\n                      <input type=\"hidden\">\n                    </div>\n                    <div class=\"v-menu\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Jelly bean\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              375\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              94\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Lollipop\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              392\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0.2\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              98\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              2%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Honeycomb\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              408\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.2\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              87\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6.5\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              45%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Donut\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              452\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              25\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              51\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              22%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              KitKat\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              518\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              26\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              65\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              7\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6%\n            </div>\n          </td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-375\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  5\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-375\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"5\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      6-10 of 20\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              class=\"v-btn v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              class=\"v-btn v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should not search column with filterable set to false 1`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n          <th>\n            <div class=\"v-data-table-header-mobile__wrapper\">\n              <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n                <div class=\"v-input__control\">\n                  <div role=\"button\"\n                       aria-haspopup=\"listbox\"\n                       aria-expanded=\"false\"\n                       aria-owns=\"list-387\"\n                       class=\"v-input__slot\"\n                  >\n                    <div class=\"v-select__slot\">\n                      <label for=\"input-387\"\n                             class=\"v-label theme--light\"\n                             style=\"left: 0px; position: absolute;\"\n                      >\n                        Sort by\n                      </label>\n                      <div class=\"v-select__selections\">\n                        <input id=\"input-387\"\n                               readonly=\"readonly\"\n                               type=\"text\"\n                               aria-readonly=\"false\"\n                               autocomplete=\"off\"\n                        >\n                      </div>\n                      <div class=\"v-input__append-inner\">\n                        <div class=\"v-input__icon v-input__icon--append\">\n                          <i aria-hidden=\"true\"\n                             class=\"v-icon notranslate material-icons theme--light\"\n                          >\n                            $dropdown\n                          </i>\n                        </div>\n                      </div>\n                      <input type=\"hidden\">\n                    </div>\n                    <div class=\"v-menu\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Frozen Yogurt\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              159\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              24\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Ice cream sandwich\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              237\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              37\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Eclair\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              262\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              23\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              7%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Cupcake\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              305\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.7\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              67\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              8%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Gingerbread\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              356\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              49\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Jelly bean\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              375\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              94\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Lollipop\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              392\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0.2\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              98\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              2%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Honeycomb\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              408\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.2\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              87\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6.5\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              45%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Donut\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              452\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              25\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              51\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              22%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              KitKat\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              518\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              26\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              65\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              7\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6%\n            </div>\n          </td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-391\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  10\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-391\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"10\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      1-10 of 10\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should not search column with filterable set to false 2`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n          <th>\n            <div class=\"v-data-table-header-mobile__wrapper\">\n              <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n                <div class=\"v-input__control\">\n                  <div role=\"button\"\n                       aria-haspopup=\"listbox\"\n                       aria-expanded=\"false\"\n                       aria-owns=\"list-387\"\n                       class=\"v-input__slot\"\n                  >\n                    <div class=\"v-select__slot\">\n                      <label for=\"input-387\"\n                             class=\"v-label theme--light\"\n                             style=\"left: 0px; position: absolute;\"\n                      >\n                        Sort by\n                      </label>\n                      <div class=\"v-select__selections\">\n                        <input id=\"input-387\"\n                               readonly=\"readonly\"\n                               type=\"text\"\n                               aria-readonly=\"false\"\n                               autocomplete=\"off\"\n                        >\n                      </div>\n                      <div class=\"v-input__append-inner\">\n                        <div class=\"v-input__icon v-input__icon--append\">\n                          <i aria-hidden=\"true\"\n                             class=\"v-icon notranslate material-icons theme--light\"\n                          >\n                            $dropdown\n                          </i>\n                        </div>\n                      </div>\n                      <input type=\"hidden\">\n                    </div>\n                    <div class=\"v-menu\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-data-table__empty-wrapper\">\n          <td class>\n            No matching records found\n          </td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-391\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  10\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-391\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"10\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      –\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should not search column with filterable set to false and has filter function 1`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n          <th>\n            <div class=\"v-data-table-header-mobile__wrapper\">\n              <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n                <div class=\"v-input__control\">\n                  <div role=\"button\"\n                       aria-haspopup=\"listbox\"\n                       aria-expanded=\"false\"\n                       aria-owns=\"list-403\"\n                       class=\"v-input__slot\"\n                  >\n                    <div class=\"v-select__slot\">\n                      <label for=\"input-403\"\n                             class=\"v-label theme--light\"\n                             style=\"left: 0px; position: absolute;\"\n                      >\n                        Sort by\n                      </label>\n                      <div class=\"v-select__selections\">\n                        <input id=\"input-403\"\n                               readonly=\"readonly\"\n                               type=\"text\"\n                               aria-readonly=\"false\"\n                               autocomplete=\"off\"\n                        >\n                      </div>\n                      <div class=\"v-input__append-inner\">\n                        <div class=\"v-input__icon v-input__icon--append\">\n                          <i aria-hidden=\"true\"\n                             class=\"v-icon notranslate material-icons theme--light\"\n                          >\n                            $dropdown\n                          </i>\n                        </div>\n                      </div>\n                      <input type=\"hidden\">\n                    </div>\n                    <div class=\"v-menu\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Honeycomb\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              408\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.2\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              87\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6.5\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              45%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Donut\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              452\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              25\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              51\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              22%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              KitKat\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              518\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              26\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              65\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              7\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6%\n            </div>\n          </td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-407\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  10\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-407\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"10\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      1-3 of 3\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should not search column with filterable set to false and has filter function 2`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n          <th>\n            <div class=\"v-data-table-header-mobile__wrapper\">\n              <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n                <div class=\"v-input__control\">\n                  <div role=\"button\"\n                       aria-haspopup=\"listbox\"\n                       aria-expanded=\"false\"\n                       aria-owns=\"list-403\"\n                       class=\"v-input__slot\"\n                  >\n                    <div class=\"v-select__slot\">\n                      <label for=\"input-403\"\n                             class=\"v-label theme--light\"\n                             style=\"left: 0px; position: absolute;\"\n                      >\n                        Sort by\n                      </label>\n                      <div class=\"v-select__selections\">\n                        <input id=\"input-403\"\n                               readonly=\"readonly\"\n                               type=\"text\"\n                               aria-readonly=\"false\"\n                               autocomplete=\"off\"\n                        >\n                      </div>\n                      <div class=\"v-input__append-inner\">\n                        <div class=\"v-input__icon v-input__icon--append\">\n                          <i aria-hidden=\"true\"\n                             class=\"v-icon notranslate material-icons theme--light\"\n                          >\n                            $dropdown\n                          </i>\n                        </div>\n                      </div>\n                      <input type=\"hidden\">\n                    </div>\n                    <div class=\"v-menu\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Frozen Yogurt\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              159\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              24\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Ice cream sandwich\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              237\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              37\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Eclair\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              262\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              23\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              7%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Cupcake\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              305\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.7\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              67\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              8%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Gingerbread\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              356\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              49\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Jelly bean\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              375\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              94\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Lollipop\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              392\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0.2\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              98\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              2%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Honeycomb\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              408\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.2\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              87\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6.5\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              45%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Donut\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              452\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              25\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              51\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              22%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              KitKat\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              518\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              26\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              65\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              7\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6%\n            </div>\n          </td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-407\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  10\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-407\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"10\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      1-10 of 10\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should not select item that is not selectable 1`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n          <th>\n            <div class=\"v-data-table-header-mobile__wrapper\">\n              <div width=\"1px\"\n                   class=\"v-data-table-header-mobile__select\"\n              >\n                <div class=\"v-data-table__checkbox v-simple-checkbox\">\n                  <div class=\"v-input--selection-controls__input\">\n                    <i aria-hidden=\"true\"\n                       class=\"v-icon notranslate material-icons theme--light\"\n                    >\n                      $checkboxOff\n                    </i>\n                    <div class=\"v-input--selection-controls__ripple\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n              <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n                <div class=\"v-input__control\">\n                  <div role=\"button\"\n                       aria-haspopup=\"listbox\"\n                       aria-expanded=\"false\"\n                       aria-owns=\"list-515\"\n                       class=\"v-input__slot\"\n                  >\n                    <div class=\"v-select__slot\">\n                      <label for=\"input-515\"\n                             class=\"v-label theme--light\"\n                             style=\"left: 0px; position: absolute;\"\n                      >\n                        Sort by\n                      </label>\n                      <div class=\"v-select__selections\">\n                        <input id=\"input-515\"\n                               readonly=\"readonly\"\n                               type=\"text\"\n                               aria-readonly=\"false\"\n                               autocomplete=\"off\"\n                        >\n                      </div>\n                      <div class=\"v-input__append-inner\">\n                        <div class=\"v-input__icon v-input__icon--append\">\n                          <i aria-hidden=\"true\"\n                             class=\"v-icon notranslate material-icons theme--light\"\n                          >\n                            $dropdown\n                          </i>\n                        </div>\n                      </div>\n                      <input type=\"hidden\">\n                    </div>\n                    <div class=\"v-menu\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              <div class=\"v-data-table__checkbox v-simple-checkbox v-simple-checkbox--disabled\">\n                <div class=\"v-input--selection-controls__input\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate v-icon--disabled material-icons theme--light\"\n                  >\n                    $checkboxOff\n                  </i>\n                </div>\n              </div>\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Frozen Yogurt\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              159\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              24\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              <div class=\"v-data-table__checkbox v-simple-checkbox\">\n                <div class=\"v-input--selection-controls__input\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $checkboxOff\n                  </i>\n                  <div class=\"v-input--selection-controls__ripple\">\n                  </div>\n                </div>\n              </div>\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Ice cream sandwich\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              237\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              37\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-521\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  10\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-521\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"10\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      1-2 of 2\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should pass kebab-case footer props correctly 1`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-data-table__empty-wrapper\">\n          <td>\n            No data available\n          </td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Foo:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-315\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  10\n                </div>\n                <input aria-label=\"Foo:\"\n                       id=\"input-315\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"10\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      –\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should render 1`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-data-table__empty-wrapper\">\n          <td>\n            No data available\n          </td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-6\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  10\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-6\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"10\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      –\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should render footer.page-text slot content 1`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-data-table__mobile-table-row\">\n        </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-359\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  10\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-359\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"10\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      <div>\n        foo 1 bar 1\n      </div>\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should render footer.prepend slot content 1`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-data-table__mobile-table-row\">\n        </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div>\n      footer.prepend slot content\n    </div>\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-345\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  10\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-345\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"10\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      1-1 of 1\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should render item slot when using group-by function 1`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n          <th>\n            <div class=\"v-data-table-header-mobile__wrapper\">\n              <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n                <div class=\"v-input__control\">\n                  <div role=\"button\"\n                       aria-haspopup=\"listbox\"\n                       aria-expanded=\"false\"\n                       aria-owns=\"list-577\"\n                       class=\"v-input__slot\"\n                  >\n                    <div class=\"v-select__slot\">\n                      <label for=\"input-577\"\n                             class=\"v-label theme--light\"\n                             style=\"left: 0px; position: absolute;\"\n                      >\n                        Sort by\n                      </label>\n                      <div class=\"v-select__selections\">\n                        <input id=\"input-577\"\n                               readonly=\"readonly\"\n                               type=\"text\"\n                               aria-readonly=\"false\"\n                               autocomplete=\"off\"\n                        >\n                      </div>\n                      <div class=\"v-input__append-inner\">\n                        <div class=\"v-input__icon v-input__icon--append\">\n                          <i aria-hidden=\"true\"\n                             class=\"v-icon notranslate material-icons theme--light\"\n                          >\n                            $dropdown\n                          </i>\n                        </div>\n                      </div>\n                      <input type=\"hidden\">\n                    </div>\n                    <div class=\"v-menu\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-row-group__header\">\n          <td class=\"text-start\">\n            <button type=\"button\"\n                    class=\"ma-0 v-btn v-btn--icon v-btn--round theme--light v-size--small\"\n            >\n              <span class=\"v-btn__content\">\n                <i aria-hidden=\"true\"\n                   class=\"v-icon notranslate material-icons theme--light\"\n                >\n                  $minus\n                </i>\n              </span>\n            </button>\n            Dessert (100g serving): Frozen Yogurt\n            <button type=\"button\"\n                    class=\"ma-0 v-btn v-btn--icon v-btn--round theme--light v-size--small\"\n            >\n              <span class=\"v-btn__content\">\n                <i aria-hidden=\"true\"\n                   class=\"v-icon notranslate material-icons theme--light\"\n                >\n                  $close\n                </i>\n              </span>\n            </button>\n          </td>\n        </tr>\n        <div>\n          scoped\n        </div>\n        <tr class=\"v-row-group__header\">\n          <td class=\"text-start\">\n            <button type=\"button\"\n                    class=\"ma-0 v-btn v-btn--icon v-btn--round theme--light v-size--small\"\n            >\n              <span class=\"v-btn__content\">\n                <i aria-hidden=\"true\"\n                   class=\"v-icon notranslate material-icons theme--light\"\n                >\n                  $minus\n                </i>\n              </span>\n            </button>\n            Dessert (100g serving): Ice cream sandwich\n            <button type=\"button\"\n                    class=\"ma-0 v-btn v-btn--icon v-btn--round theme--light v-size--small\"\n            >\n              <span class=\"v-btn__content\">\n                <i aria-hidden=\"true\"\n                   class=\"v-icon notranslate material-icons theme--light\"\n                >\n                  $close\n                </i>\n              </span>\n            </button>\n          </td>\n        </tr>\n        <div>\n          scoped\n        </div>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-589\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  10\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-589\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"10\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      1-2 of 2\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should render loading state 1`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n        </tr>\n      </thead>\n      <thead>\n        <tr class=\"v-data-table__progress\">\n          <th class=\"column\">\n            <div role=\"progressbar\"\n                 aria-valuemin=\"0\"\n                 aria-valuemax=\"100\"\n                 class=\"v-progress-linear v-progress-linear--absolute v-progress-linear--reverse v-progress-linear--visible theme--light\"\n                 style=\"height: 4px;\"\n            >\n              <div class=\"v-progress-linear__background primary\"\n                   style=\"opacity: 0.3; right: 0%; width: 100%;\"\n              >\n              </div>\n              <div class=\"v-progress-linear__buffer\">\n              </div>\n              <div class=\"v-progress-linear__indeterminate v-progress-linear__indeterminate--active\">\n                <div class=\"v-progress-linear__indeterminate long primary\">\n                </div>\n                <div class=\"v-progress-linear__indeterminate short primary\">\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-data-table__empty-wrapper\">\n          <td>\n            Loading items...\n          </td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-238\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  10\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-238\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"10\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      –\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should render loading state 2`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n          <th>\n            <div class=\"v-data-table-header-mobile__wrapper\">\n              <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n                <div class=\"v-input__control\">\n                  <div role=\"button\"\n                       aria-haspopup=\"listbox\"\n                       aria-expanded=\"false\"\n                       aria-owns=\"list-250\"\n                       class=\"v-input__slot\"\n                  >\n                    <div class=\"v-select__slot\">\n                      <label for=\"input-250\"\n                             class=\"v-label theme--light\"\n                             style=\"left: 0px; position: absolute;\"\n                      >\n                        Sort by\n                      </label>\n                      <div class=\"v-select__selections\">\n                        <input id=\"input-250\"\n                               readonly=\"readonly\"\n                               type=\"text\"\n                               aria-readonly=\"false\"\n                               autocomplete=\"off\"\n                        >\n                      </div>\n                      <div class=\"v-input__append-inner\">\n                        <div class=\"v-input__icon v-input__icon--append\">\n                          <i aria-hidden=\"true\"\n                             class=\"v-icon notranslate material-icons theme--light\"\n                          >\n                            $dropdown\n                          </i>\n                        </div>\n                      </div>\n                      <input type=\"hidden\">\n                    </div>\n                    <div class=\"v-menu\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <thead>\n        <tr class=\"v-data-table__progress\">\n          <th class=\"column\">\n            <div class=\"progress\">\n              50%\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-data-table__empty-wrapper\">\n          <td>\n            Loading items...\n          </td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-254\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  10\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-254\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"10\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      –\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should render with body slot 1`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n          <th>\n            <div class=\"v-data-table-header-mobile__wrapper\">\n              <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n                <div class=\"v-input__control\">\n                  <div role=\"button\"\n                       aria-haspopup=\"listbox\"\n                       aria-expanded=\"false\"\n                       aria-owns=\"list-35\"\n                       class=\"v-input__slot\"\n                  >\n                    <div class=\"v-select__slot\">\n                      <label for=\"input-35\"\n                             class=\"v-label theme--light\"\n                             style=\"left: 0px; position: absolute;\"\n                      >\n                        Sort by\n                      </label>\n                      <div class=\"v-select__selections\">\n                        <input id=\"input-35\"\n                               readonly=\"readonly\"\n                               type=\"text\"\n                               aria-readonly=\"false\"\n                               autocomplete=\"off\"\n                        >\n                      </div>\n                      <div class=\"v-input__append-inner\">\n                        <div class=\"v-input__icon v-input__icon--append\">\n                          <i aria-hidden=\"true\"\n                             class=\"v-icon notranslate material-icons theme--light\"\n                          >\n                            $dropdown\n                          </i>\n                        </div>\n                      </div>\n                      <input type=\"hidden\">\n                    </div>\n                    <div class=\"v-menu\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <div>\n        5\n      </div>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-39\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  5\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-39\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"5\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      1-5 of 10\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              class=\"v-btn v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should render with data 1`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n          <th>\n            <div class=\"v-data-table-header-mobile__wrapper\">\n              <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n                <div class=\"v-input__control\">\n                  <div role=\"button\"\n                       aria-haspopup=\"listbox\"\n                       aria-expanded=\"false\"\n                       aria-owns=\"list-18\"\n                       class=\"v-input__slot\"\n                  >\n                    <div class=\"v-select__slot\">\n                      <label for=\"input-18\"\n                             class=\"v-label theme--light\"\n                             style=\"left: 0px; position: absolute;\"\n                      >\n                        Sort by\n                      </label>\n                      <div class=\"v-select__selections\">\n                        <input id=\"input-18\"\n                               readonly=\"readonly\"\n                               type=\"text\"\n                               aria-readonly=\"false\"\n                               autocomplete=\"off\"\n                        >\n                      </div>\n                      <div class=\"v-input__append-inner\">\n                        <div class=\"v-input__icon v-input__icon--append\">\n                          <i aria-hidden=\"true\"\n                             class=\"v-icon notranslate material-icons theme--light\"\n                          >\n                            $dropdown\n                          </i>\n                        </div>\n                      </div>\n                      <input type=\"hidden\">\n                    </div>\n                    <div class=\"v-menu\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Frozen Yogurt\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              159\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              24\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Ice cream sandwich\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              237\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              37\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Eclair\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              262\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              23\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              7%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Cupcake\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              305\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.7\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              67\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              8%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Gingerbread\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              356\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              49\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16%\n            </div>\n          </td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-22\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  5\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-22\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"5\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      1-5 of 10\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              class=\"v-btn v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should render with foot slot 1`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n          <th>\n            <div class=\"v-data-table-header-mobile__wrapper\">\n              <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n                <div class=\"v-input__control\">\n                  <div role=\"button\"\n                       aria-haspopup=\"listbox\"\n                       aria-expanded=\"false\"\n                       aria-owns=\"list-52\"\n                       class=\"v-input__slot\"\n                  >\n                    <div class=\"v-select__slot\">\n                      <label for=\"input-52\"\n                             class=\"v-label theme--light\"\n                             style=\"left: 0px; position: absolute;\"\n                      >\n                        Sort by\n                      </label>\n                      <div class=\"v-select__selections\">\n                        <input id=\"input-52\"\n                               readonly=\"readonly\"\n                               type=\"text\"\n                               aria-readonly=\"false\"\n                               autocomplete=\"off\"\n                        >\n                      </div>\n                      <div class=\"v-input__append-inner\">\n                        <div class=\"v-input__icon v-input__icon--append\">\n                          <i aria-hidden=\"true\"\n                             class=\"v-icon notranslate material-icons theme--light\"\n                          >\n                            $dropdown\n                          </i>\n                        </div>\n                      </div>\n                      <input type=\"hidden\">\n                    </div>\n                    <div class=\"v-menu\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Frozen Yogurt\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              159\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              24\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Ice cream sandwich\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              237\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              37\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Eclair\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              262\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              23\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              7%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Cupcake\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              305\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.7\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              67\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              8%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Gingerbread\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              356\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              49\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16%\n            </div>\n          </td>\n        </tr>\n      </tbody>\n      <tfoot>\n        5\n      </tfoot>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-56\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  5\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-56\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"5\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      1-5 of 10\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              class=\"v-btn v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should render with group scoped slot 1`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n          <th>\n            <div class=\"v-data-table-header-mobile__wrapper\">\n              <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n                <div class=\"v-input__control\">\n                  <div role=\"button\"\n                       aria-haspopup=\"listbox\"\n                       aria-expanded=\"false\"\n                       aria-owns=\"list-219\"\n                       class=\"v-input__slot\"\n                  >\n                    <div class=\"v-select__slot\">\n                      <label for=\"input-219\"\n                             class=\"v-label theme--light\"\n                             style=\"left: 0px; position: absolute;\"\n                      >\n                        Sort by\n                      </label>\n                      <div class=\"v-select__selections\">\n                        <input id=\"input-219\"\n                               readonly=\"readonly\"\n                               type=\"text\"\n                               aria-readonly=\"false\"\n                               autocomplete=\"off\"\n                        >\n                      </div>\n                      <div class=\"v-input__append-inner\">\n                        <div class=\"v-input__icon v-input__icon--append\">\n                          <i aria-hidden=\"true\"\n                             class=\"v-icon notranslate material-icons theme--light\"\n                          >\n                            $dropdown\n                          </i>\n                        </div>\n                      </div>\n                      <input type=\"hidden\">\n                    </div>\n                    <div class=\"v-menu\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <tbody>\n        <div>\n          {\"group\":0,\"options\":{\"page\":1,\"itemsPerPage\":5,\"sortBy\":[],\"sortDesc\":[false],\"groupBy\":[\"protein\"],\"groupDesc\":[false],\"mustSort\":false,\"multiSort\":false},\"isMobile\":true,\"items\":[{\"name\":\"Jelly bean\",\"calories\":375,\"fat\":0,\"carbs\":94,\"protein\":0,\"iron\":\"0%\"},{\"name\":\"Lollipop\",\"calories\":392,\"fat\":0.2,\"carbs\":98,\"protein\":0,\"iron\":\"2%\"}],\"headers\":[{\"text\":\"Dessert (100g serving)\",\"align\":\"left\",\"sortable\":false,\"value\":\"name\"},{\"text\":\"Calories\",\"value\":\"calories\"},{\"text\":\"Fat (g)\",\"value\":\"fat\"},{\"text\":\"Carbs (g)\",\"value\":\"carbs\"},{\"text\":\"Iron (%)\",\"value\":\"iron\"}]}\n        </div>\n        <div>\n          {\"group\":3.9,\"options\":{\"page\":1,\"itemsPerPage\":5,\"sortBy\":[],\"sortDesc\":[false],\"groupBy\":[\"protein\"],\"groupDesc\":[false],\"mustSort\":false,\"multiSort\":false},\"isMobile\":true,\"items\":[{\"name\":\"Gingerbread\",\"calories\":356,\"fat\":16,\"carbs\":49,\"protein\":3.9,\"iron\":\"16%\"}],\"headers\":[{\"text\":\"Dessert (100g serving)\",\"align\":\"left\",\"sortable\":false,\"value\":\"name\"},{\"text\":\"Calories\",\"value\":\"calories\"},{\"text\":\"Fat (g)\",\"value\":\"fat\"},{\"text\":\"Carbs (g)\",\"value\":\"carbs\"},{\"text\":\"Iron (%)\",\"value\":\"iron\"}]}\n        </div>\n        <div>\n          {\"group\":4,\"options\":{\"page\":1,\"itemsPerPage\":5,\"sortBy\":[],\"sortDesc\":[false],\"groupBy\":[\"protein\"],\"groupDesc\":[false],\"mustSort\":false,\"multiSort\":false},\"isMobile\":true,\"items\":[{\"name\":\"Frozen Yogurt\",\"calories\":159,\"fat\":6,\"carbs\":24,\"protein\":4,\"iron\":\"1%\",\"class\":\"test\"}],\"headers\":[{\"text\":\"Dessert (100g serving)\",\"align\":\"left\",\"sortable\":false,\"value\":\"name\"},{\"text\":\"Calories\",\"value\":\"calories\"},{\"text\":\"Fat (g)\",\"value\":\"fat\"},{\"text\":\"Carbs (g)\",\"value\":\"carbs\"},{\"text\":\"Iron (%)\",\"value\":\"iron\"}]}\n        </div>\n        <div>\n          {\"group\":4.3,\"options\":{\"page\":1,\"itemsPerPage\":5,\"sortBy\":[],\"sortDesc\":[false],\"groupBy\":[\"protein\"],\"groupDesc\":[false],\"mustSort\":false,\"multiSort\":false},\"isMobile\":true,\"items\":[{\"name\":\"Ice cream sandwich\",\"calories\":237,\"fat\":9,\"carbs\":37,\"protein\":4.3,\"iron\":\"1%\",\"class\":[\"test\",\"second\"]}],\"headers\":[{\"text\":\"Dessert (100g serving)\",\"align\":\"left\",\"sortable\":false,\"value\":\"name\"},{\"text\":\"Calories\",\"value\":\"calories\"},{\"text\":\"Fat (g)\",\"value\":\"fat\"},{\"text\":\"Carbs (g)\",\"value\":\"carbs\"},{\"text\":\"Iron (%)\",\"value\":\"iron\"}]}\n        </div>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-223\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  5\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-223\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"5\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      1-5 of 10\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              class=\"v-btn v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should render with group.summary scoped slot 1`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n          <th>\n            <div class=\"v-data-table-header-mobile__wrapper\">\n              <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n                <div class=\"v-input__control\">\n                  <div role=\"button\"\n                       aria-haspopup=\"listbox\"\n                       aria-expanded=\"false\"\n                       aria-owns=\"list-131\"\n                       class=\"v-input__slot\"\n                  >\n                    <div class=\"v-select__slot\">\n                      <label for=\"input-131\"\n                             class=\"v-label theme--light\"\n                             style=\"left: 0px; position: absolute;\"\n                      >\n                        Sort by\n                      </label>\n                      <div class=\"v-select__selections\">\n                        <input id=\"input-131\"\n                               readonly=\"readonly\"\n                               type=\"text\"\n                               aria-readonly=\"false\"\n                               autocomplete=\"off\"\n                        >\n                      </div>\n                      <div class=\"v-input__append-inner\">\n                        <div class=\"v-input__icon v-input__icon--append\">\n                          <i aria-hidden=\"true\"\n                             class=\"v-icon notranslate material-icons theme--light\"\n                          >\n                            $dropdown\n                          </i>\n                        </div>\n                      </div>\n                      <input type=\"hidden\">\n                    </div>\n                    <div class=\"v-menu\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-row-group__header\">\n          <td class=\"text-start\">\n            <button type=\"button\"\n                    class=\"ma-0 v-btn v-btn--icon v-btn--round theme--light v-size--small\"\n            >\n              <span class=\"v-btn__content\">\n                <i aria-hidden=\"true\"\n                   class=\"v-icon notranslate material-icons theme--light\"\n                >\n                  $minus\n                </i>\n              </span>\n            </button>\n            Calories: 159\n            <button type=\"button\"\n                    class=\"ma-0 v-btn v-btn--icon v-btn--round theme--light v-size--small\"\n            >\n              <span class=\"v-btn__content\">\n                <i aria-hidden=\"true\"\n                   class=\"v-icon notranslate material-icons theme--light\"\n                >\n                  $close\n                </i>\n              </span>\n            </button>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Frozen Yogurt\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              24\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-row-group__summary\">\n          <div>\n            summary\n          </div>\n        </tr>\n        <tr class=\"v-row-group__header\">\n          <td class=\"text-start\">\n            <button type=\"button\"\n                    class=\"ma-0 v-btn v-btn--icon v-btn--round theme--light v-size--small\"\n            >\n              <span class=\"v-btn__content\">\n                <i aria-hidden=\"true\"\n                   class=\"v-icon notranslate material-icons theme--light\"\n                >\n                  $minus\n                </i>\n              </span>\n            </button>\n            Calories: 237\n            <button type=\"button\"\n                    class=\"ma-0 v-btn v-btn--icon v-btn--round theme--light v-size--small\"\n            >\n              <span class=\"v-btn__content\">\n                <i aria-hidden=\"true\"\n                   class=\"v-icon notranslate material-icons theme--light\"\n                >\n                  $close\n                </i>\n              </span>\n            </button>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Ice cream sandwich\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              37\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-row-group__summary\">\n          <div>\n            summary\n          </div>\n        </tr>\n        <tr class=\"v-row-group__header\">\n          <td class=\"text-start\">\n            <button type=\"button\"\n                    class=\"ma-0 v-btn v-btn--icon v-btn--round theme--light v-size--small\"\n            >\n              <span class=\"v-btn__content\">\n                <i aria-hidden=\"true\"\n                   class=\"v-icon notranslate material-icons theme--light\"\n                >\n                  $minus\n                </i>\n              </span>\n            </button>\n            Calories: 262\n            <button type=\"button\"\n                    class=\"ma-0 v-btn v-btn--icon v-btn--round theme--light v-size--small\"\n            >\n              <span class=\"v-btn__content\">\n                <i aria-hidden=\"true\"\n                   class=\"v-icon notranslate material-icons theme--light\"\n                >\n                  $close\n                </i>\n              </span>\n            </button>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Eclair\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              23\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              7%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-row-group__summary\">\n          <div>\n            summary\n          </div>\n        </tr>\n        <tr class=\"v-row-group__header\">\n          <td class=\"text-start\">\n            <button type=\"button\"\n                    class=\"ma-0 v-btn v-btn--icon v-btn--round theme--light v-size--small\"\n            >\n              <span class=\"v-btn__content\">\n                <i aria-hidden=\"true\"\n                   class=\"v-icon notranslate material-icons theme--light\"\n                >\n                  $minus\n                </i>\n              </span>\n            </button>\n            Calories: 305\n            <button type=\"button\"\n                    class=\"ma-0 v-btn v-btn--icon v-btn--round theme--light v-size--small\"\n            >\n              <span class=\"v-btn__content\">\n                <i aria-hidden=\"true\"\n                   class=\"v-icon notranslate material-icons theme--light\"\n                >\n                  $close\n                </i>\n              </span>\n            </button>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Cupcake\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.7\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              67\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              8%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-row-group__summary\">\n          <div>\n            summary\n          </div>\n        </tr>\n        <tr class=\"v-row-group__header\">\n          <td class=\"text-start\">\n            <button type=\"button\"\n                    class=\"ma-0 v-btn v-btn--icon v-btn--round theme--light v-size--small\"\n            >\n              <span class=\"v-btn__content\">\n                <i aria-hidden=\"true\"\n                   class=\"v-icon notranslate material-icons theme--light\"\n                >\n                  $minus\n                </i>\n              </span>\n            </button>\n            Calories: 356\n            <button type=\"button\"\n                    class=\"ma-0 v-btn v-btn--icon v-btn--round theme--light v-size--small\"\n            >\n              <span class=\"v-btn__content\">\n                <i aria-hidden=\"true\"\n                   class=\"v-icon notranslate material-icons theme--light\"\n                >\n                  $close\n                </i>\n              </span>\n            </button>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Gingerbread\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              49\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-row-group__summary\">\n          <div>\n            summary\n          </div>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-155\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  5\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-155\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"5\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      1-5 of 10\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              class=\"v-btn v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should render with grouped rows 1`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n          <th>\n            <div class=\"v-data-table-header-mobile__wrapper\">\n              <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n                <div class=\"v-input__control\">\n                  <div role=\"button\"\n                       aria-haspopup=\"listbox\"\n                       aria-expanded=\"false\"\n                       aria-owns=\"list-185\"\n                       class=\"v-input__slot\"\n                  >\n                    <div class=\"v-select__slot\">\n                      <label for=\"input-185\"\n                             class=\"v-label theme--light\"\n                             style=\"left: 0px; position: absolute;\"\n                      >\n                        Sort by\n                      </label>\n                      <div class=\"v-select__selections\">\n                        <input id=\"input-185\"\n                               readonly=\"readonly\"\n                               type=\"text\"\n                               aria-readonly=\"false\"\n                               autocomplete=\"off\"\n                        >\n                      </div>\n                      <div class=\"v-input__append-inner\">\n                        <div class=\"v-input__icon v-input__icon--append\">\n                          <i aria-hidden=\"true\"\n                             class=\"v-icon notranslate material-icons theme--light\"\n                          >\n                            $dropdown\n                          </i>\n                        </div>\n                      </div>\n                      <input type=\"hidden\">\n                    </div>\n                    <div class=\"v-menu\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-row-group__header\">\n          <td class=\"text-start\">\n            <button type=\"button\"\n                    class=\"ma-0 v-btn v-btn--icon v-btn--round theme--light v-size--small\"\n            >\n              <span class=\"v-btn__content\">\n                <i aria-hidden=\"true\"\n                   class=\"v-icon notranslate material-icons theme--light\"\n                >\n                  $minus\n                </i>\n              </span>\n            </button>\n            Protein (g): 0\n            <button type=\"button\"\n                    class=\"ma-0 v-btn v-btn--icon v-btn--round theme--light v-size--small\"\n            >\n              <span class=\"v-btn__content\">\n                <i aria-hidden=\"true\"\n                   class=\"v-icon notranslate material-icons theme--light\"\n                >\n                  $close\n                </i>\n              </span>\n            </button>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Jelly bean\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              375\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              94\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Lollipop\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              392\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              0.2\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              98\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              2%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-row-group__header\">\n          <td class=\"text-start\">\n            <button type=\"button\"\n                    class=\"ma-0 v-btn v-btn--icon v-btn--round theme--light v-size--small\"\n            >\n              <span class=\"v-btn__content\">\n                <i aria-hidden=\"true\"\n                   class=\"v-icon notranslate material-icons theme--light\"\n                >\n                  $minus\n                </i>\n              </span>\n            </button>\n            Protein (g): 3.9\n            <button type=\"button\"\n                    class=\"ma-0 v-btn v-btn--icon v-btn--round theme--light v-size--small\"\n            >\n              <span class=\"v-btn__content\">\n                <i aria-hidden=\"true\"\n                   class=\"v-icon notranslate material-icons theme--light\"\n                >\n                  $close\n                </i>\n              </span>\n            </button>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Gingerbread\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              356\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              49\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-row-group__header\">\n          <td class=\"text-start\">\n            <button type=\"button\"\n                    class=\"ma-0 v-btn v-btn--icon v-btn--round theme--light v-size--small\"\n            >\n              <span class=\"v-btn__content\">\n                <i aria-hidden=\"true\"\n                   class=\"v-icon notranslate material-icons theme--light\"\n                >\n                  $minus\n                </i>\n              </span>\n            </button>\n            Protein (g): 4\n            <button type=\"button\"\n                    class=\"ma-0 v-btn v-btn--icon v-btn--round theme--light v-size--small\"\n            >\n              <span class=\"v-btn__content\">\n                <i aria-hidden=\"true\"\n                   class=\"v-icon notranslate material-icons theme--light\"\n                >\n                  $close\n                </i>\n              </span>\n            </button>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Frozen Yogurt\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              159\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              24\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-row-group__header\">\n          <td class=\"text-start\">\n            <button type=\"button\"\n                    class=\"ma-0 v-btn v-btn--icon v-btn--round theme--light v-size--small\"\n            >\n              <span class=\"v-btn__content\">\n                <i aria-hidden=\"true\"\n                   class=\"v-icon notranslate material-icons theme--light\"\n                >\n                  $minus\n                </i>\n              </span>\n            </button>\n            Protein (g): 4.3\n            <button type=\"button\"\n                    class=\"ma-0 v-btn v-btn--icon v-btn--round theme--light v-size--small\"\n            >\n              <span class=\"v-btn__content\">\n                <i aria-hidden=\"true\"\n                   class=\"v-icon notranslate material-icons theme--light\"\n                >\n                  $close\n                </i>\n              </span>\n            </button>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Ice cream sandwich\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              237\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              37\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-205\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  5\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-205\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"5\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      1-5 of 10\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              class=\"v-btn v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should render with item scoped slot 1`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n          <th>\n            <div class=\"v-data-table-header-mobile__wrapper\">\n              <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n                <div class=\"v-input__control\">\n                  <div role=\"button\"\n                       aria-haspopup=\"listbox\"\n                       aria-expanded=\"false\"\n                       aria-owns=\"list-169\"\n                       class=\"v-input__slot\"\n                  >\n                    <div class=\"v-select__slot\">\n                      <label for=\"input-169\"\n                             class=\"v-label theme--light\"\n                             style=\"left: 0px; position: absolute;\"\n                      >\n                        Sort by\n                      </label>\n                      <div class=\"v-select__selections\">\n                        <input id=\"input-169\"\n                               readonly=\"readonly\"\n                               type=\"text\"\n                               aria-readonly=\"false\"\n                               autocomplete=\"off\"\n                        >\n                      </div>\n                      <div class=\"v-input__append-inner\">\n                        <div class=\"v-input__icon v-input__icon--append\">\n                          <i aria-hidden=\"true\"\n                             class=\"v-icon notranslate material-icons theme--light\"\n                          >\n                            $dropdown\n                          </i>\n                        </div>\n                      </div>\n                      <input type=\"hidden\">\n                    </div>\n                    <div class=\"v-menu\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <tbody>\n        <div>\n          {\"item\":{\"name\":\"Frozen Yogurt\",\"calories\":159,\"fat\":6,\"carbs\":24,\"protein\":4,\"iron\":\"1%\",\"class\":\"test\"},\"index\":0,\"isSelected\":false,\"isExpanded\":false,\"isMobile\":true,\"headers\":[{\"text\":\"Dessert (100g serving)\",\"align\":\"left\",\"sortable\":false,\"value\":\"name\"},{\"text\":\"Calories\",\"value\":\"calories\"},{\"text\":\"Fat (g)\",\"value\":\"fat\"},{\"text\":\"Carbs (g)\",\"value\":\"carbs\"},{\"text\":\"Protein (g)\",\"value\":\"protein\"},{\"text\":\"Iron (%)\",\"value\":\"iron\"}]}\n        </div>\n        <div>\n          {\"item\":{\"name\":\"Ice cream sandwich\",\"calories\":237,\"fat\":9,\"carbs\":37,\"protein\":4.3,\"iron\":\"1%\",\"class\":[\"test\",\"second\"]},\"index\":1,\"isSelected\":false,\"isExpanded\":false,\"isMobile\":true,\"headers\":[{\"text\":\"Dessert (100g serving)\",\"align\":\"left\",\"sortable\":false,\"value\":\"name\"},{\"text\":\"Calories\",\"value\":\"calories\"},{\"text\":\"Fat (g)\",\"value\":\"fat\"},{\"text\":\"Carbs (g)\",\"value\":\"carbs\"},{\"text\":\"Protein (g)\",\"value\":\"protein\"},{\"text\":\"Iron (%)\",\"value\":\"iron\"}]}\n        </div>\n        <div>\n          {\"item\":{\"name\":\"Eclair\",\"calories\":262,\"fat\":16,\"carbs\":23,\"protein\":6,\"iron\":\"7%\",\"class\":{\"test\":true,\"second\":false}},\"index\":2,\"isSelected\":false,\"isExpanded\":false,\"isMobile\":true,\"headers\":[{\"text\":\"Dessert (100g serving)\",\"align\":\"left\",\"sortable\":false,\"value\":\"name\"},{\"text\":\"Calories\",\"value\":\"calories\"},{\"text\":\"Fat (g)\",\"value\":\"fat\"},{\"text\":\"Carbs (g)\",\"value\":\"carbs\"},{\"text\":\"Protein (g)\",\"value\":\"protein\"},{\"text\":\"Iron (%)\",\"value\":\"iron\"}]}\n        </div>\n        <div>\n          {\"item\":{\"name\":\"Cupcake\",\"calories\":305,\"fat\":3.7,\"carbs\":67,\"protein\":4.3,\"iron\":\"8%\"},\"index\":3,\"isSelected\":false,\"isExpanded\":false,\"isMobile\":true,\"headers\":[{\"text\":\"Dessert (100g serving)\",\"align\":\"left\",\"sortable\":false,\"value\":\"name\"},{\"text\":\"Calories\",\"value\":\"calories\"},{\"text\":\"Fat (g)\",\"value\":\"fat\"},{\"text\":\"Carbs (g)\",\"value\":\"carbs\"},{\"text\":\"Protein (g)\",\"value\":\"protein\"},{\"text\":\"Iron (%)\",\"value\":\"iron\"}]}\n        </div>\n        <div>\n          {\"item\":{\"name\":\"Gingerbread\",\"calories\":356,\"fat\":16,\"carbs\":49,\"protein\":3.9,\"iron\":\"16%\"},\"index\":4,\"isSelected\":false,\"isExpanded\":false,\"isMobile\":true,\"headers\":[{\"text\":\"Dessert (100g serving)\",\"align\":\"left\",\"sortable\":false,\"value\":\"name\"},{\"text\":\"Calories\",\"value\":\"calories\"},{\"text\":\"Fat (g)\",\"value\":\"fat\"},{\"text\":\"Carbs (g)\",\"value\":\"carbs\"},{\"text\":\"Protein (g)\",\"value\":\"protein\"},{\"text\":\"Iron (%)\",\"value\":\"iron\"}]}\n        </div>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-173\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  5\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-173\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"5\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      1-5 of 10\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              class=\"v-btn v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should render with item.expanded scoped slot 1`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n          <th>\n            <div class=\"v-data-table-header-mobile__wrapper\">\n              <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n                <div class=\"v-input__control\">\n                  <div role=\"button\"\n                       aria-haspopup=\"listbox\"\n                       aria-expanded=\"false\"\n                       aria-owns=\"list-113\"\n                       class=\"v-input__slot\"\n                  >\n                    <div class=\"v-select__slot\">\n                      <label for=\"input-113\"\n                             class=\"v-label theme--light\"\n                             style=\"left: 0px; position: absolute;\"\n                      >\n                        Sort by\n                      </label>\n                      <div class=\"v-select__selections\">\n                        <input id=\"input-113\"\n                               readonly=\"readonly\"\n                               type=\"text\"\n                               aria-readonly=\"false\"\n                               autocomplete=\"off\"\n                        >\n                      </div>\n                      <div class=\"v-input__append-inner\">\n                        <div class=\"v-input__icon v-input__icon--append\">\n                          <i aria-hidden=\"true\"\n                             class=\"v-icon notranslate material-icons theme--light\"\n                          >\n                            $dropdown\n                          </i>\n                        </div>\n                      </div>\n                      <input type=\"hidden\">\n                    </div>\n                    <div class=\"v-menu\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-data-table__mobile-table-row v-data-table__expanded v-data-table__expanded__row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Frozen Yogurt\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              159\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              24\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__expanded v-data-table__expanded__content\">\n          <div>\n            expanded\n          </div>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row v-data-table__expanded v-data-table__expanded__row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Ice cream sandwich\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              237\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              37\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__expanded v-data-table__expanded__content\">\n          <div>\n            expanded\n          </div>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row v-data-table__expanded v-data-table__expanded__row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Eclair\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              262\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              23\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              7%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__expanded v-data-table__expanded__content\">\n          <div>\n            expanded\n          </div>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row v-data-table__expanded v-data-table__expanded__row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Cupcake\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              305\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.7\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              67\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              8%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__expanded v-data-table__expanded__content\">\n          <div>\n            expanded\n          </div>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row v-data-table__expanded v-data-table__expanded__row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Gingerbread\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              356\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              49\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__expanded v-data-table__expanded__content\">\n          <div>\n            expanded\n          </div>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-117\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  5\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-117\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"5\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      1-5 of 10\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              class=\"v-btn v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should render with showExpand 1`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n          <th>\n            <div class=\"v-data-table-header-mobile__wrapper\">\n              <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n                <div class=\"v-input__control\">\n                  <div role=\"button\"\n                       aria-haspopup=\"listbox\"\n                       aria-expanded=\"false\"\n                       aria-owns=\"list-68\"\n                       class=\"v-input__slot\"\n                  >\n                    <div class=\"v-select__slot\">\n                      <label for=\"input-68\"\n                             class=\"v-label theme--light\"\n                             style=\"left: 0px; position: absolute;\"\n                      >\n                        Sort by\n                      </label>\n                      <div class=\"v-select__selections\">\n                        <input id=\"input-68\"\n                               readonly=\"readonly\"\n                               type=\"text\"\n                               aria-readonly=\"false\"\n                               autocomplete=\"off\"\n                        >\n                      </div>\n                      <div class=\"v-input__append-inner\">\n                        <div class=\"v-input__icon v-input__icon--append\">\n                          <i aria-hidden=\"true\"\n                             class=\"v-icon notranslate material-icons theme--light\"\n                          >\n                            $dropdown\n                          </i>\n                        </div>\n                      </div>\n                      <input type=\"hidden\">\n                    </div>\n                    <div class=\"v-menu\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              <button type=\"button\"\n                      class=\"v-icon notranslate v-data-table__expand-icon v-icon--link material-icons theme--light\"\n              >\n                $expand\n              </button>\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Frozen Yogurt\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              159\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              24\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              <button type=\"button\"\n                      class=\"v-icon notranslate v-data-table__expand-icon v-icon--link material-icons theme--light\"\n              >\n                $expand\n              </button>\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Ice cream sandwich\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              237\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              37\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              <button type=\"button\"\n                      class=\"v-icon notranslate v-data-table__expand-icon v-icon--link material-icons theme--light\"\n              >\n                $expand\n              </button>\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Eclair\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              262\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              23\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              7%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              <button type=\"button\"\n                      class=\"v-icon notranslate v-data-table__expand-icon v-icon--link material-icons theme--light\"\n              >\n                $expand\n              </button>\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Cupcake\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              305\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.7\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              67\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              8%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              <button type=\"button\"\n                      class=\"v-icon notranslate v-data-table__expand-icon v-icon--link material-icons theme--light\"\n              >\n                $expand\n              </button>\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Gingerbread\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              356\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              49\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16%\n            </div>\n          </td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-77\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  5\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-77\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"5\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      1-5 of 10\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              class=\"v-btn v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should render with showExpand 2`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n          <th>\n            <div class=\"v-data-table-header-mobile__wrapper\">\n              <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n                <div class=\"v-input__control\">\n                  <div role=\"button\"\n                       aria-haspopup=\"listbox\"\n                       aria-expanded=\"false\"\n                       aria-owns=\"list-68\"\n                       class=\"v-input__slot\"\n                  >\n                    <div class=\"v-select__slot\">\n                      <label for=\"input-68\"\n                             class=\"v-label theme--light\"\n                             style=\"left: 0px; position: absolute;\"\n                      >\n                        Sort by\n                      </label>\n                      <div class=\"v-select__selections\">\n                        <input id=\"input-68\"\n                               readonly=\"readonly\"\n                               type=\"text\"\n                               aria-readonly=\"false\"\n                               autocomplete=\"off\"\n                        >\n                      </div>\n                      <div class=\"v-input__append-inner\">\n                        <div class=\"v-input__icon v-input__icon--append\">\n                          <i aria-hidden=\"true\"\n                             class=\"v-icon notranslate material-icons theme--light\"\n                          >\n                            $dropdown\n                          </i>\n                        </div>\n                      </div>\n                      <input type=\"hidden\">\n                    </div>\n                    <div class=\"v-menu\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              <button type=\"button\"\n                      class=\"v-icon notranslate v-data-table__expand-icon v-icon--link material-icons theme--light v-data-table__expand-icon--active\"\n              >\n                $expand\n              </button>\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Frozen Yogurt\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              159\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              24\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              <button type=\"button\"\n                      class=\"v-icon notranslate v-data-table__expand-icon v-icon--link material-icons theme--light\"\n              >\n                $expand\n              </button>\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Ice cream sandwich\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              237\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              37\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              <button type=\"button\"\n                      class=\"v-icon notranslate v-data-table__expand-icon v-icon--link material-icons theme--light\"\n              >\n                $expand\n              </button>\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Eclair\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              262\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              23\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              7%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              <button type=\"button\"\n                      class=\"v-icon notranslate v-data-table__expand-icon v-icon--link material-icons theme--light\"\n              >\n                $expand\n              </button>\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Cupcake\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              305\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.7\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              67\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              8%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              <button type=\"button\"\n                      class=\"v-icon notranslate v-data-table__expand-icon v-icon--link material-icons theme--light\"\n              >\n                $expand\n              </button>\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Gingerbread\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              356\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              49\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16%\n            </div>\n          </td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-77\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  5\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-77\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"5\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      1-5 of 10\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              class=\"v-btn v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should render with showSelect 1`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n          <th>\n            <div class=\"v-data-table-header-mobile__wrapper\">\n              <div width=\"1px\"\n                   class=\"v-data-table-header-mobile__select\"\n              >\n                <div class=\"v-data-table__checkbox v-simple-checkbox\">\n                  <div class=\"v-input--selection-controls__input\">\n                    <i aria-hidden=\"true\"\n                       class=\"v-icon notranslate material-icons theme--light\"\n                    >\n                      $checkboxOff\n                    </i>\n                    <div class=\"v-input--selection-controls__ripple\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n              <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n                <div class=\"v-input__control\">\n                  <div role=\"button\"\n                       aria-haspopup=\"listbox\"\n                       aria-expanded=\"false\"\n                       aria-owns=\"list-90\"\n                       class=\"v-input__slot\"\n                  >\n                    <div class=\"v-select__slot\">\n                      <label for=\"input-90\"\n                             class=\"v-label theme--light\"\n                             style=\"left: 0px; position: absolute;\"\n                      >\n                        Sort by\n                      </label>\n                      <div class=\"v-select__selections\">\n                        <input id=\"input-90\"\n                               readonly=\"readonly\"\n                               type=\"text\"\n                               aria-readonly=\"false\"\n                               autocomplete=\"off\"\n                        >\n                      </div>\n                      <div class=\"v-input__append-inner\">\n                        <div class=\"v-input__icon v-input__icon--append\">\n                          <i aria-hidden=\"true\"\n                             class=\"v-icon notranslate material-icons theme--light\"\n                          >\n                            $dropdown\n                          </i>\n                        </div>\n                      </div>\n                      <input type=\"hidden\">\n                    </div>\n                    <div class=\"v-menu\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              <div class=\"v-data-table__checkbox v-simple-checkbox\">\n                <div class=\"v-input--selection-controls__input\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $checkboxOff\n                  </i>\n                  <div class=\"v-input--selection-controls__ripple\">\n                  </div>\n                </div>\n              </div>\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Frozen Yogurt\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              159\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              24\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              <div class=\"v-data-table__checkbox v-simple-checkbox\">\n                <div class=\"v-input--selection-controls__input\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $checkboxOff\n                  </i>\n                  <div class=\"v-input--selection-controls__ripple\">\n                  </div>\n                </div>\n              </div>\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Ice cream sandwich\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              237\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              37\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              <div class=\"v-data-table__checkbox v-simple-checkbox\">\n                <div class=\"v-input--selection-controls__input\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $checkboxOff\n                  </i>\n                  <div class=\"v-input--selection-controls__ripple\">\n                  </div>\n                </div>\n              </div>\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Eclair\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              262\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              23\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              7%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              <div class=\"v-data-table__checkbox v-simple-checkbox\">\n                <div class=\"v-input--selection-controls__input\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $checkboxOff\n                  </i>\n                  <div class=\"v-input--selection-controls__ripple\">\n                  </div>\n                </div>\n              </div>\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Cupcake\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              305\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.7\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              67\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              8%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              <div class=\"v-data-table__checkbox v-simple-checkbox\">\n                <div class=\"v-input--selection-controls__input\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $checkboxOff\n                  </i>\n                  <div class=\"v-input--selection-controls__ripple\">\n                  </div>\n                </div>\n              </div>\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Gingerbread\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              356\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              49\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16%\n            </div>\n          </td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-99\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  5\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-99\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"5\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      1-5 of 10\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              class=\"v-btn v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should respect mustSort property on options 1`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n        <col class>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n          <th>\n            <div class=\"v-data-table-header-mobile__wrapper\">\n              <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n                <div class=\"v-input__control\">\n                  <div role=\"button\"\n                       aria-haspopup=\"listbox\"\n                       aria-expanded=\"false\"\n                       aria-owns=\"list-731\"\n                       class=\"v-input__slot\"\n                  >\n                    <div class=\"v-select__slot\">\n                      <label for=\"input-731\"\n                             class=\"v-label theme--light\"\n                             style=\"left: 0px; position: absolute;\"\n                      >\n                        Sort by\n                      </label>\n                      <div class=\"v-select__selections\">\n                        <input id=\"input-731\"\n                               readonly=\"readonly\"\n                               type=\"text\"\n                               aria-readonly=\"false\"\n                               autocomplete=\"off\"\n                        >\n                      </div>\n                      <div class=\"v-input__append-inner\">\n                        <div class=\"v-input__icon v-input__icon--append\">\n                          <i aria-hidden=\"true\"\n                             class=\"v-icon notranslate material-icons theme--light\"\n                          >\n                            $dropdown\n                          </i>\n                        </div>\n                      </div>\n                      <input type=\"hidden\">\n                    </div>\n                    <div class=\"v-menu\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Frozen Yogurt\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Ice cream sandwich\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Eclair\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Cupcake\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Gingerbread\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Jelly bean\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Lollipop\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Honeycomb\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Donut\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              KitKat\n            </div>\n          </td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-735\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  10\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-735\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"10\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      1-10 of 10\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should search group-by column 1`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n        <col class>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n          <th>\n            <div class=\"v-data-table-header-mobile__wrapper\">\n              <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n                <div class=\"v-input__control\">\n                  <div role=\"button\"\n                       aria-haspopup=\"listbox\"\n                       aria-expanded=\"false\"\n                       aria-owns=\"list-552\"\n                       class=\"v-input__slot\"\n                  >\n                    <div class=\"v-select__slot\">\n                      <label for=\"input-552\"\n                             class=\"v-label theme--light\"\n                             style=\"left: 0px; position: absolute;\"\n                      >\n                        Sort by\n                      </label>\n                      <div class=\"v-select__selections\">\n                        <input id=\"input-552\"\n                               readonly=\"readonly\"\n                               type=\"text\"\n                               aria-readonly=\"false\"\n                               autocomplete=\"off\"\n                        >\n                      </div>\n                      <div class=\"v-input__append-inner\">\n                        <div class=\"v-input__icon v-input__icon--append\">\n                          <i aria-hidden=\"true\"\n                             class=\"v-icon notranslate material-icons theme--light\"\n                          >\n                            $dropdown\n                          </i>\n                        </div>\n                      </div>\n                      <input type=\"hidden\">\n                    </div>\n                    <div class=\"v-menu\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-row-group__header\">\n          <td class=\"text-start\">\n            <button type=\"button\"\n                    class=\"ma-0 v-btn v-btn--icon v-btn--round theme--light v-size--small\"\n            >\n              <span class=\"v-btn__content\">\n                <i aria-hidden=\"true\"\n                   class=\"v-icon notranslate material-icons theme--light\"\n                >\n                  $minus\n                </i>\n              </span>\n            </button>\n            Name: Assistance\n            <button type=\"button\"\n                    class=\"ma-0 v-btn v-btn--icon v-btn--round theme--light v-size--small\"\n            >\n              <span class=\"v-btn__content\">\n                <i aria-hidden=\"true\"\n                   class=\"v-icon notranslate material-icons theme--light\"\n                >\n                  $close\n                </i>\n              </span>\n            </button>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              ID\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-row-group__header\">\n          <td class=\"text-start\">\n            <button type=\"button\"\n                    class=\"ma-0 v-btn v-btn--icon v-btn--round theme--light v-size--small\"\n            >\n              <span class=\"v-btn__content\">\n                <i aria-hidden=\"true\"\n                   class=\"v-icon notranslate material-icons theme--light\"\n                >\n                  $minus\n                </i>\n              </span>\n            </button>\n            Name: Candidat\n            <button type=\"button\"\n                    class=\"ma-0 v-btn v-btn--icon v-btn--round theme--light v-size--small\"\n            >\n              <span class=\"v-btn__content\">\n                <i aria-hidden=\"true\"\n                   class=\"v-icon notranslate material-icons theme--light\"\n                >\n                  $close\n                </i>\n              </span>\n            </button>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              ID\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              2\n            </div>\n          </td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-564\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  10\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-564\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"10\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      1-2 of 2\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should search group-by column 2`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n        <col class>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n          <th>\n            <div class=\"v-data-table-header-mobile__wrapper\">\n              <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n                <div class=\"v-input__control\">\n                  <div role=\"button\"\n                       aria-haspopup=\"listbox\"\n                       aria-expanded=\"false\"\n                       aria-owns=\"list-552\"\n                       class=\"v-input__slot\"\n                  >\n                    <div class=\"v-select__slot\">\n                      <label for=\"input-552\"\n                             class=\"v-label theme--light\"\n                             style=\"left: 0px; position: absolute;\"\n                      >\n                        Sort by\n                      </label>\n                      <div class=\"v-select__selections\">\n                        <input id=\"input-552\"\n                               readonly=\"readonly\"\n                               type=\"text\"\n                               aria-readonly=\"false\"\n                               autocomplete=\"off\"\n                        >\n                      </div>\n                      <div class=\"v-input__append-inner\">\n                        <div class=\"v-input__icon v-input__icon--append\">\n                          <i aria-hidden=\"true\"\n                             class=\"v-icon notranslate material-icons theme--light\"\n                          >\n                            $dropdown\n                          </i>\n                        </div>\n                      </div>\n                      <input type=\"hidden\">\n                    </div>\n                    <div class=\"v-menu\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-row-group__header\">\n          <td class=\"text-start\">\n            <button type=\"button\"\n                    class=\"ma-0 v-btn v-btn--icon v-btn--round theme--light v-size--small\"\n            >\n              <span class=\"v-btn__content\">\n                <i aria-hidden=\"true\"\n                   class=\"v-icon notranslate material-icons theme--light\"\n                >\n                  $minus\n                </i>\n              </span>\n            </button>\n            Name: Candidat\n            <button type=\"button\"\n                    class=\"ma-0 v-btn v-btn--icon v-btn--round theme--light v-size--small\"\n            >\n              <span class=\"v-btn__content\">\n                <i aria-hidden=\"true\"\n                   class=\"v-icon notranslate material-icons theme--light\"\n                >\n                  $close\n                </i>\n              </span>\n            </button>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              ID\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              2\n            </div>\n          </td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-564\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  10\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-564\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"10\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      1-1 of 1\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should show correct aria-labels when sorting 1`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n          <th>\n            <div class=\"v-data-table-header-mobile__wrapper\">\n              <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n                <div class=\"v-input__control\">\n                  <div role=\"button\"\n                       aria-haspopup=\"listbox\"\n                       aria-expanded=\"false\"\n                       aria-owns=\"list-633\"\n                       class=\"v-input__slot\"\n                  >\n                    <div class=\"v-select__slot\">\n                      <label for=\"input-633\"\n                             class=\"v-label v-label--active theme--light\"\n                             style=\"left: 0px; position: absolute;\"\n                      >\n                        Sort by\n                      </label>\n                      <div class=\"v-select__selections\">\n                        <span class=\"sortable v-chip v-chip--clickable v-chip--no-color theme--light v-size--default\">\n                          <span class=\"v-chip__content\">\n                            Calories\n                            <div class=\"v-chip__close sortable active desc\">\n                              <i aria-hidden=\"true\"\n                                 class=\"v-icon notranslate v-data-table-header__icon material-icons theme--light\"\n                                 style=\"font-size: 18px;\"\n                              >\n                                $sort\n                              </i>\n                            </div>\n                          </span>\n                        </span>\n                        <input id=\"input-633\"\n                               readonly=\"readonly\"\n                               type=\"text\"\n                               aria-readonly=\"false\"\n                               autocomplete=\"off\"\n                        >\n                      </div>\n                      <div class=\"v-input__append-inner\">\n                        <div class=\"v-input__icon v-input__icon--append\">\n                          <i aria-hidden=\"true\"\n                             class=\"v-icon notranslate material-icons theme--light\"\n                          >\n                            $dropdown\n                          </i>\n                        </div>\n                      </div>\n                      <input type=\"hidden\"\n                             value=\"calories\"\n                      >\n                    </div>\n                    <div class=\"v-menu\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Gingerbread\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              356\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              49\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Cupcake\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              305\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.7\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              67\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              8%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Eclair\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              262\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              23\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              7%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Ice cream sandwich\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              237\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              37\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Frozen Yogurt\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              159\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              24\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-639\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  10\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-639\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"10\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      1-5 of 5\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDataTable.ts should show correct aria-labels when sorting 2`] = `\n<div class=\"v-data-table v-data-table--has-bottom theme--light v-data-table--mobile\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <colgroup>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n        <col class>\n      </colgroup>\n      <thead class=\"v-data-table-header v-data-table-header-mobile\">\n        <tr>\n          <th>\n            <div class=\"v-data-table-header-mobile__wrapper\">\n              <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n                <div class=\"v-input__control\">\n                  <div role=\"button\"\n                       aria-haspopup=\"listbox\"\n                       aria-expanded=\"false\"\n                       aria-owns=\"list-633\"\n                       class=\"v-input__slot\"\n                  >\n                    <div class=\"v-select__slot\">\n                      <label for=\"input-633\"\n                             class=\"v-label v-label--active theme--light\"\n                             style=\"left: 0px; position: absolute;\"\n                      >\n                        Sort by\n                      </label>\n                      <div class=\"v-select__selections\">\n                        <span class=\"sortable v-chip v-chip--clickable v-chip--no-color theme--light v-size--default\">\n                          <span class=\"v-chip__content\">\n                            Calories\n                            <div class=\"v-chip__close sortable active desc\">\n                              <i aria-hidden=\"true\"\n                                 class=\"v-icon notranslate v-data-table-header__icon material-icons theme--light\"\n                                 style=\"font-size: 18px;\"\n                              >\n                                $sort\n                              </i>\n                            </div>\n                          </span>\n                        </span>\n                        <input id=\"input-633\"\n                               readonly=\"readonly\"\n                               type=\"text\"\n                               aria-readonly=\"false\"\n                               autocomplete=\"off\"\n                        >\n                      </div>\n                      <div class=\"v-input__append-inner\">\n                        <div class=\"v-input__icon v-input__icon--append\">\n                          <i aria-hidden=\"true\"\n                             class=\"v-icon notranslate material-icons theme--light\"\n                          >\n                            $dropdown\n                          </i>\n                        </div>\n                      </div>\n                      <input type=\"hidden\"\n                             value=\"calories\"\n                      >\n                    </div>\n                    <div class=\"v-menu\">\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Gingerbread\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              356\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              49\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Cupcake\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              305\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              3.7\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              67\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              8%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Eclair\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              262\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              16\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              23\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              7%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Ice cream sandwich\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              237\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              9\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              37\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4.3\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n        <tr class=\"v-data-table__mobile-table-row\">\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Dessert (100g serving)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              Frozen Yogurt\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Calories\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              159\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Fat (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              6\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Carbs (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              24\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Protein (g)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              4\n            </div>\n          </td>\n          <td class=\"v-data-table__mobile-row\">\n            <div class=\"v-data-table__mobile-row__header\">\n              Iron (%)\n            </div>\n            <div class=\"v-data-table__mobile-row__cell\">\n              1%\n            </div>\n          </td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class=\"v-data-footer\">\n    <div class=\"v-data-footer__select\">\n      Rows per page:\n      <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n        <div class=\"v-input__control\">\n          <div role=\"button\"\n               aria-haspopup=\"listbox\"\n               aria-expanded=\"false\"\n               aria-owns=\"list-639\"\n               class=\"v-input__slot\"\n          >\n            <div class=\"v-select__slot\">\n              <div class=\"v-select__selections\">\n                <div class=\"v-select__selection v-select__selection--comma\">\n                  10\n                </div>\n                <input aria-label=\"Rows per page:\"\n                       id=\"input-639\"\n                       readonly=\"readonly\"\n                       type=\"text\"\n                       aria-readonly=\"false\"\n                       autocomplete=\"off\"\n                >\n              </div>\n              <div class=\"v-input__append-inner\">\n                <div class=\"v-input__icon v-input__icon--append\">\n                  <i aria-hidden=\"true\"\n                     class=\"v-icon notranslate material-icons theme--light\"\n                  >\n                    $dropdown\n                  </i>\n                </div>\n              </div>\n              <input type=\"hidden\"\n                     value=\"10\"\n              >\n            </div>\n            <div class=\"v-menu\">\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"v-data-footer__pagination\">\n      1-5 of 5\n    </div>\n    <div class=\"v-data-footer__icons-before\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Previous page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $prev\n          </i>\n        </span>\n      </button>\n    </div>\n    <div class=\"v-data-footer__icons-after\">\n      <button type=\"button\"\n              disabled=\"disabled\"\n              class=\"v-btn v-btn--disabled v-btn--icon v-btn--round v-btn--text theme--light v-size--default\"\n              aria-label=\"Next page\"\n      >\n        <span class=\"v-btn__content\">\n          <i aria-hidden=\"true\"\n             class=\"v-icon notranslate material-icons theme--light\"\n          >\n            $next\n          </i>\n        </span>\n      </button>\n    </div>\n  </div>\n</div>\n`;\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/__tests__/__snapshots__/VDataTableHeader.spec.ts.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`VDataTableHeader.ts desktop should render 1`] = `\n<thead class=\"v-data-table-header\">\n  <tr>\n    <th role=\"columnheader\"\n        scope=\"col\"\n        aria-label=\"Dessert (100g serving)\"\n        class=\"text-left\"\n    >\n      <span>\n        Dessert (100g serving)\n      </span>\n    </th>\n    <th role=\"columnheader\"\n        scope=\"col\"\n        aria-label=\"Calories: Not sorted. Activate to sort ascending.\"\n        aria-sort=\"none\"\n        class=\"text-start sortable\"\n        style=\"width: 50px; min-width: 50px;\"\n    >\n      <span>\n        Calories\n      </span>\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate v-data-table-header__icon material-icons theme--light\"\n         style=\"font-size: 18px;\"\n      >\n        $sort\n      </i>\n    </th>\n    <th role=\"columnheader\"\n        scope=\"col\"\n        aria-label=\"Fat (g): Not sorted. Activate to sort ascending.\"\n        aria-sort=\"none\"\n        class=\"text-start sortable\"\n        style=\"width: 50em; min-width: 50em;\"\n    >\n      <span>\n        Fat (g)\n      </span>\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate v-data-table-header__icon material-icons theme--light\"\n         style=\"font-size: 18px;\"\n      >\n        $sort\n      </i>\n    </th>\n    <th role=\"columnheader\"\n        scope=\"col\"\n        aria-label=\"Carbs (g): Not sorted. Activate to sort ascending.\"\n        aria-sort=\"none\"\n        class=\"text-start sortable\"\n    >\n      <span>\n        Carbs (g)\n      </span>\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate v-data-table-header__icon material-icons theme--light\"\n         style=\"font-size: 18px;\"\n      >\n        $sort\n      </i>\n    </th>\n    <th role=\"columnheader\"\n        scope=\"col\"\n        aria-label=\"Protein (g): Not sorted. Activate to sort ascending.\"\n        aria-sort=\"none\"\n        class=\"text-start sortable\"\n    >\n      <span>\n        Protein (g)\n      </span>\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate v-data-table-header__icon material-icons theme--light\"\n         style=\"font-size: 18px;\"\n      >\n        $sort\n      </i>\n    </th>\n    <th role=\"columnheader\"\n        scope=\"col\"\n        aria-label=\"Iron (%): Not sorted. Activate to sort ascending.\"\n        aria-sort=\"none\"\n        class=\"text-start sortable\"\n    >\n      <span>\n        Iron (%)\n      </span>\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate v-data-table-header__icon material-icons theme--light\"\n         style=\"font-size: 18px;\"\n      >\n        $sort\n      </i>\n    </th>\n  </tr>\n</thead>\n`;\n\nexports[`VDataTableHeader.ts desktop should work with multiSort 1`] = `\n<thead class=\"v-data-table-header\">\n  <tr>\n    <th role=\"columnheader\"\n        scope=\"col\"\n        aria-label=\"Dessert (100g serving)\"\n        class=\"text-left\"\n    >\n      <span>\n        Dessert (100g serving)\n      </span>\n    </th>\n    <th role=\"columnheader\"\n        scope=\"col\"\n        aria-label=\"Calories: Not sorted. Activate to sort ascending.\"\n        aria-sort=\"none\"\n        class=\"text-start sortable\"\n        style=\"width: 50px; min-width: 50px;\"\n    >\n      <span>\n        Calories\n      </span>\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate v-data-table-header__icon material-icons theme--light\"\n         style=\"font-size: 18px;\"\n      >\n        $sort\n      </i>\n    </th>\n    <th role=\"columnheader\"\n        scope=\"col\"\n        aria-label=\"Fat (g): Not sorted. Activate to sort ascending.\"\n        aria-sort=\"none\"\n        class=\"text-start sortable\"\n        style=\"width: 50em; min-width: 50em;\"\n    >\n      <span>\n        Fat (g)\n      </span>\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate v-data-table-header__icon material-icons theme--light\"\n         style=\"font-size: 18px;\"\n      >\n        $sort\n      </i>\n    </th>\n    <th role=\"columnheader\"\n        scope=\"col\"\n        aria-label=\"Carbs (g): Not sorted. Activate to sort ascending.\"\n        aria-sort=\"none\"\n        class=\"text-start sortable\"\n    >\n      <span>\n        Carbs (g)\n      </span>\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate v-data-table-header__icon material-icons theme--light\"\n         style=\"font-size: 18px;\"\n      >\n        $sort\n      </i>\n    </th>\n    <th role=\"columnheader\"\n        scope=\"col\"\n        aria-label=\"Protein (g): Not sorted. Activate to sort ascending.\"\n        aria-sort=\"none\"\n        class=\"text-start sortable\"\n    >\n      <span>\n        Protein (g)\n      </span>\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate v-data-table-header__icon material-icons theme--light\"\n         style=\"font-size: 18px;\"\n      >\n        $sort\n      </i>\n    </th>\n    <th role=\"columnheader\"\n        scope=\"col\"\n        aria-label=\"Iron (%): Sorted descending. Activate to remove sorting.\"\n        aria-sort=\"descending\"\n        class=\"text-start sortable active desc\"\n    >\n      <span>\n        Iron (%)\n      </span>\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate v-data-table-header__icon material-icons theme--light\"\n         style=\"font-size: 18px;\"\n      >\n        $sort\n      </i>\n      <span class=\"v-data-table-header__sort-badge\">\n        1\n      </span>\n    </th>\n  </tr>\n</thead>\n`;\n\nexports[`VDataTableHeader.ts desktop should work with showGroupBy 1`] = `\n<thead class=\"v-data-table-header\">\n  <tr>\n    <th role=\"columnheader\"\n        scope=\"col\"\n        aria-label=\"Dessert (100g serving)\"\n        class=\"text-left\"\n    >\n      <span>\n        Dessert (100g serving)\n      </span>\n      <span>\n        group\n      </span>\n    </th>\n    <th role=\"columnheader\"\n        scope=\"col\"\n        aria-label=\"Calories: Not sorted. Activate to sort ascending.\"\n        aria-sort=\"none\"\n        class=\"text-start sortable\"\n        style=\"width: 50px; min-width: 50px;\"\n    >\n      <span>\n        Calories\n      </span>\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate v-data-table-header__icon material-icons theme--light\"\n         style=\"font-size: 18px;\"\n      >\n        $sort\n      </i>\n      <span>\n        group\n      </span>\n    </th>\n    <th role=\"columnheader\"\n        scope=\"col\"\n        aria-label=\"Fat (g): Not sorted. Activate to sort ascending.\"\n        aria-sort=\"none\"\n        class=\"text-start sortable\"\n        style=\"width: 50em; min-width: 50em;\"\n    >\n      <span>\n        Fat (g)\n      </span>\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate v-data-table-header__icon material-icons theme--light\"\n         style=\"font-size: 18px;\"\n      >\n        $sort\n      </i>\n      <span>\n        group\n      </span>\n    </th>\n    <th role=\"columnheader\"\n        scope=\"col\"\n        aria-label=\"Carbs (g): Not sorted. Activate to sort ascending.\"\n        aria-sort=\"none\"\n        class=\"text-start sortable\"\n    >\n      <span>\n        Carbs (g)\n      </span>\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate v-data-table-header__icon material-icons theme--light\"\n         style=\"font-size: 18px;\"\n      >\n        $sort\n      </i>\n      <span>\n        group\n      </span>\n    </th>\n    <th role=\"columnheader\"\n        scope=\"col\"\n        aria-label=\"Protein (g): Not sorted. Activate to sort ascending.\"\n        aria-sort=\"none\"\n        class=\"text-start sortable\"\n    >\n      <span>\n        Protein (g)\n      </span>\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate v-data-table-header__icon material-icons theme--light\"\n         style=\"font-size: 18px;\"\n      >\n        $sort\n      </i>\n      <span>\n        group\n      </span>\n    </th>\n    <th role=\"columnheader\"\n        scope=\"col\"\n        aria-label=\"Iron (%): Not sorted. Activate to sort ascending.\"\n        aria-sort=\"none\"\n        class=\"text-start sortable\"\n    >\n      <span>\n        Iron (%)\n      </span>\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate v-data-table-header__icon material-icons theme--light\"\n         style=\"font-size: 18px;\"\n      >\n        $sort\n      </i>\n      <span>\n        group\n      </span>\n    </th>\n  </tr>\n</thead>\n`;\n\nexports[`VDataTableHeader.ts desktop should work with sortBy correctly 1`] = `\n<thead class=\"v-data-table-header\">\n  <tr>\n    <th role=\"columnheader\"\n        scope=\"col\"\n        aria-label=\"Dessert (100g serving)\"\n        class=\"text-left\"\n    >\n      <span>\n        Dessert (100g serving)\n      </span>\n    </th>\n    <th role=\"columnheader\"\n        scope=\"col\"\n        aria-label=\"Calories: Not sorted. Activate to sort ascending.\"\n        aria-sort=\"none\"\n        class=\"text-start sortable\"\n        style=\"width: 50px; min-width: 50px;\"\n    >\n      <span>\n        Calories\n      </span>\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate v-data-table-header__icon material-icons theme--light\"\n         style=\"font-size: 18px;\"\n      >\n        $sort\n      </i>\n    </th>\n    <th role=\"columnheader\"\n        scope=\"col\"\n        aria-label=\"Fat (g): Not sorted. Activate to sort ascending.\"\n        aria-sort=\"none\"\n        class=\"text-start sortable\"\n        style=\"width: 50em; min-width: 50em;\"\n    >\n      <span>\n        Fat (g)\n      </span>\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate v-data-table-header__icon material-icons theme--light\"\n         style=\"font-size: 18px;\"\n      >\n        $sort\n      </i>\n    </th>\n    <th role=\"columnheader\"\n        scope=\"col\"\n        aria-label=\"Carbs (g): Not sorted. Activate to sort ascending.\"\n        aria-sort=\"none\"\n        class=\"text-start sortable\"\n    >\n      <span>\n        Carbs (g)\n      </span>\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate v-data-table-header__icon material-icons theme--light\"\n         style=\"font-size: 18px;\"\n      >\n        $sort\n      </i>\n    </th>\n    <th role=\"columnheader\"\n        scope=\"col\"\n        aria-label=\"Protein (g): Not sorted. Activate to sort ascending.\"\n        aria-sort=\"none\"\n        class=\"text-start sortable\"\n    >\n      <span>\n        Protein (g)\n      </span>\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate v-data-table-header__icon material-icons theme--light\"\n         style=\"font-size: 18px;\"\n      >\n        $sort\n      </i>\n    </th>\n    <th role=\"columnheader\"\n        scope=\"col\"\n        aria-label=\"Iron (%): Sorted descending. Activate to remove sorting.\"\n        aria-sort=\"descending\"\n        class=\"text-start sortable active desc\"\n    >\n      <span>\n        Iron (%)\n      </span>\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate v-data-table-header__icon material-icons theme--light\"\n         style=\"font-size: 18px;\"\n      >\n        $sort\n      </i>\n    </th>\n  </tr>\n</thead>\n`;\n\nexports[`VDataTableHeader.ts desktop should work with sortDesc correctly 1`] = `\n<thead class=\"v-data-table-header\">\n  <tr>\n    <th role=\"columnheader\"\n        scope=\"col\"\n        aria-label=\"Dessert (100g serving)\"\n        class=\"text-left\"\n    >\n      <span>\n        Dessert (100g serving)\n      </span>\n    </th>\n    <th role=\"columnheader\"\n        scope=\"col\"\n        aria-label=\"Calories: Not sorted. Activate to sort ascending.\"\n        aria-sort=\"none\"\n        class=\"text-start sortable\"\n        style=\"width: 50px; min-width: 50px;\"\n    >\n      <span>\n        Calories\n      </span>\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate v-data-table-header__icon material-icons theme--light\"\n         style=\"font-size: 18px;\"\n      >\n        $sort\n      </i>\n    </th>\n    <th role=\"columnheader\"\n        scope=\"col\"\n        aria-label=\"Fat (g): Not sorted. Activate to sort ascending.\"\n        aria-sort=\"none\"\n        class=\"text-start sortable\"\n        style=\"width: 50em; min-width: 50em;\"\n    >\n      <span>\n        Fat (g)\n      </span>\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate v-data-table-header__icon material-icons theme--light\"\n         style=\"font-size: 18px;\"\n      >\n        $sort\n      </i>\n    </th>\n    <th role=\"columnheader\"\n        scope=\"col\"\n        aria-label=\"Carbs (g): Sorted descending. Activate to remove sorting.\"\n        aria-sort=\"descending\"\n        class=\"text-start sortable active desc\"\n    >\n      <span>\n        Carbs (g)\n      </span>\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate v-data-table-header__icon material-icons theme--light\"\n         style=\"font-size: 18px;\"\n      >\n        $sort\n      </i>\n    </th>\n    <th role=\"columnheader\"\n        scope=\"col\"\n        aria-label=\"Protein (g): Not sorted. Activate to sort ascending.\"\n        aria-sort=\"none\"\n        class=\"text-start sortable\"\n    >\n      <span>\n        Protein (g)\n      </span>\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate v-data-table-header__icon material-icons theme--light\"\n         style=\"font-size: 18px;\"\n      >\n        $sort\n      </i>\n    </th>\n    <th role=\"columnheader\"\n        scope=\"col\"\n        aria-label=\"Iron (%): Sorted ascending. Activate to sort descending.\"\n        aria-sort=\"ascending\"\n        class=\"text-start sortable active asc\"\n    >\n      <span>\n        Iron (%)\n      </span>\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate v-data-table-header__icon material-icons theme--light\"\n         style=\"font-size: 18px;\"\n      >\n        $sort\n      </i>\n    </th>\n  </tr>\n</thead>\n`;\n\nexports[`VDataTableHeader.ts mobile should render 1`] = `\n<thead class=\"v-data-table-header v-data-table-header-mobile\">\n  <tr>\n    <th>\n      <div class=\"v-data-table-header-mobile__wrapper\">\n        <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n          <div class=\"v-input__control\">\n            <div role=\"button\"\n                 aria-haspopup=\"listbox\"\n                 aria-expanded=\"false\"\n                 aria-owns=\"list-37\"\n                 class=\"v-input__slot\"\n            >\n              <div class=\"v-select__slot\">\n                <label for=\"input-37\"\n                       class=\"v-label theme--light\"\n                       style=\"left: 0px; position: absolute;\"\n                >\n                  Sort by\n                </label>\n                <div class=\"v-select__selections\">\n                  <input id=\"input-37\"\n                         readonly=\"readonly\"\n                         type=\"text\"\n                         aria-readonly=\"false\"\n                         autocomplete=\"off\"\n                  >\n                </div>\n                <div class=\"v-input__append-inner\">\n                  <div class=\"v-input__icon v-input__icon--append\">\n                    <i aria-hidden=\"true\"\n                       class=\"v-icon notranslate material-icons theme--light\"\n                    >\n                      $dropdown\n                    </i>\n                  </div>\n                </div>\n                <input type=\"hidden\">\n              </div>\n              <div class=\"v-menu\">\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </th>\n  </tr>\n</thead>\n`;\n\nexports[`VDataTableHeader.ts mobile should render with data-table-select header 1`] = `\n<thead class=\"v-data-table-header v-data-table-header-mobile\">\n  <tr>\n    <th>\n      <div class=\"v-data-table-header-mobile__wrapper\">\n        <div class=\"v-data-table-header-mobile__select\">\n          <div class=\"v-data-table__checkbox v-simple-checkbox\">\n            <div class=\"v-input--selection-controls__input\">\n              <i aria-hidden=\"true\"\n                 class=\"v-icon notranslate material-icons theme--light\"\n              >\n                $checkboxOff\n              </i>\n              <div class=\"v-input--selection-controls__ripple\">\n              </div>\n            </div>\n          </div>\n        </div>\n        <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n          <div class=\"v-input__control\">\n            <div role=\"button\"\n                 aria-haspopup=\"listbox\"\n                 aria-expanded=\"false\"\n                 aria-owns=\"list-69\"\n                 class=\"v-input__slot\"\n            >\n              <div class=\"v-select__slot\">\n                <label for=\"input-69\"\n                       class=\"v-label theme--light\"\n                       style=\"left: 0px; position: absolute;\"\n                >\n                  Sort by\n                </label>\n                <div class=\"v-select__selections\">\n                  <input id=\"input-69\"\n                         readonly=\"readonly\"\n                         type=\"text\"\n                         aria-readonly=\"false\"\n                         autocomplete=\"off\"\n                  >\n                </div>\n                <div class=\"v-input__append-inner\">\n                  <div class=\"v-input__icon v-input__icon--append\">\n                    <i aria-hidden=\"true\"\n                       class=\"v-icon notranslate material-icons theme--light\"\n                    >\n                      $dropdown\n                    </i>\n                  </div>\n                </div>\n                <input type=\"hidden\">\n              </div>\n              <div class=\"v-menu\">\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </th>\n  </tr>\n</thead>\n`;\n\nexports[`VDataTableHeader.ts mobile should work with multiSort 1`] = `\n<thead class=\"v-data-table-header v-data-table-header-mobile\">\n  <tr>\n    <th>\n      <div class=\"v-data-table-header-mobile__wrapper\">\n        <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select v-select--is-multi\">\n          <div class=\"v-input__control\">\n            <div role=\"button\"\n                 aria-haspopup=\"listbox\"\n                 aria-expanded=\"false\"\n                 aria-owns=\"list-47\"\n                 class=\"v-input__slot\"\n            >\n              <div class=\"v-select__slot\">\n                <label for=\"input-47\"\n                       class=\"v-label v-label--active theme--light\"\n                       style=\"left: 0px; position: absolute;\"\n                >\n                  Sort by\n                </label>\n                <div class=\"v-select__selections\">\n                  <span class=\"sortable v-chip v-chip--clickable v-chip--no-color theme--light v-size--default\">\n                    <span class=\"v-chip__content\">\n                      Iron (%)\n                      <div class=\"v-chip__close sortable active desc\">\n                        <i aria-hidden=\"true\"\n                           class=\"v-icon notranslate v-data-table-header__icon material-icons theme--light\"\n                           style=\"font-size: 18px;\"\n                        >\n                          $sort\n                        </i>\n                      </div>\n                    </span>\n                  </span>\n                  <input id=\"input-47\"\n                         readonly=\"readonly\"\n                         type=\"text\"\n                         aria-readonly=\"false\"\n                         autocomplete=\"off\"\n                  >\n                </div>\n                <div class=\"v-input__append-inner\">\n                  <div class=\"v-input__icon v-input__icon--append\">\n                    <i aria-hidden=\"true\"\n                       class=\"v-icon notranslate material-icons theme--light\"\n                    >\n                      $dropdown\n                    </i>\n                  </div>\n                </div>\n                <input type=\"hidden\"\n                       value=\"iron\"\n                >\n              </div>\n              <div class=\"v-menu\">\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </th>\n  </tr>\n</thead>\n`;\n\nexports[`VDataTableHeader.ts mobile should work with showGroupBy 1`] = `\n<thead class=\"v-data-table-header v-data-table-header-mobile\">\n  <tr>\n    <th>\n      <div class=\"v-data-table-header-mobile__wrapper\">\n        <div class=\"v-input v-input--hide-details theme--light v-text-field v-select\">\n          <div class=\"v-input__control\">\n            <div role=\"button\"\n                 aria-haspopup=\"listbox\"\n                 aria-expanded=\"false\"\n                 aria-owns=\"list-42\"\n                 class=\"v-input__slot\"\n            >\n              <div class=\"v-select__slot\">\n                <label for=\"input-42\"\n                       class=\"v-label theme--light\"\n                       style=\"left: 0px; position: absolute;\"\n                >\n                  Sort by\n                </label>\n                <div class=\"v-select__selections\">\n                  <input id=\"input-42\"\n                         readonly=\"readonly\"\n                         type=\"text\"\n                         aria-readonly=\"false\"\n                         autocomplete=\"off\"\n                  >\n                </div>\n                <div class=\"v-input__append-inner\">\n                  <div class=\"v-input__icon v-input__icon--append\">\n                    <i aria-hidden=\"true\"\n                       class=\"v-icon notranslate material-icons theme--light\"\n                    >\n                      $dropdown\n                    </i>\n                  </div>\n                </div>\n                <input type=\"hidden\">\n              </div>\n              <div class=\"v-menu\">\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </th>\n  </tr>\n</thead>\n`;\n\nexports[`VDataTableHeader.ts mobile should work with sortBy correctly 1`] = `\n<thead class=\"v-data-table-header v-data-table-header-mobile\">\n  <tr>\n    <th>\n      <div class=\"v-data-table-header-mobile__wrapper\">\n        <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n          <div class=\"v-input__control\">\n            <div role=\"button\"\n                 aria-haspopup=\"listbox\"\n                 aria-expanded=\"false\"\n                 aria-owns=\"list-54\"\n                 class=\"v-input__slot\"\n            >\n              <div class=\"v-select__slot\">\n                <label for=\"input-54\"\n                       class=\"v-label v-label--active theme--light\"\n                       style=\"left: 0px; position: absolute;\"\n                >\n                  Sort by\n                </label>\n                <div class=\"v-select__selections\">\n                  <span class=\"sortable v-chip v-chip--clickable v-chip--no-color theme--light v-size--default\">\n                    <span class=\"v-chip__content\">\n                      Iron (%)\n                      <div class=\"v-chip__close sortable active desc\">\n                        <i aria-hidden=\"true\"\n                           class=\"v-icon notranslate v-data-table-header__icon material-icons theme--light\"\n                           style=\"font-size: 18px;\"\n                        >\n                          $sort\n                        </i>\n                      </div>\n                    </span>\n                  </span>\n                  <input id=\"input-54\"\n                         readonly=\"readonly\"\n                         type=\"text\"\n                         aria-readonly=\"false\"\n                         autocomplete=\"off\"\n                  >\n                </div>\n                <div class=\"v-input__append-inner\">\n                  <div class=\"v-input__icon v-input__icon--append\">\n                    <i aria-hidden=\"true\"\n                       class=\"v-icon notranslate material-icons theme--light\"\n                    >\n                      $dropdown\n                    </i>\n                  </div>\n                </div>\n                <input type=\"hidden\"\n                       value=\"iron\"\n                >\n              </div>\n              <div class=\"v-menu\">\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </th>\n  </tr>\n</thead>\n`;\n\nexports[`VDataTableHeader.ts mobile should work with sortDesc correctly 1`] = `\n<thead class=\"v-data-table-header v-data-table-header-mobile\">\n  <tr>\n    <th>\n      <div class=\"v-data-table-header-mobile__wrapper\">\n        <div class=\"v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select\">\n          <div class=\"v-input__control\">\n            <div role=\"button\"\n                 aria-haspopup=\"listbox\"\n                 aria-expanded=\"false\"\n                 aria-owns=\"list-61\"\n                 class=\"v-input__slot\"\n            >\n              <div class=\"v-select__slot\">\n                <label for=\"input-61\"\n                       class=\"v-label v-label--active theme--light\"\n                       style=\"left: 0px; position: absolute;\"\n                >\n                  Sort by\n                </label>\n                <div class=\"v-select__selections\">\n                  <span class=\"sortable v-chip v-chip--clickable v-chip--no-color theme--light v-size--default\">\n                    <span class=\"v-chip__content\">\n                      Iron (%)\n                      <div class=\"v-chip__close sortable active asc\">\n                        <i aria-hidden=\"true\"\n                           class=\"v-icon notranslate v-data-table-header__icon material-icons theme--light\"\n                           style=\"font-size: 18px;\"\n                        >\n                          $sort\n                        </i>\n                      </div>\n                    </span>\n                  </span>\n                  <input id=\"input-61\"\n                         readonly=\"readonly\"\n                         type=\"text\"\n                         aria-readonly=\"false\"\n                         autocomplete=\"off\"\n                  >\n                </div>\n                <div class=\"v-input__append-inner\">\n                  <div class=\"v-input__icon v-input__icon--append\">\n                    <i aria-hidden=\"true\"\n                       class=\"v-icon notranslate material-icons theme--light\"\n                    >\n                      $dropdown\n                    </i>\n                  </div>\n                </div>\n                <input type=\"hidden\"\n                       value=\"iron\"\n                >\n              </div>\n              <div class=\"v-menu\">\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </th>\n  </tr>\n</thead>\n`;\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/__tests__/__snapshots__/VEditDialog.spec.ts.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`VEditDialog.ts should render 1`] = `\n<div class=\"v-menu v-small-dialog theme--light\">\n  <div class=\"v-small-dialog__activator\">\n    <span class=\"v-small-dialog__activator__content\">\n    </span>\n  </div>\n</div>\n`;\n\nexports[`VEditDialog.ts should render actions 1`] = `\n<div class=\"v-small-dialog__actions\">\n  <button type=\"button\"\n          class=\"v-btn v-btn--text theme--light v-size--default primary--text\"\n  >\n    <span class=\"v-btn__content\">\n      Cancel\n    </span>\n  </button>\n  <button type=\"button\"\n          class=\"v-btn v-btn--text theme--light v-size--default primary--text\"\n  >\n    <span class=\"v-btn__content\">\n      Save\n    </span>\n  </button>\n</div>\n`;\n\nexports[`VEditDialog.ts should render button 1`] = `\n<button type=\"button\"\n        class=\"v-btn v-btn--text theme--light v-size--default primary--text\"\n>\n  <span class=\"v-btn__content\">\n    test\n  </span>\n</button>\n`;\n\nexports[`VEditDialog.ts should render custom button texts 1`] = `\n<div class=\"v-menu v-small-dialog theme--light\">\n  <div class=\"v-small-dialog__activator\">\n    <span class=\"v-small-dialog__activator__content\">\n    </span>\n  </div>\n</div>\n`;\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/__tests__/__snapshots__/VSimpleTable.spec.ts.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`VSimpleTable.ts should render 1`] = `\n<div class=\"v-data-table theme--light\">\n  <div class=\"v-data-table__wrapper\">\n    <table>\n      <tr>\n        <th>\n          Foo\n        </th>\n        <th>\n          Bar\n        </th>\n      </tr>\n      <tr>\n        <td>\n          baz\n        </td>\n        <td>\n          qux\n        </td>\n      </tr>\n    </table>\n  </div>\n</div>\n`;\n\nexports[`VSimpleTable.ts should render with custom height 1`] = `\n<div class=\"v-data-table v-data-table--fixed-height theme--light\">\n  <div class=\"v-data-table__wrapper\"\n       style=\"height: 1000px;\"\n  >\n    <table>\n      <tr>\n        <th>\n          Foo\n        </th>\n        <th>\n          Bar\n        </th>\n      </tr>\n      <tr>\n        <td>\n          baz\n        </td>\n        <td>\n          qux\n        </td>\n      </tr>\n    </table>\n  </div>\n</div>\n`;\n\nexports[`VSimpleTable.ts should render with custom wrapper 1`] = `\n<div class=\"v-data-table theme--light\">\n  <table>\n    <tr>\n      <th>\n        Foo\n      </th>\n      <th>\n        Bar\n      </th>\n    </tr>\n    <tr>\n      <td>\n        baz\n      </td>\n      <td>\n        qux\n      </td>\n    </tr>\n  </table>\n</div>\n`;\n\nexports[`VSimpleTable.ts should render with top & bottom slots 1`] = `\n<div class=\"v-data-table v-data-table--has-top v-data-table--has-bottom theme--light\">\n  <div class=\"top\">\n    Header\n  </div>\n  <div class=\"v-data-table__wrapper\">\n    <table>\n    </table>\n  </div>\n  <div class=\"bottom\">\n    Footer\n  </div>\n</div>\n`;\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/__tests__/__snapshots__/VVirtualTable.spec.ts.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`VVirtualTable.ts should re-render when items change 1`] = `\n<div class=\"v-data-table v-virtual-table theme--light\">\n  <div class=\"v-virtual-table__wrapper\">\n    <div class=\"v-virtual-table__table\">\n      <table>\n        <tbody>\n          <tr style=\"height: 0px;\">\n          </tr>\n          <div>\n            <div>\n              a\n            </div>\n            <div>\n              b\n            </div>\n            <div>\n              c\n            </div>\n          </div>\n          <tr style=\"height: 0px;\">\n          </tr>\n        </tbody>\n      </table>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VVirtualTable.ts should re-render when items change 2`] = `\n<div class=\"v-data-table v-virtual-table theme--light\">\n  <div class=\"v-virtual-table__wrapper\">\n    <div class=\"v-virtual-table__table\">\n      <table>\n        <tbody>\n          <tr style=\"height: 0px;\">\n          </tr>\n          <div>\n            <div>\n              d\n            </div>\n            <div>\n              e\n            </div>\n            <div>\n              f\n            </div>\n          </div>\n          <tr style=\"height: 0px;\">\n          </tr>\n        </tbody>\n      </table>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VVirtualTable.ts should render 1`] = `\n<div class=\"v-data-table v-virtual-table theme--light\">\n  <div class=\"v-virtual-table__wrapper\">\n    <div class=\"v-virtual-table__table\">\n      <table>\n        <tbody>\n          <tr style=\"height: 0px;\">\n          </tr>\n          <div class=\"test\">\n            {\"items\":[\"a\",\"b\",\"c\"]}\n          </div>\n          <tr style=\"height: 0px;\">\n          </tr>\n        </tbody>\n      </table>\n    </div>\n  </div>\n</div>\n`;\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/__tests__/headers.spec.ts",
    "content": "// Utilities\nimport { createHeaders } from '../composables/headers'\n\ndescribe('VDataTable headers', () => {\n  it('flattens 2d headers', () => {\n    const { headers, columns } = createHeaders({\n      items: [],\n      headers: [\n        { key: 'foo' },\n        { key: 'bar', children: [{ key: 'fizz' }, { key: 'buzz' }] },\n        { key: 'baz' },\n      ],\n    })\n    expect(headers.value).toMatchObject([\n      [{ key: 'foo', rowspan: 2 }, { key: 'bar', colspan: 2 }, { key: 'baz', rowspan: 2 }],\n      [{ key: 'fizz' }, { key: 'buzz' }],\n    ] as any)\n    expect(columns.value).toMatchObject([{ key: 'foo' }, { key: 'fizz' }, { key: 'buzz' }, { key: 'baz' }])\n    expect('provide() can only be used inside setup()').toHaveBeenTipped()\n  })\n\n  it('orders sibling columns correctly', () => {\n    const { headers, columns } = createHeaders({\n      items: [],\n      headers: [\n        {\n          key: 'left',\n          children: [\n            {\n              key: 'left_child',\n              children: [\n                {\n                  key: 'foo',\n                },\n                {\n                  key: 'bar',\n                },\n              ],\n            },\n          ],\n        },\n        {\n          key: 'right',\n          children: [\n            {\n              key: 'fizz',\n            },\n            {\n              key: 'buzz',\n            },\n          ],\n        },\n      ],\n    })\n\n    expect(headers.value).toMatchObject([\n      [{ key: 'left', colspan: 2 }, { key: 'right', rowspan: 2, colspan: 2 }],\n      [{ key: 'left_child', colspan: 2 }],\n      [{ key: 'foo' }, { key: 'bar' }, { key: 'fizz' }, { key: 'buzz' }],\n    ] as any)\n    expect(columns.value).toMatchObject([{ key: 'foo' }, { key: 'bar' }, { key: 'fizz' }, { key: 'buzz' }])\n    expect('provide() can only be used inside setup()').toHaveBeenTipped()\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/__tests__/sort.spec.ts",
    "content": "// Composables\nimport { createHeaders } from '../composables/headers'\nimport { transformItems as _transformItems } from '../composables/items'\nimport { sortItems as _sortItems } from '../composables/sort'\n\n// Utilities\nimport { mount } from '@vue/test-utils'\n\n// Types\nimport type { SortItem } from '../composables/sort'\nimport type { DataTableCompareFunction, DataTableHeader, DataTableItem } from '@/components/VDataTable/types'\n\nfunction transformItems (items: any[], headers?: DataTableHeader[]) {\n  let _items: DataTableItem[]\n  mount({\n    setup () {\n      const { columns } = createHeaders({ items, headers })\n      _items = _transformItems({} as any, items, columns.value)\n      return () => {}\n    },\n  })\n  return _items!\n}\n\nfunction sortItems (items: any[], sortBy: SortItem[], sortFunctions?: Record<string, DataTableCompareFunction>) {\n  return _sortItems(items, sortBy, 'en', {\n    sortFunctions,\n    transform: item => item.columns,\n  })\n}\n\ndescribe('VDataTable - sorting', () => {\n  it('should sort items by single column', () => {\n    const items = transformItems([\n      { string: 'foo', number: 1 },\n      { string: 'bar', number: 2 },\n      { string: 'baz', number: 4 },\n      { string: 'fizzbuzz', number: 3 },\n    ])\n\n    expect(\n      sortItems(items, [{ key: 'string', order: 'asc' }])\n        .map(i => i.raw)\n    ).toStrictEqual([\n      { string: 'bar', number: 2 },\n      { string: 'baz', number: 4 },\n      { string: 'fizzbuzz', number: 3 },\n      { string: 'foo', number: 1 },\n    ])\n\n    expect(\n      sortItems(items, [{ key: 'string', order: 'desc' }])\n        .map(i => i.raw)\n    ).toStrictEqual([\n      { string: 'foo', number: 1 },\n      { string: 'fizzbuzz', number: 3 },\n      { string: 'baz', number: 4 },\n      { string: 'bar', number: 2 },\n    ])\n\n    expect(\n      sortItems(items, [{ key: 'number', order: 'asc' }])\n        .map(i => i.raw)\n    ).toStrictEqual([\n      { string: 'foo', number: 1 },\n      { string: 'bar', number: 2 },\n      { string: 'fizzbuzz', number: 3 },\n      { string: 'baz', number: 4 },\n    ])\n\n    expect(\n      sortItems(items, [{ key: 'number', order: 'desc' }])\n        .map(i => i.raw)\n    ).toStrictEqual([\n      { string: 'baz', number: 4 },\n      { string: 'fizzbuzz', number: 3 },\n      { string: 'bar', number: 2 },\n      { string: 'foo', number: 1 },\n    ])\n\n    expect(\n      sortItems(items, [{ key: 'number', order: 'asc' }], { number: (a, b) => b - a })\n        .map(i => i.raw)\n    ).toStrictEqual([\n      { string: 'baz', number: 4 },\n      { string: 'fizzbuzz', number: 3 },\n      { string: 'bar', number: 2 },\n      { string: 'foo', number: 1 },\n    ])\n\n    expect(\n      sortItems(items, [{ key: 'number', order: 'desc' }], { number: (a, b) => b - a })\n        .map(i => i.raw)\n    ).toStrictEqual([\n      { string: 'foo', number: 1 },\n      { string: 'bar', number: 2 },\n      { string: 'fizzbuzz', number: 3 },\n      { string: 'baz', number: 4 },\n    ])\n  })\n\n  it('should sort items with deep structure', () => {\n    const items = transformItems([\n      { foo: { bar: { baz: 3 } } },\n      { foo: { bar: { baz: 1 } } },\n      { foo: { bar: { baz: 2 } } },\n    ], [{ key: 'foo.bar.baz' }])\n\n    expect(\n      sortItems(items, [{ key: 'foo.bar.baz', order: 'asc' }])\n        .map(i => i.raw)\n    ).toStrictEqual([\n      { foo: { bar: { baz: 1 } } },\n      { foo: { bar: { baz: 2 } } },\n      { foo: { bar: { baz: 3 } } },\n    ])\n  })\n\n  it('should sort items by multiple columns', () => {\n    const items = transformItems([\n      { string: 'foo', number: 1 },\n      { string: 'bar', number: 3 },\n      { string: 'baz', number: 2 },\n      { string: 'baz', number: 1 },\n    ])\n\n    expect(\n      sortItems(items, [{ key: 'string', order: 'asc' }, { key: 'number', order: 'asc' }])\n        .map(i => i.raw)\n    ).toStrictEqual([\n      { string: 'bar', number: 3 },\n      { string: 'baz', number: 1 },\n      { string: 'baz', number: 2 },\n      { string: 'foo', number: 1 },\n    ])\n\n    // { string: 'foo', number: 1 },\n    // { string: 'bar', number: 3 },\n    // { string: 'baz', number: 2 },\n    // { string: 'baz', number: 1 },\n\n    // { string: 'bar', number: 3 },\n    // { string: 'baz', number: 2 },\n    // { string: 'baz', number: 1 },\n    // { string: 'foo', number: 1 },\n\n    expect(\n      sortItems(items, [{ key: 'string', order: 'desc' }, { key: 'number', order: 'asc' }])\n        .map(i => i.raw)\n    ).toStrictEqual([\n      { string: 'foo', number: 1 },\n      { string: 'baz', number: 1 },\n      { string: 'baz', number: 2 },\n      { string: 'bar', number: 3 },\n    ])\n\n    expect(\n      sortItems(items, [{ key: 'string', order: 'asc' }, { key: 'number', order: 'desc' }])\n        .map(i => i.raw)\n    ).toStrictEqual([\n      { string: 'bar', number: 3 },\n      { string: 'baz', number: 2 },\n      { string: 'baz', number: 1 },\n      { string: 'foo', number: 1 },\n    ])\n\n    expect(\n      sortItems(items, [{ key: 'string', order: 'desc' }, { key: 'number', order: 'desc' }])\n        .map(i => i.raw)\n    ).toStrictEqual([\n      { string: 'foo', number: 1 },\n      { string: 'baz', number: 2 },\n      { string: 'baz', number: 1 },\n      { string: 'bar', number: 3 },\n    ])\n\n    expect(\n      sortItems(items, [{ key: 'number', order: 'asc' }, { key: 'string', order: 'asc' }])\n        .map(i => i.raw)\n    ).toStrictEqual([\n      { string: 'baz', number: 1 },\n      { string: 'foo', number: 1 },\n      { string: 'baz', number: 2 },\n      { string: 'bar', number: 3 },\n    ])\n\n    expect(\n      sortItems(items, [{ key: 'number', order: 'desc' }, { key: 'string', order: 'asc' }])\n        .map(i => i.raw)\n    ).toStrictEqual([\n      { string: 'bar', number: 3 },\n      { string: 'baz', number: 2 },\n      { string: 'baz', number: 1 },\n      { string: 'foo', number: 1 },\n    ])\n\n    expect(\n      sortItems(items, [{ key: 'number', order: 'asc' }, { key: 'string', order: 'desc' }])\n        .map(i => i.raw)\n    ).toStrictEqual([\n      { string: 'foo', number: 1 },\n      { string: 'baz', number: 1 },\n      { string: 'baz', number: 2 },\n      { string: 'bar', number: 3 },\n    ])\n\n    expect(\n      sortItems(items, [{ key: 'number', order: 'desc' }, { key: 'string', order: 'desc' }])\n        .map(i => i.raw)\n    ).toStrictEqual([\n      { string: 'bar', number: 3 },\n      { string: 'baz', number: 2 },\n      { string: 'foo', number: 1 },\n      { string: 'baz', number: 1 },\n    ])\n\n    expect(\n      sortItems(items, [{ key: 'string', order: 'asc' }, { key: 'number', order: 'asc' }], { number: (a, b) => b - a })\n        .map(i => i.raw)\n    ).toStrictEqual([\n      { string: 'bar', number: 3 },\n      { string: 'baz', number: 2 },\n      { string: 'baz', number: 1 },\n      { string: 'foo', number: 1 },\n    ])\n\n    expect(\n      sortItems(items, [{ key: 'number', order: 'asc' }, { key: 'string', order: 'asc' }], { number: (a, b) => b - a })\n        .map(i => i.raw)\n    ).toStrictEqual([\n      { string: 'bar', number: 3 },\n      { string: 'baz', number: 2 },\n      { string: 'baz', number: 1 },\n      { string: 'foo', number: 1 },\n    ])\n  })\n\n  it('should sort items with nullable column', () => {\n    const items = transformItems([\n      { string: 'foo', number: 1 },\n      { string: 'bar', number: null },\n      { string: 'baz', number: 4 },\n      { string: 'fizzbuzz', number: 3 },\n      { string: 'foobar', number: 5 },\n      { string: 'barbaz', number: undefined },\n      { string: 'foobarbuzz', number: '' },\n    ])\n\n    expect(\n      sortItems(items, [{ key: 'number', order: 'asc' }])\n        .map(i => i.raw)\n    ).toStrictEqual([\n      { string: 'bar', number: null },\n      { string: 'barbaz', number: undefined },\n      { string: 'foobarbuzz', number: '' },\n      { string: 'foo', number: 1 },\n      { string: 'fizzbuzz', number: 3 },\n      { string: 'baz', number: 4 },\n      { string: 'foobar', number: 5 },\n    ])\n\n    expect(\n      sortItems(items, [{ key: 'number', order: 'desc' }])\n        .map(i => i.raw)\n    ).toStrictEqual([\n      { string: 'foobar', number: 5 },\n      { string: 'baz', number: 4 },\n      { string: 'fizzbuzz', number: 3 },\n      { string: 'foo', number: 1 },\n      { string: 'bar', number: null },\n      { string: 'barbaz', number: undefined },\n      { string: 'foobarbuzz', number: '' },\n    ])\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/_variables.scss",
    "content": "@use '../../styles/settings';\n@use '../../styles/tools';\n\n$data-table-header-sort-badge-size: 20px !default;\n$data-table-header-sort-badge-color: rgba(var(--v-border-color), var(--v-border-opacity)) !default;\n$data-table-header-sort-icon-default-opacity: .0 !default;\n$data-table-header-sort-icon-hover-opacity: .5 !default;\n$data-table-header-sort-icon-margin-inline: 0px !default;\n\n$data-table-loading-opacity: var(--v-disabled-opacity) !default;\n\n$data-table-footer-info-min-width: 116px !default;\n$data-table-footer-info-padding: 0 16px !default;\n$data-table-footer-padding: 8px 4px !default;\n$data-table-footer-pagination-margin-inline-start: 16px !default;\n$data-table-footer-select-width: 90px !default;\n$data-table-footer-items-per-page-padding: 8px !default;\n\n$data-table-header-mobile-chip-icon-color: tools.theme-color('on-surface', var(--v-disabled-opacity)) !default;\n$data-table-header-mobile-chip-icon-color-active: rgba(var(--v-theme-on-surface)) !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/composables/expand.ts",
    "content": "// Composables\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { inject, provide, toRaw, toRef } from 'vue'\nimport { propsFactory } from '@/util'\n\n// Types\nimport type { InjectionKey, PropType, Ref } from 'vue'\nimport type { DataTableItem } from '../types'\n\nexport const makeDataTableExpandProps = propsFactory({\n  expandOnClick: Boolean,\n  showExpand: Boolean,\n  expanded: {\n    type: Array as PropType<readonly string[]>,\n    default: () => ([]),\n  },\n}, 'DataTable-expand')\n\nexport const VDataTableExpandedKey: InjectionKey<{\n  expand: (item: DataTableItem, value: boolean) => void\n  expanded: Ref<Set<string>>\n  expandOnClick: Ref<boolean | undefined>\n  isExpanded: (item: DataTableItem) => boolean\n  toggleExpand: (item: DataTableItem) => void\n}> = Symbol.for('vuetify:datatable:expanded')\n\ntype ExpandProps = {\n  expandOnClick: boolean\n  expanded: readonly string[]\n  'onUpdate:expanded': ((value: any[]) => void) | undefined\n}\n\nexport function provideExpanded (props: ExpandProps) {\n  const expandOnClick = toRef(() => props.expandOnClick)\n  const expanded = useProxiedModel(props, 'expanded', props.expanded, v => {\n    return new Set(v)\n  }, v => {\n    return [...v.values()]\n  })\n\n  function expand (item: DataTableItem, value: boolean) {\n    const newExpanded = new Set(expanded.value)\n    const rawValue = toRaw(item.value)\n\n    if (!value) {\n      const item = [...expanded.value].find(x => toRaw(x) === rawValue)!\n      newExpanded.delete(item)\n    } else {\n      newExpanded.add(item.value)\n    }\n\n    expanded.value = newExpanded\n  }\n\n  function isExpanded (item: DataTableItem) {\n    const rawValue = toRaw(item.value)\n    return [...expanded.value].some(x => toRaw(x) === rawValue)\n  }\n\n  function toggleExpand (item: DataTableItem) {\n    expand(item, !isExpanded(item))\n  }\n\n  const data = { expand, expanded, expandOnClick, isExpanded, toggleExpand }\n\n  provide(VDataTableExpandedKey, data)\n\n  return data\n}\n\nexport function useExpanded () {\n  const data = inject(VDataTableExpandedKey)\n\n  if (!data) throw new Error('foo')\n\n  return data\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/composables/group.ts",
    "content": "// Composables\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { computed, inject, provide, ref, toValue } from 'vue'\nimport { getObjectValueByPath, propsFactory } from '@/util'\n\n// Types\nimport type { InjectionKey, MaybeRefOrGetter, PropType, Ref } from 'vue'\nimport type { SortItem } from './sort'\nimport type { DataTableItem } from '../types'\n\nexport interface GroupableItem<T = any> {\n  type: 'item'\n  raw: T\n}\n\nexport interface Group<T = any> {\n  type: 'group'\n  depth: number\n  id: string\n  key: string\n  value: any\n  items: readonly (T | Group<T> | GroupSummary<T>)[]\n}\n\nexport interface GroupSummary<T = any> {\n  type: 'group-summary'\n  depth: number\n  id: string\n  key: string\n  value: any\n  items: readonly (T | Group<T> | GroupSummary<T>)[]\n}\n\nexport const makeDataTableGroupProps = propsFactory({\n  groupBy: {\n    type: Array as PropType<readonly SortItem[]>,\n    default: () => ([]),\n  },\n}, 'DataTable-group')\n\nconst VDataTableGroupSymbol: InjectionKey<{\n  opened: Ref<Set<string>>\n  toggleGroup: (group: Group) => void\n  isGroupOpen: (group: Group) => boolean\n  sortByWithGroups: Ref<SortItem[]>\n  groupBy: Ref<readonly SortItem[]>\n  extractRows: (items: (DataTableItem | Group<DataTableItem>)[]) => DataTableItem[]\n}> = Symbol.for('vuetify:data-table-group')\n\ntype GroupProps = {\n  groupBy: readonly SortItem[]\n  'onUpdate:groupBy': ((value: SortItem[]) => void) | undefined\n}\n\nexport function createGroupBy (props: GroupProps) {\n  const groupBy = useProxiedModel(props, 'groupBy')\n\n  return { groupBy }\n}\n\nexport function provideGroupBy (options: {\n  groupBy: Ref<readonly SortItem[]>\n  sortBy: Ref<readonly SortItem[]>\n  disableSort?: Ref<boolean>\n}) {\n  const { disableSort, groupBy, sortBy } = options\n  const opened = ref(new Set<string>())\n\n  const sortByWithGroups = computed(() => {\n    return groupBy.value.map<SortItem>(val => ({\n      ...val,\n      order: val.order ?? false,\n    })).concat(disableSort?.value ? [] : sortBy.value)\n  })\n\n  function isGroupOpen (group: Group) {\n    return opened.value.has(group.id)\n  }\n\n  function toggleGroup (group: Group) {\n    const newOpened = new Set(opened.value)\n    if (!isGroupOpen(group)) newOpened.add(group.id)\n    else newOpened.delete(group.id)\n\n    opened.value = newOpened\n  }\n\n  function extractRows <T extends GroupableItem> (items: readonly (T | Group<T> | GroupSummary<T>)[]) {\n    function dive (group: Group<T>): T[] {\n      const arr = []\n\n      for (const item of group.items) {\n        if ('type' in item && item.type === 'group') {\n          arr.push(...dive(item))\n        } else {\n          arr.push(item as T)\n        }\n      }\n\n      return [...new Set(arr)]\n    }\n    return dive({ type: 'group', items, id: 'dummy', key: 'dummy', value: 'dummy', depth: 0 })\n  }\n\n  // onBeforeMount(() => {\n  //   for (const key of groupedItems.value.keys()) {\n  //     opened.value.add(key)\n  //   }\n  // })\n\n  const data = { sortByWithGroups, toggleGroup, opened, groupBy, extractRows, isGroupOpen }\n\n  provide(VDataTableGroupSymbol, data)\n\n  return data\n}\n\nexport function useGroupBy () {\n  const data = inject(VDataTableGroupSymbol)\n\n  if (!data) throw new Error('Missing group!')\n\n  return data\n}\n\nfunction groupItemsByProperty <T extends GroupableItem> (items: readonly T[], groupBy: string) {\n  if (!items.length) return []\n\n  const groups = new Map<any, T[]>()\n  for (const item of items) {\n    const value = getObjectValueByPath(item.raw, groupBy)\n\n    if (!groups.has(value)) {\n      groups.set(value, [])\n    }\n    groups.get(value)!.push(item)\n  }\n\n  return groups\n}\n\nfunction groupItems <T extends GroupableItem> (items: readonly T[], groupBy: readonly string[], depth = 0, prefix = 'root') {\n  if (!groupBy.length) return []\n\n  const groupedItems = groupItemsByProperty(items, groupBy[0])\n  const groups: Group<T>[] = []\n\n  const rest = groupBy.slice(1)\n  groupedItems.forEach((items, value) => {\n    const key = groupBy[0]\n    const id = `${prefix}_${key}_${value}`\n    groups.push({\n      depth,\n      id,\n      key,\n      value,\n      items: rest.length ? groupItems(items, rest, depth + 1, id) : items,\n      type: 'group',\n    })\n  })\n\n  return groups\n}\n\nfunction flattenItems <T extends GroupableItem> (\n  items: readonly (T | Group<T> | GroupSummary<T>)[],\n  opened: Set<string>,\n  hasSummary: boolean\n): readonly (T | Group<T> | GroupSummary<T>)[] {\n  const flatItems: (T | Group<T> | GroupSummary<T>)[] = []\n\n  for (const item of items) {\n    // TODO: make this better\n    if ('type' in item && item.type === 'group') {\n      if (item.value != null) {\n        flatItems.push(item)\n      }\n\n      if (opened.has(item.id) || item.value == null) {\n        flatItems.push(...flattenItems(item.items, opened, hasSummary))\n\n        if (hasSummary) {\n          flatItems.push({ ...item, type: 'group-summary' })\n        }\n      }\n    } else {\n      flatItems.push(item)\n    }\n  }\n\n  return flatItems\n}\n\nexport function useGroupedItems <T extends GroupableItem> (\n  items: MaybeRefOrGetter<readonly T[]>,\n  groupBy: Ref<readonly SortItem[]>,\n  opened: Ref<Set<string>>,\n  hasSummary: MaybeRefOrGetter<boolean>,\n) {\n  const groups = computed(() => {\n    if (!groupBy.value.length) return []\n    return groupItems(toValue(items), groupBy.value.map(item => item.key))\n  })\n\n  const flatItems = computed(() => {\n    if (!groupBy.value.length) return toValue(items)\n    return flattenItems(groups.value, opened.value, toValue(hasSummary))\n  })\n\n  return { groups, flatItems }\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/composables/headers.ts",
    "content": "// Utilities\nimport { capitalize, inject, provide, ref, watchEffect } from 'vue'\nimport { consoleError, propsFactory } from '@/util'\n\n// Types\nimport type { DeepReadonly, InjectionKey, PropType, Ref } from 'vue'\nimport type { SortItem } from './sort'\nimport type { DataTableCompareFunction, DataTableHeader, InternalDataTableHeader } from '../types'\nimport type { FilterKeyFunctions } from '@/composables/filter'\n\nexport const makeDataTableHeaderProps = propsFactory({\n  headers: Array as PropType<DeepReadonly<DataTableHeader[]>>,\n}, 'DataTable-header')\n\nexport const VDataTableHeadersSymbol: InjectionKey<{\n  headers: Ref<InternalDataTableHeader[][]>\n  columns: Ref<InternalDataTableHeader[]>\n}> = Symbol.for('vuetify:data-table-headers')\n\ntype HeaderProps = {\n  headers: DeepReadonly<DataTableHeader[]> | undefined\n  items: any[]\n}\n\nconst defaultHeader = { title: '', sortable: false }\nconst defaultActionHeader = { ...defaultHeader, width: 48 }\n\nfunction priorityQueue <T> (arr: T[] = []) {\n  const queue: { element: T, priority: number }[] = arr.map(element => ({ element, priority: 0 }))\n\n  return {\n    enqueue: (element: T, priority: number) => {\n      let added = false\n      for (let i = 0; i < queue.length; i++) {\n        const item = queue[i]\n        if (item.priority > priority) {\n          queue.splice(i, 0, { element, priority })\n          added = true\n          break\n        }\n      }\n\n      if (!added) queue.push({ element, priority })\n    },\n    size: () => queue.length,\n    count: () => {\n      let count = 0\n\n      if (!queue.length) return 0\n\n      const whole = Math.floor(queue[0].priority)\n      for (let i = 0; i < queue.length; i++) {\n        if (Math.floor(queue[i].priority) === whole) count += 1\n      }\n\n      return count\n    },\n    dequeue: () => {\n      return queue.shift()\n    },\n  }\n}\n\nfunction extractLeaves (item: InternalDataTableHeader, columns: InternalDataTableHeader[] = []) {\n  if (!item.children) {\n    columns.push(item)\n  } else {\n    for (const child of item.children) {\n      extractLeaves(child, columns)\n    }\n  }\n\n  return columns\n}\n\nfunction extractKeys (headers: DeepReadonly<DataTableHeader[]>, keys = new Set<string>()) {\n  for (const item of headers) {\n    if (item.key) keys.add(item.key)\n\n    if (item.children) {\n      extractKeys(item.children, keys)\n    }\n  }\n\n  return keys\n}\n\nfunction getDefaultItem (item: DeepReadonly<DataTableHeader>) {\n  if (!item.key) return undefined\n  if (item.key === 'data-table-group') return defaultHeader\n  if (['data-table-expand', 'data-table-select'].includes(item.key)) return defaultActionHeader\n  return undefined\n}\n\nfunction getDepth (item: InternalDataTableHeader, depth = 0): number {\n  if (!item.children) return depth\n\n  return Math.max(depth, ...item.children.map(child => getDepth(child, depth + 1)))\n}\n\nfunction parseFixedColumns (items: InternalDataTableHeader[]) {\n  let seenFixed = false\n\n  function setFixed (\n    item: InternalDataTableHeader,\n    side: 'start' | 'end',\n    parentFixedSide: 'start' | 'end' | 'none' = 'none'\n  ) {\n    if (!item) return\n\n    if (parentFixedSide !== 'none') {\n      item.fixed = parentFixedSide\n    }\n\n    // normalize to simplify logic below\n    if (item.fixed === true) {\n      item.fixed = 'start'\n    }\n\n    if (item.fixed === side) {\n      if (item.children) {\n        if (side === 'start') {\n          for (let i = item.children.length - 1; i >= 0; i--) {\n            setFixed(item.children[i], side, side)\n          }\n        } else {\n          for (let i = 0; i < item.children.length; i++) {\n            setFixed(item.children[i], side, side)\n          }\n        }\n      } else {\n        if (!seenFixed && side === 'start') {\n          item.lastFixed = true\n        } else if (!seenFixed && side === 'end') {\n          item.firstFixedEnd = true\n        } else if (isNaN(Number(item.width))) {\n          consoleError(`Multiple fixed columns should have a static width (key: ${item.key})`)\n        } else {\n          item.minWidth = Math.max(Number(item.width) || 0, Number(item.minWidth) || 0)\n        }\n        seenFixed = true\n      }\n    } else {\n      if (item.children) {\n        if (side === 'start') {\n          for (let i = item.children.length - 1; i >= 0; i--) {\n            setFixed(item.children[i], side)\n          }\n        } else {\n          for (let i = 0; i < item.children.length; i++) {\n            setFixed(item.children[i], side)\n          }\n        }\n      } else {\n        seenFixed = false\n      }\n    }\n  }\n\n  for (let i = items.length - 1; i >= 0; i--) {\n    setFixed(items[i], 'start')\n  }\n\n  for (let i = 0; i < items.length; i++) {\n    setFixed(items[i], 'end')\n  }\n\n  let fixedOffset = 0\n  for (let i = 0; i < items.length; i++) {\n    fixedOffset = setFixedOffset(items[i], fixedOffset)\n  }\n\n  let fixedEndOffset = 0\n  for (let i = items.length - 1; i >= 0; i--) {\n    fixedEndOffset = setFixedEndOffset(items[i], fixedEndOffset)\n  }\n}\n\nfunction setFixedOffset (item: InternalDataTableHeader, offset = 0) {\n  if (!item) return offset\n\n  if (item.children) {\n    item.fixedOffset = offset\n    for (const child of item.children) {\n      offset = setFixedOffset(child, offset)\n    }\n  } else if (item.fixed && item.fixed !== 'end') {\n    item.fixedOffset = offset\n    offset += parseFloat(item.width || '0') || 0\n  }\n\n  return offset\n}\n\nfunction setFixedEndOffset (item: InternalDataTableHeader, offset = 0) {\n  if (!item) return offset\n\n  if (item.children) {\n    item.fixedEndOffset = offset\n    for (const child of item.children) {\n      offset = setFixedEndOffset(child, offset)\n    }\n  } else if (item.fixed === 'end') {\n    item.fixedEndOffset = offset\n    offset += parseFloat(item.width || '0') || 0\n  }\n\n  return offset\n}\n\nfunction parse (items: InternalDataTableHeader[], maxDepth: number) {\n  const headers: InternalDataTableHeader[][] = []\n  let currentDepth = 0\n  const queue = priorityQueue(items)\n\n  while (queue.size() > 0) {\n    let rowSize = queue.count()\n    const row: InternalDataTableHeader[] = []\n    let fraction = 1\n    while (rowSize > 0) {\n      const { element: item, priority } = queue.dequeue()!\n      const diff = maxDepth - currentDepth - getDepth(item)\n\n      row.push({\n        ...item,\n        rowspan: diff ?? 1,\n        colspan: item.children ? extractLeaves(item).length : 1,\n      })\n\n      if (item.children) {\n        for (const child of item.children) {\n          // This internally sorts items that are on the same priority \"row\"\n          const sort = priority % 1 + (fraction / Math.pow(10, currentDepth + 2))\n          queue.enqueue(child, currentDepth + diff + sort)\n        }\n      }\n\n      fraction += 1\n      rowSize -= 1\n    }\n    currentDepth += 1\n    headers.push(row)\n  }\n\n  const columns = items.map(item => extractLeaves(item)).flat()\n\n  return { columns, headers }\n}\n\nfunction convertToInternalHeaders (items: DeepReadonly<DataTableHeader[]>) {\n  const internalHeaders: InternalDataTableHeader[] = []\n  for (const item of items) {\n    const defaultItem = { ...getDefaultItem(item), ...item }\n    const key = defaultItem.key ?? (typeof defaultItem.value === 'string' ? defaultItem.value : null)\n    const value = defaultItem.value ?? key ?? null\n    const internalItem: InternalDataTableHeader = {\n      ...defaultItem,\n      key,\n      value,\n      sortable: defaultItem.sortable ?? (defaultItem.key != null || !!defaultItem.sort),\n      children: defaultItem.children ? convertToInternalHeaders(defaultItem.children) : undefined,\n    }\n\n    internalHeaders.push(internalItem)\n  }\n\n  return internalHeaders\n}\n\nexport function createHeaders (\n  props: HeaderProps,\n  options?: {\n    groupBy?: Ref<readonly SortItem[]>\n    showSelect?: Ref<boolean>\n    showExpand?: Ref<boolean>\n  }\n) {\n  const headers = ref<InternalDataTableHeader[][]>([])\n  const columns = ref<InternalDataTableHeader[]>([])\n  const sortFunctions = ref<Record<string, DataTableCompareFunction>>({})\n  const sortRawFunctions = ref<Record<string, DataTableCompareFunction>>({})\n  const filterFunctions = ref<FilterKeyFunctions>({})\n\n  watchEffect(() => {\n    const _headers = props.headers ||\n      Object.keys(props.items[0] ?? {}).map(key => ({ key, title: capitalize(key) })) as never\n\n    const items = _headers.slice()\n    const keys = extractKeys(items)\n\n    if (options?.groupBy?.value.length && !keys.has('data-table-group')) {\n      items.unshift({ key: 'data-table-group', title: 'Group' })\n    }\n\n    if (options?.showSelect?.value && !keys.has('data-table-select')) {\n      items.unshift({ key: 'data-table-select' })\n    }\n\n    if (options?.showExpand?.value && !keys.has('data-table-expand')) {\n      items.push({ key: 'data-table-expand' })\n    }\n\n    const internalHeaders = convertToInternalHeaders(items)\n\n    parseFixedColumns(internalHeaders)\n\n    const maxDepth = Math.max(...internalHeaders.map(item => getDepth(item))) + 1\n    const parsed = parse(internalHeaders, maxDepth)\n\n    headers.value = parsed.headers\n    columns.value = parsed.columns\n\n    const flatHeaders = parsed.headers.flat(1)\n\n    for (const header of flatHeaders) {\n      if (!header.key) continue\n\n      if (header.sortable) {\n        if (header.sort) {\n          sortFunctions.value[header.key] = header.sort\n        }\n\n        if (header.sortRaw) {\n          sortRawFunctions.value[header.key] = header.sortRaw\n        }\n      }\n\n      if (header.filter) {\n        filterFunctions.value[header.key] = header.filter\n      }\n    }\n  })\n\n  const data = { headers, columns, sortFunctions, sortRawFunctions, filterFunctions }\n\n  provide(VDataTableHeadersSymbol, data)\n\n  return data\n}\n\nexport function useHeaders () {\n  const data = inject(VDataTableHeadersSymbol)\n\n  if (!data) throw new Error('Missing headers!')\n\n  return data\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/composables/items.ts",
    "content": "// Utilities\nimport { computed } from 'vue'\nimport { getPropertyFromItem, propsFactory } from '@/util'\n\n// Types\nimport type { PropType, Ref } from 'vue'\nimport type { CellProps, DataTableItem, InternalDataTableHeader, RowProps } from '../types'\nimport type { SelectItemKey } from '@/util'\n\nexport interface DataTableItemProps {\n  items: any[]\n  itemValue: SelectItemKey\n  itemSelectable: SelectItemKey\n  returnObject: boolean\n}\n\n// Composables\nexport const makeDataTableItemsProps = propsFactory({\n  items: {\n    type: Array as PropType<DataTableItemProps['items']>,\n    default: () => ([]),\n  },\n  itemValue: {\n    type: [String, Array, Function] as PropType<SelectItemKey>,\n    default: 'id',\n  },\n  itemSelectable: {\n    type: [String, Array, Function] as PropType<SelectItemKey>,\n    default: null,\n  },\n  rowProps: [Object, Function] as PropType<RowProps<any>>,\n  cellProps: [Object, Function] as PropType<CellProps<any>>,\n  returnObject: Boolean,\n}, 'DataTable-items')\n\nexport function transformItem (\n  props: Omit<DataTableItemProps, 'items'>,\n  item: any,\n  index: number,\n  columns: InternalDataTableHeader[]\n): DataTableItem {\n  const value = props.returnObject ? item : getPropertyFromItem(item, props.itemValue)\n  const selectable = getPropertyFromItem(item, props.itemSelectable, true)\n  const itemColumns = columns.reduce((obj, column) => {\n    if (column.key != null) obj[column.key] = getPropertyFromItem(item, column.value!)\n    return obj\n  }, {} as Record<string, unknown>)\n\n  return {\n    type: 'item',\n    key: props.returnObject ? getPropertyFromItem(item, props.itemValue) : value,\n    index,\n    value,\n    selectable,\n    columns: itemColumns,\n    raw: item,\n  }\n}\n\nexport function transformItems (\n  props: Omit<DataTableItemProps, 'items'>,\n  items: DataTableItemProps['items'],\n  columns: InternalDataTableHeader[]\n): DataTableItem[] {\n  return items.map((item, index) => transformItem(props, item, index, columns))\n}\n\nexport function useDataTableItems (props: DataTableItemProps, columns: Ref<InternalDataTableHeader[]>) {\n  const items = computed(() => transformItems(props, props.items, columns.value))\n\n  return { items }\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/composables/options.ts",
    "content": "// Utilities\nimport { watch } from 'vue'\nimport { deepEqual, getCurrentInstance } from '@/util'\n\n// Types\nimport type { Ref } from 'vue'\nimport type { SortItem } from './sort'\n\nexport function useOptions ({\n  page,\n  itemsPerPage,\n  sortBy,\n  groupBy,\n  search,\n}: {\n  page: Ref<number>\n  itemsPerPage: Ref<number>\n  sortBy: Ref<readonly SortItem[]>\n  groupBy: Ref<readonly SortItem[]>\n  search: Ref<string | undefined>\n}) {\n  const vm = getCurrentInstance('VDataTable')\n\n  const options = () => ({\n    page: page.value,\n    itemsPerPage: itemsPerPage.value,\n    sortBy: sortBy.value,\n    groupBy: groupBy.value,\n    search: search.value,\n  })\n\n  let oldOptions: ReturnType<typeof options> | null = null\n  watch(options, value => {\n    if (deepEqual(oldOptions, value)) return\n\n    // Reset page when searching\n    if (oldOptions && oldOptions.search !== value.search) {\n      page.value = 1\n    }\n\n    vm.emit('update:options', value)\n    oldOptions = value\n  }, { deep: true, immediate: true })\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/composables/paginate.ts",
    "content": "// Composables\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { computed, inject, provide, toValue, watch } from 'vue'\nimport { clamp, getCurrentInstance, propsFactory } from '@/util'\n\n// Types\nimport type { ComputedRef, InjectionKey, MaybeRefOrGetter, PropType, Ref } from 'vue'\nimport type { Group, GroupableItem, GroupSummary } from './group'\nimport type { EventProp } from '@/util'\n\nexport const makeDataTablePaginateProps = propsFactory({\n  page: {\n    type: [Number, String],\n    default: 1,\n  },\n  itemsPerPage: {\n    type: [Number, String],\n    default: 10,\n  },\n  pageBy: {\n    type: String as PropType<'item' | 'any' | 'auto'>,\n    default: 'any',\n  },\n}, 'DataTable-paginate')\n\nexport type VDataTablePaginationInjectionData = {\n  page: Ref<number>\n  itemsPerPage: Ref<number>\n  startIndex: Ref<number>\n  stopIndex: Ref<number>\n  pageCount: Ref<number>\n  itemsLength: Ref<number>\n  prevPage: () => void\n  nextPage: () => void\n  setPage: (value: number) => void\n  setItemsPerPage: (value: number) => void\n}\n\nconst VDataTablePaginationSymbol: InjectionKey<VDataTablePaginationInjectionData> = Symbol.for('vuetify:data-table-pagination')\n\ntype PaginationProps = {\n  page: number | string\n  'onUpdate:page': EventProp | undefined\n  itemsPerPage: number | string\n  'onUpdate:itemsPerPage': EventProp | undefined\n  itemsLength?: number | string\n}\n\nexport function createPagination (props: PaginationProps) {\n  const page = useProxiedModel(props, 'page', undefined, value => Number(value ?? 1))\n  const itemsPerPage = useProxiedModel(props, 'itemsPerPage', undefined, value => Number(value ?? 10))\n\n  return { page, itemsPerPage }\n}\n\nexport function providePagination (options: {\n  page: Ref<number>\n  itemsPerPage: Ref<number>\n  itemsLength: Ref<number>\n}) {\n  const { page, itemsPerPage, itemsLength } = options\n\n  const startIndex = computed(() => {\n    if (itemsPerPage.value === -1) return 0\n\n    return itemsPerPage.value * (page.value - 1)\n  })\n  const stopIndex = computed(() => {\n    if (itemsPerPage.value === -1) return itemsLength.value\n\n    return Math.min(itemsLength.value, startIndex.value + itemsPerPage.value)\n  })\n\n  const pageCount = computed(() => {\n    if (itemsPerPage.value === -1 || itemsLength.value === 0) return 1\n\n    return Math.ceil(itemsLength.value / itemsPerPage.value)\n  })\n\n  // Don't run immediately, items may not have been loaded yet: #17966\n  watch([page, pageCount], () => {\n    if (page.value > pageCount.value) {\n      page.value = pageCount.value\n    }\n  })\n\n  function setItemsPerPage (value: number) {\n    itemsPerPage.value = value\n    page.value = 1\n  }\n\n  function nextPage () {\n    page.value = clamp(page.value + 1, 1, pageCount.value)\n  }\n\n  function prevPage () {\n    page.value = clamp(page.value - 1, 1, pageCount.value)\n  }\n\n  function setPage (value: number) {\n    page.value = clamp(value, 1, pageCount.value)\n  }\n\n  const data = { page, itemsPerPage, startIndex, stopIndex, pageCount, itemsLength, nextPage, prevPage, setPage, setItemsPerPage }\n\n  provide(VDataTablePaginationSymbol, data)\n\n  return data\n}\n\nexport function usePagination () {\n  const data = inject(VDataTablePaginationSymbol)\n\n  if (!data) throw new Error('Missing pagination!')\n\n  return data\n}\n\nexport function usePaginatedItems <T> (options: {\n  items: MaybeRefOrGetter<readonly T[]>\n  startIndex: Ref<number>\n  stopIndex: Ref<number>\n  itemsPerPage: Ref<number>\n}) {\n  const vm = getCurrentInstance('usePaginatedItems')\n\n  const { items, startIndex, stopIndex, itemsPerPage } = options\n  const paginatedItems = computed(() => {\n    if (itemsPerPage.value <= 0) return toValue(items)\n\n    return toValue(items).slice(startIndex.value, stopIndex.value)\n  })\n\n  watch(paginatedItems, val => {\n    vm.emit('update:currentItems', val)\n  }, { immediate: true })\n\n  return { paginatedItems }\n}\n\nexport function usePaginatedGroups <T extends GroupableItem> (options: {\n  pageBy: ComputedRef<'item' | 'group' | 'any'>\n  sortedItems: Ref<readonly T[]>\n  paginate: <TItem>(items: MaybeRefOrGetter<readonly TItem[]>) => {\n    paginatedItems: ComputedRef<readonly TItem[]>\n    pageCount: ComputedRef<number>\n    setItemsPerPage: (value: number) => void\n    prevPage: () => void\n    nextPage: () => void\n    setPage: (value: number) => void\n  }\n  group: (items: MaybeRefOrGetter<readonly T[]>) => {\n    flatItems: ComputedRef<readonly (T | Group<T> | GroupSummary<T>)[]>\n    groups: ComputedRef<readonly Group<T>[]>\n  }\n}) {\n  const { sortedItems, paginate, group } = options\n  const pageBy = toValue(options.pageBy) // TODO: make reactive\n\n  if (pageBy === 'item') {\n    const { paginatedItems, pageCount, setItemsPerPage, prevPage, nextPage, setPage } = paginate(sortedItems)\n    const { flatItems: paginatedItemsWithGroups } = group(paginatedItems)\n\n    return {\n      pageCount,\n      setItemsPerPage,\n      prevPage,\n      nextPage,\n      setPage,\n      paginatedItems: paginatedItemsWithGroups,\n    }\n  }\n\n  if (pageBy === 'group') {\n    const { flatItems, groups } = group(sortedItems)\n    const { paginatedItems: paginatedGroups, pageCount, setItemsPerPage, prevPage, nextPage, setPage } = paginate(groups)\n    const paginatedItemsWithGroups = computed(() => {\n      if (!paginatedGroups.value.length) return []\n      const firstGroupId = paginatedGroups.value.at(0)!.id\n      const lastGroupId = paginatedGroups.value.at(-1)!.id\n      const start = flatItems.value.findIndex(item => item.type === 'group' && item.id === firstGroupId)\n      const lastGroupIndex = flatItems.value.findIndex(item => item.type === 'group' && item.id === lastGroupId)\n      const stop = flatItems.value.findIndex((item, i) => i > lastGroupIndex && item.type === 'group' && item.depth === 0)\n      return flatItems.value.slice(start, stop === -1 ? undefined : stop)\n    })\n\n    return {\n      pageCount,\n      setItemsPerPage,\n      prevPage,\n      nextPage,\n      setPage,\n      paginatedItems: paginatedItemsWithGroups,\n    }\n  }\n\n  if (pageBy === 'any') {\n    const { flatItems } = group(sortedItems)\n    const { paginatedItems: paginatedItemsWithGroups, pageCount, setItemsPerPage, prevPage, nextPage, setPage } = paginate(flatItems)\n\n    return {\n      pageCount,\n      setItemsPerPage,\n      prevPage,\n      nextPage,\n      setPage,\n      paginatedItems: paginatedItemsWithGroups,\n    }\n  }\n\n  throw new Error(`Unrecognized pagination target ${pageBy}`)\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/composables/select.ts",
    "content": "// Composables\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { computed, inject, provide, shallowRef, toRef, toValue } from 'vue'\nimport { deepEqual, isPrimitive, propsFactory, wrapInArray } from '@/util'\n\n// Types\nimport type { InjectionKey, MaybeRefOrGetter, PropType, Ref } from 'vue'\nimport type { DataTableItemProps } from './items'\nimport type { EventProp, ValueComparator } from '@/util'\n\nexport interface SelectableItem {\n  value: any\n  selectable: boolean\n}\n\nexport interface DataTableSelectStrategy {\n  showSelectAll: boolean\n  allSelected: (data: {\n    allItems: SelectableItem[]\n    currentPage: SelectableItem[]\n  }) => SelectableItem[]\n  select: (data: {\n    items: SelectableItem[]\n    value: boolean\n    selected: Set<unknown>\n  }) => Set<unknown>\n  selectAll: (data: {\n    value: boolean\n    allItems: SelectableItem[]\n    currentPage: SelectableItem[]\n    selected: Set<unknown>\n  }) => Set<unknown>\n}\n\ntype SelectionProps = Pick<DataTableItemProps, 'itemValue'> & {\n  modelValue: readonly any[]\n  selectStrategy: 'single' | 'page' | 'all'\n  valueComparator?: ValueComparator\n  'onUpdate:modelValue': EventProp<[any[]]> | undefined\n}\n\nconst singleSelectStrategy: DataTableSelectStrategy = {\n  showSelectAll: false,\n  allSelected: () => [],\n  select: ({ items, value }) => {\n    return new Set(value ? [items[0]?.value] : [])\n  },\n  selectAll: ({ selected }) => selected,\n}\n\nconst pageSelectStrategy: DataTableSelectStrategy = {\n  showSelectAll: true,\n  allSelected: ({ currentPage }) => currentPage,\n  select: ({ items, value, selected }) => {\n    for (const item of items) {\n      if (value) selected.add(item.value)\n      else selected.delete(item.value)\n    }\n\n    return selected\n  },\n  selectAll: ({ value, currentPage, selected }) => pageSelectStrategy.select({ items: currentPage, value, selected }),\n}\n\nconst allSelectStrategy: DataTableSelectStrategy = {\n  showSelectAll: true,\n  allSelected: ({ allItems }) => allItems,\n  select: ({ items, value, selected }) => {\n    for (const item of items) {\n      if (value) selected.add(item.value)\n      else selected.delete(item.value)\n    }\n\n    return selected\n  },\n  selectAll: ({ value, allItems }) => {\n    return new Set(value ? allItems.map(item => item.value) : [])\n  },\n}\n\nexport const makeDataTableSelectProps = propsFactory({\n  showSelect: Boolean,\n  selectStrategy: {\n    type: [String, Object] as PropType<'single' | 'page' | 'all'>,\n    default: 'page',\n  },\n  modelValue: {\n    type: Array as PropType<readonly any[]>,\n    default: () => ([]),\n  },\n  valueComparator: Function as PropType<ValueComparator>,\n}, 'DataTable-select')\n\nexport const VDataTableSelectionSymbol: InjectionKey<ReturnType<typeof provideSelection>> = Symbol.for('vuetify:data-table-selection')\n\nexport function provideSelection (\n  props: SelectionProps,\n  { allItems, currentPage }: { allItems: Ref<SelectableItem[]>, currentPage: MaybeRefOrGetter<readonly SelectableItem[]> }\n) {\n  const selected = useProxiedModel(props, 'modelValue', props.modelValue, v => {\n    const customComparator = props.valueComparator\n    if (customComparator) {\n      return new Set(wrapInArray(v).map(v => {\n        return allItems.value.find(item => customComparator(v, item.value))?.value ?? v\n      }))\n    }\n    return new Set(wrapInArray(v).map(v => {\n      return isPrimitive(v)\n        ? allItems.value.find(item => v === item.value)?.value ?? v\n        : allItems.value.find(item => deepEqual(v, item.value))?.value ?? v\n    }))\n  }, v => {\n    return [...v.values()]\n  })\n\n  const allSelectable = computed(() => allItems.value.filter(item => item.selectable))\n  const currentPageSelectable = computed(() => toValue(currentPage).filter(item => item.selectable))\n\n  const selectStrategy = computed(() => {\n    if (typeof props.selectStrategy === 'object') return props.selectStrategy\n\n    switch (props.selectStrategy) {\n      case 'single': return singleSelectStrategy\n      case 'all': return allSelectStrategy\n      case 'page':\n      default: return pageSelectStrategy\n    }\n  })\n\n  const lastSelectedIndex = shallowRef<number | null>(null)\n\n  function isSelected (items: SelectableItem | SelectableItem[]) {\n    return wrapInArray(items).every(item => selected.value.has(item.value))\n  }\n\n  function isSomeSelected (items: SelectableItem | SelectableItem[]) {\n    return wrapInArray(items).some(item => selected.value.has(item.value))\n  }\n\n  function select (items: SelectableItem[], value: boolean) {\n    const newSelected = selectStrategy.value.select({\n      items,\n      value,\n      selected: new Set(selected.value),\n    })\n\n    selected.value = newSelected\n  }\n\n  function toggleSelect (item: SelectableItem, index?: number, event?: MouseEvent) {\n    const items = []\n    const pageItems = toValue(currentPage)\n    index = index ?? pageItems.findIndex(i => i.value === item.value)\n\n    if (props.selectStrategy !== 'single' && event?.shiftKey && lastSelectedIndex.value !== null) {\n      const [start, end] = [lastSelectedIndex.value, index].sort((a, b) => a - b)\n\n      items.push(...pageItems.slice(start, end + 1).filter(item => item.selectable))\n    } else {\n      items.push(item)\n      lastSelectedIndex.value = index\n    }\n\n    select(items, !isSelected([item]))\n  }\n\n  function selectAll (value: boolean) {\n    const newSelected = selectStrategy.value.selectAll({\n      value,\n      allItems: allSelectable.value,\n      currentPage: currentPageSelectable.value,\n      selected: new Set(selected.value),\n    })\n\n    selected.value = newSelected\n  }\n\n  const someSelected = computed(() => selected.value.size > 0)\n  const allSelected = computed(() => {\n    const items = selectStrategy.value.allSelected({\n      allItems: allSelectable.value,\n      currentPage: currentPageSelectable.value,\n    })\n    return !!items.length && isSelected(items)\n  })\n  const showSelectAll = toRef(() => selectStrategy.value.showSelectAll)\n\n  const data = {\n    toggleSelect,\n    select,\n    selectAll,\n    isSelected,\n    isSomeSelected,\n    someSelected,\n    allSelected,\n    showSelectAll,\n    lastSelectedIndex,\n    selectStrategy,\n  }\n\n  provide(VDataTableSelectionSymbol, data)\n\n  return data\n}\n\nexport function useSelection () {\n  const data = inject(VDataTableSelectionSymbol)\n\n  if (!data) throw new Error('Missing selection!')\n\n  return data\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/composables/sort.ts",
    "content": "// Composables\nimport { useLocale } from '@/composables/locale'\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { computed, inject, provide, toRef } from 'vue'\nimport { getObjectValueByPath, isEmpty, isObject, propsFactory } from '@/util'\n\n// Types\nimport type { InjectionKey, PropType, Ref } from 'vue'\nimport type { DataTableCompareFunction, InternalDataTableHeader } from '../types'\nimport type { InternalItem } from '@/composables/filter'\n\nexport const makeDataTableSortProps = propsFactory({\n  initialSortOrder: {\n    type: String as PropType<'asc' | 'desc'>,\n    default: 'asc',\n    validator: (v: any) => !v || ['asc', 'desc'].includes(v),\n  },\n  sortBy: {\n    type: Array as PropType<readonly SortItem[]>,\n    default: () => ([]),\n  },\n  customKeySort: Object as PropType<Record<string, DataTableCompareFunction>>,\n  multiSort: {\n    type: [Boolean, Object] as PropType<boolean | MultiSortProps>,\n    default: false,\n  },\n  mustSort: Boolean,\n}, 'DataTable-sort')\n\nconst VDataTableSortSymbol: InjectionKey<{\n  sortBy: Ref<readonly SortItem[]>\n  toggleSort: (column: InternalDataTableHeader, event?: KeyboardEvent | PointerEvent, mandatory?: boolean) => void\n  isSorted: (column: InternalDataTableHeader) => boolean\n}> = Symbol.for('vuetify:data-table-sort')\n\nexport type SortItem = { key: string, order?: boolean | 'asc' | 'desc' }\nexport type MultiSortProps = {\n  key?: 'ctrl'\n  mode?: MultiSortMode\n  modifier?: 'alt' | 'shift'\n}\n\nexport type MultiSortMode = 'append' | 'prepend'\n\ntype SortProps = {\n  initialSortOrder: 'asc' | 'desc'\n  sortBy: readonly SortItem[]\n  'onUpdate:sortBy': ((value: any) => void) | undefined\n  multiSort: boolean | MultiSortProps\n  mustSort: boolean\n}\n\nexport function createSort (props: SortProps) {\n  const initialSortOrder = toRef(() => props.initialSortOrder)\n  const sortBy = useProxiedModel(props, 'sortBy')\n  const mustSort = toRef(() => props.mustSort)\n  const multiSort = toRef(() => props.multiSort)\n  return { initialSortOrder, sortBy, multiSort, mustSort }\n}\n\nfunction resolveMultiSort (\n  multiSort: boolean | MultiSortProps,\n  event?: KeyboardEvent | PointerEvent\n): {\n    active: boolean\n    mode?: MultiSortMode\n  } {\n  if (!isObject(multiSort)) {\n    return { active: !!multiSort }\n  }\n\n  const { key, mode, modifier } = multiSort\n  const reverseMode = (modifier === 'alt' && event?.altKey) ||\n    (modifier === 'shift' && event?.shiftKey)\n\n  return {\n    active: !key || event?.ctrlKey || event?.metaKey || false,\n    mode: reverseMode ? (mode === 'append' ? 'prepend' : 'append') : mode,\n  }\n}\n\nexport function provideSort (options: {\n  initialSortOrder: Ref<'asc' | 'desc'>\n  sortBy: Ref<readonly SortItem[]>\n  multiSort: Ref<boolean | MultiSortProps>\n  mustSort: Ref<boolean>\n  page?: Ref<number>\n}) {\n  const { initialSortOrder, sortBy, mustSort, multiSort, page } = options\n\n  const toggleSort = (column: InternalDataTableHeader, event?: KeyboardEvent | PointerEvent, mandatory = false) => {\n    if (column.key == null) return\n\n    let newSortBy = sortBy.value.map(x => ({ ...x })) ?? []\n    const item = newSortBy.find(x => x.key === column.key)\n\n    const initialOrder = initialSortOrder.value\n    const secondaryOrder = initialSortOrder.value === 'desc' ? 'asc' : 'desc'\n    if (!item) {\n      const { active, mode } = resolveMultiSort(multiSort.value, event)\n      if (active) {\n        if (mode === 'prepend') {\n          newSortBy.unshift({ key: column.key, order: initialOrder })\n        } else {\n          newSortBy.push({ key: column.key, order: initialOrder })\n        }\n      } else {\n        newSortBy = [{ key: column.key, order: initialOrder }]\n      }\n    } else if (item.order === secondaryOrder) {\n      if (mandatory || (mustSort.value && newSortBy.length === 1)) {\n        item.order = initialSortOrder.value\n      } else {\n        newSortBy = newSortBy.filter(x => x.key !== column.key)\n      }\n    } else {\n      item.order = secondaryOrder\n    }\n\n    sortBy.value = newSortBy\n    if (page) page.value = 1\n  }\n\n  function isSorted (column: InternalDataTableHeader) {\n    return !!sortBy.value.find(item => item.key === column.key)\n  }\n\n  const data = { sortBy, toggleSort, isSorted }\n\n  provide(VDataTableSortSymbol, data)\n\n  return data\n}\n\nexport function useSort () {\n  const data = inject(VDataTableSortSymbol)\n\n  if (!data) throw new Error('Missing sort!')\n\n  return data\n}\n\n// TODO: abstract into project composable\nexport function useSortedItems<T extends InternalItem> (\n  props: {\n    customKeySort: Record<string, DataTableCompareFunction> | undefined\n  },\n  items: Ref<T[]>,\n  sortBy: Ref<readonly SortItem[]>,\n  options?: {\n    transform?: (item: T) => {}\n    sortFunctions?: Ref<Record<string, DataTableCompareFunction> | undefined>\n    sortRawFunctions?: Ref<Record<string, DataTableCompareFunction> | undefined>\n  },\n) {\n  const locale = useLocale()\n  const sortedItems = computed(() => {\n    if (!sortBy.value.length) return items.value\n\n    return sortItems(items.value, sortBy.value, locale.current.value, {\n      transform: options?.transform,\n      sortFunctions: {\n        ...props.customKeySort,\n        ...options?.sortFunctions?.value,\n      },\n      sortRawFunctions: options?.sortRawFunctions?.value,\n    })\n  })\n\n  return { sortedItems }\n}\n\nexport function sortItems<T extends InternalItem> (\n  items: T[],\n  sortByItems: readonly SortItem[],\n  locale: string,\n  options?: {\n    transform?: (item: T) => Record<string, any>\n    sortFunctions?: Record<string, DataTableCompareFunction>\n    sortRawFunctions?: Record<string, DataTableCompareFunction>\n  },\n): T[] {\n  const stringCollator = new Intl.Collator(locale, { sensitivity: 'accent', usage: 'sort' })\n\n  const transformedItems = items.map(item => (\n    [item, options?.transform ? options.transform(item) : item as never] as const)\n  )\n\n  return transformedItems.sort((a, b) => {\n    for (let i = 0; i < sortByItems.length; i++) {\n      let hasCustomResult = false\n      const sortKey = sortByItems[i].key\n      const sortOrder = sortByItems[i].order ?? 'asc'\n\n      if (sortOrder === false) continue\n\n      let sortA = getObjectValueByPath(a[1], sortKey)\n      let sortB = getObjectValueByPath(b[1], sortKey)\n      let sortARaw = a[0].raw\n      let sortBRaw = b[0].raw\n\n      if (sortOrder === 'desc') {\n        [sortA, sortB] = [sortB, sortA]\n        ;[sortARaw, sortBRaw] = [sortBRaw, sortARaw]\n      }\n\n      if (options?.sortRawFunctions?.[sortKey]) {\n        const customResult = options.sortRawFunctions[sortKey](sortARaw, sortBRaw)\n\n        if (customResult == null) continue\n        hasCustomResult = true\n        if (customResult) return customResult\n      }\n\n      if (options?.sortFunctions?.[sortKey]) {\n        const customResult = options.sortFunctions[sortKey](sortA, sortB)\n\n        if (customResult == null) continue\n        hasCustomResult = true\n        if (customResult) return customResult\n      }\n\n      if (hasCustomResult) continue\n\n      // Dates should be compared numerically\n      if (sortA instanceof Date && sortB instanceof Date) {\n        sortA = sortA.getTime()\n        sortB = sortB.getTime()\n      }\n\n      [sortA, sortB] = [sortA, sortB].map(s => s != null ? s.toString().toLocaleLowerCase() : s)\n\n      if (sortA !== sortB) {\n        if (isEmpty(sortA) && isEmpty(sortB)) return 0\n        if (isEmpty(sortA)) return -1\n        if (isEmpty(sortB)) return 1\n        if (!isNaN(sortA) && !isNaN(sortB)) return Number(sortA) - Number(sortB)\n        return stringCollator.compare(sortA, sortB)\n      }\n    }\n\n    return 0\n  }).map(([item]) => item)\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/index.ts",
    "content": "export { VDataTable } from './VDataTable'\nexport { VDataTableHeaders } from './VDataTableHeaders'\nexport { VDataTableFooter } from './VDataTableFooter'\nexport { VDataTableRows } from './VDataTableRows'\nexport { VDataTableRow } from './VDataTableRow'\nexport { VDataTableVirtual } from './VDataTableVirtual'\nexport { VDataTableServer } from './VDataTableServer'\n"
  },
  {
    "path": "packages/vuetify/src/components/VDataTable/types.ts",
    "content": "// Types\nimport type { provideExpanded } from './composables/expand'\nimport type { Group, GroupableItem, GroupSummary, provideGroupBy } from './composables/group'\nimport type { provideSelection, SelectableItem } from './composables/select'\nimport type { FilterFunction, InternalItem } from '@/composables/filter'\nimport type { SelectItemKey } from '@/util'\n\nexport type DataTableCompareFunction<T = any> = (a: T, b: T) => number | null\n\nexport type DataTableHeader<T = Record<string, any>> = {\n  key?: 'data-table-group' | 'data-table-select' | 'data-table-expand' | (string & {})\n  value?: SelectItemKey<T>\n  title?: string\n\n  fixed?: boolean | 'start' | 'end'\n  align?: 'start' | 'end' | 'center'\n\n  width?: number | string\n  minWidth?: number | string\n  maxWidth?: number | string\n  nowrap?: boolean\n  indent?: number\n\n  headerProps?: Record<string, any>\n  cellProps?: HeaderCellProps\n\n  sortable?: boolean\n  sort?: DataTableCompareFunction\n  sortRaw?: DataTableCompareFunction\n  filter?: FilterFunction\n\n  children?: DataTableHeader<T>[]\n}\n\nexport type InternalDataTableHeader = Omit<DataTableHeader, 'key' | 'value' | 'children'> & {\n  key: string | null\n  value: SelectItemKey | null\n  sortable: boolean\n  fixedOffset?: number\n  fixedEndOffset?: number\n  lastFixed?: boolean\n  firstFixedEnd?: boolean\n  nowrap?: boolean\n  colspan?: number\n  rowspan?: number\n  children?: InternalDataTableHeader[]\n}\n\nexport interface DataTableItem<T = any> extends Omit<InternalItem<T>, 'type'>, GroupableItem<T>, SelectableItem {\n  key: any\n  index: number\n  virtualIndex?: number\n  columns: {\n    [key: string]: any\n  }\n}\n\nexport type GroupHeaderSlot = {\n  index: number\n  item: Group\n  columns: InternalDataTableHeader[]\n  isExpanded: ReturnType<typeof provideExpanded>['isExpanded']\n  toggleExpand: ReturnType<typeof provideExpanded>['toggleExpand']\n  isSelected: ReturnType<typeof provideSelection>['isSelected']\n  toggleSelect: ReturnType<typeof provideSelection>['toggleSelect']\n  toggleGroup: ReturnType<typeof provideGroupBy>['toggleGroup']\n  isGroupOpen: ReturnType<typeof provideGroupBy>['isGroupOpen']\n}\n\nexport type GroupSummarySlot = {\n  index: number\n  item: GroupSummary\n  columns: InternalDataTableHeader[]\n  toggleGroup: ReturnType<typeof provideGroupBy>['toggleGroup']\n}\n\ntype ItemSlotBase<T> = {\n  index: number\n  item: T\n  internalItem: DataTableItem<T>\n  isExpanded: ReturnType<typeof provideExpanded>['isExpanded']\n  toggleExpand: ReturnType<typeof provideExpanded>['toggleExpand']\n  isSelected: ReturnType<typeof provideSelection>['isSelected']\n  toggleSelect: ReturnType<typeof provideSelection>['toggleSelect']\n}\n\nexport type ItemSlot<T> = ItemSlotBase<T> & {\n  columns: InternalDataTableHeader[]\n}\n\nexport type ItemKeySlot<T> = ItemSlotBase<T> & {\n  value: any\n  column: InternalDataTableHeader\n}\n\nexport type RowProps<T> = Record<string, any> | RowPropsFunction<T>\nexport type RowPropsFunction<T> = (\n  data: Pick<ItemKeySlot<T>, 'index' | 'item' | 'internalItem'>\n) => Record<string, any>\n\nexport type CellProps<T> = Record<string, any> | CellPropsFunction<T>\nexport type CellPropsFunction<T> = (\n  data: Pick<ItemKeySlot<T>, 'index' | 'item' | 'internalItem' | 'value' | 'column'>\n) => Record<string, any>\n\nexport type HeaderCellProps = Record<string, any> | HeaderCellPropsFunction\nexport type HeaderCellPropsFunction = (\n  data: Pick<ItemKeySlot<any>, 'index' | 'item' | 'internalItem' | 'value'>\n) => Record<string, any>\n"
  },
  {
    "path": "packages/vuetify/src/components/VDatePicker/VDatePicker.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-date-picker\n    overflow: hidden\n    width: $date-picker-width\n    --v-date-picker-landscape-header-width: #{$date-picker-landscape-header-width}\n\n    &--show-week\n      width: $date-picker-show-week-width\n\n    &.v-picker--landscape:has(.v-picker__header-wrapper)\n      width: calc(#{$date-picker-width} + var(--v-date-picker-landscape-header-width))\n\n      .v-picker__header-wrapper\n        width: var(--v-date-picker-landscape-header-width)\n\n        .v-date-picker-header\n          height: auto\n          padding-inline: 24px\n\n      &.v-picker--show-week\n        width: calc(#{$date-picker-show-week-width} + var(--v-date-picker-landscape-header-width))\n\n    > .v-picker__body\n      flex-direction: column"
  },
  {
    "path": "packages/vuetify/src/components/VDatePicker/VDatePicker.tsx",
    "content": "// Styles\nimport './VDatePicker.sass'\n\n// Components\nimport { makeVDatePickerControlsProps, VDatePickerControls } from './VDatePickerControls'\nimport { VDatePickerHeader } from './VDatePickerHeader'\nimport { makeVDatePickerMonthProps, VDatePickerMonth } from './VDatePickerMonth'\nimport { makeVDatePickerMonthsProps, VDatePickerMonths } from './VDatePickerMonths'\nimport { makeVDatePickerYearsProps, VDatePickerYears } from './VDatePickerYears'\nimport { VFadeTransition } from '@/components/transitions'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\nimport { makeVPickerProps, VPicker } from '@/labs/VPicker/VPicker'\n\n// Composables\nimport { useCalendarRange } from '@/composables/calendar'\nimport { useDate } from '@/composables/date'\nimport { daysDiff } from '@/composables/date/date'\nimport { useLocale, useRtl } from '@/composables/locale'\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { computed, shallowRef, toRef, watch } from 'vue'\nimport { convertToUnit, genericComponent, omit, propsFactory, useRender, wrapInArray } from '@/util'\n\n// Types\nimport type { VDatePickerControlsDefaultSlotProps } from './VDatePickerControls'\nimport type { VDatePickerHeaderSlots } from './VDatePickerHeader'\nimport type { VDatePickerMonthSlots } from './VDatePickerMonth'\nimport type { VDatePickerMonthsSlots } from './VDatePickerMonths'\nimport type { VDatePickerYearsSlots } from './VDatePickerYears'\nimport type { VPickerSlots } from '@/labs/VPicker/VPicker'\nimport type { GenericProps } from '@/util'\n\n// Types\nexport type VDatePickerSlots =\n  & Omit<VPickerSlots, 'header' | 'default'>\n  & Omit<VDatePickerHeaderSlots, 'default'>\n  & VDatePickerYearsSlots\n  & VDatePickerMonthsSlots\n  & VDatePickerMonthSlots\n  & {\n    header: {\n      header: string\n      transition: string\n    }\n    controls: VDatePickerControlsDefaultSlotProps\n  }\n\nexport const makeVDatePickerProps = propsFactory({\n  // TODO: implement in v3.5\n  // calendarIcon: {\n  //   type: String,\n  //   default: '$calendar',\n  // },\n  // keyboardIcon: {\n  //   type: String,\n  //   default: '$edit',\n  // },\n  // inputMode: {\n  //   type: String as PropType<'calendar' | 'keyboard'>,\n  //   default: 'calendar',\n  // },\n  // inputText: {\n  //   type: String,\n  //   default: '$vuetify.datePicker.input.placeholder',\n  // },\n  // inputPlaceholder: {\n  //   type: String,\n  //   default: 'dd/mm/yyyy',\n  // },\n  header: {\n    type: String,\n    default: '$vuetify.datePicker.header',\n  },\n  headerColor: String,\n  headerDateFormat: {\n    type: String,\n    default: 'normalDateWithWeekday',\n  },\n  landscapeHeaderWidth: [Number, String],\n\n  ...omit(makeVDatePickerControlsProps(), ['active', 'monthText', 'yearText']),\n  ...makeVDatePickerMonthProps({\n    weeksInMonth: 'static' as const,\n  }),\n  ...omit(makeVDatePickerMonthsProps(), ['modelValue']),\n  ...omit(makeVDatePickerYearsProps(), ['modelValue']),\n  ...makeVPickerProps({ title: '$vuetify.datePicker.title' }),\n\n  modelValue: null,\n}, 'VDatePicker')\n\nexport const VDatePicker = genericComponent<new <\n  T,\n  Multiple extends boolean | 'range' | number | (string & {}) = false,\n  TModel = Multiple extends true | number | string\n    ? T[]\n    : T,\n> (\n  props: {\n    modelValue?: TModel\n    'onUpdate:modelValue'?: (value: TModel) => void\n    multiple?: Multiple\n  },\n  slots: VDatePickerSlots\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VDatePicker',\n\n  props: makeVDatePickerProps(),\n\n  emits: {\n    'update:modelValue': (date: any) => true,\n    'update:month': (date: any) => true,\n    'update:year': (date: any) => true,\n    // 'update:inputMode': (date: any) => true,\n    'update:viewMode': (date: any) => true,\n  },\n\n  setup (props, { emit, slots }) {\n    const adapter = useDate()\n    const { t } = useLocale()\n    const { rtlClasses } = useRtl()\n\n    const model = useProxiedModel(\n      props,\n      'modelValue',\n      undefined,\n      v => wrapInArray(v).map(i => adapter.date(i)),\n      v => props.multiple ? v : v[0],\n    )\n\n    const viewMode = useProxiedModel(props, 'viewMode')\n    // const inputMode = useProxiedModel(props, 'inputMode')\n\n    const { minDate, maxDate, clampDate } = useCalendarRange(props)\n\n    const internal = computed(() => {\n      const today = adapter.date()\n      const value = model.value?.[0]\n        ? adapter.date(model.value[0])\n        : clampDate(today)\n\n      return value && adapter.isValid(value) ? value : today\n    })\n    const headerColor = toRef(() => props.headerColor ?? props.color)\n\n    const _month = useProxiedModel(props, 'month')\n    const month = computed({\n      get: () => Number(_month.value ?? adapter.getMonth(adapter.startOfMonth(internal.value))),\n      set: v => _month.value = v,\n    })\n\n    const _year = useProxiedModel(props, 'year')\n    const year = computed({\n      get: () => Number(_year.value ?? adapter.getYear(adapter.startOfYear(adapter.setMonth(internal.value, month.value)))),\n      set: v => _year.value = v,\n    })\n\n    const isReversing = shallowRef(false)\n    const header = computed(() => {\n      if (props.multiple === 'range' && model.value.length === 2) {\n        const [startDate, endDate] = model.value\n        const daysBetween = adapter.getDiff(endDate, startDate, 'days') + 1\n\n        return t('$vuetify.datePicker.itemsSelected', daysBetween)\n      }\n\n      if (props.multiple && model.value.length > 1) {\n        return t('$vuetify.datePicker.itemsSelected', model.value.length)\n      }\n\n      const formattedDate = (model.value[0] && adapter.isValid(model.value[0]))\n        ? adapter.format(adapter.date(model.value[0]), props.headerDateFormat)\n        : t(props.header)\n\n      return props.landscape && formattedDate.split(' ').length === 3\n        ? formattedDate.replace(' ', '\\n')\n        : formattedDate\n    })\n\n    const monthStart = toRef(() => {\n      let date = adapter.date()\n      date = adapter.setDate(date, 1)\n      date = adapter.setMonth(date, month.value)\n      date = adapter.setYear(date, year.value) // year is not always ISO\n      return date\n    })\n    const monthYearText = toRef(() => adapter.format(monthStart.value, 'monthAndYear'))\n    const monthText = toRef(() => adapter.format(monthStart.value, 'monthShort'))\n    const yearText = toRef(() => adapter.format(monthStart.value, 'year'))\n\n    // const headerIcon = toRef(() => props.inputMode === 'calendar' ? props.keyboardIcon : props.calendarIcon)\n    const headerTransition = toRef(() => `date-picker-header${isReversing.value ? '-reverse' : ''}-transition`)\n\n    const disabled = computed(() => {\n      if (props.disabled) return true\n\n      const targets = []\n\n      if (viewMode.value !== 'month') {\n        targets.push(...['prev-month', 'next-month', 'prev-year', 'next-year'])\n      } else {\n        let _date = adapter.date()\n\n        _date = adapter.startOfMonth(_date)\n        _date = adapter.setMonth(_date, month.value)\n        _date = adapter.setYear(_date, year.value)\n\n        if (minDate.value) {\n          const prevMonthEnd = adapter.addDays(adapter.startOfMonth(_date), -1)\n          const prevYearEnd = adapter.addDays(adapter.startOfYear(_date), -1)\n\n          adapter.isAfter(minDate.value, prevMonthEnd) && targets.push('prev-month')\n          adapter.isAfter(minDate.value, prevYearEnd) && targets.push('prev-year')\n        }\n\n        if (maxDate.value) {\n          const nextMonthStart = adapter.addDays(adapter.endOfMonth(_date), 1)\n          const nextYearStart = adapter.addDays(adapter.endOfYear(_date), 1)\n\n          adapter.isAfter(nextMonthStart, maxDate.value) && targets.push('next-month')\n          adapter.isAfter(nextYearStart, maxDate.value) && targets.push('next-year')\n        }\n      }\n\n      return targets\n    })\n\n    const allowedYears = computed(() => {\n      return props.allowedYears || isYearAllowed\n    })\n\n    const allowedMonths = computed(() => {\n      return props.allowedMonths || isMonthAllowed\n    })\n\n    function isAllowedInRange (start: unknown, end: unknown) {\n      const allowedDates = props.allowedDates\n      if (typeof allowedDates !== 'function') return true\n\n      const days = 1 + daysDiff(adapter, start, end)\n\n      for (let i = 0; i < days; i++) {\n        if (allowedDates(adapter.addDays(start, i))) return true\n      }\n      return false\n    }\n\n    function isYearAllowed (year: number) {\n      if (typeof props.allowedDates === 'function') {\n        const startOfYear = adapter.parseISO(`${year}-01-01`)\n        return isAllowedInRange(startOfYear, adapter.endOfYear(startOfYear))\n      }\n\n      if (Array.isArray(props.allowedDates) && props.allowedDates.length) {\n        for (const date of props.allowedDates) {\n          if (adapter.getYear(adapter.date(date)) === year) return true\n        }\n        return false\n      }\n\n      return true\n    }\n\n    function isMonthAllowed (month: number) {\n      if (typeof props.allowedDates === 'function') {\n        const monthTwoDigits = String(month + 1).padStart(2, '0')\n        const startOfMonth = adapter.parseISO(`${year.value}-${monthTwoDigits}-01`)\n        return isAllowedInRange(startOfMonth, adapter.endOfMonth(startOfMonth))\n      }\n\n      if (Array.isArray(props.allowedDates) && props.allowedDates.length) {\n        for (const date of props.allowedDates) {\n          if (\n            adapter.getYear(adapter.date(date)) === year.value &&\n            adapter.getMonth(adapter.date(date)) === month\n          ) return true\n        }\n        return false\n      }\n\n      return true\n    }\n\n    // function onClickAppend () {\n    //   inputMode.value = inputMode.value === 'calendar' ? 'keyboard' : 'calendar'\n    // }\n\n    function onClickNextMonth () {\n      if (month.value < 11) {\n        month.value++\n      } else {\n        year.value++\n        month.value = 0\n        onUpdateYear()\n      }\n      onUpdateMonth()\n    }\n\n    function onClickPrevMonth () {\n      if (month.value > 0) {\n        month.value--\n      } else {\n        year.value--\n        month.value = 11\n        onUpdateYear()\n      }\n      onUpdateMonth()\n    }\n\n    function onClickNextYear () {\n      year.value++\n      if (maxDate.value) {\n        const monthTwoDigits = String(month.value + 1).padStart(2, '0')\n        const monthStart = adapter.parseISO(`${year.value}-${monthTwoDigits}-01`)\n        if (adapter.isAfter(monthStart, maxDate.value)) {\n          month.value = adapter.getMonth(maxDate.value)\n        }\n      }\n      onUpdateYear()\n    }\n\n    function onClickPrevYear () {\n      year.value--\n      if (minDate.value) {\n        const monthTwoDigits = String(month.value + 1).padStart(2, '0')\n        const monthStart = adapter.endOfMonth(adapter.parseISO(`${year.value}-${monthTwoDigits}-01`))\n        if (adapter.isAfter(minDate.value, monthStart)) {\n          month.value = adapter.getMonth(minDate.value)\n        }\n      }\n      onUpdateYear()\n    }\n\n    function onClickDate () {\n      viewMode.value = 'month'\n    }\n\n    function onClickMonth () {\n      viewMode.value = viewMode.value === 'months' ? 'month' : 'months'\n    }\n\n    function onClickYear () {\n      viewMode.value = viewMode.value === 'year' ? 'month' : 'year'\n    }\n\n    function onUpdateMonth () {\n      if (viewMode.value === 'months') onClickMonth()\n    }\n\n    function onUpdateYear () {\n      if (viewMode.value === 'year') onClickYear()\n    }\n\n    watch(model, (val, oldVal) => {\n      const arrBefore = wrapInArray(oldVal)\n      const arrAfter = wrapInArray(val)\n\n      if (!arrAfter.length) return\n\n      const before = adapter.date(arrBefore[arrBefore.length - 1])\n      const after = adapter.date(arrAfter[arrAfter.length - 1])\n\n      if (adapter.isSameDay(before, after)) return\n\n      const newMonth = adapter.getMonth(after)\n      const newYear = adapter.getYear(after)\n\n      if (newMonth !== month.value) {\n        month.value = newMonth\n        onUpdateMonth()\n      }\n\n      if (newYear !== year.value) {\n        year.value = newYear\n        onUpdateYear()\n      }\n\n      isReversing.value = adapter.isBefore(before, after)\n    })\n\n    useRender(() => {\n      const pickerProps = VPicker.filterProps(props)\n      const datePickerControlsProps = omit(VDatePickerControls.filterProps(props), ['viewMode'])\n      const datePickerHeaderProps = VDatePickerHeader.filterProps(props)\n      const datePickerMonthProps = VDatePickerMonth.filterProps(props)\n      const datePickerMonthsProps = omit(VDatePickerMonths.filterProps(props), ['modelValue'])\n      const datePickerYearsProps = omit(VDatePickerYears.filterProps(props), ['modelValue'])\n\n      const headerProps = {\n        color: headerColor.value,\n        header: header.value,\n        transition: headerTransition.value,\n      }\n\n      return (\n        <VPicker\n          { ...pickerProps }\n          color={ headerColor.value }\n          class={[\n            'v-date-picker',\n            `v-date-picker--${viewMode.value}`,\n            {\n              'v-date-picker--show-week': props.showWeek,\n            },\n            rtlClasses.value,\n            props.class,\n          ]}\n          style={[\n            {\n              '--v-date-picker-landscape-header-width': convertToUnit(props.landscapeHeaderWidth),\n            },\n            props.style,\n          ]}\n          v-slots={{\n            title: () => slots.title?.() ?? (\n              <div class=\"v-date-picker__title\">\n                { t(props.title) }\n              </div>\n            ),\n            header: () => slots.header ? (\n              <VDefaultsProvider\n                defaults={{\n                  VDatePickerHeader: { ...headerProps },\n                }}\n              >\n                { slots.header?.(headerProps) }\n              </VDefaultsProvider>\n            ) : (\n              <VDatePickerHeader\n                key=\"header\"\n                { ...datePickerHeaderProps }\n                { ...headerProps }\n                onClick={ viewMode.value !== 'month' ? onClickDate : undefined }\n                v-slots={{\n                  prepend: slots.prepend,\n                  append: slots.append,\n                }}\n              />\n            ),\n            default: () => (\n              <>\n                <VDatePickerControls\n                  { ...datePickerControlsProps }\n                  disabled={ disabled.value }\n                  viewMode={ viewMode.value }\n                  text={ monthYearText.value }\n                  monthText={ monthText.value }\n                  yearText={ yearText.value }\n                  onClick:next={ onClickNextMonth }\n                  onClick:prev={ onClickPrevMonth }\n                  onClick:nextYear={ onClickNextYear }\n                  onClick:prevYear={ onClickPrevYear }\n                  onClick:month={ onClickMonth }\n                  onClick:year={ onClickYear }\n                  v-slots={{ default: slots.controls }}\n                />\n\n                <VFadeTransition hideOnLeave>\n                  { viewMode.value === 'months' ? (\n                    <VDatePickerMonths\n                      key=\"date-picker-months\"\n                      { ...datePickerMonthsProps }\n                      v-model={ month.value }\n                      min={ minDate.value }\n                      max={ maxDate.value }\n                      year={ year.value }\n                      allowedMonths={ allowedMonths.value }\n                      onUpdate:modelValue={ onUpdateMonth }\n                    >\n                      {{ month: slots.month }}\n                    </VDatePickerMonths>\n                  ) : viewMode.value === 'year' ? (\n                    <VDatePickerYears\n                      key=\"date-picker-years\"\n                      { ...datePickerYearsProps }\n                      v-model={ year.value }\n                      min={ minDate.value }\n                      max={ maxDate.value }\n                      allowedYears={ allowedYears.value }\n                      onUpdate:modelValue={ onUpdateYear }\n                    >\n                      {{ year: slots.year }}\n                    </VDatePickerYears>\n                  ) : (\n                    <VDatePickerMonth\n                      key=\"date-picker-month\"\n                      { ...datePickerMonthProps }\n                      v-model={ model.value }\n                      v-model:month={ month.value }\n                      v-model:year={ year.value }\n                      onUpdate:month={ onUpdateMonth }\n                      onUpdate:year={ onUpdateYear }\n                      min={ minDate.value }\n                      max={ maxDate.value }\n                    >\n                      {{ day: slots.day }}\n                    </VDatePickerMonth>\n                  )}\n                </VFadeTransition>\n              </>\n            ),\n            actions: slots.actions,\n          }}\n        />\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VDatePicker = InstanceType<typeof VDatePicker>\n"
  },
  {
    "path": "packages/vuetify/src/components/VDatePicker/VDatePickerControls.sass",
    "content": "@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-date-picker-controls\n    display: flex\n    align-items: center\n    justify-content: space-between\n    font-size: .875rem\n    height: $date-picker-controls-height\n    padding: $date-picker-controls-padding\n\n    .v-btn\n      text-transform: none\n      font-weight: 400\n      line-height: initial\n      letter-spacing: initial\n\n      > .v-btn__append > .v-icon\n        // matching VBtn for icon rotation\n        transition-property: transform\n        transition-duration: 0.28s\n        transition-timing-function: settings.$standard-easing\n\n    .v-date-picker--months &\n      .v-date-picker-controls__only-month-btn\n        > .v-btn__append > .v-icon\n          transform: rotate(180deg)\n\n    .v-date-picker--year &\n      .v-date-picker-controls__mode-btn\n        transform: rotate(180deg)\n      .v-date-picker-controls__year-btn,\n      .v-date-picker-controls__only-year-btn\n        > .v-btn__append > .v-icon\n          transform: rotate(180deg)\n\n    &__date\n      margin-inline-end: 4px\n\n    &__month,\n    &__year\n      display: flex\n\n      @include tools.rtl()\n        flex-direction: row-reverse\n\n    & &__month-btn,\n    & &__year-btn\n      padding: 0 12px\n\n    & &__only-month-btn,\n    & &__only-year-btn\n      padding-inline: $date-picker-controls-docked-toggle-btn-padding\n\n      // just lower than default\n      min-width: 40px\n\n      > .v-btn__append\n        margin-inline: $date-picker-controls-docked-toggle-append-margin-inline\n\n  .v-date-picker__title\n    display: inline-block\n"
  },
  {
    "path": "packages/vuetify/src/components/VDatePicker/VDatePickerControls.tsx",
    "content": "// Styles\nimport './VDatePickerControls.sass'\n\n// Components\nimport { VBtn } from '@/components/VBtn'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\nimport { VSpacer } from '@/components/VGrid'\n\n// Composables\nimport { IconValue } from '@/composables/icons'\nimport { useLocale } from '@/composables/locale'\n\n// Utilities\nimport { computed } from 'vue'\nimport { convertToUnit, genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\ntype ControlVariant = 'docked' | 'modal'\n\nexport type VDatePickerControlsDefaultSlotProps = {\n  viewMode: 'month' | 'months' | 'year'\n  monthYearText: string\n  monthText: string\n  yearText: string\n  disabled: string[]\n  openMonths: () => void\n  openYears: () => void\n  prevMonth: () => void\n  nextMonth: () => void\n  prevYear: () => void\n  nextYear: () => void\n}\n\ntype VDatePickerControlsSlots = {\n  default: VDatePickerControlsDefaultSlotProps\n}\n\nexport const makeVDatePickerControlsProps = propsFactory({\n  active: {\n    type: [String, Array] as PropType<string | string[]>,\n    default: undefined,\n  },\n  controlHeight: [Number, String],\n  controlVariant: {\n    type: String as PropType<ControlVariant>,\n    default: 'docked',\n  },\n  noMonthPicker: Boolean,\n  disabled: {\n    type: [Boolean, String, Array] as PropType<boolean | string | string[] | null>,\n    default: null,\n  },\n  nextIcon: {\n    type: IconValue,\n    default: '$next',\n  },\n  prevIcon: {\n    type: IconValue,\n    default: '$prev',\n  },\n  modeIcon: {\n    type: IconValue,\n    default: '$subgroup',\n  },\n  text: String,\n  monthText: String,\n  yearText: String,\n  viewMode: {\n    type: String as PropType<'month' | 'months' | 'year'>,\n    default: 'month',\n  },\n}, 'VDatePickerControls')\n\nexport const VDatePickerControls = genericComponent<VDatePickerControlsSlots>()({\n  name: 'VDatePickerControls',\n\n  props: makeVDatePickerControlsProps(),\n\n  emits: {\n    'click:year': () => true,\n    'click:month': () => true,\n    'click:prev': () => true,\n    'click:next': () => true,\n    'click:prev-year': () => true,\n    'click:next-year': () => true,\n  },\n\n  setup (props, { emit, slots }) {\n    const { t } = useLocale()\n\n    const disableMonth = computed(() => {\n      return Array.isArray(props.disabled)\n        ? props.disabled.includes('text')\n        : !!props.disabled\n    })\n    const disableYear = computed(() => {\n      return Array.isArray(props.disabled)\n        ? props.disabled.includes('mode')\n        : !!props.disabled\n    })\n    const disablePrevMonth = computed(() => {\n      return Array.isArray(props.disabled)\n        ? props.disabled.includes('prev-month')\n        : !!props.disabled\n    })\n    const disableNextMonth = computed(() => {\n      return Array.isArray(props.disabled)\n        ? props.disabled.includes('next-month')\n        : !!props.disabled\n    })\n    const disablePrevYear = computed(() => {\n      return Array.isArray(props.disabled)\n        ? props.disabled.includes('prev-year')\n        : !!props.disabled\n    })\n    const disableNextYear = computed(() => {\n      return Array.isArray(props.disabled)\n        ? props.disabled.includes('next-year')\n        : !!props.disabled\n    })\n\n    function onClickPrevMonth () {\n      emit('click:prev')\n    }\n\n    function onClickNextMonth () {\n      emit('click:next')\n    }\n\n    function onClickPrevYear () {\n      emit('click:prev-year')\n    }\n\n    function onClickNextYear () {\n      emit('click:next-year')\n    }\n\n    function onClickYear () {\n      emit('click:year')\n    }\n\n    function onClickMonth () {\n      emit('click:month')\n    }\n\n    useRender(() => {\n      const innerDefaults = {\n        VBtn: {\n          density: 'comfortable',\n          variant: 'text',\n        },\n      }\n\n      const prevMonth = (\n        <VBtn\n          data-testid=\"prev-month\"\n          disabled={ disablePrevMonth.value }\n          icon={ props.prevIcon }\n          aria-label={ t('$vuetify.datePicker.ariaLabel.previousMonth') }\n          onClick={ onClickPrevMonth }\n        />\n      )\n\n      const nextMonth = (\n        <VBtn\n          data-testid=\"next-month\"\n          disabled={ disableNextMonth.value }\n          icon={ props.nextIcon }\n          aria-label={ t('$vuetify.datePicker.ariaLabel.nextMonth') }\n          onClick={ onClickNextMonth }\n        />\n      )\n\n      const prevYear = (\n        <VBtn\n          data-testid=\"prev-year\"\n          disabled={ disablePrevYear.value }\n          icon={ props.prevIcon }\n          aria-label={ t('$vuetify.datePicker.ariaLabel.previousYear') }\n          onClick={ onClickPrevYear }\n        />\n      )\n\n      const nextYear = (\n        <VBtn\n          data-testid=\"next-year\"\n          disabled={ disableNextYear.value }\n          icon={ props.nextIcon }\n          aria-label={ t('$vuetify.datePicker.ariaLabel.nextYear') }\n          onClick={ onClickNextYear }\n        />\n      )\n\n      const onlyMonthBtn = (\n        <VBtn\n          class=\"v-date-picker-controls__only-month-btn\"\n          data-testid=\"month-btn\"\n          density=\"default\"\n          disabled={ disableMonth.value }\n          text={ props.monthText }\n          appendIcon={ props.modeIcon }\n          rounded\n          aria-label={ t('$vuetify.datePicker.ariaLabel.selectMonth') }\n          onClick={ onClickMonth }\n        />\n      )\n\n      const onlyYearBtn = (\n        <VBtn\n          class=\"v-date-picker-controls__only-year-btn\"\n          data-testid=\"year-btn\"\n          density=\"default\"\n          disabled={ disableYear.value }\n          text={ props.yearText }\n          appendIcon={ props.modeIcon }\n          rounded\n          aria-label={ t('$vuetify.datePicker.ariaLabel.selectYear') }\n          onClick={ onClickYear }\n        />\n      )\n\n      const monthYearBtn = (\n        <VBtn\n          class=\"v-date-picker-controls__year-btn\"\n          data-testid=\"year-btn\"\n          density=\"default\"\n          disabled={ disableYear.value }\n          text={ props.text }\n          appendIcon={ props.modeIcon }\n          rounded\n          aria-label={ t('$vuetify.datePicker.ariaLabel.selectYear') }\n          onClick={ onClickYear }\n        />\n      )\n\n      const monthYearSplit = (\n        <>\n          <VBtn\n            class=\"v-date-picker-controls__month-btn\"\n            data-testid=\"month-btn\"\n            height=\"36\"\n            disabled={ disableMonth.value }\n            text={ props.text }\n            rounded\n            aria-label={ t('$vuetify.datePicker.ariaLabel.selectMonth') }\n            onClick={ onClickMonth }\n          />\n          <VBtn\n            class=\"v-date-picker-controls__mode-btn\"\n            data-testid=\"year-btn\"\n            disabled={ disableYear.value }\n            icon={ props.modeIcon }\n            aria-label={ t('$vuetify.datePicker.ariaLabel.selectYear') }\n            onClick={ onClickYear }\n          />\n        </>\n      )\n\n      const slotProps: VDatePickerControlsDefaultSlotProps = {\n        viewMode: props.viewMode,\n        disabled: Array.isArray(props.disabled) ? props.disabled : [],\n        monthYearText: props.text ?? '',\n        monthText: props.monthText ?? '',\n        yearText: props.yearText ?? '',\n        openMonths: onClickMonth,\n        openYears: onClickYear,\n        prevMonth: onClickPrevMonth,\n        nextMonth: onClickNextMonth,\n        prevYear: onClickPrevYear,\n        nextYear: onClickNextYear,\n      }\n\n      const modalControls = (\n        <>\n          { props.noMonthPicker ? monthYearBtn : monthYearSplit }\n\n          <VSpacer />\n\n          <div class=\"v-date-picker-controls__month\">\n            { prevMonth }\n            { nextMonth }\n          </div>\n        </>\n      )\n\n      const dockedControls = (\n        <>\n          <div class=\"v-date-picker-controls__month\">\n            { prevMonth }\n            { onlyMonthBtn }\n            { nextMonth }\n          </div>\n\n          <VSpacer />\n\n          <div class=\"v-date-picker-controls__year\">\n            { prevYear }\n            { onlyYearBtn }\n            { nextYear }\n          </div>\n        </>\n      )\n\n      return (\n        <VDefaultsProvider defaults={ innerDefaults }>\n          <div\n            class={[\n              'v-date-picker-controls',\n              `v-date-picker-controls--variant-${props.controlVariant}`,\n            ]}\n            style={{\n              '--v-date-picker-controls-height': convertToUnit(props.controlHeight),\n            }}\n          >\n            { slots.default?.(slotProps) ?? (\n              <>\n                { props.controlVariant === 'modal' && modalControls }\n                { props.controlVariant === 'docked' && dockedControls }\n              </>\n            )}\n          </div>\n        </VDefaultsProvider>\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VDatePickerControls = InstanceType<typeof VDatePickerControls>\n"
  },
  {
    "path": "packages/vuetify/src/components/VDatePicker/VDatePickerHeader.sass",
    "content": "@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-date-picker-header\n    align-items: flex-end\n    height: $date-picker-header-height\n    display: grid\n    grid-template-areas: \"prepend content append\"\n    grid-template-columns: min-content minmax(0, 1fr) min-content\n    overflow: hidden\n    padding-inline: 24px 12px\n    padding-bottom: 12px\n\n  .v-date-picker-header__append\n    grid-area: append\n\n  .v-date-picker-header__prepend\n    grid-area: prepend\n    padding-inline-start: 8px\n\n  .v-date-picker-header__content\n    align-items: center\n    display: inline-flex\n    font-size: 32px\n    line-height: 40px\n    grid-area: content\n    justify-content: space-between\n    white-space: pre-wrap\n\n    .v-date-picker-header--clickable &\n      cursor: pointer\n\n      &:not(:hover)\n        opacity: .7\n\n  .date-picker-header-transition,\n  .date-picker-header-reverse-transition\n    &-enter-active\n      transition-duration: 0.3s\n      transition-timing-function: settings.$standard-easing\n\n    &-leave-active\n      transition-duration: 0.3s\n      transition-timing-function: settings.$standard-easing\n\n  .date-picker-header-transition\n    &-enter-from\n      transform: translate(0, 100%)\n\n    &-leave-to\n      opacity: 0\n      transform: translate(0, -100%)\n\n  .date-picker-header-reverse-transition\n    &-enter-from\n      transform: translate(0, -100%)\n\n    &-leave-to\n      opacity: 0\n      transform: translate(0, 100%)\n"
  },
  {
    "path": "packages/vuetify/src/components/VDatePicker/VDatePickerHeader.tsx",
    "content": "// Styles\nimport './VDatePickerHeader.sass'\n\n// Components\nimport { VBtn } from '@/components/VBtn'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\n\n// Composables\nimport { useBackgroundColor } from '@/composables/color'\nimport { IconValue } from '@/composables/icons'\nimport { MaybeTransition } from '@/composables/transition'\n\n// Utilities\nimport { EventProp, genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nexport type VDatePickerHeaderSlots = {\n  prepend: never\n  default: never\n  append: never\n}\n\nexport const makeVDatePickerHeaderProps = propsFactory({\n  appendIcon: IconValue,\n  color: String,\n  header: String,\n  transition: String,\n  onClick: EventProp<[MouseEvent]>(),\n}, 'VDatePickerHeader')\n\nexport const VDatePickerHeader = genericComponent<VDatePickerHeaderSlots>()({\n  name: 'VDatePickerHeader',\n\n  props: makeVDatePickerHeaderProps(),\n\n  emits: {\n    click: () => true,\n    'click:append': () => true,\n  },\n\n  setup (props, { emit, slots }) {\n    const { backgroundColorClasses, backgroundColorStyles } = useBackgroundColor(() => props.color)\n\n    function onClick () {\n      emit('click')\n    }\n\n    function onClickAppend () {\n      emit('click:append')\n    }\n\n    useRender(() => {\n      const hasContent = !!(slots.default || props.header)\n      const hasAppend = !!(slots.append || props.appendIcon)\n\n      return (\n        <div\n          class={[\n            'v-date-picker-header',\n            {\n              'v-date-picker-header--clickable': !!props.onClick,\n            },\n            backgroundColorClasses.value,\n          ]}\n          style={ backgroundColorStyles.value }\n          onClick={ onClick }\n        >\n          { slots.prepend && (\n            <div key=\"prepend\" class=\"v-date-picker-header__prepend\">\n              { slots.prepend() }\n            </div>\n          )}\n\n          { hasContent && (\n            <MaybeTransition key=\"content\" name={ props.transition }>\n              <div key={ props.header } class=\"v-date-picker-header__content\">\n                { slots.default?.() ?? props.header }\n              </div>\n            </MaybeTransition>\n          )}\n\n          { hasAppend && (\n            <div class=\"v-date-picker-header__append\">\n              { !slots.append ? (\n                <VBtn\n                  key=\"append-btn\"\n                  icon={ props.appendIcon }\n                  variant=\"text\"\n                  onClick={ onClickAppend }\n                />\n              ) : (\n                <VDefaultsProvider\n                  key=\"append-defaults\"\n                  disabled={ !props.appendIcon }\n                  defaults={{\n                    VBtn: {\n                      icon: props.appendIcon,\n                      variant: 'text',\n                    },\n                  }}\n                >\n                  { slots.append?.() }\n                </VDefaultsProvider>\n              )}\n            </div>\n          )}\n        </div>\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VDatePickerHeader = InstanceType<typeof VDatePickerHeader>\n"
  },
  {
    "path": "packages/vuetify/src/components/VDatePicker/VDatePickerMonth.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-date-picker-month\n    display: flex\n    justify-content: center\n    padding: $date-picker-month-padding\n\n    --v-date-picker-month-day-diff: 4px\n\n  .v-date-picker-month__weeks\n    display: flex\n    flex-direction: column\n    column-gap: $date-picker-month-column-gap\n    font-size: $date-picker-month-font-size\n\n  .v-date-picker-month__weekday\n    font-size: $date-picker-month-font-size\n\n  .v-date-picker-month__days\n    display: grid\n    grid-template-columns: repeat(var(--v-date-picker-days-in-week), min-content)\n    column-gap: $date-picker-month-column-gap\n    justify-content: space-around\n    width: 100%\n\n  .v-date-picker-month__day\n    align-items: center\n    display: flex\n    justify-content: center\n    position: relative\n    height: $date-picker-month-day-size\n    width: $date-picker-month-day-size\n\n    &--selected\n      .v-btn\n        background-color: rgb(var(--v-theme-surface-variant))\n        color: rgb(var(--v-theme-on-surface-variant))\n\n    .v-btn.v-date-picker-month__day-btn\n      --v-btn-height: #{$date-picker-month-btn-height}\n      --v-btn-size: #{$date-picker-month-btn-size}\n\n    &--week\n      font-size: var(--v-btn-size)\n\n  .v-date-picker-month__day--adjacent\n    opacity: 0.5\n\n  .v-date-picker-month__day--hide-adjacent\n    opacity: 0\n  .v-date-picker-month__events\n    height: $date-picker-event-size\n    left: 0\n    text-indent: 0\n    position: absolute\n    text-align: center\n    white-space: pre\n    width: 100%\n\n    > div\n      height: $date-picker-event-size\n      margin: $date-picker-event-margin\n      width: $date-picker-event-size\n      margin-bottom: -1px\n\n    .v-badge--dot .v-badge__badge\n      border-radius: $date-picker-event-border-radius\n      height: $date-picker-event-size\n      width: $date-picker-event-size\n\n  .v-date-picker-month__day .v-date-picker-month__events\n    bottom: $date-picker-event-date-bottom\n"
  },
  {
    "path": "packages/vuetify/src/components/VDatePicker/VDatePickerMonth.tsx",
    "content": "// Styles\nimport './VDatePickerMonth.sass'\n\n// Components\nimport { VBadge } from '@/components/VBadge'\nimport { VBtn } from '@/components/VBtn'\n\n// Composables\nimport { makeCalendarProps, useCalendar } from '@/composables/calendar'\nimport { useDate } from '@/composables/date/date'\nimport { useLocale } from '@/composables/locale'\nimport { MaybeTransition } from '@/composables/transition'\n\n// Utilities\nimport { computed, ref, shallowRef, toRef, watch } from 'vue'\nimport { genericComponent, omit, propsFactory, useRender, wrapInArray } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { GenericProps } from '@/util'\n\nexport type DatePickerEventColorValue = boolean | string | string[]\n\nexport type DatePickerEventColors = DatePickerEventColorValue |\nRecord<string, DatePickerEventColorValue> | ((date: string) => DatePickerEventColorValue)\n\nexport type DatePickerEvents = string[] |\n((date: string) => DatePickerEventColorValue) | Record<string, DatePickerEventColorValue>\n\nexport type VDatePickerMonthSlots = {\n  day: {\n    props: {\n      onClick: () => void\n    }\n    item: any\n    i: number\n  }\n}\n\nexport const makeVDatePickerMonthProps = propsFactory({\n  color: String,\n  hideWeekdays: Boolean,\n  multiple: [Boolean, Number, String] as PropType<boolean | 'range' | number | (string & {})>,\n  showWeek: Boolean,\n  readonly: Boolean,\n  transition: {\n    type: String,\n    default: 'picker-transition',\n  },\n  reverseTransition: {\n    type: String,\n    default: 'picker-reverse-transition',\n  },\n  events: {\n    type: [Array, Function, Object] as PropType<DatePickerEvents | null>,\n    default: () => null,\n  },\n  eventColor: {\n    type: [Array, Function, Object, String] as PropType<DatePickerEventColors>,\n    default: () => null,\n  },\n  ...omit(makeCalendarProps(), ['displayValue']),\n}, 'VDatePickerMonth')\n\nexport const VDatePickerMonth = genericComponent<new <TModel>(\n  props: {\n    modelValue?: TModel\n    'onUpdate:modelValue'?: (value: TModel) => void\n  },\n  slots: VDatePickerMonthSlots\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VDatePickerMonth',\n\n  props: makeVDatePickerMonthProps(),\n\n  emits: {\n    'update:modelValue': (date: unknown) => true,\n    'update:month': (date: number) => true,\n    'update:year': (date: number) => true,\n  },\n\n  setup (props, { emit, slots }) {\n    const daysRef = ref()\n    const { t } = useLocale()\n\n    const { daysInMonth, model, weekNumbers, weekdayLabels } = useCalendar(props)\n    const adapter = useDate()\n\n    const rangeStart = shallowRef()\n    const rangeStop = shallowRef()\n    const isReverse = shallowRef(false)\n\n    const transition = toRef(() => {\n      return !isReverse.value ? props.transition : props.reverseTransition\n    })\n\n    if (props.multiple === 'range' && model.value.length > 0) {\n      rangeStart.value = model.value[0]\n      if (model.value.length > 1) {\n        rangeStop.value = model.value[model.value.length - 1]\n      }\n    }\n\n    const atMax = computed(() => {\n      const max = ['number', 'string'].includes(typeof props.multiple) ? Number(props.multiple) : Infinity\n\n      return model.value.length >= max\n    })\n\n    watch(daysInMonth, (val, oldVal) => {\n      if (!oldVal) return\n\n      isReverse.value = adapter.isBefore(val[0].date, oldVal[0].date)\n    })\n\n    function onRangeClick (value: unknown) {\n      const _value = adapter.startOfDay(value)\n\n      if (model.value.length === 0) {\n        rangeStart.value = undefined\n      } else if (model.value.length === 1) {\n        rangeStart.value = model.value[0]\n        rangeStop.value = undefined\n      }\n\n      if (!rangeStart.value) {\n        rangeStart.value = _value\n        model.value = [rangeStart.value]\n      } else if (!rangeStop.value) {\n        if (adapter.isSameDay(_value, rangeStart.value)) {\n          rangeStart.value = undefined\n          model.value = []\n          return\n        } else if (adapter.isBefore(_value, rangeStart.value)) {\n          rangeStop.value = adapter.endOfDay(rangeStart.value)\n          rangeStart.value = _value\n        } else {\n          rangeStop.value = adapter.endOfDay(_value)\n        }\n\n        model.value = [rangeStart.value, rangeStop.value]\n      } else {\n        rangeStart.value = value\n        rangeStop.value = undefined\n        model.value = [rangeStart.value]\n      }\n    }\n\n    function getDateAriaLabel (item: any) {\n      const fullDate = adapter.format(item.date, 'fullDateWithWeekday')\n      const localeKey = item.isToday ? 'currentDate' : 'selectDate'\n      return t(`$vuetify.datePicker.ariaLabel.${localeKey}`, fullDate)\n    }\n\n    function onMultipleClick (value: unknown) {\n      const index = model.value.findIndex(selection => adapter.isSameDay(selection, value))\n\n      if (index === -1) {\n        model.value = [...model.value, value]\n      } else {\n        const value = [...model.value]\n        value.splice(index, 1)\n        model.value = value\n      }\n    }\n\n    function onClick (value: unknown) {\n      if (props.multiple === 'range') {\n        onRangeClick(value)\n      } else if (props.multiple) {\n        onMultipleClick(value)\n      } else {\n        model.value = [value]\n      }\n    }\n    function getEventColors (date: string): string[] {\n      const { events, eventColor } = props\n      let eventData: boolean | DatePickerEventColorValue\n      let eventColors: (boolean | string)[] = []\n\n      if (Array.isArray(events)) {\n        eventData = events.includes(date)\n      } else if (events instanceof Function) {\n        eventData = events(date) || false\n      } else if (events) {\n        eventData = events[date] || false\n      } else {\n        eventData = false\n      }\n\n      if (!eventData) {\n        return []\n      } else if (eventData !== true) {\n        eventColors = wrapInArray(eventData)\n      } else if (typeof eventColor === 'string') {\n        eventColors = [eventColor]\n      } else if (typeof eventColor === 'function') {\n        eventColors = wrapInArray(eventColor(date))\n      } else if (Array.isArray(eventColor)) {\n        eventColors = eventColor\n      } else if (typeof eventColor === 'object' && eventColor !== null) {\n        eventColors = wrapInArray(eventColor[date])\n      }\n\n      // Fallback to default color if no color is found\n      return !eventColors.length\n        ? ['surface-variant']\n        : eventColors\n          .filter(Boolean)\n          .map((color: string | boolean) => typeof color === 'string' ? color : 'surface-variant')\n    }\n\n    function genEvents (date: string): JSX.Element | null {\n      const eventColors = getEventColors(date)\n\n      if (!eventColors.length) return null\n\n      return (\n        <div class=\"v-date-picker-month__events\">\n          { eventColors.map((color: string) => <VBadge dot color={ color } />) }\n        </div>\n      )\n    }\n    useRender(() => (\n      <div\n        class=\"v-date-picker-month\"\n        style={{ '--v-date-picker-days-in-week': props.weekdays.length }}\n      >\n        { props.showWeek && (\n          <div key=\"weeks\" class=\"v-date-picker-month__weeks\">\n            { !props.hideWeekdays && (\n              <div key=\"hide-week-days\" class=\"v-date-picker-month__day\">&nbsp;</div>\n            )}\n            { weekNumbers.value.map(week => (\n              <div\n                class={[\n                  'v-date-picker-month__day',\n                  'v-date-picker-month__day--adjacent',\n                ]}\n              >{ week }</div>\n            ))}\n          </div>\n        )}\n\n        <MaybeTransition name={ transition.value }>\n          <div\n            ref={ daysRef }\n            key={ daysInMonth.value[0].date?.toString() }\n            class=\"v-date-picker-month__days\"\n          >\n            { !props.hideWeekdays && weekdayLabels.value.map(weekDay => (\n              <div\n                class={[\n                  'v-date-picker-month__day',\n                  'v-date-picker-month__weekday',\n                ]}\n              >{ weekDay }</div>\n            ))}\n\n            { daysInMonth.value.map((item, i) => {\n              const slotProps = {\n                props: {\n                  class: 'v-date-picker-month__day-btn',\n                  color: item.isSelected || item.isToday ? props.color : undefined,\n                  disabled: item.isDisabled,\n                  readonly: props.readonly,\n                  icon: true,\n                  ripple: false,\n                  variant: item.isSelected ? 'flat' : item.isToday ? 'outlined' : 'text',\n                  'aria-label': getDateAriaLabel(item),\n                  'aria-current': item.isToday ? 'date' : undefined,\n                  onClick: () => onClick(item.date),\n                },\n                item,\n                i,\n              } as const\n\n              const isSelected = props.multiple === 'range' && model.value.length === 2\n                ? adapter.isWithinRange(item.date, model.value as [Date, Date])\n                : model.value.some(selectedDate => adapter.isSameDay(selectedDate, item.date))\n\n              if (atMax.value && !isSelected) {\n                item.isDisabled = true\n              }\n\n              return (\n                <div\n                  class={[\n                    'v-date-picker-month__day',\n                    {\n                      'v-date-picker-month__day--adjacent': item.isAdjacent,\n                      'v-date-picker-month__day--hide-adjacent': item.isHidden,\n                      'v-date-picker-month__day--selected': isSelected,\n                      'v-date-picker-month__day--week-end': item.isWeekEnd,\n                      'v-date-picker-month__day--week-start': item.isWeekStart,\n                    },\n                  ]}\n                  data-v-date={ !item.isDisabled ? item.isoDate : undefined }\n                >\n                  { (props.showAdjacentMonths || !item.isAdjacent) && (\n                    slots.day?.(slotProps) ?? (\n                      <VBtn { ...slotProps.props }>\n                        { item.localized }\n                        { genEvents(item.isoDate) }\n                      </VBtn>\n                    )\n                  )}\n                </div>\n              )\n            })}\n          </div>\n        </MaybeTransition>\n      </div>\n    ))\n  },\n})\n\nexport type VDatePickerMonth = InstanceType<typeof VDatePickerMonth>\n"
  },
  {
    "path": "packages/vuetify/src/components/VDatePicker/VDatePickerMonths.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-date-picker-months\n    height: $date-picker-months-height\n\n  .v-date-picker-months__content\n    align-items: center\n    display: grid\n    flex: 1 1\n    height: inherit\n    justify-content: space-around\n    grid-template-columns: repeat(2, 1fr)\n    grid-gap: $date-picker-months-grid-gap\n    padding-inline-start: 36px\n    padding-inline-end: 36px\n\n    .v-btn\n      text-transform: none\n      padding-inline-start: 8px\n      padding-inline-end: 8px\n"
  },
  {
    "path": "packages/vuetify/src/components/VDatePicker/VDatePickerMonths.tsx",
    "content": "// Styles\nimport './VDatePickerMonths.sass'\n\n// Components\nimport { VBtn } from '@/components/VBtn'\n\n// Composables\nimport { useDate } from '@/composables/date'\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { computed, watchEffect } from 'vue'\nimport { convertToUnit, createRange, genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\nexport type VDatePickerMonthsSlots = {\n  month: {\n    month: {\n      text: string\n      value: number\n    }\n    i: number\n    props: {\n      onClick: () => void\n    }\n  }\n}\n\nexport const makeVDatePickerMonthsProps = propsFactory({\n  color: String,\n  height: [String, Number],\n  min: null as any as PropType<unknown>,\n  max: null as any as PropType<unknown>,\n  modelValue: Number,\n  year: Number,\n  allowedMonths: [Array, Function] as PropType<number[] | ((date: number) => boolean)>,\n}, 'VDatePickerMonths')\n\nexport const VDatePickerMonths = genericComponent<VDatePickerMonthsSlots>()({\n  name: 'VDatePickerMonths',\n\n  props: makeVDatePickerMonthsProps(),\n\n  emits: {\n    'update:modelValue': (date: any) => true,\n  },\n\n  setup (props, { emit, slots }) {\n    const adapter = useDate()\n    const model = useProxiedModel(props, 'modelValue')\n\n    const months = computed(() => {\n      let date = adapter.startOfYear(adapter.date())\n      if (props.year) {\n        date = adapter.setYear(date, props.year)\n      }\n      return createRange(12).map(i => {\n        const text = adapter.format(date, 'monthShort')\n        const label = adapter.format(date, 'month')\n        const isDisabled =\n          !!(\n            !isMonthAllowed(i) ||\n            (props.min && adapter.isAfter(adapter.startOfMonth(adapter.date(props.min)), date)) ||\n            (props.max && adapter.isAfter(date, adapter.startOfMonth(adapter.date(props.max))))\n          )\n        date = adapter.getNextMonth(date)\n\n        return {\n          isDisabled,\n          text,\n          label,\n          value: i,\n        }\n      })\n    })\n\n    watchEffect(() => {\n      model.value = model.value ?? adapter.getMonth(adapter.date())\n    })\n\n    function isMonthAllowed (month: number) {\n      if (Array.isArray(props.allowedMonths) && props.allowedMonths.length) {\n        return props.allowedMonths.includes(month)\n      }\n\n      if (typeof props.allowedMonths === 'function') {\n        return props.allowedMonths(month)\n      }\n\n      return true\n    }\n\n    useRender(() => (\n      <div\n        class=\"v-date-picker-months\"\n        style={{\n          height: convertToUnit(props.height),\n        }}\n      >\n        <div class=\"v-date-picker-months__content\">\n          { months.value.map((month, i) => {\n            const btnProps = {\n              active: model.value === i,\n              ariaLabel: month.label,\n              color: model.value === i ? props.color : undefined,\n              disabled: month.isDisabled,\n              rounded: true,\n              text: month.text,\n              variant: model.value === month.value ? 'flat' : 'text',\n              onClick: () => onClick(i),\n            } as const\n\n            function onClick (i: number) {\n              if (model.value === i) {\n                emit('update:modelValue', model.value)\n                return\n              }\n              model.value = i\n            }\n\n            return slots.month?.({\n              month,\n              i,\n              props: btnProps,\n            }) ?? (\n              <VBtn\n                key=\"month\"\n                { ...btnProps }\n              />\n            )\n          })}\n        </div>\n      </div>\n    ))\n\n    return {}\n  },\n})\n\nexport type VDatePickerMonths = InstanceType<typeof VDatePickerMonths>\n"
  },
  {
    "path": "packages/vuetify/src/components/VDatePicker/VDatePickerYears.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-date-picker-years\n    height: $date-picker-years-height\n    overflow-y: scroll\n\n  .v-date-picker-years__content\n    display: grid\n    flex: 1 1\n    justify-content: space-around\n    grid-template-columns: repeat(3, 1fr)\n    gap: 8px 24px\n    padding-inline: $date-picker-years-padding-inline\n\n    .v-btn\n      padding-inline: 8px\n"
  },
  {
    "path": "packages/vuetify/src/components/VDatePicker/VDatePickerYears.tsx",
    "content": "// Styles\nimport './VDatePickerYears.sass'\n\n// Components\nimport { VBtn } from '@/components/VBtn'\n\n// Composables\nimport { useDate } from '@/composables/date'\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Directives\nimport vIntersect from '@/directives/intersect'\n\n// Utilities\nimport { computed, shallowRef, watchEffect } from 'vue'\nimport { convertToUnit, createRange, genericComponent, propsFactory, templateRef, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\n// Types\nexport type VDatePickerYearsSlots = {\n  year: {\n    year: {\n      text: string\n      value: number\n    }\n    i: number\n    props: {\n      active: boolean\n      color?: string\n      rounded: boolean\n      text: string\n      variant: 'flat' | 'text'\n      onClick: () => void\n    }\n  }\n}\n\nexport const makeVDatePickerYearsProps = propsFactory({\n  color: String,\n  height: [String, Number],\n  min: null as any as PropType<unknown>,\n  max: null as any as PropType<unknown>,\n  modelValue: Number,\n  allowedYears: [Array, Function] as PropType<number[] | ((date: number) => boolean)>,\n}, 'VDatePickerYears')\n\nexport const VDatePickerYears = genericComponent<VDatePickerYearsSlots>()({\n  name: 'VDatePickerYears',\n\n  props: makeVDatePickerYearsProps(),\n\n  directives: { vIntersect },\n\n  emits: {\n    'update:modelValue': (year: number) => true,\n  },\n\n  setup (props, { emit, slots }) {\n    const adapter = useDate()\n    const model = useProxiedModel(props, 'modelValue')\n    const hasFocusedItem = shallowRef(false)\n    const years = computed(() => {\n      const year = adapter.getYear(adapter.date())\n\n      let min = year - 100\n      let max = year + 52\n\n      if (props.min) {\n        min = adapter.getYear(adapter.date(props.min))\n      }\n\n      if (props.max) {\n        max = adapter.getYear(adapter.date(props.max))\n      }\n\n      let date = adapter.startOfYear(adapter.date())\n\n      date = adapter.setYear(date, min)\n\n      return createRange(max - min + 1, min).map(i => {\n        const text = adapter.format(date, 'year')\n        date = adapter.setYear(date, adapter.getYear(date) + 1)\n\n        return {\n          text,\n          value: i,\n          isDisabled: !isYearAllowed(i),\n        }\n      })\n    })\n\n    watchEffect(() => {\n      model.value = model.value ?? adapter.getYear(adapter.date())\n    })\n\n    const containerRef = templateRef()\n    const yearRef = templateRef()\n\n    function focusSelectedYear () {\n      const container = containerRef.el\n      const target = yearRef.el\n      if (!container || !target) return\n\n      const containerRect = container.getBoundingClientRect()\n      const targetRect = target.getBoundingClientRect()\n\n      container.scrollTop += (targetRect.top - containerRect.top) - (container.clientHeight / 2) + (targetRect.height / 2)\n    }\n\n    function isYearAllowed (year: number) {\n      if (Array.isArray(props.allowedYears) && props.allowedYears.length) {\n        return props.allowedYears.includes(year)\n      }\n\n      if (typeof props.allowedYears === 'function') {\n        return props.allowedYears(year)\n      }\n\n      return true\n    }\n\n    useRender(() => (\n      <div\n        class=\"v-date-picker-years\"\n        ref={ containerRef }\n        v-intersect={[{\n          handler: focusSelectedYear,\n        }, null, ['once']]}\n        style={{\n          height: convertToUnit(props.height),\n        }}\n      >\n        <div\n          class=\"v-date-picker-years__content\"\n          onFocus={ () => yearRef.el?.focus() }\n          onFocusin={ () => hasFocusedItem.value = true }\n          onFocusout={ () => hasFocusedItem.value = false }\n          tabindex={ hasFocusedItem.value ? -1 : 0 }\n        >\n          { years.value.map((year, i) => {\n            const btnProps = {\n              ref: model.value === year.value ? yearRef : undefined,\n              active: model.value === year.value,\n              color: model.value === year.value ? props.color : undefined,\n              rounded: true,\n              text: year.text,\n              disabled: year.isDisabled,\n              variant: model.value === year.value ? 'flat' : 'text',\n              onClick: () => {\n                if (model.value === year.value) {\n                  emit('update:modelValue', model.value)\n                  return\n                }\n                model.value = year.value\n              },\n            } as const\n\n            return slots.year?.({\n              year,\n              i,\n              props: btnProps,\n            }) ?? (\n              <VBtn\n                key=\"month\"\n                { ...btnProps }\n              />\n            )\n          })}\n        </div>\n      </div>\n    ))\n\n    return {}\n  },\n})\n\nexport type VDatePickerYears = InstanceType<typeof VDatePickerYears>\n"
  },
  {
    "path": "packages/vuetify/src/components/VDatePicker/__tests__/VDatePicker.a11y.spec.tsx",
    "content": "import { VDatePicker } from '../VDatePicker'\n\n// Utilities\nimport { render, screen } from '@test'\nimport { mount } from '@vue/test-utils'\nimport { createVuetify } from '@/framework'\n\ndescribe('VDatePicker accessibility', () => {\n  const vuetify = createVuetify()\n\n  function mountFunction (component: any, options = {}) {\n    return mount(component, {\n      global: {\n        plugins: [vuetify],\n      },\n      ...options,\n    })\n  }\n\n  it('should have aria-labels on navigation buttons', () => {\n    render(<VDatePicker modelValue=\"2024-01-15\" />)\n\n    expect(screen.getByTestId('prev-month').getAttribute('aria-label')).toBe('Previous month')\n    expect(screen.getByTestId('next-month').getAttribute('aria-label')).toBe('Next month')\n    expect(screen.getByTestId('year-btn').getAttribute('aria-label')).toBe('Select year')\n  })\n\n  it('should have aria-current=\"date\" on today\\'s date', () => {\n    const today = new Date()\n    render(<VDatePicker modelValue={ today } />)\n\n    expect(screen.queryAllByCSS('[aria-current=\"date\"]')).toHaveLength(1)\n  })\n\n  it('should have aria-labels on date buttons', () => {\n    render(<VDatePicker modelValue=\"2024-01-15\" />)\n\n    const dateButtons = screen.getAllByCSS('.v-date-picker-month__day-btn')\n    expect(dateButtons).toHaveLength(31)\n\n    for (const button of dateButtons) {\n      expect(button.getAttribute('aria-label')).toBeTruthy()\n    }\n  })\n\n  it('should use full month name for aria-labels in month selection', async () => {\n    const wrapper = mountFunction(<VDatePicker modelValue=\"2024-01-15\" />)\n\n    await wrapper.find('[data-testid=\"month-btn\"]').trigger('click')\n\n    const buttons = wrapper.findAll('.v-date-picker-months__content .v-btn')\n    expect(buttons).toHaveLength(12)\n\n    for (const button of buttons) {\n      expect(button.attributes('aria-label')).toBeTruthy()\n    }\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VDatePicker/__tests__/VDatePicker.date.spec.ts",
    "content": "// @ts-nocheck\n/* eslint-disable */\n\n// Components\nimport { VDatePicker } from '../VDatePicker'\n\n// import { touch } from '@/../test'\nimport { render, screen } from '@test'\nimport {\n  mount,\n  MountOptions,\n  Wrapper,\n} from '@vue/test-utils'\n// import { Lang } from '../../../services/lang'\n// import VDatePicker from '../VDatePicker'\n// import Vue from 'vue'\n// import { preset } from '../../../presets/default'\n\n// Vue.prototype.$vuetify = {\n//   icons: {\n//     values: {\n//       next: 'mdi-chevron-right',\n//       prev: 'mdi-chevron-left',\n//     },\n//   },\n// }\n\ndescribe.skip('VDatePicker.ts', () => { // eslint-disable-line max-statements\n  type Instance = InstanceType<typeof VDatePicker>\n  let mountFunction: (options?: MountOptions<Instance>) => Wrapper<Instance>\n  beforeEach(() => {\n    mountFunction = (options?: MountOptions<Instance>) => {\n      return mount(VDatePicker, {\n        ...options,\n        mocks: {\n          $vuetify: {\n            lang: new Lang({\n              ...preset,\n            }),\n          },\n        },\n      })\n    }\n  })\n\n  it('should display the correct date in title and header', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2005-11-01',\n      },\n    })\n\n    const title = wrapper.findAll('.v-date-picker-title__date').at(0)\n    const header = wrapper.findAll('.v-date-picker-header__value div').at(0)\n\n    expect(title.text()).toBe('Tue, Nov 1')\n    expect(header.text()).toBe('November 2005')\n  })\n\n  it('should work with year < 1000', () => {\n    expect(() => {\n      mountFunction({\n        propsData: {\n          value: '0005-11-01',\n        },\n      })\n    }).not.toThrow()\n  })\n\n  it('should display the correct year when model is null', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: null,\n        pickerDate: '2013-01',\n      },\n    })\n\n    const year = wrapper.findAll('.v-date-picker-title__year').at(0)\n\n    expect(year.text()).toBe('2013')\n  })\n\n  it('should match snapshot with default settings', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2013-05-07',\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render readonly picker', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2013-05-07',\n        readonly: true,\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render flat picker', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2013-05-07',\n        flat: true,\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render picker with elevation', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2013-05-07',\n        elevation: 4,\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render disabled picker', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2013-05-07',\n        disabled: true,\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should emit input event on date click', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2013-05-07',\n      },\n    })\n\n    const input = jest.fn()\n    wrapper.vm.$on('input', input)\n\n    const change = jest.fn()\n    wrapper.vm.$on('change', change)\n\n    wrapper.findAll('.v-date-picker-table--date tbody tr+tr td:first-child button').at(0).trigger('click')\n    expect(input).toHaveBeenCalledWith('2013-05-05')\n    expect(change).toHaveBeenCalledWith('2013-05-05')\n  })\n\n  it('should not emit input event on month click if date is not allowed', async () => {\n    const cb = jest.fn()\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2013-05-13',\n        allowedDates: () => false,\n      },\n      data: () => ({\n        internalActivePicker: 'MONTH',\n      }),\n    })\n\n    wrapper.vm.$on('input', cb)\n    wrapper.findAll('.v-date-picker-table--month button').at(0).trigger('click')\n    expect(cb).not.toHaveBeenCalled()\n  })\n\n  it('should emit input event on year click (reactive picker)', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2013-05-13',\n        reactive: true,\n      },\n      data: () => ({\n        internalActivePicker: 'YEAR',\n      }),\n    })\n\n    const input = jest.fn()\n    wrapper.vm.$on('input', input)\n\n    const change = jest.fn()\n    wrapper.vm.$on('change', input)\n\n    wrapper.findAll('.v-date-picker-years li.active + li').at(0).trigger('click')\n    expect(input).toHaveBeenCalledWith('2012-05-13')\n    expect(change).not.toHaveBeenCalled()\n  })\n\n  it('should not emit input event on year click if date is not allowed', async () => {\n    const cb = jest.fn()\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2013-05-13',\n        allowedDates: () => false,\n      },\n      data: () => ({\n        internalActivePicker: 'YEAR',\n      }),\n    })\n\n    wrapper.vm.$on('input', cb)\n    wrapper.findAll('.v-date-picker-years li.active + li').at(0).trigger('click')\n    expect(cb).not.toHaveBeenCalled()\n  })\n\n  it('should emit input event with selected dates after click', async () => {\n    const cb = jest.fn()\n    const wrapper = mountFunction({\n      propsData: {\n        multiple: true,\n        value: ['2013-05-07', '2013-05-08'],\n      },\n    })\n\n    wrapper.vm.$on('input', cb)\n    wrapper.findAll('.v-date-picker-table--date tbody tr+tr td:first-child button').at(0).trigger('click')\n    expect(cb.mock.calls[0][0]).toHaveLength(3)\n    expect(cb.mock.calls[0][0][2]).toBe('2013-05-05')\n    expect(cb.mock.calls[0][0]).toEqual(\n      expect.arrayContaining(['2013-05-07', '2013-05-08', '2013-05-05']),\n    )\n  })\n\n  it('should display translated title', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        multiple: true,\n        value: ['2013-05-07'],\n      },\n    })\n\n    expect(wrapper.find('.v-date-picker-title__date').text()).toBe('Tue, May 7')\n\n    wrapper.setProps({\n      value: [],\n    })\n    expect(wrapper.find('.v-date-picker-title__date').text()).toBe('-')\n\n    wrapper.setProps({\n      value: ['2013-05-07', '2013-05-08', '2013-05-09'],\n    })\n    expect(wrapper.find('.v-date-picker-title__date').text()).toBe('3 selected')\n  })\n\n  it('should emit input without unselected dates after click', async () => {\n    const cb = jest.fn()\n    const wrapper = mountFunction({\n      propsData: {\n        multiple: true,\n        value: ['2013-05-07', '2013-05-08', '2013-05-05'],\n      },\n    })\n\n    wrapper.vm.$on('input', cb)\n    wrapper.findAll('.v-date-picker-table--date tbody tr+tr td:first-child button').at(0).trigger('click')\n    expect(cb.mock.calls[0][0]).toHaveLength(2)\n    expect(cb.mock.calls[0][0]).toEqual(expect.arrayContaining(['2013-05-07', '2013-05-08']))\n    expect(cb.mock.calls[0][0]).not.toEqual(expect.arrayContaining(['2013-05-05']))\n  })\n\n  it('should be scrollable', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2013-05-07',\n        scrollable: true,\n      },\n    })\n\n    wrapper.findAll('.v-date-picker-table--date').at(0).trigger('wheel', { deltaY: 1 })\n    expect(wrapper.vm.tableDate).toBe('2013-06')\n  })\n\n  it('should change tableDate on touch', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2013-05-07',\n        scrollable: true,\n      },\n    })\n\n    const table = wrapper.findAll('.v-date-picker-table--date').at(0)\n    touch(table).start(0, 0).end(20, 0)\n    expect(wrapper.vm.tableDate).toBe('2013-04')\n\n    touch(table).start(0, 0).end(-20, 0)\n    expect(wrapper.vm.tableDate).toBe('2013-05')\n  })\n\n  it('should match snapshot with dark theme', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2013-05-07',\n        dark: true,\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should match snapshot with no title', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2013-05-07',\n        noTitle: true,\n      },\n    })\n\n    expect(wrapper.findAll('.v-picker__title').wrappers).toHaveLength(0)\n  })\n\n  it('should pass first day of week to v-date-picker-table component', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2013-05-07',\n        firstDayOfWeek: 2,\n      },\n    })\n\n    expect(wrapper.vm.$refs.table.firstDayOfWeek).toBe(2)\n  })\n\n  // TODO: This fails in different ways for multiple people\n  // Avoriaz/Jsdom (?) doesn't fully support date formatting using locale\n  // This should be tested in browser env\n  it.skip('should match snapshot with locale', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2013-05-07',\n        locale: 'fa-AF',\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should match snapshot with title/header formatting functions', () => {\n    const dateFormat = date => `(${date})`\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2005-11-01',\n        headerDateFormat: dateFormat,\n        titleDateFormat: dateFormat,\n        weekdayFormat: () => 'W',\n      },\n    })\n\n    expect(wrapper.findAll('.v-date-picker-title__date').at(0).text()).toBe('(2005-11-01)')\n    expect(wrapper.findAll('.v-date-picker-header__value').at(0).text()).toBe('(2005-11)')\n    expect(wrapper.findAll('.v-date-picker-table--date th').at(1).text()).toBe('W')\n  })\n\n  it('should match snapshot with colored picker & header', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2005-11-01',\n        color: 'primary',\n        headerColor: 'orange darken-1',\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should match snapshot with colored picker', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2005-11-01',\n        color: 'orange darken-1',\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should match snapshot with year icon', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2005-11-01',\n        yearIcon: 'year',\n      },\n    })\n\n    expect(wrapper.findAll('.v-picker__title').at(0).html()).toMatchSnapshot()\n  })\n\n  it('should match change month when clicked on header arrow buttons', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2005-11-01',\n      },\n    })\n\n    const [leftButton, rightButton] = wrapper.findAll('.v-date-picker-header button.v-btn').wrappers\n\n    leftButton.trigger('click')\n    expect(wrapper.vm.tableDate).toBe('2005-10')\n\n    rightButton.trigger('click')\n    expect(wrapper.vm.tableDate).toBe('2005-11')\n  })\n\n  it('should match change active picker when clicked on month button', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2005-11-01',\n      },\n    })\n\n    const button = wrapper.findAll('.v-date-picker-header__value button').at(0)\n\n    button.trigger('click')\n    expect(wrapper.vm.internalActivePicker).toBe('MONTH')\n  })\n\n  it('should match snapshot with slot', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        type: 'date',\n        value: '2005-11-01',\n      },\n      scopedSlots: {\n        default: '<div class=\"scoped-slot\"></div>',\n      },\n    })\n    expect(wrapper.findAll('.v-picker__actions .scoped-slot').wrappers).toHaveLength(1)\n  })\n\n  it('should match years snapshot', async () => {\n    const wrapper = mountFunction({\n      data: () => ({\n        internalActivePicker: 'YEAR',\n      }),\n      propsData: {\n        type: 'date',\n        value: '2005-11-01',\n      },\n    })\n\n    expect(wrapper.vm.internalActivePicker).toBe('YEAR')\n\n    wrapper.findAll('.v-date-picker-title__date').at(0).trigger('click')\n    await wrapper.vm.$nextTick()\n    expect(wrapper.vm.internalActivePicker).toBe('DATE')\n\n    wrapper.findAll('.v-date-picker-title__year').at(0).trigger('click')\n    await wrapper.vm.$nextTick()\n    expect(wrapper.vm.internalActivePicker).toBe('YEAR')\n  })\n\n  it('should select year', async () => {\n    const wrapper = mountFunction({\n      data: () => ({\n        internalActivePicker: 'YEAR',\n      }),\n      propsData: {\n        type: 'date',\n        value: '2005-11-01',\n      },\n    })\n\n    wrapper.findAll('.v-date-picker-years li.active + li').at(0).trigger('click')\n    expect(wrapper.vm.internalActivePicker).toBe('MONTH')\n    expect(wrapper.vm.tableDate).toBe('2004-11')\n  })\n\n  it('should set the table date when value has changed', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: null,\n      },\n    })\n\n    wrapper.setProps({ value: '2005-11-11' })\n    expect(wrapper.vm.tableDate).toBe('2005-11')\n  })\n\n  it('should update the active picker if type has changed', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '1999-12-13',\n        type: 'date',\n      },\n    })\n\n    wrapper.vm.$on('input', value => wrapper.setProps({ value }))\n\n    wrapper.setProps({ type: 'month' })\n    expect(wrapper.vm.internalActivePicker).toBe('MONTH')\n    expect(wrapper.vm.value).toBe('1999-12')\n    // TODO: uncomment when type: 'year' is implemented\n    // wrapper.setProps({ type: 'year' })\n    // expect(wrapper.vm.internalActivePicker).toBe('YEAR')\n    // expect(wrapper.vm.inputDate).toBe('1999')\n    // wrapper.setProps({ type: 'month' })\n    // expect(wrapper.vm.internalActivePicker).toBe('MONTH')\n    // expect(wrapper.vm.inputDate).toBe('1999-01')\n    wrapper.setProps({ type: 'date' })\n    expect(wrapper.vm.internalActivePicker).toBe('DATE')\n    expect(wrapper.vm.value).toBe('1999-12-01')\n  })\n\n  it('should format title date', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2013-05-07',\n      },\n    })\n\n    expect(wrapper.vm.defaultTitleDateFormatter('2013-03-05')).toBe('Tue, Mar 5')\n\n    wrapper.setProps({ landscape: true })\n    expect(wrapper.vm.defaultTitleDateFormatter('2013-03-05')).toBe('Tue,<br>Mar 5')\n  })\n\n  it('should use prev and next icons', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        prevIcon: 'block',\n        nextIcon: 'check',\n      },\n    })\n\n    const icons = wrapper.findAll('.v-date-picker-header .v-icon').wrappers\n    expect(icons[0].element.textContent).toBe('block')\n    expect(icons[1].element.textContent).toBe('check')\n  })\n\n  it('should emit update:picker-date event when tableDate changes', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2017-09',\n      },\n    })\n\n    const pickerDate = jest.fn()\n    wrapper.vm.$on('update:picker-date', pickerDate)\n    wrapper.vm.tableDate = '2013-11'\n    await wrapper.vm.$nextTick()\n    expect(pickerDate).toHaveBeenCalledWith('2013-11')\n  })\n\n  it('should set tableDate to pickerDate if provided', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2017-09',\n        pickerDate: '2013-11',\n      },\n    })\n\n    expect(wrapper.vm.tableDate).toBe('2013-11')\n  })\n\n  it('should update pickerDate to the selected month after setting it to null', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2017-09-13',\n        pickerDate: '2013-11',\n      },\n    })\n\n    const update = jest.fn()\n    wrapper.vm.$on('update:picker-date', update)\n    await wrapper.vm.$nextTick()\n\n    wrapper.setProps({\n      pickerDate: null,\n    })\n    await wrapper.vm.$nextTick()\n    expect(update).toHaveBeenCalledWith('2017-09')\n  })\n\n  it.skip('should render component with min/max props', async () => { // TODO: fix this one\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2013-01-07',\n        min: '2013-01-03',\n        max: '2013-01-17',\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n    wrapper.setData({\n      internalActivePicker: 'MONTH',\n    })\n    await wrapper.vm.$nextTick()\n    expect(wrapper.html()).toMatchSnapshot()\n    wrapper.setData({\n      internalActivePicker: 'YEAR',\n    })\n    await wrapper.vm.$nextTick()\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should round down min date in ISO 8601 format', async () => {\n    const cb = jest.fn()\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2019-01-20',\n        min: '2019-01-06T15:55:56.441Z',\n      },\n    })\n\n    wrapper.vm.$on('input', cb)\n    wrapper.findAll('.v-date-picker-table--date tbody tr+tr td:first-child button').at(0).trigger('click')\n    expect(cb.mock.calls[0][0]).toEqual('2019-01-06')\n  })\n\n  it('should emit @input and not emit @change when month is clicked (not reactive picker)', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2013-02-07',\n        reactive: true,\n      },\n      data: () => ({\n        internalActivePicker: 'MONTH',\n      }),\n    })\n\n    const input = jest.fn()\n    wrapper.vm.$on('input', input)\n\n    const change = jest.fn()\n    wrapper.vm.$on('change', change)\n\n    wrapper.findAll('tbody tr td button').at(0).trigger('click')\n    wrapper.vm.$nextTick()\n    expect(change).not.toHaveBeenCalled()\n    expect(input).toHaveBeenCalledWith('2013-01-07')\n  })\n\n  it('should not emit @input and not emit @change when month is clicked (lazy picker)', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2013-02-07',\n      },\n      data: () => ({\n        internalActivePicker: 'MONTH',\n      }),\n    })\n\n    const input = jest.fn()\n    wrapper.vm.$on('input', input)\n\n    const change = jest.fn()\n    wrapper.vm.$on('change', change)\n\n    wrapper.findAll('tbody tr td button').at(0).trigger('click')\n    wrapper.vm.$nextTick()\n    expect(change).not.toHaveBeenCalled()\n    expect(input).not.toHaveBeenCalled()\n  })\n\n  it('should emit click/dblclick:date event', async () => {\n    const click = jest.fn()\n    const dblclick = jest.fn()\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2013-05-20',\n        type: 'date',\n      },\n      listeners: {\n        'click:date': (value: any, event: any) => click(value, event instanceof Event),\n        'dblclick:date': (value: any, event: any) => dblclick(value, event instanceof Event),\n      },\n    })\n\n    wrapper.findAll('.v-date-picker-table--date tbody tr+tr td:first-child button').at(0).trigger('click')\n    expect(click).toHaveBeenCalledWith('2013-05-05', true)\n\n    wrapper.findAll('.v-date-picker-table--date tbody tr+tr td:first-child button').at(0).trigger('dblclick')\n    expect(dblclick).toHaveBeenCalledWith('2013-05-05', true)\n  })\n\n  it('should handle date range select', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        range: true,\n        value: ['2019-01-06'],\n      },\n    })\n\n    const [input, change] = [jest.fn(), jest.fn()]\n    wrapper.vm.$on('input', input)\n    wrapper.vm.$on('change', change)\n\n    wrapper.findAll('.v-date-picker-table--date tbody tr+tr td button').at(2).trigger('click')\n    // Lead to [from, to], both 'input' and 'change' should be called\n    expect(input.mock.calls[0][0]).toEqual(expect.arrayContaining(['2019-01-06', '2019-01-08']))\n    expect(change.mock.calls[0][0]).toEqual(expect.arrayContaining(['2019-01-06', '2019-01-08']))\n\n    wrapper.setProps({\n      value: ['2019-01-01', '2019-01-31'],\n    })\n    wrapper.findAll('.v-date-picker-table--date tbody tr+tr td:first-child button').at(0).trigger('click')\n    // Lead to [from,], only 'input' should be called\n    expect(input.mock.calls[1][0]).toEqual(expect.arrayContaining(['2019-01-06']))\n    expect(change.mock.calls).toHaveLength(1)\n  })\n\n  it('should add class for the first and last days in range', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        range: true,\n        showCurrent: '2019-01',\n        type: 'date',\n        value: ['2019-01-06', '2019-01-16'],\n      },\n    })\n\n    expect(wrapper.findAll('.v-date-picker-table--date tbody button.v-date-picker--first-in-range')\n      .exists()).toBe(true)\n    expect(wrapper.findAll('.v-date-picker-table--date tbody button.v-date-picker--last-in-range')\n      .exists()).toBe(true)\n  })\n\n  it('should set proper tableDate', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        showCurrent: '2030-04-04',\n      },\n    })\n\n    expect(wrapper.vm.tableDate).toBe('2030-04')\n  })\n\n  it('should not highlight not allowed dates in range', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        range: true,\n        value: ['2019-09-01', '2019-09-03'],\n        allowedDates: value => value.endsWith('1') || value.endsWith('3'),\n      },\n    })\n\n    const buttonOfDay02 = wrapper.findAll('.v-date-picker-table--date tbody button').at(1)\n    expect(buttonOfDay02.element.classList.contains('accent')).toBeFalsy()\n  })\n\n  it('should handle date range picker with null value', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        range: true,\n        value: null,\n      },\n    })\n\n    expect(wrapper.find('.v-date-picker-title__date').html()).toMatchSnapshot()\n  })\n\n  it('should correctly show weeks and dates when showWeek and showAdjacentMonths props are passed', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2021-02-01',\n        firstDayOfWeek: 1,\n        showWeek: true,\n        showAdjacentMonths: true,\n      },\n    })\n\n    const lastWeekEl = wrapper.find('.v-date-picker-table--date tbody tr:last-child td small')\n    const lastDayEl = wrapper.findAll('.v-date-picker-table--date tbody tr:last-child td button div').at(6)\n\n    expect(lastWeekEl.text()).toBe('09')\n    expect(lastDayEl.text()).toBe('7')\n  })\n})\n\ndescribe('week numbers with time zone', () => {\n  beforeEach(() => vi.stubEnv('TZ', 'Europe/Warsaw'))\n  afterEach(() => vi.unstubAllEnvs())\n\n  it('should calculate weeks correctly near ST/DST transition', async () => {\n    render(VDatePicker, {\n      props: {\n        showWeek: true,\n        modelValue: new Date(2025,3,1),\n      },\n    })\n    const $weeks = await screen.findAllByCSS('.v-date-picker-month__weeks > div')\n    expect($weeks[1].innerHTML).toBe('14')\n    expect($weeks[2].innerHTML).toBe('15')\n  })\n\n  it('should calculate weeks correctly near DST/ST transition', async () => {\n    render(VDatePicker, {\n      props: {\n        showWeek: true,\n        modelValue: new Date(2025,10,1),\n      },\n    })\n    const $weeks = await screen.findAllByCSS('.v-date-picker-month__weeks > div')\n    expect($weeks[1].innerHTML).toBe('44')\n    expect($weeks[2].innerHTML).toBe('45')\n  })\n})\n\ndescribe('range selection with time zone', () => {\n  beforeEach(() => vi.stubEnv('TZ', 'America/New_York'))\n  afterEach(() => vi.unstubAllEnvs())\n\n  it('should select correct dates near ST/DST transition', async () => {\n    const update = vi.fn()\n    const wrapper = render(VDatePicker, {\n      props: {\n        multiple: 'range',\n        modelValue: ['2025-03-01','2025-03-01'],\n        'onUpdate:modelValue': update,\n      },\n    })\n\n    const btn1 = await wrapper.findByText('8') as HTMLElement\n    btn1.click()\n    expect(update).toHaveBeenNthCalledWith(1, [new Date('2025-03-08T05:00:00.000Z')])\n    const btn2 = await wrapper.findByText('9') as HTMLElement\n    btn2.click()\n    expect(update).toHaveBeenNthCalledWith(2, [new Date('2025-03-08T05:00:00.000Z'), new Date('2025-03-10T03:59:59.999Z')])\n  })\n\n  it('should select correct dates near DST/ST transition', async () => {\n    const update = vi.fn()\n    const wrapper = render(VDatePicker, {\n      props: {\n        multiple: 'range',\n        modelValue: ['2025-10-01','2025-10-01'],\n        'onUpdate:modelValue': update,\n      },\n    })\n\n    const btn1 = await wrapper.findByText('2') as HTMLElement\n    btn1.click()\n    expect(update).toHaveBeenNthCalledWith(1, [new Date('2025-10-02T04:00:00.000Z')])\n    const btn2 = await wrapper.findByText('3') as HTMLElement\n    btn2.click()\n    expect(update).toHaveBeenNthCalledWith(2, [new Date('2025-10-02T04:00:00.000Z'), new Date('2025-10-04T03:59:59.999Z')])\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VDatePicker/__tests__/VDatePicker.events.spec.browser.tsx",
    "content": "// Utilities\nimport { render } from '@test'\nimport { VDatePicker } from '../VDatePicker'\n\ndescribe('VDatePicker events', () => {\n  it('renders event markers when events is an array', async () => {\n    render(() => (\n      <VDatePicker\n        type=\"month\"\n        month={ 3 }\n        year={ 2022 }\n        events={['2022-04-09']}\n        eventColor=\"red\"\n      />\n    ))\n\n    const eventElements = document.querySelectorAll('.v-badge')\n    expect(eventElements.length).toBeGreaterThan(0)\n  })\n\n  it('renders event markers when events is a function', async () => {\n    render(() => (\n      <VDatePicker\n        month={ 3 }\n        year={ 2022 }\n        events={ (date: string) => date === '2022-04-09' }\n        eventColor=\"red\"\n      />\n    ))\n\n    // Query the DOM for the event markers\n    const eventElements = document.querySelectorAll('.v-badge')\n    expect(eventElements.length).toBeGreaterThan(0)\n  })\n\n  it('renders event markers with colors defined by an object', async () => {\n    render(() => (\n      <VDatePicker\n        month={ 3 }\n        year={ 2022 }\n        events={['2022-04-09', '2022-04-20']}\n        eventColor={{ '2022-04-09': 'red', '2022-04-20': 'blue lighten-1' }}\n      />\n    ))\n\n    const eventElements = document.querySelectorAll('.v-badge')\n    expect(eventElements.length).toBeGreaterThan(0)\n  })\n\n  it('renders event markers with colors defined by a function', async () => {\n    render(() => (\n      <VDatePicker\n        month={ 3 }\n        year={ 2022 }\n        events={['2022-04-09', '2022-04-20']}\n        eventColor={ (date: string) => ({ '2022-04-09': 'red' }[date] || false) }\n      />\n    ))\n\n    const eventElements = document.querySelectorAll('.v-badge')\n    expect(eventElements.length).toBeGreaterThan(0)\n  })\n\n  it('uses default color when eventColor is not set', async () => {\n    render(() => (\n      <VDatePicker\n        type=\"month\"\n        month={ 3 }\n        year={ 2022 }\n        events={{ '2022-04-09': true }}\n      />\n    ))\n\n    const eventElements = document.querySelectorAll('.v-badge')\n    expect(eventElements.length).toBeGreaterThan(0)\n\n    const hasSurfaceVariant = Array.from(eventElements).some(el =>\n      el.querySelector('.v-badge__badge')?.classList.contains('bg-surface-variant')\n    )\n    expect(hasSurfaceVariant).toBe(true)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VDatePicker/__tests__/VDatePicker.month.spec.ts",
    "content": "// @ts-nocheck\n/* eslint-disable */\n\n// import VDatePicker from '../VDatePicker'\n// import { Lang } from '../../../services/lang'\nimport {\n  mount,\n  MountOptions,\n  Wrapper,\n} from '@vue/test-utils'\n// import Vue from 'vue'\n// import { preset } from '../../../presets/default'\n// import en from '../../../locale/en'\n\n// Vue.prototype.$vuetify = {\n//   icons: {\n//     values: {\n//       next: 'mdi-chevron-right',\n//       prev: 'mdi-chevron-left',\n//     },\n//   },\n// }\n\ndescribe.skip('VDatePicker.ts', () => {\n  type Instance = InstanceType<typeof VDatePicker>\n  let mountFunction: (options?: MountOptions<Instance>) => Wrapper<Instance>\n  beforeEach(() => {\n    mountFunction = (options?: MountOptions<Instance>) => {\n      return mount(VDatePicker, {\n        ...options,\n        mocks: {\n          $vuetify: {\n            rtl: false,\n            lang: new Lang({\n              ...preset,\n            }),\n          },\n        },\n      })\n    }\n  })\n\n  it('should emit input event on year click (reactive picker)', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2013-05',\n        type: 'month',\n        reactive: true,\n      },\n    })\n\n    wrapper.setData({\n      internalActivePicker: 'YEAR',\n    })\n\n    const input = jest.fn()\n    wrapper.vm.$on('input', input)\n\n    const change = jest.fn()\n    wrapper.vm.$on('change', input)\n\n    wrapper.findAll('.v-date-picker-years li.active + li').at(0).trigger('click')\n    expect(input).toHaveBeenCalledWith('2012-05')\n    expect(change).not.toHaveBeenCalled()\n  })\n\n  it('should render flat picker', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2013-05',\n        flat: true,\n        type: 'month',\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render picker with elevation', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2013-05',\n        elevation: 4,\n        type: 'month',\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should not emit input event on year click if month is not allowed', async () => {\n    const cb = jest.fn()\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2013-05',\n        type: 'month',\n        allowedDates: () => false,\n      },\n    })\n\n    wrapper.setData({\n      internalActivePicker: 'YEAR',\n    })\n\n    wrapper.vm.$on('input', cb)\n    wrapper.findAll('.v-date-picker-years li.active + li').at(0).trigger('click')\n    expect(cb).not.toHaveBeenCalled()\n  })\n\n  it('should emit input event on month click', async () => {\n    const cb = jest.fn()\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2013-05',\n        type: 'month',\n      },\n    })\n\n    wrapper.vm.$on('input', cb)\n    wrapper.findAll('.v-date-picker-table--month button').at(0).trigger('click')\n    expect(cb).toHaveBeenCalledWith('2013-01')\n  })\n\n  it('should be scrollable', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2013-05',\n        type: 'month',\n        scrollable: true,\n      },\n    })\n\n    wrapper.findAll('.v-date-picker-table--month').at(0).trigger('wheel', { deltaY: 1 })\n    await wrapper.vm.$nextTick()\n    expect(wrapper.vm.tableDate).toBe('2014')\n  })\n\n  it('should match snapshot with pick-month prop', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2013-05-07',\n        type: 'month',\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should match snapshot with allowed dates as array', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2013-05',\n        type: 'month',\n        allowedDates: value => ['2013-01', '2013-03', '2013-05', '2013-07'].includes(value),\n      },\n    })\n\n    expect(wrapper.findAll('.v-date-picker-table--month tbody').at(0).html()).toMatchSnapshot()\n  })\n\n  it('should match snapshot with month formatting functions', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2005-11-01',\n        type: 'month',\n        monthFormat: date => `(${date.split('-')[1]})`,\n      },\n    })\n\n    expect(wrapper.findAll('.v-date-picker-table--month tbody').at(0).html()).toMatchSnapshot()\n  })\n\n  it('should match snapshot with colored picker & header', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        type: 'month',\n        value: '2005-11-01',\n        color: 'primary',\n        headerColor: 'orange darken-1',\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should match snapshot with colored picker', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        type: 'month',\n        value: '2005-11-01',\n        color: 'orange darken-1',\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should match change month when clicked on header arrow buttons', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2005-11',\n        type: 'month',\n      },\n    })\n\n    const [leftButton, rightButton] = wrapper.findAll('.v-date-picker-header button.v-btn').wrappers\n\n    leftButton.trigger('click')\n    expect(wrapper.vm.tableDate).toBe('2004')\n\n    rightButton.trigger('click')\n    expect(wrapper.vm.tableDate).toBe('2005')\n  })\n\n  it('should match change active picker when clicked on month button', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2005-11-01',\n        type: 'month',\n      },\n    })\n\n    const button = wrapper.findAll('.v-date-picker-header__value button').at(0)\n\n    button.trigger('click')\n    expect(wrapper.vm.internalActivePicker).toBe('YEAR')\n  })\n\n  it('should select year', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        type: 'month',\n        value: '2005-11',\n      },\n    })\n\n    wrapper.setData({\n      internalActivePicker: 'YEAR',\n    })\n\n    wrapper.findAll('.v-date-picker-years li.active + li').at(0).trigger('click')\n    expect(wrapper.vm.internalActivePicker).toBe('MONTH')\n    expect(wrapper.vm.tableDate).toBe('2004')\n  })\n\n  it('should set the table date when value has changed', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: null,\n        type: 'month',\n      },\n    })\n\n    wrapper.setProps({ value: '2005-11' })\n    expect(wrapper.vm.tableDate).toBe('2005')\n  })\n\n  it('should use prev and next icons', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        type: 'month',\n        prevIcon: 'block',\n        nextIcon: 'check',\n      },\n    })\n\n    const icons = wrapper.findAll('.v-date-picker-header .v-icon').wrappers\n    expect(icons[0].element.textContent).toBe('block')\n    expect(icons[1].element.textContent).toBe('check')\n  })\n\n  it('should display translated title', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        multiple: true,\n        type: 'month',\n        value: ['2013-05'],\n      },\n    })\n\n    expect(wrapper.find('.v-date-picker-title__date').text()).toBe('May')\n\n    wrapper.setProps({\n      value: [],\n    })\n    expect(wrapper.find('.v-date-picker-title__date').text()).toBe('-')\n\n    wrapper.setProps({\n      value: ['2013-05', '2013-06', '2013-07'],\n    })\n    expect(wrapper.find('.v-date-picker-title__date').text()).toBe('3 selected')\n  })\n\n  it('should emit click/dblclick:month event', async () => {\n    const click = jest.fn()\n    const dblclick = jest.fn()\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2013-05',\n        type: 'month',\n      },\n      listeners: {\n        'click:month': (value: any, event: any) => click(value, event instanceof Event),\n        'dblclick:month': (value: any, event: any) => dblclick(value, event instanceof Event),\n      },\n    })\n\n    wrapper.findAll('.v-date-picker-table--month tbody tr+tr td:first-child button').at(0).trigger('click')\n    expect(click).toHaveBeenCalledWith('2013-04', true)\n\n    wrapper.findAll('.v-date-picker-table--month tbody tr+tr td:first-child button').at(0).trigger('dblclick')\n    expect(dblclick).toHaveBeenCalledWith('2013-04', true)\n  })\n\n  it('should handle date range select', async () => {\n    const cb = jest.fn()\n    const wrapper = mountFunction({\n      propsData: {\n        range: true,\n        type: 'month',\n        value: [],\n      },\n    })\n    const year = new Date().getFullYear()\n    const toDate = `${year}-08`\n    const fromDate = `${year}-03`\n\n    wrapper.vm.$on('input', cb)\n    wrapper.find('.v-date-picker-table--month tbody tr:first-child td:nth-child(3) button').trigger('click')\n    expect(cb.mock.calls[0][0]).toEqual(\n      expect.arrayContaining([fromDate])\n    )\n\n    wrapper.find('.v-date-picker-table--month tbody tr:first-child+tr+tr td:nth-child(2) button').trigger('click')\n    expect(cb.mock.calls[0][0][0]).toBe(fromDate)\n    expect(cb.mock.calls[1][0][0]).toBe(toDate)\n  })\n\n  it('should add class for the first and last days in range', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        range: true,\n        showCurrent: '2019',\n        type: 'month',\n        value: ['2019-01', '2019-02'],\n      },\n    })\n\n    expect(wrapper.findAll('.v-date-picker-table--month tbody button.v-date-picker--first-in-range')\n      .exists()).toBe(true)\n    expect(wrapper.findAll('.v-date-picker-table--month tbody button.v-date-picker--last-in-range')\n      .exists()).toBe(true)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VDatePicker/__tests__/VDatePicker.spec.browser.tsx",
    "content": "// Components\nimport { VDatePicker } from '..'\n\n// Utilities\nimport { render, screen, userEvent, waitIdle } from '@test'\nimport { within } from '@testing-library/vue'\nimport { commands } from 'vitest/browser'\nimport { nextTick, ref } from 'vue'\n\ndescribe('VDatePicker', () => {\n  it('selects a range of dates', async () => {\n    const model = ref<unknown[]>([])\n    render(() => (\n      <VDatePicker v-model={ model.value } multiple=\"range\" />\n    ))\n\n    // Select two days in the same month (e.g., 10th and 20th)\n    await userEvent.click(await screen.findByText(10))\n    await userEvent.click(await screen.findByText(20))\n\n    // Expect only 2 dates (first and last) to be selected\n    await expect.poll(() => model.value).toHaveLength(2)\n\n    // Verify the correct dates are selected (10th and 20th)\n    const dates = model.value as Date[]\n\n    expect(dates[0].getDate()).toBe(10)\n    expect(dates[1].getDate()).toBe(20)\n  })\n\n  it('selects a range of dates across month boundary', async () => {\n    const model = ref<unknown[]>([])\n    render(() => (\n      <VDatePicker v-model={ model.value } multiple=\"range\" />\n    ))\n\n    // Select 2025-01-07\n    await userEvent.click(await screen.findByTestId('year-btn'))\n    const yearsContainer = await screen.getByCSS('.v-date-picker-years__content')\n    await userEvent.click(await within(yearsContainer).getByText('2025'))\n    await userEvent.click(await screen.findByTestId('month-btn'))\n    await commands.waitStable('.v-date-picker-months')\n    const monthsContainer = await screen.getByCSS('.v-date-picker-months__content')\n    await userEvent.click(await within(monthsContainer).findByText('Jan'))\n    await commands.waitStable('.v-date-picker-month__days')\n    await userEvent.click(await screen.findByText(7))\n\n    // Select 2025-02-07\n    await userEvent.click(await screen.findByTestId('next-month'))\n    await commands.waitStable('.v-date-picker-month__days')\n    await userEvent.click(await screen.findByText(7))\n\n    // Expect only 2 dates (first and last) spanning across two months\n    await expect.poll(() => model.value).toHaveLength(2)\n\n    // Verify the correct dates are selected (2025-01-07 and 2025-02-07)\n    const dates = model.value as Date[]\n\n    expect(dates[0].getFullYear()).toBe(2025)\n    expect(dates[0].getMonth()).toBe(0)\n    expect(dates[0].getDate()).toBe(7)\n    expect(dates[1].getFullYear()).toBe(2025)\n    expect(dates[1].getMonth()).toBe(1)\n    expect(dates[1].getDate()).toBe(7)\n  })\n\n  it('does not trigger infinite loop when first-day-of-week is out of range', async () => {\n    const model = ref<unknown[]>([])\n    const firstDay = ref<number>(0)\n    render(() => (\n      <VDatePicker v-model={ model.value } firstDayOfWeek={ firstDay.value } multiple />\n    ))\n\n    await userEvent.click(await screen.findByText(10))\n    await userEvent.click(await screen.findByText(13))\n    await expect.poll(() => model.value).toHaveLength(2)\n\n    await commands.abortAfter(5000, 'VDatePicker infinite loop detection')\n\n    firstDay.value = -1.5\n    await nextTick()\n    await waitIdle()\n\n    await userEvent.click(await screen.findByText(21))\n    await userEvent.click(await screen.findByText(7))\n    await expect.poll(() => model.value).toHaveLength(4)\n\n    expect('Invalid firstDayOfWeek, expected discrete number in range [0-6]').toHaveBeenTipped()\n\n    await commands.clearAbortTimeout()\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VDatePicker/__tests__/VDatePickerHeader.spec.ts",
    "content": "// @ts-nocheck\n/* eslint-disable */\n\n// import VDatePickerHeader from '../VDatePickerHeader'\n// import { Lang } from '../../../services/lang'\n// import { preset } from '../../../presets/default'\nimport {\n  mount,\n  MountOptions,\n  Wrapper,\n} from '@vue/test-utils'\n// import Vue from 'vue'\n\n// Vue.prototype.$vuetify = {\n//   icons: {\n//     values: {\n//       next: 'mdi-chevron-right',\n//       prev: 'mdi-chevron-left',\n//     },\n//   },\n// }\n\ndescribe.skip('VDatePickerHeader.ts', () => {\n  type Instance = InstanceType<typeof VDatePickerHeader>\n  let mountFunction: (options?: MountOptions<Instance>) => Wrapper<Instance>\n  beforeEach(() => {\n    mountFunction = (options?: MountOptions<Instance>) => {\n      return mount(VDatePickerHeader, {\n        ...options,\n        mocks: {\n          $vuetify: {\n            rtl: false,\n            lang: new Lang(preset),\n          },\n        },\n      })\n    }\n  })\n\n  it('should render component and match snapshot', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2005-11',\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render disabled component and match snapshot', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2005-11',\n        disabled: true,\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render readonly component and match snapshot', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2005-11',\n        readonly: true,\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render component in RTL mode and match snapshot', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2005-11',\n      },\n    })\n    wrapper.vm.$vuetify.rtl = true\n    await wrapper.vm.$nextTick()\n\n    expect(wrapper.html()).toMatchSnapshot()\n    wrapper.vm.$vuetify.rtl = undefined\n  })\n\n  it('should render component with year value and match snapshot', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2005',\n      },\n    })\n\n    expect(wrapper.findAll('.v-date-picker-header__value div').at(0).element.textContent).toBe('2005')\n  })\n\n  it('should render prev/next icons', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2005',\n        prevIcon: 'foo',\n        nextIcon: 'bar',\n      },\n    })\n\n    expect(wrapper.findAll('.v-icon').at(0).element.textContent).toBe('foo')\n    expect(wrapper.findAll('.v-icon').at(1).element.textContent).toBe('bar')\n  })\n\n  it('should render component with own formatter and match snapshot', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2005-11',\n        format: value => `(${value})`,\n      },\n    })\n\n    expect(wrapper.findAll('.v-date-picker-header__value div').at(0).element.textContent).toBe('(2005-11)')\n  })\n\n  it('should render colored component and match snapshot', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2005-11',\n        color: 'green lighten-1',\n      },\n    })\n\n    const div = wrapper.findAll('.v-date-picker-header__value div').at(0)\n    expect(div.classes('green--text')).toBe(true)\n    expect(div.classes('text--lighten-1')).toBe(true)\n  })\n\n  it('should render component with default slot and match snapshot', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2005-11',\n      },\n      slots: {\n        default: '<span>foo</span>',\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should trigger event on selector click', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2005-11',\n      },\n    })\n\n    const toggle = jest.fn()\n    wrapper.vm.$on('toggle', toggle)\n\n    wrapper.findAll('.v-date-picker-header__value button').at(0).trigger('click')\n    expect(toggle).toHaveBeenCalled()\n  })\n\n  it('should trigger event on arrows click', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2005-12',\n      },\n    })\n\n    const input = jest.fn()\n    wrapper.vm.$on('input', input)\n\n    wrapper.findAll('button.v-btn').at(0).trigger('click')\n    expect(input).toHaveBeenCalledWith('2005-11')\n\n    wrapper.findAll('button.v-btn').at(1).trigger('click')\n    expect(input).toHaveBeenCalledWith('2006-01')\n  })\n\n  it('should calculate prev/next value', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2005-12',\n      },\n    })\n    expect(wrapper.vm.calculateChange(-1)).toBe('2005-11')\n    expect(wrapper.vm.calculateChange(+1)).toBe('2006-01')\n\n    wrapper.setProps({\n      value: '2005',\n    })\n    expect(wrapper.vm.calculateChange(-1)).toBe('2004')\n    expect(wrapper.vm.calculateChange(+1)).toBe('2006')\n  })\n\n  it.skip('should watch value and run transition', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: 2005,\n      },\n    })\n\n    wrapper.setProps({\n      value: 2006,\n    })\n    await wrapper.vm.$nextTick()\n    expect(wrapper.findAll('.v-date-picker-header__value div').at(0).classes('tab-transition-enter')).toBe(true)\n    expect(wrapper.findAll('.v-date-picker-header__value div').at(0).classes('tab-transition-enter-active')).toBe(true)\n  })\n\n  it.skip('should watch value and run reverse transition', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: 2005,\n      },\n    })\n\n    wrapper.setProps({\n      value: 2004,\n    })\n    await wrapper.vm.$nextTick()\n    expect(wrapper.findAll('.v-date-picker-header__value div').at(0).classes('tab-reverse-transition-enter')).toBe(true)\n    expect(wrapper.findAll('.v-date-picker-header__value div').at(0).classes('tab-reverse-transition-enter-active')).toBe(true)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VDatePicker/__tests__/VDatePickerTitle.spec.ts",
    "content": "// @ts-nocheck\n/* eslint-disable */\n\n// import VDatePickerTitle from '../VDatePickerTitle'\nimport {\n  mount,\n  MountOptions,\n  Wrapper,\n} from '@vue/test-utils'\n\ndescribe.skip('VDatePickerTitle.ts', () => {\n  type Instance = InstanceType<typeof VDatePickerTitle>\n  let mountFunction: (options?: MountOptions<Instance>) => Wrapper<Instance>\n  beforeEach(() => {\n    mountFunction = (options?: MountOptions<Instance>) => {\n      return mount(VDatePickerTitle, options)\n    }\n  })\n\n  it('should render component and match snapshot', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        year: '1234',\n        date: '2005-11-01',\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render disabled component and match snapshot', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        year: '1234',\n        date: '2005-11-01',\n        disabled: true,\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render readonly component and match snapshot', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        year: '1234',\n        date: '2005-11-01',\n        readonly: true,\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render component when selecting year and match snapshot', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        year: '1234',\n        date: '2005-11-01',\n        selectingYear: true,\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render year icon', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        year: '1234',\n        yearIcon: 'year',\n        date: '2005-11-01',\n      },\n    })\n\n    expect(wrapper.findAll('.v-date-picker-title__year').at(0).html()).toMatchSnapshot()\n  })\n\n  it('should emit input event on year/date click', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        year: '1234',\n        yearIcon: 'year',\n        date: '2005-11-01',\n      },\n    })\n\n    const input = jest.fn(value => wrapper.setProps({ selectingYear: value }))\n    wrapper.vm.$on('update:selecting-year', input)\n\n    wrapper.findAll('.v-date-picker-title__date').at(0).trigger('click')\n    expect(input).not.toHaveBeenCalled()\n    wrapper.findAll('.v-date-picker-title__year').at(0).trigger('click')\n    expect(input).toHaveBeenCalledWith(true)\n    wrapper.findAll('.v-date-picker-title__date').at(0).trigger('click')\n    expect(input).toHaveBeenCalledWith(false)\n    wrapper.findAll('.v-date-picker-title__year').at(0).trigger('click')\n    wrapper.findAll('.v-date-picker-title__year').at(0).trigger('click')\n    expect(input).toHaveBeenCalledWith(false)\n  })\n\n  it('should have the correct transition', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        year: '2018',\n        date: 'Tue, Mar 3',\n        value: '2018-03-03',\n      },\n    })\n\n    expect(wrapper.vm.isReversing).toBe(false)\n\n    wrapper.setProps({\n      date: 'Wed, Mar 4',\n      value: '2018-03-04',\n    })\n\n    expect(wrapper.vm.isReversing).toBe(false)\n\n    wrapper.setProps({\n      date: 'Wed, Mar 3',\n      value: '2018-03-03',\n    })\n\n    expect(wrapper.vm.isReversing).toBe(true)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VDatePicker/__tests__/VDatePickerYears.spec.ts",
    "content": "// @ts-nocheck\n/* eslint-disable */\n\n// import VDatePickerYears from '../VDatePickerYears'\nimport {\n  mount,\n  MountOptions,\n  Wrapper,\n} from '@vue/test-utils'\n\ndescribe.skip('VDatePickerYears.ts', () => {\n  type Instance = InstanceType<typeof VDatePickerYears>\n  let mountFunction: (options?: MountOptions<Instance>) => Wrapper<Instance>\n  beforeEach(() => {\n    mountFunction = (options?: MountOptions<Instance>) => {\n      return mount(VDatePickerYears, {\n        ...options,\n        mocks: {\n          $vuetify: {\n            rtl: false,\n            lang: {\n              t: () => {},\n            },\n          },\n        },\n      })\n    }\n  })\n\n  it('should render component and match snapshot', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: '2000',\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should respect min/max props', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        min: 1234,\n        max: 1238,\n      },\n    })\n\n    expect(wrapper.findAll('li:first-child').at(0).element.textContent).toBe('1238')\n    expect(wrapper.findAll('li:last-child').at(0).element.textContent).toBe('1234')\n  })\n\n  it('should not allow min to be greater then max', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        min: 1238,\n        max: 1234,\n      },\n    })\n    expect(wrapper.findAll('li')).toHaveLength(1)\n    expect(wrapper.findAll('li').at(0).element.textContent).toBe('1234')\n    expect(wrapper.findAll('li').at(0).element.textContent).toBe('1234')\n  })\n\n  it('should emit event on year click', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: 1999,\n      },\n    })\n\n    const input = jest.fn()\n    wrapper.vm.$on('input', input)\n\n    wrapper.findAll('li.active + li').at(0).trigger('click')\n    expect(input).toHaveBeenCalledWith(1998)\n  })\n\n  it('should format years', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        format: year => `(${year})`,\n        min: 1001,\n        max: 1001,\n      },\n    })\n\n    expect(wrapper.findAll('li').at(0).element.textContent).toBe('(1001)')\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VDatePicker/__tests__/__snapshots__/VDatePicker.date.spec.ts.snap",
    "content": "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html\n\nexports[`VDatePicker.ts should handle date range picker with null value 1`] = `\n<div class=\"v-picker__title__btn v-date-picker-title__date v-picker__title__btn--active\">\n  <div>\n    &nbsp;\n  </div>\n</div>\n`;\n\nexports[`VDatePicker.ts should match snapshot with colored picker & header 1`] = `\n<div class=\"v-picker v-card v-picker--date theme--light\">\n  <div class=\"v-picker__title orange darken-1\">\n    <div class=\"v-date-picker-title\">\n      <div class=\"v-picker__title__btn v-date-picker-title__year\">\n        2005\n      </div>\n      <div class=\"v-picker__title__btn v-date-picker-title__date v-picker__title__btn--active\">\n        <div>\n          Tue, Nov 1\n        </div>\n      </div>\n    </div>\n  </div>\n  <div class=\"v-picker__body theme--light\"\n       style=\"width: 290px;\"\n  >\n    <div>\n      <div class=\"v-date-picker-header theme--light\">\n        <button type=\"button\"\n                class=\"v-btn v-btn--icon v-btn--round theme--light v-size--default\"\n                aria-label=\"Previous month\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon notranslate mdi mdi-chevron-left theme--light\"\n            >\n            </i>\n          </span>\n        </button>\n        <div class=\"v-date-picker-header__value\">\n          <div class=\"primary--text\">\n            <button type=\"button\">\n              November 2005\n            </button>\n          </div>\n        </div>\n        <button type=\"button\"\n                class=\"v-btn v-btn--icon v-btn--round theme--light v-size--default\"\n                aria-label=\"Next month\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon notranslate mdi mdi-chevron-right theme--light\"\n            >\n            </i>\n          </span>\n        </button>\n      </div>\n      <div class=\"v-date-picker-table v-date-picker-table--date theme--light\">\n        <table>\n          <thead>\n            <tr>\n              <th>\n                S\n              </th>\n              <th>\n                M\n              </th>\n              <th>\n                T\n              </th>\n              <th>\n                W\n              </th>\n              <th>\n                T\n              </th>\n              <th>\n                F\n              </th>\n              <th>\n                S\n              </th>\n            </tr>\n          </thead>\n          <tbody>\n            <tr>\n              <td>\n              </td>\n              <td>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--active v-btn--rounded theme--light primary\"\n                >\n                  <div class=\"v-btn__content\">\n                    1\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    2\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    3\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    4\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    5\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    6\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    7\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    8\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    9\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    10\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    11\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    12\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    13\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    14\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    15\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    16\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    17\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    18\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    19\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    20\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    21\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    22\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    23\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    24\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    25\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    26\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    27\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    28\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    29\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    30\n                  </div>\n                </button>\n              </td>\n              <td>\n              </td>\n              <td>\n              </td>\n              <td>\n              </td>\n            </tr>\n          </tbody>\n        </table>\n      </div>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDatePicker.ts should match snapshot with colored picker 1`] = `\n<div class=\"v-picker v-card v-picker--date theme--light\">\n  <div class=\"v-picker__title orange darken-1\">\n    <div class=\"v-date-picker-title\">\n      <div class=\"v-picker__title__btn v-date-picker-title__year\">\n        2005\n      </div>\n      <div class=\"v-picker__title__btn v-date-picker-title__date v-picker__title__btn--active\">\n        <div>\n          Tue, Nov 1\n        </div>\n      </div>\n    </div>\n  </div>\n  <div class=\"v-picker__body theme--light\"\n       style=\"width: 290px;\"\n  >\n    <div>\n      <div class=\"v-date-picker-header theme--light\">\n        <button type=\"button\"\n                class=\"v-btn v-btn--icon v-btn--round theme--light v-size--default\"\n                aria-label=\"Previous month\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon notranslate mdi mdi-chevron-left theme--light\"\n            >\n            </i>\n          </span>\n        </button>\n        <div class=\"v-date-picker-header__value\">\n          <div class=\"orange--text text--darken-1\">\n            <button type=\"button\">\n              November 2005\n            </button>\n          </div>\n        </div>\n        <button type=\"button\"\n                class=\"v-btn v-btn--icon v-btn--round theme--light v-size--default\"\n                aria-label=\"Next month\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon notranslate mdi mdi-chevron-right theme--light\"\n            >\n            </i>\n          </span>\n        </button>\n      </div>\n      <div class=\"v-date-picker-table v-date-picker-table--date theme--light\">\n        <table>\n          <thead>\n            <tr>\n              <th>\n                S\n              </th>\n              <th>\n                M\n              </th>\n              <th>\n                T\n              </th>\n              <th>\n                W\n              </th>\n              <th>\n                T\n              </th>\n              <th>\n                F\n              </th>\n              <th>\n                S\n              </th>\n            </tr>\n          </thead>\n          <tbody>\n            <tr>\n              <td>\n              </td>\n              <td>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--active v-btn--rounded theme--light orange darken-1\"\n                >\n                  <div class=\"v-btn__content\">\n                    1\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    2\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    3\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    4\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    5\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    6\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    7\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    8\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    9\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    10\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    11\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    12\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    13\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    14\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    15\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    16\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    17\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    18\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    19\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    20\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    21\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    22\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    23\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    24\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    25\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    26\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    27\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    28\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    29\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    30\n                  </div>\n                </button>\n              </td>\n              <td>\n              </td>\n              <td>\n              </td>\n              <td>\n              </td>\n            </tr>\n          </tbody>\n        </table>\n      </div>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDatePicker.ts should match snapshot with dark theme 1`] = `\n<div class=\"v-picker v-card v-picker--date theme--dark\">\n  <div class=\"v-picker__title\">\n    <div class=\"v-date-picker-title\">\n      <div class=\"v-picker__title__btn v-date-picker-title__year\">\n        2013\n      </div>\n      <div class=\"v-picker__title__btn v-date-picker-title__date v-picker__title__btn--active\">\n        <div>\n          Tue, May 7\n        </div>\n      </div>\n    </div>\n  </div>\n  <div class=\"v-picker__body theme--dark\"\n       style=\"width: 290px;\"\n  >\n    <div>\n      <div class=\"v-date-picker-header theme--dark\">\n        <button type=\"button\"\n                class=\"v-btn v-btn--icon v-btn--round theme--dark v-size--default\"\n                aria-label=\"Previous month\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon notranslate mdi mdi-chevron-left theme--dark\"\n            >\n            </i>\n          </span>\n        </button>\n        <div class=\"v-date-picker-header__value\">\n          <div class=\"accent--text\">\n            <button type=\"button\">\n              May 2013\n            </button>\n          </div>\n        </div>\n        <button type=\"button\"\n                class=\"v-btn v-btn--icon v-btn--round theme--dark v-size--default\"\n                aria-label=\"Next month\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon notranslate mdi mdi-chevron-right theme--dark\"\n            >\n            </i>\n          </span>\n        </button>\n      </div>\n      <div class=\"v-date-picker-table v-date-picker-table--date theme--dark\">\n        <table>\n          <thead>\n            <tr>\n              <th>\n                S\n              </th>\n              <th>\n                M\n              </th>\n              <th>\n                T\n              </th>\n              <th>\n                W\n              </th>\n              <th>\n                T\n              </th>\n              <th>\n                F\n              </th>\n              <th>\n                S\n              </th>\n            </tr>\n          </thead>\n          <tbody>\n            <tr>\n              <td>\n              </td>\n              <td>\n              </td>\n              <td>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--dark\"\n                >\n                  <div class=\"v-btn__content\">\n                    1\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--dark\"\n                >\n                  <div class=\"v-btn__content\">\n                    2\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--dark\"\n                >\n                  <div class=\"v-btn__content\">\n                    3\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--dark\"\n                >\n                  <div class=\"v-btn__content\">\n                    4\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--dark\"\n                >\n                  <div class=\"v-btn__content\">\n                    5\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--dark\"\n                >\n                  <div class=\"v-btn__content\">\n                    6\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--active v-btn--rounded theme--dark accent\"\n                >\n                  <div class=\"v-btn__content\">\n                    7\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--dark\"\n                >\n                  <div class=\"v-btn__content\">\n                    8\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--dark\"\n                >\n                  <div class=\"v-btn__content\">\n                    9\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--dark\"\n                >\n                  <div class=\"v-btn__content\">\n                    10\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--dark\"\n                >\n                  <div class=\"v-btn__content\">\n                    11\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--dark\"\n                >\n                  <div class=\"v-btn__content\">\n                    12\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--dark\"\n                >\n                  <div class=\"v-btn__content\">\n                    13\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--dark\"\n                >\n                  <div class=\"v-btn__content\">\n                    14\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--dark\"\n                >\n                  <div class=\"v-btn__content\">\n                    15\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--dark\"\n                >\n                  <div class=\"v-btn__content\">\n                    16\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--dark\"\n                >\n                  <div class=\"v-btn__content\">\n                    17\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--dark\"\n                >\n                  <div class=\"v-btn__content\">\n                    18\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--dark\"\n                >\n                  <div class=\"v-btn__content\">\n                    19\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--dark\"\n                >\n                  <div class=\"v-btn__content\">\n                    20\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--dark\"\n                >\n                  <div class=\"v-btn__content\">\n                    21\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--dark\"\n                >\n                  <div class=\"v-btn__content\">\n                    22\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--dark\"\n                >\n                  <div class=\"v-btn__content\">\n                    23\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--dark\"\n                >\n                  <div class=\"v-btn__content\">\n                    24\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--dark\"\n                >\n                  <div class=\"v-btn__content\">\n                    25\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--dark\"\n                >\n                  <div class=\"v-btn__content\">\n                    26\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--dark\"\n                >\n                  <div class=\"v-btn__content\">\n                    27\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--dark\"\n                >\n                  <div class=\"v-btn__content\">\n                    28\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--dark\"\n                >\n                  <div class=\"v-btn__content\">\n                    29\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--dark\"\n                >\n                  <div class=\"v-btn__content\">\n                    30\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--dark\"\n                >\n                  <div class=\"v-btn__content\">\n                    31\n                  </div>\n                </button>\n              </td>\n              <td>\n              </td>\n            </tr>\n          </tbody>\n        </table>\n      </div>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDatePicker.ts should match snapshot with default settings 1`] = `\n<div class=\"v-picker v-card v-picker--date theme--light\">\n  <div class=\"v-picker__title primary\">\n    <div class=\"v-date-picker-title\">\n      <div class=\"v-picker__title__btn v-date-picker-title__year\">\n        2013\n      </div>\n      <div class=\"v-picker__title__btn v-date-picker-title__date v-picker__title__btn--active\">\n        <div>\n          Tue, May 7\n        </div>\n      </div>\n    </div>\n  </div>\n  <div class=\"v-picker__body theme--light\"\n       style=\"width: 290px;\"\n  >\n    <div>\n      <div class=\"v-date-picker-header theme--light\">\n        <button type=\"button\"\n                class=\"v-btn v-btn--icon v-btn--round theme--light v-size--default\"\n                aria-label=\"Previous month\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon notranslate mdi mdi-chevron-left theme--light\"\n            >\n            </i>\n          </span>\n        </button>\n        <div class=\"v-date-picker-header__value\">\n          <div class=\"accent--text\">\n            <button type=\"button\">\n              May 2013\n            </button>\n          </div>\n        </div>\n        <button type=\"button\"\n                class=\"v-btn v-btn--icon v-btn--round theme--light v-size--default\"\n                aria-label=\"Next month\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon notranslate mdi mdi-chevron-right theme--light\"\n            >\n            </i>\n          </span>\n        </button>\n      </div>\n      <div class=\"v-date-picker-table v-date-picker-table--date theme--light\">\n        <table>\n          <thead>\n            <tr>\n              <th>\n                S\n              </th>\n              <th>\n                M\n              </th>\n              <th>\n                T\n              </th>\n              <th>\n                W\n              </th>\n              <th>\n                T\n              </th>\n              <th>\n                F\n              </th>\n              <th>\n                S\n              </th>\n            </tr>\n          </thead>\n          <tbody>\n            <tr>\n              <td>\n              </td>\n              <td>\n              </td>\n              <td>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    1\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    2\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    3\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    4\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    5\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    6\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--active v-btn--rounded theme--light accent\"\n                >\n                  <div class=\"v-btn__content\">\n                    7\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    8\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    9\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    10\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    11\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    12\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    13\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    14\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    15\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    16\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    17\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    18\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    19\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    20\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    21\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    22\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    23\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    24\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    25\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    26\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    27\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    28\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    29\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    30\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    31\n                  </div>\n                </button>\n              </td>\n              <td>\n              </td>\n            </tr>\n          </tbody>\n        </table>\n      </div>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDatePicker.ts should match snapshot with year icon 1`] = `\n<div class=\"v-picker__title primary\">\n  <div class=\"v-date-picker-title\">\n    <div class=\"v-picker__title__btn v-date-picker-title__year\">\n      2005\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate material-icons theme--dark\"\n      >\n        year\n      </i>\n    </div>\n    <div class=\"v-picker__title__btn v-date-picker-title__date v-picker__title__btn--active\">\n      <div>\n        Tue, Nov 1\n      </div>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDatePicker.ts should render component with min/max props 1`] = `\n\n<div class=\"v-picker v-card v-picker--date theme--light\">\n  <div class=\"v-picker__title primary\">\n    <div class=\"v-date-picker-title\">\n      <div class=\"v-picker__title__btn v-date-picker-title__year\">\n        2013\n      </div>\n      <div class=\"v-picker__title__btn v-date-picker-title__date v-picker__title__btn--active\">\n        <div>\n          Mon, Jan 7\n        </div>\n      </div>\n    </div>\n  </div>\n  <div class=\"v-picker__body theme--light\"\n       style=\"width: 290px;\"\n  >\n    <div>\n      <div class=\"v-date-picker-header theme--light\">\n        <button disabled=\"disabled\"\n                type=\"button\"\n                class=\"v-btn v-btn--disabled v-btn--fab v-btn--flat v-btn--icon v-btn--round theme--light v-size--default\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon mdi mdi-chevron-left theme--light\"\n            >\n            </i>\n          </span>\n        </button>\n        <div class=\"v-date-picker-header__value\">\n          <div class=\"accent--text\">\n            <button type=\"button\">\n              January 2013\n            </button>\n          </div>\n        </div>\n        <button disabled=\"disabled\"\n                type=\"button\"\n                class=\"v-btn v-btn--disabled v-btn--fab v-btn--flat v-btn--icon v-btn--round theme--light v-size--default\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon mdi mdi-chevron-right theme--light\"\n            >\n            </i>\n          </span>\n        </button>\n      </div>\n      <div class=\"v-date-picker-table v-date-picker-table--date theme--light\">\n        <table>\n          <thead>\n            <tr>\n              <th>\n                S\n              </th>\n              <th>\n                M\n              </th>\n              <th>\n                T\n              </th>\n              <th>\n                W\n              </th>\n              <th>\n                T\n              </th>\n              <th>\n                F\n              </th>\n              <th>\n                S\n              </th>\n            </tr>\n          </thead>\n          <tbody>\n            <tr>\n              <td>\n              </td>\n              <td>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    1\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    2\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    3\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    4\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    5\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    6\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--active v-btn--rounded theme--light accent\"\n                >\n                  <div class=\"v-btn__content\">\n                    7\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    8\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    9\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    10\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    11\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    12\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    13\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    14\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    15\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    16\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    17\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    18\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    19\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    20\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    21\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    22\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    23\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    24\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    25\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    26\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    27\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    28\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    29\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    30\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    31\n                  </div>\n                </button>\n              </td>\n            </tr>\n          </tbody>\n        </table>\n      </div>\n    </div>\n  </div>\n</div>\n\n`;\n\nexports[`VDatePicker.ts should render component with min/max props 2`] = `\n\n<div class=\"v-picker v-card v-picker--date theme--light\">\n  <div class=\"v-picker__title primary\">\n    <div class=\"v-date-picker-title\">\n      <div class=\"v-picker__title__btn v-date-picker-title__year\">\n        2013\n      </div>\n      <div class=\"v-picker__title__btn v-date-picker-title__date v-picker__title__btn--active\">\n        <div>\n          Mon, Jan 7\n        </div>\n      </div>\n    </div>\n  </div>\n  <div class=\"v-picker__body theme--light\"\n       style=\"width: 290px;\"\n  >\n    <div class=\"fade-transition-leave fade-transition-leave-active\">\n      <div class=\"v-date-picker-header theme--light\">\n        <button disabled=\"disabled\"\n                type=\"button\"\n                class=\"v-btn v-btn--disabled v-btn--fab v-btn--flat v-btn--icon v-btn--round theme--light v-size--default\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon mdi mdi-chevron-left theme--light\"\n            >\n            </i>\n          </span>\n        </button>\n        <div class=\"v-date-picker-header__value\">\n          <div class=\"accent--text\">\n            <button type=\"button\">\n              January 2013\n            </button>\n          </div>\n        </div>\n        <button disabled=\"disabled\"\n                type=\"button\"\n                class=\"v-btn v-btn--disabled v-btn--fab v-btn--flat v-btn--icon v-btn--round theme--light v-size--default\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon mdi mdi-chevron-right theme--light\"\n            >\n            </i>\n          </span>\n        </button>\n      </div>\n      <div class=\"v-date-picker-table v-date-picker-table--date theme--light\">\n        <table>\n          <thead>\n            <tr>\n              <th>\n                S\n              </th>\n              <th>\n                M\n              </th>\n              <th>\n                T\n              </th>\n              <th>\n                W\n              </th>\n              <th>\n                T\n              </th>\n              <th>\n                F\n              </th>\n              <th>\n                S\n              </th>\n            </tr>\n          </thead>\n          <tbody>\n            <tr>\n              <td>\n              </td>\n              <td>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    1\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    2\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    3\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    4\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    5\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    6\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--active v-btn--rounded theme--light accent\"\n                >\n                  <div class=\"v-btn__content\">\n                    7\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    8\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    9\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    10\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    11\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    12\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    13\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    14\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    15\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    16\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    17\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    18\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    19\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    20\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    21\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    22\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    23\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    24\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    25\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    26\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    27\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    28\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    29\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    30\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    31\n                  </div>\n                </button>\n              </td>\n            </tr>\n          </tbody>\n        </table>\n      </div>\n    </div>\n    <div class=\"fade-transition-enter fade-transition-enter-active\">\n      <div class=\"v-date-picker-header theme--light\">\n        <button disabled=\"disabled\"\n                type=\"button\"\n                class=\"v-btn v-btn--disabled v-btn--fab v-btn--flat v-btn--icon v-btn--round theme--light v-size--default\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon mdi mdi-chevron-left theme--light\"\n            >\n            </i>\n          </span>\n        </button>\n        <div class=\"v-date-picker-header__value\">\n          <div class=\"accent--text\">\n            <button type=\"button\">\n              2013\n            </button>\n          </div>\n        </div>\n        <button disabled=\"disabled\"\n                type=\"button\"\n                class=\"v-btn v-btn--disabled v-btn--fab v-btn--flat v-btn--icon v-btn--round theme--light v-size--default\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon mdi mdi-chevron-right theme--light\"\n            >\n            </i>\n          </span>\n        </button>\n      </div>\n      <div class=\"v-date-picker-table v-date-picker-table--month theme--light\">\n        <table>\n          <tbody>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--active theme--light accent\"\n                >\n                  <div class=\"v-btn__content\">\n                    Jan\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--flat v-btn--text v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    Feb\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--flat v-btn--text v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    Mar\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--flat v-btn--text v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    Apr\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--flat v-btn--text v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    May\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--flat v-btn--text v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    Jun\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--flat v-btn--text v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    Jul\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--flat v-btn--text v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    Aug\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--flat v-btn--text v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    Sep\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--flat v-btn--text v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    Oct\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--flat v-btn--text v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    Nov\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--flat v-btn--text v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    Dec\n                  </div>\n                </button>\n              </td>\n            </tr>\n          </tbody>\n        </table>\n      </div>\n    </div>\n  </div>\n</div>\n\n`;\n\nexports[`VDatePicker.ts should render component with min/max props 3`] = `\n\n<div class=\"v-picker v-card v-picker--date theme--light\">\n  <div class=\"v-picker__title primary\">\n    <div class=\"v-date-picker-title\">\n      <div class=\"v-picker__title__btn v-date-picker-title__year v-picker__title__btn--active\">\n        2013\n      </div>\n      <div class=\"v-picker__title__btn v-date-picker-title__date\">\n        <div>\n          Mon, Jan 7\n        </div>\n      </div>\n    </div>\n  </div>\n  <div class=\"v-picker__body theme--light\"\n       style=\"width: 290px;\"\n  >\n    <div class=\"fade-transition-leave fade-transition-leave-active\">\n      <div class=\"v-date-picker-header theme--light\">\n        <button disabled=\"disabled\"\n                type=\"button\"\n                class=\"v-btn v-btn--disabled v-btn--fab v-btn--flat v-btn--icon v-btn--round theme--light v-size--default\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon mdi mdi-chevron-left theme--light\"\n            >\n            </i>\n          </span>\n        </button>\n        <div class=\"v-date-picker-header__value\">\n          <div class=\"accent--text\">\n            <button type=\"button\">\n              January 2013\n            </button>\n          </div>\n        </div>\n        <button disabled=\"disabled\"\n                type=\"button\"\n                class=\"v-btn v-btn--disabled v-btn--fab v-btn--flat v-btn--icon v-btn--round theme--light v-size--default\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon mdi mdi-chevron-right theme--light\"\n            >\n            </i>\n          </span>\n        </button>\n      </div>\n      <div class=\"v-date-picker-table v-date-picker-table--date theme--light\">\n        <table>\n          <thead>\n            <tr>\n              <th>\n                S\n              </th>\n              <th>\n                M\n              </th>\n              <th>\n                T\n              </th>\n              <th>\n                W\n              </th>\n              <th>\n                T\n              </th>\n              <th>\n                F\n              </th>\n              <th>\n                S\n              </th>\n            </tr>\n          </thead>\n          <tbody>\n            <tr>\n              <td>\n              </td>\n              <td>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    1\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    2\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    3\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    4\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    5\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    6\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--active v-btn--rounded theme--light accent\"\n                >\n                  <div class=\"v-btn__content\">\n                    7\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    8\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    9\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    10\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    11\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    12\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    13\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    14\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    15\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    16\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    17\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    18\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    19\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    20\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    21\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    22\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    23\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    24\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    25\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    26\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    27\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    28\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    29\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    30\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    31\n                  </div>\n                </button>\n              </td>\n            </tr>\n          </tbody>\n        </table>\n      </div>\n    </div>\n    <div class=\"fade-transition-leave fade-transition-leave-active\">\n      <div class=\"v-date-picker-header theme--light\">\n        <button disabled=\"disabled\"\n                type=\"button\"\n                class=\"v-btn v-btn--disabled v-btn--fab v-btn--flat v-btn--icon v-btn--round theme--light v-size--default\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon mdi mdi-chevron-left theme--light\"\n            >\n            </i>\n          </span>\n        </button>\n        <div class=\"v-date-picker-header__value\">\n          <div class=\"accent--text\">\n            <button type=\"button\">\n              2013\n            </button>\n          </div>\n        </div>\n        <button disabled=\"disabled\"\n                type=\"button\"\n                class=\"v-btn v-btn--disabled v-btn--fab v-btn--flat v-btn--icon v-btn--round theme--light v-size--default\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon mdi mdi-chevron-right theme--light\"\n            >\n            </i>\n          </span>\n        </button>\n      </div>\n      <div class=\"v-date-picker-table v-date-picker-table--month theme--light\">\n        <table>\n          <tbody>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--active theme--light accent\"\n                >\n                  <div class=\"v-btn__content\">\n                    Jan\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--flat v-btn--text v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    Feb\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--flat v-btn--text v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    Mar\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--flat v-btn--text v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    Apr\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--flat v-btn--text v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    May\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--flat v-btn--text v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    Jun\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--flat v-btn--text v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    Jul\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--flat v-btn--text v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    Aug\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--flat v-btn--text v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    Sep\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--flat v-btn--text v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    Oct\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--flat v-btn--text v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    Nov\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--flat v-btn--text v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    Dec\n                  </div>\n                </button>\n              </td>\n            </tr>\n          </tbody>\n        </table>\n      </div>\n    </div>\n    <div class=\"fade-transition-enter fade-transition-enter-active\">\n      <ul class=\"v-date-picker-years\">\n        <li class=\"active primary--text\">\n          2013\n        </li>\n      </ul>\n    </div>\n  </div>\n</div>\n\n`;\n\nexports[`VDatePicker.ts should render disabled picker 1`] = `\n<div class=\"v-picker v-card v-picker--date theme--light\">\n  <div class=\"v-picker__title primary\">\n    <div class=\"v-date-picker-title v-date-picker-title--disabled\">\n      <div class=\"v-picker__title__btn v-date-picker-title__year\">\n        2013\n      </div>\n      <div class=\"v-picker__title__btn v-date-picker-title__date v-picker__title__btn--active\">\n        <div>\n          Tue, May 7\n        </div>\n      </div>\n    </div>\n  </div>\n  <div class=\"v-picker__body theme--light\"\n       style=\"width: 290px;\"\n  >\n    <div>\n      <div class=\"v-date-picker-header v-date-picker-header--disabled theme--light\">\n        <button type=\"button\"\n                disabled=\"disabled\"\n                class=\"v-btn v-btn--disabled v-btn--icon v-btn--round theme--light v-size--default\"\n                aria-label=\"Previous month\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon notranslate mdi mdi-chevron-left theme--light\"\n            >\n            </i>\n          </span>\n        </button>\n        <div class=\"v-date-picker-header__value v-date-picker-header__value--disabled\">\n          <div>\n            <button type=\"button\">\n              May 2013\n            </button>\n          </div>\n        </div>\n        <button type=\"button\"\n                disabled=\"disabled\"\n                class=\"v-btn v-btn--disabled v-btn--icon v-btn--round theme--light v-size--default\"\n                aria-label=\"Next month\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon notranslate mdi mdi-chevron-right theme--light\"\n            >\n            </i>\n          </span>\n        </button>\n      </div>\n      <div class=\"v-date-picker-table v-date-picker-table--date v-date-picker-table--disabled theme--light\">\n        <table>\n          <thead>\n            <tr>\n              <th>\n                S\n              </th>\n              <th>\n                M\n              </th>\n              <th>\n                T\n              </th>\n              <th>\n                W\n              </th>\n              <th>\n                T\n              </th>\n              <th>\n                F\n              </th>\n              <th>\n                S\n              </th>\n            </tr>\n          </thead>\n          <tbody>\n            <tr>\n              <td>\n              </td>\n              <td>\n              </td>\n              <td>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    1\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    2\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    3\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    4\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    5\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    6\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--active v-btn--flat v-btn--rounded v-btn--disabled theme--light accent\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    7\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    8\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    9\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    10\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    11\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    12\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    13\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    14\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    15\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    16\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    17\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    18\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    19\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    20\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    21\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    22\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    23\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    24\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    25\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    26\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    27\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    28\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    29\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    30\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--flat v-btn--text v-btn--rounded v-btn--disabled theme--light\"\n                        disabled\n                >\n                  <div class=\"v-btn__content\">\n                    31\n                  </div>\n                </button>\n              </td>\n              <td>\n              </td>\n            </tr>\n          </tbody>\n        </table>\n      </div>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDatePicker.ts should render flat picker 1`] = `\n<div class=\"v-picker v-card v-picker--date v-picker--flat theme--light\">\n  <div class=\"v-picker__title primary\">\n    <div class=\"v-date-picker-title\">\n      <div class=\"v-picker__title__btn v-date-picker-title__year\">\n        2013\n      </div>\n      <div class=\"v-picker__title__btn v-date-picker-title__date v-picker__title__btn--active\">\n        <div>\n          Tue, May 7\n        </div>\n      </div>\n    </div>\n  </div>\n  <div class=\"v-picker__body theme--light\"\n       style=\"width: 290px;\"\n  >\n    <div>\n      <div class=\"v-date-picker-header theme--light\">\n        <button type=\"button\"\n                class=\"v-btn v-btn--icon v-btn--round theme--light v-size--default\"\n                aria-label=\"Previous month\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon notranslate mdi mdi-chevron-left theme--light\"\n            >\n            </i>\n          </span>\n        </button>\n        <div class=\"v-date-picker-header__value\">\n          <div class=\"accent--text\">\n            <button type=\"button\">\n              May 2013\n            </button>\n          </div>\n        </div>\n        <button type=\"button\"\n                class=\"v-btn v-btn--icon v-btn--round theme--light v-size--default\"\n                aria-label=\"Next month\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon notranslate mdi mdi-chevron-right theme--light\"\n            >\n            </i>\n          </span>\n        </button>\n      </div>\n      <div class=\"v-date-picker-table v-date-picker-table--date theme--light\">\n        <table>\n          <thead>\n            <tr>\n              <th>\n                S\n              </th>\n              <th>\n                M\n              </th>\n              <th>\n                T\n              </th>\n              <th>\n                W\n              </th>\n              <th>\n                T\n              </th>\n              <th>\n                F\n              </th>\n              <th>\n                S\n              </th>\n            </tr>\n          </thead>\n          <tbody>\n            <tr>\n              <td>\n              </td>\n              <td>\n              </td>\n              <td>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    1\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    2\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    3\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    4\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    5\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    6\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--active v-btn--rounded theme--light accent\"\n                >\n                  <div class=\"v-btn__content\">\n                    7\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    8\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    9\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    10\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    11\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    12\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    13\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    14\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    15\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    16\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    17\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    18\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    19\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    20\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    21\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    22\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    23\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    24\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    25\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    26\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    27\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    28\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    29\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    30\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    31\n                  </div>\n                </button>\n              </td>\n              <td>\n              </td>\n            </tr>\n          </tbody>\n        </table>\n      </div>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDatePicker.ts should render picker with elevation 1`] = `\n<div class=\"v-picker v-card v-picker--date theme--light elevation-4\">\n  <div class=\"v-picker__title primary\">\n    <div class=\"v-date-picker-title\">\n      <div class=\"v-picker__title__btn v-date-picker-title__year\">\n        2013\n      </div>\n      <div class=\"v-picker__title__btn v-date-picker-title__date v-picker__title__btn--active\">\n        <div>\n          Tue, May 7\n        </div>\n      </div>\n    </div>\n  </div>\n  <div class=\"v-picker__body theme--light\"\n       style=\"width: 290px;\"\n  >\n    <div>\n      <div class=\"v-date-picker-header theme--light\">\n        <button type=\"button\"\n                class=\"v-btn v-btn--icon v-btn--round theme--light v-size--default\"\n                aria-label=\"Previous month\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon notranslate mdi mdi-chevron-left theme--light\"\n            >\n            </i>\n          </span>\n        </button>\n        <div class=\"v-date-picker-header__value\">\n          <div class=\"accent--text\">\n            <button type=\"button\">\n              May 2013\n            </button>\n          </div>\n        </div>\n        <button type=\"button\"\n                class=\"v-btn v-btn--icon v-btn--round theme--light v-size--default\"\n                aria-label=\"Next month\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon notranslate mdi mdi-chevron-right theme--light\"\n            >\n            </i>\n          </span>\n        </button>\n      </div>\n      <div class=\"v-date-picker-table v-date-picker-table--date theme--light\">\n        <table>\n          <thead>\n            <tr>\n              <th>\n                S\n              </th>\n              <th>\n                M\n              </th>\n              <th>\n                T\n              </th>\n              <th>\n                W\n              </th>\n              <th>\n                T\n              </th>\n              <th>\n                F\n              </th>\n              <th>\n                S\n              </th>\n            </tr>\n          </thead>\n          <tbody>\n            <tr>\n              <td>\n              </td>\n              <td>\n              </td>\n              <td>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    1\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    2\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    3\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    4\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    5\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    6\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--active v-btn--rounded theme--light accent\"\n                >\n                  <div class=\"v-btn__content\">\n                    7\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    8\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    9\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    10\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    11\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    12\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    13\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    14\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    15\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    16\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    17\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    18\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    19\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    20\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    21\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    22\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    23\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    24\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    25\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    26\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    27\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    28\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    29\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    30\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    31\n                  </div>\n                </button>\n              </td>\n              <td>\n              </td>\n            </tr>\n          </tbody>\n        </table>\n      </div>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDatePicker.ts should render readonly picker 1`] = `\n<div class=\"v-picker v-card v-picker--date theme--light\">\n  <div class=\"v-picker__title primary\">\n    <div class=\"v-date-picker-title\">\n      <div class=\"v-picker__title__btn v-date-picker-title__year\">\n        2013\n      </div>\n      <div class=\"v-picker__title__btn v-date-picker-title__date v-picker__title__btn--active\">\n        <div>\n          Tue, May 7\n        </div>\n      </div>\n    </div>\n  </div>\n  <div class=\"v-picker__body theme--light\"\n       style=\"width: 290px;\"\n  >\n    <div>\n      <div class=\"v-date-picker-header theme--light\">\n        <button type=\"button\"\n                class=\"v-btn v-btn--icon v-btn--round theme--light v-size--default\"\n                aria-label=\"Previous month\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon notranslate mdi mdi-chevron-left theme--light\"\n            >\n            </i>\n          </span>\n        </button>\n        <div class=\"v-date-picker-header__value\">\n          <div class=\"accent--text\">\n            <button type=\"button\">\n              May 2013\n            </button>\n          </div>\n        </div>\n        <button type=\"button\"\n                class=\"v-btn v-btn--icon v-btn--round theme--light v-size--default\"\n                aria-label=\"Next month\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon notranslate mdi mdi-chevron-right theme--light\"\n            >\n            </i>\n          </span>\n        </button>\n      </div>\n      <div class=\"v-date-picker-table v-date-picker-table--date theme--light\">\n        <table>\n          <thead>\n            <tr>\n              <th>\n                S\n              </th>\n              <th>\n                M\n              </th>\n              <th>\n                T\n              </th>\n              <th>\n                W\n              </th>\n              <th>\n                T\n              </th>\n              <th>\n                F\n              </th>\n              <th>\n                S\n              </th>\n            </tr>\n          </thead>\n          <tbody>\n            <tr>\n              <td>\n              </td>\n              <td>\n              </td>\n              <td>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    1\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    2\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    3\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    4\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    5\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    6\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--active v-btn--rounded theme--light accent\"\n                >\n                  <div class=\"v-btn__content\">\n                    7\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    8\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    9\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    10\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    11\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    12\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    13\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    14\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    15\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    16\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    17\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    18\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    19\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    20\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    21\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    22\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    23\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    24\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    25\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    26\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    27\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    28\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    29\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    30\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-btn--text v-btn--rounded theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    31\n                  </div>\n                </button>\n              </td>\n              <td>\n              </td>\n            </tr>\n          </tbody>\n        </table>\n      </div>\n    </div>\n  </div>\n</div>\n`;\n"
  },
  {
    "path": "packages/vuetify/src/components/VDatePicker/__tests__/__snapshots__/VDatePicker.month.spec.ts.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`VDatePicker.ts should match snapshot with allowed dates as array 1`] = `\n<tbody>\n  <tr>\n    <td>\n      <button type=\"button\"\n              class=\"v-btn v-size--default v-btn--text theme--light\"\n      >\n        <div class=\"v-btn__content\">\n          Jan\n        </div>\n      </button>\n    </td>\n    <td>\n      <button type=\"button\"\n              class=\"v-btn v-size--default v-btn--flat v-btn--text v-btn--disabled theme--light\"\n              disabled\n      >\n        <div class=\"v-btn__content\">\n          Feb\n        </div>\n      </button>\n    </td>\n    <td>\n      <button type=\"button\"\n              class=\"v-btn v-size--default v-btn--text theme--light\"\n      >\n        <div class=\"v-btn__content\">\n          Mar\n        </div>\n      </button>\n    </td>\n  </tr>\n  <tr>\n    <td>\n      <button type=\"button\"\n              class=\"v-btn v-size--default v-btn--flat v-btn--text v-btn--disabled theme--light\"\n              disabled\n      >\n        <div class=\"v-btn__content\">\n          Apr\n        </div>\n      </button>\n    </td>\n    <td>\n      <button type=\"button\"\n              class=\"v-btn v-size--default v-btn--active theme--light accent\"\n      >\n        <div class=\"v-btn__content\">\n          May\n        </div>\n      </button>\n    </td>\n    <td>\n      <button type=\"button\"\n              class=\"v-btn v-size--default v-btn--flat v-btn--text v-btn--disabled theme--light\"\n              disabled\n      >\n        <div class=\"v-btn__content\">\n          Jun\n        </div>\n      </button>\n    </td>\n  </tr>\n  <tr>\n    <td>\n      <button type=\"button\"\n              class=\"v-btn v-size--default v-btn--text theme--light\"\n      >\n        <div class=\"v-btn__content\">\n          Jul\n        </div>\n      </button>\n    </td>\n    <td>\n      <button type=\"button\"\n              class=\"v-btn v-size--default v-btn--flat v-btn--text v-btn--disabled theme--light\"\n              disabled\n      >\n        <div class=\"v-btn__content\">\n          Aug\n        </div>\n      </button>\n    </td>\n    <td>\n      <button type=\"button\"\n              class=\"v-btn v-size--default v-btn--flat v-btn--text v-btn--disabled theme--light\"\n              disabled\n      >\n        <div class=\"v-btn__content\">\n          Sep\n        </div>\n      </button>\n    </td>\n  </tr>\n  <tr>\n    <td>\n      <button type=\"button\"\n              class=\"v-btn v-size--default v-btn--flat v-btn--text v-btn--disabled theme--light\"\n              disabled\n      >\n        <div class=\"v-btn__content\">\n          Oct\n        </div>\n      </button>\n    </td>\n    <td>\n      <button type=\"button\"\n              class=\"v-btn v-size--default v-btn--flat v-btn--text v-btn--disabled theme--light\"\n              disabled\n      >\n        <div class=\"v-btn__content\">\n          Nov\n        </div>\n      </button>\n    </td>\n    <td>\n      <button type=\"button\"\n              class=\"v-btn v-size--default v-btn--flat v-btn--text v-btn--disabled theme--light\"\n              disabled\n      >\n        <div class=\"v-btn__content\">\n          Dec\n        </div>\n      </button>\n    </td>\n  </tr>\n</tbody>\n`;\n\nexports[`VDatePicker.ts should match snapshot with colored picker & header 1`] = `\n<div class=\"v-picker v-card v-picker--date theme--light\">\n  <div class=\"v-picker__title orange darken-1\">\n    <div class=\"v-date-picker-title\">\n      <div class=\"v-picker__title__btn v-date-picker-title__year\">\n        2005\n      </div>\n      <div class=\"v-picker__title__btn v-date-picker-title__date v-picker__title__btn--active\">\n        <div>\n          November\n        </div>\n      </div>\n    </div>\n  </div>\n  <div class=\"v-picker__body theme--light\"\n       style=\"width: 290px;\"\n  >\n    <div>\n      <div class=\"v-date-picker-header theme--light\">\n        <button type=\"button\"\n                class=\"v-btn v-btn--icon v-btn--round theme--light v-size--default\"\n                aria-label=\"Previous year\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon notranslate mdi mdi-chevron-left theme--light\"\n            >\n            </i>\n          </span>\n        </button>\n        <div class=\"v-date-picker-header__value\">\n          <div class=\"primary--text\">\n            <button type=\"button\">\n              2005\n            </button>\n          </div>\n        </div>\n        <button type=\"button\"\n                class=\"v-btn v-btn--icon v-btn--round theme--light v-size--default\"\n                aria-label=\"Next year\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon notranslate mdi mdi-chevron-right theme--light\"\n            >\n            </i>\n          </span>\n        </button>\n      </div>\n      <div class=\"v-date-picker-table v-date-picker-table--month theme--light\">\n        <table>\n          <tbody>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Jan\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Feb\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Mar\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Apr\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    May\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Jun\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Jul\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Aug\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Sep\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Oct\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Nov\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Dec\n                  </div>\n                </button>\n              </td>\n            </tr>\n          </tbody>\n        </table>\n      </div>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDatePicker.ts should match snapshot with colored picker 1`] = `\n<div class=\"v-picker v-card v-picker--date theme--light\">\n  <div class=\"v-picker__title orange darken-1\">\n    <div class=\"v-date-picker-title\">\n      <div class=\"v-picker__title__btn v-date-picker-title__year\">\n        2005\n      </div>\n      <div class=\"v-picker__title__btn v-date-picker-title__date v-picker__title__btn--active\">\n        <div>\n          November\n        </div>\n      </div>\n    </div>\n  </div>\n  <div class=\"v-picker__body theme--light\"\n       style=\"width: 290px;\"\n  >\n    <div>\n      <div class=\"v-date-picker-header theme--light\">\n        <button type=\"button\"\n                class=\"v-btn v-btn--icon v-btn--round theme--light v-size--default\"\n                aria-label=\"Previous year\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon notranslate mdi mdi-chevron-left theme--light\"\n            >\n            </i>\n          </span>\n        </button>\n        <div class=\"v-date-picker-header__value\">\n          <div class=\"orange--text text--darken-1\">\n            <button type=\"button\">\n              2005\n            </button>\n          </div>\n        </div>\n        <button type=\"button\"\n                class=\"v-btn v-btn--icon v-btn--round theme--light v-size--default\"\n                aria-label=\"Next year\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon notranslate mdi mdi-chevron-right theme--light\"\n            >\n            </i>\n          </span>\n        </button>\n      </div>\n      <div class=\"v-date-picker-table v-date-picker-table--month theme--light\">\n        <table>\n          <tbody>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Jan\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Feb\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Mar\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Apr\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    May\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Jun\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Jul\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Aug\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Sep\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Oct\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Nov\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Dec\n                  </div>\n                </button>\n              </td>\n            </tr>\n          </tbody>\n        </table>\n      </div>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDatePicker.ts should match snapshot with month formatting functions 1`] = `\n<tbody>\n  <tr>\n    <td>\n      <button type=\"button\"\n              class=\"v-btn v-size--default v-btn--text theme--light\"\n      >\n        <div class=\"v-btn__content\">\n          (01)\n        </div>\n      </button>\n    </td>\n    <td>\n      <button type=\"button\"\n              class=\"v-btn v-size--default v-btn--text theme--light\"\n      >\n        <div class=\"v-btn__content\">\n          (02)\n        </div>\n      </button>\n    </td>\n    <td>\n      <button type=\"button\"\n              class=\"v-btn v-size--default v-btn--text theme--light\"\n      >\n        <div class=\"v-btn__content\">\n          (03)\n        </div>\n      </button>\n    </td>\n  </tr>\n  <tr>\n    <td>\n      <button type=\"button\"\n              class=\"v-btn v-size--default v-btn--text theme--light\"\n      >\n        <div class=\"v-btn__content\">\n          (04)\n        </div>\n      </button>\n    </td>\n    <td>\n      <button type=\"button\"\n              class=\"v-btn v-size--default v-btn--text theme--light\"\n      >\n        <div class=\"v-btn__content\">\n          (05)\n        </div>\n      </button>\n    </td>\n    <td>\n      <button type=\"button\"\n              class=\"v-btn v-size--default v-btn--text theme--light\"\n      >\n        <div class=\"v-btn__content\">\n          (06)\n        </div>\n      </button>\n    </td>\n  </tr>\n  <tr>\n    <td>\n      <button type=\"button\"\n              class=\"v-btn v-size--default v-btn--text theme--light\"\n      >\n        <div class=\"v-btn__content\">\n          (07)\n        </div>\n      </button>\n    </td>\n    <td>\n      <button type=\"button\"\n              class=\"v-btn v-size--default v-btn--text theme--light\"\n      >\n        <div class=\"v-btn__content\">\n          (08)\n        </div>\n      </button>\n    </td>\n    <td>\n      <button type=\"button\"\n              class=\"v-btn v-size--default v-btn--text theme--light\"\n      >\n        <div class=\"v-btn__content\">\n          (09)\n        </div>\n      </button>\n    </td>\n  </tr>\n  <tr>\n    <td>\n      <button type=\"button\"\n              class=\"v-btn v-size--default v-btn--text theme--light\"\n      >\n        <div class=\"v-btn__content\">\n          (10)\n        </div>\n      </button>\n    </td>\n    <td>\n      <button type=\"button\"\n              class=\"v-btn v-size--default v-btn--text theme--light\"\n      >\n        <div class=\"v-btn__content\">\n          (11)\n        </div>\n      </button>\n    </td>\n    <td>\n      <button type=\"button\"\n              class=\"v-btn v-size--default v-btn--text theme--light\"\n      >\n        <div class=\"v-btn__content\">\n          (12)\n        </div>\n      </button>\n    </td>\n  </tr>\n</tbody>\n`;\n\nexports[`VDatePicker.ts should match snapshot with pick-month prop 1`] = `\n<div class=\"v-picker v-card v-picker--date theme--light\">\n  <div class=\"v-picker__title primary\">\n    <div class=\"v-date-picker-title\">\n      <div class=\"v-picker__title__btn v-date-picker-title__year\">\n        2013\n      </div>\n      <div class=\"v-picker__title__btn v-date-picker-title__date v-picker__title__btn--active\">\n        <div>\n          May\n        </div>\n      </div>\n    </div>\n  </div>\n  <div class=\"v-picker__body theme--light\"\n       style=\"width: 290px;\"\n  >\n    <div>\n      <div class=\"v-date-picker-header theme--light\">\n        <button type=\"button\"\n                class=\"v-btn v-btn--icon v-btn--round theme--light v-size--default\"\n                aria-label=\"Previous year\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon notranslate mdi mdi-chevron-left theme--light\"\n            >\n            </i>\n          </span>\n        </button>\n        <div class=\"v-date-picker-header__value\">\n          <div class=\"accent--text\">\n            <button type=\"button\">\n              2013\n            </button>\n          </div>\n        </div>\n        <button type=\"button\"\n                class=\"v-btn v-btn--icon v-btn--round theme--light v-size--default\"\n                aria-label=\"Next year\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon notranslate mdi mdi-chevron-right theme--light\"\n            >\n            </i>\n          </span>\n        </button>\n      </div>\n      <div class=\"v-date-picker-table v-date-picker-table--month theme--light\">\n        <table>\n          <tbody>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Jan\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Feb\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Mar\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Apr\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    May\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Jun\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Jul\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Aug\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Sep\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Oct\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Nov\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Dec\n                  </div>\n                </button>\n              </td>\n            </tr>\n          </tbody>\n        </table>\n      </div>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDatePicker.ts should render flat picker 1`] = `\n<div class=\"v-picker v-card v-picker--date v-picker--flat theme--light\">\n  <div class=\"v-picker__title primary\">\n    <div class=\"v-date-picker-title\">\n      <div class=\"v-picker__title__btn v-date-picker-title__year\">\n        2013\n      </div>\n      <div class=\"v-picker__title__btn v-date-picker-title__date v-picker__title__btn--active\">\n        <div>\n          May\n        </div>\n      </div>\n    </div>\n  </div>\n  <div class=\"v-picker__body theme--light\"\n       style=\"width: 290px;\"\n  >\n    <div>\n      <div class=\"v-date-picker-header theme--light\">\n        <button type=\"button\"\n                class=\"v-btn v-btn--icon v-btn--round theme--light v-size--default\"\n                aria-label=\"Previous year\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon notranslate mdi mdi-chevron-left theme--light\"\n            >\n            </i>\n          </span>\n        </button>\n        <div class=\"v-date-picker-header__value\">\n          <div class=\"accent--text\">\n            <button type=\"button\">\n              2013\n            </button>\n          </div>\n        </div>\n        <button type=\"button\"\n                class=\"v-btn v-btn--icon v-btn--round theme--light v-size--default\"\n                aria-label=\"Next year\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon notranslate mdi mdi-chevron-right theme--light\"\n            >\n            </i>\n          </span>\n        </button>\n      </div>\n      <div class=\"v-date-picker-table v-date-picker-table--month theme--light\">\n        <table>\n          <tbody>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Jan\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Feb\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Mar\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Apr\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--active theme--light accent\"\n                >\n                  <div class=\"v-btn__content\">\n                    May\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Jun\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Jul\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Aug\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Sep\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Oct\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Nov\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Dec\n                  </div>\n                </button>\n              </td>\n            </tr>\n          </tbody>\n        </table>\n      </div>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VDatePicker.ts should render picker with elevation 1`] = `\n<div class=\"v-picker v-card v-picker--date theme--light elevation-4\">\n  <div class=\"v-picker__title primary\">\n    <div class=\"v-date-picker-title\">\n      <div class=\"v-picker__title__btn v-date-picker-title__year\">\n        2013\n      </div>\n      <div class=\"v-picker__title__btn v-date-picker-title__date v-picker__title__btn--active\">\n        <div>\n          May\n        </div>\n      </div>\n    </div>\n  </div>\n  <div class=\"v-picker__body theme--light\"\n       style=\"width: 290px;\"\n  >\n    <div>\n      <div class=\"v-date-picker-header theme--light\">\n        <button type=\"button\"\n                class=\"v-btn v-btn--icon v-btn--round theme--light v-size--default\"\n                aria-label=\"Previous year\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon notranslate mdi mdi-chevron-left theme--light\"\n            >\n            </i>\n          </span>\n        </button>\n        <div class=\"v-date-picker-header__value\">\n          <div class=\"accent--text\">\n            <button type=\"button\">\n              2013\n            </button>\n          </div>\n        </div>\n        <button type=\"button\"\n                class=\"v-btn v-btn--icon v-btn--round theme--light v-size--default\"\n                aria-label=\"Next year\"\n        >\n          <span class=\"v-btn__content\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon notranslate mdi mdi-chevron-right theme--light\"\n            >\n            </i>\n          </span>\n        </button>\n      </div>\n      <div class=\"v-date-picker-table v-date-picker-table--month theme--light\">\n        <table>\n          <tbody>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Jan\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Feb\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Mar\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Apr\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--active theme--light accent\"\n                >\n                  <div class=\"v-btn__content\">\n                    May\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Jun\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Jul\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Aug\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Sep\n                  </div>\n                </button>\n              </td>\n            </tr>\n            <tr>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Oct\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Nov\n                  </div>\n                </button>\n              </td>\n              <td>\n                <button type=\"button\"\n                        class=\"v-btn v-size--default v-btn--text theme--light\"\n                >\n                  <div class=\"v-btn__content\">\n                    Dec\n                  </div>\n                </button>\n              </td>\n            </tr>\n          </tbody>\n        </table>\n      </div>\n    </div>\n  </div>\n</div>\n`;\n"
  },
  {
    "path": "packages/vuetify/src/components/VDatePicker/__tests__/__snapshots__/VDatePickerHeader.spec.ts.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`VDatePickerHeader.ts should render component and match snapshot 1`] = `\n<div class=\"v-date-picker-header theme--light\">\n  <button type=\"button\"\n          class=\"v-btn v-btn--icon v-btn--round theme--light v-size--default\"\n  >\n    <span class=\"v-btn__content\">\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate mdi mdi-chevron-left theme--light\"\n      >\n      </i>\n    </span>\n  </button>\n  <div class=\"v-date-picker-header__value\">\n    <div class=\"accent--text\">\n      <button type=\"button\">\n        November 2005\n      </button>\n    </div>\n  </div>\n  <button type=\"button\"\n          class=\"v-btn v-btn--icon v-btn--round theme--light v-size--default\"\n  >\n    <span class=\"v-btn__content\">\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate mdi mdi-chevron-right theme--light\"\n      >\n      </i>\n    </span>\n  </button>\n</div>\n`;\n\nexports[`VDatePickerHeader.ts should render component in RTL mode and match snapshot 1`] = `\n<div class=\"v-date-picker-header theme--light\">\n  <button type=\"button\"\n          class=\"v-btn v-btn--icon v-btn--round theme--light v-size--default\"\n  >\n    <span class=\"v-btn__content\">\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate mdi mdi-chevron-right theme--light\"\n      >\n      </i>\n    </span>\n  </button>\n  <div class=\"v-date-picker-header__value\">\n    <div class=\"accent--text\">\n      <button type=\"button\">\n        November 2005\n      </button>\n    </div>\n  </div>\n  <button type=\"button\"\n          class=\"v-btn v-btn--icon v-btn--round theme--light v-size--default\"\n  >\n    <span class=\"v-btn__content\">\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate mdi mdi-chevron-left theme--light\"\n      >\n      </i>\n    </span>\n  </button>\n</div>\n`;\n\nexports[`VDatePickerHeader.ts should render component with default slot and match snapshot 1`] = `\n<div class=\"v-date-picker-header theme--light\">\n  <button type=\"button\"\n          class=\"v-btn v-btn--icon v-btn--round theme--light v-size--default\"\n  >\n    <span class=\"v-btn__content\">\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate mdi mdi-chevron-left theme--light\"\n      >\n      </i>\n    </span>\n  </button>\n  <div class=\"v-date-picker-header__value\">\n    <div class=\"accent--text\">\n      <button type=\"button\">\n        <span>\n          foo\n        </span>\n      </button>\n    </div>\n  </div>\n  <button type=\"button\"\n          class=\"v-btn v-btn--icon v-btn--round theme--light v-size--default\"\n  >\n    <span class=\"v-btn__content\">\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate mdi mdi-chevron-right theme--light\"\n      >\n      </i>\n    </span>\n  </button>\n</div>\n`;\n\nexports[`VDatePickerHeader.ts should render disabled component and match snapshot 1`] = `\n<div class=\"v-date-picker-header v-date-picker-header--disabled theme--light\">\n  <button type=\"button\"\n          disabled=\"disabled\"\n          class=\"v-btn v-btn--disabled v-btn--icon v-btn--round theme--light v-size--default\"\n  >\n    <span class=\"v-btn__content\">\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate mdi mdi-chevron-left theme--light\"\n      >\n      </i>\n    </span>\n  </button>\n  <div class=\"v-date-picker-header__value v-date-picker-header__value--disabled\">\n    <div>\n      <button type=\"button\">\n        November 2005\n      </button>\n    </div>\n  </div>\n  <button type=\"button\"\n          disabled=\"disabled\"\n          class=\"v-btn v-btn--disabled v-btn--icon v-btn--round theme--light v-size--default\"\n  >\n    <span class=\"v-btn__content\">\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate mdi mdi-chevron-right theme--light\"\n      >\n      </i>\n    </span>\n  </button>\n</div>\n`;\n\nexports[`VDatePickerHeader.ts should render readonly component and match snapshot 1`] = `\n<div class=\"v-date-picker-header theme--light\">\n  <button type=\"button\"\n          class=\"v-btn v-btn--icon v-btn--round theme--light v-size--default\"\n  >\n    <span class=\"v-btn__content\">\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate mdi mdi-chevron-left theme--light\"\n      >\n      </i>\n    </span>\n  </button>\n  <div class=\"v-date-picker-header__value\">\n    <div class=\"accent--text\">\n      <button type=\"button\">\n        November 2005\n      </button>\n    </div>\n  </div>\n  <button type=\"button\"\n          class=\"v-btn v-btn--icon v-btn--round theme--light v-size--default\"\n  >\n    <span class=\"v-btn__content\">\n      <i aria-hidden=\"true\"\n         class=\"v-icon notranslate mdi mdi-chevron-right theme--light\"\n      >\n      </i>\n    </span>\n  </button>\n</div>\n`;\n"
  },
  {
    "path": "packages/vuetify/src/components/VDatePicker/__tests__/__snapshots__/VDatePickerYears.spec.ts.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`VDatePickerYears.ts should render component and match snapshot 1`] = `\n<ul class=\"v-date-picker-years\">\n  <li class>\n    2100\n  </li>\n  <li class>\n    2099\n  </li>\n  <li class>\n    2098\n  </li>\n  <li class>\n    2097\n  </li>\n  <li class>\n    2096\n  </li>\n  <li class>\n    2095\n  </li>\n  <li class>\n    2094\n  </li>\n  <li class>\n    2093\n  </li>\n  <li class>\n    2092\n  </li>\n  <li class>\n    2091\n  </li>\n  <li class>\n    2090\n  </li>\n  <li class>\n    2089\n  </li>\n  <li class>\n    2088\n  </li>\n  <li class>\n    2087\n  </li>\n  <li class>\n    2086\n  </li>\n  <li class>\n    2085\n  </li>\n  <li class>\n    2084\n  </li>\n  <li class>\n    2083\n  </li>\n  <li class>\n    2082\n  </li>\n  <li class>\n    2081\n  </li>\n  <li class>\n    2080\n  </li>\n  <li class>\n    2079\n  </li>\n  <li class>\n    2078\n  </li>\n  <li class>\n    2077\n  </li>\n  <li class>\n    2076\n  </li>\n  <li class>\n    2075\n  </li>\n  <li class>\n    2074\n  </li>\n  <li class>\n    2073\n  </li>\n  <li class>\n    2072\n  </li>\n  <li class>\n    2071\n  </li>\n  <li class>\n    2070\n  </li>\n  <li class>\n    2069\n  </li>\n  <li class>\n    2068\n  </li>\n  <li class>\n    2067\n  </li>\n  <li class>\n    2066\n  </li>\n  <li class>\n    2065\n  </li>\n  <li class>\n    2064\n  </li>\n  <li class>\n    2063\n  </li>\n  <li class>\n    2062\n  </li>\n  <li class>\n    2061\n  </li>\n  <li class>\n    2060\n  </li>\n  <li class>\n    2059\n  </li>\n  <li class>\n    2058\n  </li>\n  <li class>\n    2057\n  </li>\n  <li class>\n    2056\n  </li>\n  <li class>\n    2055\n  </li>\n  <li class>\n    2054\n  </li>\n  <li class>\n    2053\n  </li>\n  <li class>\n    2052\n  </li>\n  <li class>\n    2051\n  </li>\n  <li class>\n    2050\n  </li>\n  <li class>\n    2049\n  </li>\n  <li class>\n    2048\n  </li>\n  <li class>\n    2047\n  </li>\n  <li class>\n    2046\n  </li>\n  <li class>\n    2045\n  </li>\n  <li class>\n    2044\n  </li>\n  <li class>\n    2043\n  </li>\n  <li class>\n    2042\n  </li>\n  <li class>\n    2041\n  </li>\n  <li class>\n    2040\n  </li>\n  <li class>\n    2039\n  </li>\n  <li class>\n    2038\n  </li>\n  <li class>\n    2037\n  </li>\n  <li class>\n    2036\n  </li>\n  <li class>\n    2035\n  </li>\n  <li class>\n    2034\n  </li>\n  <li class>\n    2033\n  </li>\n  <li class>\n    2032\n  </li>\n  <li class>\n    2031\n  </li>\n  <li class>\n    2030\n  </li>\n  <li class>\n    2029\n  </li>\n  <li class>\n    2028\n  </li>\n  <li class>\n    2027\n  </li>\n  <li class>\n    2026\n  </li>\n  <li class>\n    2025\n  </li>\n  <li class>\n    2024\n  </li>\n  <li class>\n    2023\n  </li>\n  <li class>\n    2022\n  </li>\n  <li class>\n    2021\n  </li>\n  <li class>\n    2020\n  </li>\n  <li class>\n    2019\n  </li>\n  <li class>\n    2018\n  </li>\n  <li class>\n    2017\n  </li>\n  <li class>\n    2016\n  </li>\n  <li class>\n    2015\n  </li>\n  <li class>\n    2014\n  </li>\n  <li class>\n    2013\n  </li>\n  <li class>\n    2012\n  </li>\n  <li class>\n    2011\n  </li>\n  <li class>\n    2010\n  </li>\n  <li class>\n    2009\n  </li>\n  <li class>\n    2008\n  </li>\n  <li class>\n    2007\n  </li>\n  <li class>\n    2006\n  </li>\n  <li class>\n    2005\n  </li>\n  <li class>\n    2004\n  </li>\n  <li class>\n    2003\n  </li>\n  <li class>\n    2002\n  </li>\n  <li class>\n    2001\n  </li>\n  <li class=\"active primary--text\">\n    2000\n  </li>\n  <li class>\n    1999\n  </li>\n  <li class>\n    1998\n  </li>\n  <li class>\n    1997\n  </li>\n  <li class>\n    1996\n  </li>\n  <li class>\n    1995\n  </li>\n  <li class>\n    1994\n  </li>\n  <li class>\n    1993\n  </li>\n  <li class>\n    1992\n  </li>\n  <li class>\n    1991\n  </li>\n  <li class>\n    1990\n  </li>\n  <li class>\n    1989\n  </li>\n  <li class>\n    1988\n  </li>\n  <li class>\n    1987\n  </li>\n  <li class>\n    1986\n  </li>\n  <li class>\n    1985\n  </li>\n  <li class>\n    1984\n  </li>\n  <li class>\n    1983\n  </li>\n  <li class>\n    1982\n  </li>\n  <li class>\n    1981\n  </li>\n  <li class>\n    1980\n  </li>\n  <li class>\n    1979\n  </li>\n  <li class>\n    1978\n  </li>\n  <li class>\n    1977\n  </li>\n  <li class>\n    1976\n  </li>\n  <li class>\n    1975\n  </li>\n  <li class>\n    1974\n  </li>\n  <li class>\n    1973\n  </li>\n  <li class>\n    1972\n  </li>\n  <li class>\n    1971\n  </li>\n  <li class>\n    1970\n  </li>\n  <li class>\n    1969\n  </li>\n  <li class>\n    1968\n  </li>\n  <li class>\n    1967\n  </li>\n  <li class>\n    1966\n  </li>\n  <li class>\n    1965\n  </li>\n  <li class>\n    1964\n  </li>\n  <li class>\n    1963\n  </li>\n  <li class>\n    1962\n  </li>\n  <li class>\n    1961\n  </li>\n  <li class>\n    1960\n  </li>\n  <li class>\n    1959\n  </li>\n  <li class>\n    1958\n  </li>\n  <li class>\n    1957\n  </li>\n  <li class>\n    1956\n  </li>\n  <li class>\n    1955\n  </li>\n  <li class>\n    1954\n  </li>\n  <li class>\n    1953\n  </li>\n  <li class>\n    1952\n  </li>\n  <li class>\n    1951\n  </li>\n  <li class>\n    1950\n  </li>\n  <li class>\n    1949\n  </li>\n  <li class>\n    1948\n  </li>\n  <li class>\n    1947\n  </li>\n  <li class>\n    1946\n  </li>\n  <li class>\n    1945\n  </li>\n  <li class>\n    1944\n  </li>\n  <li class>\n    1943\n  </li>\n  <li class>\n    1942\n  </li>\n  <li class>\n    1941\n  </li>\n  <li class>\n    1940\n  </li>\n  <li class>\n    1939\n  </li>\n  <li class>\n    1938\n  </li>\n  <li class>\n    1937\n  </li>\n  <li class>\n    1936\n  </li>\n  <li class>\n    1935\n  </li>\n  <li class>\n    1934\n  </li>\n  <li class>\n    1933\n  </li>\n  <li class>\n    1932\n  </li>\n  <li class>\n    1931\n  </li>\n  <li class>\n    1930\n  </li>\n  <li class>\n    1929\n  </li>\n  <li class>\n    1928\n  </li>\n  <li class>\n    1927\n  </li>\n  <li class>\n    1926\n  </li>\n  <li class>\n    1925\n  </li>\n  <li class>\n    1924\n  </li>\n  <li class>\n    1923\n  </li>\n  <li class>\n    1922\n  </li>\n  <li class>\n    1921\n  </li>\n  <li class>\n    1920\n  </li>\n  <li class>\n    1919\n  </li>\n  <li class>\n    1918\n  </li>\n  <li class>\n    1917\n  </li>\n  <li class>\n    1916\n  </li>\n  <li class>\n    1915\n  </li>\n  <li class>\n    1914\n  </li>\n  <li class>\n    1913\n  </li>\n  <li class>\n    1912\n  </li>\n  <li class>\n    1911\n  </li>\n  <li class>\n    1910\n  </li>\n  <li class>\n    1909\n  </li>\n  <li class>\n    1908\n  </li>\n  <li class>\n    1907\n  </li>\n  <li class>\n    1906\n  </li>\n  <li class>\n    1905\n  </li>\n  <li class>\n    1904\n  </li>\n  <li class>\n    1903\n  </li>\n  <li class>\n    1902\n  </li>\n  <li class>\n    1901\n  </li>\n  <li class>\n    1900\n  </li>\n</ul>\n`;\n"
  },
  {
    "path": "packages/vuetify/src/components/VDatePicker/_variables.scss",
    "content": "$date-picker-width: 328px !default;\n$date-picker-show-week-width: 368px !default;\n\n$date-picker-landscape-header-width: 170px !default;\n$date-picker-controls-height: var(--v-date-picker-controls-height, 56px) !default;\n$date-picker-controls-padding: 4px 12px !default;\n$date-picker-controls-docked-toggle-btn-padding: 12px 8px !default;\n$date-picker-controls-docked-toggle-append-margin-inline: 4px -4px !default;\n\n$date-picker-header-height: 70px !default;\n\n$date-picker-month-btn-height: 24px !default;\n$date-picker-month-btn-size: 0.875rem !default;\n$date-picker-month-column-gap: 4px !default;\n$date-picker-month-day-size: 40px !default;\n$date-picker-month-font-size: 0.875rem !default;\n$date-picker-month-padding: 0 12px 8px !default;\n\n$date-picker-months-grid-gap: 0px 24px !default;\n$date-picker-months-height: 288px !default;\n\n$date-picker-years-height: 288px !default;\n$date-picker-years-padding-inline: 32px !default;\n\n$date-picker-event-size: 8px !default;\n$date-picker-event-border-radius: 4px !default;\n$date-picker-event-margin: 0 1px !default;\n$date-picker-event-date-bottom: 8px !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VDatePicker/index.ts",
    "content": "export { VDatePicker } from './VDatePicker'\nexport { VDatePickerControls } from './VDatePickerControls'\nexport { VDatePickerHeader } from './VDatePickerHeader'\nexport { VDatePickerMonth } from './VDatePickerMonth'\nexport { VDatePickerMonths } from './VDatePickerMonths'\nexport { VDatePickerYears } from './VDatePickerYears'\n"
  },
  {
    "path": "packages/vuetify/src/components/VDefaultsProvider/VDefaultsProvider.tsx",
    "content": "// Composables\nimport { provideDefaults } from '@/composables/defaults'\n\n// Utilities\nimport { toRefs } from 'vue'\nimport { genericComponent, propsFactory } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { DefaultsOptions } from '@/composables/defaults'\n\nexport const makeVDefaultsProviderProps = propsFactory({\n  defaults: Object as PropType<DefaultsOptions>,\n  disabled: Boolean,\n  reset: [Number, String],\n  root: [Boolean, String],\n  scoped: Boolean,\n}, 'VDefaultsProvider')\n\nexport const VDefaultsProvider = genericComponent(false)({\n  name: 'VDefaultsProvider',\n\n  props: makeVDefaultsProviderProps(),\n\n  setup (props, { slots }) {\n    const { defaults, disabled, reset, root, scoped } = toRefs(props)\n\n    provideDefaults(defaults, {\n      reset,\n      root,\n      scoped,\n      disabled,\n    })\n\n    return () => slots.default?.()\n  },\n})\n\nexport type VDefaultsProvider = InstanceType<typeof VDefaultsProvider>\n"
  },
  {
    "path": "packages/vuetify/src/components/VDefaultsProvider/__tests__/VDefaultsProvider.spec.tsx",
    "content": "// Components\nimport { VDefaultsProvider } from '../VDefaultsProvider'\nimport { VCard } from '@/components/VCard'\n\n// Utilities\nimport { render, screen } from '@test'\n\ndescribe('VDefaultsProvider', () => {\n  it('should apply new defaults', () => {\n    render(() => (\n      <VDefaultsProvider defaults={{ global: { elevation: 3 }, VCard: { color: 'primary' } }}>\n        <VCard title=\"foo\" subtitle=\"bar\" />\n      </VDefaultsProvider>\n    ))\n\n    const card = screen.getByCSS('.v-card')\n    expect(card.classList).toContain('elevation-3')\n    expect(card.classList).toContain('bg-primary')\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VDefaultsProvider/index.ts",
    "content": "export { VDefaultsProvider } from './VDefaultsProvider'\n"
  },
  {
    "path": "packages/vuetify/src/components/VDialog/VDialog.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-dialog\n    align-items: center\n    justify-content: center\n    margin: auto\n\n    > .v-overlay__content\n      max-height: calc(100% - #{$dialog-margin * 2})\n      width: calc(100% - #{$dialog-margin * 2})\n      max-width: calc(100% - #{$dialog-margin * 2})\n      margin: $dialog-margin\n\n      &,\n      > form\n        display: flex\n        flex-direction: column\n        min-height: 0\n\n        > .v-card,\n        > .v-sheet\n          --v-scrollbar-offset: 0px\n          border-radius: $dialog-border-radius\n          overflow-y: auto\n          flex: 1 1 var(--v-card-height, 100%)\n\n          @include tools.elevation($dialog-elevation)\n\n        > .v-card\n          display: flex\n          flex-direction: column\n\n          > .v-card-item\n            padding: $dialog-card-header-padding\n\n            + .v-card-text\n              padding-top: $dialog-card-header-text-padding-top\n\n          > .v-card-text\n            font-size: inherit\n            letter-spacing: $dialog-card-text-letter-spacing\n            line-height: inherit\n            padding: $dialog-card-text-padding\n\n          > .v-card-actions\n            justify-content: $dialog-card-actions-justify\n\n  .v-dialog--fullscreen\n    --v-scrollbar-offset: 0px\n\n    > .v-overlay__content\n      border-radius: 0\n      margin: 0\n      padding: 0\n      width: 100%\n      height: 100%\n      max-width: 100%\n      max-height: 100%\n      overflow-y: auto\n      top: 0\n      left: 0\n\n      &,\n      > form\n        > .v-card,\n        > .v-sheet\n          min-height: 100%\n          min-width: 100%\n          border-radius: 0\n\n  .v-dialog--scrollable > .v-overlay__content\n    > form\n      &,\n      > .v-card\n        max-height: 100%\n        max-width: 100%\n\n    &,\n    > form\n      &,\n      > .v-card\n        display: flex\n        flex: 1 1 var(--v-card-height, 100%)\n        flex-direction: column\n\n      > .v-card > .v-card-text\n        backface-visibility: hidden\n        overflow-y: auto\n"
  },
  {
    "path": "packages/vuetify/src/components/VDialog/VDialog.tsx",
    "content": "// Styles\nimport './VDialog.sass'\n\n// Components\nimport { VDialogTransition } from '@/components/transitions'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\nimport { VOverlay } from '@/components/VOverlay'\nimport { makeVOverlayProps } from '@/components/VOverlay/VOverlay'\n\n// Composables\nimport { forwardRefs } from '@/composables/forwardRefs'\nimport { useProxiedModel } from '@/composables/proxiedModel'\nimport { useScopeId } from '@/composables/scopeId'\n\n// Utilities\nimport { mergeProps, nextTick, ref, watch } from 'vue'\nimport { genericComponent, omit, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { OverlaySlots } from '@/components/VOverlay/VOverlay'\n\nexport const makeVDialogProps = propsFactory({\n  fullscreen: Boolean,\n  scrollable: Boolean,\n\n  ...omit(makeVOverlayProps({\n    captureFocus: true,\n    origin: 'center center' as const,\n    scrollStrategy: 'block' as const,\n    transition: { component: VDialogTransition },\n    zIndex: 2400,\n    retainFocus: true,\n  }), ['disableInitialFocus']),\n}, 'VDialog')\n\nexport const VDialog = genericComponent<OverlaySlots>()({\n  name: 'VDialog',\n\n  props: makeVDialogProps(),\n\n  emits: {\n    'update:modelValue': (value: boolean) => true,\n    afterEnter: () => true,\n    afterLeave: () => true,\n  },\n\n  setup (props, { emit, slots }) {\n    const isActive = useProxiedModel(props, 'modelValue')\n    const { scopeId } = useScopeId()\n\n    const overlay = ref<VOverlay>()\n\n    function onAfterEnter () {\n      emit('afterEnter')\n      if (\n        (props.scrim || props.retainFocus) &&\n        overlay.value?.contentEl &&\n        !overlay.value.contentEl.contains(document.activeElement)\n      ) {\n        overlay.value.contentEl.focus({ preventScroll: true })\n      }\n    }\n\n    function onAfterLeave () {\n      emit('afterLeave')\n    }\n\n    watch(isActive, async val => {\n      if (!val) {\n        await nextTick()\n        overlay.value!.activatorEl?.focus({ preventScroll: true })\n      }\n    })\n\n    useRender(() => {\n      const overlayProps = VOverlay.filterProps(props)\n      const activatorProps = mergeProps({\n        'aria-haspopup': 'dialog',\n      }, props.activatorProps)\n      const contentProps = mergeProps({\n        tabindex: -1,\n      }, props.contentProps)\n\n      return (\n        <VOverlay\n          ref={ overlay }\n          class={[\n            'v-dialog',\n            {\n              'v-dialog--fullscreen': props.fullscreen,\n              'v-dialog--scrollable': props.scrollable,\n            },\n            props.class,\n          ]}\n          style={ props.style }\n          { ...overlayProps }\n          v-model={ isActive.value }\n          aria-modal=\"true\"\n          activatorProps={ activatorProps }\n          contentProps={ contentProps }\n          height={ !props.fullscreen ? props.height : undefined }\n          width={ !props.fullscreen ? props.width : undefined }\n          maxHeight={ !props.fullscreen ? props.maxHeight : undefined }\n          maxWidth={ !props.fullscreen ? props.maxWidth : undefined }\n          role=\"dialog\"\n          onAfterEnter={ onAfterEnter }\n          onAfterLeave={ onAfterLeave }\n          { ...scopeId }\n        >\n          {{\n            activator: slots.activator,\n            default: (...args) => (\n              <VDefaultsProvider root=\"VDialog\">\n                { slots.default?.(...args) }\n              </VDefaultsProvider>\n            ),\n          }}\n        </VOverlay>\n      )\n    })\n\n    return forwardRefs({}, overlay)\n  },\n})\n\nexport type VDialog = InstanceType<typeof VDialog>\n"
  },
  {
    "path": "packages/vuetify/src/components/VDialog/__test__/VDialog.spec.browser.tsx",
    "content": "// Components\nimport { VDialog } from '../VDialog'\n\n// Utilities\nimport { commands, render, screen, userEvent, wait } from '@test'\nimport { h, nextTick, ref } from 'vue'\nimport { createMemoryHistory, createRouter } from 'vue-router'\n\n// Tests\ndescribe('VDialog', () => {\n  it('should render correctly', async () => {\n    const model = ref(false)\n    render(() => (\n      <div>\n        <VDialog v-model={ model.value } data-testid=\"dialog\">\n          <div data-testid=\"content\">Content</div>\n        </VDialog>\n      </div>\n    ))\n\n    expect(screen.queryByTestId('dialog')).toBeNull()\n\n    model.value = true\n    await nextTick()\n    await expect(screen.findByTestId('dialog')).resolves.toBeVisible()\n    await expect.element(await screen.findByTestId('content')).toBeVisible()\n\n    await commands.click(0, 0)\n    await expect.poll(() => model.value).toBeFalsy()\n    await expect.poll(() => screen.queryByTestId('dialog')).toBeNull()\n    await expect.poll(() => screen.queryByTestId('content')).toBeNull()\n  })\n\n  it('should emit afterLeave', async () => {\n    const model = ref(true)\n    const onAfterLeave = vi.fn()\n    render(() => (\n      <div>\n        <VDialog v-model={ model.value } onAfterLeave={ onAfterLeave }>\n          <div data-test=\"content\">Content</div>\n        </VDialog>\n      </div>\n    ))\n\n    await commands.click(0, 0)\n    await expect.poll(() => onAfterLeave).toHaveBeenCalledTimes(1)\n  })\n\n  it('should focus on the last element when shift + tab key is pressed on the first element', async () => {\n    const model = ref(true)\n    render(() => (\n      <div>\n        <VDialog v-model={ model.value } persistent>\n          <div>\n            <button data-testid=\"first\">First</button>\n            <button data-testid=\"last\">Last</button>\n          </div>\n        </VDialog>\n      </div>\n    ))\n    const first = screen.getByCSS('button[data-testid=\"first\"]')\n    const last = screen.getByCSS('button[data-testid=\"last\"]')\n\n    first.focus()\n    await expect.poll(() => document.activeElement).toBe(first)\n\n    await userEvent.tab({ shift: true })\n    await expect.poll(() => document.activeElement).toBe(last)\n  })\n\n  it('should focus on the first element when Tab key is pressed on the last element', async () => {\n    const model = ref(true)\n    render(() => (\n      <div>\n        <VDialog v-model={ model.value }>\n          <div>\n            <button data-testid=\"first\">First</button>\n            <button data-testid=\"last\">Last</button>\n          </div>\n        </VDialog>\n      </div>\n    ))\n    const first = screen.getByCSS('button[data-testid=\"first\"]')\n    const last = screen.getByCSS('button[data-testid=\"last\"]')\n\n    last.focus()\n    await expect.poll(() => document.activeElement).toBe(last)\n\n    await userEvent.tab()\n    await expect.poll(() => document.activeElement).toBe(first)\n  })\n\n  describe('routing back', () => {\n    function createTestRouter () {\n      return createRouter({\n        history: createMemoryHistory(),\n        routes: [\n          { path: '/', component: { setup: () => () => h('h1', 'home') } },\n          { path: '/page1', component: { setup: () => () => h('h1', 'page1') } },\n          { path: '/page2', component: { setup: () => () => h('h1', 'page2') } },\n          { path: '/page3', component: { setup: () => () => h('h1', 'page3') } },\n        ],\n      })\n    }\n\n    async function simulateBackNavigation (router: ReturnType<typeof createTestRouter>) {\n      router.back()\n      for (let i = 0; i < 10; i++) await nextTick() // flush microtasks\n      window.dispatchEvent(new PopStateEvent('popstate', { state: {} }))\n      await wait()\n    }\n\n    it('should block back with persistent dialog, allow after close, and block again when reopened', async () => {\n      const router = createTestRouter()\n      await router.push('/page1')\n      await router.push('/page2')\n      await router.push('/page3')\n\n      const model = ref(true)\n      render(() => (\n        <VDialog v-model={ model.value } persistent data-testid=\"dialog\">\n          <div data-testid=\"content\">Content</div>\n        </VDialog>\n      ), { global: { plugins: [router] } })\n\n      await expect(screen.findByTestId('dialog')).resolves.toBeVisible()\n      await wait()\n\n      // 1st back: persistent dialog blocks navigation\n      await simulateBackNavigation(router)\n      expect(model.value).toBeTruthy()\n      expect(router.currentRoute.value.path).toBe('/page3')\n\n      // close the dialog\n      model.value = false\n      await nextTick()\n\n      // 2nd back: no dialog blocking, navigation proceeds\n      await simulateBackNavigation(router)\n      expect(router.currentRoute.value.path).toBe('/page2')\n\n      // reopen\n      model.value = true\n      await nextTick()\n      await expect(screen.findByTestId('dialog')).resolves.toBeVisible()\n      await wait()\n\n      // 3rd back: persistent dialog blocks again\n      await simulateBackNavigation(router)\n      expect(model.value).toBeTruthy()\n      expect(router.currentRoute.value.path).toBe('/page2')\n    })\n\n    it('should close non-persistent dialog on back and block navigation', async () => {\n      const router = createTestRouter()\n      await router.push('/page1')\n      await router.push('/page2')\n      await router.push('/page3')\n\n      const model = ref(false)\n      render(() => (\n        <VDialog v-model={ model.value } data-testid=\"dialog\">\n          <div data-testid=\"content\">Content</div>\n        </VDialog>\n      ), { global: { plugins: [router] } })\n\n      // Open dialog\n      model.value = true\n      await nextTick()\n      await expect(screen.findByTestId('dialog')).resolves.toBeVisible()\n      await wait()\n\n      // 1st back: dialog closes but route stays (navigation blocked)\n      await simulateBackNavigation(router)\n      await expect.poll(() => model.value).toBeFalsy()\n      expect(router.currentRoute.value.path).toBe('/page3')\n\n      // 2nd back: no dialog, navigation proceeds\n      await simulateBackNavigation(router)\n      expect(router.currentRoute.value.path).toBe('/page2')\n\n      // reopen\n      model.value = true\n      await nextTick()\n      await expect(screen.findByTestId('dialog')).resolves.toBeVisible()\n      await wait()\n\n      // 3rd back: dialog closes again, route stays\n      await simulateBackNavigation(router)\n      await expect.poll(() => model.value).toBeFalsy()\n      expect(router.currentRoute.value.path).toBe('/page2')\n    })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VDialog/_variables.scss",
    "content": "@use 'sass:map';\n@use '../../styles/settings';\n@use '../../styles/tools';\n\n// Defaults\n$dialog-elevation: 5 !default;\n$dialog-border-radius: settings.$border-radius-root !default;\n$dialog-margin: 24px !default;\n\n$dialog-card-actions-justify: flex-end !default;\n$dialog-card-header-padding: 16px 24px !default;\n$dialog-card-header-text-padding-top: 0 !default;\n$dialog-card-text-padding: 16px 24px 24px !default;\n$dialog-card-text-letter-spacing: tools.map-deep-get(settings.$typography, 'body-large', 'letter-spacing') !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VDialog/index.ts",
    "content": "export { VDialog } from './VDialog'\n"
  },
  {
    "path": "packages/vuetify/src/components/VDivider/VDivider.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-divider\n    color: inherit\n    display: block\n    flex: $divider-flex\n    height: 0\n    max-height: 0\n    margin: 0\n    opacity: $divider-opacity\n    transition: inherit\n\n    @include tools.border($divider-border...)\n\n    &--vertical\n      align-self: stretch\n      border-width: $divider-vertical-border-width\n      display: inline-flex\n      height: auto\n      margin-left: $divider-vertical-margin-left\n      max-height: 100%\n      max-width: 0px\n      vertical-align: text-bottom\n      width: 0px\n\n    &--inset\n      &:not(.v-divider--vertical)\n        max-width: $divider-inset-max-width\n        margin-inline-start: $divider-inset-margin\n\n      &.v-divider--vertical\n        margin-bottom: $divider-vertical-inset-margin-bottom\n        margin-top: $divider-vertical-inset-margin-top\n        max-height: $divider-vertical-inset-max-height\n\n    &--gradient\n      mask-image: $divider-gradient-mask\n\n      &.v-divider--vertical\n        mask-image: $divider-vertical-gradient-mask\n\n  .v-divider__content\n    padding: $divider-content-padding\n    text-wrap: nowrap\n\n    .v-divider__wrapper--vertical &\n      padding: $divider-content-vertical-padding\n\n  .v-divider__wrapper\n    display: flex\n    align-items: center\n    justify-content: center\n\n\n    &--vertical\n      flex-direction: column\n      height: 100%\n\n      .v-divider\n        margin: 0 auto\n\n    &--gradient\n      mask-image: $divider-gradient-mask\n\n      &.v-divider__wrapper--vertical\n        mask-image: $divider-vertical-gradient-mask\n"
  },
  {
    "path": "packages/vuetify/src/components/VDivider/VDivider.tsx",
    "content": "// Styles\nimport './VDivider.sass'\n\n// Composables\nimport { useTextColor } from '@/composables/color'\nimport { makeComponentProps } from '@/composables/component'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\n\n// Utilities\nimport { computed, toRef } from 'vue'\nimport { convertToUnit, genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\ntype DividerKey = 'borderRightWidth' | 'borderTopWidth' | 'height' | 'width'\ntype DividerStyles = Partial<Record<DividerKey, string>>\n\nconst allowedVariants = ['dotted', 'dashed', 'solid', 'double'] as const\ntype Variant = typeof allowedVariants[number]\n\nexport const makeVDividerProps = propsFactory({\n  color: String,\n  contentOffset: [Number, String, Array] as PropType<number | string | (string | number)[]>,\n  gradient: Boolean,\n  inset: Boolean,\n  length: [Number, String],\n  opacity: [Number, String],\n  thickness: [Number, String],\n  vertical: Boolean,\n  variant: {\n    type: String as PropType<Variant>,\n    default: 'solid',\n    validator: (v: any) => allowedVariants.includes(v),\n  },\n\n  ...makeComponentProps(),\n  ...makeThemeProps(),\n}, 'VDivider')\n\nexport const VDivider = genericComponent()({\n  name: 'VDivider',\n\n  props: makeVDividerProps(),\n\n  setup (props, { attrs, slots }) {\n    const { themeClasses } = provideTheme(props)\n    const { textColorClasses, textColorStyles } = useTextColor(() => props.color)\n    const dividerStyles = computed(() => {\n      const styles: DividerStyles = {}\n\n      if (props.length) {\n        styles[props.vertical ? 'height' : 'width'] = convertToUnit(props.length)\n      }\n\n      if (props.thickness) {\n        styles[props.vertical ? 'borderRightWidth' : 'borderTopWidth'] = convertToUnit(props.thickness)\n      }\n\n      return styles\n    })\n\n    const contentStyles = toRef(() => {\n      const margin = Array.isArray(props.contentOffset) ? props.contentOffset[0] : props.contentOffset\n      const shift = Array.isArray(props.contentOffset) ? props.contentOffset[1] : 0\n\n      return {\n        marginBlock: props.vertical && margin ? convertToUnit(margin) : undefined,\n        marginInline: !props.vertical && margin ? convertToUnit(margin) : undefined,\n        transform: shift\n          ? `translate${props.vertical ? 'X' : 'Y'}(${convertToUnit(shift)})`\n          : undefined,\n      }\n    })\n\n    useRender(() => {\n      const divider = (\n        <hr\n          class={[\n            {\n              'v-divider': true,\n              'v-divider--gradient': props.gradient && !slots.default,\n              'v-divider--inset': props.inset,\n              'v-divider--vertical': props.vertical,\n            },\n            themeClasses.value,\n            textColorClasses.value,\n            props.class,\n          ]}\n          style={[\n            dividerStyles.value,\n            textColorStyles.value,\n            { '--v-border-opacity': props.opacity },\n            { 'border-style': props.variant },\n            props.style,\n          ]}\n          aria-orientation={\n            !attrs.role || attrs.role === 'separator'\n              ? props.vertical ? 'vertical' : 'horizontal'\n              : undefined\n          }\n          role={ `${attrs.role || 'separator'}` }\n        />\n      )\n\n      if (!slots.default) return divider\n\n      return (\n        <div\n          class={[\n            'v-divider__wrapper',\n            {\n              'v-divider__wrapper--gradient': props.gradient,\n              'v-divider__wrapper--inset': props.inset,\n              'v-divider__wrapper--vertical': props.vertical,\n            },\n          ]}\n        >\n          { divider }\n\n          <div\n            class=\"v-divider__content\"\n            style={ contentStyles.value }\n          >\n            { slots.default() }\n          </div>\n\n          { divider }\n        </div>\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VDivider = InstanceType<typeof VDivider>\n"
  },
  {
    "path": "packages/vuetify/src/components/VDivider/__tests__/VDivider.spec.browser.tsx",
    "content": "import { VDivider } from '../VDivider'\n\n// Components\nimport { VBtn } from '@/components/VBtn'\nimport { VCard } from '@/components/VCard'\nimport { VCol, VRow, VSpacer } from '@/components/VGrid'\nimport { VList, VListItem } from '@/components/VList'\nimport { VToolbar } from '@/components/VToolbar'\n\n// Utilities\nimport { render, screen } from '@test'\n\ndescribe('VDivider', () => {\n  describe('examples in documentation', () => {\n    it('takes full height in flexbox container with static height', () => {\n      render(() => (\n        <div\n          class=\"ma-2 d-flex align-center justify-center bg-grey-lighten-2\"\n          style=\"height: 200px;\"\n        >\n          <VDivider vertical class=\"opacity-100 text-red\" />\n        </div>\n      ))\n\n      expect(screen.getByCSS('.v-divider')).toHaveStyle({ height: '200px' })\n    })\n\n    it('takes defined length when used as centered separator in VToolbar', () => {\n      render(() => (\n        <>\n          <VToolbar>\n            <VBtn icon=\"mdi-arrow-left\"></VBtn>\n            <VSpacer></VSpacer>\n            <VBtn class=\"ms-5\" icon=\"mdi-archive-plus-outline\"></VBtn>\n            <VBtn icon=\"mdi-alert-circle-outline\"></VBtn>\n            <VBtn icon=\"mdi-delete-outline\"></VBtn>\n            <VDivider\n              class=\"mx-3 align-self-center opacity-100 text-red\"\n              length=\"24\"\n              thickness=\"2\"\n              vertical\n            />\n            <VBtn icon=\"mdi-folder-outline\"></VBtn>\n            <VBtn icon=\"mdi-tag-outline\"></VBtn>\n            <VBtn icon=\"mdi-dots-vertical\"></VBtn>\n          </VToolbar>\n        </>\n      ))\n      expect(screen.getByCSS('.v-divider')).toHaveStyle({ height: '24px' })\n    })\n  })\n\n  describe('adaptive height', () => {\n    it('takes full height in flexbox container with dynamic height', () => {\n      render(() => (\n        <>\n          <div\n            class=\"ma-2 pa-3 d-flex flex-column\"\n            style=\"height: 370px; width: 940px; outline: 1px solid currentColor\"\n          >\n            <div class=\"d-flex\">\n              <aside class=\"pr-4\" style=\"min-width: 200px\">\n                <VList class=\"py-0\">\n                  {[1, 2, 3].map(idx => (\n                    <VListItem\n                      rounded=\"lg\"\n                      class=\"bg-grey mb-3\"\n                      title={ `Nav item ${idx}` }\n                    ></VListItem>\n                  ))}\n                </VList>\n              </aside>\n              <VDivider\n                vertical\n                class=\"opacity-100 text-red\"\n              ></VDivider>\n              <main class=\"px-4 d-flex align-content-start flex-wrap ga-4\">\n                {[1, 2, 3, 4, 5, 6, 7, 8].map(idx => (\n                  <VCard color=\"grey\" width=\"200\" height=\"80\"></VCard>\n                ))}\n              </main>\n            </div>\n            <footer class=\"bg-grey flex-fill mt-4 text-center\">footer</footer>\n          </div>\n        </>\n      ))\n\n      // 272 = 3 * 80px (card height) + 2 * 16px (ga-4)\n      expect(screen.getByCSS('.v-divider')).toHaveStyle({ height: '272px' })\n    })\n\n    it('takes relative height in flexbox container with dynamic height', () => {\n      render(() => (\n        <>\n          <div class=\"d-flex w-100 pa-6\">\n            <aside class=\"bg-grey\" style=\"width: 200px; height: 300px\">\n              Sidebar\n            </aside>\n            <VDivider\n              vertical\n              class=\"mx-2 opacity-100 text-red\"\n            ></VDivider>\n            <main class=\"bg-grey align-self-stretch flex-fill\">Content</main>\n          </div>\n        </>\n      ))\n\n      expect(screen.getByCSS('.v-divider')).toHaveStyle({ height: '300px' })\n    })\n  })\n\n  describe('separator in list', () => {\n    it('takes full width in VList', () => {\n      render(() => (\n        <div\n          class=\"ma-2 pa-3 d-flex flex-column\"\n          style=\"height: 370px; width: 940px; outline: 1px solid currentColor\"\n        >\n          <aside class=\"pr-4\" style=\"max-width: 200px\">\n            <VList class=\"bg-transparent py-0\">\n              {[1, 2, 3].map(idx => (\n                <>\n                  { idx > 1 && (\n                    <VDivider class=\"my-2 opacity-100 text-red\"></VDivider>\n                  )}\n                  <VListItem\n                    rounded=\"lg\"\n                    class=\"bg-grey\"\n                    title={ `Nav item ${idx}` }\n                  ></VListItem>\n                </>\n              ))}\n            </VList>\n          </aside>\n        </div>\n      ))\n      expect(screen.getAllByCSS('.v-divider')).toHaveLength(2)\n      for (const item of screen.getAllByCSS('.v-divider')) {\n        expect(item).toHaveStyle({ width: '184px' })\n      }\n    })\n  })\n\n  describe('separator in grid', () => {\n    it('takes only necessary height when grid wraps', () => {\n      render(() => (\n        <>\n          <div\n            class=\"ma-2 pa-3\"\n            style=\"height: 370px; width: 940px; outline: 1px solid currentColor\"\n          >\n            <VRow class=\"align-content-start\" gap={[12, 24]}>\n              {[0, 1, 2, 3, 4, 5, 6, 7, 8].map(idx => (\n                <>\n                  { idx % 4 !== 0 && (\n                    <VDivider\n                      vertical\n                      style=\"margin: -12px -6px -12px -7px\"\n                      class=\"opacity-100 text-red\"\n                    ></VDivider>\n                  )}\n                  <VCol cols=\"3\">\n                    <VCard color=\"grey\" height=\"80\"></VCard>\n                  </VCol>\n                </>\n              ))}\n            </VRow>\n          </div>\n        </>\n      ))\n      expect(screen.getAllByCSS('.v-divider')).toHaveLength(6)\n      // 80px + 2 * 12px (v-col + negative margin)\n      for (const item of screen.getAllByCSS('.v-divider')) {\n        expect(item).toHaveStyle({ height: '104px' })\n      }\n    })\n  })\n\n  describe('vertical inset variant', () => {\n    it('accepts `inset` prop to get predefined margin', () => {\n      render(() => (\n        <>\n          <div\n            class=\"ma-2 d-flex align-center justify-center bg-grey-lighten-2\"\n            style=\"height: 200px;\"\n          >\n            <VDivider\n              vertical\n              inset\n              class=\"opacity-100 text-red\"\n            ></VDivider>\n          </div>\n        </>\n      ))\n\n      // 200px - 2 * 8px (inset margin)\n      expect(screen.getByCSS('.v-divider')).toHaveStyle({ height: '184px' })\n    })\n\n    it('accepts custom margin', () => {\n      render(() => (\n        <>\n          <div\n            class=\"ma-2 d-flex align-center justify-center bg-grey-lighten-2\"\n            style=\"height: 200px;\"\n          >\n            <VDivider\n              vertical\n              thickness=\"3\"\n              class=\"my-6 opacity-100 text-red\"\n            ></VDivider>\n          </div>\n          <div class=\"ma-2 d-flex align-center bg-grey-lighten-2\">\n            <VCard color=\"blue\" width=\"200\" height=\"200\" rounded=\"circle\"></VCard>\n            <VDivider\n              vertical\n              thickness=\"3\"\n              class=\"ma-6 opacity-100 text-red\"\n            ></VDivider>\n          </div>\n        </>\n      ))\n\n      expect(screen.getAllByCSS('.v-divider')).toHaveLength(2)\n      // 200px - 2 * 24px (margin)\n      for (const item of screen.getAllByCSS('.v-divider')) {\n        expect(item).toHaveStyle({ height: '152px' })\n      }\n    })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VDivider/_variables.scss",
    "content": "@use '../../styles/settings';\n\n// VDivider\n$divider-border-color: null !default;\n$divider-border-style: settings.$border-style-root !default;\n$divider-border-width: thin 0 0 0 !default;\n$divider-content-padding: 0 16px !default;\n$divider-content-vertical-padding: 4px 0 !default;\n$divider-flex: 1 1 100% !default;\n$divider-gradient-mask: linear-gradient(90deg, transparent, #000, transparent) !default;\n$divider-inset-margin: 72px !default;\n$divider-inset-max-width: calc(100% - #{$divider-inset-margin}) !default;\n$divider-margin: 8px !default;\n$divider-opacity: var(--v-border-opacity) !default;\n$divider-vertical-border-width: 0 thin 0 0 !default;\n$divider-vertical-inset-margin-bottom: $divider-margin !default;\n$divider-vertical-inset-margin-top: $divider-margin !default;\n$divider-vertical-inset-max-height: calc(100% - #{$divider-margin * 2}) !default;\n$divider-vertical-gradient-mask: linear-gradient(0deg, transparent, #000, transparent) !default;\n$divider-vertical-margin-left: -1px !default;\n\n\n// Lists\n$divider-border: (\n  $divider-border-color,\n  $divider-border-style,\n  $divider-border-width\n) !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VDivider/index.ts",
    "content": "export { VDivider } from './VDivider'\n"
  },
  {
    "path": "packages/vuetify/src/components/VEmptyState/VEmptyState.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-empty-state\n    align-items: center\n    display: flex\n    flex-direction: column\n    justify-content: center\n    min-height: $empty-state-min-height\n    padding: $empty-state-padding\n\n    &--start\n      align-items: flex-start\n\n    &--center\n      align-items: center\n\n    &--end\n      align-items: flex-end\n\n  .v-empty-state__media\n    text-align: center\n    width: 100%\n\n    .v-icon\n      color: $empty-state-media-icon-color\n\n  .v-empty-state__headline\n    color: $empty-state-headline-color\n    font-size: $empty-state-headline-font-size\n    font-weight: $empty-state-headline-font-weight\n    line-height: $empty-state-headline-line-height\n    text-align: center\n    margin-bottom: $empty-state-headline-margin-bottom\n\n    .v-empty-state--mobile &\n      font-size: $empty-state-headline-mobile-font-size\n\n  .v-empty-state__title\n    font-size: $empty-state-title-font-size\n    font-weight: $empty-state-title-font-weight\n    line-height: $empty-state-title-line-height\n    margin-bottom: $empty-state-title-margin-bottom\n    text-align: center\n\n  .v-empty-state__text\n    font-size: $empty-state-text-font-size\n    font-weight: $empty-state-text-font-weight\n    line-height: $empty-state-text-line-height\n    padding: $empty-state-text-padding\n    text-align: center\n\n  .v-empty-state__content\n    padding: $empty-state-content-padding\n\n  .v-empty-state__actions\n    display: flex\n    gap: $empty-state-actions-gap\n    padding: $empty-state-actions-padding\n\n  .v-empty-state__action-btn.v-btn\n    background-color: $empty-state-actions-btn-background-color\n    color: $empty-state-actions-btn-color\n"
  },
  {
    "path": "packages/vuetify/src/components/VEmptyState/VEmptyState.tsx",
    "content": "// Styles\nimport './VEmptyState.sass'\n\n// Components\nimport { VBtn } from '@/components/VBtn'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\nimport { VIcon } from '@/components/VIcon'\nimport { VImg } from '@/components/VImg'\n\n// Composables\nimport { useBackgroundColor } from '@/composables/color'\nimport { makeComponentProps } from '@/composables/component'\nimport { makeDimensionProps, useDimension } from '@/composables/dimensions'\nimport { useDisplay } from '@/composables/display'\nimport { IconValue } from '@/composables/icons'\nimport { makeSizeProps } from '@/composables/size'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\n\n// Utilities\nimport { convertToUnit, genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\n// Types\n\nexport type VEmptyStateSlots = {\n  actions: {\n    props: {\n      onClick: (e: Event) => void\n    }\n  }\n  default: never\n  headline: never\n  title: never\n  media: never\n  text: never\n}\n\nexport const makeVEmptyStateProps = propsFactory({\n  actionText: String,\n  bgColor: String,\n  color: String,\n  icon: IconValue,\n  image: String,\n  justify: {\n    type: String as PropType<'start' | 'center' | 'end'>,\n    default: 'center',\n  },\n  headline: String,\n  title: String,\n  text: String,\n  textWidth: {\n    type: [Number, String],\n    default: 500,\n  },\n  href: String,\n  to: String,\n\n  ...makeComponentProps(),\n  ...makeDimensionProps(),\n  ...makeSizeProps({ size: undefined }),\n  ...makeThemeProps(),\n}, 'VEmptyState')\n\nexport const VEmptyState = genericComponent<VEmptyStateSlots>()({\n  name: 'VEmptyState',\n\n  props: makeVEmptyStateProps(),\n\n  emits: {\n    'click:action': (e: Event) => true,\n  },\n\n  setup (props, { emit, slots }) {\n    const { themeClasses } = provideTheme(props)\n    const { backgroundColorClasses, backgroundColorStyles } = useBackgroundColor(() => props.bgColor)\n    const { dimensionStyles } = useDimension(props)\n    const { displayClasses } = useDisplay()\n\n    function onClickAction (e: Event) {\n      emit('click:action', e)\n    }\n\n    useRender(() => {\n      const hasActions = !!(slots.actions || props.actionText)\n      const hasHeadline = !!(slots.headline || props.headline)\n      const hasTitle = !!(slots.title || props.title)\n      const hasText = !!(slots.text || props.text)\n      const hasMedia = !!(slots.media || props.image || props.icon)\n      const size = props.size || (props.image ? 200 : 96)\n\n      return (\n        <div\n          class={[\n            'v-empty-state',\n            {\n              [`v-empty-state--${props.justify}`]: true,\n            },\n            themeClasses.value,\n            backgroundColorClasses.value,\n            displayClasses.value,\n            props.class,\n          ]}\n          style={[\n            backgroundColorStyles.value,\n            dimensionStyles.value,\n            props.style,\n          ]}\n        >\n          { hasMedia && (\n            <div key=\"media\" class=\"v-empty-state__media\">\n              { !slots.media ? (\n                <>\n                  { props.image ? (\n                    <VImg\n                      key=\"image\"\n                      src={ props.image }\n                      height={ size }\n                    />\n                  ) : props.icon ? (\n                    <VIcon\n                      key=\"icon\"\n                      color={ props.color }\n                      size={ size }\n                      icon={ props.icon }\n                    />\n                  ) : undefined }\n                </>\n              ) : (\n                <VDefaultsProvider\n                  key=\"media-defaults\"\n                  defaults={{\n                    VImg: {\n                      src: props.image,\n                      height: size,\n                    },\n                    VIcon: {\n                      size,\n                      icon: props.icon,\n                    },\n                  }}\n                >\n                  { slots.media() }\n                </VDefaultsProvider>\n              )}\n            </div>\n          )}\n\n          { hasHeadline && (\n            <div key=\"headline\" class=\"v-empty-state__headline\">\n              { slots.headline?.() ?? props.headline }\n            </div>\n          )}\n\n          { hasTitle && (\n            <div key=\"title\" class=\"v-empty-state__title\">\n              { slots.title?.() ?? props.title }\n            </div>\n          )}\n\n          { hasText && (\n            <div\n              key=\"text\"\n              class=\"v-empty-state__text\"\n              style={{\n                maxWidth: convertToUnit(props.textWidth),\n              }}\n            >\n              { slots.text?.() ?? props.text }\n            </div>\n          )}\n\n          { slots.default && (\n            <div key=\"content\" class=\"v-empty-state__content\">\n              { slots.default() }\n            </div>\n          )}\n\n          { hasActions && (\n            <div key=\"actions\" class=\"v-empty-state__actions\">\n              <VDefaultsProvider\n                defaults={{\n                  VBtn: {\n                    class: 'v-empty-state__action-btn',\n                    color: props.color ?? 'surface-variant',\n                    href: props.href,\n                    text: props.actionText,\n                    to: props.to,\n                  },\n                }}\n              >\n                {\n                  slots.actions?.({ props: { onClick: onClickAction } }) ?? (\n                    <VBtn onClick={ onClickAction } />\n                  )\n                }\n              </VDefaultsProvider>\n            </div>\n          )}\n        </div>\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VEmptyState = InstanceType<typeof VEmptyState>\n"
  },
  {
    "path": "packages/vuetify/src/components/VEmptyState/_variables.scss",
    "content": "@use '../../styles/settings';\n@use \"../../styles/tools/functions\";\n\n$empty-state-actions-btn-background-color: initial !default;\n$empty-state-actions-btn-color: initial !default;\n$empty-state-actions-gap: 8px !default;\n$empty-state-actions-padding: 16px !default;\n$empty-state-content-padding: 24px 0 !default;\n$empty-state-headline-color: functions.theme-color('on-surface', var(--v-medium-emphasis-opacity)) !default;\n$empty-state-headline-font-size: functions.map-deep-get(settings.$typography, 'display-large', 'size') !default;\n$empty-state-headline-font-weight: functions.map-deep-get(settings.$typography, 'display-large', 'weight') !default;\n$empty-state-headline-line-height: functions.map-deep-get(settings.$typography, 'display-large', 'line-height') !default;\n$empty-state-headline-margin-bottom: 8px !default;\n$empty-state-headline-mobile-font-size: functions.map-deep-get(settings.$typography, 'headline-large', 'size') !default;\n$empty-state-image-padding: 16px !default;\n$empty-state-min-height: 100% !default;\n$empty-state-media-icon-color: functions.theme-color('on-surface', var(--v-medium-emphasis-opacity)) !default;\n$empty-state-padding: 16px !default;\n$empty-state-text-font-size: functions.map-deep-get(settings.$typography, 'body-medium', 'size') !default;\n$empty-state-text-font-weight: functions.map-deep-get(settings.$typography, 'body-medium', 'weight') !default;\n$empty-state-text-line-height: functions.map-deep-get(settings.$typography, 'body-medium', 'line-height') !default;\n$empty-state-text-padding: 0 16px !default;\n$empty-state-title-font-size: functions.map-deep-get(settings.$typography, 'title-large', 'size') !default;\n$empty-state-title-font-weight: functions.map-deep-get(settings.$typography, 'title-large', 'weight') !default;\n$empty-state-title-line-height: functions.map-deep-get(settings.$typography, 'title-large', 'line-height') !default;\n$empty-state-title-margin-bottom: 4px !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VEmptyState/index.ts",
    "content": "export { VEmptyState } from './VEmptyState'\n"
  },
  {
    "path": "packages/vuetify/src/components/VExpansionPanel/VExpansionPanel.sass",
    "content": "@use 'sass:math'\n@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  // Theme\n  .v-expansion-panel\n    background-color: $expansion-panel-background-color\n    color: $expansion-panel-color\n\n    &:not(:first-child)::after\n      border-color: $expansion-panel-border-color\n\n    &--disabled\n      .v-expansion-panel-title\n        color: $expansion-panel-disabled-color\n\n        .v-expansion-panel-title__overlay\n          // This is multiplied by the text opacity,\n          // so we need to divide it to get the desired value\n          // TODO: Should disabled be part of states mixin?\n          opacity: math.div($expansion-panel-disabled-overlay, $expansion-panel-disabled-opacity)\n\n  // Block\n  .v-expansion-panels\n    display: flex\n    flex-wrap: wrap\n    justify-content: center\n    list-style-type: none\n    padding: 0\n    width: 100%\n    position: relative\n    z-index: 1\n    border-radius: $expansion-panel-border-radius\n\n    @include tools.layer('overrides')\n      > :first-child\n        border-top-left-radius: inherit\n        border-top-right-radius: inherit\n\n      > :last-child\n        border-bottom-left-radius: inherit\n        border-bottom-right-radius: inherit\n\n      &:not(&--variant-accordion)\n        > .v-expansion-panel--active\n          border-radius: inherit\n\n        > .v-expansion-panel--before-active\n          border-bottom-left-radius: inherit\n          border-bottom-right-radius: inherit\n\n        > .v-expansion-panel--after-active\n          border-top-left-radius: inherit\n          border-top-right-radius: inherit\n\n        > :not(:first-child):not(.v-expansion-panel--after-active):not(.v-expansion-panel--active)\n          border-top-left-radius: 0\n          border-top-right-radius: 0\n\n        > :not(:last-child):not(.v-expansion-panel--before-active):not(.v-expansion-panel--active)\n          border-bottom-left-radius: 0\n          border-bottom-right-radius: 0\n\n      &--variant-accordion\n        > :first-child:not(:last-child)\n          border-bottom-left-radius: 0\n          border-bottom-right-radius: 0\n\n        > :last-child:not(:first-child)\n          border-top-left-radius: 0\n          border-top-right-radius: 0\n\n          .v-expansion-panel-title--active\n            border-bottom-left-radius: initial\n            border-bottom-right-radius: initial\n\n        > :not(:first-child):not(:last-child)\n          border-radius: 0\n\n    &--variant-accordion\n      .v-expansion-panel-title__overlay\n        transition: 0.3s border-radius settings.$standard-easing\n\n  // Element\n  .v-expansion-panel\n    flex: 1 0 100%\n    max-width: 100%\n    position: relative\n    transition: .3s all settings.$standard-easing\n    transition-property: margin-top, border-radius, border, max-width\n    border-radius: $expansion-panel-border-radius\n\n    @media (prefers-reduced-motion: reduce)\n      transition-property: border-radius, border\n\n    &:not(:first-child)::after\n      border-top-style: solid\n      border-top-width: thin\n      content: ''\n      left: 0\n      position: absolute\n      right: 0\n      top: 0\n      transition: 0.3s opacity settings.$standard-easing\n\n    &--disabled\n      .v-expansion-panel-title\n        pointer-events: none\n\n    &--active\n      &:not(:first-child),\n      + .v-expansion-panel\n        margin-top: $expansion-panel-active-margin\n\n        &::after\n          opacity: 0\n\n      > .v-expansion-panel-title\n        border-bottom-left-radius: 0\n        border-bottom-right-radius: 0\n\n        &:not(.v-expansion-panel-title--static)\n          min-height: $expansion-panel-active-title-min-height\n\n  .v-expansion-panel__shadow\n    border-radius: inherit\n    z-index: -1\n    @include tools.absolute()\n    @include tools.elevation(1)\n\n  .v-expansion-panel-title\n    background-color: transparent\n    border: none\n    margin: 0\n    appearance: none\n    align-items: center\n    text-align: start\n    border-radius: inherit\n    display: flex\n    font: inherit\n    font-size: $expansion-panel-title-font-size\n    line-height: 1\n    min-height: $expansion-panel-title-min-height\n    outline: none\n    padding: $expansion-panel-title-padding\n    position: relative\n    width: 100%\n    justify-content: space-between\n\n    @media (prefers-reduced-motion: no-preference)\n      transition: .3s min-height settings.$standard-easing\n\n    @include tools.states('.v-expansion-panel-title__overlay', false)\n\n    &--focusable.v-expansion-panel-title--active\n      @include tools.active-states('.v-expansion-panel-title__overlay')\n\n  .v-expansion-panel-title__overlay\n    background-color: currentColor\n    border-radius: inherit\n    opacity: 0\n    @include tools.absolute()\n\n  .v-expansion-panel-title__icon\n    display: inline-flex\n    margin-bottom: -4px\n    margin-top: -4px\n    user-select: none\n    margin-inline-start: auto\n\n  .v-expansion-panel-text\n    display: flex\n\n    &__wrapper\n      padding: $expansion-panel-text-padding\n      flex: 1 1 auto\n      max-width: 100%\n\n  // Variants\n  .v-expansion-panels--variant-accordion\n    > .v-expansion-panel\n      margin-top: 0\n\n      &::after\n        opacity: 1\n\n  .v-expansion-panels--variant-popout\n    > .v-expansion-panel\n      max-width: $expansion-panel-popout-max-width\n\n      &--active\n        max-width: $expansion-panel-popout-active-max-width\n\n  .v-expansion-panels--variant-inset\n    > .v-expansion-panel\n      max-width: $expansion-panel-inset-max-width\n\n      &--active\n        max-width: $expansion-panel-inset-active-max-width\n\n  .v-expansion-panels--flat\n    > .v-expansion-panel\n      &::after\n        border-top: none\n\n      .v-expansion-panel__shadow\n        display: none\n\n  .v-expansion-panels--tile\n    border-radius: 0\n\n    > .v-expansion-panel\n      border-radius: 0\n"
  },
  {
    "path": "packages/vuetify/src/components/VExpansionPanel/VExpansionPanel.tsx",
    "content": "// Components\nimport { VExpansionPanelSymbol } from './shared'\nimport { makeVExpansionPanelTextProps, VExpansionPanelText } from './VExpansionPanelText'\nimport { makeVExpansionPanelTitleProps, VExpansionPanelTitle } from './VExpansionPanelTitle'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\n\n// Composables\nimport { useBackgroundColor } from '@/composables/color'\nimport { makeElevationProps, useElevation } from '@/composables/elevation'\nimport { makeGroupItemProps, useGroupItem } from '@/composables/group'\nimport { makeRoundedProps, useRounded } from '@/composables/rounded'\nimport { makeTagProps } from '@/composables/tag'\n\n// Utilities\nimport { computed, provide, toRef } from 'vue'\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\nexport const makeVExpansionPanelProps = propsFactory({\n  title: String,\n  text: String,\n  bgColor: String,\n\n  ...makeElevationProps(),\n  ...makeGroupItemProps(),\n  ...makeRoundedProps(),\n  ...makeTagProps(),\n  ...makeVExpansionPanelTitleProps(),\n  ...makeVExpansionPanelTextProps(),\n}, 'VExpansionPanel')\n\nexport type VExpansionPanelSlots = {\n  default: never\n  title: never\n  text: never\n}\n\nexport const VExpansionPanel = genericComponent<VExpansionPanelSlots>()({\n  name: 'VExpansionPanel',\n\n  props: makeVExpansionPanelProps(),\n\n  emits: {\n    'group:selected': (val: { value: boolean }) => true,\n  },\n\n  setup (props, { slots }) {\n    const groupItem = useGroupItem(props, VExpansionPanelSymbol)\n    const { backgroundColorClasses, backgroundColorStyles } = useBackgroundColor(() => props.bgColor)\n    const { elevationClasses } = useElevation(props)\n    const { roundedClasses } = useRounded(props)\n    const isDisabled = toRef(() => groupItem?.disabled.value || props.disabled)\n\n    const selectedIndices = computed(() => groupItem.group.items.value.reduce<number[]>((arr, item, index) => {\n      if (groupItem.group.selected.value.includes(item.id)) arr.push(index)\n      return arr\n    }, []))\n\n    const isBeforeSelected = computed(() => {\n      const index = groupItem.group.items.value.findIndex(item => item.id === groupItem.id)\n      return !groupItem.isSelected.value &&\n        selectedIndices.value.some(selectedIndex => selectedIndex - index === 1)\n    })\n\n    const isAfterSelected = computed(() => {\n      const index = groupItem.group.items.value.findIndex(item => item.id === groupItem.id)\n      return !groupItem.isSelected.value &&\n        selectedIndices.value.some(selectedIndex => selectedIndex - index === -1)\n    })\n\n    provide(VExpansionPanelSymbol, groupItem)\n\n    useRender(() => {\n      const hasText = !!(slots.text || props.text)\n      const hasTitle = !!(slots.title || props.title)\n\n      const expansionPanelTitleProps = VExpansionPanelTitle.filterProps(props)\n      const expansionPanelTextProps = VExpansionPanelText.filterProps(props)\n\n      return (\n        <props.tag\n          class={[\n            'v-expansion-panel',\n            {\n              'v-expansion-panel--active': groupItem.isSelected.value,\n              'v-expansion-panel--before-active': isBeforeSelected.value,\n              'v-expansion-panel--after-active': isAfterSelected.value,\n              'v-expansion-panel--disabled': isDisabled.value,\n            },\n            roundedClasses.value,\n            backgroundColorClasses.value,\n            props.class,\n          ]}\n          style={[\n            backgroundColorStyles.value,\n            props.style,\n          ]}\n        >\n          <div\n            class={[\n              'v-expansion-panel__shadow',\n              ...elevationClasses.value,\n            ]}\n          />\n\n          <VDefaultsProvider\n            defaults={{\n              VExpansionPanelTitle: {\n                ...expansionPanelTitleProps,\n              },\n              VExpansionPanelText: {\n                ...expansionPanelTextProps,\n              },\n            }}\n          >\n            { hasTitle && (\n              <VExpansionPanelTitle key=\"title\">\n                { slots.title ? slots.title() : props.title }\n              </VExpansionPanelTitle>\n            )}\n\n            { hasText && (\n              <VExpansionPanelText key=\"text\">\n                { slots.text ? slots.text() : props.text }\n              </VExpansionPanelText>\n            )}\n\n            { slots.default?.() }\n          </VDefaultsProvider>\n        </props.tag>\n      )\n    })\n\n    return {\n      groupItem,\n    }\n  },\n})\n\nexport type VExpansionPanel = InstanceType<typeof VExpansionPanel>\n"
  },
  {
    "path": "packages/vuetify/src/components/VExpansionPanel/VExpansionPanelText.tsx",
    "content": "// Components\nimport { VExpansionPanelSymbol } from './shared'\nimport { VExpandTransition } from '@/components/transitions'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { makeLazyProps, useLazy } from '@/composables/lazy'\n\n// Utilities\nimport { inject } from 'vue'\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\nexport const makeVExpansionPanelTextProps = propsFactory({\n  ...makeComponentProps(),\n  ...makeLazyProps(),\n}, 'VExpansionPanelText')\n\nexport const VExpansionPanelText = genericComponent()({\n  name: 'VExpansionPanelText',\n\n  props: makeVExpansionPanelTextProps(),\n\n  setup (props, { slots }) {\n    const expansionPanel = inject(VExpansionPanelSymbol)\n\n    if (!expansionPanel) throw new Error('[Vuetify] v-expansion-panel-text needs to be placed inside v-expansion-panel')\n\n    const { hasContent, onAfterLeave } = useLazy(props, expansionPanel.isSelected)\n\n    useRender(() => (\n      <VExpandTransition onAfterLeave={ onAfterLeave }>\n        <div\n          class={[\n            'v-expansion-panel-text',\n            props.class,\n          ]}\n          style={ props.style }\n          v-show={ expansionPanel.isSelected.value }\n        >\n          { slots.default && hasContent.value && (\n            <div class=\"v-expansion-panel-text__wrapper\">\n              { slots.default?.() }\n            </div>\n          )}\n        </div>\n      </VExpandTransition>\n    ))\n\n    return {}\n  },\n})\n\nexport type VExpansionPanelText = InstanceType<typeof VExpansionPanelText>\n"
  },
  {
    "path": "packages/vuetify/src/components/VExpansionPanel/VExpansionPanelTitle.tsx",
    "content": "// Components\nimport { VExpansionPanelSymbol } from './shared'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\nimport { VIcon } from '@/components/VIcon'\n\n// Composables\nimport { useBackgroundColor } from '@/composables/color'\nimport { makeComponentProps } from '@/composables/component'\nimport { makeDimensionProps, useDimension } from '@/composables/dimensions'\nimport { IconValue } from '@/composables/icons'\n\n// Directives\nimport vRipple from '@/directives/ripple'\n\n// Utilities\nimport { computed, inject, toRef } from 'vue'\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { RippleDirectiveBinding } from '@/directives/ripple'\n\ninterface ExpansionPanelTitleSlot {\n  collapseIcon: IconValue\n  disabled: boolean | undefined\n  expanded: boolean\n  expandIcon: IconValue\n  readonly: boolean\n}\n\nexport type VExpansionPanelTitleSlots = {\n  default: ExpansionPanelTitleSlot\n  actions: ExpansionPanelTitleSlot\n}\n\nexport const makeVExpansionPanelTitleProps = propsFactory({\n  color: String,\n  expandIcon: {\n    type: IconValue,\n    default: '$expand',\n  },\n  collapseIcon: {\n    type: IconValue,\n    default: '$collapse',\n  },\n  hideActions: Boolean,\n  focusable: Boolean,\n  static: Boolean,\n  ripple: {\n    type: [Boolean, Object] as PropType<RippleDirectiveBinding['value']>,\n    default: false,\n  },\n  readonly: Boolean,\n\n  ...makeComponentProps(),\n  ...makeDimensionProps(),\n}, 'VExpansionPanelTitle')\n\nexport const VExpansionPanelTitle = genericComponent<VExpansionPanelTitleSlots>()({\n  name: 'VExpansionPanelTitle',\n\n  directives: { vRipple },\n\n  props: makeVExpansionPanelTitleProps(),\n\n  setup (props, { slots }) {\n    const expansionPanel = inject(VExpansionPanelSymbol)\n\n    if (!expansionPanel) throw new Error('[Vuetify] v-expansion-panel-title needs to be placed inside v-expansion-panel')\n\n    const { backgroundColorClasses, backgroundColorStyles } = useBackgroundColor(() => props.color)\n    const { dimensionStyles } = useDimension(props)\n\n    const slotProps = computed(() => ({\n      collapseIcon: props.collapseIcon,\n      disabled: expansionPanel.disabled.value,\n      expanded: expansionPanel.isSelected.value,\n      expandIcon: props.expandIcon,\n      readonly: props.readonly,\n    }))\n\n    const icon = toRef(() => expansionPanel.isSelected.value ? props.collapseIcon : props.expandIcon)\n\n    useRender(() => (\n      <button\n        class={[\n          'v-expansion-panel-title',\n          {\n            'v-expansion-panel-title--active': expansionPanel.isSelected.value,\n            'v-expansion-panel-title--focusable': props.focusable,\n            'v-expansion-panel-title--static': props.static,\n          },\n          backgroundColorClasses.value,\n          props.class,\n        ]}\n        style={[\n          backgroundColorStyles.value,\n          dimensionStyles.value,\n          props.style,\n        ]}\n        type=\"button\"\n        tabindex={ expansionPanel.disabled.value ? -1 : undefined }\n        disabled={ expansionPanel.disabled.value }\n        aria-expanded={ expansionPanel.isSelected.value }\n        onClick={ !props.readonly ? expansionPanel.toggle : undefined }\n        v-ripple={ props.ripple }\n      >\n        <span class=\"v-expansion-panel-title__overlay\" />\n\n        { slots.default?.(slotProps.value) }\n\n        { !props.hideActions && (\n          <VDefaultsProvider\n            defaults={{\n              VIcon: {\n                icon: icon.value,\n              },\n            }}\n          >\n            <span class=\"v-expansion-panel-title__icon\">\n              { slots.actions?.(slotProps.value) ?? <VIcon /> }\n            </span>\n          </VDefaultsProvider>\n        )}\n      </button>\n    ))\n\n    return {}\n  },\n})\n\nexport type VExpansionPanelTitle = InstanceType<typeof VExpansionPanelTitle>\n"
  },
  {
    "path": "packages/vuetify/src/components/VExpansionPanel/VExpansionPanels.tsx",
    "content": "// Styles\nimport './VExpansionPanel.sass'\n\n// Components\nimport { VExpansionPanelSymbol } from './shared'\nimport { makeVExpansionPanelProps } from './VExpansionPanel'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { provideDefaults } from '@/composables/defaults'\nimport { makeGroupProps, useGroup } from '@/composables/group'\nimport { makeRoundedProps, useRounded } from '@/composables/rounded'\nimport { makeTagProps } from '@/composables/tag'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\n\n// Utilities\nimport { toRef } from 'vue'\nimport { genericComponent, pick, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { GenericProps } from '@/util'\n\nconst allowedVariants = ['default', 'accordion', 'inset', 'popout'] as const\n\ntype Variant = typeof allowedVariants[number]\n\nexport type VExpansionPanelSlot = {\n  prev: () => void\n  next: () => void\n}\n\nexport type VExpansionPanelSlots = {\n  default: VExpansionPanelSlot\n}\n\nexport const makeVExpansionPanelsProps = propsFactory({\n  flat: Boolean,\n\n  ...makeGroupProps(),\n  ...pick(makeVExpansionPanelProps(), [\n    'bgColor',\n    'collapseIcon',\n    'color',\n    'eager',\n    'elevation',\n    'expandIcon',\n    'focusable',\n    'hideActions',\n    'readonly',\n    'ripple',\n    'static',\n  ]),\n  ...makeRoundedProps(),\n  ...makeThemeProps(),\n  ...makeComponentProps(),\n  ...makeTagProps(),\n\n  variant: {\n    type: String as PropType<Variant>,\n    default: 'default',\n    validator: (v: any) => allowedVariants.includes(v),\n  },\n}, 'VExpansionPanels')\n\nexport const VExpansionPanels = genericComponent<new <TModel>(\n  props: {\n    modelValue?: TModel\n    'onUpdate:modelValue'?: (value: TModel) => void\n  },\n  slots: VExpansionPanelSlots\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VExpansionPanels',\n\n  props: makeVExpansionPanelsProps(),\n\n  emits: {\n    'update:modelValue': (val: unknown) => true,\n  },\n\n  setup (props, { slots }) {\n    const { next, prev } = useGroup(props, VExpansionPanelSymbol)\n\n    const { themeClasses } = provideTheme(props)\n    const { roundedClasses } = useRounded(props)\n\n    const variantClass = toRef(() => props.variant && `v-expansion-panels--variant-${props.variant}`)\n\n    provideDefaults({\n      VExpansionPanel: {\n        bgColor: toRef(() => props.bgColor),\n        collapseIcon: toRef(() => props.collapseIcon),\n        color: toRef(() => props.color),\n        eager: toRef(() => props.eager),\n        elevation: toRef(() => props.elevation),\n        expandIcon: toRef(() => props.expandIcon),\n        focusable: toRef(() => props.focusable),\n        hideActions: toRef(() => props.hideActions),\n        readonly: toRef(() => props.readonly),\n        ripple: toRef(() => props.ripple),\n        static: toRef(() => props.static),\n      },\n    })\n\n    useRender(() => (\n      <props.tag\n        class={[\n          'v-expansion-panels',\n          {\n            'v-expansion-panels--flat': props.flat,\n            'v-expansion-panels--tile': props.tile,\n          },\n          themeClasses.value,\n          roundedClasses.value,\n          variantClass.value,\n          props.class,\n        ]}\n        style={ props.style }\n      >\n        { slots.default?.({ prev, next }) }\n      </props.tag>\n    ))\n\n    return {\n      next,\n      prev,\n    }\n  },\n})\n\nexport type VExpansionPanels = InstanceType<typeof VExpansionPanels>\n"
  },
  {
    "path": "packages/vuetify/src/components/VExpansionPanel/__tests__/VExpansionPanels.spec.browser.tsx",
    "content": "// Components\nimport { VExpansionPanel, VExpansionPanels, VExpansionPanelText, VExpansionPanelTitle } from '..'\n\n// Utilities\nimport { render, screen, showcase, userEvent } from '@test'\nimport { ref } from 'vue'\n\nconst stories = {\n  'With rounded': (\n    <VExpansionPanels>\n      <VExpansionPanel value=\"foo\" title=\"Header\" text=\"Content\" rounded=\"xl\" />\n    </VExpansionPanels>\n  ),\n  'Single panel expanded': (\n    <VExpansionPanels modelValue=\"foo\">\n      <VExpansionPanel value=\"bar\" title=\"Header\" text=\"Content\" />\n      <VExpansionPanel value=\"foo\" title=\"Header\" text=\"Content\" />\n    </VExpansionPanels>\n  ),\n  'With colors': (\n    <VExpansionPanels>\n      <VExpansionPanel value=\"foo\" title=\"Header\" text=\"Content\" color=\"primary\" bgColor=\"secondary\" />\n    </VExpansionPanels>\n  ),\n  'Without action icons': (\n    <VExpansionPanels>\n      <VExpansionPanel hideActions title=\"Header\" text=\"Content\" />\n    </VExpansionPanels>\n  ),\n  'With title & text props': (\n    <VExpansionPanels>\n      {['Header 1', 'Header 2'].map((title, i) => (\n        <VExpansionPanel title={ title } text={ `${i}. Content` } />\n      ))}\n    </VExpansionPanels>\n  ),\n  'With title & text elements': (\n    <VExpansionPanels>\n      {['Header 1', 'Header 2'].map(title => (\n        <VExpansionPanel>\n          <VExpansionPanelTitle>{ title }</VExpansionPanelTitle>\n          <VExpansionPanelText>Content</VExpansionPanelText>\n        </VExpansionPanel>\n      ))}\n    </VExpansionPanels>\n  ),\n}\n\ndescribe('VExpansionPanels', () => {\n  it('responds to title click', async () => {\n    render(() => (\n      <VExpansionPanels>\n        <VExpansionPanel title=\"Header\" text=\"Content\" />\n      </VExpansionPanels>\n    ))\n\n    const title = screen.getByCSS('.v-expansion-panel-title')\n\n    await userEvent.click(title)\n\n    expect(title).toHaveClass('v-expansion-panel-title--active')\n  })\n\n  it('supports v-model', async () => {\n    const model = ref()\n    render(() => (\n      <>\n        <VExpansionPanels v-model={ model.value }>\n          <VExpansionPanel value=\"bar\" title=\"Header\" text=\"Content\" />\n          <VExpansionPanel value=\"foo\" title=\"Header\" text=\"Content\" />\n        </VExpansionPanels>\n        <div class=\"value\">{ model.value }</div>\n      </>\n    ))\n\n    await userEvent.click(screen.getAllByCSS('.v-expansion-panel-title')[1])\n\n    expect(screen.getAllByCSS('.v-expansion-panel-title')[1]).toHaveClass('v-expansion-panel-title--active')\n    expect(model.value).toBe('foo')\n  })\n\n  showcase({ stories })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VExpansionPanel/_variables.scss",
    "content": "@use '../../styles/settings';\n@use '../../styles/tools';\n\n// VExpansionPanel\n$expansion-panel-active-margin: 16px !default;\n$expansion-panel-background-color: rgb(var(--v-theme-surface)) !default;\n$expansion-panel-border-color: rgba(var(--v-border-color), var(--v-border-opacity)) !default;\n$expansion-panel-border-radius: settings.$border-radius-root !default;\n$expansion-panel-color: tools.theme-color('on-surface', var(--v-high-emphasis-opacity)) !default;\n$expansion-panel-disabled-opacity: 0.26 !default;\n$expansion-panel-disabled-color: tools.theme-color('on-surface', $expansion-panel-disabled-opacity) !default;\n$expansion-panel-disabled-overlay: 0.12 !default;\n$expansion-panel-inset-active-max-width: calc(100% - #{$expansion-panel-active-margin * 2}) !default;\n$expansion-panel-inset-max-width: 100% !default;\n$expansion-panel-popout-active-max-width: calc(100% + #{$expansion-panel-active-margin}) !default;\n$expansion-panel-popout-max-width: calc(100% - #{$expansion-panel-active-margin * 2}) !default;\n\n// VExpansionPanelTitle\n$expansion-panel-active-title-min-height: 64px !default;\n$expansion-panel-title-font-size: 0.9375rem !default;\n$expansion-panel-title-min-height: 48px !default;\n$expansion-panel-title-padding: 16px 24px !default;\n\n// VExpansionPanelText\n$expansion-panel-text-padding: 8px 24px 16px !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VExpansionPanel/index.ts",
    "content": "export { VExpansionPanels } from './VExpansionPanels'\nexport { VExpansionPanel } from './VExpansionPanel'\nexport { VExpansionPanelText } from './VExpansionPanelText'\nexport { VExpansionPanelTitle } from './VExpansionPanelTitle'\n"
  },
  {
    "path": "packages/vuetify/src/components/VExpansionPanel/shared.ts",
    "content": "// Types\nimport type { InjectionKey } from 'vue'\nimport type { GroupItemProvide } from '@/composables/group'\n\nexport const VExpansionPanelSymbol: InjectionKey<GroupItemProvide> = Symbol.for('vuetify:v-expansion-panel')\n"
  },
  {
    "path": "packages/vuetify/src/components/VFab/VFab.sass",
    "content": "@use '../../styles/tools'\n@use '../../styles/settings'\n@use 'sass:math'\n@use 'sass:map'\n@use './variables' as *\n@use './mixins' as *\n\n@include tools.layer('components')\n  .v-fab\n    align-items: center\n    display: inline-flex\n    flex: 1 1 auto\n    pointer-events: none\n    position: relative\n    transition-duration: $fab-transition-duration\n    transition-timing-function: $fab-transition-timing-function\n    vertical-align: middle\n\n    .v-btn\n      pointer-events: auto\n\n      &--variant-elevated\n        @include tools.elevation($fab-elevation)\n\n        &:hover\n          @include tools.elevation($fab-hover-elevation)\n\n    &--app,\n    &--absolute\n      display: flex\n\n    &--absolute\n      position: absolute\n      inset: 0\n\n    &--start,\n    &--left\n      justify-content: flex-start\n\n    &--center\n      align-items: center\n      justify-content: center\n\n    &--end,\n    &--right\n      justify-content: flex-end\n\n    &--bottom\n      align-items: flex-end\n\n    &--top\n      align-items: flex-start\n\n    &--extended\n      @include tools.layer('overrides')\n        .v-btn\n          // min-height: 56px\n          // min-width: 80px\n          border-radius: 9999px\n\n  .v-fab__container\n    align-self: center\n    display: inline-flex\n    vertical-align: middle\n\n    .v-fab--app &\n      margin: 12px\n      position: fixed\n\n    .v-fab--absolute &\n      position: absolute\n      z-index: 4\n\n    .v-fab--offset.v-fab--top &\n      transform: translateY(-50%)\n\n    .v-fab--offset.v-fab--bottom &\n      transform: translateY(50%)\n\n    .v-fab--top &\n      top: 0\n\n    .v-fab--bottom &\n      bottom: 0\n\n    .v-fab--left &,\n    .v-fab--start &\n      left: 0\n\n    .v-fab--right &,\n    .v-fab--end &\n      right: 0\n"
  },
  {
    "path": "packages/vuetify/src/components/VFab/VFab.tsx",
    "content": "// Styles\nimport './VFab.sass'\n\n// Components\nimport { makeVBtnProps, VBtn } from '@/components/VBtn/VBtn'\n\n// Composables\nimport { makeLayoutItemProps, useLayoutItem } from '@/composables/layout'\nimport { makeLocationProps } from '@/composables/location'\nimport { useProxiedModel } from '@/composables/proxiedModel'\nimport { useResizeObserver } from '@/composables/resizeObserver'\nimport { useToggleScope } from '@/composables/toggleScope'\nimport { makeTransitionProps, MaybeTransition } from '@/composables/transition'\n\n// Utilities\nimport { computed, ref, shallowRef, toRef, watchEffect } from 'vue'\nimport { genericComponent, omit, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { ComputedRef } from 'vue'\nimport type { Position } from '@/composables/layout'\n\nexport const makeVFabProps = propsFactory({\n  app: Boolean,\n  appear: Boolean,\n  extended: Boolean,\n  layout: Boolean,\n  offset: Boolean,\n  modelValue: {\n    type: Boolean,\n    default: true,\n  },\n\n  ...omit(makeVBtnProps({ active: true }), ['location', 'spaced']),\n  ...makeLayoutItemProps(),\n  ...makeLocationProps(),\n  ...makeTransitionProps({ transition: 'fab-transition' }),\n}, 'VFab')\n\nexport const VFab = genericComponent()({\n  name: 'VFab',\n\n  props: makeVFabProps(),\n\n  emits: {\n    'update:modelValue': (value: boolean) => true,\n  },\n\n  setup (props, { slots }) {\n    const model = useProxiedModel(props, 'modelValue')\n    const height = shallowRef(56)\n    const layoutItemStyles = ref()\n\n    const { resizeRef } = useResizeObserver(entries => {\n      if (!entries.length) return\n      height.value = entries[0].target.clientHeight\n    })\n\n    const hasPosition = toRef(() => props.app || props.absolute)\n\n    const position = computed(() => {\n      if (!hasPosition.value) return false\n\n      return props.location?.split(' ').shift() ?? 'bottom'\n    }) as ComputedRef<Position>\n\n    const orientation = computed(() => {\n      if (!hasPosition.value) return false\n\n      return props.location?.split(' ')[1] ?? 'end'\n    })\n\n    useToggleScope(() => props.app, () => {\n      const layout = useLayoutItem({\n        id: props.name,\n        order: computed(() => parseInt(props.order, 10)),\n        position,\n        layoutSize: computed(() => props.layout ? height.value + 24 : 0),\n        elementSize: computed(() => height.value + 24),\n        active: computed(() => props.app && model.value),\n        absolute: toRef(() => props.absolute),\n      })\n\n      watchEffect(() => {\n        layoutItemStyles.value = layout.layoutItemStyles.value\n      })\n    })\n\n    const vFabRef = ref()\n\n    useRender(() => {\n      const btnProps = VBtn.filterProps(props)\n\n      return (\n        <div\n          ref={ vFabRef }\n          class={[\n            'v-fab',\n            {\n              'v-fab--absolute': props.absolute,\n              'v-fab--app': !!props.app,\n              'v-fab--extended': props.extended,\n              'v-fab--offset': props.offset,\n              [`v-fab--${position.value}`]: hasPosition.value,\n              [`v-fab--${orientation.value}`]: hasPosition.value,\n            },\n            props.class,\n          ]}\n          style={[\n            props.app\n              ? { ...layoutItemStyles.value }\n              : {\n                height: props.absolute\n                  ? '100%'\n                  : 'inherit',\n              },\n            props.style,\n          ]}\n        >\n          <div class=\"v-fab__container\">\n            <MaybeTransition\n              appear={ props.appear }\n              transition={ props.transition }\n            >\n              <VBtn\n                v-show={ props.active }\n                ref={ resizeRef }\n                { ...btnProps }\n                active={ undefined }\n                location={ undefined }\n                v-slots={ slots }\n              />\n            </MaybeTransition>\n          </div>\n        </div>\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VFab = InstanceType<typeof VFab>\n"
  },
  {
    "path": "packages/vuetify/src/components/VFab/_mixins.scss",
    "content": "@use 'sass:math';\n@use 'sass:map';\n@use 'sass:meta';\n@use '../../styles/settings';\n@use '../../styles/tools';\n@use './variables' as *;\n\n@mixin fab-sizes ($map: $fab-sizes, $immediate: false) {\n  @each $sizeName, $multiplier in $fab-size-scales {\n    $size: map.get($map, 'font-size') + math.div(2 * $multiplier, 16);\n    $height: map.get($map, 'height') + (12px * $multiplier);\n\n    // .v-fab .v-btn--size-#{$sizeName} {\n    //   --v-btn-size: #{$size};\n    //   --v-btn-height: #{$height};\n    // }\n\n    .v-fab--bottom .v-btn--size-#{$sizeName} {\n      bottom: -1 * $height / 2;\n    }\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VFab/_variables.scss",
    "content": "@use 'sass:math';\n@use 'sass:map';\n@use '../../styles/settings';\n@use '../../styles/tools';\n\n$fab-border-radius: map.get(settings.$rounded, 'circle') !default;\n$fab-border-radius-multiplier: 0 !default; // 2.4 for MD3\n$fab-height: 56px !default;\n$fab-font-size: tools.map-deep-get(settings.$typography, 'label-large', 'size') !default;\n$fab-font-weight: tools.map-deep-get(settings.$typography, 'label-large', 'weight') !default;\n$fab-transition-duration: 0.2s !default;\n$fab-transition-timing-function: settings.$standard-easing !default;\n$fab-width-ratio: math.div(16, 9) !default;\n$fab-padding-ratio: 2.25 !default;\n$fab-elevation: 3 !default;\n$fab-hover-elevation: 4 !default;\n\n$fab-size-scales: (\n  'x-small': -2,\n  'small': -1,\n  'default': 0,\n  'large': 2,\n  'x-large': 5\n) !default;\n\n$fab-sizes: () !default;\n$fab-sizes: map.merge(\n  (\n    'height': $fab-height,\n    'font-size': $fab-font-size,\n    'width-ratio': $fab-width-ratio,\n    'padding-ratio': $fab-padding-ratio\n  ),\n  $fab-sizes\n);\n"
  },
  {
    "path": "packages/vuetify/src/components/VFab/index.ts",
    "content": "export { VFab } from './VFab'\n"
  },
  {
    "path": "packages/vuetify/src/components/VField/VField.sass",
    "content": "@use 'sass:map'\n@use 'sass:math'\n@use 'sass:selector'\n@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  /* region INPUT */\n  .v-field\n    display: grid\n    grid-template-areas: \"prepend-inner field clear append-inner\"\n    grid-template-columns: min-content minmax(0, 1fr) min-content min-content\n    font-size: $field-font-size\n    letter-spacing: $field-letter-spacing\n    max-width: $field-max-width\n    border-radius: $field-border-radius\n    contain: layout\n    flex: 1 0\n    grid-area: control\n    position: relative\n\n    --v-theme-overlay-multiplier: 1\n    --v-field-padding-start: #{$field-control-padding-start}\n    --v-field-padding-end: #{$field-control-padding-end}\n    --v-field-padding-top: #{$field-control-padding-top}\n    --v-field-padding-bottom: #{$field-control-padding-bottom}\n    --v-field-input-padding-top: #{$field-input-padding-top}\n    --v-field-input-padding-bottom: #{$field-input-padding-bottom}\n\n    &--disabled\n      opacity: var(--v-disabled-opacity)\n      pointer-events: none\n\n    .v-chip\n      --v-chip-height: #{$field-chip-height}\n\n  /* endregion */\n  /* region MODIFIERS */\n  .v-field\n    &--prepended\n      padding-inline-start: $field-control-affixed-padding\n\n    &--appended\n      padding-inline-end: $field-control-affixed-padding\n\n    &--variant-solo,\n    &--variant-solo-filled\n      background: $field-control-solo-background\n      border-color: transparent\n      color: $field-control-solo-color\n      @include tools.elevation($field-control-solo-elevation)\n\n    &--variant-solo-inverted\n      background: $field-control-solo-background\n      border-color: transparent\n      color: $field-control-solo-inverted-color\n      @include tools.elevation($field-control-solo-elevation)\n\n      &.v-field--focused\n        color: $field-control-solo-inverted-focused-color\n\n    &--variant-filled\n      border-bottom-left-radius: 0\n      border-bottom-right-radius: 0\n\n    &--variant-solo,\n    &--variant-solo-inverted,\n    &--variant-solo-filled,\n    &--variant-filled\n      $root: &\n\n      @at-root\n        @include tools.density('v-input', $input-density) using ($modifier)\n          @at-root #{selector.nest(&, $root)}\n            --v-input-control-height: #{$field-control-height + $modifier}\n            --v-field-padding-bottom: #{math.max(0px, $field-control-padding-bottom + $modifier * .5)}\n\n    &--variant-outlined,\n    &--single-line,\n    &--no-label\n      --v-field-padding-top: 0px\n      $root: &\n\n      @at-root\n        @include tools.density('v-input', $input-density) using ($modifier)\n          @at-root #{selector.nest(&, $root)}\n            --v-field-padding-bottom: #{16px + $modifier * .5}\n\n    &--variant-plain,\n    &--variant-underlined\n      $root: &\n      border-radius: 0\n      padding: 0\n\n      &.v-field\n        --v-field-padding-start: 0px\n        --v-field-padding-end: 0px\n\n      @at-root\n        @include tools.density('v-input', $input-density) using ($modifier)\n          @at-root #{selector.nest(&, $root)}\n            --v-input-control-height: #{$field-control-underlined-height + $modifier}\n            --v-field-padding-top: #{math.max(0px, 4px + $modifier * .25)}\n            --v-field-padding-bottom: #{math.max(0px, $field-control-padding-bottom + $modifier * .5)}\n\n    &--flat\n      box-shadow: none\n\n    &--rounded\n      @include tools.rounded($field-rounded-border-radius)\n\n    // These are separate so they can override the default variant styles\n    &.v-field\n      &--prepended\n        --v-field-padding-start: #{$field-control-affixed-inner-padding}\n\n      &--appended\n        --v-field-padding-end: #{$field-control-affixed-inner-padding}\n\n  /* endregion */\n  /* region ELEMENTS */\n  .v-field__input\n    align-items: center\n    color: inherit\n    column-gap: $field-input-column-gap\n    display: flex\n    flex-wrap: wrap\n    letter-spacing: $field-letter-spacing\n    opacity: $field-input-opacity\n    min-height: $field-input-min-height\n    min-width: 0\n    padding-inline: var(--v-field-padding-start) var(--v-field-padding-end)\n    padding-top: var(--v-field-input-padding-top)\n    padding-bottom: var(--v-field-input-padding-bottom)\n    position: relative\n    width: 100%\n\n    $root: &\n\n    @at-root\n      @include tools.density('v-input', $input-density) using ($modifier)\n        @at-root #{selector.nest(&, $root)}\n          row-gap: #{$field-input-row-gap + $modifier * .25}\n\n    input\n      letter-spacing: inherit\n\n    @at-root :where(& input, input#{&}, textarea#{&}, select#{&})\n      background-color: transparent\n      border-style: none\n      padding: 0\n      margin: 0\n\n      &::placeholder\n        color: currentColor\n        opacity: var(--v-disabled-opacity)\n\n    &:focus,\n    &:active\n      outline: none\n\n    // Remove Firefox red outline\n    &:invalid\n      box-shadow: none\n\n  .v-field__field\n    flex: 1 0\n    grid-area: field\n    position: relative\n    align-items: flex-start\n    display: flex\n\n  /* endregion */\n  /* region AFFIXES */\n  .v-field__prepend-inner\n    grid-area: prepend-inner\n    padding-inline-end: var(--v-field-padding-after)\n\n  .v-field__clearable\n    grid-area: clear\n\n  .v-field__append-inner\n    grid-area: append-inner\n    padding-inline-start: var(--v-field-padding-after)\n\n  .v-field__append-inner,\n  .v-field__clearable,\n  .v-field__prepend-inner\n    display: flex\n    align-items: flex-start\n    padding-top: var(--v-input-padding-top, $field-control-padding-top)\n\n    .v-field--center-affix &\n      align-items: center\n      padding-top: 0\n\n  .v-field.v-field--variant-underlined,\n  .v-field.v-field--variant-plain\n    .v-field__append-inner,\n    .v-field__clearable,\n    .v-field__prepend-inner\n      align-items: flex-start\n      padding-top: $field-input-padding-top\n      padding-bottom: $field-input-padding-bottom\n\n  .v-field__prepend-inner,\n  .v-field__append-inner\n    .v-field--focused &\n      opacity: 1\n\n  .v-field__prepend-inner,\n  .v-field__append-inner,\n  .v-field__clearable\n    > .v-icon\n      opacity: var(--v-medium-emphasis-opacity)\n\n    .v-field--disabled &,\n    .v-field--error &,\n    .v-field--glow.v-field--focused &\n      > .v-icon\n        opacity: 1\n\n    .v-field--error:not(.v-field--disabled) &\n      > .v-icon\n        color: rgb(var(--v-theme-error))\n\n  .v-field__clearable\n    cursor: pointer\n    opacity: 0\n    overflow: hidden\n    margin-inline: $field-clearable-margin\n    transition: $field-transition-timing\n    transition-property: opacity, transform, width\n\n    @media (prefers-reduced-motion: reduce)\n      transition-property: opacity\n\n    .v-field--focused &,\n    .v-field--persistent-clear &\n      opacity: 1\n\n    @media (hover: hover)\n      .v-field:hover &\n        opacity: 1\n\n    @media (hover: none)\n      opacity: 1\n\n  /* endregion */\n  /* region LABEL */\n  .v-label.v-field-label\n    contain: layout paint\n    display: block\n    margin-inline-start: var(--v-field-padding-start)\n    margin-inline-end: var(--v-field-padding-end)\n    max-width: calc(100% - var(--v-field-padding-start) - var(--v-field-padding-end))\n    pointer-events: none\n    position: absolute\n    top: var(--v-input-padding-top)\n    transform-origin: left center\n    z-index: 1\n\n    @media (prefers-reduced-motion: no-preference)\n      transition: $field-transition-timing\n      transition-property: opacity, transform\n\n    .v-field--variant-underlined &,\n    .v-field--variant-plain &\n      top: calc(var(--v-input-padding-top) + var(--v-field-padding-top))\n\n    .v-field--center-affix &\n      top: 50%\n      transform: translateY(-50%)\n\n    .v-field--active &\n      visibility: hidden\n\n    .v-field--focused &,\n    .v-field--error &\n      opacity: 1\n\n    .v-field--error:not(.v-field--disabled) &\n      color: rgb(var(--v-theme-error))\n\n    &--floating\n      --v-field-label-scale: #{$field-label-floating-scale}em\n      font-size: var(--v-field-label-scale)\n      visibility: hidden\n\n      .v-field--variant-outlined &\n        max-width: 100%\n\n      .v-field--center-affix &\n        transform: none\n\n      .v-field.v-field--active &\n        visibility: unset\n\n      .v-field--variant-solo &,\n      .v-field--variant-solo-inverted &,\n      .v-field--variant-filled &,\n      .v-field--variant-solo-filled &\n        $root: &\n\n        @at-root\n          @include tools.density('v-input', $input-density) using ($modifier)\n            @at-root #{selector.nest(&, $root)}\n              top: 7px + $modifier * .25\n\n      .v-field--variant-plain &,\n      .v-field--variant-underlined &\n        transform: translateY(-16px)\n        margin: 0\n        top: var(--v-input-padding-top)\n\n      .v-field--variant-outlined &\n        transform: translateY(-50%)\n        transform-origin: center\n        position: static\n        margin: 0 4px\n\n  /* endregion */\n  /* region OUTLINE */\n  .v-field__outline\n    --v-field-border-width: #{$field-border-width}\n    --v-field-border-opacity: #{$field-outline-opacity}\n    align-items: stretch\n    contain: layout\n    display: flex\n    height: 100%\n    left: 0\n    pointer-events: none\n    position: absolute\n    right: 0\n    width: 100%\n\n    @media (hover: hover)\n      .v-field:hover &\n        --v-field-border-opacity: var(--v-high-emphasis-opacity)\n\n    .v-field--error:not(.v-field--disabled) &\n      color: rgb(var(--v-theme-error))\n\n    .v-field.v-field--focused &,\n    .v-input.v-input--error &\n      --v-field-border-opacity: 1\n\n    .v-field--variant-outlined.v-field--focused &\n      --v-field-border-width: #{$field-focused-border-width}\n\n    .v-field--variant-filled &,\n    .v-field--variant-underlined &\n      &::before\n        border-color: currentColor\n        border-style: solid\n        border-width: 0 0 var(--v-field-border-width)\n        opacity: var(--v-field-border-opacity)\n        transition: opacity $field-subtle-transition-timing\n        @include tools.absolute(true)\n\n    .v-field--variant-filled &,\n    .v-field--variant-underlined &\n      &::after\n        border-color: currentColor\n        border-style: solid\n        border-width: 0 0 $field-focused-border-width\n        transform: scaleX(0)\n        transition: transform $field-transition-timing\n        @include tools.absolute(true)\n\n        @at-root #{selector.append('.v-field--focused', &)}\n          transform: scaleX(1)\n\n    .v-field--variant-outlined &\n      border-radius: inherit\n\n      &__start,\n      &__notch::before,\n      &__notch::after,\n      &__end\n        border: 0 solid currentColor\n        opacity: var(--v-field-border-opacity)\n\n        @media (prefers-reduced-motion: no-preference)\n          transition: opacity $field-subtle-transition-timing\n\n      &__start\n        flex: 0 0 $field-control-affixed-padding\n        border-top-width: var(--v-field-border-width)\n        border-bottom-width: var(--v-field-border-width)\n        border-inline-start-width: var(--v-field-border-width)\n        border-start-start-radius: inherit\n        border-start-end-radius: 0\n        border-end-end-radius: 0\n        border-end-start-radius: inherit\n\n        @at-root\n          #{selector.append('.v-field--rounded', &)},\n          #{selector.append('[class^=\"rounded-\"]', &)},\n          #{selector.append('[class*=\" rounded-\"]', &)}\n            flex-basis: calc(var(--v-input-control-height) / 2 + 2px)\n\n        @at-root #{selector.append('.v-field--reverse', &)}\n          border-start-start-radius: 0\n          border-start-end-radius: inherit\n          border-end-end-radius: inherit\n          border-end-start-radius: 0\n          border-inline-end-width: var(--v-field-border-width)\n          border-inline-start-width: 0\n\n      &__notch\n        flex: none\n        position: relative\n        max-width: calc(100% - $field-control-affixed-padding * 2)\n\n        @at-root\n          #{selector.append('.v-field--rounded', &)},\n          #{selector.append('[class^=\"rounded-\"]', &)},\n          #{selector.append('[class*=\" rounded-\"]', &)}\n            max-width: calc(100% - var(--v-input-control-height))\n\n        &::before,\n        &::after\n          opacity: var(--v-field-border-opacity)\n\n          @include tools.absolute(true)\n\n        &::before\n          border-width: var(--v-field-border-width) 0 0\n\n        &::after\n          bottom: 0\n          border-width: 0 0 var(--v-field-border-width)\n\n        @at-root #{selector.append('.v-field--active', &)}\n          &::before\n            opacity: 0\n\n      &__end\n        flex: 1\n        border-top-width: var(--v-field-border-width)\n        border-bottom-width: var(--v-field-border-width)\n        border-inline-end-width: var(--v-field-border-width)\n        border-start-start-radius: 0\n        border-start-end-radius: inherit\n        border-end-end-radius: inherit\n        border-end-start-radius: 0\n\n        @at-root #{selector.append('.v-field--reverse', &)}\n          border-start-start-radius: inherit\n          border-start-end-radius: 0\n          border-end-end-radius: 0\n          border-end-start-radius: inherit\n          border-inline-end-width: 0\n          border-inline-start-width: var(--v-field-border-width)\n\n  /* endregion */\n  /* region LOADER */\n  .v-field__loader\n    top: calc(100% - 2px)\n    left: 0\n    position: absolute\n    right: 0\n    width: 100%\n    border-top-left-radius: 0\n    border-top-right-radius: 0\n    border-bottom-left-radius: inherit\n    border-bottom-right-radius: inherit\n    overflow: hidden\n\n    .v-field--variant-outlined &\n      top: calc(100% - 3px)\n      width: calc(100% - #{$field-border-width} * 2)\n      left: $field-border-width\n\n  /* endregion */\n  /* region OVERLAY */\n  .v-field__overlay\n    border-radius: inherit\n    pointer-events: none\n\n    @include tools.absolute()\n\n  .v-field--variant-filled\n    .v-field__overlay\n      background-color: currentColor\n      opacity: $field-overlay-filled-opacity\n      transition: opacity $field-subtle-transition-timing\n\n    &.v-field--has-background .v-field__overlay\n      opacity: 0\n\n    @media (hover: hover)\n      &:hover .v-field__overlay\n        opacity: calc((#{$field-overlay-filled-opacity} + #{map.get(settings.$states, 'hover')}) * var(--v-theme-overlay-multiplier))\n\n    &.v-field--focused .v-field__overlay\n      opacity: calc((#{$field-overlay-filled-opacity} + #{map.get(settings.$states, 'focus')}) * var(--v-theme-overlay-multiplier))\n\n  .v-field--variant-solo-filled\n    .v-field__overlay\n      background-color: currentColor\n      opacity: $field-overlay-filled-opacity\n      transition: opacity $field-subtle-transition-timing\n\n    @media (hover: hover)\n      &:hover .v-field__overlay\n        opacity: calc((#{$field-overlay-filled-opacity} + #{map.get(settings.$states, 'hover')}) * var(--v-theme-overlay-multiplier))\n\n    &.v-field--focused .v-field__overlay\n      opacity: calc((#{$field-overlay-filled-opacity} + #{map.get(settings.$states, 'focus')}) * var(--v-theme-overlay-multiplier))\n\n  .v-field--variant-solo-inverted\n    .v-field__overlay\n      transition: opacity $field-subtle-transition-timing\n\n    &.v-field--has-background .v-field__overlay\n      opacity: 0\n\n    @media (hover: hover)\n      &:hover .v-field__overlay\n        opacity: calc((#{.04} + #{map.get(settings.$states, 'hover')}) * var(--v-theme-overlay-multiplier))\n\n    &.v-field--focused .v-field__overlay\n      background-color: $field-overlay-focused-background-color\n      opacity: 1\n\n  /* endregion */\n  /* region MODIFIERS */\n  .v-field--reverse\n    .v-field__field,\n    .v-field__input,\n    .v-field__outline\n      flex-direction: row-reverse\n\n    .v-field__input, input\n      text-align: end\n\n  .v-field--variant-filled,\n  .v-field--variant-underlined\n    .v-input--disabled &\n      .v-field__outline::before\n        border-image: repeating-linear-gradient(to right, $field-disabled-color 0px, $field-disabled-color 2px, transparent 2px, transparent 4px) 1 repeat\n\n  .v-field--loading\n    .v-field__outline::after,\n    .v-field__outline::before\n      opacity: 0\n\n  /* endregion */\n\n  @media (forced-colors: active)\n    .v-field\n      .v-progress-linear\n        border: none\n"
  },
  {
    "path": "packages/vuetify/src/components/VField/VField.tsx",
    "content": "// Styles\nimport './VField.sass'\n\n// Components\nimport { VFieldLabel } from './VFieldLabel'\nimport { VExpandXTransition } from '@/components/transitions'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\nimport { useInputIcon } from '@/components/VInput/InputIcon'\n\n// Composables\nimport { useBackgroundColor, useTextColor } from '@/composables/color'\nimport { makeComponentProps } from '@/composables/component'\nimport { makeFocusProps, useFocus } from '@/composables/focus'\nimport { IconValue } from '@/composables/icons'\nimport { LoaderSlot, makeLoaderProps, useLoader } from '@/composables/loader'\nimport { useRtl } from '@/composables/locale'\nimport { makeRoundedProps, useRounded } from '@/composables/rounded'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\n\n// Utilities\nimport { computed, ref, toRef, useId, watch } from 'vue'\nimport {\n  animate,\n  convertToUnit,\n  EventProp,\n  genericComponent,\n  nullifyTransforms,\n  PREFERS_REDUCED_MOTION,\n  propsFactory,\n  standardEasing,\n  useRender,\n} from '@/util'\n\n// Types\nimport type { ComputedRef, PropType, Ref } from 'vue'\nimport type { ClassValue } from '@/composables/component'\nimport type { LoaderSlotProps } from '@/composables/loader'\nimport type { GenericProps } from '@/util'\n\nconst allowedVariants = ['underlined', 'outlined', 'filled', 'solo', 'solo-inverted', 'solo-filled', 'plain'] as const\ntype Variant = typeof allowedVariants[number]\n\nexport interface DefaultInputSlot {\n  isActive: Ref<boolean>\n  isFocused: Ref<boolean>\n  iconColor: ComputedRef<string | undefined>\n  controlRef: Ref<HTMLElement | undefined>\n  focus: () => void\n  blur: () => void\n}\n\nexport interface VFieldSlot extends DefaultInputSlot {\n  props: Record<string, unknown> & {\n    class?: ClassValue\n  }\n}\n\nexport const makeVFieldProps = propsFactory({\n  appendInnerIcon: IconValue,\n  bgColor: String,\n  clearable: Boolean,\n  clearIcon: {\n    type: IconValue,\n    default: '$clear',\n  },\n  active: Boolean,\n  centerAffix: {\n    type: Boolean,\n    default: undefined,\n  },\n  color: String,\n  baseColor: String,\n  dirty: Boolean,\n  disabled: {\n    type: Boolean,\n    default: null,\n  },\n  glow: Boolean,\n  error: Boolean,\n  flat: Boolean,\n  iconColor: [Boolean, String],\n  label: String,\n  persistentClear: Boolean,\n  prependInnerIcon: IconValue,\n  reverse: Boolean,\n  singleLine: Boolean,\n  variant: {\n    type: String as PropType<Variant>,\n    default: 'filled',\n    validator: (v: any) => allowedVariants.includes(v),\n  },\n\n  'onClick:clear': EventProp<[MouseEvent]>(),\n  'onClick:appendInner': EventProp<[MouseEvent]>(),\n  'onClick:prependInner': EventProp<[MouseEvent]>(),\n\n  ...makeComponentProps(),\n  ...makeLoaderProps(),\n  ...makeRoundedProps(),\n  ...makeThemeProps(),\n}, 'VField')\n\nexport type VFieldSlots = {\n  clear: DefaultInputSlot & { props: Record<string, any> }\n  'prepend-inner': DefaultInputSlot\n  'append-inner': DefaultInputSlot\n  label: DefaultInputSlot & { label: string | undefined, props: Record<string, any> }\n  loader: LoaderSlotProps\n  default: VFieldSlot\n}\n\nexport const VField = genericComponent<new <T>(\n  props: {\n    modelValue?: T\n    'onUpdate:modelValue'?: (value: T) => void\n  },\n  slots: VFieldSlots\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VField',\n\n  inheritAttrs: false,\n\n  props: {\n    id: String,\n    details: Boolean,\n    labelId: String,\n\n    ...makeFocusProps(),\n    ...makeVFieldProps(),\n  },\n\n  emits: {\n    'update:focused': (focused: boolean) => true,\n    'update:modelValue': (value: any) => true,\n  },\n\n  setup (props, { attrs, emit, slots }) {\n    const { themeClasses } = provideTheme(props)\n    const { loaderClasses } = useLoader(props)\n    const { focusClasses, isFocused, focus, blur } = useFocus(props)\n    const { InputIcon } = useInputIcon(props)\n    const { roundedClasses } = useRounded(props)\n    const { rtlClasses } = useRtl()\n\n    const isActive = toRef(() => props.dirty || props.active)\n    const hasLabel = toRef(() => !!(props.label || slots.label))\n    const hasFloatingLabel = toRef(() => !props.singleLine && hasLabel.value)\n\n    const uid = useId()\n    const id = computed(() => props.id || `input-${uid}`)\n    const messagesId = toRef(() => !props.details ? undefined : `${id.value}-messages`)\n\n    const labelRef = ref<VFieldLabel>()\n    const floatingLabelRef = ref<VFieldLabel>()\n    const controlRef = ref<HTMLElement>()\n    const isPlainOrUnderlined = computed(() => ['plain', 'underlined'].includes(props.variant))\n    const color = computed(() => {\n      return props.error || props.disabled ? undefined\n        : isActive.value && isFocused.value ? props.color\n        : props.baseColor\n    })\n    const iconColor = computed(() => {\n      if (!props.iconColor || (props.glow && !isFocused.value)) return undefined\n\n      return props.iconColor === true ? color.value : props.iconColor\n    })\n\n    const { backgroundColorClasses, backgroundColorStyles } = useBackgroundColor(() => props.bgColor)\n    const { textColorClasses, textColorStyles } = useTextColor(color)\n\n    watch(isActive, val => {\n      if (hasFloatingLabel.value && !PREFERS_REDUCED_MOTION()) {\n        const el: HTMLElement = labelRef.value!.$el\n        const targetEl: HTMLElement = floatingLabelRef.value!.$el\n\n        requestAnimationFrame(() => {\n          const rect = nullifyTransforms(el)\n          const targetRect = targetEl.getBoundingClientRect()\n\n          const x = targetRect.x - rect.x\n          const y = targetRect.y - rect.y - (rect.height / 2 - targetRect.height / 2)\n\n          const targetWidth = targetRect.width / 0.75\n          const width = Math.abs(targetWidth - rect.width) > 1\n            ? { maxWidth: convertToUnit(targetWidth) }\n            : undefined\n\n          const style = getComputedStyle(el)\n          const targetStyle = getComputedStyle(targetEl)\n          const duration = parseFloat(style.transitionDuration) * 1000 || 150\n          const scale = parseFloat(targetStyle.getPropertyValue('--v-field-label-scale'))\n          const color = targetStyle.getPropertyValue('color')\n\n          el.style.visibility = 'visible'\n          targetEl.style.visibility = 'hidden'\n\n          animate(el, {\n            transform: `translate(${x}px, ${y}px) scale(${scale})`,\n            color,\n            ...width,\n          }, {\n            duration,\n            easing: standardEasing,\n            direction: val ? 'normal' : 'reverse',\n          }).finished.then(() => {\n            el.style.removeProperty('visibility')\n            targetEl.style.removeProperty('visibility')\n          })\n        })\n      }\n    }, { flush: 'post' })\n\n    const slotProps = computed<DefaultInputSlot>(() => ({\n      isActive,\n      isFocused,\n      controlRef,\n      iconColor,\n      blur,\n      focus,\n    }))\n\n    const floatingLabelProps = toRef(() => {\n      const ariaHidden = !isActive.value\n      return {\n        'aria-hidden': ariaHidden,\n        for: ariaHidden ? undefined : id.value,\n      }\n    })\n\n    const mainLabelProps = toRef(() => {\n      const ariaHidden = hasFloatingLabel.value && isActive.value\n      return {\n        'aria-hidden': ariaHidden,\n        for: ariaHidden ? undefined : id.value,\n      }\n    })\n\n    function onClick (e: MouseEvent) {\n      if (e.target !== document.activeElement) {\n        e.preventDefault()\n      }\n    }\n\n    useRender(() => {\n      const isOutlined = props.variant === 'outlined'\n      const hasPrepend = !!(slots['prepend-inner'] || props.prependInnerIcon)\n      const hasClear = !!(props.clearable || slots.clear) && !props.disabled\n      const hasAppend = !!(slots['append-inner'] || props.appendInnerIcon || hasClear)\n      const label = () => (\n        slots.label\n          ? slots.label({\n            ...slotProps.value,\n            label: props.label,\n            props: { for: id.value },\n          })\n          : props.label\n      )\n\n      return (\n        <div\n          class={[\n            'v-field',\n            {\n              'v-field--active': isActive.value,\n              'v-field--appended': hasAppend,\n              'v-field--center-affix': props.centerAffix ?? !isPlainOrUnderlined.value,\n              'v-field--disabled': props.disabled,\n              'v-field--dirty': props.dirty,\n              'v-field--error': props.error,\n              'v-field--glow': props.glow,\n              'v-field--flat': props.flat,\n              'v-field--has-background': !!props.bgColor,\n              'v-field--persistent-clear': props.persistentClear,\n              'v-field--prepended': hasPrepend,\n              'v-field--reverse': props.reverse,\n              'v-field--single-line': props.singleLine,\n              'v-field--no-label': !label(),\n              [`v-field--variant-${props.variant}`]: true,\n            },\n            themeClasses.value,\n            backgroundColorClasses.value,\n            focusClasses.value,\n            loaderClasses.value,\n            roundedClasses.value,\n            rtlClasses.value,\n            props.class,\n          ]}\n          style={[\n            backgroundColorStyles.value,\n            props.style,\n          ]}\n          onClick={ onClick }\n          { ...attrs }\n        >\n          <div class=\"v-field__overlay\" />\n\n          <LoaderSlot\n            name=\"v-field\"\n            active={ !!props.loading }\n            color={ props.error ? 'error' : (typeof props.loading === 'string' ? props.loading : props.color) }\n            v-slots={{ default: slots.loader }}\n          />\n\n          { hasPrepend && (\n            <div key=\"prepend\" class=\"v-field__prepend-inner\">\n              { slots['prepend-inner']\n                ? slots['prepend-inner'](slotProps.value)\n                : (props.prependInnerIcon && (\n                  <InputIcon\n                    key=\"prepend-icon\"\n                    name=\"prependInner\"\n                    color={ iconColor.value }\n                  />\n                ))\n              }\n            </div>\n          )}\n\n          <div class=\"v-field__field\" data-no-activator=\"\">\n            {['filled', 'solo', 'solo-inverted', 'solo-filled'].includes(props.variant) && hasFloatingLabel.value && (\n              <VFieldLabel\n                key=\"floating-label\"\n                ref={ floatingLabelRef }\n                class={[textColorClasses.value]}\n                floating\n                { ...floatingLabelProps.value }\n                style={ textColorStyles.value }\n              >\n                { label() }\n              </VFieldLabel>\n            )}\n\n            { hasLabel.value && (\n              <VFieldLabel\n                key=\"label\"\n                ref={ labelRef }\n                id={ props.labelId }\n                { ...mainLabelProps.value }\n              >\n                { label() }\n              </VFieldLabel>\n            )}\n\n            { slots.default?.({\n              ...slotProps.value,\n              props: {\n                id: id.value,\n                class: 'v-field__input',\n                'aria-describedby': messagesId.value,\n              },\n              focus,\n              blur,\n            } as VFieldSlot) ?? (\n              <div\n                id={ id.value }\n                class=\"v-field__input\"\n                aria-describedby={ messagesId.value }\n              />\n            )}\n          </div>\n\n          { hasClear && (\n            <VExpandXTransition key=\"clear\">\n              <div\n                class=\"v-field__clearable\"\n                v-show={ props.dirty }\n                onMousedown={ (e: MouseEvent) => {\n                  e.preventDefault()\n                  e.stopPropagation()\n                }}\n              >\n              <VDefaultsProvider\n                defaults={{\n                  VIcon: {\n                    icon: props.clearIcon,\n                  },\n                }}\n              >\n                { slots.clear\n                  ? slots.clear({\n                    ...slotProps.value,\n                    props: {\n                      onFocus: focus,\n                      onBlur: blur,\n                      onClick: props['onClick:clear'],\n                      tabindex: -1,\n                    },\n                  })\n                  : (\n                    <InputIcon\n                      name=\"clear\"\n                      onFocus={ focus }\n                      onBlur={ blur }\n                      tabindex={ -1 }\n                    />\n                  )}\n                </VDefaultsProvider>\n              </div>\n            </VExpandXTransition>\n          )}\n\n          { hasAppend && (\n            <div key=\"append\" class=\"v-field__append-inner\">\n              { slots['append-inner']\n                ? slots['append-inner'](slotProps.value)\n                : (props.appendInnerIcon && (\n                  <InputIcon\n                    key=\"append-icon\"\n                    name=\"appendInner\"\n                    color={ iconColor.value }\n                  />\n                ))\n              }\n            </div>\n          )}\n\n          <div\n            class={[\n              'v-field__outline',\n              textColorClasses.value,\n            ]}\n            style={ textColorStyles.value }\n          >\n            { isOutlined && (\n              <>\n                <div class=\"v-field__outline__start\" />\n\n                { hasFloatingLabel.value && (\n                  <div class=\"v-field__outline__notch\">\n                    <VFieldLabel\n                      ref={ floatingLabelRef }\n                      floating\n                      { ...floatingLabelProps.value }\n                    >\n                      { label() }\n                    </VFieldLabel>\n                  </div>\n                )}\n\n                <div class=\"v-field__outline__end\" />\n              </>\n            )}\n\n            { isPlainOrUnderlined.value && hasFloatingLabel.value && (\n              <VFieldLabel ref={ floatingLabelRef } floating { ...floatingLabelProps.value }>\n                { label() }\n              </VFieldLabel>\n            )}\n          </div>\n        </div>\n      )\n    })\n\n    return {\n      controlRef,\n      fieldIconColor: iconColor,\n    }\n  },\n})\n\nexport type VField = InstanceType<typeof VField>\n"
  },
  {
    "path": "packages/vuetify/src/components/VField/VFieldLabel.tsx",
    "content": "// Components\nimport { VLabel } from '@/components/VLabel'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\n\n// Utilities\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\nexport const makeVFieldLabelProps = propsFactory({\n  floating: Boolean,\n\n  ...makeComponentProps(),\n}, 'VFieldLabel')\n\nexport const VFieldLabel = genericComponent()({\n  name: 'VFieldLabel',\n\n  props: makeVFieldLabelProps(),\n\n  setup (props, { slots }) {\n    useRender(() => (\n      <VLabel\n        class={[\n          'v-field-label',\n          { 'v-field-label--floating': props.floating },\n          props.class,\n        ]}\n        style={ props.style }\n        v-slots={ slots }\n      />\n    ))\n\n    return {}\n  },\n})\n\nexport type VFieldLabel = InstanceType<typeof VFieldLabel>\n"
  },
  {
    "path": "packages/vuetify/src/components/VField/_variables.scss",
    "content": "@forward '../VInput/variables';\n@use 'sass:map';\n@use '../../styles/settings';\n@use '../../styles/tools';\n@use '../VInput/variables' as *;\n\n// INPUT\n$field-border-radius: settings.$border-radius-root !default;\n$field-rounded-border-radius: map.get(settings.$rounded, 'xl') !default;\n$field-color: tools.theme-color('on-surface', var(--v-medium-emphasis-opacity)) !default;\n$field-disabled-color: tools.theme-color('on-surface', var(--v-disabled-opacity)) !default;\n$field-error-color: rgb(var(--v-theme-error)) !default;\n$field-font-size: 16px !default;\n$field-letter-spacing: .009375em !default;\n$field-max-width: 100% !default;\n$field-transition-timing: .15s settings.$standard-easing !default;\n$field-subtle-transition-timing: 250ms settings.$standard-easing !default;\n$field-underlined-margin-bottom: 4px !default;\n$field-clearable-margin: 4px !default;\n$field-clearable-transition: .15s opacity, .15s width settings.$standard-easing !default;\n$field-chip-height: 24px !default;\n\n// CONTROL\n$field-control-solo-background: rgb(var(--v-theme-surface)) !default;\n$field-control-solo-color: tools.theme-color('on-surface', var(--v-high-emphasis-opacity)) !default;\n$field-control-solo-elevation: 1 !default;\n$field-control-solo-inverted-color: tools.theme-color('on-surface', var(--v-high-emphasis-opacity)) !default;\n$field-control-solo-inverted-focused-color: rgb(var(--v-theme-on-surface-variant)) !default;\n$field-control-filled-background: tools.theme-color('on-surface', var(--v-idle-opacity)) !default;\n$field-control-padding-start: 16px !default;\n$field-control-padding-end: 16px !default;\n$field-control-padding-top: 8px !default;\n$field-control-padding-bottom: 4px !default;\n$field-control-affixed-padding: 12px !default;\n$field-control-affixed-inner-padding: 6px !default;\n$field-control-underlined-height: 48px !default;\n$field-control-underlined-padding-bottom: 2px !default;\n$field-control-height: 56px !default;\n\n// INPUT\n$field-input-opacity: var(--v-high-emphasis-opacity) !default;\n$field-input-min-height: #{max(\n  var(--v-input-control-height, $input-control-height),\n  calc($input-font-size * $input-line-height + var(--v-field-input-padding-top) + var(--v-field-input-padding-bottom))\n)} !default;\n$field-input-padding-top: calc(var(--v-field-padding-top, $field-control-padding-top) + var(--v-input-padding-top, 0px)) !default;\n$field-input-padding-bottom: var(--v-field-padding-bottom, $field-control-padding-bottom) !default;\n$field-input-column-gap: 2px !default;\n$field-input-row-gap: 8px !default;\n\n// LABEL\n$field-label-floating-scale: .75 !default;\n\n// OUTLINE\n$field-outline-opacity: .38 !default;\n$field-border-width: 1px !default;\n$field-focused-border-width: 2px !default;\n\n// OVERLAY\n$field-overlay-filled-opacity: 0.04 !default;\n$field-overlay-focused-background-color: rgb(var(--v-theme-surface-variant)) !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VField/index.ts",
    "content": "export { VField } from './VField'\nexport { VFieldLabel } from './VFieldLabel'\n"
  },
  {
    "path": "packages/vuetify/src/components/VFileInput/VFileInput.sass",
    "content": "@use './variables' as *\n@use '../../styles/tools'\n@use 'sass:math'\n@use 'sass:selector'\n\n@include tools.layer('components')\n  .v-file-input\n    &--hide.v-input\n      .v-field,\n      .v-input__control,\n      .v-input__details\n        display: none\n\n      .v-input__prepend\n        grid-area: control\n        margin: 0 auto\n\n    &--chips.v-input--density-compact\n      .v-field--variant-solo,\n      .v-field--variant-solo-inverted,\n      .v-field--variant-filled,\n      .v-field--variant-solo-filled\n        .v-label.v-field-label\n          &--floating\n            top: 0px\n\n    .v-field__input\n      word-break: break-word\n\n    input[type=\"file\"]\n      height: 100%\n      left: 0\n      opacity: 0\n      position: absolute\n      top: 0\n      width: 100%\n      z-index: 0\n\n    &--dragging input[type=\"file\"]\n      z-index: 1\n"
  },
  {
    "path": "packages/vuetify/src/components/VFileInput/VFileInput.tsx",
    "content": "// Styles\nimport './VFileInput.sass'\n\n// Components\nimport { VChip } from '@/components/VChip'\nimport { VCounter } from '@/components/VCounter'\nimport { VField } from '@/components/VField'\nimport { makeVFieldProps } from '@/components/VField/VField'\nimport { makeVInputProps, VInput } from '@/components/VInput/VInput'\n\n// Composables\nimport { useFileDrop } from '@/composables/fileDrop'\nimport { makeFileFilterProps, useFileFilter } from '@/composables/fileFilter'\nimport { useFocus } from '@/composables/focus'\nimport { forwardRefs } from '@/composables/forwardRefs'\nimport { useLocale } from '@/composables/locale'\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { computed, nextTick, ref, shallowRef, toRef, watch } from 'vue'\nimport {\n  callEvent,\n  filterInputAttrs,\n  genericComponent,\n  humanReadableFileSize,\n  omit,\n  propsFactory,\n  useRender,\n  wrapInArray,\n} from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { VFieldSlots } from '@/components/VField/VField'\nimport type { VInputSlots } from '@/components/VInput/VInput'\n\nexport type VFileInputSlots = VInputSlots & VFieldSlots & {\n  counter: never\n  selection: {\n    fileNames: string[]\n    totalBytes: number\n    totalBytesReadable: string\n  }\n}\n\nexport const makeVFileInputProps = propsFactory({\n  chips: Boolean,\n  counter: Boolean,\n  counterSizeString: {\n    type: String,\n    default: '$vuetify.fileInput.counterSize',\n  },\n  counterString: {\n    type: String,\n    default: '$vuetify.fileInput.counter',\n  },\n  hideInput: Boolean,\n  multiple: Boolean,\n  showSize: {\n    type: [Boolean, Number, String] as PropType<boolean | 1000 | 1024>,\n    default: false,\n    validator: (v: boolean | number) => {\n      return (\n        typeof v === 'boolean' ||\n        [1000, 1024].includes(Number(v))\n      )\n    },\n  },\n  truncateLength: {\n    type: [Number, String],\n    default: 22,\n  },\n\n  ...omit(makeVInputProps({ prependIcon: '$file' }), ['direction']),\n\n  modelValue: {\n    type: [Array, Object] as PropType<File[] | File | null>,\n    default: (props: any) => props.multiple ? [] : null,\n    validator: (val: any) => {\n      return wrapInArray(val).every(v => v != null && typeof v === 'object')\n    },\n  },\n\n  ...makeFileFilterProps(),\n  ...makeVFieldProps({ clearable: true }),\n}, 'VFileInput')\n\nexport const VFileInput = genericComponent<VFileInputSlots>()({\n  name: 'VFileInput',\n\n  inheritAttrs: false,\n\n  props: makeVFileInputProps(),\n\n  emits: {\n    'click:control': (e: MouseEvent) => true,\n    'mousedown:control': (e: MouseEvent) => true,\n    'update:focused': (focused: boolean) => true,\n    'update:modelValue': (files: File | File[]) => true,\n    rejected: (files: File[]) => true,\n  },\n\n  setup (props, { attrs, emit, slots }) {\n    const { t } = useLocale()\n    const { filterAccepted } = useFileFilter(props)\n    const model = useProxiedModel(\n      props,\n      'modelValue',\n      props.modelValue,\n      val => wrapInArray(val),\n      val => (!props.multiple && Array.isArray(val)) ? val[0] : val,\n    )\n    const { isFocused, focus, blur } = useFocus(props)\n    const base = computed(() => typeof props.showSize !== 'boolean' ? props.showSize : undefined)\n    const totalBytes = computed(() => (model.value ?? []).reduce((bytes, { size = 0 }) => bytes + size, 0))\n    const totalBytesReadable = computed(() => humanReadableFileSize(totalBytes.value, base.value))\n\n    const fileNames = computed(() => (model.value ?? []).map(file => {\n      const { name = '', size = 0 } = file\n      const truncatedText = truncateText(name)\n      return !props.showSize\n        ? truncatedText\n        : `${truncatedText} (${humanReadableFileSize(size, base.value)})`\n    }))\n\n    const counterValue = computed(() => {\n      const fileCount = model.value?.length ?? 0\n      if (props.showSize) return t(props.counterSizeString, fileCount, totalBytesReadable.value)\n      else return t(props.counterString, fileCount)\n    })\n    const vInputRef = ref<VInput>()\n    const vFieldRef = ref<VField>()\n    const inputRef = ref<HTMLInputElement>()\n    const isActive = toRef(() => isFocused.value || props.active)\n    const isPlainOrUnderlined = computed(() => ['plain', 'underlined'].includes(props.variant))\n    const isDragging = shallowRef(false)\n    const { handleDrop, hasFilesOrFolders } = useFileDrop()\n\n    function onFocus () {\n      if (inputRef.value !== document.activeElement) {\n        inputRef.value?.focus()\n      }\n\n      if (!isFocused.value) focus()\n    }\n    function onClickPrepend (e: MouseEvent) {\n      inputRef.value?.click()\n    }\n    function onControlMousedown (e: MouseEvent) {\n      emit('mousedown:control', e)\n    }\n    function onControlClick (e: MouseEvent) {\n      inputRef.value?.click()\n\n      emit('click:control', e)\n    }\n    function onClear (e: MouseEvent) {\n      e.stopPropagation()\n\n      onFocus()\n\n      nextTick(() => {\n        model.value = []\n\n        callEvent(props['onClick:clear'], e)\n      })\n    }\n    function truncateText (str: string) {\n      if (str.length < Number(props.truncateLength)) return str\n      const charsKeepOneSide = Math.floor((Number(props.truncateLength) - 1) / 2)\n      return `${str.slice(0, charsKeepOneSide)}…${str.slice(str.length - charsKeepOneSide)}`\n    }\n    function onDragover (e: DragEvent) {\n      e.preventDefault()\n      e.stopImmediatePropagation()\n      isDragging.value = true\n    }\n    function onDragleave (e: DragEvent) {\n      e.preventDefault()\n      isDragging.value = false\n    }\n    async function onDrop (e: DragEvent) {\n      e.preventDefault()\n      e.stopImmediatePropagation()\n      isDragging.value = false\n\n      if (!inputRef.value || !hasFilesOrFolders(e)) return\n\n      const allDroppedFiles = await handleDrop(e)\n      selectAccepted(allDroppedFiles)\n    }\n\n    function onFileSelection (e: Event) {\n      if (!e.target || (e as any).repack) return // prevent loop\n\n      if (!props.filterByType) {\n        const target = e.target as HTMLInputElement\n        model.value = [...target.files ?? []]\n      } else {\n        selectAccepted([...(e as any).target.files])\n      }\n    }\n\n    function selectAccepted (files: File[]) {\n      const dataTransfer = new DataTransfer()\n      const { accepted, rejected } = filterAccepted(files)\n\n      if (rejected.length) {\n        emit('rejected', rejected)\n      }\n\n      for (const file of accepted) {\n        dataTransfer.items.add(file)\n      }\n\n      inputRef.value!.files = dataTransfer.files\n      model.value = [...dataTransfer.files]\n\n      const event = new Event('change', { bubbles: true }) as any\n      event.repack = true\n      inputRef.value!.dispatchEvent(event)\n    }\n\n    watch(model, newValue => {\n      const hasModelReset = !Array.isArray(newValue) || !newValue.length\n\n      if (hasModelReset && inputRef.value) {\n        inputRef.value.value = ''\n      }\n    })\n\n    useRender(() => {\n      const hasCounter = !!(slots.counter || props.counter)\n      const hasDetails = !!(hasCounter || slots.details)\n      const [rootAttrs, inputAttrs] = filterInputAttrs(attrs)\n      const { modelValue: _, ...inputProps } = VInput.filterProps(props)\n      const fieldProps = {\n        ...VField.filterProps(props),\n        'onClick:clear': onClear,\n      }\n\n      const expectsDirectory = attrs.webkitdirectory !== undefined && attrs.webkitdirectory !== false\n      const acceptFallback = attrs.accept ? String(attrs.accept) : undefined\n      const inputAccept = expectsDirectory ? undefined : (props.filterByType ?? acceptFallback)\n\n      return (\n        <VInput\n          ref={ vInputRef }\n          modelValue={ props.multiple ? model.value : model.value[0] }\n          class={[\n            'v-file-input',\n            {\n              'v-file-input--chips': !!props.chips,\n              'v-file-input--dragging': isDragging.value,\n              'v-file-input--hide': props.hideInput,\n              'v-input--plain-underlined': isPlainOrUnderlined.value,\n            },\n            props.class,\n          ]}\n          style={ props.style }\n          onClick:prepend={ onClickPrepend }\n          { ...rootAttrs }\n          { ...inputProps }\n          centerAffix={ !isPlainOrUnderlined.value }\n          focused={ isFocused.value }\n          indentDetails={ props.indentDetails ?? !isPlainOrUnderlined.value }\n        >\n          {{\n            ...slots,\n            default: ({\n              id,\n              isDisabled,\n              isDirty,\n              isReadonly,\n              isValid,\n              hasDetails,\n            }) => (\n              <VField\n                ref={ vFieldRef }\n                prependIcon={ props.prependIcon }\n                onMousedown={ onControlMousedown }\n                onClick={ onControlClick }\n                onClick:prependInner={ props['onClick:prependInner'] }\n                onClick:appendInner={ props['onClick:appendInner'] }\n                { ...fieldProps }\n                id={ id.value }\n                active={ isActive.value || isDirty.value }\n                dirty={ isDirty.value || props.dirty }\n                disabled={ isDisabled.value }\n                focused={ isFocused.value }\n                details={ hasDetails.value }\n                error={ isValid.value === false }\n                onDragover={ onDragover }\n                onDrop={ onDrop }\n              >\n                {{\n                  ...slots,\n                  default: ({\n                    props: { class: fieldClass, ...slotProps },\n                    controlRef,\n                  }) => (\n                    <>\n                      <input\n                        ref={ val => inputRef.value = controlRef.value = val as HTMLInputElement }\n                        type=\"file\"\n                        accept={ inputAccept }\n                        readonly={ isReadonly.value }\n                        disabled={ isDisabled.value }\n                        multiple={ props.multiple }\n                        name={ props.name }\n                        onClick={ e => {\n                          e.stopPropagation()\n\n                          if (isReadonly.value) e.preventDefault()\n\n                          onFocus()\n                        }}\n                        onChange={ onFileSelection }\n                        onDragleave={ onDragleave }\n                        onFocus={ onFocus }\n                        onBlur={ blur }\n                        { ...slotProps }\n                        { ...inputAttrs }\n                      />\n\n                      <div class={ fieldClass }>\n                        { !!model.value?.length && !props.hideInput && (\n                          slots.selection ? slots.selection({\n                            fileNames: fileNames.value,\n                            totalBytes: totalBytes.value,\n                            totalBytesReadable: totalBytesReadable.value,\n                          })\n                          : props.chips ? fileNames.value.map(text => (\n                            <VChip\n                              key={ text }\n                              size=\"small\"\n                              text={ text }\n                            />\n                          ))\n                          : fileNames.value.join(', ')\n                        )}\n                      </div>\n                    </>\n                  ),\n                }}\n              </VField>\n            ),\n            details: hasDetails ? slotProps => (\n              <>\n                { slots.details?.(slotProps) }\n\n                { hasCounter && (\n                  <>\n                    <span />\n\n                    <VCounter\n                      active={ !!model.value?.length }\n                      value={ counterValue.value }\n                      disabled={ props.disabled }\n                      v-slots:default={ slots.counter }\n                    />\n                  </>\n                )}\n              </>\n            ) : undefined,\n          }}\n        </VInput>\n      )\n    })\n\n    return forwardRefs({}, vInputRef, vFieldRef, inputRef)\n  },\n})\n\nexport type VFileInput = InstanceType<typeof VFileInput>\n"
  },
  {
    "path": "packages/vuetify/src/components/VFileInput/__tests__/VFileInput.spec.browser.tsx",
    "content": "// Components\nimport { VFileInput } from '../VFileInput'\n\n// Utilities\nimport { CenteredGrid, render, screen, showcase, userEvent } from '@test'\nimport { cloneVNode, defineComponent, ref } from 'vue'\n\nconst oneMBFile = new File([new ArrayBuffer(1021576)], '1MB file')\nconst twoMBFile = new File([new ArrayBuffer(2021152)], '2MB file')\n\nconst variants = ['underlined', 'outlined', 'filled', 'solo', 'plain'] as const\nconst densities = ['default', 'comfortable', 'compact'] as const\nconst items = ['California', 'Colorado', 'Florida', 'Georgia', 'Texas', 'Wyoming'] as const\n\nconst stories = Object.fromEntries(Object.entries({\n  'Default input': <VFileInput />,\n  Disabled: <VFileInput items={ items } disabled />,\n  'Prepend/append': <VFileInput items={ items } prependIcon=\"$vuetify\" appendIcon=\"$vuetify\" />,\n  'Prepend/append inner': <VFileInput items={ items } prependInnerIcon=\"$vuetify\" appendInnerIcon=\"$vuetify\" />,\n  Placeholder: <VFileInput items={ items } placeholder=\"placeholder\" persistentPlaceholder />,\n}).map(([k, v]) => [k, (\n  <div class=\"d-flex flex-column flex-grow-1\">\n    { variants.map(variant => (\n      densities.map(density => (\n        <div class=\"d-flex align-start\" style=\"gap: 0.4rem; height: 100px;\">\n          { cloneVNode(v, { variant, density, label: `${variant} ${density}` }) }\n          { cloneVNode(v, { variant, density, label: `with value`, modelValue: [oneMBFile, twoMBFile] }) }\n          { cloneVNode(v, { variant, density, label: `chips`, chips: true, modelValue: [oneMBFile, twoMBFile] }) }\n          <VFileInput\n            variant={ variant }\n            density={ density }\n            modelValue={[oneMBFile, twoMBFile]}\n            label=\"selection slot\"\n            { ...v.props }\n          >{{\n            selection: ({ fileNames }) => {\n              return fileNames.map(f => f)\n            },\n          }}\n          </VFileInput>\n        </div>\n      ))\n    )).flat()}\n  </div>\n)]))\n\ndescribe('VFileInput', () => {\n  // TODO: wdio crashes on .upload since vitest 3.2\n  it.todo('should add file', async () => {\n    const model = ref()\n    const { element } = render(() => (\n      <VFileInput v-model={ model.value } />\n    ))\n\n    const input = screen.getByCSS('input')\n\n    await userEvent.upload(input, 'text.txt')\n    expect(element).toHaveTextContent('text.txt')\n    expect(model.value).toEqual(expect.objectContaining({ name: 'text.txt' }))\n  })\n\n  it('should show number of files', async () => {\n    const { element } = render(() => (\n      <VFileInput modelValue={[oneMBFile, twoMBFile]} multiple counter />\n    ))\n\n    expect(element).toHaveTextContent('2 files')\n  })\n\n  it('should show size of files', async () => {\n    const { element } = render(() => (\n      <VFileInput modelValue={[oneMBFile, twoMBFile]} multiple showSize />\n    ))\n\n    expect(element).toHaveTextContent('1MB file (1.0 MB), 2MB file (2.0 MB)')\n  })\n\n  it('should show total size of files in counter', async () => {\n    const { element } = render(() => (\n      <VFileInput modelValue={[oneMBFile, twoMBFile]} multiple counter showSize />\n    ))\n\n    expect(element).toHaveTextContent('2 files (3.0 MB in total)')\n  })\n\n  it('should clear input', async () => {\n    const model = ref([oneMBFile, twoMBFile])\n    const { element } = render(() => (\n      <VFileInput v-model={ model.value } multiple />\n    ))\n\n    await userEvent.click(screen.getByLabelText(/clear/i))\n\n    expect(element).not.toHaveTextContent('1MB file, 2MB file')\n    expect(model.value).toHaveLength(0)\n    expect(screen.getByCSS('input')).toHaveValue('')\n  })\n\n  it('should support removing clearable icon', async () => {\n    render(() => (\n      <VFileInput modelValue={[oneMBFile, twoMBFile]} clearable={ false } />\n    ))\n\n    expect(screen.queryAllByLabelText(/clear/i)).toHaveLength(0)\n  })\n\n  it('should be disabled', async () => {\n    render(() => (\n      <VFileInput modelValue={[oneMBFile, twoMBFile]} disabled />\n    ))\n    expect(screen.getByCSS('input')).toBeDisabled()\n  })\n\n  it('should support no prepend icon', async () => {\n    render(() => (\n      <VFileInput modelValue={[oneMBFile, twoMBFile]} prependIcon=\"\" />\n    ))\n    expect(screen.queryAllByCSS('.v-file-input .v-input__prepend')).toHaveLength(0)\n  })\n\n  it('should support chips', () => {\n    render(() => (\n      <VFileInput modelValue={[oneMBFile, twoMBFile]} chips />\n    ))\n    expect(screen.getAllByCSS('.v-file-input .v-chip')).toHaveLength(2)\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/8167\n  it.skip('should not emit change event when input is blurred', async () => {\n    const change = vi.fn()\n    const update = vi.fn()\n    render(() => (\n      <VFileInput onChange={ change } onUpdate:modelValue={ update } />\n    ))\n\n    const input = screen.getByCSS('input')\n    input.focus()\n    await userEvent.upload(input, 'text.txt')\n    await userEvent.tab()\n\n    expect(change).toHaveBeenCalledTimes(1)\n    expect(update).toHaveBeenCalledTimes(1)\n  })\n\n  it('should put extra attributes on input', () => {\n    render(() => (\n      <VFileInput label=\"foo\" accept=\"image/*\" />\n    ))\n    expect(screen.getByCSS('input')).toHaveAttribute('accept', 'image/*')\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/16486\n  it.todo('should reset the underlying HTMLInput when model is controlled input', async () => {\n    render(defineComponent({\n      setup () {\n        const files = ref<File[]>([])\n        const onReset = () => {\n          files.value = []\n        }\n        return () => (\n          <CenteredGrid width=\"400px\">\n            <VFileInput modelValue={ files.value } />\n            <button type=\"button\" onClick={ onReset }>Reset Model Value</button>\n          </CenteredGrid>\n        )\n      },\n    }))\n\n    const input = screen.getByCSS('input') as HTMLInputElement\n    expect(input.files).toHaveLength(0)\n\n    // add file\n    await userEvent.upload(input, 'text.txt')\n    expect(input.files).toHaveLength(1)\n\n    // reset input from wrapper/parent component\n    await userEvent.click(screen.getByText(/reset/i))\n    expect(input.files).toHaveLength(0)\n\n    // add same file again\n    await userEvent.upload(input, 'text.txt')\n    expect(input.files).toHaveLength(1)\n\n    // reset input from wrapper/parent component\n    await userEvent.click(screen.getByText(/reset/i))\n    expect(input.files).toHaveLength(0)\n  })\n\n  showcase({ stories })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VFileInput/__tests__/VFileInput.spec.tsx",
    "content": "import { VFileInput } from '../VFileInput'\n\n// Utilities\nimport { mount } from '@vue/test-utils'\nimport { createVuetify } from '@/framework'\n\ndescribe('VFileInput', () => {\n  const vuetify = createVuetify()\n\n  function mountFunction (component: any, options = {}) {\n    return mount(component, {\n      global: {\n        plugins: [vuetify],\n      },\n      ...options,\n    })\n  }\n\n  it('has affixed icons', () => {\n    const wrapper = mountFunction(\n      <VFileInput\n        prependIcon=\"$vuetify\"\n        prependInnerIcon=\"$vuetify\"\n        appendInnerIcon=\"$vuetify\"\n        appendIcon=\"$vuetify\"\n      />\n    )\n\n    let el = wrapper.find('.v-input__prepend .v-icon')\n    expect(el.attributes('aria-hidden')).toBe('false')\n    expect(el.attributes('aria-label')).toBeTruthy()\n\n    el = wrapper.find('.v-field__prepend-inner .v-icon')\n    expect(el.attributes('aria-hidden')).toBe('true')\n    expect(el.attributes('aria-label')).toBeUndefined()\n\n    el = wrapper.find('.v-field__append-inner .v-icon')\n    expect(el.attributes('aria-hidden')).toBe('true')\n    expect(el.attributes('aria-label')).toBeUndefined()\n\n    el = wrapper.find('.v-input__append .v-icon')\n    expect(el.attributes('aria-hidden')).toBe('true')\n    expect(el.attributes('aria-label')).toBeUndefined()\n  })\n\n  it('has affixed icons with actions', () => {\n    const onClickPrepend = vi.fn()\n    const onClickPrependInner = vi.fn()\n    const onClickAppendInner = vi.fn()\n    const onClickAppend = vi.fn()\n\n    const wrapper = mountFunction(\n      <VFileInput\n        prependIcon=\"$vuetify\"\n        prependInnerIcon=\"$vuetify\"\n        appendInnerIcon=\"$vuetify\"\n        appendIcon=\"$vuetify\"\n        onClick:prepend={ onClickPrepend }\n        onClick:prependInner={ onClickPrependInner }\n        onClick:appendInner={ onClickAppendInner }\n        onClick:append={ onClickAppend }\n      />\n    )\n\n    expect(onClickPrepend).toHaveBeenCalledTimes(0)\n    expect(onClickPrependInner).toHaveBeenCalledTimes(0)\n    expect(onClickAppendInner).toHaveBeenCalledTimes(0)\n    expect(onClickAppend).toHaveBeenCalledTimes(0)\n\n    let el = wrapper.find('.v-input__prepend .v-icon')\n    expect(el.attributes('aria-hidden')).toBe('false')\n    expect(el.attributes('aria-label')).toBeTruthy()\n    el.trigger('click')\n    expect(onClickPrepend).toHaveBeenCalledTimes(1)\n\n    el = wrapper.find('.v-field__prepend-inner .v-icon')\n    expect(el.attributes('aria-hidden')).toBe('false')\n    expect(el.attributes('aria-label')).toBeTruthy()\n    el.trigger('click')\n    expect(onClickPrependInner).toHaveBeenCalledTimes(1)\n\n    el = wrapper.find('.v-field__append-inner .v-icon')\n    expect(el.attributes('aria-hidden')).toBe('false')\n    expect(el.attributes('aria-label')).toBeTruthy()\n    el.trigger('click')\n    expect(onClickAppendInner).toHaveBeenCalledTimes(1)\n\n    el = wrapper.find('.v-input__append .v-icon')\n    expect(el.attributes('aria-hidden')).toBe('false')\n    expect(el.attributes('aria-label')).toBeTruthy()\n    el.trigger('click')\n    expect(onClickAppend).toHaveBeenCalledTimes(1)\n\n    expect(onClickPrepend).toHaveBeenCalledTimes(1)\n    expect(onClickPrependInner).toHaveBeenCalledTimes(1)\n    expect(onClickAppendInner).toHaveBeenCalledTimes(1)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VFileInput/__tests__/text.txt",
    "content": "text\n"
  },
  {
    "path": "packages/vuetify/src/components/VFileInput/_variables.scss",
    "content": "// Defaults\n$file-input-chip-margin-inline-end: null !default;\n$file-input-chips-margin-top: null !default;\n$file-input-chips-margin-bottom: null !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VFileInput/index.ts",
    "content": "export { VFileInput } from './VFileInput'\n"
  },
  {
    "path": "packages/vuetify/src/components/VFooter/VFooter.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-footer\n    align-items: center\n    display: flex\n    flex: $footer-flex\n    padding: $footer-padding\n    position: relative\n    transition: $footer-transition\n    transition-property: height, width, transform, max-width, left, right, top, bottom\n\n    // missing from variables\n    @include tools.border($footer-border...)\n    @include tools.elevation($footer-elevation)\n    @include tools.position($footer-positions)\n    @include tools.rounded($footer-border-radius)\n    @include tools.theme($footer-theme...)\n\n    &--rounded\n      @include tools.rounded($footer-rounded-border-radius)\n"
  },
  {
    "path": "packages/vuetify/src/components/VFooter/VFooter.tsx",
    "content": "// Styles\nimport './VFooter.sass'\n\n// Composables\nimport { makeBorderProps, useBorder } from '@/composables/border'\nimport { useBackgroundColor } from '@/composables/color'\nimport { makeComponentProps } from '@/composables/component'\nimport { makeElevationProps, useElevation } from '@/composables/elevation'\nimport { makeLayoutItemProps, useLayoutItem } from '@/composables/layout'\nimport { useResizeObserver } from '@/composables/resizeObserver'\nimport { makeRoundedProps, useRounded } from '@/composables/rounded'\nimport { makeTagProps } from '@/composables/tag'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\nimport { useToggleScope } from '@/composables/toggleScope'\n\n// Utilities\nimport { computed, ref, shallowRef, toRef, watchEffect } from 'vue'\nimport { convertToUnit, genericComponent, propsFactory, useRender } from '@/util'\n\nexport const makeVFooterProps = propsFactory({\n  app: Boolean,\n  color: String,\n  height: {\n    type: [Number, String],\n    default: 'auto',\n  },\n\n  ...makeBorderProps(),\n  ...makeComponentProps(),\n  ...makeElevationProps(),\n  ...makeLayoutItemProps(),\n  ...makeRoundedProps(),\n  ...makeTagProps({ tag: 'footer' }),\n  ...makeThemeProps(),\n}, 'VFooter')\n\nexport const VFooter = genericComponent()({\n  name: 'VFooter',\n\n  props: makeVFooterProps(),\n\n  setup (props, { slots }) {\n    const layoutItemStyles = ref()\n\n    const { themeClasses } = provideTheme(props)\n    const { backgroundColorClasses, backgroundColorStyles } = useBackgroundColor(() => props.color)\n    const { borderClasses } = useBorder(props)\n    const { elevationClasses } = useElevation(props)\n    const { roundedClasses } = useRounded(props)\n\n    const autoHeight = shallowRef(32)\n    const { resizeRef } = useResizeObserver(entries => {\n      if (!entries.length) return\n      autoHeight.value = entries[0].target.clientHeight\n    })\n    const height = computed(() => props.height === 'auto' ? autoHeight.value : parseInt(props.height, 10))\n\n    useToggleScope(() => props.app, () => {\n      const layout = useLayoutItem({\n        id: props.name,\n        order: computed(() => parseInt(props.order, 10)),\n        position: toRef(() => 'bottom'),\n        layoutSize: height,\n        elementSize: computed(() => props.height === 'auto' ? undefined : height.value),\n        active: toRef(() => props.app),\n        absolute: toRef(() => props.absolute),\n      })\n\n      watchEffect(() => {\n        layoutItemStyles.value = layout.layoutItemStyles.value\n      })\n    })\n\n    useRender(() => (\n      <props.tag\n        ref={ resizeRef }\n        class={[\n          'v-footer',\n          themeClasses.value,\n          backgroundColorClasses.value,\n          borderClasses.value,\n          elevationClasses.value,\n          roundedClasses.value,\n          props.class,\n        ]}\n        style={[\n          backgroundColorStyles.value,\n          props.app ? layoutItemStyles.value : {\n            height: convertToUnit(props.height),\n          },\n          props.style,\n        ]}\n        v-slots={ slots }\n      />\n    ))\n\n    return {}\n  },\n})\n\nexport type VFooter = InstanceType<typeof VFooter>\n"
  },
  {
    "path": "packages/vuetify/src/components/VFooter/_variables.scss",
    "content": "@use 'sass:map';\n@use '../../styles/settings';\n@use '../../styles/tools';\n\n// VFooter\n$footer-background: rgb(var(--v-theme-surface)) !default;\n$footer-border-color: settings.$border-color-root !default;\n$footer-border-style: settings.$border-style-root !default;\n$footer-border-thin-width: thin !default;\n$footer-border-width: 0 !default;\n$footer-border-radius: map.get(settings.$rounded, 0) !default;\n$footer-color: tools.theme-color('on-surface', var(--v-high-emphasis-opacity)) !default;\n$footer-flex: 1 1 auto !default;\n$footer-font-size: 14px !default;\n$footer-elevation: 0 !default;\n$footer-padding: 8px 16px !default;\n$footer-positions: absolute fixed !default;\n$footer-rounded-border-radius: settings.$border-radius-root !default;\n$footer-transition: .2s settings.$standard-easing !default;\n\n// Lists\n$footer-border: (\n  $footer-border-color,\n  $footer-border-style,\n  $footer-border-width,\n  $footer-border-thin-width\n) !default;\n\n$footer-theme: (\n  $footer-background,\n  $footer-color\n) !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VFooter/index.ts",
    "content": "export { VFooter } from './VFooter'\n"
  },
  {
    "path": "packages/vuetify/src/components/VForm/VForm.tsx",
    "content": "// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { createForm, makeFormProps } from '@/composables/form'\nimport { forwardRefs } from '@/composables/forwardRefs'\n\n// Utilities\nimport { ref } from 'vue'\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { FieldValidationResult, FormField, FormValidationResult, SubmitEventPromise } from '@/composables/form'\n\nexport const makeVFormProps = propsFactory({\n  ...makeComponentProps(),\n  ...makeFormProps(),\n}, 'VForm')\n\ntype VFormSlots = {\n  default: {\n    errors: FieldValidationResult[]\n    isDisabled: boolean\n    isReadonly: boolean\n    isValidating: boolean\n    isValid: boolean | null\n    items: FormField[]\n    validate: () => Promise<FormValidationResult>\n    reset: () => void\n    resetValidation: () => void\n  }\n}\n\nexport const VForm = genericComponent<VFormSlots>()({\n  name: 'VForm',\n\n  props: makeVFormProps(),\n\n  emits: {\n    'update:modelValue': (val: boolean | null) => true,\n    submit: (e: SubmitEventPromise) => true,\n  },\n\n  setup (props, { slots, emit }) {\n    const form = createForm(props)\n    const formRef = ref<HTMLFormElement>()\n\n    function onReset (e: Event) {\n      e.preventDefault()\n      form.reset()\n    }\n\n    function onSubmit (_e: Event) {\n      const e = _e as SubmitEventPromise\n\n      const ready = form.validate()\n      e.then = ready.then.bind(ready)\n      e.catch = ready.catch.bind(ready)\n      e.finally = ready.finally.bind(ready)\n\n      emit('submit', e)\n\n      if (!e.defaultPrevented) {\n        ready.then(({ valid }) => {\n          if (valid) {\n            formRef.value?.submit()\n          }\n        })\n      }\n\n      e.preventDefault()\n    }\n\n    useRender(() => ((\n      <form\n        ref={ formRef }\n        class={[\n          'v-form',\n          props.class,\n        ]}\n        style={ props.style }\n        novalidate\n        onReset={ onReset }\n        onSubmit={ onSubmit }\n      >\n        { slots.default?.({\n          errors: form.errors.value,\n          isDisabled: form.isDisabled.value,\n          isReadonly: form.isReadonly.value,\n          isValidating: form.isValidating.value,\n          isValid: form.isValid.value,\n          items: form.items.value,\n          validate: form.validate,\n          reset: form.reset,\n          resetValidation: form.resetValidation,\n        })}\n      </form>\n    )))\n\n    return forwardRefs(form, formRef)\n  },\n})\n\nexport type VForm = InstanceType<typeof VForm>\n"
  },
  {
    "path": "packages/vuetify/src/components/VForm/__tests__/VForm.spec.cy.tsx",
    "content": "/* eslint-disable sonarjs/no-identical-functions */\n/// <reference types=\"../../../../types/cypress\" />\n\n// Components\nimport { VForm } from '../'\nimport { Application } from '../../../../cypress/templates'\nimport { VBtn } from '@/components/VBtn'\nimport { VTextField } from '@/components/VTextField'\n\n// Utilities\nimport { ref } from 'vue'\n\n// Types\nimport type { SubmitEventPromise } from '@/composables'\n\ndescribe('VForm', () => {\n  it('emits when inputs are updated', () => {\n    cy.mount(() => (\n      <Application>\n        <VForm>\n          <VTextField label=\"Name\" rules={[v => v?.length > 10 || 'Name should be longer than 10 characters']}></VTextField>\n        </VForm>\n      </Application>\n    ))\n\n    cy.emitted(VForm, 'update:modelValue')\n      .should('be.undefined')\n    cy.get('.v-text-field').type('Something!!')\n    cy.emitted(VForm, 'update:modelValue')\n      .should('deep.equal', [[false], [true]])\n    cy.get('.v-text-field').type('{backspace}{backspace}')\n    cy.emitted(VForm, 'update:modelValue')\n      .should('deep.equal', [[false], [true], [false]])\n  })\n\n  it('only emits true if all inputs are explicitly valid', () => {\n    cy.mount(() => (\n      <Application>\n        <VForm>\n          <VTextField label=\"Name\" rules={[v => v?.length < 10 || 'Name should be longer than 10 characters']}></VTextField>\n          <VTextField label=\"Email\" rules={[v => v?.length < 10 || 'E-mail should be longer than 10 characters']}></VTextField>\n        </VForm>\n      </Application>\n    ))\n\n    cy.emitted(VForm, 'update:modelValue')\n      .should('be.undefined')\n    cy.get('.v-text-field').eq(0).type('Valid')\n    cy.emitted(VForm, 'update:modelValue')\n      .should('be.undefined')\n    cy.get('.v-text-field').eq(1).type('Valid')\n    cy.emitted(VForm, 'update:modelValue')\n      .should('deep.equal', [[true]])\n  })\n\n  it('exposes validate function', () => {\n    const form = ref()\n    cy.mount(() => (\n      <Application>\n        <VForm ref={ form }>\n          <VTextField label=\"Name\" rules={[v => !!v || 'Name required']}></VTextField>\n        </VForm>\n      </Application>\n    ))\n\n    cy.get('.v-form')\n      .then(async () => {\n        const { valid } = await form.value.validate()\n        expect(valid).to.equal(false)\n      })\n      .get('.v-text-field').should('have.class', 'v-input--error')\n  })\n\n  it('exposes reset function', () => {\n    const form = ref()\n    cy.mount(() => (\n      <Application>\n        <VForm ref={ form }>\n          <VTextField label=\"Name\" rules={[v => v?.length > 10 || 'Name should be longer than 10 characters']}></VTextField>\n        </VForm>\n      </Application>\n    ))\n\n    cy.get('.v-text-field')\n      .type('Something')\n      .should('have.class', 'v-input--error')\n    cy.get('.v-form').then(() => {\n      form.value.reset()\n    })\n    cy.get('.v-text-field')\n      .should('have.not.class', 'v-input--error')\n      .find('input')\n      .should('have.value', '')\n  })\n\n  it('exposes resetValidation function', () => {\n    const form = ref()\n    cy.mount(() => (\n      <Application>\n        <VForm ref={ form }>\n          <VTextField label=\"Name\" rules={[v => v?.length > 10 || 'Name should be longer than 10 characters']}></VTextField>\n        </VForm>\n      </Application>\n    ))\n\n    cy.get('.v-text-field')\n      .type('Something')\n      .should('have.class', 'v-input--error')\n    cy.emitted(VForm, 'update:modelValue')\n      .should('deep.equal', [[false]])\n    cy.get('.v-form').then(() => {\n      form.value.resetValidation()\n    })\n    cy.get('.v-text-field')\n      .should('have.not.class', 'v-input--error')\n      .find('input')\n      .should('have.value', 'Something')\n    cy.emitted(VForm, 'update:modelValue')\n      .should('deep.equal', [[false], [null]])\n  })\n\n  it('does not submit form if validation fails', () => {\n    cy.mount(() => (\n      <VForm action=\"/action\">\n        <VTextField rules={[v => !!v || 'Field required']} />\n        <VBtn type=\"submit\">Submit</VBtn>\n      </VForm>\n    ))\n\n    cy.get('.v-btn').click().url().should('not.contain', '/action')\n      .get('.v-text-field').should('have.class', 'v-input--error').find('.v-messages').should('have.text', 'Field required')\n  })\n\n  it('emits a SubmitEventPromise', () => {\n    cy.mount(() => (\n      <Application>\n        <VForm action=\"/action\" onSubmit={ onSubmit }>\n          <VTextField modelValue=\"foo\" rules={[v => !!v || 'Field required']} />\n          <VBtn type=\"submit\">Submit</VBtn>\n        </VForm>\n      </Application>\n    ))\n\n    function onSubmit (e: SubmitEventPromise) {\n      e.preventDefault()\n    }\n\n    cy.get('.v-btn').click().url().should('not.contain', '/action')\n      .emitted(VForm, 'submit')\n      .then(async emits => {\n        const result = await emits[0][0]\n        expect(result).to.deep.equal({ valid: true, errors: [] })\n      })\n  })\n\n  it('exposes errors reactively', () => {\n    const form = ref()\n\n    cy.mount(() => (\n      <Application>\n        <VForm ref={ form }>\n          <VTextField rules={[v => v?.length < 4 || 'Error']} />\n        </VForm>\n      </Application>\n    ))\n\n    cy.get('.v-text-field')\n      .type('Invalid')\n      .then(() => {\n        expect(form.value.errors).to.deep.equal([\n          {\n            id: 'input-0',\n            errorMessages: ['Error'],\n          },\n        ])\n      })\n  })\n\n  it('provides validate-on prop to child inputs', () => {\n    const form = ref()\n\n    cy.mount(() => (\n      <Application>\n        <VForm ref={ form } validateOn=\"lazy\">\n          <VTextField name=\"empty\" rules={[v => v?.length > 5 || 'Error']} modelValue=\"\" />\n        </VForm>\n      </Application>\n    ))\n\n    cy.then(() => {\n      expect(form.value.isValid).to.be.null\n    })\n      .get('.v-text-field').should('not.have.class', 'v-input--error')\n      .get('.v-text-field input')\n      .type('Hello')\n      .then(() => {\n        expect(form.value.isValid).to.be.false\n      })\n      .get('.v-text-field').should('have.class', 'v-input--error')\n  })\n\n  it('validates inputs to true if there are no rules', () => {\n    const model = ref(false)\n    cy.mount(() => (\n      <Application>\n        <VForm v-model={ model.value }>\n          <VTextField></VTextField>\n          <VTextField rules={[]}></VTextField>\n        </VForm>\n      </Application>\n    ))\n\n    cy.then(() => {\n      expect(model.value).to.be.true\n    })\n  })\n\n  // TODO: This test has to be the last one,\n  // because subsequent tests in the same file\n  // will break due to the page change\n  it('submits form if validation passes', () => {\n    cy.mount(() => (\n      <VForm action=\"/__cypress/src/action\">\n        <VTextField modelValue=\"foo\" rules={[v => !!v || 'Field required']} />\n        <VBtn type=\"submit\">Submit</VBtn>\n      </VForm>\n    ))\n\n    cy.get('.v-btn').click().url().should('contain', '/action')\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VForm/index.ts",
    "content": "export { VForm } from './VForm'\n"
  },
  {
    "path": "packages/vuetify/src/components/VGrid/VCol.ts",
    "content": "// Styles\nimport './VGrid.sass'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { breakpoints } from '@/composables/display'\nimport { makeTagProps } from '@/composables/tag'\n\n// Utilities\nimport { capitalize, computed, h } from 'vue'\nimport { genericComponent, keys, propsFactory } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { Breakpoint } from '@/composables/display'\n\ntype BreakpointOffset = `offset${Capitalize<Breakpoint>}`\n\nconst breakpointProps = (() => {\n  return breakpoints.reduce((props, val) => {\n    props[val] = {\n      type: [Boolean, String, Number],\n      default: false,\n    }\n    return props\n  }, {} as Record<Breakpoint, {\n    type: [BooleanConstructor, StringConstructor, NumberConstructor]\n    default: false\n  }>)\n})()\n\nconst offsetProps = (() => {\n  return breakpoints.reduce((props, val) => {\n    const offsetKey = ('offset' + capitalize(val)) as BreakpointOffset\n    props[offsetKey] = {\n      type: [String, Number],\n      default: null,\n    }\n    return props\n  }, {} as Record<BreakpointOffset, {\n    type: [StringConstructor, NumberConstructor]\n    default: null\n  }>)\n})()\n\nconst propMap = {\n  col: keys(breakpointProps),\n  offset: keys(offsetProps),\n  order: ['order', 'orderSm', 'orderMd', 'orderLg', 'orderXl', 'orderXxl'],\n}\n\nfunction parseCols (val: boolean | string | number) {\n  if (typeof val === 'string' && val.includes('/')) {\n    const [cols, size] = val.split('/')\n    return { cols: Number(cols), size: Number(size) }\n  }\n  return { cols: val }\n}\n\nfunction parseBreakpoint (type: keyof typeof propMap, prop: string, val: boolean | string | number) {\n  if (val == null || val === false) {\n    return {}\n  }\n  const { cols, size } = parseCols(val)\n\n  const breakpoint = prop.replace(type, '').toLowerCase()\n\n  if (type === 'offset') {\n    return {\n      className: `v-col--offset-${breakpoint}-${cols}`,\n      variables: [{ [`--v-col-offset-base-${breakpoint}`]: size }],\n    }\n  } else if (type === 'order') {\n    return { className: `order-${breakpoint}-${cols}` }\n  }\n\n  // Handling the boolean style prop when accepting [Boolean, String, Number]\n  // means Vue will not convert <v-col sm></v-col> to sm: true for us.\n  // Since the default is false, an empty string indicates the prop's presence.\n  return {\n    className: cols === '' || cols === true\n      ? `v-col--${breakpoint}`\n      : `v-col--cols-${breakpoint}-${cols}`,\n    variables: [{ [`--v-col-size-base-${breakpoint}`]: size }],\n  }\n}\n\nconst ALIGN_SELF_VALUES = ['auto', 'start', 'end', 'center', 'baseline', 'stretch'] as const\nconst alignSelfValidator = (str: any) => ALIGN_SELF_VALUES.includes(str)\n\nexport const makeVColProps = propsFactory({\n  cols: {\n    type: [Boolean, String, Number],\n    default: false,\n  },\n  ...breakpointProps,\n  offset: {\n    type: [String, Number],\n    default: null,\n  },\n  ...offsetProps,\n\n  /** @deprecated use order-* class instead */\n  order: { type: [String, Number], default: null },\n  /** @deprecated use order-sm-* class instead */\n  orderSm: { type: String as PropType<typeof ALIGN_SELF_VALUES[number]>, default: null },\n  /** @deprecated use order-md-* class instead */\n  orderMd: { type: String as PropType<typeof ALIGN_SELF_VALUES[number]>, default: null },\n  /** @deprecated use order-lg-* class instead */\n  orderLg: { type: String as PropType<typeof ALIGN_SELF_VALUES[number]>, default: null },\n  /** @deprecated use order-xl-* class instead */\n  orderXl: { type: String as PropType<typeof ALIGN_SELF_VALUES[number]>, default: null },\n  /** @deprecated use order-xxl-* class instead */\n  orderXxl: { type: String as PropType<typeof ALIGN_SELF_VALUES[number]>, default: null },\n  /** @deprecated use align-self-* class instead */\n  alignSelf: { type: String as PropType<typeof ALIGN_SELF_VALUES[number]>, default: null, validator: alignSelfValidator },\n\n  ...makeComponentProps(),\n  ...makeTagProps(),\n}, 'VCol')\n\nexport const VCol = genericComponent()({\n  name: 'VCol',\n\n  props: makeVColProps(),\n\n  setup (props, { slots }) {\n    const sizeBaseOverride = computed(() => parseCols(props.cols).size)\n    const offsetBaseOverride = computed(() => parseCols(props.offset).size)\n\n    const responsive = computed(() => {\n      const classList: any[] = ['v-col']\n      const variablesList: any[] = []\n\n      // Loop through `col`, `offset`, `order` breakpoint props\n      let type: keyof typeof propMap\n      for (type in propMap) {\n        propMap[type].forEach(prop => {\n          const value = (props as any)[prop]\n          const { className, variables } = parseBreakpoint(type, prop, value)\n          if (className) classList.push(className)\n          if (variables) variablesList.push(...variables)\n        })\n      }\n\n      const { cols } = parseCols(props.cols)\n      const { cols: offset } = parseCols(props.offset)\n\n      classList.push({\n        [`v-col--cols-${cols}`]: cols,\n        [`v-col--offset-${offset}`]: offset,\n        [`order-${props.order}`]: props.order,\n        [`align-self-${props.alignSelf}`]: props.alignSelf,\n      })\n\n      return {\n        classes: classList,\n        variables: variablesList,\n      }\n    })\n\n    return () => h(props.tag, {\n      class: [\n        responsive.value.classes,\n        props.class,\n      ],\n      style: [\n        { '--v-col-size-base': sizeBaseOverride.value },\n        { '--v-col-offset-base': offsetBaseOverride.value },\n        responsive.value.variables,\n        props.style,\n      ],\n    }, slots.default?.())\n  },\n})\n\nexport type VCol = InstanceType<typeof VCol>\n"
  },
  {
    "path": "packages/vuetify/src/components/VGrid/VContainer.sass",
    "content": "@use '../../styles/tools'\n@use './mixins' as *\n\n@include tools.layer('components')\n  .v-container\n    @include make-container\n    @include make-container-max-widths\n\n    &--fluid\n      max-width: 100%\n"
  },
  {
    "path": "packages/vuetify/src/components/VGrid/VContainer.tsx",
    "content": "// Styles\nimport './VContainer.sass'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { makeDimensionProps, useDimension } from '@/composables/dimensions'\nimport { useRtl } from '@/composables/locale'\nimport { makeTagProps } from '@/composables/tag'\n\n// Utilities\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\nexport const makeVContainerProps = propsFactory({\n  fluid: {\n    type: Boolean,\n    default: false,\n  },\n\n  ...makeComponentProps(),\n  ...makeDimensionProps(),\n  ...makeTagProps(),\n}, 'VContainer')\n\nexport const VContainer = genericComponent()({\n  name: 'VContainer',\n\n  props: makeVContainerProps(),\n\n  setup (props, { slots }) {\n    const { rtlClasses } = useRtl()\n    const { dimensionStyles } = useDimension(props)\n\n    useRender(() => (\n      <props.tag\n        class={[\n          'v-container',\n          { 'v-container--fluid': props.fluid },\n          rtlClasses.value,\n          props.class,\n        ]}\n        style={[\n          dimensionStyles.value,\n          props.style,\n        ]}\n        v-slots={ slots }\n      />\n    ))\n\n    return {}\n  },\n})\n\nexport type VContainer = InstanceType<typeof VContainer>\n"
  },
  {
    "path": "packages/vuetify/src/components/VGrid/VGrid.sass",
    "content": "@use 'sass:map'\n@use '../../styles/settings'\n@use '../../styles/tools'\n@use './mixins' as *\n\n// https://lea.verou.me/blog/2020/10/the-var-space-hack-to-toggle-multiple-values-with-one-custom-property/\n$true: initial\n$false: ' '\n\n@include tools.layer('components')\n  // Row\n  //\n  // Rows contain and clear the floats of your columns.\n  .v-row\n    --v-row-columns: #{settings.$grid-columns}\n    display: flex\n    flex-wrap: wrap\n    flex: 1 1 auto\n    gap: var(--v-col-gap-y) var(--v-col-gap-x)\n\n    & + .v-row\n      margin-top: var(--v-col-gap-y)\n\n    @at-root\n      @include tools.density('v-row', settings.$grid-density) using ($modifier)\n        --v-col-gap-x: #{settings.$grid-gutter + $modifier * 2}\n        --v-col-gap-y: #{settings.$grid-gutter + $modifier * 2}\n\n  .v-row--no-gutters\n    --v-col-gap-x: 0px\n    --v-col-gap-y: 0px\n\n  // Columns\n  //\n  // Common styles for small and large grid columns\n  .v-col\n    $size: var(--v-col-size)\n    $cols: var(--v-col-size-columns)\n    $gap: var(--v-col-gap-x)\n    $offset: var(--v-col-offset)\n    $offsetCols: var(--v-col-offset-columns)\n    flex-grow: var(--v-col-is-size, 0) var(--v-col-is-auto, 0) var(--v-col-is-grow, 1)\n    flex-shrink: 0\n    flex-basis: var(--v-col-is-size, calc(($size * (100% + $gap)) / $cols - $gap)) var(--v-col-is-auto, auto) var(--v-col-is-grow, 0)\n    max-width: 100%\n    min-width: var(--v-col-is-size, 0) var(--v-col-is-auto, auto) var(--v-col-is-grow, auto)\n    --v-col-is-size: #{$false}\n    --v-col-is-auto: #{$false}\n    --v-col-is-grow: #{$true}\n\n    --v-col-size-base: initial\n    --v-col-size-base-sm: initial\n    --v-col-size-base-md: initial\n    --v-col-size-base-lg: initial\n    --v-col-size-base-xl: initial\n    --v-col-size-base-xxl: initial\n\n    --v-col-offset-base: initial\n    --v-col-offset-base-sm: initial\n    --v-col-offset-base-md: initial\n    --v-col-offset-base-lg: initial\n    --v-col-offset-base-xl: initial\n    --v-col-offset-base-xxl: initial\n\n    &:where([class*='v-col--offset-'])\n      margin-inline-start: calc($offset * (100% + $gap) / $offsetCols)\n\n  @include make-grid-columns using ($infix)\n    @if $infix != ''\n      .v-col-#{$infix}\n        --v-col-is-size: #{$false}\n        --v-col-is-auto: #{$false}\n        --v-col-is-grow: #{$true}\n\n    .v-col--cols#{$infix}-auto\n      --v-col-is-size: #{$false}\n      --v-col-is-auto: #{$true}\n      --v-col-is-grow: #{$false}\n\n    @for $i from 1 through settings.$grid-columns\n      .v-col--cols#{$infix}-#{$i}\n        --v-col-size: #{$i}\n        --v-col-is-size: #{$true}\n        --v-col-is-auto: #{$false}\n        --v-col-is-grow: #{$false}\n        --v-col-size-columns: var(--v-col-size-base#{$infix}, var(--v-row-columns))\n\n    @for $i from 0 through settings.$grid-columns - 1\n      @if not ($infix == \"\" and $i == 0) // skip useless .v-col-offset-0\n        .v-col--offset#{$infix}-#{$i}\n          --v-col-offset: #{$i}\n          --v-col-offset-columns: var(--v-col-offset-base#{$infix}, var(--v-row-columns))\n"
  },
  {
    "path": "packages/vuetify/src/components/VGrid/VRow.ts",
    "content": "// Styles\nimport './VGrid.sass'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { makeDensityProps } from '@/composables/density'\nimport { makeTagProps } from '@/composables/tag'\n\n// Utilities\nimport { computed, h } from 'vue'\nimport { convertToUnit, deprecate, genericComponent, propsFactory } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\nconst ALIGNMENT = ['start', 'end', 'center'] as const\n\nconst SPACE = ['space-between', 'space-around', 'space-evenly'] as const\n\nconst ALIGN_VALUES = [...ALIGNMENT, 'baseline', 'stretch'] as const\nconst alignValidator = (str: any) => ALIGN_VALUES.includes(str)\n\nconst JUSTIFY_VALUES = [...ALIGNMENT, ...SPACE] as const\nconst justifyValidator = (str: any) => JUSTIFY_VALUES.includes(str)\n\nconst ALIGN_CONTENT_VALUES = [...ALIGNMENT, ...SPACE, 'stretch'] as const\nconst alignContentValidator = (str: any) => ALIGN_CONTENT_VALUES.includes(str)\n\nconst propMap = {\n  align: ['align', 'alignSm', 'alignMd', 'alignLg', 'alignXl', 'alignXxl'],\n  justify: ['justify', 'justifySm', 'justifyMd', 'justifyLg', 'justifyXl', 'justifyXxl'],\n  alignContent: ['alignContent', 'alignContentSm', 'alignContentMd', 'alignContentLg', 'alignContentXl', 'alignContentXxl'],\n}\n\nconst classMap = {\n  align: 'align',\n  justify: 'justify',\n  alignContent: 'align-content',\n}\n\nfunction breakpointClass (type: keyof typeof classMap, prop: string, val: string) {\n  let className = classMap[type]\n  if (val == null) {\n    return undefined\n  }\n  if (prop) {\n    // alignSm -> Sm\n    const breakpoint = prop.replace(type, '')\n    className += `-${breakpoint}`\n  }\n  // .align-items-sm-center\n  className += `-${val}`\n  return className.toLowerCase()\n}\n\nexport const makeVRowProps = propsFactory({\n  /** @deprecated use density=\"compact\" instead */\n  dense: Boolean,\n  /** @deprecated use align-* class instead */\n  align: { type: String as PropType<typeof ALIGN_VALUES[number]>, default: null, validator: alignValidator },\n  /** @deprecated use align-sm-* class instead */\n  alignSm: { type: String as PropType<typeof ALIGN_VALUES[number]>, default: null, validator: alignValidator },\n  /** @deprecated use align-md-* class instead */\n  alignMd: { type: String as PropType<typeof ALIGN_VALUES[number]>, default: null, validator: alignValidator },\n  /** @deprecated use align-lg-* class instead */\n  alignLg: { type: String as PropType<typeof ALIGN_VALUES[number]>, default: null, validator: alignValidator },\n  /** @deprecated use align-xl-* class instead */\n  alignXl: { type: String as PropType<typeof ALIGN_VALUES[number]>, default: null, validator: alignValidator },\n  /** @deprecated use align-xxl-* class instead */\n  alignXxl: { type: String as PropType<typeof ALIGN_VALUES[number]>, default: null, validator: alignValidator },\n  /** @deprecated use justify-* class instead */\n  justify: { type: String as PropType<typeof JUSTIFY_VALUES[number]>, default: null, validator: justifyValidator },\n  /** @deprecated use justify-sm-* class instead */\n  justifySm: { type: String as PropType<typeof JUSTIFY_VALUES[number]>, default: null, validator: justifyValidator },\n  /** @deprecated use justify-md-* class instead */\n  justifyMd: { type: String as PropType<typeof JUSTIFY_VALUES[number]>, default: null, validator: justifyValidator },\n  /** @deprecated use justify-lg-* class instead */\n  justifyLg: { type: String as PropType<typeof JUSTIFY_VALUES[number]>, default: null, validator: justifyValidator },\n  /** @deprecated use justify-xl-* class instead */\n  justifyXl: { type: String as PropType<typeof JUSTIFY_VALUES[number]>, default: null, validator: justifyValidator },\n  /** @deprecated use justify-xxl-* class instead */\n  justifyXxl: { type: String as PropType<typeof JUSTIFY_VALUES[number]>, default: null, validator: justifyValidator },\n  /** @deprecated use align-content-* class instead */\n  alignContent: { type: String as PropType<typeof ALIGN_CONTENT_VALUES[number]>, default: null, validator: alignContentValidator },\n  /** @deprecated use align-content-sm-* class instead */\n  alignContentSm: { type: String as PropType<typeof ALIGN_CONTENT_VALUES[number]>, default: null, validator: alignContentValidator },\n  /** @deprecated use align-content-md-* class instead */\n  alignContentMd: { type: String as PropType<typeof ALIGN_CONTENT_VALUES[number]>, default: null, validator: alignContentValidator },\n  /** @deprecated use align-content-lg-* class instead */\n  alignContentLg: { type: String as PropType<typeof ALIGN_CONTENT_VALUES[number]>, default: null, validator: alignContentValidator },\n  /** @deprecated use align-content-xl-* class instead */\n  alignContentXl: { type: String as PropType<typeof ALIGN_CONTENT_VALUES[number]>, default: null, validator: alignContentValidator },\n  /** @deprecated use align-content-xxl-* class instead */\n  alignContentXxl: { type: String as PropType<typeof ALIGN_CONTENT_VALUES[number]>, default: null, validator: alignContentValidator },\n\n  noGutters: Boolean,\n  gap: [Number, String, Array] as PropType<number | string | (string | number)[]>,\n  size: [Number, String],\n  ...makeComponentProps(),\n  ...makeDensityProps(),\n  ...makeTagProps(),\n}, 'VRow')\n\nexport const VRow = genericComponent()({\n  name: 'VRow',\n\n  props: makeVRowProps(),\n\n  setup (props, { slots }) {\n    if (props.dense) {\n      deprecate('dense', 'density=\"comfortable\"')\n    }\n\n    const classes = computed(() => {\n      const classList: any[] = []\n\n      // Loop through `align`, `justify`, `alignContent` breakpoint props\n      let type: keyof typeof propMap\n      for (type in propMap) {\n        propMap[type].forEach(prop => {\n          const value: string = (props as any)[prop]\n          const className = breakpointClass(type, prop, value)\n          if (className) classList!.push(className)\n        })\n      }\n\n      classList.push({\n        'v-row--no-gutters': props.noGutters,\n        'v-row--density-default': props.density === 'default' && !props.noGutters && !props.dense,\n        'v-row--density-compact': props.density === 'compact',\n        'v-row--density-comfortable': props.density === 'comfortable' || props.dense,\n        [`align-${props.align}`]: props.align,\n        [`justify-${props.justify}`]: props.justify,\n        [`align-content-${props.alignContent}`]: props.alignContent,\n      })\n\n      return classList\n    })\n\n    const horizontalGap = computed(() => {\n      return (Array.isArray(props.gap))\n        ? convertToUnit(props.gap[0] || 0)\n        : convertToUnit(props.gap)\n    })\n\n    const verticalGap = computed(() => {\n      return (Array.isArray(props.gap))\n        ? convertToUnit(props.gap[1] || 0)\n        : horizontalGap.value\n    })\n\n    return () => h(props.tag, {\n      class: [\n        'v-row',\n        classes.value,\n        props.class,\n      ],\n      style: [\n        {\n          '--v-col-gap-x': horizontalGap.value,\n          '--v-col-gap-y': verticalGap.value,\n          '--v-row-columns': props.size,\n        },\n        props.style,\n      ],\n    }, slots.default?.())\n  },\n})\n\nexport type VRow = InstanceType<typeof VRow>\n"
  },
  {
    "path": "packages/vuetify/src/components/VGrid/VSpacer.sass",
    "content": "@use '../../styles/tools'\n\n@include tools.layer('components')\n  .v-spacer\n    flex-grow: 1\n"
  },
  {
    "path": "packages/vuetify/src/components/VGrid/VSpacer.ts",
    "content": "// Styles\nimport './VSpacer.sass'\n\n// Utilities\nimport { createSimpleFunctional } from '@/util'\n\nexport const VSpacer = createSimpleFunctional('v-spacer', 'div', 'VSpacer')\n\nexport type VSpacer = InstanceType<typeof VSpacer>\n"
  },
  {
    "path": "packages/vuetify/src/components/VGrid/__tests__/VCol.spec.browser.tsx",
    "content": "import { VRow } from '../VRow'\nimport { VCol } from '../VCol'\n\n// Utilities\nimport { page, render, screen } from '@test'\n\nconst defaultGap = 24\n\nfunction expectedSize (cols: number, rowSize: number) {\n  return cols * (rowSize - 11 * defaultGap) / 12 + (cols - 1) * defaultGap\n}\n\nfunction expectedShift (offset: number, rowSize: number) {\n  return offset * (rowSize - 11 * defaultGap) / 12 + offset * defaultGap\n}\n\ndescribe('VCol', () => {\n  describe('sizing', () => {\n    it('renders two columns side by side', () => {\n      render(() => (\n        <VRow>\n          <VCol data-testid=\"col-1\">Column 1</VCol>\n          <VCol data-testid=\"col-2\">Column 2</VCol>\n        </VRow>\n      ))\n\n      const rect1 = screen.getByTestId('col-1').getBoundingClientRect()\n      const rect2 = screen.getByTestId('col-2').getBoundingClientRect()\n\n      // same top position\n      expect(rect1.top).toBe(rect2.top)\n      // 2nd column should be to the right of the first\n      expect(rect2.left).toBeGreaterThan(rect1.left)\n    })\n\n    it('breakpoint size should override auto', async () => {\n      // xs viewport (below sm breakpoint of 600px)\n      await page.viewport(500, 800)\n\n      render(() => (\n        <VRow>\n          <VCol cols=\"auto\" sm=\"4\" data-testid=\"col-1\">Column 1</VCol>\n          <VCol cols=\"auto\" sm=\"8\" data-testid=\"col-2\">Column 2</VCol>\n        </VRow>\n      ))\n\n      const col1 = screen.getByTestId('col-1')\n      const col2 = screen.getByTestId('col-2')\n\n      let rect1 = col1.getBoundingClientRect()\n      let rect2 = col2.getBoundingClientRect()\n\n      // at xs, Auto columns should have similar widths based on content\n      expect(rect1.width).toBeCloseTo(rect2.width, 0)\n      expect(rect1.top).toBe(rect2.top)\n      expect(rect2.left).toBeGreaterThan(rect1.left)\n\n      await page.viewport(1000, 800)\n\n      rect1 = col1.getBoundingClientRect()\n      rect2 = col2.getBoundingClientRect()\n\n      // At sm, breakpoint sizes should apply (4/12 vs 8/12)\n      expect(rect1.width).toBeCloseTo(expectedSize(4, 1000), 1)\n      expect(rect2.width).toBeCloseTo(expectedSize(8, 1000), 1)\n      // Columns should be still side by side, not stacked\n      expect(rect1.top).toBe(rect2.top)\n      expect(rect2.left).toBeGreaterThan(rect1.left)\n    })\n\n    it('breakpoint auto should override size', async () => {\n      // xs viewport (below sm breakpoint of 600px)\n      await page.viewport(500, 800)\n\n      render(() => (\n        <VRow>\n          <VCol cols=\"4\" sm=\"auto\" data-testid=\"col-1\">Column 1</VCol>\n          <VCol cols=\"8\" sm=\"auto\" data-testid=\"col-2\">Column 2</VCol>\n        </VRow>\n      ))\n\n      const col1 = screen.getByTestId('col-1')\n      const col2 = screen.getByTestId('col-2')\n\n      let rect1 = col1.getBoundingClientRect()\n      let rect2 = col2.getBoundingClientRect()\n\n      // At xs, cols sizes should apply (4/12 vs 8/12)\n      expect(rect1.width).toBeCloseTo(expectedSize(4, 500), 1)\n      expect(rect2.width).toBeCloseTo(expectedSize(8, 500), 1)\n      expect(rect1.top).toBe(rect2.top)\n      expect(rect2.left).toBeGreaterThan(rect1.left)\n\n      await page.viewport(1000, 800)\n\n      rect1 = col1.getBoundingClientRect()\n      rect2 = col2.getBoundingClientRect()\n\n      // At sm, auto should apply - columns size to content (similar widths)\n      expect(rect1.width).toBeCloseTo(rect2.width, 0)\n      // Columns should be still side by side, not stacked\n      expect(rect1.top).toBe(rect2.top)\n      expect(rect2.left).toBeGreaterThan(rect1.left)\n    })\n  })\n\n  describe('offset', () => {\n    it('basic offset without wrapping', () => {\n      const rowSize = 1000\n\n      render(() => (\n        <VRow style={ `width: ${rowSize}px` }>\n          <VCol cols=\"1\" offset=\"3\" data-testid=\"col-1\">Column 1</VCol>\n          <VCol cols=\"1\" offset=\"2\" data-testid=\"col-2\">Column 2</VCol>\n          <VCol cols=\"1\" offset=\"1\" data-testid=\"col-3\">Column 3</VCol>\n        </VRow>\n      ))\n\n      const rowRect = screen.getByCSS('.v-row').getBoundingClientRect()\n      const rect1 = screen.getByTestId('col-1').getBoundingClientRect()\n      const rect2 = screen.getByTestId('col-2').getBoundingClientRect()\n      const rect3 = screen.getByTestId('col-3').getBoundingClientRect()\n\n      // All columns should be on the same row (total: 4 + 3 + 2 = 9 columns)\n      expect(rect1.top).toBe(rect2.top)\n      expect(rect2.top).toBe(rect3.top)\n\n      // Each column should be shifted by its offset\n      expect(rect1.left - rowRect.left).toBeCloseTo(expectedShift(3, rowSize), 1)\n      expect(rect2.left - rect1.right).toBeCloseTo(expectedShift(2, rowSize) + defaultGap, 1)\n      expect(rect3.left - rect2.right).toBeCloseTo(expectedShift(1, rowSize) + defaultGap, 1)\n\n      // All columns should have size 1\n      expect(rect1.width).toBeCloseTo(expectedSize(1, rowSize), 1)\n      expect(rect2.width).toBeCloseTo(expectedSize(1, rowSize), 1)\n      expect(rect3.width).toBeCloseTo(expectedSize(1, rowSize), 1)\n    })\n\n    it('basic offset with wrapping', () => {\n      const rowSize = 1000\n\n      render(() => (\n        <VRow style={ `width: ${rowSize}px` }>\n          <VCol cols=\"4\" offset=\"2\" data-testid=\"col-1\">Column 1</VCol>\n          <VCol cols=\"4\" offset=\"5\" data-testid=\"col-2\">Column 2</VCol>\n        </VRow>\n      ))\n\n      const rowRect = screen.getByCSS('.v-row').getBoundingClientRect()\n      const rect1 = screen.getByTestId('col-1').getBoundingClientRect()\n      const rect2 = screen.getByTestId('col-2').getBoundingClientRect()\n\n      // First column: offset=2 shifts it from the row's left edge\n      expect(rect1.left - rowRect.left).toBeCloseTo(expectedShift(2, rowSize), 1)\n      expect(rect1.width).toBeCloseTo(expectedSize(4, rowSize), 1)\n\n      expect(rect2.top).toBeGreaterThan(rect1.top)\n      // Second column: offset=5 shifts it from the row's left edge on its row\n      expect(rect2.left - rowRect.left).toBeCloseTo(expectedShift(5, rowSize), 1)\n      expect(rect2.width).toBeCloseTo(expectedSize(4, rowSize), 1)\n    })\n  })\n\n  describe('grow', () => {\n    it('sized column next to grow column', async () => {\n      await page.viewport(500, 800)\n\n      render(() => (\n        <VRow>\n          <VCol cols=\"4\" sm=\"\" data-testid=\"col-1\">Column 1</VCol>\n          <VCol data-testid=\"col-2\">Column 2</VCol>\n        </VRow>\n      ))\n\n      const col1 = screen.getByTestId('col-1')\n      const col2 = screen.getByTestId('col-2')\n\n      let rect1 = col1.getBoundingClientRect()\n      let rect2 = col2.getBoundingClientRect()\n\n      // At xs, expecting 4:8 split\n      expect(rect1.width).toBeCloseTo(expectedSize(4, 500), 1)\n      expect(rect2.width).toBeCloseTo(expectedSize(8, 500), 1)\n      expect(rect1.top).toBe(rect2.top)\n\n      await page.viewport(1000, 800)\n\n      rect1 = col1.getBoundingClientRect()\n      rect2 = col2.getBoundingClientRect()\n\n      // At sm, expecting 6:6 split (both grow equally)\n      expect(rect1.width).toBeCloseTo(expectedSize(6, 1000), 1)\n      expect(rect2.width).toBeCloseTo(expectedSize(6, 1000), 1)\n      expect(rect1.top).toBe(rect2.top)\n    })\n\n    it('grow column with breakpoint size next to two grow columns', async () => {\n      await page.viewport(500, 800)\n\n      render(() => (\n        <VRow>\n          <VCol sm=\"3\" data-testid=\"col-1\">Column 1</VCol>\n          <VCol data-testid=\"col-2\">Column 2</VCol>\n          <VCol data-testid=\"col-3\">Column 3</VCol>\n        </VRow>\n      ))\n\n      const col1 = screen.getByTestId('col-1')\n      const col2 = screen.getByTestId('col-2')\n      const col3 = screen.getByTestId('col-3')\n\n      let rect1 = col1.getBoundingClientRect()\n      let rect2 = col2.getBoundingClientRect()\n      let rect3 = col3.getBoundingClientRect()\n\n      // At xs, expecting 3 equal pieces (all grow)\n      expect(rect1.width).toBeCloseTo(expectedSize(4, 500), 1)\n      expect(rect2.width).toBeCloseTo(expectedSize(4, 500), 1)\n      expect(rect3.width).toBeCloseTo(expectedSize(4, 500), 1)\n      expect(rect1.top).toBe(rect2.top)\n      expect(rect2.top).toBe(rect3.top)\n\n      await page.viewport(1000, 800)\n\n      rect1 = col1.getBoundingClientRect()\n      rect2 = col2.getBoundingClientRect()\n      rect3 = col3.getBoundingClientRect()\n\n      // At sm, expecting 1 specific size (3 cols) + 2 adapted sizes\n      expect(rect1.width).toBeCloseTo(expectedSize(3, 1000), 1)\n      const adaptedSize = (expectedSize(9, 1000) - defaultGap) / 2\n      expect(rect2.width).toBeCloseTo(adaptedSize, 1)\n      expect(rect3.width).toBeCloseTo(adaptedSize, 1)\n      expect(rect1.top).toBe(rect2.top)\n      expect(rect2.top).toBe(rect3.top)\n    })\n\n    it('auto column next to grow column with breakpoint offset', async () => {\n      await page.viewport(500, 800)\n\n      render(() => (\n        <VRow>\n          <VCol cols=\"auto\" sm=\"4\" data-testid=\"col-1\" style=\"min-width: 100px\">Column 1</VCol>\n          <VCol offsetSm=\"4\" data-testid=\"col-2\">Column 2</VCol>\n        </VRow>\n      ))\n\n      const col1 = screen.getByTestId('col-1')\n      const col2 = screen.getByTestId('col-2')\n\n      let rect1 = col1.getBoundingClientRect()\n      let rect2 = col2.getBoundingClientRect()\n\n      // At xs, expecting 100px and (rest - gap) split\n      expect(rect1.width).toBeCloseTo(100, 1)\n      expect(rect2.width).toBeCloseTo(500 - 100 - defaultGap, 1)\n      expect(rect1.top).toBe(rect2.top)\n\n      await page.viewport(1000, 800)\n\n      rect1 = col1.getBoundingClientRect()\n      rect2 = col2.getBoundingClientRect()\n\n      // At sm, expecting 4:4 split (offset-sm:4 takes 4 cols)\n      expect(rect1.width).toBeCloseTo(expectedSize(4, 1000), 1)\n      expect(rect2.width).toBeCloseTo(expectedSize(4, 1000), 1)\n      expect(rect1.top).toBe(rect2.top)\n    })\n\n    it('grow column with offset next to grow column', () => {\n      const rowSize = 1000\n\n      render(() => (\n        <VRow style={ `width: ${rowSize}px` }>\n          <VCol offset=\"2\" data-testid=\"col-1\">Column 1</VCol>\n          <VCol data-testid=\"col-2\">Column 2</VCol>\n        </VRow>\n      ))\n\n      const rowRect = screen.getByCSS('.v-row').getBoundingClientRect()\n      const rect1 = screen.getByTestId('col-1').getBoundingClientRect()\n      const rect2 = screen.getByTestId('col-2').getBoundingClientRect()\n\n      // Expecting 5:5 split with offset:2 gap on the left\n      expect(rect1.left - rowRect.left).toBeCloseTo(expectedShift(2, rowSize), 1)\n      expect(rect1.width).toBeCloseTo(expectedSize(5, rowSize), 1)\n      expect(rect2.width).toBeCloseTo(expectedSize(5, rowSize), 1)\n      expect(rect1.top).toBe(rect2.top)\n    })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VGrid/__tests__/VCol.spec.ts",
    "content": "// Utilities\nimport { mount } from '@vue/test-utils'\nimport { VCol } from '../VCol'\nimport { createVuetify } from '@/framework'\n\ndescribe('VCol', () => {\n  const vuetify = createVuetify()\n\n  function mountFunction (template: string) {\n    return mount({\n      components: { VCol },\n      template,\n    }, {\n      global: { plugins: [vuetify] },\n    })\n  }\n\n  it('should have default expected structure', async () => {\n    const wrapper = mountFunction(`<VCol />`)\n\n    expect(wrapper.html()).toBe('<div class=\"v-col\"></div>')\n  })\n\n  it('renders custom root element when tag prop set', async () => {\n    const wrapper = mountFunction(`<VCol tag=\"span\" />`)\n\n    expect(wrapper.html()).toBe('<span class=\"v-col\"></span>')\n  })\n\n  it('should apply breakpoint specific col-{bp}-{#} classes', async () => {\n    const wrapper = mountFunction(`<VCol cols=\"6\" sm=\"5\" md=\"4\" lg=\"3\" xl=\"2\" />`)\n\n    // eslint-disable-next-line max-len\n    expect(wrapper.html()).toBe('<div class=\"v-col v-col--cols-sm-5 v-col--cols-md-4 v-col--cols-lg-3 v-col--cols-xl-2 v-col--cols-6\"></div>')\n  })\n\n  it('should apply \".v-col-offset-*\" classes with \"offset-{bp}-{#}\" props', async () => {\n    const wrapper = mountFunction(`<VCol offset=\"6\" offset-sm=\"5\" offset-md=\"4\" offset-lg=\"3\" offset-xl=\"2\" />`)\n    expect(wrapper.html()).toBe(\n      '<div class=\"v-col v-col--offset-sm-5 v-col--offset-md-4 v-col--offset-lg-3 v-col--offset-xl-2 v-col--offset-6\"></div>'\n    )\n  })\n\n  it(`should apply boolean breakpoint classes for 'sm', 'md', 'lg', 'xl' prop`, async () => {\n    const wrapper = mountFunction(`<VCol sm md lg xl />`)\n\n    expect(wrapper.html()).toBe('<div class=\"v-col v-col--sm v-col--md v-col--lg v-col--xl\"></div>')\n  })\n\n  it(`should apply boolean breakpoint classes for 'sm', 'md', 'lg', 'xl' prop set to empty string`, async () => {\n    const wrapper = mountFunction(`<VCol sm=\"\" md=\"\" lg=\"\" xl=\"\" />`)\n\n    expect(wrapper.html()).toBe('<div class=\"v-col v-col--sm v-col--md v-col--lg v-col--xl\"></div>')\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VGrid/_mixins.sass",
    "content": "@use 'sass:map'\n@use '../../styles/settings'\n@use '../../styles/tools'\n\n@mixin make-container($padding-x: settings.$container-padding-x)\n  width: 100%\n  padding: $padding-x\n  margin-right: auto\n  margin-left: auto\n\n// For each breakpoint, define the maximum width of the container in a media query\n@mixin make-container-max-widths\n  $max-widths: settings.$container-max-widths\n  $breakpoints: settings.$grid-breakpoints\n  @each $breakpoint, $container-max-width in $max-widths\n    @include tools.media-breakpoint-up($breakpoint, $breakpoints)\n      max-width: $container-max-width\n\n@mixin make-grid-columns\n  $breakpoints: settings.$grid-breakpoints\n  @each $breakpoint in map.keys($breakpoints)\n    $infix: tools.breakpoint-infix($breakpoint, $breakpoints)\n\n    @include tools.media-breakpoint-up($breakpoint, $breakpoints)\n      @content($infix)\n"
  },
  {
    "path": "packages/vuetify/src/components/VGrid/index.ts",
    "content": "export { VContainer } from './VContainer'\nexport { VCol } from './VCol'\nexport { VRow } from './VRow'\nexport { VSpacer } from './VSpacer'\n"
  },
  {
    "path": "packages/vuetify/src/components/VHotkey/VHotkey.scss",
    "content": "@use '../../styles/tools';\n@use './variables' as *;\n\n@include tools.layer('components') {\n  .v-hotkey {\n    align-items: center;\n    display: inline-flex;\n    gap: $hotkey-gap;\n    vertical-align: middle;\n    line-height: $hotkey-line-height;\n\n    &--disabled {\n      opacity: $hotkey-disabled-opacity;\n    }\n\n    &--inline {\n      max-height: 1lh;\n      vertical-align: baseline;\n      font-size: $hotkey-inline-font-size;\n      line-height: inherit;\n    }\n\n    &__prefix {\n      opacity: $hotkey-prefix-suffix-opacity;\n      font-weight: $hotkey-prefix-suffix-font-weight;\n      vertical-align: baseline;\n    }\n\n    &__suffix {\n      opacity: $hotkey-prefix-suffix-opacity;\n      font-weight: $hotkey-prefix-suffix-font-weight;\n      vertical-align: baseline;\n    }\n\n    // Contained variant\n    &--contained {\n      .v-hotkey__contained-wrapper {\n        display: inline-flex;\n        align-items: center;\n        gap: $hotkey-combination-gap;\n        padding: $hotkey-contained-padding;\n        box-sizing: border-box;\n        background: unset;\n        box-shadow: unset;\n        min-height: 1em;\n        font-size: $hotkey-font-size;\n        line-height: $hotkey-line-height;\n        .v-hotkey__prefix, .v-hotkey__suffix {\n          opacity: $hotkey-prefix-suffix-contained-opacity;\n        }\n        .v-hotkey__prefix {\n          margin-right: $hotkey-contained-prefix-margin-right;\n        }\n        .v-hotkey__suffix {\n          margin-left: $hotkey-contained-suffix-margin-left;\n        }\n      }\n\n      .v-hotkey__divider {\n        opacity: $hotkey-divider-opacity;\n        font-size: inherit;\n      }\n\n      .v-hotkey__combination {\n        display: inline-flex;\n        align-items: center;\n        gap: $hotkey-combination-gap;\n      }\n\n      &.v-hotkey--inline .v-hotkey__contained-wrapper.v-kbd {\n        align-self: baseline;\n        align-items: baseline;\n        font-size: $hotkey-inline-font-size;\n        line-height: inherit;\n        padding: $hotkey-inline-padding;\n        gap: $hotkey-combination-gap;\n        margin-left: 0;\n        margin-right: 0;\n      }\n\n      &.v-hotkey--inline .v-hotkey__divider {\n        font-size: $hotkey-inline-divider-font-size;\n        align-self: baseline;\n      }\n\n      &.v-hotkey--inline .v-hotkey__combination {\n        gap: $hotkey-combination-gap;\n        align-items: baseline;\n      }\n    }\n\n    &__key {\n      &.v-kbd {\n        min-height: unset;\n        font-size: $hotkey-font-size;\n        line-height: $hotkey-line-height;\n        padding: $hotkey-padding;\n        min-width: $hotkey-min-width;\n        @include tools.variant($hotkey-variants...);\n      }\n\n      &-symbol.v-kbd {\n        line-height: normal;\n        font-size: 1em;\n      }\n\n      &-icon .v-icon {\n        min-width: unset;\n\n        &:has(svg) {\n          max-width: $hotkey-icon-size;\n        }\n        &:not(:has(svg)) {\n          font-size: $hotkey-icon-size;\n          line-height: inherit;\n          height: inherit;\n        }\n      }\n\n      &--nested {\n        background: none;\n        border: none;\n        padding: 0;\n        margin: 0;\n        font: inherit;\n        color: inherit;\n        display: inline-flex;\n        align-items: center;\n        min-width: auto;\n        min-height: auto;\n        align-self: baseline;\n\n        &.v-hotkey__key-icon {\n          align-self: center;\n        }\n      }\n    }\n\n    &__divider {\n      align-items: center;\n      display: inline-flex;\n      opacity: $hotkey-divider-opacity;\n      font-size: $hotkey-divider-font-size;\n    }\n\n    &__combination {\n      display: flex;\n      gap: $hotkey-combination-gap;\n    }\n\n    &--inline &__key {\n      align-self: center;\n      padding: $hotkey-inline-padding;\n      min-width: $hotkey-inline-min-width;\n      height: calc(1lh - 2px);\n      line-height: calc(1lh - 2px);\n\n      &-icon {\n        &.v-kbd {\n          padding-block: 0;\n        }\n\n        .v-icon {\n          width: min-content;\n          min-width: fit-content;\n          max-height: $hotkey-inline-icon-max-height;\n\n          .v-icon__svg {\n            height: 100%;\n            width: unset;\n          }\n        }\n      }\n    }\n\n    &--inline &__combination {\n      align-items: baseline;\n      gap: 1px;\n    }\n\n    &--inline &__divider {\n      font-size: $hotkey-inline-divider-font-size;\n    }\n\n    &--inline &__prefix,\n    &--inline &__suffix {\n      align-self: baseline;\n      font-size: inherit;\n    }\n\n    &--variant-elevated &__key.v-kbd {\n      @include tools.elevation($hotkey-elevation);\n    }\n\n    &--variant-flat &__key.v-kbd {\n      box-shadow: none;\n    }\n\n    &--variant-outlined &__key.v-kbd {\n      background: none;\n\n      @include tools.elevation(0);\n    }\n\n    &--variant-text {\n      @include tools.layer('overrides') {\n        .v-hotkey__key.v-kbd {\n          background: transparent;\n          border: none;\n          padding-inline: 0;\n          min-width: auto;\n\n          @include tools.elevation(0);\n        }\n      }\n\n      .v-hotkey__combination {\n        gap: 1px;\n      }\n    }\n\n    &--variant-tonal &__key.v-kbd {\n      border: unset;\n      box-shadow: unset;\n    }\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VHotkey/VHotkey.tsx",
    "content": "/**\n * VHotkey Component\n *\n * Purpose: Renders keyboard shortcuts in a visually consistent and accessible way.\n * This component handles the complex logic of displaying keyboard combinations\n * across different platforms (Mac vs PC) and display modes (icons, symbols, text).\n *\n * Why it exists:\n * - Provides consistent visual representation of keyboard shortcuts\n * - Handles platform-specific key differences (Cmd vs Ctrl, Option vs Alt)\n * - Supports multiple display modes for different design needs\n * - Encapsulates complex key parsing and rendering logic\n * - Used throughout the command palette for instruction display\n *\n * Key Mapping Structure:\n * The keyMap uses a simple object structure where each key has:\n * - `default`: Required configuration for all platforms\n * - `mac`: Optional Mac-specific overrides\n * Each config can specify `symbol`, `icon`, and `text` representations.\n *\n * Example:\n * ```\n * ctrl: {\n *   mac: { symbol: '⌃', icon: '$ctrl', text: 'Control' },\n *   default: { text: 'Ctrl', icon: '$ctrl' }\n * }\n * ```\n */\n\n// Styles\nimport './VHotkey.scss'\n\n// Components\nimport { VIcon } from '@/components/VIcon'\nimport { VKbd } from '@/components/VKbd'\n\n// Composables\nimport { makeBorderProps, useBorder } from '@/composables/border'\nimport { makeComponentProps } from '@/composables/component'\nimport { makeElevationProps, useElevation } from '@/composables/elevation'\nimport { parseKeyCombination } from '@/composables/hotkey/hotkey-parsing'\nimport { useLocale, useRtl } from '@/composables/locale'\nimport { makeRoundedProps, useRounded } from '@/composables/rounded'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\nimport { useVariant } from '@/composables/variant'\n\n// Utilities\nimport { computed } from 'vue'\nimport { genericComponent, mergeDeep, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { KeyCombination } from '@/composables/hotkey/hotkey-parsing'\nimport type { IconValue } from '@/composables/icons'\n\n// Display mode types for different visual representations\ntype DisplayMode = 'icon' | 'symbol' | 'text'\n\n// Extended variant type that includes our custom 'contained' variant\ntype HotkeyVariant = 'elevated' | 'flat' | 'tonal' | 'outlined' | 'text' | 'plain' | 'contained'\n\n// Key display tuple: [mode, content] where content is string or IconValue\ntype KeyDisplay = [Exclude<DisplayMode, 'icon'>, string] | [Extract<DisplayMode, 'icon'>, IconValue]\n\n// Key tuple: [mode, content, keycode] where content is string or IconValue\ntype Key = [Exclude<DisplayMode, 'icon'>, string, string] | [Extract<DisplayMode, 'icon'>, IconValue, string]\n\ntype KeyConfig = {\n  symbol?: string\n  icon?: string\n  text: string\n}\n\ntype PlatformKeyConfig = {\n  mac?: KeyConfig\n  default: KeyConfig\n}\n\ntype KeyMapConfig = Record<string, PlatformKeyConfig>\n\nfunction processKey (config: PlatformKeyConfig, requestedMode: DisplayMode, isMac: boolean): KeyDisplay {\n  const keyCfg = (isMac && config.mac) ? config.mac : config.default\n\n  // 1. Resolve the safest display mode for the current platform\n  const mode: DisplayMode = (() => {\n    // If the requested mode lacks an asset, fall back to text\n    if (requestedMode === 'icon' && !keyCfg.icon) return 'text'\n    if (requestedMode === 'symbol' && !keyCfg.symbol) return 'text'\n\n    return requestedMode\n  })()\n\n  // 2. Pick value for the chosen mode, defaulting to text representation\n  let value: string | IconValue = keyCfg[mode] ?? keyCfg.text\n\n  // 3. Guard against icon tokens leaking into text mode (e.g. \"$ctrl\")\n  if (mode === 'text' && typeof value === 'string' && value.startsWith('$') && !value.startsWith('$vuetify.')) {\n    value = value.slice(1).toUpperCase() // \"$ctrl\" → \"CTRL\"\n  }\n\n  return mode === 'icon'\n    ? ['icon', value as IconValue]\n    : [mode as Exclude<DisplayMode, 'icon'>, value as string]\n}\n\nexport const hotkeyMap: KeyMapConfig = {\n  ctrl: {\n    mac: { symbol: '⌃', icon: '$ctrl', text: '$vuetify.hotkey.ctrl' },\n    default: { text: 'Ctrl' },\n  },\n  meta: {\n    mac: { symbol: '⌘', icon: '$command', text: '$vuetify.hotkey.command' },\n    default: { text: 'Ctrl' },\n  },\n  cmd: {\n    mac: { symbol: '⌘', icon: '$command', text: '$vuetify.hotkey.command' },\n    default: { text: 'Ctrl' },\n  },\n  shift: {\n    mac: { symbol: '⇧', icon: '$shift', text: '$vuetify.hotkey.shift' },\n    default: { text: 'Shift' },\n  },\n  alt: {\n    mac: { symbol: '⌥', icon: '$alt', text: '$vuetify.hotkey.option' },\n    default: { text: 'Alt' },\n  },\n  enter: {\n    default: { symbol: '↵', icon: '$enter', text: '$vuetify.hotkey.enter' },\n  },\n  arrowup: {\n    default: { symbol: '↑', icon: '$arrowup', text: '$vuetify.hotkey.upArrow' },\n  },\n  arrowdown: {\n    default: { symbol: '↓', icon: '$arrowdown', text: '$vuetify.hotkey.downArrow' },\n  },\n  arrowleft: {\n    default: { symbol: '←', icon: '$arrowleft', text: '$vuetify.hotkey.leftArrow' },\n  },\n  arrowright: {\n    default: { symbol: '→', icon: '$arrowright', text: '$vuetify.hotkey.rightArrow' },\n  },\n  backspace: {\n    default: { symbol: '⌫', icon: '$backspace', text: '$vuetify.hotkey.backspace' },\n  },\n  escape: {\n    default: { text: '$vuetify.hotkey.escape' },\n  },\n  ' ': {\n    mac: { symbol: '␣', icon: '$space', text: '$vuetify.hotkey.space' },\n    default: { text: '$vuetify.hotkey.space' },\n  },\n  '-': {\n    default: { text: '-' },\n  },\n  '+': {\n    default: { text: '+' },\n  },\n}\n\nexport const makeVHotkeyProps = propsFactory({\n  // String representing keyboard shortcuts (e.g., \"ctrl+k\", \"meta+shift+p\")\n  keys: String,\n  // How to display keys: 'symbol' uses special characters (⌘, ⌃), 'icon' uses SVG icons, 'text' uses words\n  displayMode: {\n    type: String as PropType<DisplayMode>,\n    default: 'icon',\n  },\n  // Custom key mapping configuration. Users can import and modify the exported hotkeyMap as needed\n  keyMap: {\n    type: Object as PropType<KeyMapConfig>,\n    default: () => hotkeyMap,\n  },\n  platform: {\n    type: String as PropType<'auto' | 'pc' | 'mac'>,\n    default: 'auto',\n  },\n  inline: Boolean,\n  disabled: Boolean,\n  prefix: String,\n  suffix: String,\n  variant: {\n    type: String as PropType<HotkeyVariant>,\n    default: 'elevated' as const,\n    validator: (v: any) => ['elevated', 'flat', 'tonal', 'outlined', 'text', 'plain', 'contained'].includes(v),\n  },\n\n  ...makeComponentProps(),\n  ...makeThemeProps(),\n  ...makeBorderProps(),\n  ...makeRoundedProps(),\n  ...makeElevationProps(),\n  color: String,\n}, 'VHotkey')\n\nconst AND_DELINEATOR = Symbol('VHotkey:AND_DELINEATOR') // For +_ separators\nconst OR_DELINEATOR = Symbol('VHotkey:OR_DELINEATOR') // For / separators\nconst THEN_DELINEATOR = Symbol('VHotkey:THEN_DELINEATOR') // For - separators\ntype Delineator = typeof AND_DELINEATOR | typeof OR_DELINEATOR | typeof THEN_DELINEATOR\n\nfunction getKeyText (keyMap: KeyMapConfig, key: string, isMac: boolean): string {\n  const lowerKey = key.toLowerCase()\n\n  if (lowerKey in keyMap) {\n    const result = processKey(keyMap[lowerKey], 'text', isMac)\n    return typeof result[1] === 'string' ? result[1] : String(result[1])\n  }\n\n  return key.toUpperCase()\n}\n\nfunction applyDisplayModeToKey (keyMap: KeyMapConfig, mode: DisplayMode, key: string, isMac: boolean): Key {\n  const lowerKey = key.toLowerCase()\n\n  if (lowerKey in keyMap) {\n    const result = processKey(keyMap[lowerKey], mode, isMac)\n\n    if (result[0] === 'text' && typeof result[1] === 'string' && result[1].startsWith('$') && !result[1].startsWith('$vuetify.')) {\n      return ['text', result[1].replace('$', '').toUpperCase(), key]\n    }\n\n    return [...result, key]\n  }\n\n  return ['text', key.toUpperCase(), key]\n}\n\nexport const VHotkey = genericComponent()({\n  name: 'VHotkey',\n\n  props: makeVHotkeyProps(),\n\n  setup (props) {\n    const { t } = useLocale()\n    const { themeClasses } = provideTheme(props)\n    const { rtlClasses } = useRtl()\n    const { borderClasses } = useBorder(props)\n    const { roundedClasses } = useRounded(props)\n    const { elevationClasses } = useElevation(props)\n\n    const { colorClasses, colorStyles, variantClasses } = useVariant(() => ({\n      color: props.color,\n      variant: props.variant === 'contained' ? 'elevated' : props.variant,\n    }))\n\n    const isMac = computed(() =>\n      props.platform === 'auto'\n        ? (typeof navigator !== 'undefined' && /macintosh/i.test(navigator.userAgent))\n        : props.platform === 'mac'\n    )\n\n    const keyCombinations = computed(() => {\n      if (!props.keys) return []\n\n      // Split by spaces to handle multiple key combinations\n      // Example: \"ctrl+k meta+p\" -> [\"ctrl+k\", \"meta+p\"]\n      return props.keys.split(/\\b \\b/).map(combination => {\n        const result: Array<Key | Delineator> = []\n\n        function visit (node: KeyCombination) {\n          if (typeof node === 'string') {\n            if (node !== '') {\n              result.push(applyDisplayModeToKey(props.keyMap, props.displayMode, node, isMac.value))\n            }\n          } else {\n            for (let i = 0; i < node.parts.length; i++) {\n              if (i > 0) {\n                if (node.type === 'sequence') {\n                  result.push(THEN_DELINEATOR)\n                } else if (node.type === 'alternate') {\n                  result.push(OR_DELINEATOR)\n                } else if (node.type === 'combo') {\n                  result.push(AND_DELINEATOR)\n                } else {\n                  void (node satisfies never)\n                }\n              }\n              visit(node.parts[i])\n            }\n          }\n        }\n\n        visit(parseKeyCombination(combination))\n        return result\n      })\n    })\n\n    const accessibleLabel = computed(() => {\n      if (!props.keys) return ''\n\n      // Convert the parsed key combinations into readable text\n      const readableShortcuts = keyCombinations.value.map(combination => {\n        const readableParts: string[] = []\n\n        for (const key of combination) {\n          if (Array.isArray(key)) {\n            // Always use text representation for screen readers\n            const textKey = key[0] === 'icon' || key[0] === 'symbol'\n              ? applyDisplayModeToKey(mergeDeep(hotkeyMap, props.keyMap), 'text', String(key[1]), isMac.value)[1]\n              : key[1]\n            readableParts.push(translateKey(textKey as string))\n          } else {\n            if (key === AND_DELINEATOR) {\n              readableParts.push(t('$vuetify.hotkey.plus'))\n            } else if (key === OR_DELINEATOR) {\n              readableParts.push(t('$vuetify.hotkey.or'))\n            } else if (key === THEN_DELINEATOR) {\n              readableParts.push(t('$vuetify.hotkey.then'))\n            }\n          }\n        }\n\n        return readableParts.join(' ')\n      })\n\n      const shortcutText = readableShortcuts.join(', ')\n      return t('$vuetify.hotkey.shortcut', shortcutText)\n    })\n\n    function translateKey (key: string) {\n      return key.startsWith('$vuetify.') ? t(key) : key\n    }\n\n    function getKeyTooltip (key: Key): string | undefined {\n      if (props.displayMode === 'text') return undefined\n\n      const textKey = getKeyText(props.keyMap, String(key[2]), isMac.value)\n      return translateKey(textKey)\n    }\n\n    function renderKey (key: Key, keyIndex: number) {\n      const isContained = props.variant === 'contained'\n      const KeyComponent = isContained ? 'kbd' : VKbd\n      const keyClasses = [\n        'v-hotkey__key',\n        `v-hotkey__key-${key[0]}`,\n        ...(isContained ? ['v-hotkey__key--nested'] : [\n          borderClasses.value,\n          roundedClasses.value,\n          elevationClasses.value,\n          colorClasses.value,\n        ]),\n      ]\n\n      return (\n        <KeyComponent\n          key={ keyIndex }\n          class={ keyClasses }\n          style={ isContained ? undefined : colorStyles.value }\n          aria-hidden=\"true\"\n          title={ getKeyTooltip(key) }\n        >\n          {\n            key[0] === 'icon' ? (\n              <VIcon\n                icon={ key[1] }\n                aria-hidden=\"true\"\n              />\n            ) : translateKey(key[1])\n          }\n        </KeyComponent>\n      )\n    }\n\n    function renderDivider (key: Delineator, keyIndex: number) {\n      return (\n        <span\n          key={ keyIndex }\n          class=\"v-hotkey__divider\"\n          aria-hidden=\"true\"\n        >\n          { key === AND_DELINEATOR ? '+'\n          : key === OR_DELINEATOR ? t('$vuetify.hotkey.or')\n          : t('$vuetify.hotkey.then')}\n        </span>\n      )\n    }\n\n    useRender(() => {\n      const content = (\n        <>\n          { props.prefix && (\n            <span key=\"prefix\" class=\"v-hotkey__prefix\">{ props.prefix }</span>\n          )}\n\n          { keyCombinations.value.map((combination, comboIndex) => (\n            <span class=\"v-hotkey__combination\" key={ comboIndex }>\n              { combination.map((key, keyIndex) =>\n                Array.isArray(key)\n                  ? renderKey(key, keyIndex)\n                  : renderDivider(key, keyIndex)\n              )}\n              { comboIndex < keyCombinations.value.length - 1 && (\n                <span aria-hidden=\"true\">&nbsp;</span>\n              )}\n            </span>\n          ))}\n\n          { props.suffix && (\n            <span key=\"suffix\" class=\"v-hotkey__suffix\">{ props.suffix }</span>\n          )}\n        </>\n      )\n\n      return (\n        <div\n          class={[\n            'v-hotkey',\n            {\n              'v-hotkey--disabled': props.disabled,\n              'v-hotkey--inline': props.inline,\n              'v-hotkey--contained': props.variant === 'contained',\n            },\n            themeClasses.value,\n            rtlClasses.value,\n            variantClasses.value,\n            props.class,\n          ]}\n          style={ props.style }\n          role=\"img\"\n          aria-label={ accessibleLabel.value }\n        >\n          { props.variant !== 'contained' ? content : (\n            <VKbd\n              key=\"contained\"\n              class={[\n                'v-hotkey__contained-wrapper',\n                borderClasses.value,\n                roundedClasses.value,\n                elevationClasses.value,\n                colorClasses.value,\n              ]}\n              style={ colorStyles.value }\n              aria-hidden=\"true\"\n            >\n              { content }\n            </VKbd>\n          )}\n        </div>\n      )\n    })\n  },\n})\n\nexport type VHotkey = InstanceType<typeof VHotkey>\n\nexport type { KeyConfig, PlatformKeyConfig, KeyMapConfig, DisplayMode }\n"
  },
  {
    "path": "packages/vuetify/src/components/VHotkey/__tests__/VHotkey.spec.browser.tsx",
    "content": "// Components\nimport { VHotkey } from '../VHotkey'\n\n// Utilities\nimport { render, screen } from '@test'\nimport { defineComponent, ref } from 'vue'\n\ndescribe('VHotkey.tsx', () => {\n  describe('Key Parsing', () => {\n    it('should parse simple key combinations with + separator', () => {\n      render(() => <VHotkey keys=\"ctrl+k\" />)\n\n      // Should render ctrl and k keys with + separator\n      expect(screen.getByCSS('.v-hotkey__combination')).toBeInTheDocument()\n      expect(screen.getAllByCSS('.v-hotkey__key')).toHaveLength(2)\n      expect(screen.getByCSS('.v-hotkey__divider')).toHaveTextContent('+')\n    })\n\n    it('should parse key sequences with - separator', () => {\n      render(() => <VHotkey keys=\"ctrl+a-ctrl+b\" />)\n\n      // Should render two key combinations with \"then\" separator\n      const combinations = screen.getAllByCSS('.v-hotkey__combination')\n      expect(combinations).toHaveLength(1) // Single combination with internal separators\n\n      const keys = screen.getAllByCSS('.v-hotkey__key')\n      expect(keys).toHaveLength(4) // ctrl, a, ctrl, b\n\n      const dividers = screen.getAllByCSS('.v-hotkey__divider')\n      expect(dividers).toHaveLength(3) // +, then, +\n    })\n\n    it('should correctly handle literal minus key (shift+-)', () => {\n      render(() => <VHotkey keys=\"shift+-\" displayMode=\"text\" />)\n\n      // Should render shift and minus keys with + separator, NOT treat - as sequence separator\n      const keys = screen.getAllByCSS('.v-hotkey__key')\n      expect(keys).toHaveLength(2) // shift and -\n\n      const dividers = screen.getAllByCSS('.v-hotkey__divider')\n      expect(dividers).toHaveLength(1) // Only the + separator\n      expect(dividers[0]).toHaveTextContent('+')\n\n      // The second key should be the minus key\n      expect(keys[1]).toHaveTextContent('-')\n    })\n\n    it('should handle minus key with alternative names', () => {\n      // Test both variations in a single isolated render\n      const { rerender } = render(() => <VHotkey keys=\"alt+minus\" displayMode=\"text\" />)\n\n      let keys = screen.getAllByCSS('.v-hotkey__key')\n      expect(keys).toHaveLength(2)\n      expect(keys[1]).toHaveTextContent('-')\n\n      // Rerender with different keys\n      rerender(() => <VHotkey keys=\"ctrl+hyphen\" displayMode=\"text\" />)\n      keys = screen.getAllByCSS('.v-hotkey__key')\n      expect(keys).toHaveLength(2)\n      expect(keys[1]).toHaveTextContent('-')\n    })\n\n    it('should handle plus key with alias name', () => {\n      render(() => <VHotkey keys=\"shift+plus\" displayMode=\"text\" />)\n\n      const keys = screen.getAllByCSS('.v-hotkey__key')\n      expect(keys).toHaveLength(2)\n      expect(keys[1]).toHaveTextContent('+')\n\n      const dividers = screen.getAllByCSS('.v-hotkey__divider')\n      expect(dividers).toHaveLength(1)\n      expect(dividers[0]).toHaveTextContent('+')\n    })\n\n    it('should handle slash key with alias name', () => {\n      render(() => <VHotkey keys=\"shift+slash\" displayMode=\"text\" />)\n\n      const keys = screen.getAllByCSS('.v-hotkey__key')\n      expect(keys).toHaveLength(2)\n      expect(keys[1]).toHaveTextContent('/')\n\n      const dividers = screen.getAllByCSS('.v-hotkey__divider')\n      expect(dividers).toHaveLength(1)\n      expect(dividers[0]).toHaveTextContent('+')\n    })\n\n    it('should not treat - as separator when not between alphanumeric characters', () => {\n      render(() => <VHotkey keys=\"ctrl+-\" />)\n\n      // Should parse as ctrl + literal minus, not as a sequence\n      const keys = screen.getAllByCSS('.v-hotkey__key')\n      expect(keys).toHaveLength(2)\n\n      const dividers = screen.getAllByCSS('.v-hotkey__divider')\n      expect(dividers).toHaveLength(1)\n      expect(dividers[0]).toHaveTextContent('+')\n    })\n\n    it('should treat - as separator when between alphanumeric characters', () => {\n      render(() => <VHotkey keys=\"a-b\" />)\n\n      // Should parse as sequence: a then b\n      const keys = screen.getAllByCSS('.v-hotkey__key')\n      expect(keys).toHaveLength(2)\n\n      const dividers = screen.getAllByCSS('.v-hotkey__divider')\n      expect(dividers).toHaveLength(1)\n      // Should contain \"then\" text (localized)\n      expect(dividers[0]).toHaveTextContent(/then/i)\n    })\n\n    it('should handle complex combinations with both + and - separators', () => {\n      render(() => <VHotkey keys=\"ctrl+shift+a-alt+b\" />)\n\n      // Should parse as: ctrl+shift+a then alt+b\n      const keys = screen.getAllByCSS('.v-hotkey__key')\n      expect(keys).toHaveLength(5) // ctrl, shift, a, alt, b\n\n      const dividers = screen.getAllByCSS('.v-hotkey__divider')\n      // Should have: +, +, then, +\n      expect(dividers).toHaveLength(4)\n    })\n\n    it('should handle \"then\" keyword in key combinations correctly', () => {\n      render(() => <VHotkey keys=\"meta+k-z\" displayMode=\"text\" />)\n\n      // Should parse as: meta+k then z (NOT meta+k then THEN then z)\n      const keys = screen.getAllByCSS('.v-hotkey__key')\n      expect(keys).toHaveLength(3) // meta, k, z (NOT meta, k, then, z)\n\n      const dividers = screen.getAllByCSS('.v-hotkey__divider')\n      expect(dividers).toHaveLength(2) // +, then\n\n      // Should have + between meta and k, then \"then\" separator, then z\n      expect(dividers[0]).toHaveTextContent('+')\n      expect(dividers[1]).toHaveTextContent(/then/i)\n\n      // Keys should be meta/ctrl (platform dependent), k, z\n      const firstKeyText = keys[0].textContent?.toUpperCase()\n      expect(['META', 'CTRL', 'CMD', 'COMMAND']).toContain(firstKeyText)\n      expect(keys[1]).toHaveTextContent('K')\n      expect(keys[2]).toHaveTextContent('Z')\n    })\n\n    it('should handle various sequence patterns correctly', () => {\n      // Test the exact pattern from the user's screenshot issue\n      render(() => <VHotkey keys=\"k-z\" displayMode=\"text\" />)\n\n      const keys1 = screen.getAllByCSS('.v-hotkey__key')\n      expect(keys1).toHaveLength(2) // k, z (NOT k, then, z)\n      expect(keys1[0]).toHaveTextContent('K')\n      expect(keys1[1]).toHaveTextContent('Z')\n\n      const dividers1 = screen.getAllByCSS('.v-hotkey__divider')\n      expect(dividers1).toHaveLength(1) // just \"then\"\n      expect(dividers1[0]).toHaveTextContent(/then/i)\n    })\n\n    it('should handle case-insensitive sequence patterns', () => {\n      // Test case-insensitive matching\n      render(() => <VHotkey keys=\"a-b\" displayMode=\"text\" />)\n\n      const keys = screen.getAllByCSS('.v-hotkey__key')\n      const dividers = screen.getAllByCSS('.v-hotkey__divider')\n\n      expect(keys).toHaveLength(2) // a, b\n      expect(keys[0]).toHaveTextContent('A')\n      expect(keys[1]).toHaveTextContent('B')\n      expect(dividers).toHaveLength(1)\n      expect(dividers[0]).toHaveTextContent(/then/i)\n    })\n  })\n\n  describe('Display Modes', () => {\n    it('should render minus key in text mode', () => {\n      render(() => <VHotkey keys=\"shift+-\" displayMode=\"text\" />)\n\n      const keys = screen.getAllByCSS('.v-hotkey__key')\n      expect(keys[1]).toHaveTextContent('-')\n      expect(keys[1]).toHaveClass('v-hotkey__key-text')\n    })\n\n    it('should render minus key in symbol mode', () => {\n      render(() => <VHotkey keys=\"shift+-\" displayMode=\"symbol\" />)\n\n      const keys = screen.getAllByCSS('.v-hotkey__key')\n      // Should fallback to text mode for minus key in symbol mode\n      expect(keys[1]).toHaveTextContent('-')\n      expect(keys[1]).toHaveClass('v-hotkey__key-text')\n    })\n\n    it('should render minus key in icon mode', () => {\n      render(() => <VHotkey keys=\"shift+-\" displayMode=\"icon\" platform=\"mac\" />)\n\n      const keys = screen.getAllByCSS('.v-hotkey__key')\n      // Should fallback to text mode for minus key in icon mode\n      expect(keys[1]).toHaveTextContent('-')\n      expect(keys[1]).toHaveClass('v-hotkey__key-text')\n    })\n  })\n\n  describe('Variants', () => {\n    it('should render standard variants correctly', () => {\n      const variants = ['elevated', 'flat', 'tonal', 'outlined', 'text', 'plain'] as const\n\n      for (const variant of variants) {\n        const { unmount } = render(() => <VHotkey keys=\"ctrl+k\" variant={ variant } />)\n\n        // Should render individual VKbd elements for standard variants\n        const keys = screen.getAllByCSS('.v-hotkey__key')\n        expect(keys).toHaveLength(2)\n\n        // Should not have contained wrapper\n        expect(screen.queryByCSS('.v-hotkey__contained-wrapper')).not.toBeInTheDocument()\n        expect(screen.queryByCSS('.v-hotkey--contained')).not.toBeInTheDocument()\n\n        unmount()\n      }\n    })\n\n    it('should render contained variant with nested kbd structure', () => {\n      render(() => <VHotkey keys=\"ctrl+k\" variant=\"contained\" />)\n\n      // Should have contained modifier class\n      expect(screen.getByCSS('.v-hotkey--contained')).toBeInTheDocument()\n\n      // Should have the contained wrapper VKbd\n      expect(screen.getByCSS('.v-hotkey__contained-wrapper')).toBeInTheDocument()\n\n      // Should have nested kbd elements (not VKbd components)\n      const nestedKbds = screen.getAllByCSS('.v-hotkey__key--nested')\n      expect(nestedKbds).toHaveLength(2)\n\n      // Nested elements should be actual kbd tags\n      nestedKbds.forEach(kbd => {\n        expect(kbd.tagName.toLowerCase()).toBe('kbd')\n      })\n\n      // Should still have divider\n      expect(screen.getByCSS('.v-hotkey__divider')).toHaveTextContent('+')\n    })\n\n    it('should render contained variant with key sequences', () => {\n      render(() => <VHotkey keys=\"ctrl+k-p\" variant=\"contained\" />)\n\n      // Should have contained wrapper\n      expect(screen.getByCSS('.v-hotkey__contained-wrapper')).toBeInTheDocument()\n\n      // Should have nested kbd elements for all keys\n      const nestedKbds = screen.getAllByCSS('.v-hotkey__key--nested')\n      expect(nestedKbds).toHaveLength(3) // ctrl, k, p\n\n      // Should have both + and then dividers\n      const dividers = screen.getAllByCSS('.v-hotkey__divider')\n      expect(dividers).toHaveLength(2) // +, then\n    })\n\n    it('should render contained variant with different display modes', () => {\n      // Test text mode first (always works)\n      const { unmount: unmountText } = render(() => <VHotkey keys=\"ctrl+k\" variant=\"contained\" displayMode=\"text\" />)\n\n      expect(screen.getByCSS('.v-hotkey__contained-wrapper')).toBeInTheDocument()\n      let nestedKbds = screen.getAllByCSS('.v-hotkey__key--nested')\n      expect(nestedKbds).toHaveLength(2)\n      nestedKbds.forEach(kbd => {\n        expect(kbd).toHaveClass('v-hotkey__key-text')\n      })\n      unmountText()\n\n      // Test symbol mode with keys that have symbols\n      const { unmount: unmountSymbol } = render(() => <VHotkey keys=\"cmd+shift\" variant=\"contained\" displayMode=\"symbol\" platform=\"mac\" />)\n\n      expect(screen.getByCSS('.v-hotkey__contained-wrapper')).toBeInTheDocument()\n      nestedKbds = screen.getAllByCSS('.v-hotkey__key--nested')\n      expect(nestedKbds).toHaveLength(2)\n      // Both cmd and shift should have symbols available\n      nestedKbds.forEach(kbd => {\n        expect(kbd).toHaveClass('v-hotkey__key-symbol')\n      })\n      unmountSymbol()\n\n      // Test icon mode with keys that have icons\n      const { unmount: unmountIcon } = render(() => (\n        <VHotkey keys=\"cmd+shift\" variant=\"contained\" displayMode=\"icon\" platform=\"mac\" />\n      ))\n\n      expect(screen.getByCSS('.v-hotkey__contained-wrapper')).toBeInTheDocument()\n      nestedKbds = screen.getAllByCSS('.v-hotkey__key--nested')\n      expect(nestedKbds).toHaveLength(2)\n      // On Mac, cmd and shift should have icons available\n      nestedKbds.forEach(kbd => {\n        expect(kbd).toHaveClass('v-hotkey__key-icon')\n      })\n      unmountIcon()\n    })\n\n    it('should render contained variant inline correctly', () => {\n      render(() => <VHotkey keys=\"ctrl+k\" variant=\"contained\" inline />)\n\n      // Should have both contained and inline classes\n      const hotkey = screen.getByCSS('.v-hotkey')\n      expect(hotkey).toHaveClass('v-hotkey--contained')\n      expect(hotkey).toHaveClass('v-hotkey--inline')\n\n      // Should still have contained wrapper\n      expect(screen.getByCSS('.v-hotkey__contained-wrapper')).toBeInTheDocument()\n    })\n\n    it('should apply variant-specific styling to individual VKbd elements', () => {\n      // Test elevated variant has variant class\n      const { unmount: unmountElevated } = render(() => <VHotkey keys=\"ctrl+k\" variant=\"elevated\" />)\n      const hotkeyWrapper = screen.getByCSS('.v-hotkey')\n      expect(hotkeyWrapper).toHaveClass('v-hotkey--variant-elevated')\n      unmountElevated()\n\n      // Test flat variant has variant class\n      const { unmount: unmountFlat } = render(() => <VHotkey keys=\"ctrl+k\" variant=\"flat\" />)\n      const flatWrapper = screen.getByCSS('.v-hotkey')\n      expect(flatWrapper).toHaveClass('v-hotkey--variant-flat')\n      unmountFlat()\n\n      // Test outlined variant has variant class\n      const { unmount: unmountOutlined } = render(() => <VHotkey keys=\"ctrl+k\" variant=\"outlined\" />)\n      const outlinedWrapper = screen.getByCSS('.v-hotkey')\n      expect(outlinedWrapper).toHaveClass('v-hotkey--variant-outlined')\n      unmountOutlined()\n    })\n\n    it('should apply text variant styling correctly', () => {\n      render(() => <VHotkey keys=\"ctrl+k\" variant=\"text\" />)\n\n      const hotkeyWrapper = screen.getByCSS('.v-hotkey')\n      expect(hotkeyWrapper).toHaveClass('v-hotkey--variant-text')\n\n      const kbdElements = screen.getAllByCSS('.v-hotkey__key.v-kbd')\n      expect(kbdElements.length).toBeGreaterThan(0)\n\n      kbdElements.forEach(kbd => {\n        // Text variant should have transparent background and no border\n        expect(kbd).toHaveStyle({ background: 'transparent' })\n        expect(kbd).toHaveStyle({ border: 'none' })\n        // Text variant should have no horizontal padding and auto min-width\n        expect(kbd).toHaveStyle({ paddingLeft: '0px' })\n        expect(kbd).toHaveStyle({ paddingRight: '0px' })\n        expect(kbd).toHaveStyle({ minWidth: 'auto' })\n      })\n\n      // Text variant should have reduced gap between keys\n      const combinations = screen.getAllByCSS('.v-hotkey__combination')\n      expect(combinations.length).toBeGreaterThan(0)\n      combinations.forEach(combo => {\n        expect(combo).toHaveStyle({ gap: '1px' })\n      })\n    })\n\n    it('should apply tonal variant styling correctly', () => {\n      render(() => <VHotkey keys=\"ctrl+k\" variant=\"tonal\" />)\n\n      const hotkeyWrapper = screen.getByCSS('.v-hotkey')\n      expect(hotkeyWrapper).toHaveClass('v-hotkey--variant-tonal')\n\n      const kbdElements = screen.getAllByCSS('.v-hotkey__key.v-kbd')\n      expect(kbdElements.length).toBeGreaterThan(0)\n\n      kbdElements.forEach(kbd => {\n        // Tonal variant should have no border and no elevation\n        expect(kbd).toHaveStyle({ border: 'unset' })\n        expect(kbd).toHaveStyle({ boxShadow: 'unset' })\n      })\n    })\n\n    it('should apply contained variant wrapper styling correctly', () => {\n      render(() => <VHotkey keys=\"ctrl+k\" variant=\"contained\" />)\n\n      const wrapper = screen.getByCSS('.v-hotkey__contained-wrapper')\n      expect(wrapper).toBeInTheDocument()\n\n      // Contained wrapper should have proper styling - VKbd uses flex by default\n      expect(wrapper).toHaveStyle({ display: 'flex' })\n      expect(wrapper).toHaveStyle({ alignItems: 'center' })\n      expect(wrapper).toHaveStyle({ gap: '2px' }) // combination gap\n      expect(wrapper).toHaveStyle({ background: 'unset' })\n\n      // Nested kbd elements should have minimal styling\n      const nestedKbds = screen.getAllByCSS('.v-hotkey__key--nested')\n      expect(nestedKbds.length).toBeGreaterThan(0)\n\n      nestedKbds.forEach(kbd => {\n        expect(kbd).toHaveStyle({ background: 'none' })\n        expect(kbd).toHaveStyle({ border: 'none' })\n        expect(kbd).toHaveStyle({ padding: '0px' })\n        expect(kbd).toHaveStyle({ margin: '0px' })\n        expect(kbd).toHaveStyle({ minWidth: 'auto' })\n        expect(kbd).toHaveStyle({ minHeight: 'auto' })\n      })\n    })\n\n    it('should apply contained variant inline styling correctly', () => {\n      render(() => <VHotkey keys=\"ctrl+k\" variant=\"contained\" inline />)\n\n      const wrapper = screen.getByCSS('.v-hotkey__contained-wrapper')\n      expect(wrapper).toBeInTheDocument()\n\n      // Should have both contained and inline classes on the main element\n      const hotkey = screen.getByCSS('.v-hotkey')\n      expect(hotkey).toHaveClass('v-hotkey--contained')\n      expect(hotkey).toHaveClass('v-hotkey--inline')\n\n      // Should have nested kbd elements for contained variant\n      const nestedKbds = screen.getAllByCSS('.v-hotkey__key--nested')\n      expect(nestedKbds.length).toBeGreaterThan(0)\n\n      // Should have combinations\n      const combinations = screen.getAllByCSS('.v-hotkey__combination')\n      expect(combinations.length).toBeGreaterThan(0)\n    })\n\n    it('should apply contained variant with color correctly', () => {\n      render(() => <VHotkey keys=\"ctrl+k\" variant=\"contained\" color=\"primary\" />)\n\n      const wrapper = screen.getByCSS('.v-hotkey__contained-wrapper')\n      expect(wrapper).toHaveClass('bg-primary')\n\n      // Nested elements should inherit color, not have their own background\n      const nestedKbds = screen.getAllByCSS('.v-hotkey__key--nested')\n      nestedKbds.forEach(kbd => {\n        expect(kbd).not.toHaveClass('bg-primary')\n        expect(kbd).toHaveStyle({ background: 'none' })\n      })\n    })\n\n    it('should not allow contained variant with other variants', () => {\n      // This is more of a design constraint - contained should be mutually exclusive\n      // We test that when contained is used, it creates the wrapper structure\n      render(() => <VHotkey keys=\"ctrl+k\" variant=\"contained\" />)\n\n      expect(screen.getByCSS('.v-hotkey--contained')).toBeInTheDocument()\n      expect(screen.getByCSS('.v-hotkey__contained-wrapper')).toBeInTheDocument()\n\n      // Should not have individual VKbd elements with variant styling\n      const individualKbds = screen.queryAllByCSS('.v-hotkey__key.v-kbd')\n      expect(individualKbds).toHaveLength(0)\n    })\n\n    it('should accept all valid variant values', () => {\n      const validVariants = ['elevated', 'flat', 'tonal', 'outlined', 'text', 'plain', 'contained'] as const\n\n      for (const variant of validVariants) {\n        const { unmount } = render(() => <VHotkey keys=\"ctrl+k\" variant={ variant } />)\n\n        const hotkeyWrapper = screen.getByCSS('.v-hotkey')\n\n        // Check for contained variant or standard variant class\n        const expectedClass = variant === 'contained' ? 'v-hotkey--contained' : `v-hotkey--variant-${variant}`\n        expect(hotkeyWrapper).toHaveClass(expectedClass)\n\n        unmount()\n      }\n    })\n  })\n\n  describe('Multiple Key Combinations', () => {\n    it('should handle multiple space-separated combinations', () => {\n      render(() => <VHotkey keys=\"ctrl+k meta+p\" />)\n\n      // Should render two separate combinations\n      const combinations = screen.getAllByCSS('.v-hotkey__combination')\n      expect(combinations).toHaveLength(2)\n\n      // Each combination should have 2 keys\n      const allKeys = screen.getAllByCSS('.v-hotkey__key')\n      expect(allKeys).toHaveLength(4)\n    })\n  })\n\n  describe('Custom Key Mapping', () => {\n    it('should use custom key mapping when provided', () => {\n      const customKeyMap = {\n        shift: {\n          default: { text: 'Shift', icon: '$shift' },\n        },\n        '-': {\n          default: { text: 'MINUS' },\n        },\n      }\n\n      render(() => <VHotkey keys=\"shift+-\" keyMap={ customKeyMap } platform=\"pc\" />)\n\n      const keys = screen.getAllByCSS('.v-hotkey__key')\n      expect(keys[1]).toHaveTextContent('MINUS')\n    })\n  })\n\n  describe('Error Handling', () => {\n    it('should handle empty keys prop gracefully', () => {\n      render(() => <VHotkey keys=\"\" />)\n\n      expect(screen.getByCSS('.v-hotkey')).toBeInTheDocument()\n      expect(screen.queryAllByCSS('.v-hotkey__key')).toHaveLength(0)\n    })\n\n    it('should handle undefined keys prop gracefully', () => {\n      render(() => <VHotkey />)\n\n      expect(screen.getByCSS('.v-hotkey')).toBeInTheDocument()\n      expect(screen.queryAllByCSS('.v-hotkey__key')).toHaveLength(0)\n    })\n  })\n\n  describe('Text-only Key Configuration', () => {\n    it('should render text value when only text is provided in key config (text mode)', () => {\n      render(() => <VHotkey keys=\"escape\" displayMode=\"text\" />)\n\n      const keys = screen.getAllByCSS('.v-hotkey__key')\n      expect(keys).toHaveLength(1)\n      expect(keys[0]).toHaveTextContent(/Escape/i) // Should show localized text\n      expect(keys[0]).toHaveClass('v-hotkey__key-text')\n    })\n\n    it('should fallback to text when only text is provided in key config (symbol mode)', () => {\n      render(() => <VHotkey keys=\"escape\" displayMode=\"symbol\" />)\n\n      const keys = screen.getAllByCSS('.v-hotkey__key')\n      expect(keys).toHaveLength(1)\n      // Should fallback to text when symbol is not available\n      expect(keys[0]).toHaveTextContent(/Escape/i)\n      expect(keys[0]).toHaveClass('v-hotkey__key-text') // Should use text CSS class when fallback occurs\n    })\n\n    it('should fallback to text when only text is provided in key config (icon mode)', () => {\n      render(() => <VHotkey keys=\"escape\" displayMode=\"icon\" />)\n\n      const keys = screen.getAllByCSS('.v-hotkey__key')\n      expect(keys).toHaveLength(1)\n      // Should fallback to text when icon is not available\n      expect(keys[0]).toHaveTextContent(/Escape/i)\n      expect(keys[0]).toHaveClass('v-hotkey__key-text') // Should use text CSS class when fallback occurs\n    })\n\n    it('should handle custom key with only text config in all display modes', () => {\n      const customKeyMap = {\n        customkey: {\n          default: { text: 'CUSTOM' },\n        },\n      }\n\n      // Test all modes in sequence using rerender to avoid interference\n      const { rerender } = render(() => <VHotkey keys=\"customkey\" displayMode=\"text\" keyMap={ customKeyMap } />)\n      expect(screen.getAllByCSS('.v-hotkey__key')[0]).toHaveTextContent('CUSTOM')\n      expect(screen.getAllByCSS('.v-hotkey__key')[0]).toHaveClass('v-hotkey__key-text')\n\n      // Test symbol mode - should fallback to text since custom key only provides text\n      rerender(() => <VHotkey keys=\"customkey\" displayMode=\"symbol\" keyMap={ customKeyMap } />)\n      expect(screen.getAllByCSS('.v-hotkey__key')[0]).toHaveTextContent('CUSTOM')\n      expect(screen.getAllByCSS('.v-hotkey__key')[0]).toHaveClass('v-hotkey__key-text')\n\n      // Test icon mode - should fallback to text since custom key only provides text\n      rerender(() => <VHotkey keys=\"customkey\" displayMode=\"icon\" keyMap={ customKeyMap } />)\n      expect(screen.getAllByCSS('.v-hotkey__key')[0]).toHaveTextContent('CUSTOM')\n      expect(screen.getAllByCSS('.v-hotkey__key')[0]).toHaveClass('v-hotkey__key-text')\n    })\n  })\n\n  describe('Accessibility', () => {\n    it('should have proper ARIA attributes for screen readers', () => {\n      render(() => <VHotkey keys=\"ctrl+k\" />)\n      const container = screen.getByCSS('.v-hotkey')\n\n      // Should have role=\"img\" for semantic meaning\n      expect(container).toHaveAttribute('role', 'img')\n\n      // Should have aria-label with readable description\n      expect(container).toHaveAttribute('aria-label')\n      expect(container.getAttribute('aria-label')).toMatch(/Keyboard shortcut/i)\n    })\n\n    it('should hide visual elements from screen readers', () => {\n      render(() => <VHotkey keys=\"ctrl+k\" />)\n\n      // Individual keys should be hidden from screen readers\n      const keys = screen.getAllByCSS('.v-hotkey__key')\n      keys.forEach(key => {\n        expect(key).toHaveAttribute('aria-hidden', 'true')\n      })\n\n      // Dividers should be hidden from screen readers\n      const dividers = screen.getAllByCSS('.v-hotkey__divider')\n      dividers.forEach(divider => {\n        expect(divider).toHaveAttribute('aria-hidden', 'true')\n      })\n    })\n\n    it('should handle empty state gracefully', () => {\n      render(() => <VHotkey keys=\"\" />)\n      const container = screen.getByCSS('.v-hotkey')\n\n      // Should not have aria-describedby for empty state\n      expect(container).not.toHaveAttribute('aria-describedby')\n\n      // Should have an empty aria-label for empty state\n      expect(container).toHaveAttribute('aria-label', '')\n    })\n\n    it('should generate readable text for complex shortcuts', () => {\n      render(() => <VHotkey keys=\"ctrl+shift+k-p\" />)\n      const container = screen.getByCSS('.v-hotkey')\n      const ariaLabel = container.getAttribute('aria-label')\n\n      // Should contain readable text representation\n      expect(ariaLabel).toMatch(/Keyboard shortcut/i)\n      // The locale keys start with $, so we check for those patterns\n      expect(ariaLabel).toMatch(/CTRL/i)\n      expect(ariaLabel).toMatch(/SHIFT/i)\n      expect(ariaLabel).toMatch(/then/i)\n    })\n\n    it('should provide title tooltips for icon mode', () => {\n      const originalUserAgent = navigator.userAgent\n\n      try {\n        // Test on Mac for better icon/symbol support\n        Object.defineProperty(window.navigator, 'userAgent', {\n          value: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)',\n          configurable: true,\n        })\n\n        // Test icon mode - should have title tooltips\n        render(() => <VHotkey keys=\"cmd+shift+k\" displayMode=\"icon\" platform=\"mac\" />)\n\n        const keys = screen.getAllByCSS('.v-hotkey__key')\n        expect(keys).toHaveLength(3) // cmd, shift, k\n\n        // Icon mode keys should have title attributes with text representations\n        keys.forEach(key => {\n          expect(key).toHaveAttribute('title')\n          const title = key.getAttribute('title')\n          expect(title).toBeTruthy()\n          expect(title?.length).toBeGreaterThan(0)\n        })\n\n        // Check specific expected titles for known keys\n        const iconKeys = keys.filter(key => key.querySelector('.v-icon'))\n        const textKeys = keys.filter(key => !key.querySelector('.v-icon'))\n\n        // Should have at least 2 icon keys (cmd and shift)\n        expect(iconKeys.length).toBeGreaterThanOrEqual(2)\n\n        // Check that icon keys have appropriate titles\n        const titles = iconKeys.map(key => key.getAttribute('title'))\n        expect(titles.some(title => title && /Command|Cmd/i.test(title))).toBe(true)\n        expect(titles.some(title => title && /Shift/i.test(title))).toBe(true)\n\n        // Check text keys (like 'k') have simple uppercase titles\n        textKeys.forEach(key => {\n          const title = key.getAttribute('title')\n          expect(title).toBeTruthy()\n          expect(title?.length).toBeGreaterThan(0)\n        })\n      } finally {\n        // Restore original userAgent\n        Object.defineProperty(window.navigator, 'userAgent', {\n          value: originalUserAgent,\n          configurable: true,\n        })\n      }\n    })\n\n    it('should provide title tooltips for symbol mode', () => {\n      const originalUserAgent = navigator.userAgent\n\n      try {\n        // Test on Mac for better symbol support\n        Object.defineProperty(window.navigator, 'userAgent', {\n          value: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)',\n          configurable: true,\n        })\n\n        // Test symbol mode - should have title tooltips\n        render(() => <VHotkey keys=\"cmd+shift+k\" displayMode=\"symbol\" platform=\"mac\" />)\n\n        const keys = screen.getAllByCSS('.v-hotkey__key')\n        expect(keys).toHaveLength(3)\n\n        // Symbol mode keys should have title attributes\n        keys.forEach(key => {\n          expect(key).toHaveAttribute('title')\n          const title = key.getAttribute('title')\n          expect(title).toBeTruthy()\n          expect(title?.length).toBeGreaterThan(0)\n        })\n      } finally {\n        // Restore original userAgent\n        Object.defineProperty(window.navigator, 'userAgent', {\n          value: originalUserAgent,\n          configurable: true,\n        })\n      }\n    })\n\n    it('should handle title tooltips for keys with localization fallback', () => {\n      const originalUserAgent = navigator.userAgent\n\n      try {\n        // Test on Mac for better support\n        Object.defineProperty(window.navigator, 'userAgent', {\n          value: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)',\n          configurable: true,\n        })\n\n        // Test with keys that have localization vs keys that don't\n        render(() => <VHotkey keys=\"escape+f1\" displayMode=\"icon\" platform=\"mac\" />)\n\n        const keys = screen.getAllByCSS('.v-hotkey__key')\n        expect(keys).toHaveLength(2) // escape, f1\n\n        // Both keys should have title attributes\n        keys.forEach(key => {\n          expect(key).toHaveAttribute('title')\n          const title = key.getAttribute('title')\n          expect(title).toBeTruthy()\n          expect(title?.length).toBeGreaterThan(0)\n        })\n\n        // Check that we have the expected titles\n        const titles = keys.map(key => key.getAttribute('title')).filter(Boolean)\n        expect(titles).toHaveLength(2) // Should have titles for both keys\n\n        // Should have one title containing 'escape' (case insensitive)\n        expect(titles.some(title => title && title.toLowerCase().includes('escape'))).toBe(true)\n\n        // Should have one title that is exactly 'F1'\n        expect(titles.some(title => title === 'F1')).toBe(true)\n      } finally {\n        // Restore original userAgent\n        Object.defineProperty(window.navigator, 'userAgent', {\n          value: originalUserAgent,\n          configurable: true,\n        })\n      }\n    })\n\n    it('should handle title tooltips for custom keyMap entries in icon mode', () => {\n      const customKeyMap = {\n        customkey: {\n          default: { text: 'Custom Key', symbol: '★' },\n        },\n      }\n\n      // Test icon mode with custom key (falls back to text but should still have tooltip)\n      render(() => (\n        <VHotkey keys=\"customkey\" displayMode=\"icon\" keyMap={ customKeyMap } />\n      ))\n\n      const keys = screen.getAllByCSS('.v-hotkey__key')\n      expect(keys).toHaveLength(1)\n\n      // Should have title with text representation\n      expect(keys[0]).toHaveAttribute('title')\n      expect(keys[0].getAttribute('title')).toBe('Custom Key')\n    })\n\n    it('should handle title tooltips for custom keyMap entries in symbol mode', () => {\n      const customKeyMap = {\n        customkey: {\n          default: { text: 'Custom Key', symbol: '★' },\n        },\n      }\n\n      // Test symbol mode with custom key\n      render(() => (\n        <VHotkey keys=\"customkey\" displayMode=\"symbol\" keyMap={ customKeyMap } />\n      ))\n\n      const keys = screen.getAllByCSS('.v-hotkey__key')\n      expect(keys).toHaveLength(1)\n\n      // Should have title with text representation\n      expect(keys[0]).toHaveAttribute('title')\n      expect(keys[0].getAttribute('title')).toBe('Custom Key')\n    })\n\n    it('should handle title tooltips for custom keyMap entries in text mode', () => {\n      const customKeyMap = {\n        customkey: {\n          default: { text: 'Custom Key', symbol: '★' },\n        },\n      }\n\n      // Test text mode with custom key\n      render(() => (\n        <VHotkey keys=\"customkey\" displayMode=\"text\" keyMap={ customKeyMap } />\n      ))\n\n      const keys = screen.getAllByCSS('.v-hotkey__key')\n      expect(keys).toHaveLength(1)\n\n      // Should NOT have title in text mode\n      const title = keys[0].getAttribute('title')\n      expect(title).toBeFalsy()\n    })\n\n    it('should NOT provide title tooltips in text mode (simple test)', () => {\n      const originalUserAgent = navigator.userAgent\n\n      try {\n        // Test on Mac\n        Object.defineProperty(window.navigator, 'userAgent', {\n          value: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)',\n          configurable: true,\n        })\n\n        // Test text mode directly - should NOT have title tooltips\n        render(() => <VHotkey keys=\"cmd+shift+k\" displayMode=\"text\" platform=\"mac\" />)\n\n        const keys = screen.getAllByCSS('.v-hotkey__key')\n        expect(keys).toHaveLength(3)\n\n        // Text mode keys should NOT have title attributes\n        keys.forEach((key, index) => {\n          const title = key.getAttribute('title')\n          expect(title).toBeFalsy() // Should be null, undefined, or empty string\n        })\n      } finally {\n        // Restore original userAgent\n        Object.defineProperty(window.navigator, 'userAgent', {\n          value: originalUserAgent,\n          configurable: true,\n        })\n      }\n    })\n  })\n\n  describe('Platform-specific Rendering', () => {\n    const originalUserAgent = navigator.userAgent\n\n    afterEach(() => {\n      // Restore original userAgent after each test\n      Object.defineProperty(window.navigator, 'userAgent', {\n        value: originalUserAgent,\n        configurable: true,\n      })\n    })\n\n    it('should fall back to text when displayMode is \"icon\" on non-Mac platforms', () => {\n      // Simulate a Windows environment (non-Mac)\n      Object.defineProperty(window.navigator, 'userAgent', {\n        value: 'Windows NT 10.0',\n        configurable: true,\n      })\n\n      render(() => <VHotkey keys=\"ctrl+k\" />) // displayMode defaults to 'icon'\n\n      // On Windows, no icon should be rendered for the Ctrl key\n      const icons = screen.queryAllByCSS('.v-icon')\n      expect(icons).toHaveLength(0)\n\n      // The component should instead render text for the keys\n      const textKeys = screen.getAllByCSS('.v-hotkey__key-text')\n      expect(textKeys.length).toBeGreaterThanOrEqual(1)\n      expect(textKeys[0]).toHaveTextContent(/ctrl/i)\n    })\n\n    it('should render icons when displayMode is \"icon\" on Mac platforms', () => {\n      // Simulate a Mac environment\n      Object.defineProperty(window.navigator, 'userAgent', {\n        value: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)',\n        configurable: true,\n      })\n\n      render(() => <VHotkey keys=\"cmd+k\" />) // displayMode defaults to 'icon'\n\n      // On Mac, icons should be rendered for keys that have icon configurations\n      const icons = screen.queryAllByCSS('.v-icon')\n      expect(icons.length).toBeGreaterThan(0)\n\n      // Should have icon keys, not text keys\n      const iconKeys = screen.getAllByCSS('.v-hotkey__key-icon')\n      expect(iconKeys.length).toBeGreaterThan(0)\n    })\n\n    it('should render plain \"Ctrl\" text without \"$\" prefix on non-Mac platforms', () => {\n      // Simulate a Windows environment (non-Mac)\n      Object.defineProperty(window.navigator, 'userAgent', {\n        value: 'Windows NT 10.0',\n        configurable: true,\n      })\n\n      render(() => <VHotkey keys=\"ctrl+k\" />)\n\n      const textKeys = screen.getAllByCSS('.v-hotkey__key-text')\n      expect(textKeys[0]).toHaveTextContent('Ctrl')\n      expect(textKeys[0]).not.toHaveTextContent('$ctrl')\n    })\n\n    it('should handle icon tokens in text mode gracefully', () => {\n      // Simulate a Windows environment (non-Mac)\n      Object.defineProperty(window.navigator, 'userAgent', {\n        value: 'Windows NT 10.0',\n        configurable: true,\n      })\n\n      // Create a keyMap that has an incomplete text configuration (simulating the docs bug)\n      const problematicKeyMap = {\n        ctrl: {\n          default: { text: '$ctrl', icon: '$ctrl' }, // Bug: icon token in text field\n        },\n      }\n\n      render(() => <VHotkey keys=\"ctrl\" keyMap={ problematicKeyMap } displayMode=\"text\" />)\n\n      const textKeys = screen.getAllByCSS('.v-hotkey__key-text')\n      expect(textKeys).toHaveLength(1)\n\n      // After the fix, should render \"CTRL\" instead of \"$ctrl\"\n      expect(textKeys[0]).toHaveTextContent('CTRL') // Should be converted from $ctrl to CTRL\n      expect(textKeys[0]).not.toHaveTextContent('$ctrl') // Should not contain the icon token\n    })\n\n    it('should preserve valid localization keys starting with $vuetify', () => {\n      // Simulate a Windows environment (non-Mac)\n      Object.defineProperty(window.navigator, 'userAgent', {\n        value: 'Windows NT 10.0',\n        configurable: true,\n      })\n\n      // Create a keyMap that uses proper localization keys\n      const localizationKeyMap = {\n        ctrl: {\n          default: { text: '$vuetify.hotkey.ctrl' }, // Valid localization key\n        },\n      }\n\n      render(() => <VHotkey keys=\"ctrl\" keyMap={ localizationKeyMap } displayMode=\"text\" />)\n\n      const textKeys = screen.getAllByCSS('.v-hotkey__key-text')\n      expect(textKeys).toHaveLength(1)\n\n      // Should preserve the localization key and let the translation system handle it\n      expect(textKeys[0]).toHaveTextContent('Ctrl') // Should be translated by the locale system\n    })\n\n    it('should force mac rendering when platform=\"mac\" is set on non-Mac platform', () => {\n      Object.defineProperty(window.navigator, 'userAgent', {\n        value: 'Windows NT 10.0',\n        configurable: true,\n      })\n\n      render(() => <VHotkey keys=\"cmd+k\" platform=\"mac\" />)\n\n      // Expect icons present due to forced mac\n      const iconKeys = screen.queryAllByCSS('.v-hotkey__key-icon')\n      expect(iconKeys.length).toBeGreaterThan(0)\n    })\n\n    it('should force non-Mac rendering when platform=\"pc\" is set on Mac platform', () => {\n      Object.defineProperty(window.navigator, 'userAgent', {\n        value: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)', // Mac user agent\n        configurable: true,\n      })\n\n      const { unmount } = render(() => <VHotkey keys=\"cmd+k\" platform=\"pc\" />)\n\n      // Should not render icons (Mac behavior) despite being on Mac\n      const iconKeys = screen.queryAllByCSS('.v-hotkey__key-icon')\n      expect(iconKeys).toHaveLength(0)\n\n      // Should render text instead (non-Mac behavior)\n      const textKeys = screen.queryAllByCSS('.v-hotkey__key-text')\n      expect(textKeys.length).toBeGreaterThan(0)\n\n      unmount()\n    })\n  })\n\n  describe('Platform Behavior with cmd+k', () => {\n    const originalUserAgent = navigator.userAgent\n\n    afterEach(() => {\n      // Restore original userAgent after each test\n      Object.defineProperty(window.navigator, 'userAgent', {\n        value: originalUserAgent,\n        configurable: true,\n      })\n    })\n\n    describe('platform auto, displayMode undefined (defaults to icon)', () => {\n      it('should show command icon on Mac', () => {\n        Object.defineProperty(window.navigator, 'userAgent', {\n          value: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)',\n          configurable: true,\n        })\n\n        render(() => <VHotkey keys=\"cmd+k\" />)\n\n        // Should have command icon\n        const iconKeys = screen.getAllByCSS('.v-hotkey__key-icon')\n        expect(iconKeys.length).toBeGreaterThan(0)\n\n        // Should not show \"Ctrl\" text\n        const textKeys = screen.queryAllByCSS('.v-hotkey__key-text')\n        const hasCtrlText = textKeys.some(key => key.textContent?.includes('Ctrl'))\n        expect(hasCtrlText).toBe(false)\n      })\n\n      it('should show Ctrl text on non-Mac', () => {\n        Object.defineProperty(window.navigator, 'userAgent', {\n          value: 'Windows NT 10.0',\n          configurable: true,\n        })\n\n        render(() => <VHotkey keys=\"cmd+k\" />)\n\n        // Should not have icons (non-Mac fallback to text)\n        const iconKeys = screen.queryAllByCSS('.v-hotkey__key-icon')\n        expect(iconKeys).toHaveLength(0)\n\n        // Should show \"Ctrl\" text\n        const textKeys = screen.getAllByCSS('.v-hotkey__key-text')\n        const hasCtrlText = textKeys.some(key => key.textContent?.includes('Ctrl'))\n        expect(hasCtrlText).toBe(true)\n      })\n    })\n\n    describe('platform auto, displayMode icon', () => {\n      it('should show command icon on Mac', () => {\n        Object.defineProperty(window.navigator, 'userAgent', {\n          value: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)',\n          configurable: true,\n        })\n\n        render(() => <VHotkey keys=\"cmd+k\" displayMode=\"icon\" />)\n\n        // Should have command icon\n        const iconKeys = screen.getAllByCSS('.v-hotkey__key-icon')\n        expect(iconKeys.length).toBeGreaterThan(0)\n      })\n\n      it('should show Ctrl text on non-Mac', () => {\n        Object.defineProperty(window.navigator, 'userAgent', {\n          value: 'Windows NT 10.0',\n          configurable: true,\n        })\n\n        render(() => <VHotkey keys=\"cmd+k\" displayMode=\"icon\" />)\n\n        // Should fallback to text (no icons on non-Mac)\n        const iconKeys = screen.queryAllByCSS('.v-hotkey__key-icon')\n        expect(iconKeys).toHaveLength(0)\n\n        // Should show \"Ctrl\" text\n        const textKeys = screen.getAllByCSS('.v-hotkey__key-text')\n        const hasCtrlText = textKeys.some(key => key.textContent?.includes('Ctrl'))\n        expect(hasCtrlText).toBe(true)\n      })\n    })\n\n    describe('platform mac, displayMode undefined (defaults to icon)', () => {\n      it('should show command icon on Mac', () => {\n        Object.defineProperty(window.navigator, 'userAgent', {\n          value: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)',\n          configurable: true,\n        })\n\n        render(() => <VHotkey keys=\"cmd+k\" platform=\"mac\" />)\n\n        // Should have command icon\n        const iconKeys = screen.getAllByCSS('.v-hotkey__key-icon')\n        expect(iconKeys.length).toBeGreaterThan(0)\n      })\n\n      it('should show command icon on non-Mac (forced Mac behavior)', () => {\n        Object.defineProperty(window.navigator, 'userAgent', {\n          value: 'Windows NT 10.0',\n          configurable: true,\n        })\n\n        render(() => <VHotkey keys=\"cmd+k\" platform=\"mac\" />)\n\n        // Should have command icon (forced Mac behavior)\n        const iconKeys = screen.getAllByCSS('.v-hotkey__key-icon')\n        expect(iconKeys.length).toBeGreaterThan(0)\n\n        // Should not show \"Ctrl\" text\n        const textKeys = screen.queryAllByCSS('.v-hotkey__key-text')\n        const hasCtrlText = textKeys.some(key => key.textContent?.includes('Ctrl'))\n        expect(hasCtrlText).toBe(false)\n      })\n    })\n\n    describe('platform mac, displayMode icon', () => {\n      it('should show command icon on Mac', () => {\n        Object.defineProperty(window.navigator, 'userAgent', {\n          value: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)',\n          configurable: true,\n        })\n\n        render(() => <VHotkey keys=\"cmd+k\" platform=\"mac\" displayMode=\"icon\" />)\n\n        // Should have command icon\n        const iconKeys = screen.getAllByCSS('.v-hotkey__key-icon')\n        expect(iconKeys.length).toBeGreaterThan(0)\n      })\n\n      it('should show command icon on non-Mac (forced Mac behavior)', () => {\n        Object.defineProperty(window.navigator, 'userAgent', {\n          value: 'Windows NT 10.0',\n          configurable: true,\n        })\n\n        render(() => <VHotkey keys=\"cmd+k\" platform=\"mac\" displayMode=\"icon\" />)\n\n        // Should have command icon (forced Mac behavior)\n        const iconKeys = screen.getAllByCSS('.v-hotkey__key-icon')\n        expect(iconKeys.length).toBeGreaterThan(0)\n      })\n    })\n\n    describe('platform pc, displayMode undefined (defaults to icon)', () => {\n      it('should show Ctrl text on Mac (forced non-Mac behavior)', () => {\n        Object.defineProperty(window.navigator, 'userAgent', {\n          value: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)',\n          configurable: true,\n        })\n\n        render(() => <VHotkey keys=\"cmd+k\" platform=\"pc\" />)\n\n        // Should not have icons (forced non-Mac behavior)\n        const iconKeys = screen.queryAllByCSS('.v-hotkey__key-icon')\n        expect(iconKeys).toHaveLength(0)\n\n        // Should show \"Ctrl\" text\n        const textKeys = screen.getAllByCSS('.v-hotkey__key-text')\n        const hasCtrlText = textKeys.some(key => key.textContent?.includes('Ctrl'))\n        expect(hasCtrlText).toBe(true)\n      })\n\n      it('should show Ctrl text on non-Mac', () => {\n        Object.defineProperty(window.navigator, 'userAgent', {\n          value: 'Windows NT 10.0',\n          configurable: true,\n        })\n\n        render(() => <VHotkey keys=\"cmd+k\" platform=\"pc\" />)\n\n        // Should not have icons\n        const iconKeys = screen.queryAllByCSS('.v-hotkey__key-icon')\n        expect(iconKeys).toHaveLength(0)\n\n        // Should show \"Ctrl\" text\n        const textKeys = screen.getAllByCSS('.v-hotkey__key-text')\n        const hasCtrlText = textKeys.some(key => key.textContent?.includes('Ctrl'))\n        expect(hasCtrlText).toBe(true)\n      })\n    })\n\n    describe('platform mac, displayMode symbol', () => {\n      it('should show command symbol on Mac', () => {\n        Object.defineProperty(window.navigator, 'userAgent', {\n          value: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)',\n          configurable: true,\n        })\n\n        render(() => <VHotkey keys=\"cmd+k\" platform=\"mac\" displayMode=\"symbol\" />)\n\n        // Should have command symbol\n        const symbolKeys = screen.getAllByCSS('.v-hotkey__key-symbol')\n        expect(symbolKeys.length).toBeGreaterThan(0)\n\n        // Should contain the command symbol ⌘\n        const hasCommandSymbol = symbolKeys.some(key => key.textContent?.includes('⌘'))\n        expect(hasCommandSymbol).toBe(true)\n      })\n\n      it('should show command symbol on non-Mac (forced Mac behavior)', () => {\n        Object.defineProperty(window.navigator, 'userAgent', {\n          value: 'Windows NT 10.0',\n          configurable: true,\n        })\n\n        render(() => <VHotkey keys=\"cmd+k\" platform=\"mac\" displayMode=\"symbol\" />)\n\n        // Should have command symbol (forced Mac behavior)\n        const symbolKeys = screen.getAllByCSS('.v-hotkey__key-symbol')\n        expect(symbolKeys.length).toBeGreaterThan(0)\n\n        // Should contain the command symbol ⌘\n        const hasCommandSymbol = symbolKeys.some(key => key.textContent?.includes('⌘'))\n        expect(hasCommandSymbol).toBe(true)\n      })\n    })\n\n    describe('platform pc, displayMode text', () => {\n      it('should show Ctrl text on Mac (forced non-Mac behavior)', () => {\n        Object.defineProperty(window.navigator, 'userAgent', {\n          value: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)',\n          configurable: true,\n        })\n\n        render(() => <VHotkey keys=\"cmd+k\" platform=\"pc\" displayMode=\"text\" />)\n\n        // Should show \"Ctrl\" text\n        const textKeys = screen.getAllByCSS('.v-hotkey__key-text')\n        const hasCtrlText = textKeys.some(key => key.textContent?.includes('Ctrl'))\n        expect(hasCtrlText).toBe(true)\n      })\n\n      it('should show Ctrl text on non-Mac', () => {\n        Object.defineProperty(window.navigator, 'userAgent', {\n          value: 'Windows NT 10.0',\n          configurable: true,\n        })\n\n        render(() => <VHotkey keys=\"cmd+k\" platform=\"pc\" displayMode=\"text\" />)\n\n        // Should show \"Ctrl\" text\n        const textKeys = screen.getAllByCSS('.v-hotkey__key-text')\n        const hasCtrlText = textKeys.some(key => key.textContent?.includes('Ctrl'))\n        expect(hasCtrlText).toBe(true)\n      })\n    })\n  })\n\n  describe('Visual Rendering', () => {\n    it('should render key combinations visually correctly', () => {\n      render(() => <VHotkey keys=\"ctrl+shift+a\" displayMode=\"text\" />)\n\n      const hotkeyContainer = screen.getByCSS('.v-hotkey')\n      expect(hotkeyContainer).toBeVisible()\n\n      const keys = screen.getAllByCSS('.v-hotkey__key')\n      expect(keys).toHaveLength(3)\n\n      // Check that keys are visually present\n      keys.forEach(key => {\n        expect(key).toBeVisible()\n      })\n\n      const dividers = screen.getAllByCSS('.v-hotkey__divider')\n      expect(dividers).toHaveLength(2)\n\n      // Check that dividers are visually present\n      dividers.forEach(divider => {\n        expect(divider).toBeVisible()\n        expect(divider).toHaveTextContent('+')\n      })\n    })\n\n    it('should apply correct CSS classes for different display modes', () => {\n      // Test all modes in sequence using rerender\n      const { rerender } = render(() => <VHotkey keys=\"ctrl+k\" displayMode=\"text\" />)\n      const textKeys = screen.getAllByCSS('.v-hotkey__key-text')\n      expect(textKeys.length).toBeGreaterThan(0)\n\n      // Test symbol mode - keys that have symbols should render with symbol class\n      // For ctrl+k, ctrl has a symbol but k doesn't, so k will fallback to text\n      rerender(() => <VHotkey keys=\"shift+k\" displayMode=\"symbol\" />)\n      const shiftSymbolKeys = screen.queryAllByCSS('.v-hotkey__key-symbol')\n      const textFallbackKeys = screen.queryAllByCSS('.v-hotkey__key-text')\n      // Either we have symbol keys or text fallback keys (or both)\n      expect(shiftSymbolKeys.length + textFallbackKeys.length).toBeGreaterThan(0)\n\n      // Test icon mode - use keys that have icon representations\n      rerender(() => <VHotkey keys=\"shift+enter\" displayMode=\"icon\" />)\n      const iconKeys = screen.queryAllByCSS('.v-hotkey__key-icon')\n      const iconTextKeys = screen.queryAllByCSS('.v-hotkey__key-text')\n      // Should have either icon keys or fallback to text keys\n      expect(iconKeys.length + iconTextKeys.length).toBeGreaterThan(0)\n    })\n\n    it('should handle sequence separators correctly in visual output', () => {\n      render(() => <VHotkey keys=\"ctrl+a-escape\" displayMode=\"text\" />)\n\n      const dividers = screen.getAllByCSS('.v-hotkey__divider')\n      expect(dividers).toHaveLength(2)\n\n      // First divider should be +\n      expect(dividers[0]).toHaveTextContent('+')\n\n      // Second divider should be \"then\" (localized)\n      expect(dividers[1]).toHaveTextContent(/then/i)\n    })\n  })\n\n  describe('Reactivity', () => {\n    const originalUserAgent = navigator.userAgent\n\n    afterEach(() => {\n      // Restore original userAgent after each test\n      Object.defineProperty(window.navigator, 'userAgent', {\n        value: originalUserAgent,\n        configurable: true,\n      })\n    })\n\n    it('should accept custom class and style props', () => {\n      render(() => (\n        <VHotkey\n          keys=\"ctrl+k\"\n          class=\"custom-class another-class\"\n          style={{ backgroundColor: 'red', fontSize: '16px' }}\n        />\n      ))\n\n      const hotkeyElement = screen.getByCSS('.v-hotkey')\n\n      // Check custom classes are applied\n      expect(hotkeyElement).toHaveClass('v-hotkey')\n      expect(hotkeyElement).toHaveClass('custom-class')\n      expect(hotkeyElement).toHaveClass('another-class')\n\n      // Check custom styles are applied\n      expect(hotkeyElement).toHaveStyle({ backgroundColor: 'red' })\n      expect(hotkeyElement).toHaveStyle({ fontSize: '16px' })\n    })\n\n    it('should apply theme classes correctly', () => {\n      render(() => (\n        <VHotkey\n          keys=\"ctrl+k\"\n          theme=\"dark\"\n        />\n      ))\n\n      const hotkeyElement = screen.getByCSS('.v-hotkey')\n\n      // Check theme classes are applied\n      expect(hotkeyElement).toHaveClass('v-hotkey')\n      expect(hotkeyElement).toHaveClass('v-theme--dark')\n    })\n\n    it('should include RTL composable integration', () => {\n      // Test that RTL composable is integrated (classes may be empty in LTR mode)\n      render(() => (\n        <VHotkey keys=\"ctrl+k\" />\n      ))\n\n      const hotkeyElement = screen.getByCSS('.v-hotkey')\n\n      // Check that element exists and RTL composable doesn't break rendering\n      expect(hotkeyElement).toHaveClass('v-hotkey')\n      expect(hotkeyElement).toBeInTheDocument()\n    })\n\n    it('should apply border classes correctly', () => {\n      render(() => (\n        <VHotkey\n          keys=\"ctrl+k\"\n          border=\"md\"\n        />\n      ))\n\n      const hotkeyElement = screen.getByCSS('.v-hotkey')\n      const kbdElements = screen.getAllByCSS('.v-hotkey__key')\n\n      // Check main element exists\n      expect(hotkeyElement).toHaveClass('v-hotkey')\n\n      // Check border classes are applied to individual keys\n      expect(kbdElements.length).toBeGreaterThan(0)\n      kbdElements.forEach(kbd => {\n        expect(kbd).toHaveClass('border-md')\n      })\n    })\n\n    it('should apply rounded classes correctly', () => {\n      render(() => (\n        <VHotkey\n          keys=\"ctrl+k\"\n          rounded=\"lg\"\n        />\n      ))\n\n      const hotkeyElement = screen.getByCSS('.v-hotkey')\n      const kbdElements = screen.getAllByCSS('.v-hotkey__key')\n\n      // Check main element exists\n      expect(hotkeyElement).toHaveClass('v-hotkey')\n\n      // Check rounded classes are applied to individual keys\n      expect(kbdElements.length).toBeGreaterThan(0)\n      kbdElements.forEach(kbd => {\n        expect(kbd).toHaveClass('rounded-lg')\n      })\n    })\n\n    it('should apply color classes correctly', () => {\n      render(() => (\n        <VHotkey\n          keys=\"ctrl+k\"\n          color=\"primary\"\n        />\n      ))\n\n      const hotkeyElement = screen.getByCSS('.v-hotkey')\n      const kbdElements = screen.getAllByCSS('.v-hotkey__key')\n\n      // Check main element exists and has variant class but no background color\n      expect(hotkeyElement).toHaveClass('v-hotkey')\n      expect(hotkeyElement).toHaveClass('v-hotkey--variant-elevated')\n      expect(hotkeyElement).not.toHaveClass('bg-primary')\n\n      // Check color classes are applied to individual keys\n      expect(kbdElements.length).toBeGreaterThan(0)\n      kbdElements.forEach(kbd => {\n        expect(kbd).toHaveClass('bg-primary')\n      })\n    })\n\n    it('should apply elevation classes correctly', () => {\n      render(() => (\n        <VHotkey\n          keys=\"ctrl+k\"\n          elevation=\"4\"\n        />\n      ))\n\n      const hotkeyElement = screen.getByCSS('.v-hotkey')\n      const kbdElements = screen.getAllByCSS('.v-hotkey__key')\n\n      // Check main element exists\n      expect(hotkeyElement).toHaveClass('v-hotkey')\n\n      // Check elevation classes are applied to individual keys\n      expect(kbdElements.length).toBeGreaterThan(0)\n      kbdElements.forEach(kbd => {\n        expect(kbd).toHaveClass('elevation-4')\n      })\n    })\n\n    it('should apply disabled classes correctly', () => {\n      render(() => (\n        <VHotkey\n          keys=\"ctrl+k\"\n          disabled\n        />\n      ))\n\n      const hotkeyElement = screen.getByCSS('.v-hotkey')\n\n      // Check disabled classes are applied\n      expect(hotkeyElement).toHaveClass('v-hotkey')\n      expect(hotkeyElement).toHaveClass('v-hotkey--disabled')\n    })\n\n    it('should combine all composable classes together', () => {\n      render(() => (\n        <VHotkey\n          keys=\"ctrl+k\"\n          class=\"custom-class\"\n          theme=\"dark\"\n          border=\"sm\"\n          rounded=\"md\"\n          elevation=\"2\"\n          color=\"primary\"\n          disabled\n        />\n      ))\n\n      const hotkeyElement = screen.getByCSS('.v-hotkey')\n      const kbdElements = screen.getAllByCSS('.v-hotkey__key')\n\n      // Check all classes are applied together on main element (no background color)\n      expect(hotkeyElement).toHaveClass('v-hotkey')\n      expect(hotkeyElement).toHaveClass('custom-class')\n      expect(hotkeyElement).toHaveClass('v-theme--dark')\n      expect(hotkeyElement).toHaveClass('v-hotkey--variant-elevated')\n      expect(hotkeyElement).toHaveClass('v-hotkey--disabled')\n      expect(hotkeyElement).not.toHaveClass('bg-primary')\n\n      // Check border, rounded, elevation, and color classes are applied to individual keys\n      expect(kbdElements.length).toBeGreaterThan(0)\n      kbdElements.forEach(kbd => {\n        expect(kbd).toHaveClass('border-sm')\n        expect(kbd).toHaveClass('rounded-md')\n        expect(kbd).toHaveClass('elevation-2')\n        expect(kbd).toHaveClass('bg-primary')\n      })\n    })\n\n    it('should react to platform prop changes', async () => {\n      // Start on a Windows machine\n      Object.defineProperty(window.navigator, 'userAgent', {\n        value: 'Windows NT 10.0',\n        configurable: true,\n      })\n\n      const TestWrapper = defineComponent({\n        setup () {\n          const platform = ref<'auto' | 'pc' | 'mac'>('auto')\n          return { platform }\n        },\n        render () {\n          return <VHotkey keys=\"cmd+k\" platform={ this.platform } />\n        },\n      })\n\n      const wrapper = render(TestWrapper)\n\n      // Initially should show Ctrl (Windows auto-detection)\n      let textKeys = screen.getAllByCSS('.v-hotkey__key-text')\n      let hasCtrlText = textKeys.some(key => key.textContent?.includes('Ctrl'))\n      expect(hasCtrlText).toBe(true)\n      expect(screen.queryAllByCSS('.v-hotkey__key-icon')).toHaveLength(0)\n\n      // Change to mac\n      await wrapper.rerender({ platform: 'mac' })\n\n      // Should now show command icon (forced Mac behavior)\n      const iconKeys = screen.getAllByCSS('.v-hotkey__key-icon')\n      expect(iconKeys.length).toBeGreaterThan(0)\n      textKeys = screen.queryAllByCSS('.v-hotkey__key-text')\n      hasCtrlText = textKeys.some(key => key.textContent?.includes('Ctrl'))\n      expect(hasCtrlText).toBe(false)\n\n      // Change to pc\n      await wrapper.rerender({ platform: 'pc' })\n\n      // Should go back to Ctrl text (forced PC behavior)\n      expect(screen.queryAllByCSS('.v-hotkey__key-icon')).toHaveLength(0)\n      textKeys = screen.getAllByCSS('.v-hotkey__key-text')\n      hasCtrlText = textKeys.some(key => key.textContent?.includes('Ctrl'))\n      expect(hasCtrlText).toBe(true)\n\n      // Change back to auto (auto-detection)\n      await wrapper.rerender({ platform: 'auto' })\n\n      // Should show Ctrl again (Windows auto-detection)\n      expect(screen.queryAllByCSS('.v-hotkey__key-icon')).toHaveLength(0)\n      textKeys = screen.getAllByCSS('.v-hotkey__key-text')\n      hasCtrlText = textKeys.some(key => key.textContent?.includes('Ctrl'))\n      expect(hasCtrlText).toBe(true)\n    })\n\n    it('should react to displayMode prop changes while maintaining platform behavior', async () => {\n      // Start on a Mac\n      Object.defineProperty(window.navigator, 'userAgent', {\n        value: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)',\n        configurable: true,\n      })\n\n      const TestWrapper = defineComponent({\n        setup () {\n          const displayMode = ref<'icon' | 'symbol' | 'text'>('icon')\n          const platform = ref<'auto' | 'pc' | 'mac'>('mac')\n          return { displayMode, platform }\n        },\n        render () {\n          return <VHotkey keys=\"cmd+k\" displayMode={ this.displayMode } platform={ this.platform } />\n        },\n      })\n\n      const wrapper = render(TestWrapper)\n\n      // Initially should show command icon\n      const iconKeys = screen.getAllByCSS('.v-hotkey__key-icon')\n      expect(iconKeys.length).toBeGreaterThan(0)\n\n      // Change to symbol mode\n      await wrapper.rerender({ displayMode: 'symbol', platform: 'mac' })\n\n      // Should show command symbol\n      const symbolKeys = screen.getAllByCSS('.v-hotkey__key-symbol')\n      expect(symbolKeys.length).toBeGreaterThan(0)\n      const hasCommandSymbol = symbolKeys.some(key => key.textContent?.includes('⌘'))\n      expect(hasCommandSymbol).toBe(true)\n\n      // Change platform to PC while keeping symbol mode\n      await wrapper.rerender({ displayMode: 'symbol', platform: 'pc' })\n\n      // Should show Ctrl text (PC doesn't have command symbols)\n      expect(screen.queryAllByCSS('.v-hotkey__key-symbol')).toHaveLength(0)\n      const textKeys = screen.getAllByCSS('.v-hotkey__key-text')\n      const hasCtrlText = textKeys.some(key => key.textContent?.includes('Ctrl'))\n      expect(hasCtrlText).toBe(true)\n\n      // Change back to icon mode while on PC\n      await wrapper.rerender({ displayMode: 'icon', platform: 'pc' })\n\n      // Should still show Ctrl text (PC doesn't use icons for modifiers)\n      expect(screen.queryAllByCSS('.v-hotkey__key-icon')).toHaveLength(0)\n      const textKeys2 = screen.getAllByCSS('.v-hotkey__key-text')\n      const hasCtrlText2 = textKeys2.some(key => key.textContent?.includes('Ctrl'))\n      expect(hasCtrlText2).toBe(true)\n    })\n\n    it('should react to both platform and displayMode changes simultaneously', async () => {\n      const TestWrapper = defineComponent({\n        setup () {\n          const displayMode = ref<'icon' | 'symbol' | 'text'>('icon')\n          const platform = ref<'auto' | 'pc' | 'mac'>('pc')\n          return { displayMode, platform }\n        },\n        render () {\n          return <VHotkey keys=\"cmd+k\" displayMode={ this.displayMode } platform={ this.platform } />\n        },\n      })\n\n      const wrapper = render(TestWrapper)\n\n      // Initially PC + icon should show Ctrl text\n      let textKeys = screen.getAllByCSS('.v-hotkey__key-text')\n      const hasCtrlText = textKeys.some(key => key.textContent?.includes('Ctrl'))\n      expect(hasCtrlText).toBe(true)\n      expect(screen.queryAllByCSS('.v-hotkey__key-icon')).toHaveLength(0)\n\n      // Change both to Mac + symbol simultaneously\n      await wrapper.rerender({ displayMode: 'symbol', platform: 'mac' })\n\n      // Should show command symbol\n      const symbolKeys = screen.getAllByCSS('.v-hotkey__key-symbol')\n      expect(symbolKeys.length).toBeGreaterThan(0)\n      const hasCommandSymbol = symbolKeys.some(key => key.textContent?.includes('⌘'))\n      expect(hasCommandSymbol).toBe(true)\n\n      // Change both to auto platform + text mode\n      await wrapper.rerender({ displayMode: 'text', platform: 'auto' })\n\n      // Should auto-detect platform and show appropriate text\n      // (This will depend on the test environment's navigator.userAgent)\n      textKeys = screen.getAllByCSS('.v-hotkey__key-text')\n      expect(textKeys.length).toBeGreaterThan(0)\n      // Should show either Ctrl or Command depending on auto-detection\n      const hasCtrl = textKeys.some(key => key.textContent?.includes('Ctrl'))\n      const hasCommand = textKeys.some(key => key.textContent?.includes('Command'))\n      expect(hasCtrl || hasCommand).toBe(true)\n    })\n  })\n\n  describe('Disabled State', () => {\n    it('should apply disabled styling when disabled prop is true', () => {\n      render(() => <VHotkey keys=\"ctrl+k\" disabled />)\n\n      const hotkeyWrapper = screen.getByCSS('.v-hotkey')\n      expect(hotkeyWrapper).toHaveClass('v-hotkey--disabled')\n    })\n\n    it('should not apply disabled styling when disabled prop is false', () => {\n      render(() => <VHotkey keys=\"ctrl+k\" disabled={ false } />)\n\n      const hotkeyWrapper = screen.getByCSS('.v-hotkey')\n      expect(hotkeyWrapper).not.toHaveClass('v-hotkey--disabled')\n    })\n\n    it('should work with disabled state in contained variant', () => {\n      render(() => <VHotkey keys=\"ctrl+k\" variant=\"contained\" disabled />)\n\n      const hotkeyWrapper = screen.getByCSS('.v-hotkey')\n      expect(hotkeyWrapper).toHaveClass('v-hotkey--disabled')\n      expect(hotkeyWrapper).toHaveClass('v-hotkey--contained')\n    })\n  })\n\n  describe('Variant Validation', () => {\n    it('should accept all valid variant values', () => {\n      const validVariants = ['elevated', 'flat', 'tonal', 'outlined', 'text', 'plain', 'contained'] as const\n\n      for (const variant of validVariants) {\n        const { unmount } = render(() => <VHotkey keys=\"ctrl+k\" variant={ variant } />)\n\n        const hotkeyWrapper = screen.getByCSS('.v-hotkey')\n\n        // Check for contained variant or standard variant class\n        const expectedClass = variant === 'contained' ? 'v-hotkey--contained' : `v-hotkey--variant-${variant}`\n        expect(hotkeyWrapper).toHaveClass(expectedClass)\n\n        unmount()\n      }\n    })\n  })\n\n  describe('Component Rendering with Special Keys', () => {\n    it('should render literal symbol keys correctly', () => {\n      render(() => <VHotkey keys=\"ctrl+-\" displayMode=\"text\" />)\n\n      const keys = screen.getAllByCSS('.v-hotkey__key')\n      expect(keys).toHaveLength(2) // ctrl and -\n\n      const dividers = screen.getAllByCSS('.v-hotkey__divider')\n      expect(dividers).toHaveLength(1) // Only the + separator\n      expect(dividers[0]).toHaveTextContent('+')\n\n      // The second key should be the minus key\n      expect(keys[1]).toHaveTextContent('-')\n    })\n\n    it('should render complex combinations with literal symbols', () => {\n      render(() => <VHotkey keys=\"ctrl+shift+-\" displayMode=\"text\" />)\n\n      const keys = screen.getAllByCSS('.v-hotkey__key')\n      expect(keys).toHaveLength(3) // ctrl, shift, and -\n\n      const dividers = screen.getAllByCSS('.v-hotkey__divider')\n      expect(dividers).toHaveLength(2) // Two + separators\n      dividers.forEach(divider => {\n        expect(divider).toHaveTextContent('+')\n      })\n\n      expect(keys[0]).toHaveTextContent('Ctrl')\n      expect(keys[1]).toHaveTextContent('Shift')\n      expect(keys[2]).toHaveTextContent('-')\n    })\n\n    it('should render sequence with literal symbols', () => {\n      render(() => <VHotkey keys=\"ctrl+a-shift+-\" displayMode=\"text\" />)\n\n      const keys = screen.getAllByCSS('.v-hotkey__key')\n      expect(keys).toHaveLength(4) // ctrl, a, shift, -\n\n      const dividers = screen.getAllByCSS('.v-hotkey__divider')\n      expect(dividers).toHaveLength(3) // +, then, +\n\n      expect(dividers[0]).toHaveTextContent('+')\n      expect(dividers[1]).toHaveTextContent(/then/i)\n      expect(dividers[2]).toHaveTextContent('+')\n\n      expect(keys[0]).toHaveTextContent('Ctrl')\n      expect(keys[1]).toHaveTextContent('A')\n      expect(keys[2]).toHaveTextContent('Shift')\n      expect(keys[3]).toHaveTextContent('-')\n    })\n  })\n\n  describe('Space Key Rendering', () => {\n    it('should render the word \"Space\" in text mode, not an empty character', () => {\n      render(() => <VHotkey keys=\"ctrl+space\" displayMode=\"text\" />)\n\n      const keys = screen.getAllByCSS('.v-hotkey__key')\n      const spaceKey = keys.find(key => key.textContent?.match(/space/i))\n\n      expect(spaceKey).toBeInTheDocument()\n      expect(spaceKey).toHaveTextContent(/space/i)\n      expect(spaceKey?.textContent?.trim()).not.toBe('')\n    })\n\n    it('should render an icon for space on Mac in icon mode', () => {\n      render(() => <VHotkey keys=\"ctrl+space\" displayMode=\"icon\" platform=\"mac\" />)\n\n      const keys = screen.getAllByCSS('.v-hotkey__key')\n      // ctrl, space\n      expect(keys).toHaveLength(2)\n\n      // The key for 'space' should be an icon\n      const spaceKey = keys[1]\n      expect(spaceKey).toHaveClass('v-hotkey__key-icon')\n      expect(spaceKey.querySelector('.v-icon')).toBeInTheDocument()\n    })\n\n    it('should fall back to text for space on PC in icon mode', () => {\n      render(() => <VHotkey keys=\"ctrl+space\" displayMode=\"icon\" platform=\"pc\" />)\n\n      const keys = screen.getAllByCSS('.v-hotkey__key')\n      expect(keys).toHaveLength(2)\n\n      const spaceKey = keys[1]\n      expect(spaceKey).toHaveClass('v-hotkey__key-text')\n      expect(spaceKey).toHaveTextContent(/space/i)\n      expect(spaceKey.querySelector('.v-icon')).not.toBeInTheDocument()\n    })\n\n    it('should render the symbol for space on Mac in symbol mode', () => {\n      render(() => <VHotkey keys=\"ctrl+space\" displayMode=\"symbol\" platform=\"mac\" />)\n\n      const keys = screen.getAllByCSS('.v-hotkey__key')\n      expect(keys).toHaveLength(2)\n\n      const spaceKey = keys[1]\n      expect(spaceKey).toHaveClass('v-hotkey__key-symbol')\n      expect(spaceKey).toHaveTextContent('␣')\n    })\n\n    it('should fall back to text for space on PC in symbol mode', () => {\n      render(() => <VHotkey keys=\"ctrl+space\" displayMode=\"symbol\" platform=\"pc\" />)\n\n      const keys = screen.getAllByCSS('.v-hotkey__key')\n      expect(keys).toHaveLength(2)\n\n      const spaceKey = keys[1]\n      expect(spaceKey).toHaveClass('v-hotkey__key-text')\n      expect(spaceKey).toHaveTextContent(/space/i)\n    })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VHotkey/_variables.scss",
    "content": "@forward '../VKbd/variables';\n@use '../../styles/settings';\n@use '../../styles/tools';\n@use '../VKbd/variables' as vkbd;\n\n$hotkey-gap: 4px !default;\n$hotkey-icon-size: 0.75rem !default;\n$hotkey-divider-opacity: var(--v-medium-emphasis-opacity) !default;\n$hotkey-divider-font-size: 1em !default;\n$hotkey-combination-gap: 2px !default;\n$hotkey-font-size: 0.75rem !default;\n$hotkey-line-height: 1.5 !default;\n$hotkey-padding: 0.2rem !default;\n$hotkey-min-width: 1.5em !default;\n$hotkey-disabled-opacity: 0.26 !default;\n\n\n$hotkey-inline-font-size: 1em !default;\n$hotkey-inline-padding: 1px 4px 0 !default;\n$hotkey-inline-min-width: vkbd.$kbd-min-width !default;\n$hotkey-inline-icon-max-height: calc(1ex + 2px) !default;\n$hotkey-inline-divider-font-size: 1em !default;\n\n$hotkey-contained-padding: 0.2rem 4px !default;\n$hotkey-contained-prefix-margin-right: 2px !default;\n$hotkey-contained-suffix-margin-left: 2px !default;\n\n$hotkey-prefix-suffix-opacity: var(--v-medium-emphasis-opacity) !default;\n$hotkey-prefix-suffix-contained-opacity: var(--v-high-emphasis-opacity) !default;\n$hotkey-prefix-suffix-font-weight: normal !default;\n\n// Variant variables\n$hotkey-background: rgb(var(--v-theme-surface)) !default;\n$hotkey-color: tools.theme-color('on-surface', var(--v-high-emphasis-opacity)) !default;\n$hotkey-elevation: 1 !default;\n$hotkey-plain-opacity: .62 !default;\n\n$hotkey-variants: (\n  $hotkey-background,\n  $hotkey-color,\n  $hotkey-elevation,\n  $hotkey-plain-opacity,\n  'v-hotkey'\n) !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VHotkey/index.ts",
    "content": "export { VHotkey } from './VHotkey'\n"
  },
  {
    "path": "packages/vuetify/src/components/VHover/VHover.tsx",
    "content": "// Composables\nimport { makeDelayProps, useDelay } from '@/composables/delay'\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { genericComponent, propsFactory } from '@/util'\n\ntype VHoverSlots = {\n  default: {\n    isHovering: boolean | null\n    props: Record<string, unknown>\n  }\n}\n\nexport const makeVHoverProps = propsFactory({\n  disabled: Boolean,\n  modelValue: {\n    type: Boolean,\n    default: null,\n  },\n\n  ...makeDelayProps(),\n}, 'VHover')\n\nexport const VHover = genericComponent<VHoverSlots>()({\n  name: 'VHover',\n\n  props: makeVHoverProps(),\n\n  emits: {\n    'update:modelValue': (value: boolean) => true,\n  },\n\n  setup (props, { slots }) {\n    const isHovering = useProxiedModel(props, 'modelValue')\n    const { runOpenDelay, runCloseDelay } = useDelay(props, value => !props.disabled && (isHovering.value = value))\n\n    return () => slots.default?.({\n      isHovering: isHovering.value,\n      props: {\n        onMouseenter: runOpenDelay,\n        onMouseleave: runCloseDelay,\n      },\n    })\n  },\n})\n\nexport type VHover = InstanceType<typeof VHover>\n"
  },
  {
    "path": "packages/vuetify/src/components/VHover/__tests__/VHover.spec.browser.tsx",
    "content": "import { VHover } from '../VHover'\n\n// Utilities\nimport { render, screen, userEvent, wait } from '@test'\n\ndescribe('VHover', () => {\n  it('should react on mouse events', async () => {\n    render(() => (\n      <VHover>\n        {{\n          default: ({ isHovering, props }) => (\n            <div { ...props } class={['hover-element', isHovering && 'bg-primary']}>foobar</div>\n          ),\n        }}\n      </VHover>\n    ))\n\n    const element = screen.getByCSS('.hover-element')\n\n    expect(element).not.toHaveClass('bg-primary')\n\n    await userEvent.hover(element)\n    await expect.element(element).toHaveClass('bg-primary')\n\n    await userEvent.unhover(element)\n    await expect.element(element).not.toHaveClass('bg-primary')\n  })\n\n  it('should not react when disabled', async () => {\n    render(() => (\n      <VHover disabled>\n        {{\n          default: ({ isHovering, props }) => (\n            <div { ...props } class={['hover-element', isHovering && 'bg-primary']}>foobar</div>\n          ),\n        }}\n      </VHover>\n    ))\n\n    const element = screen.getByCSS('.hover-element')\n\n    expect(element).not.toHaveClass('bg-primary')\n\n    await userEvent.hover(element)\n    await expect.element(element).not.toHaveClass('bg-primary')\n\n    await userEvent.unhover(element)\n    await expect.element(element).not.toHaveClass('bg-primary')\n  })\n\n  it('should respect delays', async () => {\n    render(() => (\n      <VHover openDelay={ 200 } closeDelay={ 200 }>\n        {{\n          default: ({ isHovering, props }) => (\n            <div { ...props } class={['hover-element', { 'bg-primary': isHovering }]}>foobar</div>\n          ),\n        }}\n      </VHover>\n    ))\n\n    const element = screen.getByCSS('.hover-element')\n\n    await userEvent.hover(element)\n    expect(element).not.toHaveClass('bg-primary')\n    await wait(200)\n    await expect.element(element).toHaveClass('bg-primary')\n\n    await userEvent.unhover(element)\n    expect(element).toHaveClass('bg-primary')\n    await wait(200)\n    await expect.element(element).not.toHaveClass('bg-primary')\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VHover/index.ts",
    "content": "export { VHover } from './VHover'\n"
  },
  {
    "path": "packages/vuetify/src/components/VIcon/VIcon.sass",
    "content": "@use 'sass:map'\n@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-icon\n    --v-icon-size-multiplier: 1\n    align-items: center\n    display: inline-flex\n    font-feature-settings: 'liga'\n    height: $icon-size\n    justify-content: center\n    letter-spacing: $icon-letter-spacing\n    line-height: $icon-line-height\n    position: relative\n    opacity: var(--v-icon-opacity, 1)\n    text-indent: $icon-text-indent\n    text-align: center\n    user-select: none\n    vertical-align: $icon-vertical-align\n    width: $icon-size\n    min-width: $icon-size\n\n    &--clickable\n      cursor: pointer\n\n    &--disabled\n      pointer-events: none\n      opacity: $icon-disabled-opacity\n\n    @each $name in settings.$sizes\n      &--size-#{$name}\n        font-size: calc(var(--v-icon-size-multiplier) * #{map.get($icon-sizes, $name)})\n\n  .v-icon__svg\n    fill: currentColor\n    width: 100%\n    height: 100%\n\n  .v-icon--start\n    margin-inline-end: $icon-margin-start\n\n  .v-icon--end\n    margin-inline-start: $icon-margin-end\n"
  },
  {
    "path": "packages/vuetify/src/components/VIcon/VIcon.tsx",
    "content": "// Styles\nimport './VIcon.sass'\n\n// Composables\nimport { useTextColor } from '@/composables/color'\nimport { makeComponentProps } from '@/composables/component'\nimport { IconValue, useIcon } from '@/composables/icons'\nimport { makeSizeProps, useSize } from '@/composables/size'\nimport { makeTagProps } from '@/composables/tag'\nimport { makeThemeProps, useTheme } from '@/composables/theme'\n\n// Utilities\nimport { shallowRef, Text } from 'vue'\nimport { convertToUnit, flattenFragments, genericComponent, propsFactory, useRender } from '@/util'\n\nexport const makeVIconProps = propsFactory({\n  color: String,\n  disabled: Boolean,\n  start: Boolean,\n  end: Boolean,\n  icon: IconValue,\n  opacity: [String, Number],\n\n  ...makeComponentProps(),\n  ...makeSizeProps(),\n  ...makeTagProps({ tag: 'i' }),\n  ...makeThemeProps(),\n}, 'VIcon')\n\nexport const VIcon = genericComponent()({\n  name: 'VIcon',\n\n  props: makeVIconProps(),\n\n  setup (props, { attrs, slots }) {\n    const slotIcon = shallowRef<string>()\n\n    const { themeClasses } = useTheme()\n    const { iconData } = useIcon(() => slotIcon.value || props.icon)\n    const { sizeClasses } = useSize(props)\n    const { textColorClasses, textColorStyles } = useTextColor(() => props.color)\n\n    useRender(() => {\n      const slotValue = slots.default?.()\n      if (slotValue) {\n        slotIcon.value = flattenFragments(slotValue).filter(node =>\n          node.type === Text && node.children && typeof node.children === 'string'\n        )[0]?.children as string\n      }\n      const hasClick = !!(attrs.onClick || attrs.onClickOnce)\n\n      return (\n        <iconData.value.component\n          tag={ props.tag }\n          icon={ iconData.value.icon }\n          class={[\n            'v-icon',\n            'notranslate',\n            themeClasses.value,\n            sizeClasses.value,\n            textColorClasses.value,\n            {\n              'v-icon--clickable': hasClick,\n              'v-icon--disabled': props.disabled,\n              'v-icon--start': props.start,\n              'v-icon--end': props.end,\n            },\n            props.class,\n          ]}\n          style={[\n            {\n              '--v-icon-opacity': props.opacity,\n            },\n            !sizeClasses.value ? ({\n              fontSize: convertToUnit(props.size),\n              height: convertToUnit(props.size),\n              width: convertToUnit(props.size),\n            }) : undefined,\n            textColorStyles.value,\n            props.style,\n          ]}\n          role={ hasClick ? 'button' : undefined }\n          aria-hidden={ !hasClick }\n          tabindex={ hasClick ? props.disabled ? -1 : 0 : undefined }\n        >\n          { slotValue }\n        </iconData.value.component>\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VIcon = InstanceType<typeof VIcon>\n"
  },
  {
    "path": "packages/vuetify/src/components/VIcon/__tests__/VIcon.spec.browser.tsx",
    "content": "import { VIcon } from '../VIcon'\n\n// Utilities\nimport { render, screen } from '@test'\n\ndescribe('VIcon', () => {\n  describe('icon prop', () => {\n    it('should render icon from default set', () => {\n      render(() => <VIcon icon=\"mdi-home\" />)\n\n      const icon = screen.getByText('', { selector: '.mdi-home' })\n      expect(icon).toHaveClass('mdi-home')\n      expect(icon).toHaveClass('mdi')\n    })\n  })\n\n  describe('default slot', () => {\n    it('should render icon from default set', () => {\n      render(() => <VIcon>mdi-home</VIcon>)\n\n      const icon = screen.getByText('', { selector: '.mdi-home' })\n      expect(icon).toHaveClass('mdi-home')\n      expect(icon).toHaveClass('mdi')\n    })\n\n    it('should render default slot if no icon value is found', () => {\n      const Foo = () => (\n        <svg style=\"width: 100%; height: 100%;\" class=\"foo\">\n          <path d=\"M7,10L12,15L17,10H7Z\" />\n        </svg>\n      )\n\n      render(() => (\n        <VIcon>\n          <Foo />\n        </VIcon>\n      ))\n\n      const svg = screen.getByText('', { selector: '.foo' })\n      expect(svg).toBeVisible()\n    })\n  })\n\n  it('should render svg icon', () => {\n    render(() => <VIcon icon=\"svg:M7,10L12,15L17,10H7Z\" />)\n\n    const svg = screen.getByCSS('svg')\n    expect(svg).toBeVisible()\n    const path = screen.getByCSS('svg path')\n    expect(path).toHaveAttribute('d', 'M7,10L12,15L17,10H7Z')\n  })\n\n  it('should render class icon', () => {\n    render(() => <VIcon icon=\"class:foo\" />)\n\n    const icon = screen.getByText('', { selector: '.foo' })\n    expect(icon).toHaveClass('foo')\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VIcon/_variables.scss",
    "content": "@use 'sass:map';\n@use '../../styles/settings';\n@use '../../styles/tools';\n\n// VIcon\n$icon-disabled-opacity: 0.38 !default;\n$icon-left-margin-left: 8px !default;\n$icon-letter-spacing: normal !default;\n$icon-line-height: 1 !default;\n$icon-margin-end: 8px !default;\n$icon-margin-start: 8px !default;\n$icon-size: 1em !default;\n$icon-text-indent: 0 !default;\n$icon-vertical-align: middle !default;\n\n// Lists\n$icon-sizes: () !default;\n$icon-sizes: tools.map-deep-merge(\n  (\n    'x-small': 1em,\n    'small': 1.25em,\n    'default': 1.5em,\n    'large': 1.75em,\n    'x-large': 2em,\n  ),\n  $icon-sizes\n);\n"
  },
  {
    "path": "packages/vuetify/src/components/VIcon/index.ts",
    "content": "export { VIcon } from './VIcon'\nexport { VComponentIcon, VSvgIcon, VLigatureIcon, VClassIcon } from '@/composables/icons'\n"
  },
  {
    "path": "packages/vuetify/src/components/VImg/VImg.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-img\n    --v-theme-overlay-multiplier: 3\n    z-index: 0\n\n    &.v-img--absolute\n      height: 100%\n      left: 0\n      overflow: hidden\n      position: absolute\n      top: 0\n      width: 100%\n      z-index: -1\n\n    &.v-img--fit-content\n      max-width: fit-content\n\n      > .v-img__img\n        position: relative\n\n      > .v-responsive__sizer\n        display: none\n\n    &--booting .v-responsive__sizer\n      transition: none\n\n    &--rounded\n      @include tools.rounded($img-rounded-border-radius)\n\n  .v-img__img,\n  .v-img__picture,\n  .v-img__gradient,\n  .v-img__placeholder,\n  .v-img__error\n    z-index: -1\n\n    @include tools.absolute()\n\n  .v-img__img\n    &--preload\n      filter: $img-preload-filter\n\n    &--contain\n      object-fit: contain\n\n    &--cover\n      object-fit: cover\n\n  .v-img__gradient\n    background-repeat: no-repeat\n"
  },
  {
    "path": "packages/vuetify/src/components/VImg/VImg.tsx",
    "content": "// Styles\nimport './VImg.sass'\n\n// Components\nimport { makeVResponsiveProps, VResponsive } from '@/components/VResponsive/VResponsive'\n\n// Composables\nimport { useBackgroundColor } from '@/composables/color'\nimport { makeComponentProps } from '@/composables/component'\nimport { makeRoundedProps, useRounded } from '@/composables/rounded'\nimport { makeTransitionProps, MaybeTransition } from '@/composables/transition'\n\n// Directives\nimport vIntersect from '@/directives/intersect'\n\n// Utilities\nimport {\n  computed,\n  nextTick,\n  onBeforeMount,\n  onBeforeUnmount,\n  ref,\n  shallowRef,\n  toRef,\n  vShow,\n  watch,\n  withDirectives,\n} from 'vue'\nimport {\n  convertToUnit,\n  filterInputAttrs,\n  genericComponent,\n  getCurrentInstance,\n  propsFactory,\n  SUPPORTS_INTERSECTION,\n  useRender,\n} from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\n// not intended for public use, this is passed in by vuetify-loader\nexport interface srcObject {\n  src?: string\n  srcset?: string\n  lazySrc?: string\n  aspect: number\n}\n\nexport type VImgSlots = {\n  default: never\n  placeholder: never\n  error: never\n  sources: never\n}\n\nexport const makeVImgProps = propsFactory({\n  absolute: Boolean,\n  alt: String,\n  cover: Boolean,\n  color: String,\n  draggable: {\n    type: [Boolean, String] as PropType<boolean | 'true' | 'false'>,\n    default: undefined,\n  },\n  eager: Boolean,\n  gradient: String,\n  imageClass: null,\n  lazySrc: String,\n  options: {\n    type: Object as PropType<IntersectionObserverInit>,\n    // For more information on types, navigate to:\n    // https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API\n    default: () => ({\n      root: undefined,\n      rootMargin: undefined,\n      threshold: undefined,\n    }),\n  },\n  sizes: String,\n  src: {\n    type: [String, Object] as PropType<string | srcObject>,\n    default: '',\n  },\n  crossorigin: String as PropType<'' | 'anonymous' | 'use-credentials'>,\n  referrerpolicy: String as PropType<\n    | 'no-referrer'\n    | 'no-referrer-when-downgrade'\n    | 'origin'\n    | 'origin-when-cross-origin'\n    | 'same-origin'\n    | 'strict-origin'\n    | 'strict-origin-when-cross-origin'\n    | 'unsafe-url'\n  >,\n  srcset: String,\n  position: String,\n\n  ...makeVResponsiveProps(),\n  ...makeComponentProps(),\n  ...makeRoundedProps(),\n  ...makeTransitionProps(),\n}, 'VImg')\n\nexport const VImg = genericComponent<VImgSlots>()({\n  name: 'VImg',\n\n  directives: { vIntersect },\n\n  inheritAttrs: false,\n\n  props: makeVImgProps(),\n\n  emits: {\n    loadstart: (value: string | undefined) => true,\n    load: (value: string | undefined) => true,\n    error: (value: string | undefined) => true,\n  },\n\n  setup (props, { attrs, emit, slots }) {\n    const { backgroundColorClasses, backgroundColorStyles } = useBackgroundColor(() => props.color)\n    const { roundedClasses } = useRounded(props)\n    const vm = getCurrentInstance('VImg')\n\n    const currentSrc = shallowRef('') // Set from srcset\n    const image = ref<HTMLImageElement>()\n    const state = shallowRef<'idle' | 'loading' | 'loaded' | 'error'>(props.eager ? 'loading' : 'idle')\n    const naturalWidth = shallowRef<number>()\n    const naturalHeight = shallowRef<number>()\n\n    const normalisedSrc = computed<srcObject>(() => {\n      return props.src && typeof props.src === 'object'\n        ? {\n          src: props.src.src,\n          srcset: props.srcset || props.src.srcset,\n          lazySrc: props.lazySrc || props.src.lazySrc,\n          aspect: Number(props.aspectRatio || props.src.aspect || 0),\n        } : {\n          src: props.src,\n          srcset: props.srcset,\n          lazySrc: props.lazySrc,\n          aspect: Number(props.aspectRatio || 0),\n        }\n    })\n    const aspectRatio = computed(() => {\n      return normalisedSrc.value.aspect || naturalWidth.value! / naturalHeight.value! || 0\n    })\n\n    watch(() => props.src, () => {\n      init(state.value !== 'idle')\n    })\n    watch(aspectRatio, (val, oldVal) => {\n      if (!val && oldVal && image.value) {\n        pollForSize(image.value)\n      }\n    })\n\n    // TODO: getSrc when window width changes\n\n    onBeforeMount(() => init())\n\n    function init (isIntersecting?: boolean) {\n      if (props.eager && isIntersecting) return\n      if (\n        SUPPORTS_INTERSECTION &&\n        !isIntersecting &&\n        !props.eager\n      ) return\n\n      state.value = 'loading'\n\n      if (normalisedSrc.value.lazySrc) {\n        const lazyImg = new Image()\n        lazyImg.src = normalisedSrc.value.lazySrc\n        pollForSize(lazyImg, null)\n      }\n\n      if (!normalisedSrc.value.src) return\n\n      nextTick(() => {\n        emit('loadstart', image.value?.currentSrc || normalisedSrc.value.src)\n\n        setTimeout(() => {\n          if (vm.isUnmounted) return\n\n          if (image.value?.complete) {\n            if (!image.value.naturalWidth) {\n              onError()\n            }\n\n            if (state.value === 'error') return\n\n            if (!aspectRatio.value) pollForSize(image.value, null)\n            if (state.value === 'loading') onLoad()\n          } else {\n            if (!aspectRatio.value) pollForSize(image.value!)\n            getSrc()\n          }\n        })\n      })\n    }\n\n    function onLoad () {\n      if (vm.isUnmounted) return\n\n      getSrc()\n      pollForSize(image.value!)\n      state.value = 'loaded'\n      emit('load', image.value?.currentSrc || normalisedSrc.value.src)\n    }\n\n    function onError () {\n      if (vm.isUnmounted) return\n\n      state.value = 'error'\n      emit('error', image.value?.currentSrc || normalisedSrc.value.src)\n    }\n\n    function getSrc () {\n      const img = image.value\n      if (img) currentSrc.value = img.currentSrc || img.src\n    }\n\n    let timer = -1\n\n    onBeforeUnmount(() => {\n      clearTimeout(timer)\n    })\n\n    function pollForSize (img: HTMLImageElement, timeout: number | null = 100) {\n      const poll = () => {\n        clearTimeout(timer)\n        if (vm.isUnmounted) return\n\n        const { naturalHeight: imgHeight, naturalWidth: imgWidth } = img\n\n        if (imgHeight || imgWidth) {\n          naturalWidth.value = imgWidth\n          naturalHeight.value = imgHeight\n        } else if (!img.complete && state.value === 'loading' && timeout != null) {\n          timer = window.setTimeout(poll, timeout)\n        } else if (img.currentSrc.endsWith('.svg') || img.currentSrc.startsWith('data:image/svg+xml')) {\n          naturalWidth.value = 1\n          naturalHeight.value = 1\n        }\n      }\n\n      poll()\n    }\n\n    const containClasses = toRef(() => ({\n      'v-img__img--cover': props.cover,\n      'v-img__img--contain': !props.cover,\n    }))\n\n    const __image = () => {\n      if (!normalisedSrc.value.src || state.value === 'idle') return null\n\n      const img = (\n        <img\n          class={['v-img__img', containClasses.value, props.imageClass]}\n          style={{ objectPosition: props.position }}\n          crossorigin={ props.crossorigin }\n          src={ normalisedSrc.value.src }\n          srcset={ normalisedSrc.value.srcset }\n          alt={ props.alt }\n          referrerpolicy={ props.referrerpolicy }\n          draggable={ props.draggable }\n          sizes={ props.sizes }\n          ref={ image }\n          onLoad={ onLoad }\n          onError={ onError }\n        />\n      )\n\n      const sources = slots.sources?.()\n\n      return (\n        <MaybeTransition transition={ props.transition } appear>\n          {\n            withDirectives(\n              sources\n                ? <picture class=\"v-img__picture\">{ sources }{ img }</picture>\n                : img,\n              [[vShow, state.value === 'loaded']]\n            )\n          }\n        </MaybeTransition>\n      )\n    }\n\n    const __preloadImage = () => (\n      <MaybeTransition transition={ props.transition }>\n        { normalisedSrc.value.lazySrc && state.value !== 'loaded' && (\n          <img\n            class={['v-img__img', 'v-img__img--preload', containClasses.value]}\n            style={{ objectPosition: props.position }}\n            crossorigin={ props.crossorigin }\n            src={ normalisedSrc.value.lazySrc }\n            alt={ props.alt }\n            referrerpolicy={ props.referrerpolicy }\n            draggable={ props.draggable }\n          />\n        )}\n      </MaybeTransition>\n    )\n\n    const __placeholder = () => {\n      if (!slots.placeholder) return null\n\n      return (\n        <MaybeTransition transition={ props.transition } appear>\n          { (state.value === 'loading' || (state.value === 'error' && !slots.error)) &&\n          <div class=\"v-img__placeholder\">{ slots.placeholder() }</div>\n          }\n        </MaybeTransition>\n      )\n    }\n\n    const __error = () => {\n      if (!slots.error) return null\n\n      return (\n        <MaybeTransition transition={ props.transition } appear>\n          { state.value === 'error' &&\n            <div class=\"v-img__error\">{ slots.error() }</div>\n          }\n        </MaybeTransition>\n      )\n    }\n\n    const __gradient = () => {\n      if (!props.gradient) return null\n\n      return <div class=\"v-img__gradient\" style={{ backgroundImage: `linear-gradient(${props.gradient})` }} />\n    }\n\n    const isBooted = shallowRef(false)\n    {\n      const stop = watch(aspectRatio, val => {\n        if (val) {\n          // Doesn't work with nextTick, idk why\n          requestAnimationFrame(() => {\n            requestAnimationFrame(() => {\n              isBooted.value = true\n            })\n          })\n          stop()\n        }\n      })\n    }\n\n    useRender(() => {\n      const responsiveProps = VResponsive.filterProps(props)\n      const [rootAttrs, imageAttrs] = filterInputAttrs(attrs)\n\n      return (\n        <VResponsive\n          class={[\n            'v-img',\n            {\n              'v-img--absolute': props.absolute,\n              'v-img--booting': !isBooted.value,\n              'v-img--fit-content': props.width === 'fit-content',\n            },\n            backgroundColorClasses.value,\n            roundedClasses.value,\n            props.class,\n          ]}\n          style={[\n            { width: convertToUnit(props.width === 'auto' ? naturalWidth.value : props.width) },\n            backgroundColorStyles.value,\n            props.style,\n          ]}\n          { ...responsiveProps }\n          { ...rootAttrs }\n          aspectRatio={ aspectRatio.value }\n          aria-label={ props.alt }\n          role={ props.alt ? 'img' : undefined }\n          v-intersect={[{\n            handler: init,\n            options: props.options,\n          }, null, ['once']]}\n        >{{\n          additional: () => (\n            <>\n              <__image { ...imageAttrs } />\n              <__preloadImage />\n              <__gradient />\n              <__placeholder />\n              <__error />\n            </>\n          ),\n          default: slots.default,\n        }}</VResponsive>\n      )\n    })\n\n    return {\n      currentSrc,\n      image,\n      state,\n      naturalWidth,\n      naturalHeight,\n    }\n  },\n})\n\nexport type VImg = InstanceType<typeof VImg>\n"
  },
  {
    "path": "packages/vuetify/src/components/VImg/_variables.scss",
    "content": "@use '../../styles/settings';\n\n// Defaults\n$img-rounded-border-radius: settings.$border-radius-root !default;\n$img-preload-filter: blur(4px) !default;\n$img-card-media-height: 200px !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VImg/index.ts",
    "content": "export { VImg } from './VImg'\n"
  },
  {
    "path": "packages/vuetify/src/components/VInfiniteScroll/VInfiniteScroll.sass",
    "content": "@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-infinite-scroll--horizontal\n    display: flex\n    flex-direction: row\n    overflow-x: auto\n\n    .v-infinite-scroll-intersect\n      height: 100%\n      width: var(--v-infinite-margin-size, 1px)\n\n  .v-infinite-scroll--vertical\n    display: flex\n    flex-direction: column\n    overflow-y: auto\n\n    .v-infinite-scroll-intersect\n      height: 1px\n      width: 100%\n\n  .v-infinite-scroll-intersect\n    overflow: hidden\n    pointer-events: none\n    margin-top: var(--v-infinite-margin)\n    margin-bottom: calc(var(--v-infinite-margin) * -1)\n\n    &:nth-child(2) // TODO: \"1 of &\" would be more stable if structure changes\n      --v-infinite-margin: var(--v-infinite-margin-size, 1px)\n    &:nth-last-child(2)\n      --v-infinite-margin: calc(var(--v-infinite-margin-size, 1px) * -1)\n\n  .v-infinite-scroll__side\n    align-items: center\n    display: flex\n    justify-content: center\n    padding: $infinite-scroll-side-padding\n    transition-property: padding\n    transition-duration: settings.$transition-duration-root\n    transition-timing-function: settings.$standard-easing\n\n    &:empty,\n    &:has(> div:only-child:empty)\n      padding: 0\n"
  },
  {
    "path": "packages/vuetify/src/components/VInfiniteScroll/VInfiniteScroll.tsx",
    "content": "// Styles\nimport './VInfiniteScroll.sass'\n\n// Components\nimport { VBtn } from '@/components/VBtn'\nimport { VProgressCircular } from '@/components/VProgressCircular'\n\n// Composables\nimport { makeDimensionProps, useDimension } from '@/composables/dimensions'\nimport { useIntersectionObserver } from '@/composables/intersectionObserver'\nimport { useLocale } from '@/composables/locale'\nimport { makeTagProps } from '@/composables/tag'\n\n// Utilities\nimport { computed, nextTick, onMounted, ref, shallowRef, watch } from 'vue'\nimport { convertToUnit, defineComponent, genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\nexport type InfiniteScrollSide = 'start' | 'end' | 'both'\nexport type InfiniteScrollStatus = 'ok' | 'empty' | 'loading' | 'error'\n\ntype InfiniteScrollSlot = {\n  side: InfiniteScrollSide\n  props: Record<string, any>\n}\n\ntype VInfiniteScrollSlots = {\n  default: never\n  loading: InfiniteScrollSlot\n  error: InfiniteScrollSlot\n  empty: InfiniteScrollSlot\n  'load-more': InfiniteScrollSlot\n}\n\nexport const makeVInfiniteScrollProps = propsFactory({\n  color: String,\n  direction: {\n    type: String as PropType<'vertical' | 'horizontal'>,\n    default: 'vertical',\n    validator: (v: any) => ['vertical', 'horizontal'].includes(v),\n  },\n  side: {\n    type: String as PropType<InfiniteScrollSide>,\n    default: 'end',\n    validator: (v: any) => ['start', 'end', 'both'].includes(v),\n  },\n  mode: {\n    type: String as PropType<'intersect' | 'manual'>,\n    default: 'intersect',\n    validator: (v: any) => ['intersect', 'manual'].includes(v),\n  },\n  margin: [Number, String],\n  loadMoreText: {\n    type: String,\n    default: '$vuetify.infiniteScroll.loadMore',\n  },\n  emptyText: {\n    type: String,\n    default: '$vuetify.infiniteScroll.empty',\n  },\n\n  ...makeDimensionProps(),\n  ...makeTagProps(),\n}, 'VInfiniteScroll')\n\nexport const VInfiniteScrollIntersect = defineComponent({\n  name: 'VInfiniteScrollIntersect',\n\n  props: {\n    side: {\n      type: String as PropType<InfiniteScrollSide>,\n      required: true,\n    },\n    rootMargin: String,\n  },\n\n  emits: {\n    intersect: (side: InfiniteScrollSide, isIntersecting: boolean) => true,\n  },\n\n  setup (props, { emit }) {\n    const { intersectionRef, isIntersecting } = useIntersectionObserver()\n\n    watch(isIntersecting, async val => {\n      emit('intersect', props.side, val)\n    })\n\n    useRender(() => (\n      <div\n        class=\"v-infinite-scroll-intersect\"\n        style={{\n          '--v-infinite-margin-size': props.rootMargin,\n        }}\n        ref={ intersectionRef }\n      >&nbsp;</div>\n    ))\n\n    return {}\n  },\n})\n\nexport const VInfiniteScroll = genericComponent<VInfiniteScrollSlots>()({\n  name: 'VInfiniteScroll',\n\n  props: makeVInfiniteScrollProps(),\n\n  emits: {\n    load: (options: { side: InfiniteScrollSide, done: (status: InfiniteScrollStatus) => void }) => true,\n  },\n\n  setup (props, { slots, emit }) {\n    const rootEl = ref<HTMLDivElement>()\n    const startStatus = shallowRef<InfiniteScrollStatus>('ok')\n    const endStatus = shallowRef<InfiniteScrollStatus>('ok')\n    const margin = computed(() => convertToUnit(props.margin))\n    const isIntersecting = shallowRef(false)\n\n    function setScrollAmount (amount: number) {\n      if (!rootEl.value) return\n\n      const property = props.direction === 'vertical' ? 'scrollTop' : 'scrollLeft'\n      rootEl.value[property] = amount\n    }\n\n    function getScrollAmount () {\n      if (!rootEl.value) return 0\n\n      const property = props.direction === 'vertical' ? 'scrollTop' : 'scrollLeft'\n      return rootEl.value[property]\n    }\n\n    function getScrollSize () {\n      if (!rootEl.value) return 0\n\n      const property = props.direction === 'vertical' ? 'scrollHeight' : 'scrollWidth'\n      return rootEl.value[property]\n    }\n\n    function getContainerSize () {\n      if (!rootEl.value) return 0\n\n      const property = props.direction === 'vertical' ? 'clientHeight' : 'clientWidth'\n      return rootEl.value[property]\n    }\n\n    onMounted(() => {\n      if (!rootEl.value) return\n\n      if (props.side === 'start') {\n        setScrollAmount(getScrollSize())\n      } else if (props.side === 'both') {\n        setScrollAmount(getScrollSize() / 2 - getContainerSize() / 2)\n      }\n    })\n\n    function setStatus (side: InfiniteScrollSide, status: InfiniteScrollStatus) {\n      if (side === 'start') {\n        startStatus.value = status\n      } else if (side === 'end') {\n        endStatus.value = status\n      } else if (side === 'both') {\n        startStatus.value = status\n        endStatus.value = status\n      }\n    }\n\n    function getStatus (side: string) {\n      return side === 'start' ? startStatus.value : endStatus.value\n    }\n\n    let previousScrollSize = 0\n    function handleIntersect (side: InfiniteScrollSide, _isIntersecting: boolean) {\n      isIntersecting.value = _isIntersecting\n      if (isIntersecting.value) {\n        intersecting(side)\n      }\n    }\n\n    function intersecting (side: InfiniteScrollSide) {\n      if (props.mode !== 'manual' && !isIntersecting.value) return\n\n      const status = getStatus(side)\n      if (!rootEl.value || ['empty', 'loading'].includes(status)) return\n\n      previousScrollSize = getScrollSize()\n      setStatus(side, 'loading')\n\n      function done (status: InfiniteScrollStatus) {\n        setStatus(side, status)\n\n        nextTick(() => {\n          if (status === 'empty' || status === 'error') return\n\n          if (status === 'ok' && side === 'start') {\n            setScrollAmount(getScrollSize() - previousScrollSize + getScrollAmount())\n          }\n          if (props.mode !== 'manual') {\n            nextTick(() => {\n              // Browser takes 2 - 3 animation frames to trigger IntersectionObserver after\n              // VInfiniteScrollIntersect leaves the viewpoint. So far I couldn't come up\n              // with a better solution than using 3 nested window.requestAnimationFrame. (#17475)\n              window.requestAnimationFrame(() => {\n                window.requestAnimationFrame(() => {\n                  window.requestAnimationFrame(() => {\n                    intersecting(side)\n                  })\n                })\n              })\n            })\n          }\n        })\n      }\n\n      emit('load', { side, done })\n    }\n\n    const { t } = useLocale()\n\n    function renderSide (side: InfiniteScrollSide, status: InfiniteScrollStatus) {\n      if (props.side !== side && props.side !== 'both') return\n\n      const onClick = () => intersecting(side)\n      const slotProps = { side, props: { onClick, color: props.color } }\n\n      if (status === 'error') return slots.error?.(slotProps)\n\n      if (status === 'empty') return slots.empty?.(slotProps) ?? <div>{ t(props.emptyText) }</div>\n\n      if (props.mode === 'manual') {\n        if (status === 'loading') {\n          return slots.loading?.(slotProps) ?? (\n            <VProgressCircular indeterminate color={ props.color } />\n          )\n        }\n\n        return slots['load-more']?.(slotProps) ?? (\n          <VBtn variant=\"outlined\" color={ props.color } onClick={ onClick }>\n            { t(props.loadMoreText) }\n          </VBtn>\n        )\n      }\n\n      return slots.loading?.(slotProps) ?? (\n        <VProgressCircular indeterminate color={ props.color } />\n      )\n    }\n\n    const { dimensionStyles } = useDimension(props)\n\n    useRender(() => {\n      const Tag = props.tag\n      const hasStartIntersect = props.side === 'start' || props.side === 'both'\n      const hasEndIntersect = props.side === 'end' || props.side === 'both'\n      const intersectMode = props.mode === 'intersect'\n\n      return (\n        <Tag\n          ref={ rootEl }\n          class={[\n            'v-infinite-scroll',\n            `v-infinite-scroll--${props.direction}`,\n            {\n              'v-infinite-scroll--start': hasStartIntersect,\n              'v-infinite-scroll--end': hasEndIntersect,\n            },\n          ]}\n          style={ dimensionStyles.value }\n        >\n          <div class=\"v-infinite-scroll__side\">\n            { renderSide('start', startStatus.value) }\n          </div>\n\n          { hasStartIntersect && intersectMode && (\n            <VInfiniteScrollIntersect\n              key=\"start\"\n              side=\"start\"\n              onIntersect={ handleIntersect }\n              rootMargin={ margin.value }\n            />\n          )}\n\n          { slots.default?.() }\n\n          { hasEndIntersect && intersectMode && (\n            <VInfiniteScrollIntersect\n              key=\"end\"\n              side=\"end\"\n              onIntersect={ handleIntersect }\n              rootMargin={ margin.value }\n            />\n          )}\n\n          <div class=\"v-infinite-scroll__side\">\n            { renderSide('end', endStatus.value) }\n          </div>\n        </Tag>\n      )\n    })\n\n    function reset (side?: InfiniteScrollSide) {\n      const effectiveSide = side ?? props.side\n      setStatus(effectiveSide, 'ok')\n\n      nextTick(() => {\n        if (effectiveSide !== 'end') {\n          setScrollAmount(\n            getScrollSize() - previousScrollSize + getScrollAmount(),\n          )\n        }\n        if (props.mode !== 'manual') {\n          nextTick(() => {\n            // See #17475\n            window.requestAnimationFrame(() => {\n              window.requestAnimationFrame(() => {\n                window.requestAnimationFrame(() => {\n                  if (effectiveSide === 'both') {\n                    intersecting('start')\n                    intersecting('end')\n                  } else {\n                    intersecting(effectiveSide)\n                  }\n                })\n              })\n            })\n          })\n        }\n      })\n    }\n\n    return { reset }\n  },\n})\n\nexport type VInfiniteScroll = InstanceType<typeof VInfiniteScroll>\n"
  },
  {
    "path": "packages/vuetify/src/components/VInfiniteScroll/__tests__/VInfiniteScroll.spec.browser.tsx",
    "content": "// Components\nimport { VInfiniteScroll } from '../VInfiniteScroll'\n\n// Utilities\nimport { page, render, screen, scroll, wait } from '@test'\nimport { ref } from 'vue'\nimport { createRange } from '@/util'\n\ndescribe('VInfiniteScroll', () => {\n  it('should call load function when scrolled', async () => {\n    const onLoad = vi.fn()\n    const items = createRange(50)\n\n    render(() => (\n      <VInfiniteScroll height=\"400\" onLoad={ onLoad }>\n        { items.map(item => (\n          <div class=\"pa-2\">{ item }</div>\n        ))}\n      </VInfiniteScroll>\n    ))\n\n    const container = screen.getByCSS('.v-infinite-scroll')\n\n    await scroll({ top: container.scrollHeight }, container)\n    expect(screen.queryAllByCSS('.v-infinite-scroll .v-progress-circular')).toHaveLength(1)\n    expect(onLoad).toHaveBeenCalledOnce()\n  })\n\n  it('should work when using start side', async () => {\n    const onLoad = vi.fn()\n    const items = createRange(50)\n\n    render(() => (\n      <VInfiniteScroll height=\"400\" onLoad={ onLoad } side=\"start\">\n        { items.map(item => (\n          <div class=\"pa-2\">{ item }</div>\n        ))}\n      </VInfiniteScroll>\n    ))\n\n    const container = screen.getByCSS('.v-infinite-scroll')\n\n    await scroll({ top: 0 }, container)\n    expect(screen.queryAllByCSS('.v-infinite-scroll .v-progress-circular')).toHaveLength(1)\n    expect(onLoad).toHaveBeenCalledOnce()\n  })\n\n  it('should work when using both sides', async () => {\n    const onLoad = vi.fn()\n    const items = createRange(50)\n\n    render(() => (\n      <VInfiniteScroll height=\"400\" onLoad={ onLoad } side=\"both\">\n        { items.map(item => (\n          <div class=\"pa-2\">{ item }</div>\n        ))}\n      </VInfiniteScroll>\n    ))\n\n    const container = screen.getByCSS('.v-infinite-scroll')\n\n    await scroll({ top: 0 }, container)\n    expect(screen.queryAllByCSS('.v-infinite-scroll .v-progress-circular')[0]).toBeVisible()\n    expect(onLoad).toHaveBeenCalledTimes(1)\n\n    await scroll({ top: container.scrollHeight }, container)\n    expect(screen.queryAllByCSS('.v-infinite-scroll .v-progress-circular')[1]).toBeVisible()\n    expect(onLoad).toHaveBeenCalledTimes(2)\n  })\n\n  it('should support horizontal direction', async () => {\n    const onLoad = vi.fn()\n    const items = createRange(50)\n\n    render(() => (\n      <VInfiniteScroll onLoad={ onLoad } direction=\"horizontal\">\n        { items.map(item => (\n          <div class=\"pa-2\">{ item }</div>\n        ))}\n      </VInfiniteScroll>\n    ))\n    const container = screen.getByCSS('.v-infinite-scroll')\n\n    await scroll({ left: container.scrollWidth }, container)\n    expect(screen.queryAllByCSS('.v-infinite-scroll .v-progress-circular')).toHaveLength(1)\n    expect(onLoad).toHaveBeenCalledOnce()\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/17358\n  it('should keep triggering load logic until VInfiniteScrollIntersect disappears', async () => {\n    await page.viewport(400, 200)\n\n    const onLoad = vi.fn()\n    const items = ref(Array.from({ length: 3 }, (k, v) => v + 1))\n\n    const load = async ({ done }: any) => {\n      onLoad()\n      setTimeout(() => {\n        items.value.push(...Array.from({ length: 3 }, (k, v) => v + items.value.at(-1)! + 1))\n        done('ok')\n      }, 100)\n    }\n\n    render(() => (\n      <VInfiniteScroll onLoad={ load } mode=\"intersect\">\n        { items.value.map(item => (\n          <div>Item #{ item }</div>\n        ))}\n      </VInfiniteScroll>\n    ))\n\n    expect(screen.queryAllByCSS('.v-infinite-scroll .v-progress-circular')).toHaveLength(1)\n    await wait(300)\n    expect(onLoad).toHaveBeenCalledTimes(2)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VInfiniteScroll/_variables.scss",
    "content": "@use '../../styles/settings';\n\n$infinite-scroll-side-padding: 8px !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VInfiniteScroll/index.ts",
    "content": "export { VInfiniteScroll } from './VInfiniteScroll'\n"
  },
  {
    "path": "packages/vuetify/src/components/VInput/InputIcon.tsx",
    "content": "// Components\nimport { VIcon } from '@/components/VIcon'\n\n// Composables\nimport { useLocale } from '@/composables/locale'\n\n// Utilities\nimport { callEvent } from '@/util'\n\n// Types\nimport type { IconValue } from '@/composables/icons'\nimport type { EventProp } from '@/util'\n\ntype names = 'clear' | 'prepend' | 'append' | 'appendInner' | 'prependInner'\n\ntype InputIconProps<T extends names> = {\n  label: string | undefined\n} & {\n  [K in `${T}Icon`]: IconValue | undefined\n} & {\n  [K in `onClick:${T}`]: EventProp | undefined\n}\n\ntype Listeners<T extends {}, U = keyof T> = U extends `onClick:${infer V extends names}` ? V : never\n\nexport function useInputIcon<T extends {}, K extends names = Listeners<T>> (props: T & InputIconProps<K>) {\n  const { t } = useLocale()\n\n  function InputIcon ({ name, color, ...attrs }: { name: Extract<names, K>, color?: string }) {\n    const localeKey = {\n      prepend: 'prependAction',\n      prependInner: 'prependAction',\n      append: 'appendAction',\n      appendInner: 'appendAction',\n      clear: 'clear',\n    }[name]\n    const listener = props[`onClick:${name}`] as EventProp | undefined\n\n    function onKeydown (e: KeyboardEvent) {\n      if (e.key !== 'Enter' && e.key !== ' ') return\n\n      e.preventDefault()\n      e.stopPropagation()\n      callEvent(listener, new PointerEvent('click', e))\n    }\n\n    const label = listener && localeKey\n      ? t(`$vuetify.input.${localeKey}`, props.label ?? '')\n      : undefined\n\n    return (\n      <VIcon\n        icon={ props[`${name}Icon`] }\n        aria-label={ label }\n        onClick={ listener }\n        onKeydown={ onKeydown }\n        color={ color }\n        { ...attrs }\n      />\n    )\n  }\n\n  return { InputIcon }\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VInput/VInput.sass",
    "content": "@use 'sass:math'\n@use 'sass:selector'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-input\n    display: grid\n    flex: $input-flex\n    font-size: $input-font-size\n    font-weight: $input-font-weight\n    line-height: $input-line-height\n\n    &--disabled\n      pointer-events: none\n\n    &--indent-details\n      .v-input__details\n        padding-inline: $input-details-padding-inline\n\n    @at-root\n      @include tools.density('v-input', $input-density) using ($modifier)\n        --v-input-control-height: #{$input-control-height + $modifier}\n        --v-input-padding-top: #{16px + $modifier * .5}\n\n  .v-input--vertical\n    grid-template-areas: \"append\" \"control\" \"prepend\"\n    grid-template-rows: max-content auto max-content\n    grid-template-columns: min-content\n\n    .v-input__prepend\n      margin-block-start: $input-affix-margin-inside\n\n    .v-input__append\n      margin-block-end: $input-affix-margin-inside\n\n  .v-input--horizontal\n    grid-template-areas: \"prepend control append\" \"a messages b\"\n    grid-template-columns: max-content minmax(0, 1fr) max-content\n    grid-template-rows: 1fr auto\n\n    .v-input__prepend\n      margin-inline-end: $input-affix-margin-inside\n\n    .v-input__append\n      margin-inline-start: $input-affix-margin-inside\n\n  .v-input__details\n    align-items: flex-end\n    display: flex\n    font-size: $input-details-font-size\n    font-weight: $input-details-font-weight\n    grid-area: messages\n    letter-spacing: $input-details-letter-spacing\n    line-height: $input-details-line-height\n    min-height: $input-details-min-height\n    padding-top: $input-details-padding-above\n    overflow: hidden\n    justify-content: space-between\n\n  .v-input__details,\n  .v-input__prepend,\n  .v-input__append\n    > .v-icon\n      opacity: var(--v-medium-emphasis-opacity)\n\n    .v-input--disabled &,\n    .v-input--error &\n      > .v-icon,\n      .v-messages\n        opacity: 1\n\n    .v-input--glow.v-input--focused &\n      > .v-icon\n        opacity: 1\n\n    .v-input--disabled &\n      opacity: var(--v-disabled-opacity)\n\n    .v-input--error:not(.v-input--disabled) &\n      > .v-icon,\n      .v-messages\n        color: rgb(var(--v-theme-error))\n\n  .v-input__prepend,\n  .v-input__append\n    display: flex\n    align-items: flex-start\n    padding-top: var(--v-input-padding-top)\n\n    .v-input--center-affix &\n      align-items: center\n      padding-top: 0\n\n  .v-input__prepend\n    grid-area: prepend\n\n  .v-input__append\n    grid-area: append\n\n  .v-input__control\n    display: flex\n    grid-area: control\n\n  .v-input\n    &--hide-spin-buttons\n      input::-webkit-outer-spin-button,\n      input::-webkit-inner-spin-button\n        -webkit-appearance: none\n        margin: 0\n      input[type=number]\n        -moz-appearance: textfield\n\n    &--plain-underlined\n\n      .v-input__prepend,\n      .v-input__append\n        $this: &\n        align-items: flex-start\n\n        @at-root\n          @include tools.density('v-input', $input-density) using ($modifier)\n            @at-root #{selector.append(&, $this)}\n              padding-top: calc(var(--v-input-padding-top) + #{math.max(0px, 4px + $modifier * .25)})\n"
  },
  {
    "path": "packages/vuetify/src/components/VInput/VInput.tsx",
    "content": "// Styles\nimport './VInput.sass'\n\n// Components\nimport { useInputIcon } from '@/components/VInput/InputIcon'\nimport { VMessages } from '@/components/VMessages/VMessages'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { makeDensityProps, useDensity } from '@/composables/density'\nimport { makeDimensionProps, useDimension } from '@/composables/dimensions'\nimport { IconValue } from '@/composables/icons'\nimport { useRtl } from '@/composables/locale'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\nimport { makeValidationProps, useValidation } from '@/composables/validation'\n\n// Utilities\nimport { computed, toRef, useId } from 'vue'\nimport { EventProp, genericComponent, pick, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { ComputedRef, PropType, Ref } from 'vue'\nimport type { VMessageSlot } from '@/components/VMessages/VMessages'\nimport type { GenericProps } from '@/util'\n\nexport interface VInputSlot {\n  id: ComputedRef<string>\n  messagesId: ComputedRef<string | undefined>\n  isDirty: ComputedRef<boolean>\n  isDisabled: ComputedRef<boolean>\n  isReadonly: ComputedRef<boolean>\n  isPristine: Ref<boolean>\n  isValid: ComputedRef<boolean | null>\n  isValidating: Ref<boolean>\n  hasDetails: Ref<boolean>\n  reset: () => void\n  resetValidation: () => void\n  validate: () => void\n}\n\nexport const makeVInputProps = propsFactory({\n  id: String,\n  appendIcon: IconValue,\n  baseColor: String,\n  centerAffix: {\n    type: Boolean,\n    default: true,\n  },\n  color: String,\n  glow: Boolean,\n  iconColor: [Boolean, String],\n  prependIcon: IconValue,\n  hideDetails: [Boolean, String] as PropType<boolean | 'auto'>,\n  hideSpinButtons: Boolean,\n  hint: String,\n  indentDetails: {\n    type: Boolean,\n    default: null,\n  },\n  persistentHint: Boolean,\n  messages: {\n    type: [Array, String] as PropType<string | readonly string[]>,\n    default: () => ([]),\n  },\n  direction: {\n    type: String as PropType<'horizontal' | 'vertical'>,\n    default: 'horizontal',\n    validator: (v: any) => ['horizontal', 'vertical'].includes(v),\n  },\n\n  'onClick:prepend': EventProp<[MouseEvent]>(),\n  'onClick:append': EventProp<[MouseEvent]>(),\n\n  ...makeComponentProps(),\n  ...makeDensityProps(),\n  ...pick(makeDimensionProps(), [\n    'maxWidth',\n    'minWidth',\n    'width',\n  ]),\n  ...makeThemeProps(),\n  ...makeValidationProps(),\n}, 'VInput')\n\nexport type VInputSlots = {\n  default: VInputSlot\n  prepend: VInputSlot\n  append: VInputSlot\n  details: VInputSlot\n  message: VMessageSlot\n}\n\nexport const VInput = genericComponent<new <T>(\n  props: {\n    modelValue?: T | null\n    'onUpdate:modelValue'?: (value: T | null) => void\n  },\n  slots: VInputSlots,\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VInput',\n\n  props: {\n    ...makeVInputProps(),\n  },\n\n  emits: {\n    'update:modelValue': (value: any) => true,\n  },\n\n  setup (props, { attrs, slots, emit }) {\n    const { densityClasses } = useDensity(props)\n    const { dimensionStyles } = useDimension(props)\n    const { themeClasses } = provideTheme(props)\n    const { rtlClasses } = useRtl()\n    const { InputIcon } = useInputIcon(props)\n\n    const uid = useId()\n    const id = computed(() => props.id || `input-${uid}`)\n\n    const {\n      errorMessages,\n      isDirty,\n      isDisabled,\n      isReadonly,\n      isPristine,\n      isValid,\n      isValidating,\n      reset,\n      resetValidation,\n      validate,\n      validationClasses,\n    } = useValidation(props, 'v-input', id)\n\n    const messages = computed(() => {\n      if (props.errorMessages?.length || (!isPristine.value && errorMessages.value.length)) {\n        return errorMessages.value\n      } else if (props.hint && (props.persistentHint || props.focused)) {\n        return props.hint\n      } else {\n        return props.messages\n      }\n    })\n\n    const hasMessages = toRef(() => messages.value.length > 0)\n\n    const hasDetails = toRef(() => !props.hideDetails || (\n      props.hideDetails === 'auto' &&\n      (hasMessages.value || !!slots.details)\n    ))\n\n    const messagesId = computed(() => hasDetails.value ? `${id.value}-messages` : undefined)\n\n    const slotProps = computed<VInputSlot>(() => ({\n      id,\n      messagesId,\n      isDirty,\n      isDisabled,\n      isReadonly,\n      isPristine,\n      isValid,\n      isValidating,\n      hasDetails,\n      reset,\n      resetValidation,\n      validate,\n    }))\n\n    const color = toRef(() => {\n      return props.error || props.disabled ? undefined\n        : props.focused ? props.color\n        : props.baseColor\n    })\n\n    const iconColor = toRef(() => {\n      if (!props.iconColor) return undefined\n\n      return props.iconColor === true ? color.value : props.iconColor\n    })\n\n    useRender(() => {\n      const hasPrepend = !!(slots.prepend || props.prependIcon)\n      const hasAppend = !!(slots.append || props.appendIcon)\n\n      return (\n        <div\n          class={[\n            'v-input',\n            `v-input--${props.direction}`,\n            {\n              'v-input--center-affix': props.centerAffix,\n              'v-input--focused': props.focused,\n              'v-input--glow': props.glow,\n              'v-input--hide-spin-buttons': props.hideSpinButtons,\n              'v-input--indent-details': props.indentDetails,\n            },\n            densityClasses.value,\n            themeClasses.value,\n            rtlClasses.value,\n            validationClasses.value,\n            props.class,\n          ]}\n          style={[\n            dimensionStyles.value,\n            props.style,\n          ]}\n        >\n          { hasPrepend && (\n            <div key=\"prepend\" class=\"v-input__prepend\">\n              { slots.prepend\n                ? slots.prepend(slotProps.value)\n                : (props.prependIcon && (\n                  <InputIcon\n                    key=\"prepend-icon\"\n                    name=\"prepend\"\n                    color={ iconColor.value }\n                  />\n                ))\n              }\n            </div>\n          )}\n\n          { slots.default && (\n            <div class=\"v-input__control\">\n              { slots.default?.(slotProps.value) }\n            </div>\n          )}\n\n          { hasAppend && (\n            <div key=\"append\" class=\"v-input__append\">\n              { slots.append\n                ? slots.append(slotProps.value)\n                : (props.appendIcon && (\n                  <InputIcon\n                    key=\"append-icon\"\n                    name=\"append\"\n                    color={ iconColor.value }\n                  />\n                ))\n              }\n            </div>\n          )}\n\n          { hasDetails.value && (\n            <div\n              id={ messagesId.value }\n              class=\"v-input__details\"\n              role=\"alert\"\n              aria-live=\"polite\"\n            >\n              <VMessages\n                active={ hasMessages.value }\n                messages={ messages.value }\n                v-slots={{ message: slots.message }}\n              />\n\n              { slots.details?.(slotProps.value) }\n            </div>\n          )}\n        </div>\n      )\n    })\n\n    return {\n      reset,\n      resetValidation,\n      validate,\n      isValid,\n      errorMessages,\n    }\n  },\n})\n\nexport type VInput = InstanceType<typeof VInput>\n"
  },
  {
    "path": "packages/vuetify/src/components/VInput/__tests__/VInput.spec.browser.tsx",
    "content": "// Components\nimport { VInput } from '../VInput'\n\n// Utilities\nimport { showcase } from '@test'\nimport { cloneVNode } from 'vue'\n\nconst densities = ['default', 'comfortable', 'compact']\n\nconst stories = Object.fromEntries(Object.entries({\n  Default: <VInput />,\n  Disabled: <VInput disabled />,\n  PrependAppend: <VInput prependIcon=\"$vuetify\" appendIcon=\"$vuetify\" />,\n  Hint: <VInput hint=\"hint\" persistentHint />,\n  Messages: <VInput messages=\"messages\" />,\n}).map(([k, v]) => [k, (\n  <div class=\"d-flex flex-column flex-grow-1\">\n    { densities.map(density => (\n      <div class=\"d-flex\" style=\"gap: 0.4rem\">\n        { cloneVNode(v, { density }) }\n        { cloneVNode(v, { density, modelValue: 'Value' }) }\n      </div>\n    ))}\n  </div>\n)]))\n\ndescribe('VInput', () => {\n  showcase({ stories })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VInput/_variables.scss",
    "content": "@use 'sass:map';\n@use '../../styles/settings';\n@use '../../styles/tools';\n\n// CONTROL\n$input-density: ('default': 0, 'comfortable': -2, 'compact': -4) !default;\n$input-control-height: 56px !default;\n$input-flex: 1 1 auto !default;\n$input-font-size: tools.map-deep-get(settings.$typography, 'body-large', 'size') !default;\n$input-font-weight: tools.map-deep-get(settings.$typography, 'body-large', 'weight') !default;\n$input-line-height: 1.5 !default;\n\n// CHIPS\n$input-chips-margin-top: null !default;\n$input-chips-margin-bottom: null !default;\n\n// DETAILS\n$input-details-font-size: .75rem !default;\n$input-details-font-weight: 400 !default;\n$input-details-letter-spacing: .0333333333em !default;\n$input-details-line-height: normal !default;\n$input-details-min-height: 22px !default;\n$input-details-padding-above: 6px !default;\n$input-details-padding-inline: 16px !default;\n$input-details-transition: 150ms settings.$standard-easing !default;\n\n// AFFIXES\n$input-affix-margin-inside: 16px !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VInput/index.ts",
    "content": "export { VInput } from './VInput'\n"
  },
  {
    "path": "packages/vuetify/src/components/VItemGroup/VItem.tsx",
    "content": "// Composables\nimport { VItemGroupSymbol } from './VItemGroup'\nimport { makeGroupItemProps, useGroupItem } from '@/composables/group'\n\n// Utilities\nimport { genericComponent } from '@/util'\n\ntype VItemSlots = {\n  default: {\n    isSelected: boolean | undefined\n    selectedClass: boolean | (string | undefined)[] | undefined\n    select: ((value: boolean) => void) | undefined\n    toggle: (() => void) | undefined\n    value: unknown\n    disabled: boolean | undefined\n  }\n}\n\nexport const VItem = genericComponent<VItemSlots>()({\n  name: 'VItem',\n\n  props: makeGroupItemProps(),\n\n  emits: {\n    'group:selected': (val: { value: boolean }) => true,\n  },\n\n  setup (props, { slots }) {\n    const { isSelected, select, toggle, selectedClass, value, disabled } = useGroupItem(props, VItemGroupSymbol)\n    return () => slots.default?.({\n      isSelected: isSelected.value,\n      selectedClass: selectedClass.value,\n      select,\n      toggle,\n      value: value.value,\n      disabled: disabled.value,\n    })\n  },\n})\n\nexport type VItem = InstanceType<typeof VItem>\n"
  },
  {
    "path": "packages/vuetify/src/components/VItemGroup/VItemGroup.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-item-group\n    flex: 0 1 auto\n    max-width: 100%\n    position: relative\n    transition: $item-group-transition\n"
  },
  {
    "path": "packages/vuetify/src/components/VItemGroup/VItemGroup.tsx",
    "content": "// Styles\nimport './VItemGroup.sass'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { makeGroupProps, useGroup } from '@/composables/group'\nimport { makeTagProps } from '@/composables/tag'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\n\n// Utilities\nimport { genericComponent, propsFactory } from '@/util'\n\n// Types\nimport type { GenericProps } from '@/util'\n\nexport const VItemGroupSymbol = Symbol.for('vuetify:v-item-group')\n\nexport const makeVItemGroupProps = propsFactory({\n  ...makeComponentProps(),\n  ...makeGroupProps({\n    selectedClass: 'v-item--selected',\n  }),\n  ...makeTagProps(),\n  ...makeThemeProps(),\n}, 'VItemGroup')\n\ntype VItemGroupSlots = {\n  default: {\n    isSelected: (id: string) => boolean\n    select: (id: string, value: boolean) => void\n    next: () => void\n    prev: () => void\n    selected: readonly string[]\n  }\n}\n\nexport const VItemGroup = genericComponent<new <T>(\n  props: {\n    modelValue?: T\n    'onUpdate:modelValue'?: (value: T) => void\n  },\n  slots: VItemGroupSlots,\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VItemGroup',\n\n  props: makeVItemGroupProps(),\n\n  emits: {\n    'update:modelValue': (value: any) => true,\n  },\n\n  setup (props, { slots }) {\n    const { themeClasses } = provideTheme(props)\n    const { isSelected, select, next, prev, selected } = useGroup(props, VItemGroupSymbol)\n\n    return () => (\n      <props.tag\n        class={[\n          'v-item-group',\n          themeClasses.value,\n          props.class,\n        ]}\n        style={ props.style }\n      >\n        { slots.default?.({\n          isSelected,\n          select,\n          next,\n          prev,\n          selected: selected.value,\n        })}\n      </props.tag>\n    )\n  },\n})\n\nexport type VItemGroup = InstanceType<typeof VItemGroup>\n"
  },
  {
    "path": "packages/vuetify/src/components/VItemGroup/__tests__/VItemGroup.spec.browser.tsx",
    "content": "// Components\nimport { VItem, VItemGroup } from '..'\nimport { VCard } from '@/components/VCard'\n\n// Utilities\nimport { render, screen, userEvent } from '@test'\n\ndescribe('VItemGroup', () => {\n  // https://github.com/vuetifyjs/vuetify/issues/14754\n  it('should apply selected-class from both group and item', async () => {\n    render(() => (\n      <VItemGroup selectedClass=\"font-weight-bold\" class=\"d-flex text-center justify-center\">\n        <VItem value=\"foo\" selectedClass=\"bg-blue\">\n          {{\n            default: props => <VCard width=\"100\" class={ props.selectedClass } onClick={ props.toggle }>Foo</VCard>,\n          }}\n        </VItem>\n        <VItem value=\"bar\" selectedClass=\"bg-orange\">\n          {{\n            default: props => <VCard width=\"100\" class={ props.selectedClass } onClick={ props.toggle }>Bar</VCard>,\n          }}\n        </VItem>\n      </VItemGroup>\n    ))\n\n    const cards = screen.getAllByCSS('.v-card')\n\n    await userEvent.click(cards[0])\n    expect(cards[0]).toHaveClass('bg-blue', 'font-weight-bold')\n\n    await userEvent.click(cards[1])\n    expect(cards[1]).toHaveClass('bg-orange', 'font-weight-bold')\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VItemGroup/__tests__/VItemGroup.spec.ts",
    "content": "// Components\nimport { VItem } from '../VItem'\nimport { VItemGroup } from '../VItemGroup'\n\n// Utilities\nimport { mount } from '@vue/test-utils'\nimport { h } from 'vue'\nimport { createVuetify } from '@/framework'\n\ndescribe('VItemGroup', () => {\n  const vuetify = createVuetify()\n  const mountFunction = (options = {}) => {\n    return mount(VItemGroup, {\n      ...options,\n      global: {\n        plugins: [vuetify],\n      },\n    })\n  }\n\n  const defaultSlot = () => [\n    h(VItem, { value: 'foo' }, {\n      default: ({ toggle }: any) => h('div', { id: 'item', onClick: toggle }, ['foo']),\n    }),\n    h(VItem, { value: 'bar' }, {\n      default: ({ toggle }: any) => h('div', { id: 'item', onClick: toggle }, ['bar']),\n    }),\n  ]\n\n  it('should update state from child clicks', async () => {\n    const wrapper = mountFunction({\n      slots: {\n        default: defaultSlot,\n      },\n    })\n\n    const items = wrapper.findAll('#item')\n\n    await items[0].trigger('click')\n    await items[1].trigger('click')\n\n    const events = wrapper.emitted('update:modelValue')\n\n    expect(events).toEqual([['foo'], ['bar']])\n  })\n\n  it('should not deselect value when using mandatory prop', async () => {\n    const wrapper = mountFunction({\n      props: {\n        mandatory: true,\n        modelValue: 'foo',\n      },\n      slots: {\n        default: defaultSlot,\n      },\n    })\n\n    const items = wrapper.findAll('#item')\n\n    await items[0].trigger('click')\n\n    const events = wrapper.emitted('update:modelValue')\n\n    expect(events).toBeUndefined()\n  })\n\n  it('should update a multiple item group', async () => {\n    const wrapper = mountFunction({\n      props: {\n        multiple: true,\n        modelValue: ['foo'],\n      },\n      slots: {\n        default: defaultSlot,\n      },\n    })\n\n    const items = wrapper.findAll('#item')\n\n    await items[0].trigger('click')\n    await items[1].trigger('click')\n\n    const events = wrapper.emitted('update:modelValue')\n\n    expect(events).toEqual([\n      [[]],\n      [['bar']],\n    ])\n  })\n\n  it('should ignore disabled items', async () => {\n    const wrapper = mountFunction({\n      props: {\n        multiple: true,\n      },\n      slots: {\n        default: () => [\n          h(VItem, { value: 'foo', disabled: true }, {\n            default: ({ toggle }: any) => h('div', { id: 'item', onClick: toggle }, ['foo']),\n          }),\n          h(VItem, { value: 'bar' }, {\n            default: ({ toggle }: any) => h('div', { id: 'item', onClick: toggle }, ['bar']),\n          }),\n        ],\n      },\n    })\n\n    const items = wrapper.findAll('#item')\n\n    await items[0].trigger('click')\n    await items[1].trigger('click')\n\n    const events = wrapper.emitted('update:modelValue')\n\n    expect(events).toEqual([\n      [['bar']],\n    ])\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/5384\n  it('should not unregister children when is destroyed', async () => {\n    const change = vi.fn()\n    const wrapper = mountFunction({\n      props: {\n        modelValue: 'foo',\n        'onUpdate:modelValue': change,\n      },\n      slots: {\n        default: () => h(VItem, { value: 'foo' }, () => ['foo']),\n      },\n    })\n\n    wrapper.unmount()\n\n    expect(change).not.toHaveBeenCalled()\n  })\n\n  it('should render with a specified tag when the tag prop is provided with a value', () => {\n    const wrapper = mountFunction({\n      props: {\n        tag: 'button',\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VItemGroup/__tests__/__snapshots__/VItemGroup.spec.ts.snap",
    "content": "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html\n\nexports[`VItemGroup > should render with a specified tag when the tag prop is provided with a value 1`] = `\n\"<button class=\"v-item-group v-theme--light\">\n  <!---->\n</button>\"\n`;\n"
  },
  {
    "path": "packages/vuetify/src/components/VItemGroup/_variables.scss",
    "content": "@use '../../styles/settings';\n\n// Defaults\n$item-group-transition: 0.2s settings.$standard-easing !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VItemGroup/index.ts",
    "content": "export { VItemGroup } from './VItemGroup'\nexport { VItem } from './VItem'\n"
  },
  {
    "path": "packages/vuetify/src/components/VKbd/VKbd.scss",
    "content": "@use '../../styles/tools';\n@use './variables' as *;\n\n@include tools.layer('components') {\n  .v-kbd {\n    font-family: $kbd-font-family;\n    align-items: center;\n    align-self: stretch;\n    background: rgb(var(--v-theme-kbd));\n    color: rgb(var(--v-theme-on-kbd));\n    display: $kbd-display;\n    font-size: $kbd-font-size;\n    font-weight: $kbd-font-weight;\n    line-height: $kbd-line-height;\n    justify-content: center;\n    min-height: $kbd-min-height;\n    min-width: $kbd-min-width;\n    padding: $kbd-padding;\n    vertical-align: baseline;\n    margin-inline: $kbd-margin-inline;\n\n    @include tools.border($kbd-border...);\n    @include tools.elevation($kbd-elevation);\n    @include tools.rounded($kbd-border-radius);\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VKbd/VKbd.tsx",
    "content": "// Styles\nimport './VKbd.scss'\n\n// Composables\nimport { makeBorderProps, useBorder } from '@/composables/border'\nimport { useBackgroundColor } from '@/composables/color'\nimport { makeComponentProps } from '@/composables/component'\nimport { makeElevationProps, useElevation } from '@/composables/elevation'\nimport { makeRoundedProps, useRounded } from '@/composables/rounded'\nimport { makeTagProps } from '@/composables/tag'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\n\n// Utilities\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\nexport const makeVKbdProps = propsFactory({\n  color: String,\n\n  ...makeBorderProps(),\n  ...makeComponentProps(),\n  ...makeRoundedProps(),\n  ...makeTagProps({ tag: 'kbd' }),\n  ...makeThemeProps(),\n  ...makeElevationProps(),\n}, 'VKbd')\n\nexport const VKbd = genericComponent()({\n  name: 'VKbd',\n\n  props: makeVKbdProps(),\n\n  setup (props, { slots }) {\n    const { themeClasses } = provideTheme(props)\n    const { borderClasses } = useBorder(props)\n    const { roundedClasses } = useRounded(props)\n    const { backgroundColorClasses, backgroundColorStyles } = useBackgroundColor(() => props.color)\n    const { elevationClasses } = useElevation(props)\n\n    useRender(() => (\n      <props.tag\n        class={[\n          'v-kbd',\n          themeClasses.value,\n          backgroundColorClasses.value,\n          borderClasses.value,\n          elevationClasses.value,\n          roundedClasses.value,\n          props.class,\n        ]}\n        style={[\n          backgroundColorStyles.value,\n          props.style,\n        ]}\n        v-slots={ slots }\n      />\n    ))\n\n    return {}\n  },\n})\n\nexport type VKbd = InstanceType<typeof VKbd>\n"
  },
  {
    "path": "packages/vuetify/src/components/VKbd/_variables.scss",
    "content": "@use '../../styles/settings';\n\n// VKbd\n// Kbd elements naturally use monospace fonts, if users want to change this, they can do so by setting the font-family on the v-kbd element.\n$kbd-font-family: settings.$body-font-family !default;\n$kbd-border-radius: 4px !default;\n$kbd-display: inline-flex !default;\n$kbd-elevation: 1 !default;\n// Kbd elements are used inline with text, so we should use the same font size as the text it's with.\n$kbd-font-size: 0.875em !default;\n$kbd-font-weight: normal !default;\n$kbd-line-height: 1 !default;\n$kbd-padding: 3px 6px !default;;\n$kbd-min-height: 1em !default;\n$kbd-min-width: 20px !default;\n$kbd-margin-inline: 1px !default;\n$kbd-border-color: rgba(var(--v-border-color), var(--v-border-opacity)) !default;\n$kbd-border-style: solid !default;\n$kbd-border-width: thin !default;\n$kbd-border-thin-width: thin !default;\n$kbd-border: (\n  $kbd-border-color,\n  $kbd-border-style,\n  $kbd-border-width,\n  $kbd-border-thin-width\n) !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VKbd/index.ts",
    "content": "// Styles\nimport './VKbd.scss'\n\nexport { VKbd } from './VKbd'\n"
  },
  {
    "path": "packages/vuetify/src/components/VLabel/VLabel.sass",
    "content": "@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-label\n    align-items: center\n    color: $label-color\n    display: $label-display\n    font-size: $label-font-size\n    letter-spacing: $label-letter-spacing\n    min-width: 0\n    opacity: $label-opacity\n    overflow: hidden\n    text-overflow: ellipsis\n    white-space: nowrap\n\n  .v-label--clickable\n    cursor: pointer\n"
  },
  {
    "path": "packages/vuetify/src/components/VLabel/VLabel.tsx",
    "content": "// Styles\nimport './VLabel.sass'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { makeThemeProps } from '@/composables/theme'\n\n// Utilities\nimport { EventProp, genericComponent, propsFactory, useRender } from '@/util'\n\nexport const makeVLabelProps = propsFactory({\n  text: String,\n\n  onClick: EventProp<[MouseEvent]>(),\n\n  ...makeComponentProps(),\n  ...makeThemeProps(),\n}, 'VLabel')\n\nexport const VLabel = genericComponent()({\n  name: 'VLabel',\n\n  props: makeVLabelProps(),\n\n  setup (props, { slots }) {\n    useRender(() => (\n      <label\n        class={[\n          'v-label',\n          {\n            'v-label--clickable': !!props.onClick,\n          },\n          props.class,\n        ]}\n        style={ props.style }\n        onClick={ props.onClick }\n      >\n        { props.text }\n\n        { slots.default?.() }\n      </label>\n    ))\n\n    return {}\n  },\n})\n\nexport type VLabel = InstanceType<typeof VLabel>\n"
  },
  {
    "path": "packages/vuetify/src/components/VLabel/_variables.scss",
    "content": "@use '../../styles/settings';\n@use '../../styles/tools';\n\n// VLabel\n$label-color: inherit !default;\n$label-disabled-color: tools.theme-color('on-surface', var(--v-disabled-opacity)) !default;\n$label-display: inline-flex !default;\n$label-error-color: rgb(var(--v-theme-error)) !default;\n$label-font-size: 1rem !default;\n$label-letter-spacing: .009375em !default;\n$label-opacity: var(--v-medium-emphasis-opacity) !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VLabel/index.ts",
    "content": "export { VLabel } from './VLabel'\n"
  },
  {
    "path": "packages/vuetify/src/components/VLayout/VLayout.sass",
    "content": "@use '../../styles/tools'\n\n@include tools.layer('components')\n  .v-layout\n    --v-scrollbar-offset: 0px\n    display: flex\n    flex: 1 1 auto\n\n    &--full-height\n      --v-scrollbar-offset: inherit\n      height: 100%\n"
  },
  {
    "path": "packages/vuetify/src/components/VLayout/VLayout.tsx",
    "content": "// Styles\nimport './VLayout.sass'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { makeDimensionProps, useDimension } from '@/composables/dimensions'\nimport { createLayout, makeLayoutProps } from '@/composables/layout'\n\n// Utilities\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\nexport const makeVLayoutProps = propsFactory({\n  ...makeComponentProps(),\n  ...makeDimensionProps(),\n  ...makeLayoutProps(),\n}, 'VLayout')\n\nexport const VLayout = genericComponent()({\n  name: 'VLayout',\n\n  props: makeVLayoutProps(),\n\n  setup (props, { slots }) {\n    const { layoutClasses, layoutStyles, getLayoutItem, items, layoutRef } = createLayout(props)\n    const { dimensionStyles } = useDimension(props)\n\n    useRender(() => (\n      <div\n        ref={ layoutRef }\n        class={[\n          layoutClasses.value,\n          props.class,\n        ]}\n        style={[\n          dimensionStyles.value,\n          layoutStyles.value,\n          props.style,\n        ]}\n      >\n        { slots.default?.() }\n      </div>\n    ))\n\n    return {\n      getLayoutItem,\n      items,\n    }\n  },\n})\n\nexport type VLayout = InstanceType<typeof VLayout>\n"
  },
  {
    "path": "packages/vuetify/src/components/VLayout/VLayoutItem.sass",
    "content": "@use '../../styles/settings'\n@use '../../styles/tools'\n\n@include tools.layer('components')\n  .v-layout-item\n    position: absolute\n    transition: 0.2s settings.$standard-easing\n\n  .v-layout-item--absolute\n    position: absolute\n"
  },
  {
    "path": "packages/vuetify/src/components/VLayout/VLayoutItem.tsx",
    "content": "// Styles\nimport './VLayoutItem.sass'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { makeLayoutItemProps, useLayoutItem } from '@/composables/layout'\n\n// Utilities\nimport { computed, toRef } from 'vue'\nimport { genericComponent, propsFactory } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\nexport const makeVLayoutItemProps = propsFactory({\n  position: {\n    type: String as PropType<'top' | 'right' | 'bottom' | 'left'>,\n    required: true,\n  },\n  size: {\n    type: [Number, String],\n    default: 300,\n  },\n  modelValue: Boolean,\n\n  ...makeComponentProps(),\n  ...makeLayoutItemProps(),\n}, 'VLayoutItem')\n\nexport const VLayoutItem = genericComponent()({\n  name: 'VLayoutItem',\n\n  props: makeVLayoutItemProps(),\n\n  setup (props, { slots }) {\n    const { layoutItemStyles } = useLayoutItem({\n      id: props.name,\n      order: computed(() => parseInt(props.order, 10)),\n      position: toRef(() => props.position),\n      elementSize: toRef(() => props.size),\n      layoutSize: toRef(() => props.size),\n      active: toRef(() => props.modelValue),\n      absolute: toRef(() => props.absolute),\n    })\n\n    return () => (\n      <div\n        class={[\n          'v-layout-item',\n          props.class,\n        ]}\n        style={[\n          layoutItemStyles.value,\n          props.style,\n        ]}\n      >\n        { slots.default?.() }\n      </div>\n    )\n  },\n})\n\nexport type VLayoutItem = InstanceType<typeof VLayoutItem>\n"
  },
  {
    "path": "packages/vuetify/src/components/VLayout/__tests__/VLayout.spec.cy.tsx",
    "content": "/// <reference types=\"../../../../types/cypress\" />\n\n// Components\nimport { VLayout } from '../VLayout'\nimport { VAppBar } from '@/components/VAppBar'\nimport { VMain } from '@/components/VMain'\nimport { VNavigationDrawer } from '@/components/VNavigationDrawer'\n\n// Utilities\nimport { createRange } from '@/util'\n\ndescribe('VLayout', () => {\n  it('should position main component', () => {\n    cy.mount(() => (\n      <VLayout>\n        <VAppBar height=\"64\"></VAppBar>\n        <VNavigationDrawer width=\"200\" permanent></VNavigationDrawer>\n        <VMain>\n          hello world\n        </VMain>\n      </VLayout>\n    ))\n\n    cy.get('.v-main').should('have.css', 'padding-top', '64px')\n    cy.get('.v-main').should('have.css', 'padding-left', '200px')\n  })\n\n  it('should work with sticky elements', () => {\n    cy.mount(() => (\n      <VLayout>\n        <VAppBar height=\"64\"></VAppBar>\n        <VNavigationDrawer width=\"200\" permanent></VNavigationDrawer>\n        <VMain>\n          <div>\n            { createRange(10).map(_ => <div>hello</div>) }\n            <nav style=\"position: sticky; top: var(--v-layout-top); background: grey\">Sticky Header</nav>\n            { createRange(100).map(_ => <div>hello</div>) }\n          </div>\n        </VMain>\n      </VLayout>\n    ))\n\n    cy.get('html').scrollTo(0, 1000)\n      .get('nav').should('be.visible')\n  })\n\n  it.only('should work with scrollable main', () => {\n    cy.mount(() => (\n      <VLayout>\n        <VAppBar height=\"64\"></VAppBar>\n        <VNavigationDrawer width=\"200\" permanent></VNavigationDrawer>\n        <VMain scrollable>\n          <div>\n            { createRange(10).map(_ => <div>hello</div>) }\n            <nav style=\"position: sticky; top: 0px; background: grey\">Sticky Header</nav>\n            { createRange(100).map(_ => <div>hello</div>) }\n          </div>\n        </VMain>\n      </VLayout>\n    ))\n\n    cy.get('.v-main__scroller').scrollTo(0, 1000)\n      .get('nav').should('be.visible')\n  })\n\n  it('should work when nested inside another layout', () => {\n    cy.mount(({ drawer }: any) => (\n      <VLayout>\n        <VAppBar height=\"64\"></VAppBar>\n        <VNavigationDrawer width=\"200\" permanent></VNavigationDrawer>\n        <VMain>\n          <VLayout class=\"ma-10\" style=\"height: 600px\" id=\"nested\">\n            <VAppBar height=\"64\" color=\"primary\"></VAppBar>\n            <VNavigationDrawer width=\"200\" modelValue={ drawer } permanent color=\"primary\"></VNavigationDrawer>\n            <VMain>\n              Nested\n            </VMain>\n          </VLayout>\n        </VMain>\n      </VLayout>\n    ))\n\n    cy.get('#nested .v-navigation-drawer').should('not.be.visible')\n      .setProps({ drawer: true })\n      .get('#nested .v-navigation-drawer').should('be.visible')\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VLayout/index.ts",
    "content": "export { VLayout } from './VLayout'\nexport { VLayoutItem } from './VLayoutItem'\n"
  },
  {
    "path": "packages/vuetify/src/components/VLazy/VLazy.tsx",
    "content": "// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { makeDimensionProps, useDimension } from '@/composables/dimensions'\nimport { useProxiedModel } from '@/composables/proxiedModel'\nimport { makeTagProps } from '@/composables/tag'\nimport { makeTransitionProps, MaybeTransition } from '@/composables/transition'\n\n// Directives\nimport vIntersect from '@/directives/intersect'\n\n// Utilities\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\nexport const makeVLazyProps = propsFactory({\n  modelValue: Boolean,\n  options: {\n    type: Object as PropType<IntersectionObserverInit>,\n    // For more information on types, navigate to:\n    // https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API\n    default: () => ({\n      root: undefined,\n      rootMargin: undefined,\n      threshold: undefined,\n    }),\n  },\n\n  ...makeComponentProps(),\n  ...makeDimensionProps(),\n  ...makeTagProps(),\n  ...makeTransitionProps({ transition: 'fade-transition' }),\n}, 'VLazy')\n\nexport const VLazy = genericComponent()({\n  name: 'VLazy',\n\n  directives: { vIntersect },\n\n  props: makeVLazyProps(),\n\n  emits: {\n    'update:modelValue': (value: boolean) => true,\n  },\n\n  setup (props, { slots }) {\n    const { dimensionStyles } = useDimension(props)\n\n    const isActive = useProxiedModel(props, 'modelValue')\n\n    function onIntersect (isIntersecting: boolean) {\n      if (isActive.value) return\n\n      isActive.value = isIntersecting\n    }\n\n    useRender(() => (\n      <props.tag\n        class={[\n          'v-lazy',\n          props.class,\n        ]}\n        v-intersect={[\n          {\n            handler: onIntersect,\n            options: props.options,\n          },\n          null,\n          isActive.value ? [] : ['once'],\n        ]}\n        style={[\n          dimensionStyles.value,\n          props.style,\n        ]}\n      >\n        { isActive.value && (\n          <MaybeTransition transition={ props.transition } appear>\n            { slots.default?.() }\n          </MaybeTransition>\n        )}\n      </props.tag>\n    ))\n\n    return {}\n  },\n})\n\nexport type VLazy = InstanceType<typeof VLazy>\n"
  },
  {
    "path": "packages/vuetify/src/components/VLazy/index.ts",
    "content": "export { VLazy } from './VLazy'\n"
  },
  {
    "path": "packages/vuetify/src/components/VList/VList.sass",
    "content": "@use 'sass:list'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-list\n    overflow: auto\n    padding: $list-padding\n    position: relative\n    outline: none\n\n    @include tools.border($list-border...)\n    @include tools.elevation($list-elevation)\n    @include tools.rounded($list-border-radius)\n    @include tools.theme($list-theme...)\n\n    &--disabled\n      pointer-events: none\n      user-select: none\n\n    &--nav\n      padding-inline: $list-nav-padding\n\n      .v-list-item:not(:first-child),\n      .v-list-group:not(:first-child) > .v-list-item,\n      .v-list-group__items > .v-list-item,\n      .v-list-group__items > .v-list-group\n        margin-top: $list-item-nav-margin-top\n\n    &--rounded\n      @include tools.rounded($list-rounded-border-radius)\n\n    &--subheader\n      padding-top: $list-subheader-padding-top\n\n  .v-list-img\n    border-radius: inherit\n    display: flex\n    height: 100%\n    left: 0\n    overflow: hidden\n    position: absolute\n    top: 0\n    width: 100%\n    z-index: -1\n\n  .v-list-subheader\n    $root: &\n\n    align-items: center\n    background: inherit\n    color: $list-subheader-color\n    display: flex\n    font-size: $list-subheader-font-size\n    font-weight: $list-subheader-font-weight\n    line-height: $list-subheader-line-height\n    padding-inline-end: $list-subheader-padding-end\n    min-height: $list-subheader-min-height\n    transition: $list-subheader-transition\n\n    &__text\n      overflow: hidden\n      text-overflow: ellipsis\n      white-space: nowrap\n\n    @at-root\n      @include tools.density('v-list', $list-density) using ($modifier)\n        $base-padding: list.nth($list-item-padding, 2)\n\n        #{$root}\n          min-height: $list-subheader-min-height + ($modifier * $list-subheader-min-height-multiplier)\n          padding-inline-start: calc(#{$base-padding} + var(--indent-padding))\n\n    &--inset\n      --indent-padding: #{$list-subheader-inset-padding-start}\n\n    .v-list--nav &\n      font-size: $list-nav-subheader-font-size\n\n    &--sticky\n      background: inherit\n      left: 0\n      position: sticky\n      top: 0\n      z-index: 1\n\n  .v-list__overlay\n    background-color: currentColor\n    border-radius: inherit\n    bottom: 0\n    left: 0\n    opacity: 0\n    pointer-events: none\n    position: absolute\n    right: 0\n    top: 0\n    transition: opacity 0.2s ease-in-out\n"
  },
  {
    "path": "packages/vuetify/src/components/VList/VList.tsx",
    "content": "// Styles\nimport './VList.sass'\n\n// Components\nimport { VListChildren } from './VListChildren'\n\n// Composables\nimport { createList } from './list'\nimport { makeBorderProps, useBorder } from '@/composables/border'\nimport { useBackgroundColor } from '@/composables/color'\nimport { makeComponentProps } from '@/composables/component'\nimport { provideDefaults } from '@/composables/defaults'\nimport { makeDensityProps, useDensity } from '@/composables/density'\nimport { makeDimensionProps, useDimension } from '@/composables/dimensions'\nimport { makeElevationProps, useElevation } from '@/composables/elevation'\nimport { IconValue } from '@/composables/icons'\nimport { makeItemsProps } from '@/composables/list-items'\nimport { makeNestedProps, useNested } from '@/composables/nested/nested'\nimport { useProxiedModel } from '@/composables/proxiedModel'\nimport { makeRoundedProps, useRounded } from '@/composables/rounded'\nimport { makeTagProps } from '@/composables/tag'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\nimport { makeVariantProps } from '@/composables/variant'\n\n// Utilities\nimport { computed, ref, shallowRef, toRef, useId, watch } from 'vue'\nimport {\n  convertToUnit,\n  EventProp,\n  focusChild,\n  genericComponent,\n  getPropertyFromItem,\n  isPrimitive,\n  omit,\n  propsFactory,\n  useRender,\n} from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { VListChildrenSlots } from './VListChildren'\nimport type { ItemProps, ListItem } from '@/composables/list-items'\nimport type { GenericProps, SelectItemKey } from '@/util'\n\nexport interface InternalListItem<T = any> extends ListItem<T> {}\n\nconst itemTypes = new Set(['item', 'divider', 'subheader'])\n\nfunction transformItem (props: ItemProps, item: any): ListItem {\n  const title = isPrimitive(item) ? item : getPropertyFromItem(item, props.itemTitle)\n  const value = isPrimitive(item) ? item : getPropertyFromItem(item, props.itemValue, undefined)\n  const children = getPropertyFromItem(item, props.itemChildren)\n  const itemProps = props.itemProps === true\n    ? omit(item, ['children'])\n    : getPropertyFromItem(item, props.itemProps)\n\n  let type = getPropertyFromItem(item, props.itemType, 'item')\n  if (!itemTypes.has(type)) {\n    type = 'item'\n  }\n\n  const _props = {\n    title,\n    value,\n    ...itemProps,\n  }\n\n  return {\n    type,\n    title: _props.title,\n    value: _props.value,\n    props: _props,\n    children: type === 'item' && children ? transformItems(props, children) : undefined,\n    raw: item,\n  }\n}\n\nfunction transformItems (props: ItemProps, items: (string | object)[]) {\n  const array: InternalListItem[] = []\n\n  for (const item of items) {\n    array.push(transformItem(props, item))\n  }\n\n  return array\n}\n\nexport function useListItems (props: ItemProps) {\n  const items = computed(() => transformItems(props, props.items))\n\n  return { items }\n}\n\nexport const makeVListProps = propsFactory({\n  baseColor: String,\n  /* @deprecated */\n  activeColor: String,\n  activeClass: String,\n  bgColor: String,\n  disabled: Boolean,\n  filterable: Boolean,\n  expandIcon: IconValue,\n  collapseIcon: IconValue,\n  lines: {\n    type: [Boolean, String] as PropType<'one' | 'two' | 'three' | false>,\n    default: 'one',\n  },\n  slim: Boolean,\n  prependGap: [Number, String],\n  indent: [Number, String],\n  nav: Boolean,\n  navigationStrategy: {\n    type: String as PropType<'focus' | 'track'>,\n    default: 'focus',\n  },\n  navigationIndex: Number,\n\n  'onClick:open': EventProp<[{ id: unknown, value: boolean, path: unknown[] }]>(),\n  'onClick:select': EventProp<[{ id: unknown, value: boolean, path: unknown[] }]>(),\n  'onUpdate:opened': EventProp<[unknown]>(),\n  ...makeNestedProps({\n    selectStrategy: 'single-leaf' as const,\n    openStrategy: 'list' as const,\n  }),\n  ...makeBorderProps(),\n  ...makeComponentProps(),\n  ...makeDensityProps(),\n  ...makeDimensionProps(),\n  ...makeElevationProps(),\n  ...makeItemsProps(),\n  ...makeRoundedProps(),\n  ...makeTagProps(),\n  ...makeThemeProps(),\n  ...makeVariantProps({ variant: 'text' } as const),\n}, 'VList')\n\ntype ItemType<T> = T extends readonly (infer U)[] ? U : never\n\nexport const VList = genericComponent<new <S, A, O, T extends readonly any[]>(\n  props: {\n    items?: T\n    itemTitle?: SelectItemKey<ItemType<T>>\n    itemValue?: SelectItemKey<ItemType<T>>\n    itemChildren?: SelectItemKey<ItemType<T>>\n    itemProps?: SelectItemKey<ItemType<T>>\n    selected?: S\n    activated?: A\n    opened?: O\n    'onUpdate:selected'?: (value: S) => void\n    'onUpdate:activated'?: (value: A) => void\n    'onUpdate:opened'?: (value: O) => void\n    'onClick:open'?: (value: { id: unknown, value: boolean, path: unknown[] }) => void\n    'onClick:select'?: (value: { id: unknown, value: boolean, path: unknown[] }) => void\n  },\n  slots: VListChildrenSlots<ItemType<T>>\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VList',\n\n  props: makeVListProps(),\n\n  emits: {\n    'update:selected': (value: unknown) => true,\n    'update:activated': (value: unknown) => true,\n    'update:opened': (value: unknown) => true,\n    'update:navigationIndex': (value: number) => true,\n    'click:open': (value: { id: unknown, value: boolean, path: unknown[] }) => true,\n    'click:activate': (value: { id: unknown, value: boolean, path: unknown[] }) => true,\n    'click:select': (value: { id: unknown, value: boolean, path: unknown[] }) => true,\n  },\n\n  setup (props, { attrs, slots, emit }) {\n    const { items } = useListItems(props)\n    const { themeClasses } = provideTheme(props)\n    const { backgroundColorClasses, backgroundColorStyles } = useBackgroundColor(() => props.bgColor)\n    const { borderClasses } = useBorder(props)\n    const { densityClasses } = useDensity(props)\n    const { dimensionStyles } = useDimension(props)\n    const { elevationClasses } = useElevation(props)\n    const { roundedClasses } = useRounded(props)\n\n    const { children, open, parents, select, getPath } = useNested(props, {\n      items,\n      returnObject: toRef(() => props.returnObject),\n      scrollToActive: toRef(() => props.navigationStrategy === 'track'),\n    })\n\n    const lineClasses = toRef(() => props.lines ? `v-list--${props.lines}-line` : undefined)\n    const activeColor = toRef(() => props.activeColor)\n    const baseColor = toRef(() => props.baseColor)\n    const color = toRef(() => props.color)\n    const isSelectable = toRef(() => (props.selectable || props.activatable))\n\n    const navigationIndex = useProxiedModel(\n      props,\n      'navigationIndex',\n      -1,\n      v => v ?? -1\n    )\n\n    const uid = useId()\n\n    createList({\n      filterable: props.filterable,\n      trackingIndex: navigationIndex,\n      navigationStrategy: toRef(() => props.navigationStrategy),\n      uid,\n    })\n\n    watch(items, () => {\n      if (props.navigationStrategy === 'track') {\n        navigationIndex.value = -1\n      }\n    })\n\n    provideDefaults({\n      VListGroup: {\n        activeColor,\n        baseColor,\n        color,\n        expandIcon: toRef(() => props.expandIcon),\n        collapseIcon: toRef(() => props.collapseIcon),\n      },\n      VListItem: {\n        activeClass: toRef(() => props.activeClass),\n        activeColor,\n        baseColor,\n        color,\n        density: toRef(() => props.density),\n        disabled: toRef(() => props.disabled),\n        lines: toRef(() => props.lines),\n        nav: toRef(() => props.nav),\n        slim: toRef(() => props.slim),\n        variant: toRef(() => props.variant),\n        tabindex: toRef(() => props.navigationStrategy === 'track' ? -1 : undefined),\n      },\n    })\n\n    const isFocused = shallowRef(false)\n    const contentRef = ref<HTMLElement>()\n\n    function onFocusin (e: FocusEvent) {\n      isFocused.value = true\n    }\n\n    function onFocusout (e: FocusEvent) {\n      isFocused.value = false\n    }\n\n    function onFocus (e: FocusEvent) {\n      if (props.navigationStrategy === 'track') {\n        if (!~navigationIndex.value) {\n          navigationIndex.value = getNextIndex('first')\n        }\n      } else if (\n        !isFocused.value &&\n        !(e.relatedTarget && contentRef.value?.contains(e.relatedTarget as Node))\n      ) focus()\n    }\n\n    function onBlur () {\n      if (props.navigationStrategy === 'track') {\n        navigationIndex.value = -1\n      }\n    }\n\n    function getNavigationDirection (key: string): 'next' | 'prev' | 'first' | 'last' | null {\n      switch (key) {\n        case 'ArrowDown': return 'next'\n        case 'ArrowUp': return 'prev'\n        case 'Home': return 'first'\n        case 'End': return 'last'\n        default: return null\n      }\n    }\n\n    function getNextIndex (direction: 'next' | 'prev' | 'first' | 'last'): number {\n      const itemCount = items.value.length\n      if (itemCount === 0) return -1\n\n      let nextIndex: number\n\n      if (direction === 'first') {\n        nextIndex = 0\n      } else if (direction === 'last') {\n        nextIndex = itemCount - 1\n      } else {\n        nextIndex = navigationIndex.value + (direction === 'next' ? 1 : -1)\n\n        if (nextIndex < 0) nextIndex = itemCount - 1\n        if (nextIndex >= itemCount) nextIndex = 0\n      }\n\n      const startIndex = nextIndex\n      let attempts = 0\n      while (attempts < itemCount) {\n        const item = items.value[nextIndex]\n        if (item && item.type !== 'divider' && item.type !== 'subheader') {\n          return nextIndex\n        }\n        nextIndex += direction === 'next' || direction === 'first' ? 1 : -1\n        if (nextIndex < 0) nextIndex = itemCount - 1\n        if (nextIndex >= itemCount) nextIndex = 0\n        if (nextIndex === startIndex) return -1\n        attempts++\n      }\n\n      return -1\n    }\n\n    function onKeydown (e: KeyboardEvent) {\n      const target = e.target as HTMLElement\n\n      if (!contentRef.value ||\n        (target.tagName === 'INPUT' && ['Home', 'End'].includes(e.key)) ||\n        target.tagName === 'TEXTAREA') {\n        return\n      }\n\n      const direction = getNavigationDirection(e.key)\n\n      if (direction !== null) {\n        e.preventDefault()\n        if (props.navigationStrategy === 'track') {\n          const nextIndex = getNextIndex(direction)\n          if (nextIndex !== -1) {\n            navigationIndex.value = nextIndex\n          }\n        } else {\n          focus(direction)\n        }\n      }\n    }\n\n    function onMousedown (e: MouseEvent) {\n      isFocused.value = true\n    }\n\n    function focus (location?: 'next' | 'prev' | 'first' | 'last' | number) {\n      if (contentRef.value) {\n        return focusChild(contentRef.value, location)\n      }\n    }\n\n    useRender(() => {\n      const indent = props.indent ??\n        (props.prependGap\n          ? Number(props.prependGap) + 24\n          : undefined)\n\n      const ariaMultiselectable = isSelectable.value\n        ? attrs.ariaMultiselectable ?? !String(props.selectStrategy).startsWith('single-')\n        : undefined\n\n      return (\n        <props.tag\n          ref={ contentRef }\n          class={[\n            'v-list',\n            {\n              'v-list--disabled': props.disabled,\n              'v-list--nav': props.nav,\n              'v-list--slim': props.slim,\n            },\n            themeClasses.value,\n            backgroundColorClasses.value,\n            borderClasses.value,\n            densityClasses.value,\n            elevationClasses.value,\n            lineClasses.value,\n            roundedClasses.value,\n            props.class,\n          ]}\n          style={[\n            {\n              '--v-list-indent': convertToUnit(indent),\n              '--v-list-group-prepend': indent ? '0px' : undefined,\n              '--v-list-prepend-gap': convertToUnit(props.prependGap),\n            },\n            backgroundColorStyles.value,\n            dimensionStyles.value,\n            props.style,\n          ]}\n          tabindex={ props.disabled ? -1 : 0 }\n          role={ isSelectable.value ? 'listbox' : 'list' }\n          aria-activedescendant={\n            props.navigationStrategy === 'track' && navigationIndex.value >= 0\n              ? `v-list-item-${uid}-${navigationIndex.value}`\n              : undefined\n          }\n          aria-multiselectable={ ariaMultiselectable }\n          onFocusin={ onFocusin }\n          onFocusout={ onFocusout }\n          onFocus={ onFocus }\n          onBlur={ onBlur }\n          onKeydown={ onKeydown }\n          onMousedown={ onMousedown }\n        >\n          <VListChildren\n            items={ items.value }\n            returnObject={ props.returnObject }\n            v-slots={ slots }\n          />\n        </props.tag>\n      )\n    })\n\n    return {\n      open,\n      select,\n      focus,\n      children,\n      parents,\n      getPath,\n      navigationIndex,\n    }\n  },\n})\n\nexport type VList = InstanceType<typeof VList>\n"
  },
  {
    "path": "packages/vuetify/src/components/VList/VListChildren.tsx",
    "content": "// Components\nimport { VListGroup } from './VListGroup'\nimport { VListItem } from './VListItem'\nimport { VListSubheader } from './VListSubheader'\nimport { VDivider } from '@/components/VDivider'\n\n// Utilities\nimport { mergeProps } from 'vue'\nimport { createList } from './list'\nimport { genericComponent, propsFactory } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { InternalListItem } from './VList'\nimport type { VListItemSlots } from './VListItem'\nimport type { GenericProps } from '@/util'\n\nexport type VListChildrenSlots<T> = {\n  [K in keyof Omit<VListItemSlots, 'default'>]: VListItemSlots[K] & { item: T }\n} & {\n  default: never\n  item: { props: InternalListItem['props'] & { index: number } }\n  divider: { props: InternalListItem['props'] }\n  subheader: { props: InternalListItem['props'] }\n  header: { props: InternalListItem['props'] }\n}\n\nexport const makeVListChildrenProps = propsFactory({\n  items: Array as PropType<readonly InternalListItem[]>,\n  returnObject: Boolean,\n}, 'VListChildren')\n\nexport const VListChildren = genericComponent<new <T extends InternalListItem>(\n  props: {\n    items?: readonly T[]\n    returnObject?: boolean\n  },\n  slots: VListChildrenSlots<T>\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VListChildren',\n\n  props: makeVListChildrenProps(),\n\n  setup (props, { slots }) {\n    createList()\n\n    return () => slots.default?.() ?? props.items?.map(({ children, props: itemProps, type, raw: item }, index) => {\n      if (type === 'divider') {\n        return slots.divider?.({ props: itemProps }) ?? (\n          <VDivider { ...itemProps } />\n        )\n      }\n\n      if (type === 'subheader') {\n        return slots.subheader?.({ props: itemProps }) ?? (\n          <VListSubheader { ...itemProps } />\n        )\n      }\n\n      const slotsWithItem = {\n        subtitle: slots.subtitle ? (slotProps: any) => slots.subtitle?.({ ...slotProps, item }) : undefined,\n        prepend: slots.prepend ? (slotProps: any) => slots.prepend?.({ ...slotProps, item }) : undefined,\n        append: slots.append ? (slotProps: any) => slots.append?.({ ...slotProps, item }) : undefined,\n        title: slots.title ? (slotProps: any) => slots.title?.({ ...slotProps, item }) : undefined,\n      }\n\n      const listGroupProps = VListGroup.filterProps(itemProps)\n\n      return children ? (\n        <VListGroup\n          { ...listGroupProps }\n          value={ props.returnObject ? item : itemProps?.value }\n          rawId={ itemProps?.value }\n        >\n          {{\n            activator: ({ props: activatorProps }) => {\n              const listItemProps = mergeProps(\n                itemProps,\n                activatorProps,\n                { value: props.returnObject ? item : itemProps.value }\n              ) as typeof itemProps\n\n              return slots.header\n                ? slots.header({ props: listItemProps })\n                : (\n                  <VListItem { ...listItemProps } index={ index } v-slots={ slotsWithItem } />\n                )\n            },\n            default: () => (\n              <VListChildren\n                items={ children }\n                returnObject={ props.returnObject }\n                v-slots={ slots }\n              />\n            ),\n          }}\n        </VListGroup>\n      ) : (\n        slots.item ? slots.item({ props: { ...itemProps, index } }) : (\n          <VListItem\n            { ...itemProps }\n            index={ index }\n            value={ props.returnObject ? item : itemProps.value }\n            v-slots={ slotsWithItem }\n          />\n        )\n      )\n    })\n  },\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VList/VListGroup.tsx",
    "content": "// Components\nimport { VExpandTransition } from '@/components/transitions'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\n\n// Composables\nimport { useList } from './list'\nimport { makeComponentProps } from '@/composables/component'\nimport { IconValue } from '@/composables/icons'\nimport { useNestedGroupActivator, useNestedItem, VNestedSymbol } from '@/composables/nested/nested'\nimport { useSsrBoot } from '@/composables/ssrBoot'\nimport { makeTagProps } from '@/composables/tag'\nimport { MaybeTransition } from '@/composables/transition'\n\n// Utilities\nimport { computed, inject, toRef } from 'vue'\nimport { defineComponent, genericComponent, propsFactory, useRender } from '@/util'\n\nexport type VListGroupSlots = {\n  default: never\n  activator: { isOpen: boolean, props: Record<string, unknown> }\n}\n\nconst VListGroupActivator = defineComponent({\n  name: 'VListGroupActivator',\n\n  setup (_, { slots }) {\n    useNestedGroupActivator()\n\n    return () => slots.default?.()\n  },\n})\n\nexport const makeVListGroupProps = propsFactory({\n  /* @deprecated */\n  activeColor: String,\n  baseColor: String,\n  color: String,\n  collapseIcon: {\n    type: IconValue,\n    default: '$collapse',\n  },\n  disabled: Boolean,\n  expandIcon: {\n    type: IconValue,\n    default: '$expand',\n  },\n  rawId: [String, Number],\n  prependIcon: IconValue,\n  appendIcon: IconValue,\n  fluid: Boolean,\n  subgroup: Boolean,\n  title: String,\n  value: null,\n\n  ...makeComponentProps(),\n  ...makeTagProps(),\n}, 'VListGroup')\n\nexport const VListGroup = genericComponent<VListGroupSlots>()({\n  name: 'VListGroup',\n\n  props: makeVListGroupProps(),\n\n  setup (props, { slots }) {\n    const { isOpen, open, id: _id } = useNestedItem(() => props.value, () => props.disabled, true)\n    const id = computed(() => `v-list-group--id-${String(props.rawId ?? _id.value)}`)\n    const list = useList()\n    const { isBooted } = useSsrBoot()\n\n    const parent = inject(VNestedSymbol)\n    const renderWhenClosed = toRef(() => parent?.root?.itemsRegistration.value === 'render')\n\n    function onClick (e: Event) {\n      if (['INPUT', 'TEXTAREA'].includes((e.target as Element)?.tagName)) return\n      open(!isOpen.value, e)\n    }\n\n    const activatorProps = computed(() => ({\n      onClick,\n      class: 'v-list-group__header',\n      id: id.value,\n    }))\n\n    const toggleIcon = computed(() => isOpen.value ? props.collapseIcon : props.expandIcon)\n    const activatorDefaults = computed(() => ({\n      VListItem: {\n        activeColor: props.activeColor,\n        baseColor: props.baseColor,\n        color: props.color,\n        prependIcon: props.prependIcon || (props.subgroup && toggleIcon.value),\n        appendIcon: props.appendIcon || (!props.subgroup && toggleIcon.value),\n        title: props.title,\n        value: props.value,\n      },\n    }))\n\n    useRender(() => (\n      <props.tag\n        class={[\n          'v-list-group',\n          {\n            'v-list-group--prepend': list?.hasPrepend.value,\n            'v-list-group--fluid': props.fluid,\n            'v-list-group--subgroup': props.subgroup,\n            'v-list-group--open': isOpen.value,\n          },\n          props.class,\n        ]}\n        style={ props.style }\n      >\n        { slots.activator && (\n          <VDefaultsProvider defaults={ activatorDefaults.value }>\n            <VListGroupActivator>\n              { slots.activator({ props: activatorProps.value, isOpen: isOpen.value }) }\n            </VListGroupActivator>\n          </VDefaultsProvider>\n        )}\n\n        <MaybeTransition transition={{ component: VExpandTransition }} disabled={ !isBooted.value }>\n          { renderWhenClosed.value\n            ? (\n            <div class=\"v-list-group__items\" role=\"group\" aria-labelledby={ id.value } v-show={ isOpen.value }>\n              { slots.default?.() }\n            </div>\n            ) : isOpen.value && (\n            <div class=\"v-list-group__items\" role=\"group\" aria-labelledby={ id.value }>\n              { slots.default?.() }\n            </div>\n            )}\n        </MaybeTransition>\n      </props.tag>\n    ))\n\n    return {\n      isOpen,\n    }\n  },\n})\n\nexport type VListGroup = InstanceType<typeof VListGroup>\n"
  },
  {
    "path": "packages/vuetify/src/components/VList/VListImg.ts",
    "content": "// Utilities\nimport { createSimpleFunctional } from '@/util'\n\nexport const VListImg = createSimpleFunctional('v-list-img')\n\nexport type VListImg = InstanceType<typeof VListImg>\n"
  },
  {
    "path": "packages/vuetify/src/components/VList/VListItem.sass",
    "content": "@use 'sass:list'\n@use 'sass:map'\n@use 'sass:math'\n@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-list-item\n    align-items: center\n    display: grid\n    flex: none\n    grid-template-areas: \"prepend content append\"\n    grid-template-columns: max-content 1fr auto\n    outline: none\n    max-width: 100%\n    padding: $list-item-padding\n    position: relative\n    text-decoration: none\n\n    @include tools.border($list-item-border...)\n    @include tools.states('.v-list-item__overlay')\n    @include tools.rounded($list-item-border-radius)\n    @include tools.variant($list-item-variants...)\n\n    &--focus-visible\n      .v-list-item__overlay\n        opacity: calc(#{map.get(settings.$states, 'focus')} * var(--v-theme-overlay-multiplier))\n\n    @supports selector(:focus-visible)\n      &::after\n        pointer-events: none\n        border: 2px solid currentColor\n        border-radius: 4px\n        opacity: 0\n        transition: opacity .2s ease-in-out\n        @include tools.absolute(true)\n\n      &:focus-visible::after,\n      &--focus-visible::after\n        opacity: calc(.15 * var(--v-theme-overlay-multiplier))\n\n    &__prepend,\n    &__append\n      > .v-badge .v-icon,\n      > .v-icon\n        opacity: #{$list-item-icon-opacity}\n\n    &--active\n      .v-list-item__prepend,\n      .v-list-item__append\n        > .v-badge .v-icon,\n        > .v-icon\n          opacity: #{$list-item-icon-active-opacity}\n\n      &:not(.v-list-item--link)\n        .v-list-item__overlay\n          opacity: calc(#{map.get(settings.$states, 'activated')} * var(--v-theme-overlay-multiplier))\n\n    &--rounded\n      @include tools.rounded($list-item-rounded-border-radius)\n\n    &--disabled\n      pointer-events: none\n      user-select: none\n      opacity: $list-disabled-opacity\n\n    &--link\n      cursor: pointer\n\n    .v-navigation-drawer--rail:not(.v-navigation-drawer--expand-on-hover) &,\n    .v-navigation-drawer--rail.v-navigation-drawer--expand-on-hover:not(.v-navigation-drawer--is-hovering) &\n      .v-avatar\n        --v-avatar-height: 24px\n\n  .v-list-item__prepend\n    align-items: center\n    align-self: center\n    display: flex\n    grid-area: prepend\n\n    * ~ .v-list-item__spacer\n      width: var(--v-list-prepend-gap)\n\n    > .v-badge,\n    > .v-icon,\n    > .v-tooltip\n      ~ .v-list-item__spacer\n        width: var(--v-list-prepend-gap, $list-item-icon-margin-start)\n\n    > .v-avatar,\n    > .v-badge:is(:has(.v-avatar))\n      ~ .v-list-item__spacer\n        width: var(--v-list-prepend-gap, $list-item-avatar-margin-start)\n\n\n    .v-list-item--slim &\n      > .v-badge,\n      > .v-icon,\n      > .v-tooltip\n        ~ .v-list-item__spacer\n          width: var(--v-list-prepend-gap, $list-item-slim-spacer-width)\n\n      > .v-avatar,\n      > .v-badge:is(:has(.v-avatar))\n        ~ .v-list-item__spacer\n          width: var(--v-list-prepend-gap, $list-item-slim-avatar-spacer-width)\n\n      > .v-list-item-action ~ .v-list-item__spacer\n        width: var(--v-list-prepend-gap, $list-item-slim-action-spacer-width)\n\n    .v-list-item--three-line &\n      align-self: start\n\n  .v-list-item__append\n    align-self: center\n    display: flex\n    align-items: center\n    grid-area: append\n\n    .v-list-item__spacer\n      order: -1\n      transition: 150ms width settings.$standard-easing\n\n    * ~ .v-list-item__spacer\n      width: var(--v-list-prepend-gap)\n\n    > .v-badge,\n    > .v-icon,\n    > .v-tooltip\n      ~ .v-list-item__spacer\n        width: var(--v-list-prepend-gap, $list-item-icon-margin-end)\n\n    > .v-avatar,\n    > .v-badge:is(:has(.v-avatar))\n      ~ .v-list-item__spacer\n        width: var(--v-list-prepend-gap, $list-item-avatar-margin-end)\n\n    > .v-list-item-action ~ .v-list-item__spacer\n      width: var(--v-list-prepend-gap, $list-item-action-spacer-width)\n\n    .v-list-item--slim &\n      > .v-badge,\n      > .v-icon,\n      > .v-tooltip\n        ~ .v-list-item__spacer\n          width: var(--v-list-slim-spacer-width, $list-item-slim-spacer-width)\n\n      > .v-avatar,\n      > .v-badge:is(:has(.v-avatar))\n        ~ .v-list-item__spacer\n          width: var(--v-list-prepend-gap, $list-item-slim-avatar-spacer-width)\n\n      > .v-list-item-action ~ .v-list-item__spacer\n        width: var(--v-list-prepend-gap, $list-item-slim-action-spacer-width)\n\n    .v-list-item--three-line &\n      align-self: start\n\n  .v-list-item__content\n    align-self: center\n    grid-area: content\n    overflow: hidden\n    min-width: $list-item-content-min-width\n\n    .v-navigation-drawer--rail:not(.v-navigation-drawer--expand-on-hover) &,\n    .v-navigation-drawer--rail.v-navigation-drawer--expand-on-hover:not(.v-navigation-drawer--is-hovering) &\n      min-width: 0\n\n  .v-list-item-action\n    align-self: center\n    display: flex\n    align-items: center\n    flex: none\n    transition: inherit\n    transition-property: height, width\n\n    &--start\n      margin-inline-end: $list-item-action-margin-end\n      margin-inline-start: -$list-item-action-margin-start\n\n    &--end\n      margin-inline-start: $list-item-action-margin-start\n      margin-inline-end: -$list-item-action-margin-end\n\n  .v-list-item-media\n    margin-top: $list-item-media-margin-top\n    margin-bottom: $list-item-media-margin-bottom\n\n    &--start\n      margin-inline-end: $list-item-media-margin-end\n\n    &--end\n      margin-inline-start: $list-item-media-margin-start\n\n    .v-list-item--two-line &\n      margin-top: $list-item-media-two-line-margin-top\n      margin-bottom: $list-item-media-two-line-margin-bottom\n\n    .v-list-item--three-line &\n      margin-top: $list-item-media-three-line-margin-top\n      margin-bottom: $list-item-media-three-line-margin-bottom\n\n  .v-list-item-subtitle\n    -webkit-box-orient: vertical\n    display: -webkit-box\n    opacity: $list-item-subtitle-opacity\n    overflow: hidden\n    padding: $list-item-subtitle-padding\n    text-overflow: ellipsis\n    overflow-wrap: $list-item-subtitle-overflow-wrap\n    word-break: $list-item-subtitle-word-break\n\n    .v-list-item--one-line &\n      -webkit-line-clamp: 1\n\n    .v-list-item--two-line &\n      -webkit-line-clamp: 2\n\n    .v-list-item--three-line &\n      -webkit-line-clamp: 3\n\n    @include tools.typography($list-item-subtitle-typography...)\n\n    .v-list-item--nav &\n      @include tools.typography($list-item-nav-subtitle-typography...)\n\n  .v-list-item-title\n    hyphens: $list-item-title-hyphens\n    overflow-wrap: $list-item-title-overflow-wrap\n    overflow: hidden\n    padding: $list-item-title-padding\n    white-space: nowrap\n    text-overflow: ellipsis\n    word-break: $list-item-title-word-break\n    word-wrap: $list-item-title-word-wrap\n\n    @include tools.typography($list-item-title-typography...)\n\n    .v-list-item--nav &\n      @include tools.typography($list-item-nav-title-typography...)\n\n  .v-list-item\n    @at-root\n      @include tools.density('v-list-item', $list-density) using ($modifier)\n        min-height: $list-item-min-height + $modifier\n\n        &.v-list-item--one-line\n          $one-line-padding: (list.nth($list-item-padding, 1) + $modifier)\n\n          min-height: $list-item-one-line-min-height + $modifier\n\n          @if ($one-line-padding > 0)\n            padding-top: $one-line-padding\n            padding-bottom: $one-line-padding\n\n        &.v-list-item--two-line\n          $two-line-padding: (list.nth($list-item-two-line-padding, 1) + $modifier)\n\n          min-height: $list-item-two-line-min-height + $modifier\n\n          @if ($two-line-padding > 0)\n            padding-top: $two-line-padding\n            padding-bottom: $two-line-padding\n\n        &.v-list-item--three-line\n          $three-line-padding: (list.nth($list-item-three-line-padding, 1) + $modifier)\n\n          min-height: $list-item-three-line-min-height + $modifier\n\n          @if ($three-line-padding > 0)\n            padding-top: $three-line-padding\n            padding-bottom: $three-line-padding\n\n            .v-list-item__prepend,\n            .v-list-item__append\n              padding-top: math.div($three-line-padding, 2)\n\n        &:not(.v-list-item--nav)\n          &.v-list-item--one-line\n            padding-inline: list.nth($list-item-padding, 2)\n\n          &.v-list-item--two-line\n            padding-inline: list.nth($list-item-two-line-padding, 2)\n\n          &.v-list-item--three-line\n            padding-inline: list.nth($list-item-three-line-padding, 2)\n\n    &--nav\n      padding-inline: $list-nav-padding\n\n  .v-list-item__underlay\n    position: absolute\n\n  .v-list-item__overlay\n    background-color: currentColor\n    border-radius: inherit\n    bottom: 0\n    left: 0\n    opacity: 0\n    pointer-events: none\n    position: absolute\n    right: 0\n    top: 0\n    transition: 0.2s ease-in-out\n    transition-property: opacity, color\n\n    .v-list-item--active.v-list-item--variant-elevated &\n      --v-theme-overlay-multiplier: 0\n\n  $base-padding: list.nth($list-item-padding, 2)\n  .v-list\n    --indent-padding: 0px\n\n    &--nav\n      --indent-padding: -#{$list-nav-padding}\n\n  .v-list-group\n    --list-indent-size: #{$list-indent-size}\n    --parent-padding: var(--indent-padding)\n    --prepend-width: var(--v-list-group-prepend, #{$list-item-prepend-size})\n\n    .v-list--slim &\n      --prepend-width: var(--v-list-group-prepend, #{$list-item-slim-prepend-size})\n\n    &--fluid\n      --list-indent-size: 0px\n\n    &--prepend\n      --parent-padding: calc(var(--indent-padding) + var(--prepend-width))\n\n    &--fluid.v-list-group--prepend\n      --parent-padding: var(--indent-padding)\n\n  .v-list-group__items\n    --indent-padding: calc(var(--parent-padding) + var(--v-list-indent, var(--list-indent-size)))\n    min-width: min-content\n\n    .v-navigation-drawer--rail &\n      min-width: 0\n\n  .v-list-group__items .v-list-item\n    @include tools.layer('overrides')\n      padding-inline-start: calc(#{$base-padding} + var(--indent-padding))\n\n  .v-list-group__header:not(.v-treeview-item--activatable-group-activator).v-list-item--active\n    &:not(:focus-visible)\n      .v-list-item__overlay\n        opacity: 0\n\n    &:hover\n      .v-list-item__overlay\n        opacity: calc(#{map.get(settings.$states, 'hover')} * var(--v-theme-overlay-multiplier))\n\n@include tools.layer('trumps')\n  @media (forced-colors: active)\n    .v-list-item\n      &--link:not(&--active)\n        color: buttontext\n\n      &--link[href]:not(&--active)\n        color: unset\n\n      &--active:not(&--disabled)\n        [class*=\"v-list-item-\"],\n        [class*=\"v-list-item-\"] > *,\n        .v-icon\n          color: highlight\n\n      &--active:not(&--variant-text, &--variant-plain):not(&--disabled)\n        background: highlight\n\n        [class*=\"v-list-item-\"],\n        [class*=\"v-list-item-\"] > *,\n        .v-icon\n          opacity: 1\n          color: highlighttext\n          forced-color-adjust: preserve-parent-color\n\n      &--focus-visible::after\n        opacity: 1\n\n      @supports selector(:focus-visible)\n        &::after\n          color: buttontext\n\n        &:focus-visible::after\n          opacity: 1\n"
  },
  {
    "path": "packages/vuetify/src/components/VList/VListItem.tsx",
    "content": "// Styles\nimport './VListItem.sass'\n\n// Components\nimport { VListItemSubtitle } from './VListItemSubtitle'\nimport { VListItemTitle } from './VListItemTitle'\nimport { VAvatar } from '@/components/VAvatar'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\nimport { VIcon } from '@/components/VIcon'\n\n// Composables\nimport { useList } from './list'\nimport { makeBorderProps, useBorder } from '@/composables/border'\nimport { makeComponentProps } from '@/composables/component'\nimport { makeDensityProps, useDensity } from '@/composables/density'\nimport { makeDimensionProps, useDimension } from '@/composables/dimensions'\nimport { makeElevationProps, useElevation } from '@/composables/elevation'\nimport { IconValue } from '@/composables/icons'\nimport { useNestedItem } from '@/composables/nested/nested'\nimport { makeRoundedProps, useRounded } from '@/composables/rounded'\nimport { makeRouterProps, useLink } from '@/composables/router'\nimport { makeTagProps } from '@/composables/tag'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\nimport { genOverlays, makeVariantProps, useVariant } from '@/composables/variant'\n\n// Directives\nimport vRipple from '@/directives/ripple'\n\n// Utilities\nimport { computed, nextTick, onBeforeMount, ref, toDisplayString, toRef, watch } from 'vue'\nimport { convertToUnit, deprecate, EventProp, genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { RippleDirectiveBinding } from '@/directives/ripple'\n\nexport type ListItemSlot = {\n  index?: number\n  depth?: number\n  path?: number[]\n  isFirst?: boolean\n  isLast?: boolean\n  isActive: boolean\n  isOpen: boolean\n  isSelected: boolean\n  isIndeterminate: boolean\n  isDisabled: boolean\n  select: (value: boolean) => void\n}\n\nexport type ListItemTitleSlot = {\n  title?: string | number | boolean\n}\n\nexport type ListItemSubtitleSlot = {\n  subtitle?: string | number | boolean\n}\n\nexport type VListItemSlots = {\n  prepend: ListItemSlot\n  append: ListItemSlot\n  default: ListItemSlot\n  title: ListItemTitleSlot\n  subtitle: ListItemSubtitleSlot\n}\n\nexport const makeVListItemProps = propsFactory({\n  active: {\n    type: Boolean,\n    default: undefined,\n  },\n  activeClass: String,\n  /* @deprecated */\n  activeColor: String,\n  appendAvatar: String,\n  appendIcon: IconValue,\n  baseColor: String,\n  disabled: Boolean,\n  lines: [Boolean, String] as PropType<'one' | 'two' | 'three' | false>,\n  link: {\n    type: Boolean,\n    default: undefined,\n  },\n  nav: Boolean,\n  prependAvatar: String,\n  prependIcon: IconValue,\n  ripple: {\n    type: [Boolean, Object] as PropType<RippleDirectiveBinding['value']>,\n    default: true,\n  },\n  slim: Boolean,\n  prependGap: [Number, String],\n  subtitle: {\n    type: [String, Number, Boolean],\n    default: undefined,\n  },\n  title: {\n    type: [String, Number, Boolean],\n    default: undefined,\n  },\n  value: null,\n  index: Number,\n  tabindex: [Number, String],\n\n  onClick: EventProp<[MouseEvent | KeyboardEvent]>(),\n  onClickOnce: EventProp<[MouseEvent]>(),\n\n  ...makeBorderProps(),\n  ...makeComponentProps(),\n  ...makeDensityProps(),\n  ...makeDimensionProps(),\n  ...makeElevationProps(),\n  ...makeRoundedProps(),\n  ...makeRouterProps(),\n  ...makeTagProps(),\n  ...makeThemeProps(),\n  ...makeVariantProps({ variant: 'text' } as const),\n}, 'VListItem')\n\nexport const VListItem = genericComponent<VListItemSlots>()({\n  name: 'VListItem',\n\n  directives: { vRipple },\n\n  props: makeVListItemProps(),\n\n  emits: {\n    click: (e: MouseEvent | KeyboardEvent) => true,\n  },\n\n  setup (props, { attrs, slots, emit }) {\n    const link = useLink(props, attrs)\n    const rootEl = ref<HTMLElement>()\n    const id = computed(() => props.value === undefined ? link.href.value : props.value)\n    const {\n      activate,\n      isActivated,\n      select,\n      isOpen,\n      isSelected,\n      isIndeterminate,\n      isGroupActivator,\n      root,\n      parent,\n      openOnSelect,\n      scrollToActive,\n      id: uid,\n    } = useNestedItem(id, () => props.disabled, false)\n    const list = useList()\n    const isActive = computed(() =>\n      props.active !== false &&\n      (props.active || link.isActive?.value || (root.activatable.value ? isActivated.value : isSelected.value))\n    )\n    const isLink = toRef(() => props.link !== false && link.isLink.value)\n    const isSelectable = computed(() => (!!list && (root.selectable.value || root.activatable.value || props.value != null)))\n    const isClickable = computed(() =>\n      !props.disabled &&\n      props.link !== false &&\n      (props.link || link.isClickable.value || isSelectable.value)\n    )\n    const isTracked = computed(() =>\n      list &&\n      list.navigationStrategy.value === 'track' &&\n      props.index !== undefined &&\n      list.trackingIndex.value === props.index\n    )\n    const role = computed(() => list ? (isLink.value ? 'link' : isSelectable.value ? 'option' : 'listitem') : undefined)\n    const ariaSelected = computed(() => {\n      if (!isSelectable.value) return undefined\n      return root.activatable.value ? isActivated.value\n        : root.selectable.value ? isSelected.value\n        : isActive.value\n    })\n\n    const roundedProps = toRef(() => props.rounded || props.nav)\n    const color = toRef(() => props.color ?? props.activeColor)\n    const variantProps = toRef(() => ({\n      color: isActive.value ? color.value ?? props.baseColor : props.baseColor,\n      variant: props.variant,\n    }))\n\n    // useNestedItem doesn't call register until beforeMount,\n    // so this can't be an immediate watcher as we don't know parent yet\n    watch(() => link.isActive?.value, val => {\n      if (!val) return\n      handleActiveLink()\n    })\n    watch(isActivated, val => {\n      if (!val || !scrollToActive) return\n      rootEl.value?.scrollIntoView({ block: 'nearest', behavior: 'instant' })\n    })\n    watch(isTracked, val => {\n      if (!val) return\n      rootEl.value?.scrollIntoView({ block: 'nearest', behavior: 'instant' })\n    })\n    onBeforeMount(() => {\n      if (link.isActive?.value) {\n        nextTick(() => handleActiveLink())\n      }\n    })\n    function handleActiveLink () {\n      if (parent.value != null) {\n        root.open(parent.value, true)\n      }\n      openOnSelect(true)\n    }\n\n    const { themeClasses } = provideTheme(props)\n    const { borderClasses } = useBorder(props)\n    const { colorClasses, colorStyles, variantClasses } = useVariant(variantProps)\n    const { densityClasses } = useDensity(props)\n    const { dimensionStyles } = useDimension(props)\n    const { elevationClasses } = useElevation(props)\n    const { roundedClasses } = useRounded(roundedProps)\n    const lineClasses = toRef(() => props.lines ? `v-list-item--${props.lines}-line` : undefined)\n    const rippleOptions = toRef(() =>\n      (\n        props.ripple !== undefined &&\n        !!props.ripple &&\n        list?.filterable\n      )\n        ? { keys: ['Enter'] }\n        : props.ripple\n    )\n\n    const slotProps = computed(() => ({\n      isActive: isActive.value,\n      select,\n      isOpen: isOpen.value,\n      isSelected: isSelected.value,\n      isIndeterminate: isIndeterminate.value,\n      isDisabled: props.disabled,\n    } satisfies ListItemSlot))\n\n    function onClick (e: MouseEvent) {\n      emit('click', e)\n      if (['INPUT', 'TEXTAREA'].includes((e.target as Element)?.tagName)) return\n\n      if (!isClickable.value) return\n\n      link.navigate.value?.(e)\n\n      if (isGroupActivator) return\n\n      if (root.activatable.value) {\n        activate(!isActivated.value, e)\n      } else if (root.selectable.value) {\n        select(!isSelected.value, e)\n      } else if (props.value != null && !isLink.value) {\n        select(!isSelected.value, e)\n      }\n    }\n\n    function onKeyDown (e: KeyboardEvent) {\n      const target = e.target as HTMLElement\n\n      if (['INPUT', 'TEXTAREA'].includes(target.tagName)) return\n\n      if (e.key === 'Enter' || (e.key === ' ' && !list?.filterable)) {\n        e.preventDefault()\n        e.stopPropagation()\n        e.target!.dispatchEvent(new MouseEvent('click', e))\n      }\n    }\n\n    useRender(() => {\n      const Tag = isLink.value ? 'a' : props.tag\n      const hasTitle = (slots.title || props.title != null)\n      const hasSubtitle = (slots.subtitle || props.subtitle != null)\n      const hasAppendMedia = !!(props.appendAvatar || props.appendIcon)\n      const hasAppend = !!(hasAppendMedia || slots.append)\n      const hasPrependMedia = !!(props.prependAvatar || props.prependIcon)\n      const hasPrepend = !!(hasPrependMedia || slots.prepend)\n\n      list?.updateHasPrepend(hasPrepend)\n\n      if (props.activeColor) {\n        deprecate('active-color', ['color', 'base-color'])\n      }\n\n      return (\n        <Tag\n          { ...link.linkProps }\n          ref={ rootEl }\n          id={ props.index !== undefined && list ? `v-list-item-${list.uid}-${props.index}` : undefined }\n          class={[\n            'v-list-item',\n            {\n              'v-list-item--active': isActive.value,\n              'v-list-item--disabled': props.disabled,\n              'v-list-item--link': isClickable.value,\n              'v-list-item--nav': props.nav,\n              'v-list-item--prepend': !hasPrepend && list?.hasPrepend.value,\n              'v-list-item--slim': props.slim,\n              'v-list-item--focus-visible': isTracked.value,\n              [`${props.activeClass}`]: props.activeClass && isActive.value,\n            },\n            themeClasses.value,\n            borderClasses.value,\n            colorClasses.value,\n            densityClasses.value,\n            elevationClasses.value,\n            lineClasses.value,\n            roundedClasses.value,\n            variantClasses.value,\n            props.class,\n          ]}\n          style={[\n            {\n              '--v-list-prepend-gap': convertToUnit(props.prependGap),\n            },\n            colorStyles.value,\n            dimensionStyles.value,\n            props.style,\n          ]}\n          tabindex={ props.tabindex ?? (isClickable.value ? (list ? -2 : 0) : undefined) }\n          aria-selected={ ariaSelected.value }\n          role={ role.value }\n          onClick={ onClick }\n          onKeydown={ isClickable.value && !isLink.value && onKeyDown }\n          v-ripple={ isClickable.value && rippleOptions.value }\n        >\n          { genOverlays(isClickable.value || isActive.value, 'v-list-item') }\n\n          { hasPrepend && (\n            <div key=\"prepend\" class=\"v-list-item__prepend\">\n              { !slots.prepend ? (\n                <>\n                  { props.prependAvatar && (\n                    <VAvatar\n                      key=\"prepend-avatar\"\n                      density={ props.density }\n                      image={ props.prependAvatar }\n                    />\n                  )}\n\n                  { props.prependIcon && (\n                    <VIcon\n                      key=\"prepend-icon\"\n                      density={ props.density }\n                      icon={ props.prependIcon }\n                    />\n                  )}\n                </>\n              ) : (\n                <VDefaultsProvider\n                  key=\"prepend-defaults\"\n                  defaults={{\n                    VAvatar: {\n                      density: props.density,\n                      image: props.prependAvatar,\n                    },\n                    VIcon: {\n                      density: props.density,\n                      icon: props.prependIcon,\n                    },\n                    VListItemAction: {\n                      start: true,\n                    },\n                    VCheckboxBtn: {\n                      density: props.density,\n                    },\n                  }}\n                >\n                  { slots.prepend?.(slotProps.value) }\n                </VDefaultsProvider>\n              )}\n\n              <div class=\"v-list-item__spacer\" />\n            </div>\n          )}\n\n          <div class=\"v-list-item__content\" data-no-activator=\"\">\n            { hasTitle && (\n              <VListItemTitle key=\"title\">\n                { slots.title?.({ title: props.title }) ?? toDisplayString(props.title) }\n              </VListItemTitle>\n            )}\n\n            { hasSubtitle && (\n              <VListItemSubtitle key=\"subtitle\">\n                { slots.subtitle?.({ subtitle: props.subtitle }) ?? toDisplayString(props.subtitle) }\n              </VListItemSubtitle>\n            )}\n\n            { slots.default?.(slotProps.value) }\n          </div>\n\n          { hasAppend && (\n            <div key=\"append\" class=\"v-list-item__append\">\n              { !slots.append ? (\n                <>\n                  { props.appendIcon && (\n                    <VIcon\n                      key=\"append-icon\"\n                      density={ props.density }\n                      icon={ props.appendIcon }\n                    />\n                  )}\n\n                  { props.appendAvatar && (\n                    <VAvatar\n                      key=\"append-avatar\"\n                      density={ props.density }\n                      image={ props.appendAvatar }\n                    />\n                  )}\n                </>\n              ) : (\n                <VDefaultsProvider\n                  key=\"append-defaults\"\n                  defaults={{\n                    VAvatar: {\n                      density: props.density,\n                      image: props.appendAvatar,\n                    },\n                    VIcon: {\n                      density: props.density,\n                      icon: props.appendIcon,\n                    },\n                    VListItemAction: {\n                      end: true,\n                    },\n                    VCheckboxBtn: {\n                      density: props.density,\n                    },\n                  }}\n                >\n                  { slots.append?.(slotProps.value) }\n                </VDefaultsProvider>\n              )}\n\n              <div class=\"v-list-item__spacer\" />\n            </div>\n          )}\n        </Tag>\n      )\n    })\n\n    return {\n      activate,\n      isActivated,\n      isGroupActivator,\n      isSelected,\n      list,\n      select,\n      root,\n      id: uid,\n      link,\n    }\n  },\n})\n\nexport type VListItem = InstanceType<typeof VListItem>\n"
  },
  {
    "path": "packages/vuetify/src/components/VList/VListItemAction.tsx",
    "content": "// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { makeTagProps } from '@/composables/tag'\n\n// Utilities\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\nexport const makeVListItemActionProps = propsFactory({\n  start: Boolean,\n  end: Boolean,\n\n  ...makeComponentProps(),\n  ...makeTagProps(),\n}, 'VListItemAction')\n\nexport const VListItemAction = genericComponent()({\n  name: 'VListItemAction',\n\n  props: makeVListItemActionProps(),\n\n  setup (props, { slots }) {\n    useRender(() => (\n      <props.tag\n        class={[\n          'v-list-item-action',\n          {\n            'v-list-item-action--start': props.start,\n            'v-list-item-action--end': props.end,\n          },\n          props.class,\n        ]}\n        style={ props.style }\n        v-slots={ slots }\n      />\n    ))\n\n    return {}\n  },\n})\n\nexport type VListItemAction = InstanceType<typeof VListItemAction>\n"
  },
  {
    "path": "packages/vuetify/src/components/VList/VListItemMedia.tsx",
    "content": "// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { makeTagProps } from '@/composables/tag'\n\n// Utilities\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\nexport const makeVListItemMediaProps = propsFactory({\n  start: Boolean,\n  end: Boolean,\n\n  ...makeComponentProps(),\n  ...makeTagProps(),\n}, 'VListItemMedia')\n\nexport const VListItemMedia = genericComponent()({\n  name: 'VListItemMedia',\n\n  props: makeVListItemMediaProps(),\n\n  setup (props, { slots }) {\n    useRender(() => {\n      return (\n        <props.tag\n          class={[\n            'v-list-item-media',\n            {\n              'v-list-item-media--start': props.start,\n              'v-list-item-media--end': props.end,\n            },\n            props.class,\n          ]}\n          style={ props.style }\n          v-slots={ slots }\n        />\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VListItemMedia = InstanceType<typeof VListItemMedia>\n"
  },
  {
    "path": "packages/vuetify/src/components/VList/VListItemSubtitle.tsx",
    "content": "// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { makeTagProps } from '@/composables/tag'\n\n// Utilities\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\nexport const makeVListItemSubtitleProps = propsFactory({\n  opacity: [Number, String],\n\n  ...makeComponentProps(),\n  ...makeTagProps(),\n}, 'VListItemSubtitle')\n\nexport const VListItemSubtitle = genericComponent()({\n  name: 'VListItemSubtitle',\n\n  props: makeVListItemSubtitleProps(),\n\n  setup (props, { slots }) {\n    useRender(() => (\n      <props.tag\n        class={[\n          'v-list-item-subtitle',\n          props.class,\n        ]}\n        style={[\n          { '--v-list-item-subtitle-opacity': props.opacity },\n          props.style,\n        ]}\n        v-slots={ slots }\n      />\n    ))\n\n    return {}\n  },\n})\n\nexport type VListItemSubtitle = InstanceType<typeof VListItemSubtitle>\n"
  },
  {
    "path": "packages/vuetify/src/components/VList/VListItemTitle.ts",
    "content": "// Utilities\nimport { createSimpleFunctional } from '@/util'\n\nexport const VListItemTitle = createSimpleFunctional('v-list-item-title')\n\nexport type VListItemTitle = InstanceType<typeof VListItemTitle>\n"
  },
  {
    "path": "packages/vuetify/src/components/VList/VListSubheader.tsx",
    "content": "// Composables\nimport { useTextColor } from '@/composables/color'\nimport { makeComponentProps } from '@/composables/component'\nimport { makeTagProps } from '@/composables/tag'\n\n// Utilities\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\nexport const makeVListSubheaderProps = propsFactory({\n  color: String,\n  inset: Boolean,\n  sticky: Boolean,\n  title: String,\n\n  ...makeComponentProps(),\n  ...makeTagProps(),\n}, 'VListSubheader')\n\nexport const VListSubheader = genericComponent()({\n  name: 'VListSubheader',\n\n  props: makeVListSubheaderProps(),\n\n  setup (props, { slots }) {\n    const { textColorClasses, textColorStyles } = useTextColor(() => props.color)\n\n    useRender(() => {\n      const hasText = !!(slots.default || props.title)\n\n      return (\n        <props.tag\n          class={[\n            'v-list-subheader',\n            {\n              'v-list-subheader--inset': props.inset,\n              'v-list-subheader--sticky': props.sticky,\n            },\n            textColorClasses.value,\n            props.class,\n          ]}\n          style={[\n            { textColorStyles },\n            props.style,\n          ]}\n        >\n          { hasText && (\n            <div class=\"v-list-subheader__text\">\n              { slots.default?.() ?? props.title }\n            </div>\n          )}\n        </props.tag>\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VListSubheader = InstanceType<typeof VListSubheader>\n"
  },
  {
    "path": "packages/vuetify/src/components/VList/__tests__/VList.spec.browser.tsx",
    "content": "// Components\nimport { VList, VListItem } from '..'\n\n// Utilities\nimport { render, screen, showcase, userEvent } from '@test'\nimport { ref } from 'vue'\nimport { createRouter, createWebHistory } from 'vue-router'\n\nconst FAKE_ROUTES = [\n  { path: '/', component: { template: 'Home' } },\n  { path: '/about', component: { template: 'About' } },\n  { path: '/other', component: { template: 'Other' } },\n  { path: '/__vitest_test__/:path(.*)', component: { template: 'Test' } },\n]\n\nconst NESTED_ITEMS = [\n  { title: 'Foo', subtitle: 'Bar', value: 'foo' },\n  {\n    title: 'Group',\n    value: 'group',\n    children: [\n      { title: 'Child', subtitle: 'Subtitle', value: 'child' },\n    ],\n  },\n]\n\nconst stories = {\n  'With nested items': <VList items={ NESTED_ITEMS } />,\n  'With opened group': <VList items={ NESTED_ITEMS } opened={['group']} />,\n  'With item slot': (\n    <VList items={ NESTED_ITEMS } opened={['group']}>\n      {{\n        item: item => <VListItem { ...item } prependIcon=\"mdi-home\" />,\n      }}\n    </VList>\n  ),\n  'With lines': (\n    <>\n      { (['one', 'two', 'three'] as const).map(v => (\n        <VList lines={ v }>\n          <VListItem>lines { v }</VListItem>\n        </VList>\n      ))}\n    </>\n  ),\n  'With density': (\n    <>\n      { (['default', 'comfortable', 'compact'] as const).map(v => (\n        <VList density={ v }>\n          <VListItem>density { v }</VListItem>\n        </VList>\n      ))}\n    </>\n  ),\n}\n\ndescribe('VList', () => {\n  it('should set active item on route change', async () => {\n    const router = createRouter({\n      history: createWebHistory(),\n      routes: FAKE_ROUTES,\n    })\n\n    render(() => (\n      <VList>\n        <VListItem to=\"/\" title=\"Home\" />\n        <VListItem to=\"/about\" title=\"About\" />\n      </VList>\n    ), {\n      global: {\n        plugins: [router],\n      },\n    })\n\n    await router.push('/about')\n\n    expect(screen.getAllByCSS('.v-list-item')[1]).toHaveClass('v-list-item--active')\n  })\n\n  it('should change route when clicking item with to prop', async () => {\n    const router = createRouter({\n      history: createWebHistory(),\n      routes: FAKE_ROUTES,\n    })\n\n    render(() => (\n      <VList>\n        <VListItem to=\"/\" title=\"Home\" />\n        <VListItem to=\"/about\" title=\"About\" />\n      </VList>\n    ), {\n      global: {\n        plugins: [router],\n      },\n    })\n\n    await userEvent.click(screen.getAllByCSS('.v-list-item')[1])\n\n    expect(router.currentRoute.value.path).toBe('/about')\n  })\n\n  it('should deselect v-list-item if route changes externally', async () => {\n    const router = createRouter({\n      history: createWebHistory(),\n      routes: FAKE_ROUTES,\n    })\n\n    render(() => (\n      <VList>\n        <VListItem to=\"/\" title=\"Home\" />\n        <VListItem to=\"/about\" title=\"About\" />\n      </VList>\n    ), {\n      global: {\n        plugins: [router],\n      },\n    })\n\n    await userEvent.click(screen.getAllByCSS('.v-list-item')[1])\n\n    await router.isReady()\n\n    expect(screen.getAllByCSS('.v-list-item')[1]).toHaveClass('v-list-item--active')\n\n    expect(router.currentRoute.value.path).toBe('/about')\n\n    await router.push('/other')\n\n    expect(screen.getAllByCSS('.v-list-item')[1]).not.toHaveClass('v-list-item--active')\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/18304\n  it('should support return-object', async () => {\n    const selectedItem = ref([])\n    const items = [\n      { id: '1', title: 'Events' },\n      { id: '2', title: 'Labour' },\n      { id: '3', title: 'Equipment' },\n    ]\n\n    render(() => (\n      <VList\n        items={ items }\n        onUpdate:selected={ (val: any) => selectedItem.value = val }\n        itemValue=\"id\"\n        itemTitle=\"title\"\n        returnObject\n      />\n    ))\n\n    await userEvent.click(screen.getAllByCSS('.v-list-item')[1])\n\n    expect(selectedItem.value).toEqual([items[1]])\n  })\n\n  showcase({ stories })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VList/__tests__/VList.spec.ts",
    "content": "// Components\nimport { VList } from '..'\n\n// Utilities\nimport { mount } from '@vue/test-utils'\nimport { createVuetify } from '@/framework'\n\ndescribe('VList', () => {\n  const vuetify = createVuetify()\n\n  function mountFunction (options = {}) {\n    return mount<any>(VList, {\n      global: { plugins: [vuetify] },\n      ...options,\n    })\n  }\n\n  it('should match a snapshot', () => {\n    const wrapper = mountFunction()\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it.each([\n    { selectable: true, activatable: false, expected: 'listbox' },\n    { selectable: false, activatable: true, expected: 'listbox' },\n    { selectable: true, activatable: true, expected: 'listbox' },\n    { selectable: false, activatable: false, expected: 'list' },\n  ])('should have role=\"$expected\" when selectable is $selectable and activatable is $activatable',\n    ({ selectable, activatable, expected }) => {\n      const wrapper = mountFunction({\n        props: { selectable, activatable },\n      })\n\n      expect(wrapper.attributes('role')).toBe(expected)\n    })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VList/__tests__/VListGroup.spec.browser.tsx",
    "content": "import { VListGroup } from '../VListGroup'\nimport { VListItem } from '../VListItem'\nimport { VList } from '../VList'\n\n// Components\nimport { VBtn } from '@/components/VBtn'\n\n// Utilities\nimport { render, screen } from '@test'\nimport { commands, userEvent } from 'vitest/browser'\nimport { ref } from 'vue'\n\ndescribe('VListGroup', () => {\n  it('supports activator slot', () => {\n    render(() => (\n      <VList>\n        <VListGroup>\n          {{ activator: props => <VListItem { ...props } title=\"Group\" /> }}\n        </VListGroup>\n      </VList>\n    ))\n\n    expect(screen.getByCSS('.v-list-item-title')).toHaveTextContent('Group')\n  })\n\n  it('supports children', () => {\n    render(() => (\n      <VList opened={['group']}>\n        <VListGroup value=\"group\">\n          {{\n            activator: props => <VListItem { ...props } title=\"Group\" />,\n            default: () => (\n              <>\n                <VListItem title=\"Child 1\" />\n                <VListItem title=\"Child 2\" />\n              </>\n            ),\n          }}\n        </VListGroup>\n      </VList>\n    ))\n\n    expect(screen.getAllByCSS('.v-list-item-title')[0]).toHaveTextContent('Group')\n  })\n\n  it('should not remove opened when unmounted', async () => {\n    const visible = ref(true)\n    const opened = ref(['Users'])\n    render(() => (\n        <VList opened={ opened.value }>\n          {\n            visible.value && (\n              <VListGroup value=\"Users\">\n                {{\n                  default: () => (\n                    <>\n                      <VListItem title=\"Foo\" />\n                      <VListItem title=\"Bar\" />\n                    </>\n                  ),\n                }}\n              </VListGroup>\n            )\n          }\n        </VList>\n    ))\n\n    expect(screen.queryByRole('group')).not.toBeNull()\n    expect(screen.getByCSS('.v-list-group__items')).toBeVisible()\n    visible.value = false\n    await commands.waitStable('.v-list')\n    expect(screen.queryByRole('group')).toBeNull()\n    visible.value = true\n    await commands.waitStable('.v-list')\n    expect(screen.queryByRole('group')).not.toBeNull()\n    expect(screen.getByCSS('.v-list-group__items')).toBeVisible()\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/20354\n  it('should support programmatically expand group via open model', async () => {\n    const opened = ref<string[]>([])\n\n    render(() => (\n      <>\n        <VBtn onClick={ () => { opened.value.push('Users') } }>Click me</VBtn>\n        <VList v-model:opened={ opened.value }>\n          <VListGroup value=\"Users\">\n            {{\n              activator: ({ props }) => <VListItem { ...props } title=\"Users\" />,\n              default: () => (\n                <>\n                  <VListItem title=\"Foo\" />\n                  <VListItem title=\"Bar\" />\n                </>\n              ),\n            }}\n          </VListGroup>\n        </VList>\n      </>\n    ))\n\n    await userEvent.click(screen.getByText(/click me/i))\n    await commands.waitStable('.v-list')\n    expect(opened.value).toStrictEqual(['Users'])\n    expect(screen.getByCSS('.v-list-group__items')).toBeVisible()\n  })\n\n  it('should correctly set v-model:opened when return-object is applied', async () => {\n    const opened = ref<{}[]>([])\n    const items = [\n      {\n        title: 'Item #1',\n        newValue: 1,\n        children: [\n          {\n            title: 'Child 1',\n            newValue: 100,\n          },\n        ],\n      },\n      {\n        title: 'Item #2',\n        newValue: 2,\n      },\n      {\n        title: 'Item #3',\n        newValue: 3,\n      },\n    ]\n    render(() => (\n      <VList\n        v-model:opened={ opened.value }\n        itemValue=\"newValue\"\n        items={ items }\n        returnObject\n      >\n      </VList>\n    ))\n\n    expect(opened.value).toStrictEqual([])\n\n    await userEvent.click(screen.getByCSS('.v-list-group__header'))\n\n    expect(opened.value).toStrictEqual([{\n      title: 'Item #1',\n      newValue: 1,\n      children: [\n        {\n          title: 'Child 1',\n          newValue: 100,\n        },\n      ],\n    }])\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VList/__tests__/VListItem.spec.cy.tsx",
    "content": "/// <reference types=\"../../../../types/cypress\" />\n\nimport { CenteredGrid } from '@/../cypress/templates'\nimport { VListItem } from '../'\n\ndescribe('VListItem', () => {\n  it('supports header text props, title and subtitle', () => {\n    cy.mount(() => (\n      <CenteredGrid width=\"200px\">\n        <h2 class=\"mt-8\">ListItem Header Text</h2>\n\n        <VListItem title=\"foo\" subtitle=\"bar\" />\n      </CenteredGrid>\n    ))\n\n    cy.get('.v-list-item-title').contains('foo')\n      .get('.v-list-item-subtitle').contains('bar')\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/13893\n  it('should use active-color for active item', () => {\n    cy.mount(props => (\n      <CenteredGrid width=\"200px\">\n        <VListItem title=\"foo\" subtitle=\"bar\" active-color=\"success\" { ...props } />\n      </CenteredGrid>\n    ))\n\n    cy.get('.v-list-item')\n      .should('not.have.class', 'text-success')\n      .setProps({ active: true })\n      .get('.v-list-item')\n      .should('have.class', 'text-success')\n  })\n\n  it('should render prepend and append slots', () => {\n    cy.mount(props => (\n      <CenteredGrid width=\"200px\">\n        <VListItem\n          title=\"foo\"\n          subtitle=\"bar\"\n          prepend-icon=\"$success\"\n          { ...props }\n        />\n      </CenteredGrid>\n    ))\n\n    cy.get('.v-list-item__prepend').should('exist')\n      .get('.v-list-item__append').should('not.exist')\n      .setProps({ appendIcon: '$success', prependIcon: undefined })\n      .get('.v-list-item__append').should('exist')\n      .get('.v-list-item__prepend').should('not.exist')\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VList/__tests__/VListItemMedia.spec.ts",
    "content": "// Components\nimport { VListItemMedia } from '..'\n\n// Utilities\nimport { mount } from '@vue/test-utils'\nimport { createVuetify } from '@/framework'\n\ndescribe('VListItemMedia', () => {\n  const vuetify = createVuetify()\n\n  function mountFunction (options = {}) {\n    return mount(VListItemMedia, {\n      global: { plugins: [vuetify] },\n      ...options,\n    })\n  }\n\n  it('should match a snapshot', () => {\n    const wrapper = mountFunction()\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VList/__tests__/__snapshots__/VList.spec.ts.snap",
    "content": "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html\n\nexports[`VList > should match a snapshot 1`] = `\"<div class=\"v-list v-theme--light v-list--density-default v-list--one-line\" tabindex=\"0\" role=\"list\"></div>\"`;\n"
  },
  {
    "path": "packages/vuetify/src/components/VList/__tests__/__snapshots__/VListItemMedia.spec.ts.snap",
    "content": "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html\n\nexports[`VListItemMedia > should match a snapshot 1`] = `\"<div class=\"v-list-item-media\"></div>\"`;\n"
  },
  {
    "path": "packages/vuetify/src/components/VList/_variables.scss",
    "content": "@use 'sass:map';\n@use '../../styles/settings';\n@use '../../styles/tools';\n\n// VList\n$list-background: rgba(var(--v-theme-surface)) !default;\n$list-border-color: settings.$border-color-root !default;\n$list-border-radius: 0 !default;\n$list-border-style: settings.$border-style-root !default;\n$list-border-thin-width: thin !default;\n$list-border-width: 0 !default;\n$list-color: tools.theme-color('on-surface', var(--v-high-emphasis-opacity)) !default;\n$list-disabled-opacity: 0.6 !default;\n$list-elevation: 0 !default;\n$list-padding: 8px 0 !default;\n$list-rounded-border-radius: map.get(settings.$rounded, null) !default;\n$list-indent-size: 16px !default;\n\n$list-nav-padding: 8px !default;\n$list-nav-subheader-font-size: .75rem !default;\n\n// VListSubheader\n$list-subheader-color: tools.theme-color('on-surface', var(--v-medium-emphasis-opacity)) !default;\n$list-subheader-font-size: .875rem !default;\n$list-subheader-font-weight: 400 !default;\n$list-subheader-inset-padding-start: 56px !default;\n$list-subheader-line-height: 1.375rem !default;\n$list-subheader-min-height: 40px !default;\n$list-subheader-padding-end: 16px !default;\n$list-subheader-padding-top: 0 !default;\n$list-subheader-min-height-multiplier: 1 !default;\n$list-subheader-transition: 0.2s min-height settings.$standard-easing !default;\n\n// VListItem\n$list-item-border-color: settings.$border-color-root !default;\n$list-item-border-radius: 0 !default;\n$list-item-border-style: settings.$border-style-root !default;\n$list-item-border-width: 0 !default;\n$list-item-border-thin-width: thin !default;\n$list-item-content-min-width: 40px !default;\n$list-item-elevation: 1 !default;\n$list-item-icon-opacity: var(--v-medium-emphasis-opacity) !default;\n$list-item-icon-active-opacity: 1 !default;\n$list-item-min-height: 40px !default;\n$list-item-padding: 4px 16px !default;\n$list-item-prepend-size: 40px !default;\n$list-item-slim-prepend-size: 28px !default;\n$list-item-plain-opacity: .62 !default;\n$list-item-rounded-border-radius: map.get(settings.$rounded, null) !default;\n$list-item-one-line-min-height: 48px !default;\n$list-item-two-line-min-height: 64px !default;\n$list-item-two-line-padding: 12px 16px !default;\n$list-item-three-line-min-height: 88px !default;\n$list-item-three-line-padding: 16px 16px !default;\n\n$list-item-action-spacer-width: 16px !default;\n$list-item-slim-action-spacer-width: 4px !default;\n$list-item-avatar-margin-end: 16px !default;\n$list-item-avatar-margin-start: 16px !default;\n$list-item-slim-spacer-width: 20px !default;\n$list-item-slim-avatar-spacer-width: 4px !default;\n\n$list-item-action-margin-end: 8px !default;\n$list-item-action-margin-start: 8px !default;\n\n$list-item-icon-margin-end: 32px !default;\n$list-item-icon-margin-start: 32px !default;\n\n$list-item-media-margin-bottom: 0 !default;\n$list-item-media-margin-end: 16px !default;\n$list-item-media-margin-start: 16px !default;\n$list-item-media-margin-top: 0 !default;\n$list-item-media-two-line-margin-bottom: -4px !default;\n$list-item-media-two-line-margin-top: -4px !default;\n$list-item-media-three-line-margin-bottom: 0 !default;\n$list-item-media-three-line-margin-top: 0 !default;\n\n$list-item-nav-margin-top: 4px !default;\n$list-item-nav-title-font-size: .8125rem !default;\n$list-item-nav-title-font-weight: 500 !default;\n$list-item-nav-title-letter-spacing: normal !default;\n$list-item-nav-title-line-height: 1rem !default;\n$list-item-nav-subtitle-font-size: .75rem !default;\n$list-item-nav-subtitle-font-weight: tools.map-deep-get(settings.$typography, 'body-medium', 'weight') !default;\n$list-item-nav-subtitle-letter-spacing: tools.map-deep-get(settings.$typography, 'body-medium', 'letter-spacing') !default;\n$list-item-nav-subtitle-line-height: 1rem !default;\n\n$list-item-subtitle-opacity: var(--v-list-item-subtitle-opacity, var(--v-medium-emphasis-opacity)) !default;\n$list-item-subtitle-font-size: tools.map-deep-get(settings.$typography, 'body-medium', 'size') !default;\n$list-item-subtitle-font-weight: tools.map-deep-get(settings.$typography, 'body-medium', 'weight') !default;\n$list-item-subtitle-letter-spacing: tools.map-deep-get(settings.$typography, 'body-medium', 'letter-spacing') !default;\n$list-item-subtitle-line-height: 1rem !default;\n$list-item-subtitle-padding: 0 !default;\n$list-item-subtitle-text-transform: none !default;\n$list-item-subtitle-overflow-wrap: break-word !default;\n$list-item-subtitle-word-break: initial !default;\n\n$list-item-title-font-size: tools.map-deep-get(settings.$typography, 'body-large', 'size') !default;\n$list-item-title-font-weight: tools.map-deep-get(settings.$typography, 'body-large', 'weight') !default;\n$list-item-title-hyphens: auto !default;\n$list-item-title-letter-spacing: tools.map-deep-get(settings.$typography, 'body-large', 'letter-spacing') !default;\n$list-item-title-line-height: tools.map-deep-get(settings.$typography, 'body-large', 'line-height') !default;\n$list-item-title-overflow-wrap: normal !default;\n$list-item-title-padding: 0 !default;\n$list-item-title-text-transform: none !default;\n$list-item-title-word-break: normal !default;\n$list-item-title-word-wrap: break-word !default;\n\n$list-density: ('default': 0, 'comfortable': -1, 'compact': -2) !default;\n\n$list-border: (\n  $list-border-color,\n  $list-border-style,\n  $list-border-width,\n  $list-border-thin-width\n) !default;\n\n$list-theme: (\n  $list-background,\n  $list-color\n) !default;\n\n$list-item-border: (\n  $list-item-border-color,\n  $list-item-border-style,\n  $list-item-border-width,\n  $list-item-border-thin-width\n) !default;\n\n$list-item-title-typography: (\n  $list-item-title-font-size,\n  $list-item-title-font-weight,\n  $list-item-title-letter-spacing,\n  $list-item-title-line-height,\n  $list-item-title-text-transform\n) !default;\n\n$list-item-subtitle-typography: (\n  $list-item-subtitle-font-size,\n  $list-item-subtitle-font-weight,\n  $list-item-subtitle-letter-spacing,\n  $list-item-subtitle-line-height,\n  $list-item-subtitle-text-transform\n) !default;\n\n$list-item-nav-title-typography: (\n  $list-item-nav-title-font-size,\n  $list-item-nav-title-font-weight,\n  $list-item-nav-title-letter-spacing,\n  $list-item-nav-title-line-height,\n  null\n) !default;\n\n$list-item-nav-subtitle-typography: (\n  $list-item-nav-subtitle-font-size,\n  $list-item-nav-subtitle-font-weight,\n  $list-item-nav-subtitle-letter-spacing,\n  $list-item-nav-subtitle-line-height,\n  null\n) !default;\n\n$list-item-variants: (\n  $list-background,\n  $list-color,\n  $list-item-elevation,\n  $list-item-plain-opacity,\n  'v-list-item'\n) !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VList/index.ts",
    "content": "export { VList } from './VList'\nexport { VListGroup } from './VListGroup'\nexport { VListImg } from './VListImg'\nexport { VListItem } from './VListItem'\nexport { VListItemAction } from './VListItemAction'\nexport { VListItemMedia } from './VListItemMedia'\nexport { VListItemSubtitle } from './VListItemSubtitle'\nexport { VListItemTitle } from './VListItemTitle'\nexport { VListSubheader } from './VListSubheader'\n"
  },
  {
    "path": "packages/vuetify/src/components/VList/list.ts",
    "content": "// Utilities\nimport { computed, inject, provide, shallowRef, useId } from 'vue'\n\n// Types\nimport type { InjectionKey, MaybeRefOrGetter, Ref } from 'vue'\n\n// Depth\nexport const DepthKey: InjectionKey<Ref<number>> = Symbol.for('vuetify:depth')\n\nexport function useDepth (hasPrepend?: Ref<boolean>) {\n  const parent = inject(DepthKey, shallowRef(-1))\n\n  const depth = computed(() => parent.value + 1 + (hasPrepend?.value ? 1 : 0))\n\n  provide(DepthKey, depth)\n\n  return depth\n}\n\n// List\nexport const ListKey: InjectionKey<{\n  filterable: MaybeRefOrGetter<boolean>\n  hasPrepend: Ref<boolean>\n  updateHasPrepend: (value: boolean) => void\n  trackingIndex: Ref<number>\n  navigationStrategy: Ref<'focus' | 'track'>\n  uid: string\n}> = Symbol.for('vuetify:list')\n\ntype InjectedListOptions = {\n  filterable: MaybeRefOrGetter<boolean>\n  trackingIndex?: Ref<number>\n  navigationStrategy?: Ref<'focus' | 'track'>\n  uid?: string\n}\n\nexport function createList (options: InjectedListOptions = { filterable: false }) {\n  const parent = inject(ListKey, {\n    filterable: false,\n    hasPrepend: shallowRef(false),\n    updateHasPrepend: () => null,\n    trackingIndex: shallowRef(-1),\n    navigationStrategy: shallowRef('focus' as 'focus' | 'track'),\n    uid: '',\n  })\n\n  const {\n    filterable,\n    trackingIndex = parent.trackingIndex,\n    navigationStrategy = parent.navigationStrategy,\n    uid = parent.uid || useId(),\n  } = options\n\n  const data = {\n    filterable: parent.filterable || filterable,\n    hasPrepend: shallowRef(false),\n    updateHasPrepend: (value: boolean) => {\n      if (value) data.hasPrepend.value = value\n    },\n    trackingIndex,\n    navigationStrategy,\n    uid,\n  }\n\n  provide(ListKey, data)\n\n  return parent\n}\n\nexport function useList () {\n  return inject(ListKey, null)\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VLocaleProvider/VLocaleProvider.sass",
    "content": "@use '../../styles/tools'\n\n@include tools.layer('components')\n  .v-locale-provider\n    display: contents\n"
  },
  {
    "path": "packages/vuetify/src/components/VLocaleProvider/VLocaleProvider.tsx",
    "content": "// Styles\nimport './VLocaleProvider.sass'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { provideLocale } from '@/composables/locale'\n\n// Utilities\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\nexport const makeVLocaleProviderProps = propsFactory({\n  locale: String,\n  fallbackLocale: String,\n  messages: Object,\n  rtl: {\n    type: Boolean,\n    default: undefined,\n  },\n\n  ...makeComponentProps(),\n}, 'VLocaleProvider')\n\nexport const VLocaleProvider = genericComponent()({\n  name: 'VLocaleProvider',\n\n  props: makeVLocaleProviderProps(),\n\n  setup (props, { slots }) {\n    const { rtlClasses } = provideLocale(props)\n\n    useRender(() => (\n      <div\n        class={[\n          'v-locale-provider',\n          rtlClasses.value,\n          props.class,\n        ]}\n        style={ props.style }\n      >\n        { slots.default?.() }\n      </div>\n    ))\n\n    return {}\n  },\n})\n\nexport type VLocaleProvider = InstanceType<typeof VLocaleProvider>\n"
  },
  {
    "path": "packages/vuetify/src/components/VLocaleProvider/index.ts",
    "content": "export { VLocaleProvider } from './VLocaleProvider'\n"
  },
  {
    "path": "packages/vuetify/src/components/VMain/VMain.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-main\n    flex: 1 0 auto\n    max-width: 100%\n    transition: $main-transition\n    padding-left: var(--v-layout-left)\n    padding-right: var(--v-layout-right)\n    padding-top: var(--v-layout-top)\n    padding-bottom: var(--v-layout-bottom)\n\n    @media (prefers-reduced-motion: reduce)\n      transition: none\n\n    &__scroller\n      max-width: 100%\n      position: relative\n\n    &--scrollable\n      display: flex\n      @include tools.absolute()\n\n      & > .v-main__scroller\n        flex: 1 1 auto\n        overflow-y: auto\n        --v-layout-left: 0px\n        --v-layout-right: 0px\n        --v-layout-top: 0px\n        --v-layout-bottom: 0px\n"
  },
  {
    "path": "packages/vuetify/src/components/VMain/VMain.tsx",
    "content": "// Styles\nimport './VMain.sass'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { makeDimensionProps, useDimension } from '@/composables/dimensions'\nimport { useLayout } from '@/composables/layout'\nimport { useSsrBoot } from '@/composables/ssrBoot'\nimport { makeTagProps } from '@/composables/tag'\n\n// Utilities\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\nexport const makeVMainProps = propsFactory({\n  scrollable: Boolean,\n\n  ...makeComponentProps(),\n  ...makeDimensionProps(),\n  ...makeTagProps({ tag: 'main' }),\n}, 'VMain')\n\nexport const VMain = genericComponent()({\n  name: 'VMain',\n\n  props: makeVMainProps(),\n\n  setup (props, { slots }) {\n    const { dimensionStyles } = useDimension(props)\n    const { mainStyles } = useLayout()\n    const { ssrBootStyles } = useSsrBoot()\n\n    useRender(() => (\n      <props.tag\n        class={[\n          'v-main',\n          { 'v-main--scrollable': props.scrollable },\n          props.class,\n        ]}\n        style={[\n          mainStyles.value,\n          ssrBootStyles.value,\n          dimensionStyles.value,\n          props.style,\n        ]}\n      >\n        { props.scrollable\n          ? (\n            <div class=\"v-main__scroller\">\n              { slots.default?.() }\n            </div>\n          )\n          : slots.default?.()\n        }\n      </props.tag>\n    ))\n\n    return {}\n  },\n})\n\nexport type VMain = InstanceType<typeof VMain>\n"
  },
  {
    "path": "packages/vuetify/src/components/VMain/_variables.scss",
    "content": "@use '../../styles/settings';\n\n// VMain\n$main-transition: 0.2s settings.$standard-easing !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VMain/index.ts",
    "content": "export { VMain } from './VMain'\n"
  },
  {
    "path": "packages/vuetify/src/components/VMenu/VMenu.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-menu\n    > .v-overlay__content\n      display: flex\n      flex-direction: column\n      @include tools.rounded($menu-content-border-radius)\n\n      > .v-card,\n      > .v-sheet,\n      > .v-list\n        background: rgb(var(--v-theme-surface))\n        border-radius: inherit\n        overflow: auto\n        height: 100%\n\n        @include tools.elevation($menu-elevation)\n"
  },
  {
    "path": "packages/vuetify/src/components/VMenu/VMenu.tsx",
    "content": "// Styles\nimport './VMenu.sass'\n\n// Components\nimport { VDialogTransition } from '@/components/transitions'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\nimport { VOverlay } from '@/components/VOverlay'\nimport { makeVOverlayProps } from '@/components/VOverlay/VOverlay'\n\n// Composables\nimport { forwardRefs } from '@/composables/forwardRefs'\nimport { useRtl } from '@/composables/locale'\nimport { useProxiedModel } from '@/composables/proxiedModel'\nimport { useScopeId } from '@/composables/scopeId'\n\n// Utilities\nimport {\n  computed,\n  inject,\n  mergeProps,\n  onBeforeUnmount,\n  onDeactivated,\n  provide,\n  ref,\n  shallowRef, toRef,\n  useId,\n  watch,\n} from 'vue'\nimport { VMenuSymbol } from './shared'\nimport {\n  focusableChildren,\n  focusChild,\n  genericComponent,\n  getNextElement,\n  isClickInsideElement,\n  omit,\n  propsFactory,\n  useRender,\n} from '@/util'\n\n// Types\nimport type { OverlaySlots } from '@/components/VOverlay/VOverlay'\n\nexport const makeVMenuProps = propsFactory({\n  // TODO\n  // disableKeys: Boolean,\n  id: String,\n  submenu: Boolean,\n\n  ...omit(makeVOverlayProps({\n    captureFocus: true,\n    closeDelay: 250,\n    closeOnContentClick: true,\n    locationStrategy: 'connected' as const,\n    location: undefined,\n    openDelay: 300,\n    scrim: false,\n    scrollStrategy: 'reposition' as const,\n    transition: { component: VDialogTransition },\n  }), ['absolute']),\n}, 'VMenu')\n\nexport const VMenu = genericComponent<OverlaySlots>()({\n  name: 'VMenu',\n\n  props: makeVMenuProps(),\n\n  emits: {\n    'update:modelValue': (value: boolean) => true,\n  },\n\n  setup (props, { slots }) {\n    const isActive = useProxiedModel(props, 'modelValue')\n    const { scopeId } = useScopeId()\n    const { isRtl } = useRtl()\n\n    const uid = useId()\n    const id = toRef(() => props.id || `v-menu-${uid}`)\n\n    const overlay = ref<VOverlay>()\n\n    const parent = inject(VMenuSymbol, null)\n    const openChildren = shallowRef(new Set<string>())\n    provide(VMenuSymbol, {\n      register () {\n        openChildren.value.add(uid)\n      },\n      unregister () {\n        openChildren.value.delete(uid)\n      },\n      closeParents (e) {\n        setTimeout(() => {\n          if (!openChildren.value.size &&\n            !props.persistent &&\n            (e == null || (overlay.value?.contentEl && !isClickInsideElement(e, overlay.value.contentEl)))\n          ) {\n            isActive.value = false\n            parent?.closeParents()\n          }\n        }, 40)\n      },\n    })\n\n    onBeforeUnmount(() => parent?.unregister())\n    onDeactivated(() => isActive.value = false)\n\n    watch(isActive, val => {\n      val\n        ? parent?.register()\n        : parent?.unregister()\n    }, { immediate: true })\n\n    function onClickOutside (e: MouseEvent) {\n      parent?.closeParents(e)\n    }\n\n    function onKeydown (e: KeyboardEvent) {\n      if (props.disabled) return\n\n      if (e.key === 'Tab' || (e.key === 'Enter' && !props.closeOnContentClick)) {\n        if (\n          e.key === 'Enter' &&\n          ((e.target instanceof HTMLTextAreaElement) ||\n          (e.target instanceof HTMLInputElement && !!e.target.closest('form')))\n        ) return\n        if (e.key === 'Enter') e.preventDefault()\n\n        const nextElement = getNextElement(\n          focusableChildren(overlay.value?.contentEl as Element, false),\n          e.shiftKey ? 'prev' : 'next',\n          (el: HTMLElement) => el.tabIndex >= 0\n        )\n        if (!nextElement && !props.retainFocus) {\n          isActive.value = false\n          overlay.value?.activatorEl?.focus()\n        }\n      } else if (props.submenu && e.key === (isRtl.value ? 'ArrowRight' : 'ArrowLeft')) {\n        isActive.value = false\n        overlay.value?.activatorEl?.focus()\n      }\n    }\n\n    function onActivatorKeydown (e: KeyboardEvent) {\n      if (props.disabled) return\n\n      const el = overlay.value?.contentEl\n      if (el && isActive.value) {\n        if (e.key === 'ArrowDown') {\n          e.preventDefault()\n          e.stopImmediatePropagation()\n          focusChild(el, 'next')\n        } else if (e.key === 'ArrowUp') {\n          e.preventDefault()\n          e.stopImmediatePropagation()\n          focusChild(el, 'prev')\n        } else if (props.submenu) {\n          if (e.key === (isRtl.value ? 'ArrowRight' : 'ArrowLeft')) {\n            isActive.value = false\n          } else if (e.key === (isRtl.value ? 'ArrowLeft' : 'ArrowRight')) {\n            e.preventDefault()\n            focusChild(el, 'first')\n          }\n        }\n      } else if (\n        props.submenu\n          ? e.key === (isRtl.value ? 'ArrowLeft' : 'ArrowRight')\n          : ['ArrowDown', 'ArrowUp'].includes(e.key)\n      ) {\n        isActive.value = true\n        e.preventDefault()\n        setTimeout(() => setTimeout(() => onActivatorKeydown(e)))\n      }\n    }\n\n    const activatorProps = computed(() =>\n      mergeProps({\n        'aria-haspopup': 'menu',\n        'aria-expanded': String(isActive.value),\n        'aria-controls': id.value,\n        'aria-owns': id.value,\n        onKeydown: onActivatorKeydown,\n      }, props.activatorProps)\n    )\n\n    useRender(() => {\n      const overlayProps = VOverlay.filterProps(props)\n\n      return (\n        <VOverlay\n          ref={ overlay }\n          id={ id.value }\n          class={[\n            'v-menu',\n            props.class,\n          ]}\n          style={ props.style }\n          { ...overlayProps }\n          v-model={ isActive.value }\n          absolute\n          activatorProps={ activatorProps.value }\n          location={ props.location ?? (props.submenu ? 'end' : 'bottom') }\n          onClick:outside={ onClickOutside }\n          onKeydown={ onKeydown }\n          { ...scopeId }\n        >\n          {{\n            activator: slots.activator,\n            default: (...args) => (\n              <VDefaultsProvider root=\"VMenu\">\n                { slots.default?.(...args) }\n              </VDefaultsProvider>\n            ),\n          }}\n        </VOverlay>\n      )\n    })\n\n    return forwardRefs({ id, ΨopenChildren: openChildren }, overlay)\n  },\n})\n\nexport type VMenu = InstanceType<typeof VMenu>\n"
  },
  {
    "path": "packages/vuetify/src/components/VMenu/__tests__/VMenu.spec.ts",
    "content": "// @ts-nocheck\n/* eslint-disable */\n\n// Components\n// import VMenu from '../VMenu'\n// import VCard from '../../VCard/VCard'\n// import VListItem from '../../VList/VListItem'\n\n// Utilities\nimport {\n  mount,\n  Wrapper,\n} from '@vue/test-utils'\n// import { keyCodes } from '../../../util/helpers'\n// import { waitAnimationFrame } from '@/../test'\n\ndescribe.skip('VMenu.ts', () => {\n  type Instance = InstanceType<typeof VMenu>\n  let mountFunction: (options?: object) => Wrapper<Instance>\n\n  beforeEach(() => {\n    mountFunction = (options = {}) => {\n      return mount(VMenu, {\n        // https://github.com/vuejs/vue-test-utils/issues/1130\n        sync: false,\n        ...options,\n        mocks: {\n          $vuetify: {\n            theme: {},\n          },\n        },\n      })\n    }\n  })\n\n  it('should work', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: false,\n        eager: true,\n      },\n      scopedSlots: {\n        activator: '<button v-on=\"props.on\"></button>',\n      },\n      slots: {\n        default: [VCard],\n      },\n    })\n\n    const activator = wrapper.find('button')\n    const input = jest.fn()\n    wrapper.vm.$on('input', input)\n    activator.trigger('click')\n\n    await wrapper.vm.$nextTick()\n\n    expect(input).toHaveBeenCalledWith(true)\n    expect(wrapper.html()).toMatchSnapshot()\n    expect('Unable to locate target [data-app]').toHaveBeenTipped()\n  })\n\n  it('should render multiple content nodes', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        eager: true,\n      },\n      scopedSlots: {\n        activator: '<button v-on=\"props.on\"></button>',\n      },\n      slots: {\n        default: '<span>foo</span><span>bar</span>',\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n    expect('Unable to locate target [data-app]').toHaveBeenTipped()\n  })\n\n  it('should round dimensions', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        value: false,\n        eager: true,\n      },\n      scopedSlots: {\n        activator: '<button v-on=\"props.on\"></button>',\n      },\n      slots: {\n        default: '<span class=\"content\"></span>',\n      },\n    })\n\n    const content = wrapper.find('.v-menu__content')\n\n    const getBoundingClientRect = () => {\n      return {\n        width: 100.5,\n        height: 100.25,\n        top: 0.75,\n        left: 50.123,\n        right: 75.987,\n        bottom: 4,\n        x: 0,\n        y: 0,\n      }\n    }\n\n    wrapper.find('button').element.getBoundingClientRect = getBoundingClientRect\n    wrapper.vm.$refs.content.getBoundingClientRect = getBoundingClientRect\n\n    wrapper.setProps({ value: true })\n\n    await waitAnimationFrame()\n\n    expect(content.attributes('style')).toMatchSnapshot()\n    expect('Unable to locate target [data-app]').toHaveBeenTipped()\n  })\n\n  it('should not attach event handlers to the activator container if disabled', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        disabled: true,\n      },\n      scopedSlots: {\n        activator: '<button v-on=\"props.on\"></button>',\n      },\n    })\n\n    const activator = wrapper.find('button')\n    activator.trigger('click')\n\n    expect(wrapper.vm.isActive).toBe(false)\n  })\n\n  it('should show the menu on mounted', () => {\n    const activate = jest.fn()\n    mountFunction({\n      methods: { activate },\n    })\n\n    expect(activate).not.toHaveBeenCalled()\n\n    mountFunction({\n      propsData: { value: true },\n      methods: { activate },\n    })\n    expect(activate).toHaveBeenCalled()\n    expect('Unable to locate target [data-app]').toHaveBeenTipped()\n  })\n\n  it('should update position dynamically', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        absolute: true,\n        value: true,\n        positionX: 100,\n        positionY: 200,\n      },\n    })\n\n    const content = wrapper.findAll('.v-menu__content').at(0)\n\n    // TODO replace with jest fakeTimers when it will support requestAnimationFrame: https://github.com/facebook/jest/pull/7776\n    // See https://github.com/vuetifyjs/vuetify/pull/6330#issuecomment-460083547 for details\n    expect(content.attributes('style')).toMatchSnapshot()\n\n    wrapper.setProps({\n      positionX: 110,\n      positionY: 220,\n    })\n    expect(content.attributes('style')).toMatchSnapshot()\n    expect('Unable to locate target [data-app]').toHaveBeenTipped()\n  })\n\n  it('should select next and previous tiles and skip non links/disabled', () => {\n    const wrapper = mountFunction({\n      propsData: { eager: true },\n      scopedSlots: {\n        default () {\n          return this.$createElement('div', [\n            this.$createElement(VListItem, { props: { link: true } }),\n            this.$createElement(VListItem, { props: { link: true } }),\n            this.$createElement(VListItem),\n            this.$createElement(VListItem, { props: { link: true } }),\n          ])\n        },\n      },\n    })\n\n    wrapper.vm.getTiles()\n\n    expect(wrapper.vm.listIndex).toBe(-1)\n\n    wrapper.vm.nextTile()\n    expect(wrapper.vm.listIndex).toBe(0)\n\n    wrapper.vm.nextTile()\n    expect(wrapper.vm.listIndex).toBe(1)\n\n    wrapper.vm.nextTile()\n    expect(wrapper.vm.listIndex).toBe(3)\n\n    wrapper.vm.nextTile()\n    expect(wrapper.vm.listIndex).toBe(0)\n\n    wrapper.vm.prevTile()\n    expect(wrapper.vm.listIndex).toBe(3)\n\n    wrapper.vm.prevTile()\n    expect(wrapper.vm.listIndex).toBe(1)\n\n    wrapper.vm.prevTile()\n    expect(wrapper.vm.listIndex).toBe(0)\n\n    expect('Unable to locate target [data-app]').toHaveBeenTipped()\n  })\n\n  it('should accept a custom role or use default', () => {\n    expect(mountFunction({\n      propsData: { eager: true },\n    }).vm.$refs.content.getAttribute('role')).toBe('menu')\n    expect(mountFunction({\n      propsData: { eager: true },\n      attrs: { role: 'listbox' },\n    }).vm.$refs.content.getAttribute('role')).toBe('listbox')\n\n    expect('Unable to locate target [data-app]').toHaveBeenTipped()\n  })\n\n  it('should select first or last item when opening menu with up or down key', async () => {\n    const event = (keyCode: number) => new KeyboardEvent('keydown', { keyCode })\n    const wrapper = mountFunction({\n      propsData: { eager: true },\n      scopedSlots: {\n        default () {\n          return this.$createElement('div', [\n            this.$createElement(VListItem, { props: { link: true } }),\n            this.$createElement(VListItem, { props: { link: true } }),\n            this.$createElement(VListItem, { props: { link: true } }),\n            this.$createElement(VListItem, { props: { link: true } }),\n          ])\n        },\n      },\n    })\n\n    wrapper.vm.onKeyDown(event(keyCodes.up))\n    expect(wrapper.vm.isActive).toBe(true)\n\n    await wrapper.vm.$nextTick()\n\n    expect(wrapper.vm.listIndex).toBe(3)\n\n    wrapper.setData({ isActive: false })\n\n    wrapper.vm.onKeyDown(event(keyCodes.down))\n    expect(wrapper.vm.isActive).toBe(true)\n\n    await wrapper.vm.$nextTick()\n\n    expect(wrapper.vm.listIndex).toBe(0)\n\n    expect('Unable to locate target [data-app]').toHaveBeenTipped()\n  })\n\n  it('should select first or last item when pressing home or end on active menu', async () => {\n    const event = (keyCode: number) => new KeyboardEvent('keydown', { keyCode })\n    const wrapper = mountFunction({\n      propsData: { eager: true },\n      scopedSlots: {\n        default () {\n          return this.$createElement('div', [\n            this.$createElement(VListItem),\n            this.$createElement(VListItem, { props: { link: true } }),\n            this.$createElement(VListItem, { props: { link: true } }),\n            this.$createElement(VListItem, { props: { link: true } }),\n          ])\n        },\n      },\n    })\n\n    wrapper.setData({ isActive: true })\n\n    wrapper.vm.onKeyDown(event(keyCodes.end))\n\n    await wrapper.vm.$nextTick()\n\n    expect(wrapper.vm.listIndex).toBe(3)\n\n    wrapper.vm.onKeyDown(event(keyCodes.home))\n\n    await wrapper.vm.$nextTick()\n\n    expect(wrapper.vm.listIndex).toBe(1)\n\n    expect('Unable to locate target [data-app]').toHaveBeenTipped()\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VMenu/__tests__/__snapshots__/VMenu.spec.ts.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`VMenu.ts should render multiple content nodes 1`] = `\n<div class=\"v-menu\">\n  <button>\n  </button>\n  <div role=\"menu\"\n       class=\"v-menu__content theme--light \"\n       style=\"max-height: auto; min-width: 0px; max-width: auto; top: 12px; left: 0px; transform-origin: top left; z-index: 0; display: none;\"\n  >\n    <span>\n      foo\n    </span>\n    <span>\n      bar\n    </span>\n  </div>\n</div>\n`;\n\nexports[`VMenu.ts should round dimensions 1`] = `\"max-height: auto; min-width: 0px; max-width: auto; top: 12px; left: 0px; transform-origin: top left; z-index: 0; display: none;\"`;\n\nexports[`VMenu.ts should update position dynamically 1`] = `\"max-height: auto; min-width: 0px; max-width: auto; top: 12px; left: 0px; transform-origin: top left; z-index: 8; display: none;\"`;\n\nexports[`VMenu.ts should update position dynamically 2`] = `\"max-height: auto; min-width: 0px; max-width: auto; top: 12px; left: 0px; transform-origin: top left; z-index: 8; display: none;\"`;\n\nexports[`VMenu.ts should work 1`] = `\n<div class=\"v-menu\">\n  <button>\n  </button>\n  <div role=\"menu\"\n       class=\"v-menu__content theme--light menuable__content__active \"\n       style=\"max-height: auto; min-width: 0px; max-width: auto; top: 12px; left: 0px; transform-origin: top left; z-index: 8; display: none; z-index: 8;\"\n  >\n    <div class=\"v-card v-sheet theme--light\">\n    </div>\n  </div>\n</div>\n`;\n"
  },
  {
    "path": "packages/vuetify/src/components/VMenu/_variables.scss",
    "content": "@use '../../styles/settings';\n\n$menu-elevation: 3 !default;\n$menu-content-border-radius: settings.$border-radius-root !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VMenu/index.ts",
    "content": "export { VMenu } from './VMenu'\n"
  },
  {
    "path": "packages/vuetify/src/components/VMenu/shared.ts",
    "content": "// Types\nimport type { InjectionKey } from 'vue'\n\ninterface MenuProvide {\n  register (): void\n  unregister (): void\n  closeParents (e?: MouseEvent): void\n}\n\nexport const VMenuSymbol: InjectionKey<MenuProvide> = Symbol.for('vuetify:v-menu')\n"
  },
  {
    "path": "packages/vuetify/src/components/VMessages/VMessages.sass",
    "content": "@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-messages\n    flex: 1 1 auto\n    font-size: $messages-font-size\n    min-height: $messages-min-height\n    min-width: 1px // Ensure takes up space with no messages and inside of flex\n    opacity: var(--v-medium-emphasis-opacity)\n    position: relative\n\n    &__message\n      line-height: $messages-line-height\n      word-break: break-word\n      overflow-wrap: break-word\n      word-wrap: break-word\n      hyphens: auto\n      transition-duration: $messages-transition-duration\n"
  },
  {
    "path": "packages/vuetify/src/components/VMessages/VMessages.tsx",
    "content": "// Styles\nimport './VMessages.sass'\n\n// Components\nimport { VSlideYTransition } from '@/components/transitions'\n\n// Composables\nimport { useTextColor } from '@/composables/color'\nimport { makeComponentProps } from '@/composables/component'\nimport { makeTransitionProps, MaybeTransition } from '@/composables/transition'\n\n// Utilities\nimport { computed } from 'vue'\nimport { genericComponent, propsFactory, useRender, wrapInArray } from '@/util'\n\n// Types\nimport type { Component, PropType } from 'vue'\n\nexport type VMessageSlot = {\n  message: string\n}\n\nexport type VMessagesSlots = {\n  message: VMessageSlot\n}\n\nexport const makeVMessagesProps = propsFactory({\n  active: Boolean,\n  color: String,\n  messages: {\n    type: [Array, String] as PropType<string | readonly string[]>,\n    default: () => ([]),\n  },\n\n  ...makeComponentProps(),\n  ...makeTransitionProps({\n    transition: {\n      component: VSlideYTransition as Component,\n      leaveAbsolute: true,\n      group: true,\n    },\n  }),\n}, 'VMessages')\n\nexport const VMessages = genericComponent<VMessagesSlots>()({\n  name: 'VMessages',\n\n  props: makeVMessagesProps(),\n\n  setup (props, { slots }) {\n    const messages = computed(() => wrapInArray(props.messages))\n    const { textColorClasses, textColorStyles } = useTextColor(() => props.color)\n\n    useRender(() => (\n      <MaybeTransition\n        transition={ props.transition }\n        tag=\"div\"\n        class={[\n          'v-messages',\n          textColorClasses.value,\n          props.class,\n        ]}\n        style={[\n          textColorStyles.value,\n          props.style,\n        ]}\n      >\n        { props.active && (\n          messages.value.map((message, i) => (\n            <div\n              class=\"v-messages__message\"\n              key={ `${i}-${messages.value}` }\n            >\n              { slots.message ? slots.message({ message }) : message }\n            </div>\n          ))\n        )}\n      </MaybeTransition>\n    ))\n\n    return {}\n  },\n})\n\nexport type VMessages = InstanceType<typeof VMessages>\n"
  },
  {
    "path": "packages/vuetify/src/components/VMessages/_variables.scss",
    "content": "@use '../../styles/tools';\n\n// VMessages\n$messages-color: tools.theme-color('on-surface', var(--v-medium-emphasis-opacity)) !default;\n$messages-font-size: 12px !default;\n$messages-line-height: $messages-font-size !default;\n$messages-min-height: 14px !default;\n$messages-transition-duration: 150ms !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VMessages/index.ts",
    "content": "export { VMessages } from './VMessages'\n"
  },
  {
    "path": "packages/vuetify/src/components/VNavigationDrawer/VNavigationDrawer.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-navigation-drawer\n    -webkit-overflow-scrolling: $navigation-drawer-overflow-scrolling\n    background: $navigation-drawer-background\n    display: flex\n    flex-direction: column\n    height: $navigation-drawer-height\n    max-width: 100%\n    pointer-events: auto\n    transition-duration: $navigation-drawer-transition-duration\n    transition-property: $navigation-drawer-transition-property\n    transition-timing-function: $navigation-drawer-transition-timing-function\n    position: absolute\n\n    @include tools.border($navigation-drawer-border...)\n    @include tools.elevation($navigation-drawer-elevation)\n    @include tools.rounded($navigation-drawer-border-radius)\n    @include tools.theme($navigation-drawer-theme...)\n\n    @media (prefers-reduced-motion: reduce)\n      transition: none\n\n    &--rounded\n      @include tools.rounded($navigation-drawer-rounded-border-radius)\n\n    &--top\n      top: 0\n      border-bottom-width: $navigation-drawer-border-thin-width\n\n    &--bottom\n      left: 0\n      border-top-width: $navigation-drawer-border-thin-width\n\n    &--left\n      top: 0\n      left: 0\n      right: auto\n      border-right-width: $navigation-drawer-border-thin-width\n\n    &--right\n      top: 0\n      left: auto\n      right: 0\n      border-left-width: $navigation-drawer-border-thin-width\n\n    &--floating\n      border: none\n\n    &--temporary.v-navigation-drawer--active\n      @include tools.elevation($navigation-drawer-temporary-elevation)\n\n    &--sticky\n      height: auto\n      transition: box-shadow, transform, visibility, width, height, left, right\n\n    .v-list\n      overflow: hidden\n\n  .v-navigation-drawer__content\n    flex: 0 1 auto\n    height: $navigation-drawer-content-height\n    max-width: 100%\n    overflow-x: $navigation-drawer-content-overflow-x\n    overflow-y: $navigation-drawer-content-overflow-y\n\n  .v-navigation-drawer__img\n    height: 100%\n    left: 0\n    position: absolute\n    top: 0\n    width: 100%\n    z-index: -1\n\n    // TODO: remove in v4\n    img:not(.v-img__img)\n      height: $navigation-drawer-img-height\n      object-fit: $navigation-drawer-img-object-fit\n      width: $navigation-drawer-img-width\n\n  .v-navigation-drawer__scrim\n    position: absolute\n    top: 0\n    left: 0\n    width: 100%\n    height: 100%\n    background: black\n    opacity: $navigation-drawer-scrim-opacity\n    transition: opacity $navigation-drawer-transition-duration $navigation-drawer-transition-timing-function\n    z-index: 1\n\n  .v-navigation-drawer__prepend,\n  .v-navigation-drawer__append\n    flex: none\n    overflow: hidden\n"
  },
  {
    "path": "packages/vuetify/src/components/VNavigationDrawer/VNavigationDrawer.tsx",
    "content": "// Styles\nimport './VNavigationDrawer.sass'\n\n// Components\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\nimport { VImg } from '@/components/VImg'\n\n// Composables\nimport { useSticky } from './sticky'\nimport { useTouch } from './touch'\nimport { useRtl } from '@/composables'\nimport { makeBorderProps, useBorder } from '@/composables/border'\nimport { useBackgroundColor } from '@/composables/color'\nimport { makeComponentProps } from '@/composables/component'\nimport { provideDefaults } from '@/composables/defaults'\nimport { makeDelayProps, useDelay } from '@/composables/delay'\nimport { makeDisplayProps, useDisplay } from '@/composables/display'\nimport { makeElevationProps, useElevation } from '@/composables/elevation'\nimport { makeFocusTrapProps, useFocusTrap } from '@/composables/focusTrap'\nimport { makeLayoutItemProps, useLayoutItem } from '@/composables/layout'\nimport { useProxiedModel } from '@/composables/proxiedModel'\nimport { makeRoundedProps, useRounded } from '@/composables/rounded'\nimport { useRouter } from '@/composables/router'\nimport { useScopeId } from '@/composables/scopeId'\nimport { useSsrBoot } from '@/composables/ssrBoot'\nimport { makeTagProps } from '@/composables/tag'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\nimport { useToggleScope } from '@/composables/toggleScope'\n\n// Utilities\nimport { computed, nextTick, readonly, ref, shallowRef, toRef, Transition, watch } from 'vue'\nimport { genericComponent, omit, propsFactory, toPhysical, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\nexport type VNavigationDrawerImageSlot = {\n  image: string | undefined\n}\n\nexport type VNavigationDrawerSlots = {\n  default: never\n  prepend: never\n  append: never\n  image: VNavigationDrawerImageSlot\n}\n\nconst locations = ['start', 'end', 'left', 'right', 'top', 'bottom'] as const\n\nexport const makeVNavigationDrawerProps = propsFactory({\n  color: String,\n  disableResizeWatcher: Boolean,\n  disableRouteWatcher: Boolean,\n  expandOnHover: Boolean,\n  floating: Boolean,\n  modelValue: {\n    type: Boolean as PropType<boolean | null>,\n    default: null,\n  },\n  permanent: Boolean,\n  rail: {\n    type: Boolean as PropType<boolean | null>,\n    default: null,\n  },\n  railWidth: {\n    type: [Number, String],\n    default: 56,\n  },\n  scrim: {\n    type: [Boolean, String],\n    default: true,\n  },\n  image: String,\n  temporary: Boolean,\n  persistent: Boolean,\n  touchless: Boolean,\n  width: {\n    type: [Number, String],\n    default: 256,\n  },\n  location: {\n    type: String as PropType<typeof locations[number]>,\n    default: 'start',\n    validator: (value: any) => locations.includes(value),\n  },\n  sticky: Boolean,\n\n  ...makeBorderProps(),\n  ...makeComponentProps(),\n  ...makeDelayProps(),\n  ...makeDisplayProps({ mobile: null }),\n  ...makeElevationProps(),\n  ...makeLayoutItemProps(),\n  ...makeRoundedProps(),\n  ...omit(makeFocusTrapProps(), ['disableInitialFocus']),\n  ...makeTagProps({ tag: 'nav' }),\n  ...makeThemeProps(),\n}, 'VNavigationDrawer')\n\nexport const VNavigationDrawer = genericComponent<VNavigationDrawerSlots>()({\n  name: 'VNavigationDrawer',\n\n  props: makeVNavigationDrawerProps(),\n\n  emits: {\n    'update:modelValue': (val: boolean) => true,\n    'update:rail': (val: boolean) => true,\n  },\n\n  setup (props, { attrs, emit, slots }) {\n    const { isRtl } = useRtl()\n    const { themeClasses } = provideTheme(props)\n    const { borderClasses } = useBorder(props)\n    const { backgroundColorClasses, backgroundColorStyles } = useBackgroundColor(() => props.color)\n    const { elevationClasses } = useElevation(props)\n    const { displayClasses, mobile } = useDisplay(props)\n    const { roundedClasses } = useRounded(props)\n    const router = useRouter()\n    const isActive = useProxiedModel(props, 'modelValue', null, v => !!v)\n    const { ssrBootStyles } = useSsrBoot()\n    const { scopeId } = useScopeId()\n\n    const rootEl = ref<HTMLElement>()\n    const isHovering = shallowRef(false)\n\n    const { runOpenDelay, runCloseDelay } = useDelay(props, value => {\n      isHovering.value = value\n    })\n\n    const width = computed(() => {\n      return (props.rail && props.expandOnHover && isHovering.value)\n        ? Number(props.width)\n        : Number(props.rail ? props.railWidth : props.width)\n    })\n    const location = computed(() => {\n      return toPhysical(props.location, isRtl.value) as 'left' | 'right' | 'bottom'\n    })\n    const isPersistent = toRef(() => props.persistent)\n    const isTemporary = computed(() => !props.permanent && (mobile.value || props.temporary))\n    const isSticky = computed(() =>\n      props.sticky &&\n      !isTemporary.value &&\n      location.value !== 'bottom'\n    )\n\n    useFocusTrap(props, { isActive, localTop: isTemporary, contentEl: rootEl })\n\n    useToggleScope(() => props.expandOnHover && props.rail != null, () => {\n      watch(isHovering, val => emit('update:rail', !val))\n    })\n\n    useToggleScope(() => !props.disableResizeWatcher, () => {\n      watch(isTemporary, val => !props.permanent && (nextTick(() => isActive.value = !val)))\n    })\n\n    useToggleScope(() => !props.disableRouteWatcher && !!router, () => {\n      watch(router!.currentRoute, () => isTemporary.value && (isActive.value = false))\n    })\n\n    watch(() => props.permanent, val => {\n      if (val) isActive.value = true\n    })\n\n    if (props.modelValue == null && !isTemporary.value) {\n      isActive.value = props.permanent || !mobile.value\n    }\n\n    const { isDragging, dragProgress } = useTouch({\n      el: rootEl,\n      isActive,\n      isTemporary,\n      width,\n      touchless: toRef(() => props.touchless),\n      position: location,\n    })\n\n    const layoutSize = computed(() => {\n      const size = isTemporary.value ? 0\n        : props.rail && props.expandOnHover ? Number(props.railWidth)\n        : width.value\n\n      return isDragging.value ? size * dragProgress.value : size\n    })\n    const { layoutItemStyles, layoutItemScrimStyles } = useLayoutItem({\n      id: props.name,\n      order: computed(() => parseInt(props.order, 10)),\n      position: location,\n      layoutSize,\n      elementSize: width,\n      active: readonly(isActive),\n      disableTransitions: toRef(() => isDragging.value),\n      absolute: computed(() =>\n        // eslint-disable-next-line @typescript-eslint/no-use-before-define\n        props.absolute || (isSticky.value && typeof isStuck.value !== 'string')\n      ),\n    })\n\n    const { isStuck, stickyStyles } = useSticky({ rootEl, isSticky, layoutItemStyles })\n\n    const scrimColor = useBackgroundColor(() => {\n      return typeof props.scrim === 'string' ? props.scrim : null\n    })\n    const scrimStyles = computed(() => ({\n      ...isDragging.value ? {\n        opacity: dragProgress.value * 0.2,\n        transition: 'none',\n      } : undefined,\n      ...layoutItemScrimStyles.value,\n    }))\n\n    provideDefaults({\n      VList: {\n        bgColor: 'transparent',\n      },\n    })\n\n    useRender(() => {\n      const hasImage = (slots.image || props.image)\n\n      return (\n        <>\n          <props.tag\n            ref={ rootEl }\n            onMouseenter={ runOpenDelay }\n            onMouseleave={ runCloseDelay }\n            class={[\n              'v-navigation-drawer',\n              `v-navigation-drawer--${location.value}`,\n              {\n                'v-navigation-drawer--expand-on-hover': props.expandOnHover,\n                'v-navigation-drawer--floating': props.floating,\n                'v-navigation-drawer--is-hovering': isHovering.value,\n                'v-navigation-drawer--rail': props.rail,\n                'v-navigation-drawer--temporary': isTemporary.value,\n                'v-navigation-drawer--persistent': isPersistent.value,\n                'v-navigation-drawer--active': isActive.value,\n                'v-navigation-drawer--sticky': isSticky.value,\n              },\n              themeClasses.value,\n              backgroundColorClasses.value,\n              borderClasses.value,\n              displayClasses.value,\n              elevationClasses.value,\n              roundedClasses.value,\n              props.class,\n            ]}\n            style={[\n              backgroundColorStyles.value,\n              layoutItemStyles.value,\n              ssrBootStyles.value,\n              stickyStyles.value,\n              props.style,\n            ]}\n            inert={ !isActive.value }\n            { ...scopeId }\n            { ...attrs }\n          >\n            { hasImage && (\n              <div key=\"image\" class=\"v-navigation-drawer__img\">\n                { !slots.image ? (\n                  <VImg\n                    key=\"image-img\"\n                    alt=\"\"\n                    cover\n                    height=\"inherit\"\n                    src={ props.image }\n                  />\n                ) : (\n                  <VDefaultsProvider\n                    key=\"image-defaults\"\n                    disabled={ !props.image }\n                    defaults={{\n                      VImg: {\n                        alt: '',\n                        cover: true,\n                        height: 'inherit',\n                        src: props.image,\n                      },\n                    }}\n                    v-slots:default={ slots.image }\n                  />\n                )}\n              </div>\n            )}\n\n            { slots.prepend && (\n              <div class=\"v-navigation-drawer__prepend\">\n                { slots.prepend?.() }\n              </div>\n            )}\n\n            <div class=\"v-navigation-drawer__content\">\n              { slots.default?.() }\n            </div>\n\n            { slots.append && (\n              <div class=\"v-navigation-drawer__append\">\n                { slots.append?.() }\n              </div>\n            )}\n          </props.tag>\n\n          <Transition name=\"fade-transition\">\n            { isTemporary.value && (isDragging.value || isActive.value) && !!props.scrim && (\n              <div\n                class={['v-navigation-drawer__scrim', scrimColor.backgroundColorClasses.value]}\n                style={[scrimStyles.value, scrimColor.backgroundColorStyles.value]}\n                onClick={ () => {\n                  if (isPersistent.value) return\n                  isActive.value = false\n                }}\n                { ...scopeId }\n              />\n            )}\n          </Transition>\n        </>\n      )\n    })\n\n    return {\n      isStuck,\n    }\n  },\n})\n\nexport type VNavigationDrawer = InstanceType<typeof VNavigationDrawer>\n"
  },
  {
    "path": "packages/vuetify/src/components/VNavigationDrawer/__tests__/VNavigationDrawer.spec.browser.tsx",
    "content": "// Components\nimport { VNavigationDrawer } from '..'\nimport { VLayout } from '@/components/VLayout'\nimport { VLocaleProvider } from '@/components/VLocaleProvider'\nimport { VMain } from '@/components/VMain'\n\n// Utilities\nimport { commands, page, render, screen, showcase, userEvent } from '@test'\nimport { ref } from 'vue'\n\nconst stories = {\n  'With end location': (\n    <VLayout>\n      <VNavigationDrawer location=\"end\" permanent />\n    </VLayout>\n  ),\n  'With bottom location': (\n    <VLayout>\n      <VNavigationDrawer location=\"bottom\" permanent />\n    </VLayout>\n  ),\n}\n\ndescribe('VNavigationDrawer', () => {\n  beforeEach(async () => {\n    await page.viewport(1280, 768)\n  })\n\n  it('should open when changed to permanent on mobile', async () => {\n    await page.viewport(400, 800)\n    const permanent = ref(false)\n    render(() => (\n      <VLayout>\n        <VNavigationDrawer permanent={ permanent.value } />\n      </VLayout>\n    ))\n\n    const drawer = screen.getByCSS('.v-navigation-drawer')\n\n    await commands.waitStable('.v-navigation-drawer')\n    expect(drawer).toHaveClass('v-navigation-drawer--temporary')\n\n    permanent.value = true\n\n    await commands.waitStable('.v-navigation-drawer')\n    expect(drawer).not.toHaveClass('v-navigation-drawer--temporary')\n  })\n\n  it('should change width when using rail, expandOnHover, and hovering', async () => {\n    render(() => (\n      <VLayout>\n        <VNavigationDrawer modelValue expandOnHover rail />\n      </VLayout>\n    ))\n\n    const drawer = screen.getByCSS('.v-navigation-drawer')\n\n    await expect.element(drawer).toHaveStyle({ width: '56px' })\n\n    await userEvent.hover(drawer)\n    await expect.element(drawer).toHaveStyle({ width: '256px' })\n\n    await userEvent.unhover(drawer)\n    await expect.element(drawer).toHaveStyle({ width: '56px' })\n  })\n\n  it('should change width when using bound and unbound rail and expandOnHover', async () => {\n    const rail = ref(true)\n\n    render(() => (\n      <VLayout>\n        <VNavigationDrawer v-model:rail={ rail.value } expandOnHover />\n\n        <VMain />\n      </VLayout>\n    ))\n\n    const drawer = screen.getByCSS('.v-navigation-drawer')\n    const main = screen.getByCSS('.v-main')\n\n    await expect.element(drawer).toHaveStyle({ width: '56px' })\n    await expect.element(main).toHaveStyle({ paddingLeft: '56px' })\n\n    await userEvent.hover(drawer)\n    await expect.element(drawer).toHaveStyle({ width: '256px' })\n    await expect.element(main).toHaveStyle({ paddingLeft: '256px' })\n\n    await userEvent.unhover(drawer)\n    await expect.element(drawer).toHaveStyle({ width: '56px' })\n    await expect.element(main).toHaveStyle({ paddingLeft: '56px' })\n  })\n\n  it('should hide drawer if window resizes below mobile breakpoint', async () => {\n    render(() => (\n      <VLayout>\n        <VNavigationDrawer />\n      </VLayout>\n    ))\n\n    const drawer = screen.getByCSS('.v-navigation-drawer')\n\n    expect(drawer).toHaveClass('v-navigation-drawer--active')\n\n    await page.viewport(400, 800)\n\n    await commands.waitStable('.v-navigation-drawer')\n    expect(drawer).not.toHaveClass('v-navigation-drawer--active')\n  })\n\n  it('should not hide drawer if window resizes below mobile breakpoint and disable-resize-watcher is used', async () => {\n    await page.viewport(1280, 800)\n    render(() => (\n      <VLayout>\n        <VNavigationDrawer disableResizeWatcher />\n      </VLayout>\n    ))\n\n    expect(screen.getByCSS('.v-navigation-drawer')).toHaveClass('v-navigation-drawer--active')\n    await page.viewport(400, 800)\n    await commands.waitStable('.v-navigation-drawer')\n    expect(screen.getByCSS('.v-navigation-drawer')).toHaveClass('v-navigation-drawer--active')\n  })\n\n  it('should always show drawer if using permanent', async () => {\n    render(() => (\n      <VLayout>\n        <VNavigationDrawer permanent />\n      </VLayout>\n    ))\n\n    expect(screen.getByCSS('.v-navigation-drawer')).toHaveClass('v-navigation-drawer--active')\n    await page.viewport(400, 800)\n    await commands.waitStable('.v-navigation-drawer')\n    expect(screen.getByCSS('.v-navigation-drawer')).toHaveClass('v-navigation-drawer--active')\n    expect(screen.getByCSS('.v-navigation-drawer')).not.toHaveClass('v-navigation-drawer--temporary')\n  })\n\n  it('should show temporary drawer', async () => {\n    const model = ref()\n    render(() => (\n      <VLayout>\n        <VNavigationDrawer temporary modelValue={ model.value } />\n      </VLayout>\n    ))\n\n    const drawer = screen.getByCSS('.v-navigation-drawer')\n\n    await expect.element(drawer).toHaveClass('v-navigation-drawer--temporary')\n    await expect.element(drawer).not.toHaveClass('v-navigation-drawer--active')\n\n    model.value = true\n\n    await expect.element(drawer).toHaveClass('v-navigation-drawer--active')\n  })\n\n  it('should allow custom widths', async () => {\n    render(() => (\n      <VLayout>\n        <VNavigationDrawer width={ 300 } permanent />\n      </VLayout>\n    ))\n\n    await expect.element(screen.getByCSS('.v-navigation-drawer')).toHaveStyle({ width: '300px' })\n  })\n\n  it('should position drawer scrim correctly', async () => {\n    const visible = ref(false)\n    render(() => (\n      <VLayout>\n        <VNavigationDrawer v-model={ visible.value } temporary />\n      </VLayout>\n    ))\n\n    expect(screen.queryAllByCSS('.v-navigation-drawer__scrim')).toHaveLength(0)\n\n    visible.value = true\n\n    await expect.element(screen.getByCSS('.v-navigation-drawer')).toBeInViewport()\n    await expect.element(screen.getByCSS('.v-navigation-drawer__scrim')).toBeInViewport()\n  })\n\n  it('should position drawer scrim correctly in rtl locale', async () => {\n    const visible = ref(false)\n    render(() => (\n      <VLocaleProvider rtl>\n        <VLayout>\n          <VNavigationDrawer v-model={ visible.value } temporary />\n        </VLayout>\n      </VLocaleProvider>\n    ))\n\n    expect(screen.queryAllByCSS('.v-navigation-drawer__scrim')).toHaveLength(0)\n\n    visible.value = true\n\n    await expect.element(screen.getByCSS('.v-navigation-drawer')).toBeInViewport()\n    await expect.element(screen.getByCSS('.v-navigation-drawer__scrim')).toBeInViewport()\n  })\n\n  showcase({ stories })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VNavigationDrawer/_variables.scss",
    "content": "@use 'sass:map';\n@use '../../styles/settings';\n@use '../../styles/tools';\n\n// VNavigationDrawer\n$navigation-drawer-background: rgb(var(--v-theme-surface)) !default;\n$navigation-drawer-border-color: settings.$border-color-root !default;\n$navigation-drawer-border-radius: map.get(settings.$rounded, '0') !default;\n$navigation-drawer-border-style: settings.$border-style-root !default;\n$navigation-drawer-border-thin-width: thin !default;\n$navigation-drawer-border-width: 0 !default;\n$navigation-drawer-color: tools.theme-color('on-surface', var(--v-high-emphasis-opacity)) !default;\n$navigation-drawer-content-height: 100% !default;\n$navigation-drawer-content-overflow-x: hidden !default;\n$navigation-drawer-content-overflow-y: auto !default;\n$navigation-drawer-elevation: 0 !default;\n$navigation-drawer-height: 100% !default;\n$navigation-drawer-img-height: inherit !default;\n$navigation-drawer-img-object-fit: cover !default;\n$navigation-drawer-img-width: inherit !default;\n$navigation-drawer-overflow-scrolling: touch !default;\n$navigation-drawer-rounded-border-radius: settings.$border-radius-root !default;\n$navigation-drawer-temporary-elevation: 4 !default;\n$navigation-drawer-transition-duration: 0.2s !default;\n$navigation-drawer-transition-property: box-shadow, transform, visibility, width, height, left, right, top, bottom !default;\n$navigation-drawer-transition-timing-function: settings.$standard-easing !default;\n$navigation-drawer-scrim-opacity: .2 !default;\n\n// Lists\n$navigation-drawer-border: (\n  $navigation-drawer-border-color,\n  $navigation-drawer-border-style,\n  $navigation-drawer-border-width,\n  $navigation-drawer-border-thin-width\n) !default;\n\n$navigation-drawer-theme: (\n  $navigation-drawer-background,\n  $navigation-drawer-color\n) !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VNavigationDrawer/index.ts",
    "content": "export { VNavigationDrawer } from './VNavigationDrawer'\n"
  },
  {
    "path": "packages/vuetify/src/components/VNavigationDrawer/sticky.ts",
    "content": "// Utilities\nimport { computed, onBeforeUnmount, onMounted, shallowRef, watch } from 'vue'\nimport { convertToUnit } from '@/util'\n\n// Types\nimport type { CSSProperties, Ref, StyleValue } from 'vue'\n\ninterface StickyProps {\n  rootEl: Ref<HTMLElement | undefined>\n  isSticky: Ref<boolean>\n  layoutItemStyles: Ref<CSSProperties>\n}\n\nexport function useSticky ({ rootEl, isSticky, layoutItemStyles }: StickyProps) {\n  const isStuck = shallowRef<boolean | 'top' | 'bottom'>(false)\n  const stuckPosition = shallowRef(0)\n\n  const stickyStyles = computed<StyleValue>(() => {\n    const side = typeof isStuck.value === 'boolean' ? 'top' : isStuck.value\n    return [\n      isSticky.value ? { top: 'auto', bottom: 'auto', height: undefined } : undefined,\n      isStuck.value\n        ? { [side]: convertToUnit(stuckPosition.value) }\n        : { top: layoutItemStyles.value.top },\n    ]\n  })\n\n  onMounted(() => {\n    watch(isSticky, val => {\n      if (val) {\n        window.addEventListener('scroll', onScroll, { passive: true })\n      } else {\n        window.removeEventListener('scroll', onScroll)\n      }\n    }, { immediate: true })\n  })\n\n  onBeforeUnmount(() => {\n    window.removeEventListener('scroll', onScroll)\n  })\n\n  let lastScrollTop = 0\n  function onScroll () {\n    const direction = lastScrollTop > window.scrollY ? 'up' : 'down'\n    const rect = rootEl.value!.getBoundingClientRect()\n    const layoutTop = parseFloat(layoutItemStyles.value.top ?? 0)\n    const top = window.scrollY - Math.max(0, stuckPosition.value - layoutTop)\n    const bottom =\n      rect.height +\n      Math.max(stuckPosition.value, layoutTop) -\n      window.scrollY -\n      window.innerHeight\n    const bodyScroll = parseFloat(getComputedStyle(rootEl.value!).getPropertyValue('--v-body-scroll-y')) || 0\n\n    if (rect.height < window.innerHeight - layoutTop) {\n      isStuck.value = 'top'\n      stuckPosition.value = layoutTop\n    } else if (\n      (direction === 'up' && isStuck.value === 'bottom') ||\n      (direction === 'down' && isStuck.value === 'top')\n    ) {\n      stuckPosition.value = window.scrollY + rect.top - bodyScroll\n      isStuck.value = true\n    } else if (direction === 'down' && bottom <= 0) {\n      stuckPosition.value = 0\n      isStuck.value = 'bottom'\n    } else if (direction === 'up' && top <= 0) {\n      if (!bodyScroll) {\n        stuckPosition.value = rect.top + top\n        isStuck.value = 'top'\n      } else if (isStuck.value !== 'top') {\n        stuckPosition.value = -top + bodyScroll + layoutTop\n        isStuck.value = 'top'\n      }\n    }\n\n    lastScrollTop = window.scrollY\n  }\n\n  return { isStuck, stickyStyles }\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VNavigationDrawer/touch.ts",
    "content": "// Composables\nimport { useToggleScope } from '@/composables/toggleScope'\nimport { useVelocity } from '@/composables/touch'\n\n// Utilities\nimport { computed, onBeforeUnmount, onMounted, onScopeDispose, shallowRef, watchEffect } from 'vue'\nimport { clamp } from '@/util'\n\n// Types\nimport type { Ref } from 'vue'\n\nexport function useTouch ({\n  el,\n  isActive,\n  isTemporary,\n  width,\n  touchless,\n  position,\n}: {\n  el: Ref<HTMLElement | undefined>\n  isActive: Ref<boolean>\n  isTemporary: Ref<boolean>\n  width: Ref<number>\n  touchless: Ref<boolean>\n  position: Ref<'left' | 'right' | 'top' | 'bottom'>\n}) {\n  onMounted(() => {\n    window.addEventListener('touchstart', onTouchstart, { passive: true })\n    window.addEventListener('touchmove', onTouchmove, { passive: false })\n    window.addEventListener('touchend', onTouchend, { passive: true })\n  })\n\n  onBeforeUnmount(() => {\n    window.removeEventListener('touchstart', onTouchstart)\n    window.removeEventListener('touchmove', onTouchmove)\n    window.removeEventListener('touchend', onTouchend)\n  })\n\n  const isHorizontal = computed(() => ['left', 'right'].includes(position.value))\n\n  const { addMovement, endTouch, getVelocity } = useVelocity()\n  let maybeDragging = false\n  const isDragging = shallowRef(false)\n  const dragProgress = shallowRef(0)\n  const offset = shallowRef(0)\n  let start: [number, number] | undefined\n\n  function getOffset (pos: number, active: boolean): number {\n    return (\n      position.value === 'left' ? pos\n      : position.value === 'right' ? document.documentElement.clientWidth - pos\n      : position.value === 'top' ? pos\n      : position.value === 'bottom' ? document.documentElement.clientHeight - pos\n      : oops()\n    ) - (active ? width.value : 0)\n  }\n\n  function getProgress (pos: number, limit = true): number {\n    const progress = (\n      position.value === 'left' ? (pos - offset.value) / width.value\n      : position.value === 'right' ? (document.documentElement.clientWidth - pos - offset.value) / width.value\n      : position.value === 'top' ? (pos - offset.value) / width.value\n      : position.value === 'bottom' ? (document.documentElement.clientHeight - pos - offset.value) / width.value\n      : oops()\n    )\n    return limit ? clamp(progress) : progress\n  }\n\n  function onTouchstart (e: TouchEvent) {\n    if (touchless.value) return\n\n    const touchX = e.changedTouches[0].clientX\n    const touchY = e.changedTouches[0].clientY\n\n    const touchZone = 25\n    const inTouchZone: boolean =\n      position.value === 'left' ? touchX < touchZone\n      : position.value === 'right' ? touchX > document.documentElement.clientWidth - touchZone\n      : position.value === 'top' ? touchY < touchZone\n      : position.value === 'bottom' ? touchY > document.documentElement.clientHeight - touchZone\n      : oops()\n\n    const inElement: boolean = isActive.value && (\n      position.value === 'left' ? touchX < width.value\n      : position.value === 'right' ? touchX > document.documentElement.clientWidth - width.value\n      : position.value === 'top' ? touchY < width.value\n      : position.value === 'bottom' ? touchY > document.documentElement.clientHeight - width.value\n      : oops()\n    )\n\n    if (\n      inTouchZone ||\n      inElement ||\n      (isActive.value && isTemporary.value)\n    ) {\n      start = [touchX, touchY]\n\n      offset.value = getOffset(isHorizontal.value ? touchX : touchY, isActive.value)\n      dragProgress.value = getProgress(isHorizontal.value ? touchX : touchY)\n\n      maybeDragging = offset.value > -20 && offset.value < 80\n      endTouch(e)\n      addMovement(e)\n    }\n  }\n\n  function onTouchmove (e: TouchEvent) {\n    const touchX = e.changedTouches[0].clientX\n    const touchY = e.changedTouches[0].clientY\n\n    if (maybeDragging) {\n      if (!e.cancelable) {\n        maybeDragging = false\n        return\n      }\n\n      const dx = Math.abs(touchX - start![0])\n      const dy = Math.abs(touchY - start![1])\n\n      const thresholdMet = isHorizontal.value\n        ? dx > dy && dx > 3\n        : dy > dx && dy > 3\n\n      if (thresholdMet) {\n        isDragging.value = true\n        maybeDragging = false\n      } else if ((isHorizontal.value ? dy : dx) > 3) {\n        maybeDragging = false\n      }\n    }\n\n    if (!isDragging.value) return\n\n    e.preventDefault()\n    addMovement(e)\n\n    const progress = getProgress(isHorizontal.value ? touchX : touchY, false)\n    dragProgress.value = Math.max(0, Math.min(1, progress))\n\n    if (progress > 1) {\n      offset.value = getOffset(isHorizontal.value ? touchX : touchY, true)\n    } else if (progress < 0) {\n      offset.value = getOffset(isHorizontal.value ? touchX : touchY, false)\n    }\n  }\n\n  function onTouchend (e: TouchEvent) {\n    maybeDragging = false\n\n    if (!isDragging.value) return\n\n    addMovement(e)\n\n    isDragging.value = false\n\n    const velocity = getVelocity(e.changedTouches[0].identifier)\n    const vx = Math.abs(velocity.x)\n    const vy = Math.abs(velocity.y)\n    const thresholdMet = isHorizontal.value\n      ? vx > vy && vx > 400\n      : vy > vx && vy > 3\n\n    if (thresholdMet) {\n      isActive.value = velocity.direction === ({\n        left: 'right',\n        right: 'left',\n        top: 'down',\n        bottom: 'up',\n      }[position.value] || oops())\n    } else {\n      isActive.value = dragProgress.value > 0.5\n    }\n  }\n\n  const dragStyles = computed(() => {\n    return isDragging.value ? {\n      transform:\n        position.value === 'left' ? `translateX(calc(-100% + ${dragProgress.value * width.value}px))`\n        : position.value === 'right' ? `translateX(calc(100% - ${dragProgress.value * width.value}px))`\n        : position.value === 'top' ? `translateY(calc(-100% + ${dragProgress.value * width.value}px))`\n        : position.value === 'bottom' ? `translateY(calc(100% - ${dragProgress.value * width.value}px))`\n        : oops(),\n      transition: 'none',\n    } : undefined\n  })\n\n  useToggleScope(isDragging, () => {\n    const transform = el.value?.style.transform ?? null\n    const transition = el.value?.style.transition ?? null\n\n    watchEffect(() => {\n      el.value?.style.setProperty('transform', dragStyles.value?.transform || 'none')\n      el.value?.style.setProperty('transition', dragStyles.value?.transition || null)\n    })\n\n    onScopeDispose(() => {\n      el.value?.style.setProperty('transform', transform)\n      el.value?.style.setProperty('transition', transition)\n    })\n  })\n\n  return {\n    isDragging,\n    dragProgress,\n    dragStyles,\n  }\n}\n\nfunction oops (): never {\n  throw new Error()\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VNoSsr/VNoSsr.tsx",
    "content": "// Composables\nimport { useHydration } from '@/composables/hydration'\n\n// Utilities\nimport { defineComponent } from '@/util'\n\nexport const VNoSsr = defineComponent({\n  name: 'VNoSsr',\n\n  setup (_, { slots }) {\n    const show = useHydration()\n\n    return () => show.value && slots.default?.()\n  },\n})\n\nexport type VNoSsr = InstanceType<typeof VNoSsr>\n"
  },
  {
    "path": "packages/vuetify/src/components/VNoSsr/index.ts",
    "content": "export { VNoSsr } from './VNoSsr'\n"
  },
  {
    "path": "packages/vuetify/src/components/VNumberInput/VNumberInput.sass",
    "content": "@use 'sass:selector'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-number-input\n    input[type=\"number\"]\n      -moz-appearance: textfield\n\n      &::-webkit-outer-spin-button,\n      &::-webkit-inner-spin-button\n        -webkit-appearance: none\n\n    .v-field\n      &:has(.v-field__prepend-inner > .v-number-input__control:first-child)\n        padding-inline-start: 0\n\n      &:has(.v-field__append-inner > .v-number-input__control:last-child)\n        padding-inline-end: 0\n\n    .v-field__prepend-inner:has(.v-number-input__control)\n      overflow: hidden\n      border-start-start-radius: inherit\n      border-end-start-radius: inherit\n\n      > .v-icon\n        margin-inline-end: 4px\n\n      > hr + .v-icon,\n      > .v-number-input__control + .v-icon\n        margin-inline: 8px 0\n\n      .v-divider--vertical\n        margin-inline: -1px 0\n\n    .v-field__append-inner:has(.v-number-input__control)\n      overflow: hidden\n      border-start-end-radius: inherit\n      border-end-end-radius: inherit\n\n      > .v-icon\n        margin-inline-start: 4px\n\n      > .v-icon:has(+ hr),\n      > .v-icon:has(+ .v-number-input__control)\n        margin-inline: 0 8px\n\n      .v-divider--vertical\n        margin-inline: 0 -1px\n\n    .v-field__clearable:has(+ .v-field__append-inner > hr:first-child)\n      margin-inline-end: 8px\n\n    &--inset\n      .v-divider\n        height: $number-input-inset-divider-size\n        width: $number-input-inset-divider-size\n        align-self: center\n\n    &--split\n      .v-field__input\n        text-align: center\n\n    &--stacked\n      .v-number-input__control\n        flex-direction: column-reverse\n        .v-btn\n          flex: 1\n\n      .v-field--variant-underlined\n        > .v-field__prepend-inner:has(.v-number-input__control),\n        > .v-field__append-inner:has(.v-number-input__control)\n          // drop input padding\n          padding-top: var(--v-field-padding-top)\n          // and pass it down\n          > *:not(.v-number-input__control, .v-divider--vertical)\n            margin-top: var(--v-input-padding-top, 0)\n\n    &--hide-input\n      .v-field\n        flex: none\n        gap: 0\n        &__input\n          width: 0\n          padding-inline: 0\n\n    &__control\n      display: flex\n      height: 100%\n\n      .v-btn\n        background-color: transparent\n        border-radius: 0\n"
  },
  {
    "path": "packages/vuetify/src/components/VNumberInput/VNumberInput.tsx",
    "content": "// Styles\nimport './VNumberInput.sass'\n\n// Components\nimport { VBtn } from '@/components/VBtn'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\nimport { VDivider } from '@/components/VDivider'\nimport { makeVTextFieldProps, VTextField } from '@/components/VTextField/VTextField'\n\n// Composables\nimport { useHold } from './hold'\nimport { useForm } from '@/composables/form'\nimport { forwardRefs } from '@/composables/forwardRefs'\nimport { useLocale } from '@/composables/locale'\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { computed, nextTick, ref, shallowRef, toRef, watch } from 'vue'\nimport { clamp, escapeForRegex, extractNumber, genericComponent, omit, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { VTextFieldSlots } from '@/components/VTextField/VTextField'\n\ntype ControlSlot = {\n  props: Record<string, unknown>\n}\n\ntype VNumberInputSlots = Omit<VTextFieldSlots, 'default'> & {\n  increment: ControlSlot\n  decrement: ControlSlot\n}\n\ntype ControlVariant = 'default' | 'stacked' | 'split' | 'hidden'\n\nconst makeVNumberInputProps = propsFactory({\n  controlVariant: {\n    type: String as PropType<ControlVariant>,\n    default: 'default',\n  },\n  inset: Boolean,\n  hideInput: Boolean,\n  modelValue: {\n    type: Number as PropType<number | null>,\n    default: null,\n  },\n  min: {\n    type: Number,\n    default: Number.MIN_SAFE_INTEGER,\n  },\n  max: {\n    type: Number,\n    default: Number.MAX_SAFE_INTEGER,\n  },\n  step: {\n    type: Number,\n    default: 1,\n  },\n  precision: {\n    type: Number as PropType<number | null>,\n    default: 0,\n  },\n  minFractionDigits: {\n    type: Number as PropType<number | null>,\n    default: null,\n  },\n  decimalSeparator: {\n    type: String,\n    validator: (v: any) => !v || v.length === 1,\n  },\n\n  ...omit(makeVTextFieldProps(), ['modelValue', 'validationValue']),\n}, 'VNumberInput')\n\nexport const VNumberInput = genericComponent<VNumberInputSlots>()({\n  name: 'VNumberInput',\n\n  props: {\n    ...makeVNumberInputProps(),\n  },\n\n  emits: {\n    'update:focused': (val: boolean) => true,\n    'update:modelValue': (val: number) => true,\n  },\n\n  setup (props, { slots }) {\n    const vTextFieldRef = ref<VTextField>()\n\n    const { holdStart, holdStop } = useHold({ toggleUpDown })\n    const form = useForm(props)\n    const controlsDisabled = computed(() => (\n      form.isDisabled.value || form.isReadonly.value\n    ))\n\n    const isFocused = shallowRef(props.focused)\n\n    const { decimalSeparator: decimalSeparatorFromLocale } = useLocale()\n    const decimalSeparator = computed(() => props.decimalSeparator?.[0] || decimalSeparatorFromLocale.value)\n\n    function correctPrecision (val: number, precision = props.precision, trim = true) {\n      const fixed = precision == null\n        ? String(val)\n        : val.toFixed(precision)\n\n      if (isFocused.value && trim) {\n        return Number(fixed).toString() // trim zeros\n          .replace('.', decimalSeparator.value)\n      }\n\n      if (props.minFractionDigits === null || (precision !== null && precision < props.minFractionDigits)) {\n        return fixed.replace('.', decimalSeparator.value)\n      }\n\n      let [baseDigits, fractionDigits] = fixed.split('.')\n\n      fractionDigits = (fractionDigits ?? '').padEnd(props.minFractionDigits, '0')\n        .replace(new RegExp(`(?<=\\\\d{${props.minFractionDigits}})0+$`, 'g'), '')\n\n      return [\n        baseDigits,\n        fractionDigits,\n      ].filter(Boolean).join(decimalSeparator.value)\n    }\n\n    const model = useProxiedModel(props, 'modelValue', null,\n      val => val ?? null,\n      val => val == null\n        ? val ?? null\n        : clamp(Number(val), props.min, props.max)\n    )\n\n    const _inputText = shallowRef<string | null>(null)\n    const _lastParsedValue = shallowRef<number | null>(null)\n\n    watch(model, val => {\n      if (\n        isFocused.value &&\n          !controlsDisabled.value &&\n          Number(_inputText.value?.replace(decimalSeparator.value, '.')) === val\n      ) {\n        // ignore external changes while typing\n        // e.g. 5.01{backspace}2 » should result in 5.02\n        //      but we emit '5' in and want to preserve '5.0'\n      } else if (val == null) {\n        _inputText.value = null\n        _lastParsedValue.value = null\n      } else if (!isNaN(val)) {\n        _inputText.value = correctPrecision(val)\n        _lastParsedValue.value = Number(_inputText.value.replace(decimalSeparator.value, '.'))\n      }\n    }, { immediate: true })\n\n    const inputText = computed<string | null>({\n      get: () => _inputText.value,\n      set (val) {\n        if (val === null || val === '') {\n          model.value = null\n          _inputText.value = null\n          _lastParsedValue.value = null\n          return\n        }\n        const parsedValue = Number(val.replace(decimalSeparator.value, '.'))\n        if (!isNaN(parsedValue)) {\n          _inputText.value = val\n          _lastParsedValue.value = parsedValue\n\n          if (parsedValue <= props.max && parsedValue >= props.min) {\n            model.value = parsedValue\n          }\n        }\n      },\n    })\n\n    const isOutOfRange = computed(() => {\n      if (_lastParsedValue.value === null) return false\n      const numberFromText = Number(_inputText.value?.replace(decimalSeparator.value, '.'))\n      return numberFromText !== clamp(numberFromText, props.min, props.max)\n    })\n\n    const canIncrease = computed(() => {\n      if (controlsDisabled.value) return false\n      return (model.value ?? 0) as number + props.step <= props.max\n    })\n    const canDecrease = computed(() => {\n      if (controlsDisabled.value) return false\n      return (model.value ?? 0) as number - props.step >= props.min\n    })\n\n    const controlVariant = computed(() => {\n      return props.hideInput ? 'stacked' : props.controlVariant\n    })\n\n    const incrementIcon = toRef(() => controlVariant.value === 'split' ? '$plus' : '$collapse')\n    const decrementIcon = toRef(() => controlVariant.value === 'split' ? '$minus' : '$expand')\n    const controlNodeSize = toRef(() => controlVariant.value === 'split' ? 'default' : 'small')\n    const controlNodeDefaultHeight = toRef(() => controlVariant.value === 'stacked' ? 'auto' : '100%')\n\n    const incrementSlotProps = {\n      props: {\n        onClick: onControlClick,\n        onPointerup: onControlMouseup,\n        onPointerdown: onUpControlMousedown,\n        onPointercancel: onControlMouseup,\n      },\n    }\n    const decrementSlotProps = {\n      props: {\n        onClick: onControlClick,\n        onPointerup: onControlMouseup,\n        onPointerdown: onDownControlMousedown,\n        onPointercancel: onControlMouseup,\n      },\n    }\n\n    watch(() => props.precision, () => formatInputValue())\n    watch(() => props.minFractionDigits, () => formatInputValue())\n\n    function inferPrecision (value: number | null) {\n      if (value == null) return 0\n      const str = value.toString()\n      const idx = str.indexOf('.')\n      return ~idx ? str.length - idx : 0\n    }\n\n    function toggleUpDown (increment = true) {\n      if (controlsDisabled.value) return\n      if (model.value == null) {\n        inputText.value = correctPrecision(clamp(0, props.min, props.max))\n        return\n      }\n\n      let inferredPrecision = Math.max(inferPrecision(model.value), inferPrecision(props.step))\n      if (props.precision != null) inferredPrecision = Math.max(inferredPrecision, props.precision)\n      if (increment) {\n        if (canIncrease.value) inputText.value = correctPrecision(model.value + props.step, inferredPrecision)\n      } else {\n        if (canDecrease.value) inputText.value = correctPrecision(model.value - props.step, inferredPrecision)\n      }\n    }\n\n    function onBeforeinput (e: InputEvent) {\n      if (controlsDisabled.value) return\n      if (!e.data) return\n      const inputElement = e.target as HTMLInputElement\n      const { value: existingTxt, selectionStart, selectionEnd } = inputElement ?? {}\n\n      const potentialNewInputVal =\n        existingTxt\n          ? existingTxt.slice(0, selectionStart as number | undefined) + e.data + existingTxt.slice(selectionEnd as number | undefined)\n          : e.data\n\n      const potentialNewNumber = extractNumber(potentialNewInputVal, props.precision, decimalSeparator.value)\n\n      // Allow only numbers, \"-\" and {decimal separator}\n      // Allow \"-\" and {decimal separator} only once\n      // Allow \"-\" only at the start\n      if (!new RegExp(`^-?\\\\d*${escapeForRegex(decimalSeparator.value)}?\\\\d*$`).test(potentialNewInputVal)) {\n        e.preventDefault()\n        inputElement!.value = potentialNewNumber\n        nextTick(() => inputText.value = potentialNewNumber)\n      }\n\n      if (props.precision == null) return\n\n      // Ignore decimal digits above precision limit\n      if (potentialNewInputVal.split(decimalSeparator.value)[1]?.length > props.precision) {\n        e.preventDefault()\n        inputElement!.value = potentialNewNumber\n        nextTick(() => inputText.value = potentialNewNumber)\n\n        const cursorPosition = (selectionStart ?? 0) + e.data.length\n        inputElement!.setSelectionRange(cursorPosition, cursorPosition)\n      }\n      // Ignore decimal separator when precision = 0\n      if (props.precision === 0 && potentialNewInputVal.endsWith(decimalSeparator.value)) {\n        e.preventDefault()\n        inputElement!.value = potentialNewNumber\n        nextTick(() => inputText.value = potentialNewNumber)\n      }\n    }\n\n    async function onKeydown (e: KeyboardEvent) {\n      if (\n        ['Enter', 'ArrowLeft', 'ArrowRight', 'Backspace', 'Delete', 'Tab'].includes(e.key) ||\n        e.ctrlKey\n      ) return\n\n      if (['ArrowDown', 'ArrowUp'].includes(e.key)) {\n        e.preventDefault()\n        e.stopPropagation()\n        clampModel()\n        // _model is controlled, so need to wait until props['modelValue'] is updated\n        await nextTick()\n        if (e.key === 'ArrowDown') {\n          toggleUpDown(false)\n        } else {\n          toggleUpDown()\n        }\n      }\n    }\n\n    function onControlClick (e: MouseEvent) {\n      e.stopPropagation()\n    }\n\n    function onControlMouseup (e: PointerEvent) {\n      const el = e.currentTarget as HTMLElement\n      el?.releasePointerCapture(e.pointerId)\n      e.preventDefault()\n      holdStop()\n    }\n\n    function onUpControlMousedown (e: PointerEvent) {\n      const el = e.currentTarget as HTMLElement\n      el?.setPointerCapture(e.pointerId)\n      e.preventDefault()\n      e.stopPropagation()\n      holdStart('up')\n    }\n\n    function onDownControlMousedown (e: PointerEvent) {\n      const el = e.currentTarget as HTMLElement\n      el?.setPointerCapture(e.pointerId)\n      e.preventDefault()\n      e.stopPropagation()\n      holdStart('down')\n    }\n\n    function clampModel () {\n      if (controlsDisabled.value) return\n      if (!vTextFieldRef.value) return\n      const actualText = vTextFieldRef.value.value\n      const parsedValue = Number(actualText.replace(decimalSeparator.value, '.'))\n      if (actualText && !isNaN(parsedValue)) {\n        inputText.value = correctPrecision(clamp(parsedValue, props.min, props.max))\n      } else {\n        inputText.value = null\n      }\n    }\n\n    function formatInputValue () {\n      if (controlsDisabled.value) return\n      inputText.value = model.value !== null && !isNaN(model.value)\n        ? correctPrecision(model.value, props.precision, false)\n        : null\n    }\n\n    function trimDecimalZeros () {\n      if (controlsDisabled.value) return\n      if (model.value === null || isNaN(model.value)) {\n        inputText.value = null\n        return\n      }\n      inputText.value = model.value.toString()\n        .replace('.', decimalSeparator.value)\n    }\n\n    function onFocus () {\n      trimDecimalZeros()\n    }\n\n    function onBlur () {\n      clampModel()\n    }\n\n    useRender(() => {\n      const { modelValue: _, type, ...textFieldProps } = VTextField.filterProps(props)\n\n      function incrementControlNode () {\n        return !slots.increment ? (\n          <VBtn\n            aria-hidden=\"true\"\n            data-testid=\"increment\"\n            disabled={ !canIncrease.value }\n            height={ controlNodeDefaultHeight.value }\n            icon={ incrementIcon.value }\n            key=\"increment-btn\"\n            onClick={ onControlClick }\n            onPointerdown={ onUpControlMousedown }\n            onPointerup={ onControlMouseup }\n            onPointercancel={ onControlMouseup }\n            size={ controlNodeSize.value }\n            variant=\"text\"\n            tabindex=\"-1\"\n          />\n        ) : (\n          <VDefaultsProvider\n            key=\"increment-defaults\"\n            defaults={{\n              VBtn: {\n                disabled: !canIncrease.value,\n                height: controlNodeDefaultHeight.value,\n                size: controlNodeSize.value,\n                icon: incrementIcon.value,\n                variant: 'text',\n              },\n            }}\n          >\n            { slots.increment(incrementSlotProps) }\n          </VDefaultsProvider>\n        )\n      }\n\n      function decrementControlNode () {\n        return !slots.decrement ? (\n          <VBtn\n            aria-hidden=\"true\"\n            data-testid=\"decrement\"\n            disabled={ !canDecrease.value }\n            height={ controlNodeDefaultHeight.value }\n            icon={ decrementIcon.value }\n            key=\"decrement-btn\"\n            onClick={ onControlClick }\n            onPointerdown={ onDownControlMousedown }\n            onPointerup={ onControlMouseup }\n            onPointercancel={ onControlMouseup }\n            size={ controlNodeSize.value }\n            variant=\"text\"\n            tabindex=\"-1\"\n          />\n        ) : (\n          <VDefaultsProvider\n            key=\"decrement-defaults\"\n            defaults={{\n              VBtn: {\n                disabled: !canDecrease.value,\n                height: controlNodeDefaultHeight.value,\n                size: controlNodeSize.value,\n                icon: decrementIcon.value,\n                variant: 'text',\n              },\n            }}\n          >\n            { slots.decrement(decrementSlotProps) }\n          </VDefaultsProvider>\n        )\n      }\n\n      function controlNode () {\n        return (\n          <div class=\"v-number-input__control\">\n            { decrementControlNode() }\n\n            <VDivider\n              vertical={ controlVariant.value !== 'stacked' }\n            />\n\n            { incrementControlNode() }\n          </div>\n        )\n      }\n\n      function dividerNode () {\n        return !props.hideInput && !props.inset ? <VDivider vertical /> : undefined\n      }\n\n      const appendInnerControl =\n        controlVariant.value === 'split'\n          ? (\n            <div class=\"v-number-input__control\">\n              <VDivider vertical />\n\n              { incrementControlNode() }\n            </div>\n          ) : (props.reverse || controlVariant.value === 'hidden'\n            ? undefined\n            : <>{ dividerNode() }{ controlNode() }</>)\n\n      const hasAppendInner = slots['append-inner'] || appendInnerControl\n\n      const prependInnerControl =\n        controlVariant.value === 'split'\n          ? (\n            <div class=\"v-number-input__control\">\n              { decrementControlNode() }\n\n              <VDivider vertical />\n            </div>\n          ) : (props.reverse && controlVariant.value !== 'hidden'\n            ? <>{ controlNode() }{ dividerNode() }</>\n            : undefined)\n\n      const hasPrependInner = slots['prepend-inner'] || prependInnerControl\n\n      return (\n        <VTextField\n          ref={ vTextFieldRef }\n          { ...textFieldProps }\n          v-model={ inputText.value }\n          v-model:focused={ isFocused.value }\n          validationValue={ model.value }\n          error={ props.error || isOutOfRange.value || undefined }\n          onBeforeinput={ onBeforeinput }\n          onFocus={ onFocus }\n          onBlur={ onBlur }\n          onKeydown={ onKeydown }\n          class={[\n            'v-number-input',\n            {\n              'v-number-input--default': controlVariant.value === 'default',\n              'v-number-input--hide-input': props.hideInput,\n              'v-number-input--inset': props.inset,\n              'v-number-input--reverse': props.reverse,\n              'v-number-input--split': controlVariant.value === 'split',\n              'v-number-input--stacked': controlVariant.value === 'stacked',\n            },\n            props.class,\n          ]}\n          style={ props.style }\n          inputmode=\"decimal\"\n        >\n          {{\n            ...slots,\n            'append-inner': hasAppendInner ? (...args) => (\n              <>\n                { slots['append-inner']?.(...args) }\n                { appendInnerControl }\n              </>\n            ) : undefined,\n            'prepend-inner': hasPrependInner ? (...args) => (\n              <>\n                { prependInnerControl }\n                { slots['prepend-inner']?.(...args) }\n              </>\n            ) : undefined,\n          }}\n        </VTextField>\n      )\n    })\n\n    return forwardRefs({}, vTextFieldRef)\n  },\n})\n\nexport type VNumberInput = InstanceType<typeof VNumberInput>\n"
  },
  {
    "path": "packages/vuetify/src/components/VNumberInput/__tests__/VNumberInput.spec.browser.tsx",
    "content": "// Components\nimport { VNumberInput } from '../VNumberInput'\nimport { VForm } from '@/components/VForm'\n\n// Utilities\nimport { click, commands, render, screen, userEvent } from '@test'\nimport { nextTick, ref } from 'vue'\n\ndescribe('VNumberInput', () => {\n  it.each([\n    { precision: 0, typing: '---', expected: '-' }, // \"-\" is only allowed once\n    { precision: 0, typing: '1-', expected: '1' }, // \"-\" is only at the start\n    { precision: 1, typing: '.', expected: '.' }, // \".\" is allowed at the start\n    { precision: 1, typing: '..', expected: '.' }, // \".\" is only allowed once\n    { precision: 1, typing: '1...0', expected: '1.0' }, // \".\" is only allowed once\n    { precision: 4, typing: '123.45.67', expected: '123.4567' }, // \".\" is only allowed once\n    { precision: 1, typing: 'ab-c8+.iop9', expected: '-8.9' }, // Only numbers, \"-\", \".\" are allowed to type in\n  ])('prevents NaN from arbitrary input', async ({ precision, typing, expected }) => {\n    const { element } = render(() => <VNumberInput precision={ precision } />)\n    await userEvent.click(element)\n    await userEvent.keyboard(typing)\n    expect(screen.getByCSS('input')).toHaveValue(expected)\n  })\n\n  it('resets v-model to null when click:clear is triggered', async () => {\n    const model = ref(5)\n    render(() => (\n      <VNumberInput\n        clearable\n        v-model={ model.value }\n      />\n    ))\n\n    await userEvent.click(screen.getByLabelText('Clear'))\n    expect(model.value).toBeNull()\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/20337\n  it('emits model-value when input value is a legit number within range of the max and min', async () => {\n    const model = ref(null)\n    const { element } = render(() => (\n      <VNumberInput\n        v-model={ model.value }\n        min={ 5 }\n        max={ 125 }\n      />\n    ))\n\n    await userEvent.click(element)\n    await userEvent.keyboard('1')\n    expect(model.value).toBeNull()\n\n    await userEvent.keyboard('0')\n    expect(model.value).toBe(10)\n\n    await userEvent.keyboard('0')\n    expect(model.value).toBe(100)\n\n    await userEvent.keyboard('0')\n    expect(model.value).toBe(100)\n\n    await userEvent.click(document.body)\n    expect(model.value).toBe(125)\n  })\n\n  describe('readonly', () => {\n    it('prevents mutation when readonly', async () => {\n      const model = ref(1)\n\n      const { element } = render(() => (\n        <VNumberInput v-model={ model.value } readonly />\n      ))\n\n      await click(screen.getByTestId('increment'))\n      expect(model.value).toBe(1)\n\n      await click(screen.getByTestId('decrement'))\n      expect(model.value).toBe(1)\n\n      await click(element)\n      await userEvent.keyboard('{ArrowUp}')\n      expect(model.value).toBe(1)\n\n      await userEvent.keyboard('{ArrowDown}')\n      expect(model.value).toBe(1)\n    })\n\n    // https://github.com/vuetifyjs/vuetify/issues/22677\n    it('does not mutate model when typing non-digit chars while readonly', async () => {\n      const model = ref(42)\n\n      const { element } = render(() => (\n        <VNumberInput v-model={ model.value } readonly />\n      ))\n\n      await userEvent.click(element)\n      // Select all text and type a non-digit character\n      await userEvent.keyboard('{Control>}a{/Control}')\n      await userEvent.keyboard(' ')\n      expect(model.value).toBe(42)\n\n      // Type arbitrary non-digit chars\n      await userEvent.keyboard('abc')\n      expect(model.value).toBe(42)\n    })\n\n    it('prevents mutation in readonly form', async () => {\n      const model = ref(1)\n\n      const { element } = render(() => (\n        <VForm readonly>\n          <VNumberInput v-model={ model.value } />\n        </VForm>\n      ))\n\n      await click(screen.getByTestId('increment'))\n      expect(model.value).toBe(1)\n\n      await click(screen.getByTestId('decrement'))\n      expect(model.value).toBe(1)\n\n      await click(element)\n      await userEvent.keyboard('{ArrowUp}')\n      expect(model.value).toBe(1)\n\n      await userEvent.keyboard('{ArrowDown}')\n      expect(model.value).toBe(1)\n    })\n\n    it('keeps original value when readonly or disabled', async () => {\n      const value1 = ref(120)\n      const value2 = ref(-15)\n      const value3 = ref(40.4)\n      const value4 = ref(-8.6)\n\n      render(() => (\n        <>\n          <VNumberInput\n            class=\"readonly-input-1\"\n            v-model={ value1.value }\n            min={ 0 }\n            max={ 50 }\n            readonly\n          />\n          <VNumberInput\n            class=\"readonly-input-2\"\n            v-model={ value2.value }\n            min={ 0 }\n            max={ 50 }\n            readonly\n          />\n          <VNumberInput\n            class=\"disabled-input-1\"\n            v-model={ value3.value }\n            precision={ 1 }\n            min={ 0 }\n            max={ 10 }\n            disabled\n          />\n          <VNumberInput\n            class=\"disabled-input-2\"\n            v-model={ value4.value }\n            precision={ 1 }\n            min={ 0 }\n            max={ 10 }\n            disabled\n          />\n        </>\n      ))\n\n      expect(screen.getByCSS('.readonly-input-1 input')).toHaveValue('120')\n      expect(screen.getByCSS('.readonly-input-2 input')).toHaveValue('-15')\n      expect(screen.getByCSS('.disabled-input-1 input')).toHaveValue('40.4')\n      expect(screen.getByCSS('.disabled-input-2 input')).toHaveValue('-8.6')\n    })\n  })\n\n  describe('native number input quirks', () => {\n    it('should auto-clamp after interaction', async () => {\n      const model = ref(1)\n      render(() =>\n        <VNumberInput min={ 5 } max={ 15 } v-model={ model.value } />\n      )\n\n      await expect.element(screen.getByCSS('input')).toHaveValue('1')\n      expect(model.value).toBe(1)\n\n      await userEvent.click(screen.getByCSS('input'))\n      await userEvent.tab()\n\n      await expect.element(screen.getByCSS('input')).toHaveValue('5')\n      expect(model.value).toBe(5)\n    })\n\n    it('should apply increments within the range', async () => {\n      const model = ref(20)\n      render(() =>\n        <VNumberInput min={ 5 } max={ 15 } v-model={ model.value } />\n      )\n\n      await expect.element(screen.getByCSS('input')).toHaveValue('20')\n      expect(model.value).toBe(20)\n\n      await userEvent.click(screen.getByCSS('input'))\n      await userEvent.keyboard('{arrowDown}')\n\n      await expect.element(screen.getByCSS('input')).toHaveValue('14')\n      expect(model.value).toBe(14)\n    })\n\n    it('should auto-correct when incrementing against the limit', async () => {\n      const model = ref(-33)\n      render(() =>\n        <VNumberInput min={ -10 } max={ 20 } v-model={ model.value } precision={ 2 } step={ 0.5 } />\n      )\n\n      await expect.element(screen.getByCSS('input')).toHaveValue('-33.00')\n      expect(model.value).toBe(-33)\n\n      await userEvent.click(screen.getByCSS('input'))\n      await userEvent.keyboard('{arrowDown}')\n\n      await expect.element(screen.getByCSS('input')).toHaveValue('-10')\n      expect(model.value).toBe(-10)\n    })\n\n    it('supports decimal step', async () => {\n      const model = ref(0)\n      render(() => (\n        <VNumberInput\n          step={ 0.03 }\n          precision={ 2 }\n          v-model={ model.value }\n        />\n      ))\n\n      await userEvent.click(screen.getByTestId('increment'))\n      await expect.element(screen.getByCSS('input')).toHaveValue('0.03')\n      expect(model.value).toBe(0.03)\n\n      await userEvent.click(screen.getByTestId('increment'))\n      await expect.element(screen.getByCSS('input')).toHaveValue('0.06')\n      expect(model.value).toBe(0.06)\n\n      await userEvent.click(screen.getByTestId('decrement'))\n      await expect.element(screen.getByCSS('input')).toHaveValue('0.03')\n      expect(model.value).toBe(0.03)\n\n      await userEvent.click(screen.getByTestId('decrement'))\n      await expect.element(screen.getByCSS('input')).toHaveValue('0.00')\n      expect(model.value).toBe(0)\n    })\n\n    it('shows custom decimal separator when incrementing', async () => {\n      const model = ref(0)\n      render(() => (\n        <VNumberInput\n          step={ 0.07 }\n          precision={ 2 }\n          decimalSeparator=\",\"\n          v-model={ model.value }\n        />\n      ))\n\n      await userEvent.click(screen.getByTestId('increment'))\n      await expect.element(screen.getByCSS('input')).toHaveValue('0,07')\n      expect(model.value).toBe(0.07)\n\n      await userEvent.click(screen.getByTestId('increment'))\n      await expect.element(screen.getByCSS('input')).toHaveValue('0,14')\n      expect(model.value).toBe(0.14)\n\n      await userEvent.click(screen.getByTestId('decrement'))\n      await expect.element(screen.getByCSS('input')).toHaveValue('0,07')\n      expect(model.value).toBe(0.07)\n\n      await userEvent.click(screen.getByTestId('decrement'))\n      await expect.element(screen.getByCSS('input')).toHaveValue('0,00')\n      expect(model.value).toBe(0)\n    })\n  })\n\n  it('should not fire @update:focus twice when clicking bottom of input', async () => {\n    const onFocus = vi.fn()\n    const { element } = render(() => (\n      <VNumberInput onUpdate:focused={ onFocus } />\n    ))\n\n    await userEvent.click(element, { position: { x: 10, y: 55 } })\n\n    expect(onFocus).toHaveBeenCalledTimes(1)\n  })\n\n  describe('accepts digits from pasted text', () => {\n    it.each([\n      { precision: 0, text: '-00123', expected: -123 },\n      { precision: 2, text: '.250', expected: 0.25 },\n      { precision: 3, text: '000.321', expected: 0.321 },\n      { precision: 0, text: '100.99', expected: 100 },\n      { precision: 1, text: '200.99', expected: 200.9 },\n      { precision: 2, text: ' 1,250.32\\n', expected: 1250.32 },\n      { precision: 0, text: '1\\'024.00 meters', expected: 1024 },\n      { precision: 0, text: '-1123.', expected: -1123 },\n    ])('should parse numbers correctly', async ({ precision, text, expected }) => {\n      const model = ref(null)\n      const { element } = render(() => (\n        <VNumberInput\n          v-model={ model.value }\n          precision={ precision }\n        />\n      ))\n      const input = element.querySelector('input') as HTMLInputElement\n      input.focus()\n      const lock = await commands.getLock()\n      await navigator.clipboard.writeText(text)\n      await userEvent.paste()\n      await commands.releaseLock(lock)\n      expect(model.value).toBe(expected)\n    })\n\n    it.each([\n      { sep: ',', precision: 0, text: '-00123', expected: -123 },\n      { sep: ',', precision: 2, text: ',250', expected: 0.25 },\n      { sep: ',', precision: 3, text: '000,321', expected: 0.321 },\n      { sep: ',', precision: 0, text: '100,99', expected: 100 },\n      { sep: ',', precision: 1, text: '200,99', expected: 200.9 },\n      { sep: ',', precision: 2, text: ' 1,250.32\\n', expected: 1.25 },\n      { sep: ',', precision: 0, text: '1\\'024.00 meters', expected: 102400 },\n      { sep: ',', precision: 0, text: '- 1123.', expected: -1123 },\n      { sep: ',', precision: 0, text: '- 32,', expected: -32 },\n    ])('should parse numbers with custom separator', async ({ sep, precision, text, expected }) => {\n      const model = ref(null)\n      const { element } = render(() => (\n        <VNumberInput\n          v-model={ model.value }\n          decimalSeparator={ sep }\n          precision={ precision }\n        />\n      ))\n      const input = element.querySelector('input') as HTMLInputElement\n      input.focus()\n      const lock = await commands.getLock()\n      await navigator.clipboard.writeText(text)\n      await userEvent.paste()\n      await commands.releaseLock(lock)\n      input.blur()\n      expect(model.value).toBe(expected)\n    })\n\n    // https://github.com/vuetifyjs/vuetify/issues/21828\n    it('should only trim values from the end', async () => {\n      const model = ref(0.01)\n      render(() => (\n        <VNumberInput\n          v-model={ model.value }\n          minFractionDigits={ 0 }\n          precision={ 4 }\n        />\n      ))\n\n      await userEvent.click(screen.getByCSS('input'))\n      expect(screen.getByCSS('input')).toHaveValue('0.01')\n\n      await userEvent.keyboard('{backspace}2')\n      await userEvent.tab()\n      expect(screen.getByCSS('input')).toHaveValue('0.02')\n      expect(model.value).toBe(0.02)\n    })\n  })\n\n  describe('fraction digits control', () => {\n    it.each([\n      { precision: 2, minFractionDigits: null, typing: '.312', expected: '0.31' },\n      { precision: 2, minFractionDigits: null, typing: '12.', expected: '12.00' },\n      { precision: 0, minFractionDigits: 0, typing: '42', expected: '42' },\n      { precision: 0, minFractionDigits: 1, typing: '-1.321', expected: '-1321' }, // dot is ignored while typing\n      { precision: 0, minFractionDigits: 1, typing: '2', expected: '2' },\n      { precision: 0, minFractionDigits: 3, typing: '31.9', expected: '319' }, // dot is ignored while typing\n      { precision: 5, minFractionDigits: 3, typing: '-92.21', expected: '-92.210' },\n      { precision: 5, minFractionDigits: 3, typing: '-92.2132', expected: '-92.2132' },\n      { precision: 5, minFractionDigits: 3, typing: '-92.21325555', expected: '-92.21325' },\n      { precision: null, minFractionDigits: 0, typing: '8', expected: '8' },\n      { precision: null, minFractionDigits: 1, typing: '8', expected: '8.0' },\n      { precision: null, minFractionDigits: 2, typing: '-1.5', expected: '-1.50' },\n      { precision: null, minFractionDigits: 2, typing: '-1.521', expected: '-1.521' },\n    ])('applies flexible limit on fraction digits', async ({ precision, minFractionDigits, typing, expected }) => {\n      const { element } = render(() => <VNumberInput precision={ precision } minFractionDigits={ minFractionDigits } />)\n      await userEvent.click(element)\n      await userEvent.keyboard(typing)\n      await userEvent.click(document.body)\n      expect(screen.getByCSS('input')).toHaveValue(expected)\n    })\n  })\n\n  describe('should indicate range error', () => {\n    // enable in 4.0.0\n    it.todo('on mount', async () => {\n      const model = ref(-13)\n      const onChange = vi.fn()\n      render(() => (\n        <VNumberInput\n          v-model={ model.value }\n          min={ 5 }\n          onUpdate:modelValue={ onChange }\n        />\n      ))\n\n      await nextTick()\n      expect(model.value).toBe(-13)\n      expect(onChange).not.toHaveBeenCalled()\n      expect(screen.getByCSS('.v-input')).toHaveClass('v-input--error')\n    })\n\n    it('while typing', async () => {\n      const model = ref(null)\n      const onChange = vi.fn()\n      render(() => (\n        <VNumberInput\n          v-model={ model.value }\n          min={ 5 }\n          onUpdate:modelValue={ onChange }\n        />\n      ))\n\n      const vInput = screen.getByCSS('.v-input')\n\n      await userEvent.tab()\n      await userEvent.keyboard('1')\n      expect(vInput).toHaveClass('v-input--error')\n\n      await userEvent.keyboard('2')\n      expect(vInput).not.toHaveClass('v-input--error')\n      expect(model.value).toBe(12)\n\n      await userEvent.keyboard('{arrowLeft}{arrowLeft}-')\n      expect(vInput).toHaveClass('v-input--error')\n    })\n\n    it('while typing', async () => {\n      const model = ref(0)\n      const onChange = vi.fn()\n      render(() => (\n        <VNumberInput\n          v-model={ model.value }\n          max={ 50 }\n          onUpdate:modelValue={ onChange }\n        />\n      ))\n\n      await nextTick()\n      const vInput = screen.getByCSS('.v-input')\n      expect(vInput).not.toHaveClass('v-input--error')\n\n      model.value = 50.55 // will be rounded to 51\n      await nextTick()\n      expect(vInput).toHaveClass('v-input--error')\n\n      model.value = 99\n      await nextTick()\n      expect(vInput).toHaveClass('v-input--error')\n\n      model.value = 45\n      await nextTick()\n      expect(vInput).not.toHaveClass('v-input--error')\n    })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VNumberInput/_variables.scss",
    "content": "$number-input-inset-divider-size: 55% !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VNumberInput/hold.ts",
    "content": "// Utilities\nimport { onScopeDispose } from 'vue'\n\nconst HOLD_REPEAT = 50\nconst HOLD_DELAY = 500\n\nexport function useHold ({ toggleUpDown }: { toggleUpDown: (increment: boolean) => void }) {\n  let timeout = -1\n  let interval = -1\n\n  onScopeDispose(holdStop)\n\n  function holdStart (value: 'up' | 'down') {\n    holdStop()\n    tick(value)\n    window.addEventListener('pointerup', holdStop)\n    document.addEventListener('blur', holdStop)\n    timeout = window.setTimeout(() => {\n      interval = window.setInterval(() => tick(value), HOLD_REPEAT)\n    }, HOLD_DELAY)\n  }\n\n  function holdStop () {\n    window.clearTimeout(timeout)\n    window.clearInterval(interval)\n    window.removeEventListener('pointerup', holdStop)\n    document.removeEventListener('blur', holdStop)\n  }\n\n  onScopeDispose(holdStop)\n\n  function tick (value: 'up' | 'down') {\n    toggleUpDown(value === 'up')\n  }\n\n  return { holdStart, holdStop }\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VNumberInput/index.ts",
    "content": "export { VNumberInput } from './VNumberInput'\n"
  },
  {
    "path": "packages/vuetify/src/components/VOtpInput/VOtpInput.sass",
    "content": "@use 'sass:math';\n@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-otp-input\n    align-items: center\n    display: flex\n    justify-content: center\n    padding: $otp-input-padding\n    position: relative\n    @include tools.rounded(4px)\n\n    .v-field\n      height: 100%\n\n      .v-field__outline\n        &__start,\n        &__end\n          flex: 1\n\n      input::placeholder\n        color: currentColor\n        opacity: var(--v-disabled-opacity)\n\n      &.v-field--focused\n        input::placeholder\n          opacity: 0\n\n  .v-otp-input__divider\n    margin: $otp-input-divider-margin\n\n  .v-otp-input__content\n    align-items: center\n    display: flex\n    gap: $otp-input-content-gap\n    padding: $otp-input-content-padding\n    justify-content: center\n    max-width: $otp-input-content-max-width\n    position: relative\n    border-radius: inherit\n\n    .v-otp-input--divided &\n      max-width: $otp-input-divided-content-max-width\n\n  @at-root\n    @include tools.density('v-otp-input', $input-density) using ($modifier)\n      .v-otp-input__content\n        height: #{$otp-input-content-height + math.div($modifier, 2)}\n\n  .v-otp-input__field\n    padding: 0\n    margin: 0\n    border-radius: 0\n    font: inherit\n    border-style: none\n    color: inherit\n    background-color: transparent\n    font-size: $otp-input-field-font-size\n    height: 100%\n    outline: none\n    text-align: center\n    width: 100%\n\n    &[type=number]::-webkit-outer-spin-button,\n    &[type=number]::-webkit-inner-spin-button\n      -webkit-appearance: none\n      margin: 0\n\n    &[type=number]\n      -moz-appearance: textfield\n\n  .v-otp-input__loader\n    align-items: center\n    display: flex\n    height: 100%\n    justify-content: center\n    width: 100%\n\n    .v-progress-linear\n      position: absolute\n"
  },
  {
    "path": "packages/vuetify/src/components/VOtpInput/VOtpInput.tsx",
    "content": "// Styles\nimport './VOtpInput.sass'\n\n// Components\nimport { makeVFieldProps, VField } from '@/components/VField/VField'\nimport { VOverlay } from '@/components/VOverlay/VOverlay'\nimport { VProgressCircular } from '@/components/VProgressCircular/VProgressCircular'\n\n// Composables\nimport { provideDefaults } from '@/composables/defaults'\nimport { makeDensityProps, useDensity } from '@/composables/density'\nimport { makeDimensionProps, useDimension } from '@/composables/dimensions'\nimport { makeFocusProps, useFocus } from '@/composables/focus'\nimport { useIntersectionObserver } from '@/composables/intersectionObserver'\nimport { useLocale } from '@/composables/locale'\nimport { useProxiedModel } from '@/composables/proxiedModel'\nimport { useToggleScope } from '@/composables/toggleScope'\n\n// Utilities\nimport { computed, effectScope, nextTick, ref, toRef, watch, watchEffect } from 'vue'\nimport { filterInputAttrs, focusChild, genericComponent, pick, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\n// Types\nexport type VOtpInputSlots = {\n  default: never\n  loader: never\n}\n\nexport const makeVOtpInputProps = propsFactory({\n  autofocus: Boolean,\n  divider: String,\n  focusAll: Boolean,\n  label: {\n    type: String,\n    default: '$vuetify.input.otp',\n  },\n  length: {\n    type: [Number, String],\n    default: 6,\n  },\n  masked: Boolean,\n  modelValue: {\n    type: [Number, String],\n    default: undefined,\n  },\n  placeholder: String,\n  type: {\n    type: String as PropType<'text' | 'password' | 'number'>,\n    default: 'number',\n  },\n\n  ...makeDensityProps(),\n  ...makeDimensionProps(),\n  ...makeFocusProps(),\n  ...pick(makeVFieldProps({\n    variant: 'outlined' as const,\n  }), [\n    'baseColor',\n    'bgColor',\n    'class',\n    'color',\n    'disabled',\n    'error',\n    'loading',\n    'rounded',\n    'style',\n    'theme',\n    'variant',\n  ]),\n}, 'VOtpInput')\n\nexport const VOtpInput = genericComponent<VOtpInputSlots>()({\n  name: 'VOtpInput',\n\n  props: makeVOtpInputProps(),\n\n  emits: {\n    finish: (val: string) => true,\n    'update:focused': (val: boolean) => true,\n    'update:modelValue': (val: string) => true,\n  },\n\n  setup (props, { attrs, emit, slots }) {\n    const { densityClasses } = useDensity(props)\n    const { dimensionStyles } = useDimension(props)\n    const { isFocused, focus, blur } = useFocus(props)\n    const model = useProxiedModel(\n      props,\n      'modelValue',\n      '',\n      val => val == null ? [] : String(val).split(''),\n      val => val.join('')\n    )\n    const { t } = useLocale()\n\n    const length = computed(() => Number(props.length))\n    const fields = computed(() => Array(length.value).fill(0))\n    const focusIndex = ref(-1)\n    const contentRef = ref<HTMLElement>()\n    const inputRef = ref<HTMLInputElement[]>([])\n    const current = computed(() => inputRef.value[focusIndex.value])\n    let _isComposing = false\n\n    useToggleScope(() => props.autofocus, () => {\n      const intersectScope = effectScope()\n      intersectScope.run(() => {\n        const { intersectionRef, isIntersecting } = useIntersectionObserver()\n        watchEffect(() => {\n          intersectionRef.value = inputRef.value[0]\n        })\n        watch(isIntersecting, v => {\n          if (!v) return\n          intersectionRef.value?.focus()\n          intersectScope.stop()\n        })\n      })\n    })\n\n    function onInput () {\n      // The maxlength attribute doesn't work for the number type input, so the text type is used.\n      // The following logic simulates the behavior of a number input.\n      if (isValidNumber(current.value.value)) {\n        current.value.value = ''\n        return\n      }\n\n      if (_isComposing) return\n\n      const array = model.value.slice()\n      const value = current.value.value\n\n      array[focusIndex.value] = value\n\n      let target: any = null\n\n      if (focusIndex.value > model.value.length) {\n        target = model.value.length + 1\n      } else if (focusIndex.value + 1 !== length.value) {\n        target = 'next'\n      }\n\n      model.value = array\n\n      if (target) focusChild(contentRef.value!, target)\n    }\n\n    function onCompositionend () {\n      _isComposing = false\n      onInput()\n    }\n\n    function onBeforeinput (e: InputEvent) {\n      const isBackwardDelete = [\n        'deleteContentBackward',\n        'deleteWordBackward',\n        'deleteSoftLineBackward',\n        'deleteHardLineBackward',\n      ].includes(e.inputType)\n\n      const isForwardDelete = [\n        'deleteContentForward',\n        'deleteWordForward',\n        'deleteSoftLineForward',\n        'deleteHardLineForward',\n      ].includes(e.inputType)\n\n      if (!isBackwardDelete && !isForwardDelete) return\n\n      e.preventDefault()\n\n      const array = model.value.slice()\n      const index = focusIndex.value\n      let target: 'prev' | null = null\n\n      if (isBackwardDelete) {\n        if (!array[index]) {\n          if (index > 0) {\n            array[index - 1] = ''\n            model.value = array\n            target = 'prev'\n          }\n        } else {\n          const isLastFilledField = !array.slice(index + 1).some(v => v)\n          for (let i = index; i < length.value - 1; i++) {\n            array[i] = array[i + 1]\n          }\n          array[length.value - 1] = ''\n          model.value = array\n          if (!isLastFilledField && index > 0) target = 'prev'\n        }\n      } else {\n        for (let i = index; i < length.value - 1; i++) {\n          array[i] = array[i + 1]\n        }\n        array[length.value - 1] = ''\n        model.value = array\n      }\n\n      requestAnimationFrame(() => {\n        if (target != null) {\n          focusChild(contentRef.value!, target)\n        } else {\n          inputRef.value[index]?.select()\n        }\n      })\n    }\n\n    function onKeydown (e: KeyboardEvent) {\n      let target: 'next' | 'prev' | 'first' | 'last' | number | null = null\n\n      if (!['ArrowLeft', 'ArrowRight'].includes(e.key)) return\n\n      e.preventDefault()\n\n      if (e.key === 'ArrowLeft') {\n        target = 'prev'\n      } else if (e.key === 'ArrowRight') {\n        target = 'next'\n      }\n\n      requestAnimationFrame(() => {\n        if (target != null) {\n          focusChild(contentRef.value!, target)\n        }\n      })\n    }\n\n    function onPaste (index: number, e: ClipboardEvent) {\n      e.preventDefault()\n      e.stopPropagation()\n\n      const clipboardText = e?.clipboardData?.getData('Text').trim().slice(0, length.value) ?? ''\n      const finalIndex = clipboardText.length - 1 === -1 ? index : clipboardText.length - 1\n\n      if (isValidNumber(clipboardText)) return\n\n      model.value = clipboardText.split('')\n\n      focusIndex.value = finalIndex\n    }\n\n    function reset () {\n      model.value = []\n    }\n\n    function onFocus (e: FocusEvent, index: number) {\n      focus()\n\n      focusIndex.value = index\n    }\n\n    function onBlur () {\n      blur()\n\n      focusIndex.value = -1\n    }\n\n    function isValidNumber (value: string) {\n      return props.type === 'number' && /[^0-9]/g.test(value)\n    }\n\n    provideDefaults({\n      VField: {\n        color: toRef(() => props.color),\n        bgColor: toRef(() => props.color),\n        baseColor: toRef(() => props.baseColor),\n        disabled: toRef(() => props.disabled),\n        error: toRef(() => props.error),\n        variant: toRef(() => props.variant),\n        rounded: toRef(() => props.rounded),\n      },\n    }, { scoped: true })\n\n    watch(model, val => {\n      if (val.length === length.value) {\n        emit('finish', val.join(''))\n      }\n    }, { deep: true })\n\n    watch(focusIndex, val => {\n      if (val < 0) return\n\n      nextTick(() => {\n        inputRef.value[val]?.select()\n      })\n    })\n\n    useRender(() => {\n      const [rootAttrs, inputAttrs] = filterInputAttrs(attrs)\n\n      return (\n        <div\n          class={[\n            'v-otp-input',\n            {\n              'v-otp-input--divided': !!props.divider,\n            },\n            densityClasses.value,\n            props.class,\n          ]}\n          style={[\n            props.style,\n          ]}\n          { ...rootAttrs }\n        >\n          <div\n            ref={ contentRef }\n            class=\"v-otp-input__content\"\n            style={[\n              dimensionStyles.value,\n            ]}\n          >\n            { fields.value.map((_, i) => (\n              <>\n                { props.divider && i !== 0 && (\n                  <span class=\"v-otp-input__divider\">{ props.divider }</span>\n                )}\n\n                <VField\n                  focused={ (isFocused.value && props.focusAll) || focusIndex.value === i }\n                  key={ i }\n                >\n                  {{\n                    ...slots,\n                    loader: undefined,\n                    default: () => {\n                      return (\n                        <input\n                          ref={ val => inputRef.value[i] = val as HTMLInputElement }\n                          aria-label={ t(props.label, i + 1) }\n                          autofocus={ i === 0 && props.autofocus }\n                          autocomplete=\"one-time-code\"\n                          class={[\n                            'v-otp-input__field',\n                          ]}\n                          disabled={ props.disabled }\n                          inputmode={ props.type === 'number' ? 'numeric' : 'text' }\n                          min={ props.type === 'number' ? 0 : undefined }\n                          maxlength={ i === 0 ? length.value : '1' }\n                          placeholder={ props.placeholder }\n                          type={ props.masked ? 'password' : props.type === 'number' ? 'text' : props.type }\n                          value={ model.value[i] }\n                          onInput={ onInput }\n                          onBeforeinput={ onBeforeinput }\n                          onFocus={ e => onFocus(e, i) }\n                          onBlur={ onBlur }\n                          onKeydown={ onKeydown }\n                          onCompositionstart={ () => _isComposing = true }\n                          onCompositionend={ onCompositionend }\n                          onPaste={ event => onPaste(i, event) }\n                        />\n                      )\n                    },\n                  }}\n                </VField>\n              </>\n            ))}\n\n            <input\n              class=\"v-otp-input-input\"\n              type=\"hidden\"\n              { ...inputAttrs }\n              value={ model.value.join('') }\n            />\n\n            <VOverlay\n              contained\n              contentClass=\"v-otp-input__loader\"\n              modelValue={ !!props.loading }\n              persistent\n            >\n              { slots.loader?.() ?? (\n                <VProgressCircular\n                  color={ typeof props.loading === 'boolean' ? undefined : props.loading }\n                  indeterminate\n                  size=\"24\"\n                  width=\"2\"\n                />\n              )}\n            </VOverlay>\n\n            { slots.default?.() }\n          </div>\n        </div>\n      )\n    })\n\n    return {\n      blur: () => {\n        inputRef.value?.some(input => input.blur())\n      },\n      focus: () => {\n        inputRef.value?.[0].focus()\n      },\n      reset,\n      isFocused,\n    }\n  },\n})\n\nexport type VOtpInput = InstanceType<typeof VOtpInput>\n"
  },
  {
    "path": "packages/vuetify/src/components/VOtpInput/__tests__/VOtpInput.spec.browser.tsx",
    "content": "import { VOtpInput } from '../VOtpInput'\n\n// Utilities\nimport { commands, render, screen, showcase, userEvent, waitAnimationFrame } from '@test'\nimport { ref } from 'vue'\n\nconst stories = {\n  'Default OTP input': <VOtpInput />,\n  'With custom length': <VOtpInput length={ 4 } />,\n  'With divider': <VOtpInput divider=\"-\" />,\n  'Password type': <VOtpInput type=\"password\" />,\n  Disabled: <VOtpInput disabled />,\n  Loading: <VOtpInput loading />,\n  'Error state': <VOtpInput error />,\n  'With placeholder': <VOtpInput placeholder=\"0\" />,\n  'With focus all': <VOtpInput focusAll />,\n}\n\ndescribe('VOtpInput', () => {\n  it('enters value and moves to next input', async () => {\n    render(() => (<VOtpInput />))\n    const inputs = screen.getAllByCSS('.v-otp-input input')\n\n    await userEvent.click(inputs[0])\n    await userEvent.keyboard('1')\n    expect(inputs[1]).toHaveFocus()\n\n    await userEvent.keyboard('2')\n    expect(inputs[2]).toHaveFocus()\n\n    await userEvent.keyboard('3')\n    expect(inputs[3]).toHaveFocus()\n\n    await userEvent.keyboard('4')\n    expect(inputs[4]).toHaveFocus()\n\n    await userEvent.keyboard('5')\n    expect(inputs[5]).toHaveFocus()\n\n    await userEvent.keyboard('6')\n    expect(inputs[5]).toHaveFocus()\n  })\n\n  it('enters value and moves to next input when focused index is not next', async () => {\n    render(() => (<VOtpInput />))\n    const inputs = screen.getAllByCSS('.v-otp-input input')\n\n    await userEvent.click(inputs[0])\n    await userEvent.keyboard('1')\n    expect(inputs[1]).toHaveFocus()\n\n    await userEvent.click(inputs[3])\n    await userEvent.keyboard('2')\n    expect(inputs[2]).toHaveFocus()\n  })\n\n  it('removes value and stays on current input when using delete', async () => {\n    render(() => (<VOtpInput />))\n    const inputs = screen.getAllByCSS('.v-otp-input input')\n\n    await userEvent.click(inputs[0])\n    await userEvent.keyboard('1234')\n    expect(inputs[4]).toHaveFocus()\n\n    await userEvent.keyboard('{ArrowLeft}{ArrowLeft}')\n    expect(inputs[2]).toHaveFocus()\n    expect(inputs[2]).toHaveValue('3')\n\n    await userEvent.keyboard('{Delete}')\n    expect(inputs[2]).toHaveValue('4')\n    expect(inputs[2]).toHaveFocus()\n  })\n\n  it('removes value and goes back when using backspace', async () => {\n    render(() => (<VOtpInput />))\n    const inputs = screen.getAllByCSS('.v-otp-input input')\n\n    await userEvent.click(inputs[0])\n    await userEvent.keyboard('1234')\n    expect(inputs[4]).toHaveFocus()\n\n    await userEvent.keyboard('{Backspace}')\n    expect(inputs[3]).toHaveFocus()\n    expect(inputs[3]).toHaveValue('')\n\n    await userEvent.keyboard('{Backspace}')\n    expect(inputs[2]).toHaveFocus()\n    expect(inputs[2]).toHaveValue('')\n  })\n\n  it('removes value and stays on current input when using backspace on last filled field', async () => {\n    render(() => (<VOtpInput />))\n    const inputs = screen.getAllByCSS('.v-otp-input input')\n\n    await userEvent.click(inputs[0])\n    await userEvent.keyboard('12345')\n    await userEvent.click(inputs[4])\n\n    expect(inputs[4]).toHaveFocus()\n    expect(inputs[4]).toHaveValue('5')\n\n    await userEvent.keyboard('{Backspace}')\n    expect(inputs[4]).toHaveFocus()\n    expect(inputs[4]).toHaveValue('')\n  })\n\n  it('shifts values left and goes back when using backspace on a non-last filled field', async () => {\n    render(() => (<VOtpInput />))\n    const inputs = screen.getAllByCSS('.v-otp-input input')\n\n    await userEvent.click(inputs[0])\n    await userEvent.keyboard('12345')\n    await userEvent.click(inputs[2])\n    expect(inputs[2]).toHaveFocus()\n    expect(inputs[2]).toHaveValue('3')\n\n    await userEvent.keyboard('{Backspace}')\n    expect(inputs[1]).toHaveFocus()\n    expect(inputs[2]).toHaveValue('4')\n    expect(inputs[3]).toHaveValue('5')\n    expect(inputs[4]).toHaveValue('')\n  })\n\n  it('shifts values left when using backspace on the first field', async () => {\n    render(() => (<VOtpInput />))\n    const inputs = screen.getAllByCSS('.v-otp-input input')\n\n    await userEvent.click(inputs[0])\n    await userEvent.keyboard('12345')\n    await userEvent.click(inputs[0])\n    expect(inputs[0]).toHaveFocus()\n    expect(inputs[0]).toHaveValue('1')\n\n    await userEvent.keyboard('{Backspace}')\n    expect(inputs[0]).toHaveFocus()\n    expect(inputs[0]).toHaveValue('2')\n    expect(inputs[1]).toHaveValue('3')\n    expect(inputs[4]).toHaveValue('')\n  })\n\n  it.each(['deleteWordBackward', 'deleteSoftLineBackward', 'deleteHardLineBackward'])(\n    'removes value and goes back on %s',\n    async inputType => {\n      render(() => (<VOtpInput />))\n      const inputs = screen.getAllByCSS('.v-otp-input input:not([type=\"hidden\"])')\n\n      await userEvent.click(inputs[0])\n      await userEvent.keyboard('1234')\n      expect(inputs[4]).toHaveFocus()\n\n      inputs[4].dispatchEvent(new InputEvent('beforeinput', { inputType, cancelable: true, bubbles: true }))\n      await waitAnimationFrame()\n      expect(inputs[3]).toHaveFocus()\n      expect(inputs[3]).toHaveValue('')\n    }\n  )\n\n  it.each(['deleteWordForward', 'deleteSoftLineForward', 'deleteHardLineForward'])(\n    'shifts values left and stays on %s',\n    async inputType => {\n      render(() => (<VOtpInput />))\n      const inputs = screen.getAllByCSS('.v-otp-input input:not([type=\"hidden\"])')\n\n      await userEvent.click(inputs[0])\n      await userEvent.keyboard('1234')\n      await userEvent.keyboard('{ArrowLeft}{ArrowLeft}')\n      expect(inputs[2]).toHaveFocus()\n\n      inputs[2].dispatchEvent(new InputEvent('beforeinput', { inputType, cancelable: true, bubbles: true }))\n      await waitAnimationFrame()\n      expect(inputs[2]).toHaveFocus()\n      expect(inputs[2]).toHaveValue('4')\n      expect(inputs[3]).toHaveValue('')\n    }\n  )\n\n  it('emits finish event when all inputs are filled', async () => {\n    const onFinish = vi.fn()\n    render(() => (<VOtpInput onFinish={ onFinish } />))\n    const inputs = screen.getAllByCSS('.v-otp-input input')\n\n    await userEvent.click(inputs[0])\n    await userEvent.keyboard('123456')\n\n    expect(onFinish).toHaveBeenCalledWith('123456')\n  })\n\n  it('respects custom length prop', async () => {\n    render(() => (<VOtpInput length={ 4 } />))\n    const inputs = screen.getAllByCSS('.v-otp-input input:not([type=\"hidden\"])')\n\n    expect(inputs).toHaveLength(4)\n  })\n\n  it('handles model value updates', async () => {\n    const modelValue = ref('')\n    render(() => (\n      <VOtpInput\n        modelValue={ modelValue.value }\n        onUpdate:modelValue={ val => { modelValue.value = val } }\n      />\n    ))\n    const inputs = screen.getAllByCSS('.v-otp-input input')\n\n    await userEvent.click(inputs[0])\n    await userEvent.keyboard('123')\n\n    expect(modelValue.value).toBe('123')\n  })\n\n  it('handles paste event', async () => {\n    render(() => (<VOtpInput />))\n    const inputs = screen.getAllByCSS('.v-otp-input input')\n    await userEvent.click(inputs[0])\n    const lock = await commands.getLock()\n    await navigator.clipboard.writeText('123456')\n    await userEvent.paste()\n    await commands.releaseLock(lock)\n\n    expect(inputs[0]).toHaveValue('1')\n    expect(inputs[1]).toHaveValue('2')\n    expect(inputs[2]).toHaveValue('3')\n    expect(inputs[3]).toHaveValue('4')\n    expect(inputs[4]).toHaveValue('5')\n    expect(inputs[5]).toHaveValue('6')\n    expect(inputs[5]).toHaveFocus()\n  })\n\n  it('trim paste event content', async () => {\n    render(() => (<VOtpInput />))\n    const inputs = screen.getAllByCSS('.v-otp-input input')\n    await userEvent.click(inputs[0])\n    const lock = await commands.getLock()\n    await navigator.clipboard.writeText('  123456     ')\n    await userEvent.paste()\n    await commands.releaseLock(lock)\n\n    expect(inputs[0]).toHaveValue('1')\n    expect(inputs[1]).toHaveValue('2')\n    expect(inputs[2]).toHaveValue('3')\n    expect(inputs[3]).toHaveValue('4')\n    expect(inputs[4]).toHaveValue('5')\n    expect(inputs[5]).toHaveValue('6')\n    expect(inputs[5]).toHaveFocus()\n  })\n\n  it('handles mobile OTP autofill', async () => {\n    render(() => (<VOtpInput />))\n    const inputs = screen.getAllByCSS('.v-otp-input input')\n\n    await userEvent.type(inputs[0], '123456')\n\n    expect(inputs[0]).toHaveValue('1')\n    expect(inputs[1]).toHaveValue('2')\n    expect(inputs[2]).toHaveValue('3')\n    expect(inputs[3]).toHaveValue('4')\n    expect(inputs[4]).toHaveValue('5')\n    expect(inputs[5]).toHaveValue('6')\n    expect(inputs[5]).toHaveFocus()\n  })\n\n  showcase({ stories })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VOtpInput/_variables.scss",
    "content": "@forward '../VInput/variables';\n@use '../../styles/settings';\n@use '../../styles/tools';\n\n$otp-input-content-gap: .5rem !default;\n$otp-input-content-height: 64px !default;\n$otp-input-content-max-width: 320px !default;\n$otp-input-content-padding: .5rem !default;\n$otp-input-divided-content-max-width: 360px !default;\n$otp-input-divider-margin: 0 8px !default;\n$otp-input-field-font-size: 1.25rem !default;\n$otp-input-padding: .5rem 0 !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VOtpInput/index.ts",
    "content": "export { VOtpInput } from './VOtpInput'\n"
  },
  {
    "path": "packages/vuetify/src/components/VOverflowBtn/VOverflowBtn.sass",
    "content": "@use 'sass:map'\n@use './variables' as *\n\n// Theme\n@include theme(v-overflow-btn) using ($material)\n  &#{&} > .v-input__control > .v-input__slot\n    border-color: map.get($material, 'dividers')\n\n  &:not(.v-input--is-focused):not(.v-input--has-state)\n    > .v-input__control > .v-input__slot:hover\n      background: map.get($material, 'cards')\n\n  &.v-overflow-btn--segmented\n    .v-input__append-inner\n      border-left: thin solid map.get($material, 'dividers')\n\n\n.v-autocomplete__content.v-menu__content\n  box-shadow: $overflow-menu-content-box-shadow\n\n  .v-select-list\n    border-radius: $overflow-menu-content-select-list-border-radius\n\n.v-overflow-btn\n  margin-top: $overflow-margin-top\n  padding-top: 0\n\n  &:not(.v-overflow-btn--editable) > .v-input__control > .v-input__slot\n    cursor: pointer\n\n  .v-input__slot\n    border-width: $overflow-input-slot-border-width\n    border-style: solid\n\n    &:before\n      display: none\n\n  .v-select__slot\n    height: $overflow-slot-height\n\n  &.v-input--dense\n    .v-select__slot\n      height: $overflow-dense-slot-height\n\n    input\n      cursor: pointer\n      margin-inline-start: $overflow-dense-input-margin-x\n\n  .v-select__selection--comma:first-child\n    margin-inline-start: $overflow-selection-comma-margin-x\n\n  .v-input__slot\n    transition: .3s map.get($transition, 'swing')\n\n    &::before,\n    &::after\n      display: none\n\n  .v-label\n    top: $overflow-label-top\n    margin-inline-start: $overflow-label-margin-x\n\n  .v-input__append-inner\n    align-items: center\n    align-self: auto\n    flex-shrink: 0\n    height: $overflow-append-inner-height\n    margin-top: 0\n    padding: 0 4px\n    width: $overflow-append-inner-width\n\n  .v-input__append-outer,\n  .v-input__prepend-outer\n    margin-bottom: $overflow-append-prepend-margin-bottom\n    margin-top: $overflow-append-prepend-margin-top\n\n  .v-input__control::before\n    // TODO: move to mixin\n    height: 1px\n    top: -1px\n    content: ''\n    left: 0\n    position: absolute\n    transition: $primary-transition\n    width: 100%\n\n  &.v-input--is-focused,\n  &.v-select--is-menu-active\n    .v-input__slot\n      border-color: transparent !important\n      box-shadow: $overflow-focused-active-slot-box-shadow\n\n  &.v-input--is-focused\n    .v-input__slot\n      border-radius: $overflow-focused-active-border-radius\n\n  &.v-select--is-menu-active\n    .v-input__slot\n      border-radius: $overflow-active-slot-border-radius\n\n  .v-select__selections\n    width: 0px\n\n  &--segmented\n    .v-input__slot\n      border-width: $overflow-segmented-input-slot-border-width\n\n    .v-select__selections\n      flex-wrap: nowrap\n\n      .v-btn\n        border-radius: 0\n        margin: 0\n        height: $overflow-segmented-selections-btn-height\n        width: 100%\n\n        // push past the input's padding\n        margin-inline-end: $overflow-segmented-selections-btn-margin-x\n\n        &__content\n          justify-content: start\n\n          &::before\n            background-color: transparent\n\n  &--editable\n    .v-select__slot\n      input\n        cursor: text\n        padding: $overflow-editable-select-slot-padding\n\n    .v-input__append-inner,\n    .v-input__append-inner *\n      cursor: pointer\n"
  },
  {
    "path": "packages/vuetify/src/components/VOverflowBtn/VOverflowBtn.ts",
    "content": "// @ts-nocheck\n/* eslint-disable */\n\n// Styles\nimport './VOverflowBtn.sass'\n\n// Extensions\nimport VSelect from '../VSelect/VSelect'\nimport VAutocomplete from '../VAutocomplete'\nimport VTextField from '../VTextField/VTextField'\n\n// Components\nimport VBtn from '../VBtn'\n\n// Utilities\nimport { consoleWarn } from '../../util/console'\n\n/* @vue/component */\nexport default VAutocomplete.extend({\n  name: 'v-overflow-btn',\n\n  props: {\n    editable: Boolean,\n    segmented: Boolean,\n  },\n\n  computed: {\n    classes (): object {\n      return {\n        ...VAutocomplete.options.computed.classes.call(this),\n        'v-overflow-btn': true,\n        'v-overflow-btn--segmented': this.segmented,\n        'v-overflow-btn--editable': this.editable,\n      }\n    },\n    isAnyValueAllowed (): boolean {\n      return this.editable ||\n        VAutocomplete.options.computed.isAnyValueAllowed.call(this)\n    },\n    isSingle (): true {\n      return true\n    },\n    computedItems (): object[] {\n      return this.segmented ? this.allItems : this.filteredItems\n    },\n    labelValue (): boolean {\n      return (this.isFocused && !this.persistentPlaceholder) || this.isLabelActive\n    },\n  },\n\n  methods: {\n    genSelections () {\n      return this.editable\n        ? VAutocomplete.options.methods.genSelections.call(this)\n        : VSelect.options.methods.genSelections.call(this) // Override v-autocomplete's override\n    },\n    genCommaSelection (item: any, index: number, last: boolean) {\n      return this.segmented\n        ? this.genSegmentedBtn(item)\n        : VSelect.options.methods.genCommaSelection.call(this, item, index, last)\n    },\n    genInput () {\n      const input = VTextField.options.methods.genInput.call(this)\n\n      input.data = input.data || {}\n      input.data.domProps!.value = this.editable ? this.internalSearch : ''\n      input.data.attrs!.readonly = !this.isAnyValueAllowed\n\n      return input\n    },\n    genLabel () {\n      if (this.editable && this.isFocused) return null\n\n      const label = VTextField.options.methods.genLabel.call(this)\n\n      if (!label) return label\n\n      label.data = label.data || {}\n\n      // Reset previously set styles from parent\n      label.data.style = {}\n\n      return label\n    },\n    genSegmentedBtn (item: any) {\n      const itemValue = this.getValue(item)\n      const itemObj = this.computedItems.find(i => this.getValue(i) === itemValue) || item\n\n      if (!itemObj.text || !itemObj.callback) {\n        consoleWarn('When using \"segmented\" prop without a selection slot, items must contain both a text and callback property', this)\n        return null\n      }\n\n      return this.$createElement(VBtn, {\n        props: { text: true },\n        on: {\n          click (e: Event) {\n            e.stopPropagation()\n            itemObj.callback(e)\n          },\n        },\n      }, [itemObj.text])\n    },\n    updateValue (val: boolean) {\n      if (val) {\n        this.initialValue = this.lazyValue\n      } else if (this.initialValue !== this.lazyValue) {\n        this.$emit('change', this.lazyValue)\n      }\n    },\n  },\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VOverflowBtn/__tests__/VOverflowBtn.spec.ts",
    "content": "// @ts-nocheck\n/* eslint-disable */\n\n// Components\n// import VOverflowBtn from '../VOverflowBtn'\n\n// Utilities\nimport {\n  mount,\n  Wrapper,\n} from '@vue/test-utils'\n// import { ExtractVue } from '../../../util/mixins'\n\ndescribe.skip('VOverflowBtn.js', () => {\n  type Instance = ExtractVue<typeof VOverflowBtn>\n  let mountFunction: (options?: object) => Wrapper<Instance>\n\n  beforeEach(() => {\n    document.body.setAttribute('data-app', 'true')\n\n    mountFunction = (options = {}) => {\n      return mount(VOverflowBtn, {\n        ...options,\n        // https://github.com/vuejs/vue-test-utils/issues/1130\n        sync: false,\n        mocks: {\n          $vuetify: {\n            lang: {\n              t: (val: string) => val,\n            },\n            theme: {\n              dark: false,\n            },\n          },\n        },\n      })\n    }\n  })\n\n  const warning = 'items must contain both a text and callback property'\n\n  it.skip('segmented - should warn when item has no callback', async () => {\n    const items = [\n      { text: 'Hello' },\n      { text: 'Hello' },\n    ]\n\n    const wrapper = mountFunction({\n      propsData: {\n        segmented: true,\n        items,\n      },\n    })\n\n    await wrapper.vm.$nextTick()\n\n    // The error only happens\n    // when generating the button\n    // which only happens when\n    // we have a matching model\n    wrapper.setProps({\n      items: [items[1]],\n      value: 'Hello',\n    })\n\n    await wrapper.vm.$nextTick()\n\n    expect(warning).toHaveBeenTipped()\n  })\n\n  it('should use default autocomplete selections', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        items: ['foo'],\n        multiple: true,\n        value: ['foo'],\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n\n    wrapper.setProps({\n      items: [{ text: 'foo', value: 'foo', callback: () => { } }],\n      multiple: false,\n      segmented: true,\n      value: 'foo',\n    })\n\n    await wrapper.vm.$nextTick()\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should invoke item callback', () => {\n    const callback = jest.fn()\n    const wrapper = mountFunction({\n      propsData: {\n        items: [{\n          text: 'foo',\n          value: 'bar',\n          callback,\n        }],\n        segmented: true,\n        value: 'bar',\n      },\n    })\n\n    const btn = wrapper.find('.v-btn')\n\n    btn.trigger('click')\n\n    expect(callback).toHaveBeenCalled()\n  })\n\n  it('should show label with persistentPlaceholder property set to true', async () => {\n    const wrapper = mountFunction({\n      propsData: {\n        items: ['foo'],\n        label: 'Some label',\n        persistentPlaceholder: true,\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n\n    wrapper.find('input').trigger('click')\n\n    await wrapper.vm.$nextTick()\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VOverflowBtn/__tests__/__snapshots__/VOverflowBtn.spec.ts.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`VOverflowBtn.js should show label with persistentPlaceholder property set to true 1`] = `\n<div class=\"v-input theme--light v-text-field v-text-field--single-line v-select v-autocomplete v-overflow-btn\">\n  <div class=\"v-input__control\">\n    <div role=\"combobox\"\n         aria-haspopup=\"listbox\"\n         aria-expanded=\"false\"\n         aria-owns=\"list-15\"\n         class=\"v-input__slot\"\n    >\n      <div class=\"v-select__slot\">\n        <label for=\"input-15\"\n               class=\"v-label theme--light\"\n        >\n          Some label\n        </label>\n        <div class=\"v-select__selections\">\n          <input id=\"input-15\"\n                 readonly=\"readonly\"\n                 type=\"text\"\n          >\n        </div>\n        <div class=\"v-input__append-inner\">\n          <div class=\"v-input__icon v-input__icon--append\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon notranslate material-icons theme--light\"\n            >\n              $dropdown\n            </i>\n          </div>\n        </div>\n        <input type=\"hidden\">\n      </div>\n      <div class=\"v-menu\">\n      </div>\n    </div>\n    <div class=\"v-text-field__details\">\n      <div class=\"v-messages theme--light\">\n        <span name=\"message-transition\"\n              tag=\"div\"\n              class=\"v-messages__wrapper\"\n        >\n        </span>\n      </div>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VOverflowBtn.js should show label with persistentPlaceholder property set to true 2`] = `\n<div class=\"v-input theme--light v-text-field v-text-field--single-line v-select v-select--is-menu-active v-autocomplete v-overflow-btn\">\n  <div class=\"v-input__control\">\n    <div role=\"combobox\"\n         aria-haspopup=\"listbox\"\n         aria-expanded=\"true\"\n         aria-owns=\"list-15\"\n         class=\"v-input__slot\"\n    >\n      <div class=\"v-select__slot\">\n        <label for=\"input-15\"\n               class=\"v-label theme--light\"\n        >\n          Some label\n        </label>\n        <div class=\"v-select__selections\">\n          <input id=\"input-15\"\n                 readonly=\"readonly\"\n                 type=\"text\"\n          >\n        </div>\n        <div class=\"v-input__append-inner\">\n          <div class=\"v-input__icon v-input__icon--append\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon notranslate material-icons theme--light\"\n            >\n              $dropdown\n            </i>\n          </div>\n        </div>\n        <input type=\"hidden\">\n      </div>\n      <div class=\"v-menu\">\n      </div>\n    </div>\n    <div class=\"v-text-field__details\">\n      <div class=\"v-messages theme--light\">\n        <span name=\"message-transition\"\n              tag=\"div\"\n              class=\"v-messages__wrapper\"\n        >\n        </span>\n      </div>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VOverflowBtn.js should use default autocomplete selections 1`] = `\n<div class=\"v-input v-input--is-label-active v-input--is-dirty theme--light v-text-field v-text-field--single-line v-select v-select--is-multi v-autocomplete v-overflow-btn\">\n  <div class=\"v-input__control\">\n    <div role=\"combobox\"\n         aria-haspopup=\"listbox\"\n         aria-expanded=\"false\"\n         aria-owns=\"list-1\"\n         class=\"v-input__slot\"\n    >\n      <div class=\"v-select__slot\">\n        <div class=\"v-select__selections\">\n          <div class=\"v-select__selection v-select__selection--comma\">\n            foo\n          </div>\n          <input id=\"input-1\"\n                 readonly=\"readonly\"\n                 type=\"text\"\n          >\n        </div>\n        <div class=\"v-input__append-inner\">\n          <div class=\"v-input__icon v-input__icon--append\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon notranslate material-icons theme--light\"\n            >\n              $dropdown\n            </i>\n          </div>\n        </div>\n        <input type=\"hidden\"\n               value=\"foo\"\n        >\n      </div>\n      <div class=\"v-menu\">\n      </div>\n    </div>\n    <div class=\"v-text-field__details\">\n      <div class=\"v-messages theme--light\">\n        <span name=\"message-transition\"\n              tag=\"div\"\n              class=\"v-messages__wrapper\"\n        >\n        </span>\n      </div>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`VOverflowBtn.js should use default autocomplete selections 2`] = `\n<div class=\"v-input v-input--is-label-active v-input--is-dirty theme--light v-text-field v-text-field--single-line v-select v-autocomplete v-overflow-btn v-overflow-btn--segmented\">\n  <div class=\"v-input__control\">\n    <div role=\"combobox\"\n         aria-haspopup=\"listbox\"\n         aria-expanded=\"false\"\n         aria-owns=\"list-1\"\n         class=\"v-input__slot\"\n    >\n      <div class=\"v-select__slot\">\n        <div class=\"v-select__selections\">\n          <button type=\"button\"\n                  class=\"v-btn v-btn--text theme--light v-size--default\"\n          >\n            <span class=\"v-btn__content\">\n              foo\n            </span>\n          </button>\n          <input id=\"input-1\"\n                 readonly=\"readonly\"\n                 type=\"text\"\n          >\n        </div>\n        <div class=\"v-input__append-inner\">\n          <div class=\"v-input__icon v-input__icon--append\">\n            <i aria-hidden=\"true\"\n               class=\"v-icon notranslate material-icons theme--light\"\n            >\n              $dropdown\n            </i>\n          </div>\n        </div>\n        <input type=\"hidden\"\n               value=\"foo\"\n        >\n      </div>\n      <div class=\"v-menu\">\n      </div>\n    </div>\n    <div class=\"v-text-field__details\">\n      <div class=\"v-messages theme--light\">\n        <span name=\"message-transition\"\n              tag=\"div\"\n              class=\"v-messages__wrapper\"\n        >\n        </span>\n      </div>\n    </div>\n  </div>\n</div>\n`;\n"
  },
  {
    "path": "packages/vuetify/src/components/VOverflowBtn/_variables.scss",
    "content": "@import '../../styles/styles.sass';\n\n$overflow-active-slot-border-radius: $border-radius-root $border-radius-root 0 0 !default;\n$overflow-append-inner-height: 48px !default;\n$overflow-append-inner-width: 42px !default;\n$overflow-append-prepend-margin-bottom: 12px !default;\n$overflow-append-prepend-margin-top: 12px !default;\n$overflow-dense-input-margin-x: 16px !default;\n$overflow-dense-slot-height: 38px !default;\n$overflow-focused-active-border-radius: $border-radius-root !default;\n$overflow-focused-active-slot-box-shadow: 0 1px 6px 0 rgba(32,33,36,0.28) !default;\n$overflow-focused-active-slot-elevation: 2 !default;\n$overflow-input-slot-border-width: 2px 0 !default;\n$overflow-label-margin-x: 16px !default;\n$overflow-label-top: calc(50% - 10px) !default;\n$overflow-margin-top: 12px !default;\n$overflow-menu-content-box-shadow: 0 4px 6px 0 rgba(32,33,36,0.28) !default;\n$overflow-menu-content-select-list-border-radius: 0 0 $border-radius-root $border-radius-root !default;\n$overflow-segmented-input-slot-border-width: thin 0 !default;\n$overflow-segmented-selections-btn-height: 48px !default;\n$overflow-segmented-selections-btn-margin-x: -16px !default;\n$overflow-selection-comma-margin-x: 16px !default;\n$overflow-slot-height: 48px !default;\n$overflow-editable-select-slot-padding: 8px 16px !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VOverflowBtn/index.ts",
    "content": "import VOverflowBtn from './VOverflowBtn'\n\nexport { VOverflowBtn }\nexport default VOverflowBtn\n"
  },
  {
    "path": "packages/vuetify/src/components/VOverlay/VOverlay.sass",
    "content": "@use 'sass:selector'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  // Block\n  .v-overlay-container\n    contain: layout\n    left: 0\n    pointer-events: none\n    position: absolute\n    top: 0\n    display: contents\n\n  .v-overlay\n    --v-overlay-opacity: #{$overlay-opacity}\n    border-radius: inherit\n    display: flex\n    left: 0\n    pointer-events: none\n    position: fixed\n    top: 0\n    bottom: 0\n    right: 0\n\n  // Element\n  .v-overlay__content\n    outline: none\n    position: absolute\n    pointer-events: auto\n    contain: layout\n\n  .v-overlay__scrim\n    pointer-events: auto\n    background: $overlay-scrim-background\n    border-radius: inherit\n    bottom: 0\n    left: 0\n    opacity: var(--v-overlay-opacity)\n    position: fixed\n    right: 0\n    top: 0\n\n  // Modifier\n  .v-overlay--absolute\n    position: absolute\n\n  .v-overlay--contained .v-overlay__scrim\n    position: absolute\n\n  .v-overlay--scroll-blocked\n    padding-inline-end: var(--v-scrollbar-offset)\n\n@include tools.layer('trumps')\n  .v-overlay-scroll-blocked\n    padding-inline-end: var(--v-scrollbar-offset)\n\n    &:not(html)\n      overflow-y: hidden\n\n    @at-root #{selector.append(html, &)}\n      position: fixed\n      top: var(--v-body-scroll-y)\n      left: var(--v-body-scroll-x)\n      width: 100%\n      height: 100%\n\n    .v-navigation-drawer--right.v-navigation-drawer--active\n      margin-right: var(--v-scrollbar-offset)\n"
  },
  {
    "path": "packages/vuetify/src/components/VOverlay/VOverlay.tsx",
    "content": "// Styles\nimport './VOverlay.sass'\n\n// Composables\nimport { makeLocationStrategyProps, useLocationStrategies } from './locationStrategies'\nimport { makeScrollStrategyProps, useScrollStrategies } from './scrollStrategies'\nimport { makeActivatorProps, useActivator } from './useActivator'\nimport { useBackgroundColor } from '@/composables/color'\nimport { makeComponentProps } from '@/composables/component'\nimport { makeDimensionProps, useDimension } from '@/composables/dimensions'\nimport { makeFocusTrapProps, useFocusTrap } from '@/composables/focusTrap'\nimport { useHydration } from '@/composables/hydration'\nimport { makeLazyProps, useLazy } from '@/composables/lazy'\nimport { useRtl } from '@/composables/locale'\nimport { useProxiedModel } from '@/composables/proxiedModel'\nimport { useBackButton, useRouter } from '@/composables/router'\nimport { useScopeId } from '@/composables/scopeId'\nimport { useStack } from '@/composables/stack'\nimport { useTeleport } from '@/composables/teleport'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\nimport { useToggleScope } from '@/composables/toggleScope'\nimport { makeTransitionProps, MaybeTransition } from '@/composables/transition'\n\n// Directives\nimport vClickOutside from '@/directives/click-outside'\n\n// Utilities\nimport {\n  computed,\n  mergeProps,\n  onBeforeUnmount,\n  ref,\n  Teleport,\n  Transition,\n  watch,\n} from 'vue'\nimport {\n  animate,\n  convertToUnit,\n  genericComponent,\n  getCurrentInstance,\n  getScrollParent,\n  IN_BROWSER,\n  omit,\n  propsFactory,\n  standardEasing,\n  useRender,\n} from '@/util'\n\n// Types\nimport type { PropType, Ref } from 'vue'\nimport type { BackgroundColorData } from '@/composables/color'\nimport type { TemplateRef } from '@/util'\n\ninterface ScrimProps {\n  [key: string]: unknown\n  modelValue: boolean\n  color: BackgroundColorData\n}\nfunction Scrim (props: ScrimProps) {\n  const { modelValue, color, ...rest } = props\n  return (\n    <Transition name=\"fade-transition\" appear>\n      { props.modelValue && (\n        <div\n          class={[\n            'v-overlay__scrim',\n            props.color.backgroundColorClasses.value,\n          ]}\n          style={ props.color.backgroundColorStyles.value }\n          { ...rest }\n        />\n      )}\n    </Transition>\n  )\n}\n\nexport type OverlaySlots = {\n  default: { isActive: Ref<boolean> }\n  activator: { isActive: boolean, props: Record<string, any>, targetRef: TemplateRef }\n}\n\nexport const makeVOverlayProps = propsFactory({\n  absolute: Boolean,\n  attach: [Boolean, String, Object] as PropType<boolean | string | Element>,\n  closeOnBack: {\n    type: Boolean,\n    default: true,\n  },\n  contained: Boolean,\n  contentClass: null,\n  contentProps: null,\n  disabled: Boolean,\n  opacity: [Number, String],\n  noClickAnimation: Boolean,\n  modelValue: Boolean,\n  persistent: Boolean,\n  scrim: {\n    type: [Boolean, String],\n    default: true,\n  },\n  zIndex: {\n    type: [Number, String],\n    default: 2000,\n  },\n\n  ...makeActivatorProps(),\n  ...makeComponentProps(),\n  ...makeDimensionProps(),\n  ...makeLazyProps(),\n  ...makeLocationStrategyProps(),\n  ...makeScrollStrategyProps(),\n  ...makeFocusTrapProps(),\n  ...makeThemeProps(),\n  ...makeTransitionProps(),\n}, 'VOverlay')\n\nexport const VOverlay = genericComponent<OverlaySlots>()({\n  name: 'VOverlay',\n\n  directives: { vClickOutside },\n\n  inheritAttrs: false,\n\n  props: {\n    _disableGlobalStack: Boolean,\n\n    ...omit(makeVOverlayProps(), ['disableInitialFocus']),\n  },\n\n  emits: {\n    'click:outside': (e: MouseEvent) => true,\n    'update:modelValue': (value: boolean) => true,\n    keydown: (e: KeyboardEvent) => true,\n    afterEnter: () => true,\n    afterLeave: () => true,\n  },\n\n  setup (props, { slots, attrs, emit }) {\n    const vm = getCurrentInstance('VOverlay')\n    const root = ref<HTMLElement>()\n    const scrimEl = ref<HTMLElement>()\n    const contentEl = ref<HTMLElement>()\n    const model = useProxiedModel(props, 'modelValue')\n    const isActive = computed({\n      get: () => model.value,\n      set: v => {\n        if (!(v && props.disabled)) model.value = v\n      },\n    })\n    const { themeClasses } = provideTheme(props)\n    const { rtlClasses, isRtl } = useRtl()\n    const { hasContent, onAfterLeave: _onAfterLeave } = useLazy(props, isActive)\n    const scrimColor = useBackgroundColor(() => {\n      return typeof props.scrim === 'string' ? props.scrim : null\n    })\n    const { globalTop, localTop, stackStyles } = useStack(isActive, () => props.zIndex, props._disableGlobalStack)\n    const {\n      activatorEl, activatorRef,\n      target, targetEl, targetRef,\n      activatorEvents,\n      contentEvents,\n      scrimEvents,\n    } = useActivator(props, { isActive, isTop: localTop, contentEl })\n    const { teleportTarget } = useTeleport(() => {\n      const target = props.attach || props.contained\n      if (target) return target\n      const rootNode = activatorEl?.value?.getRootNode() || vm.proxy?.$el?.getRootNode()\n      if (rootNode instanceof ShadowRoot) return rootNode\n      return false\n    })\n    const { dimensionStyles } = useDimension(props)\n    const isMounted = useHydration()\n    const { scopeId } = useScopeId()\n\n    watch(() => props.disabled, v => {\n      if (v) isActive.value = false\n    })\n\n    const { contentStyles, updateLocation } = useLocationStrategies(props, {\n      isRtl,\n      contentEl,\n      target,\n      isActive,\n    })\n    useScrollStrategies(props, {\n      root,\n      contentEl,\n      targetEl,\n      target,\n      isActive,\n      updateLocation,\n    })\n\n    function onClickOutside (e: MouseEvent) {\n      emit('click:outside', e)\n\n      if (!props.persistent) isActive.value = false\n      else animateClick()\n    }\n\n    function closeConditional (e: Event) {\n      return isActive.value && localTop.value && (\n        // If using scrim, only close if clicking on it rather than anything opened on top\n        !props.scrim || e.target === scrimEl.value || (e instanceof MouseEvent && e.shadowTarget === scrimEl.value)\n      )\n    }\n\n    useFocusTrap(props, { isActive, localTop, contentEl, activatorEl })\n\n    IN_BROWSER && watch(isActive, val => {\n      if (val) {\n        window.addEventListener('keydown', onKeydown)\n      } else {\n        window.removeEventListener('keydown', onKeydown)\n      }\n    }, { immediate: true })\n\n    onBeforeUnmount(() => {\n      if (!IN_BROWSER) return\n\n      window.removeEventListener('keydown', onKeydown)\n    })\n\n    function onKeydown (e: KeyboardEvent) {\n      if (e.key === 'Escape' && globalTop.value) {\n        if (!contentEl.value?.contains(document.activeElement)) {\n          emit('keydown', e)\n        }\n        if (!props.persistent) {\n          isActive.value = false\n          if (contentEl.value?.contains(document.activeElement)) {\n            activatorEl.value?.focus()\n          }\n        } else animateClick()\n      }\n    }\n    function onKeydownSelf (e: KeyboardEvent) {\n      if (e.key === 'Escape' && !globalTop.value) return\n\n      emit('keydown', e)\n    }\n\n    const router = useRouter()\n    useToggleScope(() => props.closeOnBack, () => {\n      useBackButton(router, () => {\n        if (globalTop.value && isActive.value) {\n          if (!props.persistent) isActive.value = false\n          else animateClick()\n          return false\n        }\n        return undefined\n      })\n    })\n\n    const top = ref<number>()\n    watch(() => isActive.value && (props.absolute || props.contained) && teleportTarget.value == null, val => {\n      if (val) {\n        const scrollParent = getScrollParent(root.value)\n        if (scrollParent && scrollParent !== document.scrollingElement) {\n          top.value = scrollParent.scrollTop\n        }\n      }\n    })\n\n    // Add a quick \"bounce\" animation to the content\n    function animateClick () {\n      if (props.noClickAnimation) return\n\n      contentEl.value && animate(contentEl.value, [\n        { transformOrigin: 'center' },\n        { transform: 'scale(1.03)' },\n        { transformOrigin: 'center' },\n      ], {\n        duration: 150,\n        easing: standardEasing,\n      })\n    }\n\n    function onAfterEnter () {\n      emit('afterEnter')\n    }\n\n    function onAfterLeave () {\n      _onAfterLeave()\n      emit('afterLeave')\n    }\n\n    useRender(() => (\n      <>\n        { slots.activator?.({\n          isActive: isActive.value,\n          targetRef,\n          props: mergeProps({\n            ref: activatorRef,\n          }, activatorEvents.value, props.activatorProps),\n        })}\n\n        { isMounted.value && hasContent.value && (\n          <Teleport\n            disabled={ !teleportTarget.value }\n            to={ teleportTarget.value }\n          >\n            <div\n              class={[\n                'v-overlay',\n                {\n                  'v-overlay--absolute': props.absolute || props.contained,\n                  'v-overlay--active': isActive.value,\n                  'v-overlay--contained': props.contained,\n                },\n                themeClasses.value,\n                rtlClasses.value,\n                props.class,\n              ]}\n              style={[\n                stackStyles.value,\n                {\n                  '--v-overlay-opacity': props.opacity,\n                  top: convertToUnit(top.value),\n                },\n                props.style,\n              ]}\n              ref={ root }\n              onKeydown={ onKeydownSelf }\n              { ...scopeId }\n              { ...attrs }\n            >\n              <Scrim\n                color={ scrimColor }\n                modelValue={ isActive.value && !!props.scrim }\n                ref={ scrimEl }\n                { ...scrimEvents.value }\n              />\n              <MaybeTransition\n                appear\n                persisted\n                transition={ props.transition }\n                target={ target.value }\n                onAfterEnter={ onAfterEnter }\n                onAfterLeave={ onAfterLeave }\n              >\n                <div\n                  ref={ contentEl }\n                  v-show={ isActive.value }\n                  v-click-outside={{ handler: onClickOutside, closeConditional, include: () => [activatorEl.value] }}\n                  class={[\n                    'v-overlay__content',\n                    props.contentClass,\n                  ]}\n                  style={[\n                    dimensionStyles.value,\n                    contentStyles.value,\n                  ]}\n                  { ...contentEvents.value }\n                  { ...props.contentProps }\n                >\n                  { slots.default?.({ isActive }) }\n                </div>\n              </MaybeTransition>\n            </div>\n          </Teleport>\n        )}\n      </>\n    ))\n\n    return {\n      activatorEl,\n      scrimEl,\n      target,\n      animateClick,\n      contentEl,\n      rootEl: root,\n      globalTop,\n      localTop,\n      updateLocation,\n    }\n  },\n})\n\nexport type VOverlay = InstanceType<typeof VOverlay>\n"
  },
  {
    "path": "packages/vuetify/src/components/VOverlay/__tests__/VOverlay.spec.cy.tsx",
    "content": "/// <reference types=\"../../../../types/cypress\" />\n\n// Components\nimport { Application } from '../../../../cypress/templates'\nimport { VOverlay } from '../VOverlay'\nimport { VLayout } from '@/components/VLayout'\nimport { VMain } from '@/components/VMain'\nimport { VNavigationDrawer } from '@/components/VNavigationDrawer'\n\n// Utilities\nimport { ref } from 'vue'\n\ndescribe('VOverlay', () => {\n  it('without activator', () => {\n    const model = ref(false)\n    cy.mount(() => (\n      <VLayout>\n        <VOverlay v-model={ model.value }>\n          <div data-test=\"content\">Content</div>\n        </VOverlay>\n      </VLayout>\n    ))\n      .get('[data-test=\"content\"]').should('not.exist')\n      // .setProps({ modelValue: true })\n      .then(() => {\n        model.value = true\n      })\n      .get('[data-test=\"content\"]').should('be.visible')\n      .get('body').click()\n      .get('[data-test=\"content\"]').should('not.exist')\n      .then(() => {\n        expect(model.value).to.be.false\n      })\n  })\n\n  it('should use activator', () => {\n    cy.mount(() => (\n      <VLayout>\n        <VOverlay>\n          {{\n            activator: ({ props }) => <div { ...props } data-test=\"activator\">Click me</div>,\n            default: () => <div data-test=\"content\">Content</div>,\n          }}\n        </VOverlay>\n      </VLayout>\n    ))\n      .get('[data-test=\"content\"]').should('not.exist')\n      .get('[data-test=\"activator\"]').should('exist').click()\n      .get('[data-test=\"content\"]').should('be.visible')\n      .get('body').click()\n      .get('[data-test=\"content\"]').should('not.exist')\n  })\n\n  it('should render overlay on top of layout', () => {\n    cy.mount(() => (\n      <Application>\n        <VNavigationDrawer permanent class=\"bg-blue\" data-test=\"drawer\" />\n        <VMain>\n          <VOverlay>\n            {{\n              activator: ({ props }) => <div { ...props } data-test=\"activator\">Click me</div>,\n              default: () => <div data-test=\"content\">Content</div>,\n            }}\n          </VOverlay>\n        </VMain>\n      </Application>\n    ))\n      .get('[data-test=\"content\"]').should('not.exist')\n      .get('[data-test=\"activator\"]').should('exist').click()\n      .get('[data-test=\"content\"]').should('be.visible')\n      .get('[data-test=\"drawer\"]').should('not.be.visible')\n      .get('body').click()\n      .get('[data-test=\"content\"]').should('not.exist')\n      .get('[data-test=\"drawer\"]').should('be.visible')\n  })\n\n  it('should render nested overlays', () => {\n    cy.mount(() => (\n      <Application>\n        <VOverlay>\n          {{\n            activator: ({ props }) => <div { ...props } data-test=\"first-activator\">Click me</div>,\n            default: () => (\n              <div data-test=\"first-content\">\n                <VOverlay>\n                  {{\n                    activator: ({ props }) => <div { ...props } data-test=\"second-activator\">Click me nested</div>,\n                    default: () => <div data-test=\"second-content\">Content</div>,\n                  }}\n                </VOverlay>\n              </div>\n            ),\n          }}\n        </VOverlay>\n      </Application>\n    ))\n      .get('[data-test=\"first-content\"]').should('not.exist')\n      .get('[data-test=\"first-activator\"]').should('exist').click()\n      .get('[data-test=\"first-content\"]').should('be.visible')\n      .get('[data-test=\"second-activator\"]').should('exist').click()\n      .get('[data-test=\"first-content\"]').should('not.be.visible')\n      .get('[data-test=\"second-content\"]').should('be.visible')\n      .get('body').click()\n      .get('[data-test=\"second-content\"]').should('not.exist')\n      .get('[data-test=\"first-content\"]').should('be.visible')\n      .get('body').click()\n      .get('[data-test=\"first-content\"]').should('not.exist')\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VOverlay/_variables.scss",
    "content": "// Defaults\n$overlay-opacity: 0.32 !default;\n$overlay-scrim-background: #000 !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VOverlay/index.ts",
    "content": "export { VOverlay } from './VOverlay'\n"
  },
  {
    "path": "packages/vuetify/src/components/VOverlay/locationStrategies.ts",
    "content": "// Composables\nimport { useToggleScope } from '@/composables/toggleScope'\n\n// Utilities\nimport { computed, nextTick, onScopeDispose, ref, watch } from 'vue'\nimport { anchorToPoint, getOffset } from './util/point'\nimport {\n  CircularBuffer,\n  clamp,\n  consoleError,\n  convertToUnit,\n  deepEqual,\n  destructComputed,\n  flipAlign,\n  flipCorner,\n  flipSide,\n  getAxis,\n  getScrollParents,\n  IN_BROWSER,\n  isFixedPosition,\n  nullifyTransforms,\n  parseAnchor,\n  propsFactory,\n} from '@/util'\nimport { Box, getElementBox, getOverflow, getTargetBox } from '@/util/box'\n\n// Types\nimport type { PropType, Ref } from 'vue'\nimport type { Anchor } from '@/util'\n\nexport interface LocationStrategyData {\n  contentEl: Ref<HTMLElement | undefined>\n  target: Ref<HTMLElement | [x: number, y: number] | undefined>\n  isActive: Ref<boolean>\n  isRtl: Ref<boolean>\n}\n\nexport type LocationStrategyFunction = (\n  data: LocationStrategyData,\n  props: StrategyProps,\n  contentStyles: Ref<Record<string, string>>\n) => undefined | { updateLocation: (e?: Event) => void }\n\nconst locationStrategies = {\n  static: staticLocationStrategy, // specific viewport position, usually centered\n  connected: connectedLocationStrategy, // connected to a certain element\n}\n\nexport interface StrategyProps {\n  locationStrategy: keyof typeof locationStrategies | LocationStrategyFunction\n  location: Anchor\n  origin: Anchor | 'auto' | 'overlap'\n  offset?: number | string | number[]\n  stickToTarget?: boolean\n  viewportMargin?: number | string\n  maxHeight?: number | string\n  maxWidth?: number | string\n  minHeight?: number | string\n  minWidth?: number | string\n}\n\nexport const makeLocationStrategyProps = propsFactory({\n  locationStrategy: {\n    type: [String, Function] as PropType<StrategyProps['locationStrategy']>,\n    default: 'static',\n    validator: (val: any) => typeof val === 'function' || val in locationStrategies,\n  },\n  location: {\n    type: String as PropType<StrategyProps['location']>,\n    default: 'bottom',\n  },\n  origin: {\n    type: String as PropType<StrategyProps['origin']>,\n    default: 'auto',\n  },\n  offset: [Number, String, Array] as PropType<StrategyProps['offset']>,\n  stickToTarget: Boolean,\n  viewportMargin: {\n    type: [Number, String],\n    default: 12,\n  },\n}, 'VOverlay-location-strategies')\n\nexport function useLocationStrategies (\n  props: StrategyProps,\n  data: LocationStrategyData\n) {\n  const contentStyles = ref({})\n  const updateLocation = ref<(e: Event) => void>()\n\n  if (IN_BROWSER) {\n    useToggleScope(() => !!(data.isActive.value && props.locationStrategy), reset => {\n      watch(() => props.locationStrategy, reset)\n      onScopeDispose(() => {\n        window.removeEventListener('resize', onResize)\n        visualViewport?.removeEventListener('resize', onVisualResize)\n        visualViewport?.removeEventListener('scroll', onVisualScroll)\n        updateLocation.value = undefined\n      })\n\n      window.addEventListener('resize', onResize, { passive: true })\n      visualViewport?.addEventListener('resize', onVisualResize, { passive: true })\n      visualViewport?.addEventListener('scroll', onVisualScroll, { passive: true })\n\n      if (typeof props.locationStrategy === 'function') {\n        updateLocation.value = props.locationStrategy(data, props, contentStyles)?.updateLocation\n      } else {\n        updateLocation.value = locationStrategies[props.locationStrategy](data, props, contentStyles)?.updateLocation\n      }\n    })\n  }\n\n  function onResize (e: Event) {\n    updateLocation.value?.(e)\n  }\n\n  function onVisualResize (e: Event) {\n    updateLocation.value?.(e)\n  }\n\n  function onVisualScroll (e: Event) {\n    updateLocation.value?.(e)\n  }\n\n  return {\n    contentStyles,\n    updateLocation,\n  }\n}\n\nfunction staticLocationStrategy () {\n  // TODO\n}\n\n/** Get size of element ignoring max-width/max-height */\nfunction getIntrinsicSize (el: HTMLElement, isRtl: boolean) {\n  // const scrollables = new Map<Element, [number, number]>()\n  // el.querySelectorAll('*').forEach(el => {\n  //   const x = el.scrollLeft\n  //   const y = el.scrollTop\n  //   if (x || y) {\n  //     scrollables.set(el, [x, y])\n  //   }\n  // })\n\n  // const initialMaxWidth = el.style.maxWidth\n  // const initialMaxHeight = el.style.maxHeight\n  // el.style.removeProperty('max-width')\n  // el.style.removeProperty('max-height')\n\n  /* eslint-disable-next-line sonarjs/prefer-immediate-return */\n  const contentBox = nullifyTransforms(el)\n\n  if (isRtl) {\n    contentBox.x += parseFloat(el.style.right || 0)\n  } else {\n    contentBox.x -= parseFloat(el.style.left || 0)\n  }\n  contentBox.y -= parseFloat(el.style.top || 0)\n\n  // el.style.maxWidth = initialMaxWidth\n  // el.style.maxHeight = initialMaxHeight\n  // scrollables.forEach((position, el) => {\n  //   el.scrollTo(...position)\n  // })\n\n  return contentBox\n}\n\nfunction connectedLocationStrategy (data: LocationStrategyData, props: StrategyProps, contentStyles: Ref<Record<string, string>>) {\n  const activatorFixed = Array.isArray(data.target.value) || isFixedPosition(data.target.value)\n  if (activatorFixed) {\n    Object.assign(contentStyles.value, {\n      position: 'fixed',\n      top: 0,\n      [data.isRtl.value ? 'right' : 'left']: 0,\n    })\n  }\n\n  const { preferredAnchor, preferredOrigin } = destructComputed(() => {\n    const parsedAnchor = parseAnchor(props.location, data.isRtl.value)\n    const parsedOrigin =\n      props.origin === 'overlap' ? parsedAnchor\n      : props.origin === 'auto' ? flipSide(parsedAnchor)\n      : parseAnchor(props.origin, data.isRtl.value)\n\n    // Some combinations of props may produce an invalid origin\n    if (parsedAnchor.side === parsedOrigin.side && parsedAnchor.align === flipAlign(parsedOrigin).align) {\n      return {\n        preferredAnchor: flipCorner(parsedAnchor),\n        preferredOrigin: flipCorner(parsedOrigin),\n      }\n    } else {\n      return {\n        preferredAnchor: parsedAnchor,\n        preferredOrigin: parsedOrigin,\n      }\n    }\n  })\n\n  const [minWidth, minHeight, maxWidth, maxHeight] =\n    (['minWidth', 'minHeight', 'maxWidth', 'maxHeight'] as const).map(key => {\n      return computed(() => {\n        const val = parseFloat(props[key]!)\n        return isNaN(val) ? Infinity : val\n      })\n    })\n\n  const offset = computed(() => {\n    if (Array.isArray(props.offset)) {\n      return props.offset\n    }\n    if (typeof props.offset === 'string') {\n      const offset = props.offset.split(' ').map(parseFloat)\n      if (offset.length < 2) offset.push(0)\n      return offset\n    }\n    return typeof props.offset === 'number' ? [props.offset, 0] : [0, 0]\n  })\n\n  let observe = false\n  let lastFrame = -1\n  const flipped = new CircularBuffer<{ x: boolean, y: boolean }>(4)\n  const observer = new ResizeObserver(() => {\n    if (!observe) return\n\n    // Detect consecutive frames\n    requestAnimationFrame(newTime => {\n      if (newTime !== lastFrame) flipped.clear()\n      requestAnimationFrame(newNewTime => {\n        lastFrame = newNewTime\n      })\n    })\n\n    if (flipped.isFull) {\n      const values = flipped.values()\n      if (\n        deepEqual(values.at(-1), values.at(-3)) &&\n        !deepEqual(values.at(-1), values.at(-2))\n      ) {\n        // Flipping is causing a container resize loop\n        return\n      }\n    }\n\n    const result = updateLocation()\n    if (result) flipped.push(result.flipped)\n  })\n\n  let targetBox = new Box({ x: 0, y: 0, width: 0, height: 0 })\n\n  watch(data.target, (newTarget, oldTarget) => {\n    if (oldTarget && !Array.isArray(oldTarget)) observer.unobserve(oldTarget)\n    if (!Array.isArray(newTarget)) {\n      if (newTarget) observer.observe(newTarget)\n    } else if (!deepEqual(newTarget, oldTarget)) {\n      updateLocation()\n    }\n  }, { immediate: true })\n\n  watch(data.contentEl, (newContentEl, oldContentEl) => {\n    if (oldContentEl) observer.unobserve(oldContentEl)\n    if (newContentEl) observer.observe(newContentEl)\n  }, { immediate: true })\n\n  onScopeDispose(() => {\n    observer.disconnect()\n  })\n\n  // eslint-disable-next-line max-statements\n  function updateLocation () {\n    observe = false\n    requestAnimationFrame(() => observe = true)\n\n    if (!data.target.value || !data.contentEl.value) return\n\n    if (\n      Array.isArray(data.target.value) ||\n      data.target.value.offsetParent ||\n      data.target.value.getClientRects().length\n    ) {\n      targetBox = getTargetBox(data.target.value)\n    } // Otherwise target element is hidden, use last known value\n\n    const contentBox = getIntrinsicSize(data.contentEl.value, data.isRtl.value)\n    const scrollParents = getScrollParents(data.contentEl.value)\n    const viewportMargin = Number(props.viewportMargin)\n\n    if (!scrollParents.length) {\n      scrollParents.push(document.documentElement)\n      if (!(data.contentEl.value.style.top && data.contentEl.value.style.left)) {\n        contentBox.x -= parseFloat(document.documentElement.style.getPropertyValue('--v-body-scroll-x') || 0)\n        contentBox.y -= parseFloat(document.documentElement.style.getPropertyValue('--v-body-scroll-y') || 0)\n      }\n    }\n\n    const viewport = scrollParents.reduce<Box>((box: Box | undefined, el) => {\n      const scrollBox = getElementBox(el)\n\n      if (box) {\n        return new Box({\n          x: Math.max(box.left, scrollBox.left),\n          y: Math.max(box.top, scrollBox.top),\n          width: Math.min(box.right, scrollBox.right) - Math.max(box.left, scrollBox.left),\n          height: Math.min(box.bottom, scrollBox.bottom) - Math.max(box.top, scrollBox.top),\n        })\n      }\n      return scrollBox\n    }, undefined!)\n\n    if (props.stickToTarget) {\n      viewport.x += Math.min(viewportMargin, targetBox.x)\n      viewport.y += Math.min(viewportMargin, targetBox.y)\n      viewport.width = Math.max(\n        viewport.width - viewportMargin * 2,\n        targetBox.x + targetBox.width - viewportMargin\n      )\n      viewport.height = Math.max(\n        viewport.height - viewportMargin * 2,\n        targetBox.y + targetBox.height - viewportMargin\n      )\n    } else {\n      viewport.x += viewportMargin\n      viewport.y += viewportMargin\n      viewport.width -= viewportMargin * 2\n      viewport.height -= viewportMargin * 2\n    }\n\n    let placement = {\n      anchor: preferredAnchor.value,\n      origin: preferredOrigin.value,\n    }\n\n    function checkOverflow (_placement: typeof placement) {\n      const box = new Box(contentBox)\n      const targetPoint = anchorToPoint(_placement.anchor, targetBox)\n      const contentPoint = anchorToPoint(_placement.origin, box)\n\n      let { x, y } = getOffset(targetPoint, contentPoint)\n\n      switch (_placement.anchor.side) {\n        case 'top': y -= offset.value[0]; break\n        case 'bottom': y += offset.value[0]; break\n        case 'left': x -= offset.value[0]; break\n        case 'right': x += offset.value[0]; break\n      }\n\n      switch (_placement.anchor.align) {\n        case 'top': y -= offset.value[1]; break\n        case 'bottom': y += offset.value[1]; break\n        case 'left': x -= offset.value[1]; break\n        case 'right': x += offset.value[1]; break\n      }\n\n      box.x += x\n      box.y += y\n\n      box.width = Math.min(box.width, maxWidth.value)\n      box.height = Math.min(box.height, maxHeight.value)\n\n      const overflows = getOverflow(box, viewport)\n\n      return { overflows, x, y }\n    }\n\n    let x = 0; let y = 0\n    const available = { x: 0, y: 0 }\n    const flipped = { x: false, y: false }\n    let resets = -1\n    while (true) {\n      if (resets++ > 10) {\n        consoleError('Infinite loop detected in connectedLocationStrategy')\n        break\n      }\n\n      const { x: _x, y: _y, overflows } = checkOverflow(placement)\n\n      x += _x\n      y += _y\n\n      contentBox.x += _x\n      contentBox.y += _y\n\n      // flip\n      {\n        const axis = getAxis(placement.anchor)\n        const hasOverflowX = overflows.x.before || overflows.x.after\n        const hasOverflowY = overflows.y.before || overflows.y.after\n\n        let reset = false\n        ;['x', 'y'].forEach(key => {\n          if (\n            (key === 'x' && hasOverflowX && !flipped.x) ||\n            (key === 'y' && hasOverflowY && !flipped.y)\n          ) {\n            const newPlacement = { anchor: { ...placement.anchor }, origin: { ...placement.origin } }\n            const flip = key === 'x'\n              ? axis === 'y' ? flipAlign : flipSide\n              : axis === 'y' ? flipSide : flipAlign\n            newPlacement.anchor = flip(newPlacement.anchor)\n            newPlacement.origin = flip(newPlacement.origin)\n            const { overflows: newOverflows } = checkOverflow(newPlacement)\n            if (\n              (newOverflows[key].before <= overflows[key].before &&\n                newOverflows[key].after <= overflows[key].after) ||\n              (newOverflows[key].before + newOverflows[key].after <\n                (overflows[key].before + overflows[key].after) / 2)\n            ) {\n              placement = newPlacement\n              reset = flipped[key] = true\n            }\n          }\n        })\n        if (reset) continue\n      }\n\n      // shift\n      if (overflows.x.before) {\n        x += overflows.x.before\n        contentBox.x += overflows.x.before\n      }\n      if (overflows.x.after) {\n        x -= overflows.x.after\n        contentBox.x -= overflows.x.after\n      }\n      if (overflows.y.before) {\n        y += overflows.y.before\n        contentBox.y += overflows.y.before\n      }\n      if (overflows.y.after) {\n        y -= overflows.y.after\n        contentBox.y -= overflows.y.after\n      }\n\n      // size\n      {\n        const overflows = getOverflow(contentBox, viewport)\n        available.x = viewport.width - overflows.x.before - overflows.x.after\n        available.y = viewport.height - overflows.y.before - overflows.y.after\n\n        x += overflows.x.before\n        contentBox.x += overflows.x.before\n        y += overflows.y.before\n        contentBox.y += overflows.y.before\n      }\n\n      break\n    }\n\n    const axis = getAxis(placement.anchor)\n\n    Object.assign(contentStyles.value, {\n      '--v-overlay-anchor-origin': `${placement.anchor.side} ${placement.anchor.align}`,\n      transformOrigin: `${placement.origin.side} ${placement.origin.align}`,\n      // transform: `translate(${pixelRound(x)}px, ${pixelRound(y)}px)`,\n      top: convertToUnit(pixelRound(y)),\n      left: data.isRtl.value ? undefined : convertToUnit(pixelRound(x)),\n      right: data.isRtl.value ? convertToUnit(pixelRound(-x)) : undefined,\n      minWidth: convertToUnit(axis === 'y' ? Math.min(minWidth.value, targetBox.width) : minWidth.value),\n      maxWidth: convertToUnit(pixelCeil(clamp(available.x, minWidth.value === Infinity ? 0 : minWidth.value, maxWidth.value))),\n      maxHeight: convertToUnit(pixelCeil(clamp(available.y, minHeight.value === Infinity ? 0 : minHeight.value, maxHeight.value))),\n    })\n\n    return {\n      available,\n      contentBox,\n      flipped,\n    }\n  }\n\n  watch(\n    () => [\n      preferredAnchor.value,\n      preferredOrigin.value,\n      props.offset,\n      props.minWidth,\n      props.minHeight,\n      props.maxWidth,\n      props.maxHeight,\n    ],\n    () => updateLocation(),\n  )\n\n  nextTick(() => {\n    const result = updateLocation()\n\n    // TODO: overflowing content should only require a single updateLocation call\n    // Icky hack to make sure the content is positioned consistently\n    if (!result) return\n    const { available, contentBox } = result\n    if (contentBox.height > available.y) {\n      requestAnimationFrame(() => {\n        updateLocation()\n        requestAnimationFrame(() => {\n          updateLocation()\n        })\n      })\n    }\n  })\n\n  return { updateLocation }\n}\n\nfunction pixelRound (val: number) {\n  return Math.round(val * devicePixelRatio) / devicePixelRatio\n}\n\nfunction pixelCeil (val: number) {\n  return Math.ceil(val * devicePixelRatio) / devicePixelRatio\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VOverlay/requestNewFrame.ts",
    "content": "let clean = true\nconst frames = [] as any[]\n\n/**\n * Schedule a task to run in an animation frame on its own\n * This is useful for heavy tasks that may cause jank if all ran together\n */\nexport function requestNewFrame (cb: () => void) {\n  if (!clean || frames.length) {\n    frames.push(cb)\n    run()\n  } else {\n    clean = false\n    cb()\n    run()\n  }\n}\n\nlet raf = -1\nfunction run () {\n  cancelAnimationFrame(raf)\n  raf = requestAnimationFrame(() => {\n    const frame = frames.shift()\n    if (frame) frame()\n\n    if (frames.length) run()\n    else clean = true\n  })\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VOverlay/scrollStrategies.ts",
    "content": "// Utilities\nimport { effectScope, onScopeDispose, watchEffect } from 'vue'\nimport { requestNewFrame } from './requestNewFrame'\nimport { convertToUnit, getScrollParents, hasScrollbar, IN_BROWSER, propsFactory } from '@/util'\n\n// Types\nimport type { EffectScope, PropType, Ref } from 'vue'\n\nexport interface ScrollStrategyData {\n  root: Ref<HTMLElement | undefined>\n  contentEl: Ref<HTMLElement | undefined>\n  targetEl: Ref<HTMLElement | undefined>\n  target: Ref<HTMLElement | [x: number, y: number] | undefined>\n  isActive: Ref<boolean>\n  updateLocation: Ref<((e: Event) => void) | undefined>\n}\n\nexport type ScrollStrategyFunction = (data: ScrollStrategyData, props: StrategyProps, scope: EffectScope) => void\n\nconst scrollStrategies = {\n  none: null,\n  close: closeScrollStrategy,\n  block: blockScrollStrategy,\n  reposition: repositionScrollStrategy,\n}\n\nexport interface StrategyProps {\n  scrollStrategy: keyof typeof scrollStrategies | ScrollStrategyFunction\n  contained: boolean | undefined\n}\n\nexport const makeScrollStrategyProps = propsFactory({\n  scrollStrategy: {\n    type: [String, Function] as PropType<StrategyProps['scrollStrategy']>,\n    default: 'block',\n    validator: (val: any) => typeof val === 'function' || val in scrollStrategies,\n  },\n}, 'VOverlay-scroll-strategies')\n\nexport function useScrollStrategies (\n  props: StrategyProps,\n  data: ScrollStrategyData\n) {\n  if (!IN_BROWSER) return\n\n  let scope: EffectScope | undefined\n  watchEffect(async () => {\n    scope?.stop()\n\n    if (!(data.isActive.value && props.scrollStrategy)) return\n\n    scope = effectScope()\n    await new Promise(resolve => setTimeout(resolve))\n    scope.active && scope.run(() => {\n      if (typeof props.scrollStrategy === 'function') {\n        props.scrollStrategy(data, props, scope!)\n      } else {\n        scrollStrategies[props.scrollStrategy]?.(data, props, scope!)\n      }\n    })\n  })\n\n  onScopeDispose(() => {\n    scope?.stop()\n  })\n}\n\nfunction closeScrollStrategy (data: ScrollStrategyData) {\n  function onScroll (e: Event) {\n    data.isActive.value = false\n  }\n\n  bindScroll(getTargetEl(data.target.value, data.contentEl.value), onScroll)\n}\n\nfunction blockScrollStrategy (data: ScrollStrategyData, props: StrategyProps) {\n  const offsetParent = data.root.value?.offsetParent\n  const target = getTargetEl(data.target.value, data.contentEl.value)\n  const scrollElements = [...new Set([\n    ...getScrollParents(target, props.contained ? offsetParent : undefined),\n    ...getScrollParents(data.contentEl.value, props.contained ? offsetParent : undefined),\n  ])].filter(el => !el.classList.contains('v-overlay-scroll-blocked'))\n  const scrollbarWidth = window.innerWidth - document.documentElement.offsetWidth\n\n  const scrollableParent = (el => hasScrollbar(el) && el)(offsetParent || document.documentElement)\n  if (scrollableParent) {\n    data.root.value!.classList.add('v-overlay--scroll-blocked')\n  }\n\n  scrollElements.forEach((el, i) => {\n    el.style.setProperty('--v-body-scroll-x', convertToUnit(-el.scrollLeft))\n    el.style.setProperty('--v-body-scroll-y', convertToUnit(-el.scrollTop))\n\n    if (el !== document.documentElement || getComputedStyle(el).overflowY !== 'scroll') {\n      el.style.setProperty('--v-scrollbar-offset', convertToUnit(scrollbarWidth))\n    }\n\n    el.classList.add('v-overlay-scroll-blocked')\n  })\n\n  onScopeDispose(() => {\n    scrollElements.forEach((el, i) => {\n      const x = parseFloat(el.style.getPropertyValue('--v-body-scroll-x'))\n      const y = parseFloat(el.style.getPropertyValue('--v-body-scroll-y'))\n\n      const scrollBehavior = el.style.scrollBehavior\n\n      el.style.scrollBehavior = 'auto'\n      el.style.removeProperty('--v-body-scroll-x')\n      el.style.removeProperty('--v-body-scroll-y')\n      el.style.removeProperty('--v-scrollbar-offset')\n      el.classList.remove('v-overlay-scroll-blocked')\n\n      el.scrollLeft = -x\n      el.scrollTop = -y\n\n      el.style.scrollBehavior = scrollBehavior\n    })\n    if (scrollableParent) {\n      data.root.value!.classList.remove('v-overlay--scroll-blocked')\n    }\n  })\n}\n\nfunction repositionScrollStrategy (data: ScrollStrategyData, props: StrategyProps, scope: EffectScope) {\n  let slow = false\n  let raf = -1\n  let ric = -1\n\n  function update (e: Event) {\n    requestNewFrame(() => {\n      const start = performance.now()\n      data.updateLocation.value?.(e)\n      const time = performance.now() - start\n      slow = time / (1000 / 60) > 2\n    })\n  }\n\n  ric = (typeof requestIdleCallback === 'undefined' ? (cb: Function) => cb() : requestIdleCallback)(() => {\n    scope.run(() => {\n      bindScroll(getTargetEl(data.target.value, data.contentEl.value), e => {\n        if (slow) {\n          // If the position calculation is slow,\n          // defer updates until scrolling is finished.\n          // Browsers usually fire one scroll event per frame so\n          // we just wait until we've got two frames without an event\n          cancelAnimationFrame(raf)\n          raf = requestAnimationFrame(() => {\n            raf = requestAnimationFrame(() => {\n              update(e)\n            })\n          })\n        } else {\n          update(e)\n        }\n      })\n    })\n  })\n\n  onScopeDispose(() => {\n    typeof cancelIdleCallback !== 'undefined' && cancelIdleCallback(ric)\n    cancelAnimationFrame(raf)\n  })\n}\n\nfunction getTargetEl (\n  target: HTMLElement | [x: number, y: number] | undefined,\n  contentEl: HTMLElement | undefined,\n) {\n  return Array.isArray(target)\n    ? document.elementsFromPoint(...target).find(el => !contentEl?.contains(el))\n    : target ?? contentEl\n}\n\nfunction bindScroll (el: Element | undefined, onScroll: (e: Event) => void) {\n  const scrollElements = [document, ...getScrollParents(el)]\n  scrollElements.forEach(el => {\n    el.addEventListener('scroll', onScroll, { passive: true })\n  })\n\n  onScopeDispose(() => {\n    scrollElements.forEach(el => {\n      el.removeEventListener('scroll', onScroll)\n    })\n  })\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VOverlay/useActivator.tsx",
    "content": "// Components\nimport { VMenuSymbol } from '@/components/VMenu/shared'\n\n// Composables\nimport { makeDelayProps, useDelay } from '@/composables/delay'\n\n// Utilities\nimport {\n  computed,\n  effectScope,\n  inject,\n  mergeProps,\n  nextTick,\n  onScopeDispose,\n  ref,\n  watch,\n  watchEffect,\n} from 'vue'\nimport {\n  bindProps,\n  getCurrentInstance,\n  IN_BROWSER,\n  matchesSelector,\n  propsFactory,\n  templateRef,\n  unbindProps,\n} from '@/util'\n\n// Types\nimport type {\n  ComponentInternalInstance,\n  ComponentPublicInstance,\n  EffectScope,\n  PropType,\n  Ref,\n} from 'vue'\nimport type { DelayProps } from '@/composables/delay'\n\ninterface ActivatorProps extends DelayProps {\n  target: 'parent' | 'cursor' | (string & {}) | Element | ComponentPublicInstance | [x: number, y: number] | undefined\n  activator: 'parent' | (string & {}) | Element | ComponentPublicInstance | undefined\n  activatorProps: Record<string, any>\n\n  openOnClick: boolean | undefined\n  openOnHover: boolean\n  openOnFocus: boolean | undefined\n\n  closeOnContentClick: boolean\n}\n\nexport const makeActivatorProps = propsFactory({\n  target: [String, Object] as PropType<ActivatorProps['target']>,\n  activator: [String, Object] as PropType<ActivatorProps['activator']>,\n  activatorProps: {\n    type: Object as PropType<ActivatorProps['activatorProps']>,\n    default: () => ({}),\n  },\n\n  openOnClick: {\n    type: Boolean,\n    default: undefined,\n  },\n  openOnHover: Boolean,\n  openOnFocus: {\n    type: Boolean,\n    default: undefined,\n  },\n\n  closeOnContentClick: Boolean,\n\n  ...makeDelayProps(),\n}, 'VOverlay-activator')\n\nexport function useActivator (\n  props: ActivatorProps,\n  { isActive, isTop, contentEl }: {\n    isActive: Ref<boolean>\n    isTop: Ref<boolean>\n    contentEl: Ref<HTMLElement | undefined>\n  }\n) {\n  const vm = getCurrentInstance('useActivator')\n  const activatorEl = ref<HTMLElement>()\n\n  let isHovered = false\n  let isFocused = false\n  let firstEnter = true\n\n  const openOnFocus = computed(() => props.openOnFocus || (props.openOnFocus == null && props.openOnHover))\n  const openOnClick = computed(() => props.openOnClick || (props.openOnClick == null && !props.openOnHover && !openOnFocus.value))\n\n  const { runOpenDelay, runCloseDelay } = useDelay(props, value => {\n    if (\n      value === (\n        (props.openOnHover && isHovered) ||\n        (openOnFocus.value && isFocused)\n      ) && !(props.openOnHover && isActive.value && !isTop.value)\n    ) {\n      if (isActive.value !== value) {\n        firstEnter = true\n      }\n      isActive.value = value\n    }\n  })\n\n  const cursorTarget = ref<[x: number, y: number]>()\n  const availableEvents = {\n    onClick: (e: MouseEvent) => {\n      e.stopPropagation()\n      activatorEl.value = (e.currentTarget || e.target) as HTMLElement\n      if (!isActive.value) {\n        cursorTarget.value = [e.clientX, e.clientY]\n      }\n      isActive.value = !isActive.value\n    },\n    onMouseenter: (e: MouseEvent) => {\n      isHovered = true\n      activatorEl.value = (e.currentTarget || e.target) as HTMLElement\n      runOpenDelay()\n    },\n    onMouseleave: (e: MouseEvent) => {\n      isHovered = false\n      runCloseDelay()\n    },\n    onFocus: (e: FocusEvent) => {\n      if (matchesSelector(e.target as HTMLElement, ':focus-visible') === false) return\n\n      isFocused = true\n      e.stopPropagation()\n      activatorEl.value = (e.currentTarget || e.target) as HTMLElement\n\n      runOpenDelay()\n    },\n    onBlur: (e: FocusEvent) => {\n      isFocused = false\n      e.stopPropagation()\n\n      runCloseDelay({ minDelay: 1 })\n    },\n  }\n\n  const activatorEvents = computed(() => {\n    const events: Partial<typeof availableEvents> = {}\n\n    if (openOnClick.value) {\n      events.onClick = availableEvents.onClick\n    }\n    if (props.openOnHover) {\n      events.onMouseenter = availableEvents.onMouseenter\n      events.onMouseleave = availableEvents.onMouseleave\n    }\n    if (openOnFocus.value) {\n      events.onFocus = availableEvents.onFocus\n      events.onBlur = availableEvents.onBlur\n    }\n\n    return events\n  })\n\n  const contentEvents = computed(() => {\n    const events: Record<string, EventListener> = {}\n\n    if (props.openOnHover) {\n      events.onMouseenter = () => {\n        isHovered = true\n        runOpenDelay()\n      }\n      events.onMouseleave = () => {\n        isHovered = false\n        runCloseDelay()\n      }\n    }\n\n    if (openOnFocus.value) {\n      events.onFocusin = (e: Event) => {\n        if (!(e.target as HTMLElement).matches(':focus-visible')) return\n        isFocused = true\n        runOpenDelay()\n      }\n      events.onFocusout = () => {\n        isFocused = false\n        runCloseDelay({ minDelay: 1 })\n      }\n    }\n\n    if (props.closeOnContentClick) {\n      const menu = inject(VMenuSymbol, null)\n      events.onClick = () => {\n        isActive.value = false\n        menu?.closeParents()\n      }\n    }\n\n    return events\n  })\n\n  const scrimEvents = computed(() => {\n    const events: Record<string, EventListener> = {}\n\n    if (props.openOnHover) {\n      events.onMouseenter = () => {\n        if (firstEnter) {\n          isHovered = true\n          firstEnter = false\n          runOpenDelay()\n        }\n      }\n      events.onMouseleave = () => {\n        isHovered = false\n        runCloseDelay()\n      }\n    }\n\n    return events\n  })\n\n  watch(isTop, val => {\n    if (val && (\n      (props.openOnHover && !isHovered && (!openOnFocus.value || !isFocused)) ||\n      (openOnFocus.value && !isFocused && (!props.openOnHover || !isHovered))\n    ) && !contentEl.value?.contains(document.activeElement)) {\n      isActive.value = false\n    }\n  })\n\n  watch(isActive, val => {\n    if (!val) {\n      setTimeout(() => {\n        cursorTarget.value = undefined\n      })\n    }\n  }, { flush: 'post' })\n\n  const activatorRef = templateRef()\n  watchEffect(() => {\n    if (!activatorRef.value) return\n\n    nextTick(() => {\n      activatorEl.value = activatorRef.el\n    })\n  })\n\n  const targetRef = templateRef()\n  const target = computed(() => {\n    if (props.target === 'cursor' && cursorTarget.value) return cursorTarget.value\n    if (targetRef.value) return targetRef.el\n    return getTarget(props.target, vm) || activatorEl.value\n  })\n  const targetEl = computed(() => {\n    return Array.isArray(target.value)\n      ? undefined\n      : target.value\n  })\n\n  let scope: EffectScope\n  watch(() => !!props.activator, val => {\n    if (val && IN_BROWSER) {\n      scope = effectScope()\n      scope.run(() => {\n        _useActivator(props, vm, { activatorEl, activatorEvents })\n      })\n    } else if (scope) {\n      scope.stop()\n    }\n  }, { flush: 'post', immediate: true })\n\n  onScopeDispose(() => {\n    scope?.stop()\n  })\n\n  return { activatorEl, activatorRef, target, targetEl, targetRef, activatorEvents, contentEvents, scrimEvents }\n}\n\nfunction _useActivator (\n  props: ActivatorProps,\n  vm: ComponentInternalInstance,\n  { activatorEl, activatorEvents }: Pick<ReturnType<typeof useActivator>, 'activatorEl' | 'activatorEvents'>\n) {\n  watch(() => props.activator, (val, oldVal) => {\n    if (oldVal && val !== oldVal) {\n      const activator = getActivator(oldVal)\n      activator && unbindActivatorProps(activator)\n    }\n    if (val) {\n      nextTick(() => bindActivatorProps())\n    }\n  }, { immediate: true })\n\n  watch(() => props.activatorProps, () => {\n    bindActivatorProps()\n  })\n\n  onScopeDispose(() => {\n    unbindActivatorProps()\n  })\n\n  function bindActivatorProps (el = getActivator(), _props = props.activatorProps) {\n    if (!el) return\n\n    bindProps(el, mergeProps(activatorEvents.value, _props))\n  }\n\n  function unbindActivatorProps (el = getActivator(), _props = props.activatorProps) {\n    if (!el) return\n\n    unbindProps(el, mergeProps(activatorEvents.value, _props))\n  }\n\n  function getActivator (selector = props.activator): HTMLElement | undefined {\n    const activator = getTarget(selector, vm)\n\n    // The activator should only be a valid element (Ignore comments and text nodes)\n    activatorEl.value = activator?.nodeType === Node.ELEMENT_NODE ? activator : undefined\n\n    return activatorEl.value\n  }\n}\n\nfunction getTarget<T extends 'parent' | string | Element | ComponentPublicInstance | [x: number, y: number] | undefined> (\n  selector: T,\n  vm: ComponentInternalInstance\n): HTMLElement | undefined | (T extends any[] ? [x: number, y: number] : never) {\n  if (!selector) return\n\n  let target\n  if (selector === 'parent') {\n    let el = vm?.proxy?.$el?.parentNode\n    while (el?.hasAttribute('data-no-activator')) {\n      el = el.parentNode\n    }\n    target = el\n  } else if (typeof selector === 'string') {\n    // Selector\n    target = document.querySelector(selector)\n  } else if ('$el' in selector) {\n    // Component (ref)\n    target = selector.$el\n  } else {\n    // HTMLElement | Element | [x, y]\n    target = selector\n  }\n\n  return target\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VOverlay/util/point.ts",
    "content": "// Types\nimport type { ParsedAnchor } from '@/util'\nimport type { Box } from '@/util/box'\n\ntype Point = { x: number, y: number }\ndeclare class As<T extends string> {\n  private as: T\n}\ntype ElementPoint = Point & As<'element'>\ntype ViewportPoint = Point & As<'viewport'>\ntype Offset = Point & As<'offset'>\n\n/** Convert a point in local space to viewport space */\nexport function elementToViewport (point: ElementPoint, offset: Offset | Box) {\n  return {\n    x: point.x + offset.x,\n    y: point.y + offset.y,\n  } as ViewportPoint\n}\n\n/** Convert a point in viewport space to local space */\nexport function viewportToElement (point: ViewportPoint, offset: Offset | Box) {\n  return {\n    x: point.x - offset.x,\n    y: point.y - offset.y,\n  } as ElementPoint\n}\n\n/** Get the difference between two points */\nexport function getOffset<T extends Point> (a: T, b: T) {\n  return {\n    x: a.x - b.x,\n    y: a.y - b.y,\n  } as Offset\n}\n\n/** Convert an anchor object to a point in local space */\nexport function anchorToPoint (anchor: ParsedAnchor, box: Box): ViewportPoint {\n  if (anchor.side === 'top' || anchor.side === 'bottom') {\n    const { side, align } = anchor\n\n    const x: number =\n      align === 'left' ? 0\n      : align === 'center' ? box.width / 2\n      : align === 'right' ? box.width\n      : align\n    const y: number =\n      side === 'top' ? 0\n      : side === 'bottom' ? box.height\n      : side\n\n    return elementToViewport({ x, y } as ElementPoint, box)\n  } else if (anchor.side === 'left' || anchor.side === 'right') {\n    const { side, align } = anchor\n\n    const x: number =\n      side === 'left' ? 0\n      : side === 'right' ? box.width\n      : side\n    const y: number =\n      align === 'top' ? 0\n      : align === 'center' ? box.height / 2\n      : align === 'bottom' ? box.height\n      : align\n\n    return elementToViewport({ x, y } as ElementPoint, box)\n  }\n\n  return elementToViewport({\n    x: box.width / 2,\n    y: box.height / 2,\n  } as ElementPoint, box)\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VPagination/VPagination.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-pagination\n    &__list\n      margin: 0\n      padding: 0\n      display: inline-flex\n      list-style-type: none\n      justify-content: center\n      width: 100%\n\n    &__item,\n    &__first,\n    &__prev,\n    &__next,\n    &__last\n      margin: $pagination-item-margin\n"
  },
  {
    "path": "packages/vuetify/src/components/VPagination/VPagination.tsx",
    "content": "// Styles\nimport './VPagination.sass'\n\n// Components\nimport { VBtn } from '../VBtn'\n\n// Composables\nimport { useDisplay } from '@/composables'\nimport { makeBorderProps } from '@/composables/border'\nimport { makeComponentProps } from '@/composables/component'\nimport { provideDefaults } from '@/composables/defaults'\nimport { makeDensityProps } from '@/composables/density'\nimport { makeElevationProps } from '@/composables/elevation'\nimport { IconValue } from '@/composables/icons'\nimport { useLocale, useRtl } from '@/composables/locale'\nimport { useProxiedModel } from '@/composables/proxiedModel'\nimport { useRefs } from '@/composables/refs'\nimport { useResizeObserver } from '@/composables/resizeObserver'\nimport { makeRoundedProps } from '@/composables/rounded'\nimport { makeSizeProps } from '@/composables/size'\nimport { makeTagProps } from '@/composables/tag'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\nimport { makeVariantProps } from '@/composables/variant'\n\n// Utilities\nimport { computed, nextTick, shallowRef, toRef } from 'vue'\nimport { createRange, genericComponent, keyValues, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { ComponentPublicInstance } from 'vue'\n\ntype ItemSlot = {\n  isActive: boolean\n  key: string | number\n  page: string\n  props: Record<string, any>\n}\n\ntype ControlSlot = {\n  icon: IconValue\n  onClick: (e: Event) => void\n  disabled: boolean\n  'aria-label': string\n  'aria-disabled': boolean\n}\n\nexport type VPaginationSlots = {\n  item: ItemSlot\n  first: ControlSlot\n  prev: ControlSlot\n  next: ControlSlot\n  last: ControlSlot\n}\n\nexport const makeVPaginationProps = propsFactory({\n  activeColor: String,\n  start: {\n    type: [Number, String],\n    default: 1,\n  },\n  modelValue: {\n    type: Number,\n    default: (props: any) => props.start as number,\n  },\n  disabled: Boolean,\n  length: {\n    type: [Number, String],\n    default: 1,\n    validator: (val: number) => val % 1 === 0,\n  },\n  totalVisible: [Number, String],\n  firstIcon: {\n    type: IconValue,\n    default: '$first',\n  },\n  prevIcon: {\n    type: IconValue,\n    default: '$prev',\n  },\n  nextIcon: {\n    type: IconValue,\n    default: '$next',\n  },\n  lastIcon: {\n    type: IconValue,\n    default: '$last',\n  },\n  ariaLabel: {\n    type: String,\n    default: '$vuetify.pagination.ariaLabel.root',\n  },\n  pageAriaLabel: {\n    type: String,\n    default: '$vuetify.pagination.ariaLabel.page',\n  },\n  currentPageAriaLabel: {\n    type: String,\n    default: '$vuetify.pagination.ariaLabel.currentPage',\n  },\n  firstAriaLabel: {\n    type: String,\n    default: '$vuetify.pagination.ariaLabel.first',\n  },\n  previousAriaLabel: {\n    type: String,\n    default: '$vuetify.pagination.ariaLabel.previous',\n  },\n  nextAriaLabel: {\n    type: String,\n    default: '$vuetify.pagination.ariaLabel.next',\n  },\n  lastAriaLabel: {\n    type: String,\n    default: '$vuetify.pagination.ariaLabel.last',\n  },\n  ellipsis: {\n    type: String,\n    default: '...',\n  },\n  showFirstLastPage: Boolean,\n\n  ...makeBorderProps(),\n  ...makeComponentProps(),\n  ...makeDensityProps(),\n  ...makeElevationProps(),\n  ...makeRoundedProps(),\n  ...makeSizeProps(),\n  ...makeTagProps({ tag: 'nav' }),\n  ...makeThemeProps(),\n  ...makeVariantProps({ variant: 'text' } as const),\n}, 'VPagination')\n\nexport const VPagination = genericComponent<VPaginationSlots>()({\n  name: 'VPagination',\n\n  props: makeVPaginationProps(),\n\n  emits: {\n    'update:modelValue': (value: number) => true,\n    first: (value: number) => true,\n    prev: (value: number) => true,\n    next: (value: number) => true,\n    last: (value: number) => true,\n  },\n\n  setup (props, { slots, emit }) {\n    const page = useProxiedModel(props, 'modelValue')\n    const { t, n } = useLocale()\n    const { isRtl } = useRtl()\n    const { themeClasses } = provideTheme(props)\n    const { width } = useDisplay()\n    const maxButtons = shallowRef(-1)\n\n    provideDefaults(undefined, { scoped: true })\n\n    const { resizeRef } = useResizeObserver((entries: ResizeObserverEntry[]) => {\n      if (!entries.length) return\n\n      const { target, contentRect } = entries[0]\n\n      const firstItem = target.querySelector('.v-pagination__list > *') as HTMLElement\n\n      if (!firstItem) return\n\n      const totalWidth = contentRect.width\n      const itemWidth =\n        firstItem.offsetWidth +\n        parseFloat(getComputedStyle(firstItem).marginRight) * 2\n\n      maxButtons.value = getMax(totalWidth, itemWidth)\n    })\n\n    const length = computed(() => parseInt(props.length, 10))\n    const start = computed(() => parseInt(props.start, 10))\n\n    const totalVisible = computed(() => {\n      if (props.totalVisible != null) return parseInt(props.totalVisible, 10)\n      else if (maxButtons.value >= 0) return maxButtons.value\n      return getMax(width.value, 58)\n    })\n\n    function getMax (totalWidth: number, itemWidth: number) {\n      const minButtons = props.showFirstLastPage ? 5 : 3\n      return Math.max(0, Math.floor(\n        // Round to two decimal places to avoid floating point errors\n        Number(((totalWidth - itemWidth * minButtons) / itemWidth).toFixed(2))\n      ))\n    }\n\n    const range = computed(() => {\n      if (length.value <= 0 || isNaN(length.value) || length.value > Number.MAX_SAFE_INTEGER) return []\n\n      if (totalVisible.value <= 0) return []\n      else if (totalVisible.value === 1) return [page.value]\n\n      if (length.value <= totalVisible.value) {\n        return createRange(length.value, start.value)\n      }\n\n      const even = totalVisible.value % 2 === 0\n      const middle = even ? totalVisible.value / 2 : Math.floor(totalVisible.value / 2)\n      const left = even ? middle : middle + 1\n      const right = length.value - middle\n\n      if (left - page.value >= 0) {\n        return [...createRange(Math.max(1, totalVisible.value - 1), start.value), props.ellipsis, length.value]\n      } else if (page.value - right >= (even ? 1 : 0)) {\n        const rangeLength = totalVisible.value - 1\n        const rangeStart = length.value - rangeLength + start.value\n        return [start.value, props.ellipsis, ...createRange(rangeLength, rangeStart)]\n      } else {\n        const rangeLength = Math.max(1, totalVisible.value - 2)\n        const rangeStart = rangeLength === 1 ? page.value : page.value - Math.ceil(rangeLength / 2) + start.value\n        return [start.value, props.ellipsis, ...createRange(rangeLength, rangeStart), props.ellipsis, length.value]\n      }\n    })\n\n    // TODO: 'first' | 'prev' | 'next' | 'last' does not work here?\n    function setValue (e: Event, value: number, event?: any) {\n      e.preventDefault()\n      page.value = value\n      event && emit(event, value)\n    }\n\n    const { refs, updateRef } = useRefs<ComponentPublicInstance>()\n\n    provideDefaults({\n      VPaginationBtn: {\n        color: toRef(() => props.color),\n        border: toRef(() => props.border),\n        density: toRef(() => props.density),\n        size: toRef(() => props.size),\n        variant: toRef(() => props.variant),\n        rounded: toRef(() => props.rounded),\n        elevation: toRef(() => props.elevation),\n      },\n    })\n\n    const items = computed(() => {\n      return range.value.map((item, index) => {\n        const ref = (e: any) => updateRef(e, index)\n\n        if (typeof item === 'string') {\n          return {\n            isActive: false,\n            key: `ellipsis-${index}`,\n            page: item,\n            props: {\n              ref,\n              ellipsis: true,\n              icon: true,\n              disabled: true,\n            },\n          }\n        } else {\n          const isActive = item === page.value\n          return {\n            isActive,\n            key: item,\n            page: n(item),\n            props: {\n              ref,\n              ellipsis: false,\n              icon: true,\n              disabled: !!props.disabled || Number(props.length) < 2,\n              color: isActive ? props.activeColor : props.color,\n              'aria-current': isActive,\n              'aria-label': t(isActive ? props.currentPageAriaLabel : props.pageAriaLabel, item),\n              onClick: (e: Event) => setValue(e, item),\n            },\n          }\n        }\n      })\n    })\n\n    const controls = computed(() => {\n      const prevDisabled = !!props.disabled || page.value <= start.value\n      const nextDisabled = !!props.disabled || page.value >= start.value + length.value - 1\n\n      return {\n        first: props.showFirstLastPage ? {\n          icon: isRtl.value ? props.lastIcon : props.firstIcon,\n          onClick: (e: Event) => setValue(e, start.value, 'first'),\n          disabled: prevDisabled,\n          'aria-label': t(props.firstAriaLabel),\n          'aria-disabled': prevDisabled,\n        } : undefined,\n        prev: {\n          icon: isRtl.value ? props.nextIcon : props.prevIcon,\n          onClick: (e: Event) => setValue(e, page.value - 1, 'prev'),\n          disabled: prevDisabled,\n          'aria-label': t(props.previousAriaLabel),\n          'aria-disabled': prevDisabled,\n        },\n        next: {\n          icon: isRtl.value ? props.prevIcon : props.nextIcon,\n          onClick: (e: Event) => setValue(e, page.value + 1, 'next'),\n          disabled: nextDisabled,\n          'aria-label': t(props.nextAriaLabel),\n          'aria-disabled': nextDisabled,\n        },\n        last: props.showFirstLastPage ? {\n          icon: isRtl.value ? props.firstIcon : props.lastIcon,\n          onClick: (e: Event) => setValue(e, start.value + length.value - 1, 'last'),\n          disabled: nextDisabled,\n          'aria-label': t(props.lastAriaLabel),\n          'aria-disabled': nextDisabled,\n        } : undefined,\n      }\n    })\n\n    function updateFocus () {\n      const currentIndex = page.value - start.value\n      refs.value[currentIndex]?.$el.focus()\n    }\n\n    function onKeydown (e: KeyboardEvent) {\n      if (e.key === keyValues.left && !props.disabled && page.value > Number(props.start)) {\n        page.value = page.value - 1\n        nextTick(updateFocus)\n      } else if (e.key === keyValues.right && !props.disabled && page.value < start.value + length.value - 1) {\n        page.value = page.value + 1\n        nextTick(updateFocus)\n      }\n    }\n\n    useRender(() => (\n      <props.tag\n        ref={ resizeRef }\n        class={[\n          'v-pagination',\n          themeClasses.value,\n          props.class,\n        ]}\n        style={ props.style }\n        role=\"navigation\"\n        aria-label={ t(props.ariaLabel) }\n        onKeydown={ onKeydown }\n        data-test=\"v-pagination-root\"\n      >\n        <ul class=\"v-pagination__list\">\n          { props.showFirstLastPage && (\n            <li key=\"first\" class=\"v-pagination__first\" data-test=\"v-pagination-first\">\n              { slots.first ? slots.first(controls.value.first!) : (\n                <VBtn _as=\"VPaginationBtn\" { ...controls.value.first } />\n              )}\n            </li>\n          )}\n\n          <li key=\"prev\" class=\"v-pagination__prev\" data-test=\"v-pagination-prev\">\n            { slots.prev ? slots.prev(controls.value.prev) : (\n              <VBtn _as=\"VPaginationBtn\" { ...controls.value.prev } />\n            )}\n          </li>\n\n          { items.value.map((item, index) => (\n            <li\n              key={ item.key }\n              class={[\n                'v-pagination__item',\n                {\n                  'v-pagination__item--is-active': item.isActive,\n                },\n              ]}\n              data-test=\"v-pagination-item\"\n            >\n              { slots.item ? slots.item(item) : (\n                <VBtn _as=\"VPaginationBtn\" { ...item.props }>{ item.page }</VBtn>\n              )}\n            </li>\n          ))}\n\n          <li\n            key=\"next\"\n            class=\"v-pagination__next\"\n            data-test=\"v-pagination-next\"\n          >\n            { slots.next ? slots.next(controls.value.next) : (\n              <VBtn _as=\"VPaginationBtn\" { ...controls.value.next } />\n            )}\n          </li>\n\n          { props.showFirstLastPage && (\n            <li\n              key=\"last\"\n              class=\"v-pagination__last\"\n              data-test=\"v-pagination-last\"\n            >\n              { slots.last ? slots.last(controls.value.last!) : (\n                <VBtn _as=\"VPaginationBtn\" { ...controls.value.last } />\n              )}\n            </li>\n          )}\n        </ul>\n      </props.tag>\n    ))\n\n    return {}\n  },\n})\n\nexport type VPagination = InstanceType<typeof VPagination>\n"
  },
  {
    "path": "packages/vuetify/src/components/VPagination/__tests__/VPagination.spec.browser.tsx",
    "content": "// Components\nimport { VPagination } from '../VPagination'\nimport { VLocaleProvider } from '@/components/VLocaleProvider'\n\n// Utilities\nimport { page, render, screen, showcase, userEvent } from '@test'\nimport { ref } from 'vue'\n\nconst stories = {\n  RTL: (\n    <VLocaleProvider rtl>\n      <VPagination length=\"5\" />\n    </VLocaleProvider>\n  ),\n}\n\ndescribe('VPagination', () => {\n  it('should render set length', () => {\n    render(() => (\n      <VPagination length=\"3\" />\n    ))\n\n    expect(screen.getAllByCSS('.v-pagination__item')).toHaveLength(3)\n  })\n\n  it('should react to mouse navigation', async () => {\n    render(() => (\n      <VPagination length=\"3\" />\n    ))\n\n    const prevBtn = screen.getByCSS('.v-pagination__prev')\n    const nextBtn = screen.getByCSS('.v-pagination__next')\n\n    await userEvent.click(screen.getAllByCSS('.v-pagination__item .v-btn').at(1)!)\n\n    expect(screen.getAllByCSS('.v-pagination__item').at(1)).toHaveClass('v-pagination__item--is-active')\n\n    await userEvent.click(nextBtn)\n\n    expect(screen.getAllByCSS('.v-pagination__item').at(2)).toHaveClass('v-pagination__item--is-active')\n\n    await userEvent.click(prevBtn)\n    await userEvent.click(prevBtn)\n\n    expect(screen.getAllByCSS('.v-pagination__item').at(0)).toHaveClass('v-pagination__item--is-active')\n  })\n\n  it('should react to keyboard navigation', async () => {\n    const model = ref(2)\n    render(() => (\n      <VPagination v-model={ model.value } length=\"3\" />\n    ))\n\n    await userEvent.tab()\n    await userEvent.keyboard('{ArrowLeft}')\n\n    expect(screen.getAllByCSS('.v-pagination__item').at(0)).toHaveClass('v-pagination__item--is-active')\n\n    await userEvent.keyboard('{ArrowRight}{ArrowRight}')\n\n    expect(screen.getAllByCSS('.v-pagination__item').at(2)).toHaveClass('v-pagination__item--is-active')\n  })\n\n  it('should render offset pages when using start prop', () => {\n    render(() => (\n      <VPagination length=\"3\" start={ 3 } />\n    ))\n\n    expect(screen.getAllByCSS('.v-pagination__item .v-btn').at(0)).toHaveTextContent('3')\n    expect(screen.getAllByCSS('.v-pagination__item .v-btn').at(1)).toHaveTextContent('4')\n    expect(screen.getAllByCSS('.v-pagination__item .v-btn').at(2)).toHaveTextContent('5')\n  })\n\n  it('should render disabled buttons when length is zero', () => {\n    render(() => (\n      <VPagination length=\"0\" />\n    ))\n\n    expect(screen.getByCSS('.v-pagination__prev .v-btn')).toHaveAttribute('disabled')\n    expect(screen.getByCSS('.v-pagination__next .v-btn')).toHaveAttribute('disabled')\n  })\n\n  it('should only render set number of visible items', async () => {\n    render(() => (\n      <VPagination length=\"100\" totalVisible=\"5\" />\n    ))\n\n    // 5 buttons and 1 ellipsis\n    expect(screen.getAllByCSS('.v-pagination__item')).toHaveLength(6)\n\n    await userEvent.click(screen.getByText('4'))\n    // 5 buttons and 2 ellipsis\n    expect(screen.getAllByCSS('.v-pagination__item')).toHaveLength(7)\n  })\n\n  it('should limit items when not enough space', async () => {\n    await page.viewport(500, 500)\n\n    render(() => (\n      <VPagination length=\"100\" />\n    ))\n\n    expect(screen.getAllByCSS('.v-pagination__item')).toHaveLength(6)\n  })\n\n  it('should use color props', () => {\n    render(() => (\n      <VPagination color=\"error\" activeColor=\"success\" length=\"5\" />\n    ))\n\n    expect(screen.getAllByCSS('.v-btn').at(0)).toHaveClass('text-error')\n    expect(screen.getAllByCSS('.v-btn').at(1)).toHaveClass('text-success')\n  })\n\n  it('should work with 2 total visible items', async () => {\n    render(() => (\n      <VPagination length=\"10\" totalVisible=\"2\" />\n    ))\n\n    expect(screen.getAllByCSS('.v-pagination__item')).toHaveLength(3)\n    expect(screen.getAllByCSS('.v-pagination__item').at(0)).toHaveTextContent('1')\n    expect(screen.getAllByCSS('.v-pagination__item').at(2)).toHaveTextContent('10')\n\n    await userEvent.click(screen.getByCSS('.v-pagination__next'))\n\n    expect(screen.getAllByCSS('.v-pagination__item')).toHaveLength(5)\n    expect(screen.getAllByCSS('.v-pagination__item').at(0)).toHaveTextContent('1')\n    expect(screen.getAllByCSS('.v-pagination__item').at(2)).toHaveTextContent('2')\n    expect(screen.getAllByCSS('.v-pagination__item').at(4)).toHaveTextContent('10')\n\n    await userEvent.click(screen.getAllByCSS('.v-pagination__item').at(4)!)\n\n    expect(screen.getAllByCSS('.v-pagination__item')).toHaveLength(3)\n    expect(screen.getAllByCSS('.v-pagination__item').at(0)).toHaveTextContent('1')\n    expect(screen.getAllByCSS('.v-pagination__item').at(2)).toHaveTextContent('10')\n\n    await userEvent.click(screen.getByCSS('.v-pagination__prev'))\n\n    expect(screen.getAllByCSS('.v-pagination__item')).toHaveLength(5)\n    expect(screen.getAllByCSS('.v-pagination__item').at(0)).toHaveTextContent('1')\n    expect(screen.getAllByCSS('.v-pagination__item').at(2)).toHaveTextContent('9')\n    expect(screen.getAllByCSS('.v-pagination__item').at(4)).toHaveTextContent('10')\n  })\n\n  it('should work with even total visible items', async () => {\n    render(() => (\n      <VPagination length=\"10\" totalVisible=\"4\" />\n    ))\n\n    expect(screen.getAllByCSS('.v-pagination__item')).toHaveLength(5)\n    expect(screen.getAllByCSS('.v-pagination__item').at(0)).toHaveTextContent('1')\n    expect(screen.getAllByCSS('.v-pagination__item').at(1)).toHaveTextContent('2')\n    expect(screen.getAllByCSS('.v-pagination__item').at(2)).toHaveTextContent('3')\n    expect(screen.getAllByCSS('.v-pagination__item').at(4)).toHaveTextContent('10')\n\n    await userEvent.click(screen.getByCSS('.v-pagination__next'))\n\n    expect(screen.getAllByCSS('.v-pagination__item')).toHaveLength(5)\n    expect(screen.getAllByCSS('.v-pagination__item').at(0)).toHaveTextContent('1')\n    expect(screen.getAllByCSS('.v-pagination__item').at(1)).toHaveTextContent('2')\n    expect(screen.getAllByCSS('.v-pagination__item').at(2)).toHaveTextContent('3')\n    expect(screen.getAllByCSS('.v-pagination__item').at(4)).toHaveTextContent('10')\n\n    await userEvent.click(screen.getAllByCSS('.v-pagination__item').at(4)!)\n\n    expect(screen.getAllByCSS('.v-pagination__item')).toHaveLength(5)\n    expect(screen.getAllByCSS('.v-pagination__item').at(0)).toHaveTextContent('1')\n    expect(screen.getAllByCSS('.v-pagination__item').at(2)).toHaveTextContent('8')\n    expect(screen.getAllByCSS('.v-pagination__item').at(3)).toHaveTextContent('9')\n    expect(screen.getAllByCSS('.v-pagination__item').at(4)).toHaveTextContent('10')\n\n    await userEvent.click(screen.getByCSS('.v-pagination__prev'))\n\n    expect(screen.getAllByCSS('.v-pagination__item')).toHaveLength(5)\n    expect(screen.getAllByCSS('.v-pagination__item').at(0)).toHaveTextContent('1')\n    expect(screen.getAllByCSS('.v-pagination__item').at(2)).toHaveTextContent('8')\n    expect(screen.getAllByCSS('.v-pagination__item').at(3)).toHaveTextContent('9')\n    expect(screen.getAllByCSS('.v-pagination__item').at(4)).toHaveTextContent('10')\n  })\n\n  it('should work with odd total visible items', async () => {\n    render(() => (\n      <VPagination length=\"10\" totalVisible=\"3\" />\n    ))\n\n    const prevBtn = screen.getByCSS('.v-pagination__prev')\n    const nextBtn = screen.getByCSS('.v-pagination__next')\n\n    expect(screen.getAllByCSS('.v-pagination__item')).toHaveLength(4)\n    expect(screen.getAllByCSS('.v-pagination__item').at(0)).toHaveTextContent('1')\n    expect(screen.getAllByCSS('.v-pagination__item').at(1)).toHaveTextContent('2')\n    expect(screen.getAllByCSS('.v-pagination__item').at(3)).toHaveTextContent('10')\n\n    await userEvent.click(nextBtn)\n    expect(screen.getAllByCSS('.v-pagination__item')).toHaveLength(4)\n    await userEvent.click(nextBtn)\n\n    expect(screen.getAllByCSS('.v-pagination__item')).toHaveLength(5)\n    expect(screen.getAllByCSS('.v-pagination__item').at(0)).toHaveTextContent('1')\n    expect(screen.getAllByCSS('.v-pagination__item').at(2)).toHaveTextContent('3')\n    expect(screen.getAllByCSS('.v-pagination__item').at(4)).toHaveTextContent('10')\n\n    await userEvent.click(screen.getAllByCSS('.v-pagination__item').at(4)!)\n\n    expect(screen.getAllByCSS('.v-pagination__item')).toHaveLength(4)\n    expect(screen.getAllByCSS('.v-pagination__item').at(0)).toHaveTextContent('1')\n    expect(screen.getAllByCSS('.v-pagination__item').at(2)).toHaveTextContent('9')\n    expect(screen.getAllByCSS('.v-pagination__item').at(3)).toHaveTextContent('10')\n\n    await userEvent.click(prevBtn)\n    expect(screen.getAllByCSS('.v-pagination__item')).toHaveLength(4)\n    await userEvent.click(prevBtn)\n\n    expect(screen.getAllByCSS('.v-pagination__item')).toHaveLength(5)\n    expect(screen.getAllByCSS('.v-pagination__item').at(0)).toHaveTextContent('1')\n    expect(screen.getAllByCSS('.v-pagination__item').at(2)).toHaveTextContent('8')\n    expect(screen.getAllByCSS('.v-pagination__item').at(4)).toHaveTextContent('10')\n  })\n\n  showcase({ stories })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VPagination/_variables.scss",
    "content": "// Defaults\n$pagination-item-margin: .3rem !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VPagination/index.ts",
    "content": "export { VPagination } from './VPagination'\n"
  },
  {
    "path": "packages/vuetify/src/components/VParallax/VParallax.sass",
    "content": "@use '../../styles/tools'\n\n@include tools.layer('components')\n  .v-parallax\n    position: relative\n    overflow: hidden\n\n    &--active > .v-img__img\n      will-change: transform\n"
  },
  {
    "path": "packages/vuetify/src/components/VParallax/VParallax.tsx",
    "content": "// Styles\nimport './VParallax.sass'\n\n// Components\nimport { VImg } from '@/components/VImg'\n\n// Composables\nimport { useDisplay } from '@/composables'\nimport { makeComponentProps } from '@/composables/component'\nimport { useIntersectionObserver } from '@/composables/intersectionObserver'\nimport { useResizeObserver } from '@/composables/resizeObserver'\n\n// Utilities\nimport { computed, onBeforeUnmount, ref, watch, watchEffect } from 'vue'\nimport { clamp, genericComponent, getScrollParent, PREFERS_REDUCED_MOTION, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { VImgSlots } from '@/components/VImg/VImg'\n\nfunction floor (val: number) {\n  return Math.floor(Math.abs(val)) * Math.sign(val)\n}\n\nexport const makeVParallaxProps = propsFactory({\n  scale: {\n    type: [Number, String],\n    default: 0.5,\n  },\n\n  ...makeComponentProps(),\n}, 'VParallax')\n\nexport const VParallax = genericComponent<VImgSlots>()({\n  name: 'VParallax',\n\n  props: makeVParallaxProps(),\n\n  setup (props, { slots }) {\n    const { intersectionRef, isIntersecting } = useIntersectionObserver()\n    const { resizeRef, contentRect } = useResizeObserver()\n    const { height: displayHeight } = useDisplay()\n\n    const root = ref<VImg>()\n\n    watchEffect(() => {\n      intersectionRef.value = resizeRef.value = root.value?.$el\n    })\n\n    let scrollParent: Element | Document\n    watch(isIntersecting, val => {\n      if (val) {\n        scrollParent = getScrollParent(intersectionRef.value)\n        scrollParent = scrollParent === document.scrollingElement ? document : scrollParent\n        scrollParent.addEventListener('scroll', onScroll, { passive: true })\n        onScroll()\n      } else {\n        scrollParent.removeEventListener('scroll', onScroll)\n      }\n    })\n\n    onBeforeUnmount(() => {\n      scrollParent?.removeEventListener('scroll', onScroll)\n    })\n\n    watch(displayHeight, onScroll)\n    watch(() => contentRect.value?.height, onScroll)\n\n    const scale = computed(() => {\n      return 1 - clamp(Number(props.scale))\n    })\n\n    let frame = -1\n    function onScroll () {\n      if (!isIntersecting.value || PREFERS_REDUCED_MOTION()) return\n\n      cancelAnimationFrame(frame)\n      frame = requestAnimationFrame(() => {\n        const el: HTMLElement | null = (root.value?.$el as Element).querySelector('.v-img__img')\n        if (!el) return\n\n        const scrollHeight = scrollParent instanceof Document ? document.documentElement.clientHeight : scrollParent.clientHeight\n        const scrollPos = scrollParent instanceof Document ? window.scrollY : scrollParent.scrollTop\n        const top = intersectionRef.value!.getBoundingClientRect().top + scrollPos\n        const height = contentRect.value!.height\n\n        const center = top + (height - scrollHeight) / 2\n        const translate = floor((scrollPos - center) * scale.value)\n        const sizeScale = Math.max(1, (scale.value * (scrollHeight - height) + height) / height)\n\n        el.style.setProperty('transform', `translateY(${translate}px) scale(${sizeScale})`)\n      })\n    }\n\n    useRender(() => (\n      <VImg\n        class={[\n          'v-parallax',\n          { 'v-parallax--active': isIntersecting.value },\n          props.class,\n        ]}\n        style={ props.style }\n        ref={ root }\n        cover\n        onLoadstart={ onScroll }\n        onLoad={ onScroll }\n        v-slots={ slots }\n      />\n    ))\n\n    return {}\n  },\n})\n\nexport type VParallax = InstanceType<typeof VParallax>\n"
  },
  {
    "path": "packages/vuetify/src/components/VParallax/index.ts",
    "content": "export { VParallax } from './VParallax'\n"
  },
  {
    "path": "packages/vuetify/src/components/VProgressCircular/VProgressCircular.sass",
    "content": "@use 'sass:list'\n@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  // Elements\n  .v-progress-circular\n    align-items: center\n    display: inline-flex\n    justify-content: center\n    overflow: hidden\n    position: relative\n    vertical-align: middle\n\n    > svg\n      width: 100%\n      height: 100%\n      margin: auto\n      position: absolute\n      top: 0\n      bottom: 0\n      left: 0\n      right: 0\n      z-index: 0\n\n  .v-progress-circular__content\n    align-items: center\n    display: flex\n    justify-content: center\n\n  .v-progress-circular__underlay\n    color: $progress-circular-underlay-color\n    stroke: currentColor\n    z-index: 1\n\n  .v-progress-circular__overlay\n    stroke: currentColor\n    transition: $progress-circular-overlay-transition\n    z-index: 2\n\n  .v-progress-circular--revealing\n    --progress-reveal-duration: $progress-circular-reveal-duration\n\n    .v-progress-circular__overlay\n      transition-duration: var(--progress-reveal-duration), 0s\n\n  // Modifiers\n  .v-progress-circular\n    @each $name, $multiplier in $progress-circular-sizes\n      $size: $progress-circular-size + (settings.$size-scale * $multiplier)\n\n      &--size-#{$name}\n        height: $size\n        width: $size\n\n  .v-progress-circular--indeterminate\n    > svg\n      animation: $progress-circular-rotate-animation\n      transform-origin: center center\n      transition: $progress-circular-intermediate-svg-transition\n\n    .v-progress-circular__overlay\n      animation: $progress-circular-rotate-dash, $progress-circular-rotate-animation\n      stroke-dasharray: 25, 200\n      stroke-dashoffset: 0\n      stroke-linecap: round\n      transform-origin: center center\n      transform: $progress-circular-overlay-transform\n\n  .v-progress-circular--disable-shrink\n    > svg\n      animation-duration: list.nth($progress-circular-rotate-animation, 2) * .5\n\n    .v-progress-circular__overlay\n      animation: none\n\n  .v-progress-circular--indeterminate:not(.v-progress-circular--visible)\n    > svg,\n    .v-progress-circular__overlay\n      animation-play-state: paused\n\n  @keyframes progress-circular-dash\n    0%\n      stroke-dasharray: 1, 200\n      stroke-dashoffset: 0px\n\n    50%\n      stroke-dasharray: 100, 200\n      stroke-dashoffset: -15px\n\n    100%\n      stroke-dasharray: 100, 200\n      stroke-dashoffset: -124px\n\n  @keyframes progress-circular-rotate\n    100%\n      transform: rotate(270deg)\n"
  },
  {
    "path": "packages/vuetify/src/components/VProgressCircular/VProgressCircular.tsx",
    "content": "// Styles\nimport './VProgressCircular.sass'\n\n// Composables\nimport { useTextColor } from '@/composables/color'\nimport { makeComponentProps } from '@/composables/component'\nimport { useIntersectionObserver } from '@/composables/intersectionObserver'\nimport { useResizeObserver } from '@/composables/resizeObserver'\nimport { makeRevealProps, useReveal } from '@/composables/reveal'\nimport { makeSizeProps, useSize } from '@/composables/size'\nimport { makeTagProps } from '@/composables/tag'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\n\n// Utilities\nimport { computed, ref, toRef, watchEffect } from 'vue'\nimport { clamp, convertToUnit, genericComponent, PREFERS_REDUCED_MOTION, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\nexport const makeVProgressCircularProps = propsFactory({\n  bgColor: String,\n  color: String,\n  indeterminate: [Boolean, String] as PropType<boolean | 'disable-shrink'>,\n  rounded: Boolean,\n  modelValue: {\n    type: [Number, String],\n    default: 0,\n  },\n  rotate: {\n    type: [Number, String],\n    default: 0,\n  },\n  width: {\n    type: [Number, String],\n    default: 4,\n  },\n\n  ...makeComponentProps(),\n  ...makeRevealProps(),\n  ...makeSizeProps(),\n  ...makeTagProps({ tag: 'div' }),\n  ...makeThemeProps(),\n}, 'VProgressCircular')\n\ntype VProgressCircularSlots = {\n  default: { value: number }\n}\n\nexport const VProgressCircular = genericComponent<VProgressCircularSlots>()({\n  name: 'VProgressCircular',\n\n  props: makeVProgressCircularProps(),\n\n  setup (props, { slots }) {\n    const MAGIC_RADIUS_CONSTANT = 20\n    const CIRCUMFERENCE = 2 * Math.PI * MAGIC_RADIUS_CONSTANT\n\n    const root = ref<HTMLElement>()\n\n    const { themeClasses } = provideTheme(props)\n    const { sizeClasses, sizeStyles } = useSize(props)\n    const { textColorClasses, textColorStyles } = useTextColor(() => props.color)\n    const { textColorClasses: underlayColorClasses, textColorStyles: underlayColorStyles } = useTextColor(() => props.bgColor)\n    const { intersectionRef, isIntersecting } = useIntersectionObserver()\n    const { resizeRef, contentRect } = useResizeObserver()\n    const { state: revealState, duration: revealDuration } = useReveal(props)\n\n    const normalizedValue = toRef(() => revealState.value === 'initial' ? 0 : clamp(parseFloat(props.modelValue), 0, 100))\n    const width = toRef(() => Number(props.width))\n    const size = toRef(() => {\n      // Get size from element if size prop value is small, large etc\n      return sizeStyles.value\n        ? Number(props.size)\n        : contentRect.value\n          ? contentRect.value.width\n          : Math.max(width.value, 32)\n    })\n    const diameter = toRef(() => (MAGIC_RADIUS_CONSTANT / (1 - width.value / size.value)) * 2)\n    const strokeWidth = toRef(() => width.value / size.value * diameter.value)\n    const strokeDashOffset = toRef(() => {\n      const baseLength = ((100 - normalizedValue.value) / 100) * CIRCUMFERENCE\n      return props.rounded && normalizedValue.value > 0 && normalizedValue.value < 100\n        ? convertToUnit(Math.min(CIRCUMFERENCE - 0.01, baseLength + strokeWidth.value))\n        : convertToUnit(baseLength)\n    })\n    const startAngle = computed(() => {\n      const baseAngle = Number(props.rotate)\n      return props.rounded\n        ? baseAngle + (strokeWidth.value / 2) / CIRCUMFERENCE * 360\n        : baseAngle\n    })\n\n    watchEffect(() => {\n      intersectionRef.value = root.value\n      resizeRef.value = root.value\n    })\n\n    useRender(() => (\n      <props.tag\n        ref={ root }\n        class={[\n          'v-progress-circular',\n          {\n            'v-progress-circular--indeterminate': !!props.indeterminate,\n            'v-progress-circular--visible': isIntersecting.value,\n            'v-progress-circular--disable-shrink': props.indeterminate &&\n              (props.indeterminate === 'disable-shrink' || PREFERS_REDUCED_MOTION()),\n            'v-progress-circular--revealing': ['initial', 'pending'].includes(revealState.value),\n          },\n          themeClasses.value,\n          sizeClasses.value,\n          textColorClasses.value,\n          props.class,\n        ]}\n        style={[\n          sizeStyles.value,\n          textColorStyles.value,\n          {\n            '--progress-reveal-duration': `${revealDuration.value}ms`,\n          },\n          props.style,\n        ]}\n        role=\"progressbar\"\n        aria-valuemin=\"0\"\n        aria-valuemax=\"100\"\n        aria-valuenow={ props.indeterminate ? undefined : normalizedValue.value }\n      >\n        <svg\n          style={{\n            transform: `rotate(calc(-90deg + ${startAngle.value}deg))`,\n          }}\n          xmlns=\"http://www.w3.org/2000/svg\"\n          viewBox={ `0 0 ${diameter.value} ${diameter.value}` }\n        >\n          <circle\n            class={[\n              'v-progress-circular__underlay',\n              underlayColorClasses.value,\n            ]}\n            style={ underlayColorStyles.value }\n            fill=\"transparent\"\n            cx=\"50%\"\n            cy=\"50%\"\n            r={ MAGIC_RADIUS_CONSTANT }\n            stroke-width={ strokeWidth.value }\n            stroke-dasharray={ CIRCUMFERENCE }\n            stroke-dashoffset={ 0 }\n          />\n\n          <circle\n            class=\"v-progress-circular__overlay\"\n            fill=\"transparent\"\n            cx=\"50%\"\n            cy=\"50%\"\n            r={ MAGIC_RADIUS_CONSTANT }\n            stroke-width={ strokeWidth.value }\n            stroke-dasharray={ CIRCUMFERENCE }\n            stroke-dashoffset={ strokeDashOffset.value }\n            stroke-linecap={ props.rounded ? 'round' : undefined }\n          />\n        </svg>\n\n        { slots.default && (\n          <div class=\"v-progress-circular__content\">\n            { slots.default({ value: normalizedValue.value }) }\n          </div>\n        )}\n      </props.tag>\n    ))\n\n    return {}\n  },\n})\n\nexport type VProgressCircular = InstanceType<typeof VProgressCircular>\n"
  },
  {
    "path": "packages/vuetify/src/components/VProgressCircular/_variables.scss",
    "content": "// VProgressCircular\n$progress-circular-intermediate-svg-transition: all 0.2s ease-in-out !default;\n$progress-circular-overlay-transition: all 0.2s ease-in-out, stroke-width 0s !default;\n$progress-circular-overlay-transform: rotate(calc(-90deg)) !default;\n$progress-circular-reveal-duration: 900ms;\n$progress-circular-rotate-animation: progress-circular-rotate 1.4s linear infinite !default;\n$progress-circular-rotate-dash: progress-circular-dash 1.4s ease-in-out infinite !default;\n$progress-circular-size: 32px !default;\n$progress-circular-underlay-color: rgba(var(--v-border-color), var(--v-border-opacity)) !default;\n\n// Lists\n$progress-circular-sizes: (\n  'x-small': -2,\n  'small': -1,\n  'default': 0,\n  'large': 2,\n  'x-large': 4\n) !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VProgressCircular/index.ts",
    "content": "export { VProgressCircular } from './VProgressCircular'\n"
  },
  {
    "path": "packages/vuetify/src/components/VProgressLinear/VProgressLinear.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  // Block\n  .v-progress-linear\n    background: transparent\n    overflow: hidden\n    position: relative\n    transition: $progress-linear-transition, mask-size 0s\n    width: 100%\n\n    &--rounded\n      @include tools.rounded($progress-linear-border-radius)\n\n    @media (forced-colors: active)\n      border: thin solid buttontext\n\n  // Elements\n  .v-progress-linear__background,\n  .v-progress-linear__buffer\n    background: $progress-linear-background\n    bottom: 0\n    left: 0\n    opacity: $progress-linear-background-opacity\n    position: absolute\n    top: 0\n    width: 100%\n    transition-property: width, left, right\n    transition: inherit\n\n  @include tools.layer('trumps')\n    @media (forced-colors: active)\n      .v-progress-linear__buffer\n        background-color: highlight\n        opacity: .5\n\n  .v-progress-linear__content\n    align-items: center\n    display: flex\n    height: 100%\n    justify-content: center\n    left: 0\n    position: absolute\n    top: 0\n    width: 100%\n\n  .v-progress-linear--clickable\n    .v-progress-linear__content\n      pointer-events: none\n\n  .v-progress-linear__determinate,\n  .v-progress-linear__indeterminate\n    background: $progress-linear-background\n\n    @include tools.layer('trumps')\n      @media (forced-colors: active)\n        background-color: highlight\n\n  .v-progress-linear__determinate\n    height: inherit\n    left: 0\n    position: absolute\n    transition: inherit\n    transition-property: width, left, right\n\n  .v-progress-linear__indeterminate\n    .long, .short\n      animation-play-state: paused\n      animation-duration: $progress-linear-indeterminate-animation-duration\n      animation-iteration-count: infinite\n      bottom: 0\n      height: inherit\n      left: 0\n      position: absolute\n      right: auto\n      top: 0\n      width: auto\n\n    .long\n      animation-name: indeterminate-ltr\n\n    .short\n      animation-name: indeterminate-short-ltr\n\n  .v-progress-linear__stream\n    animation: $progress-linear-stream-animation\n    animation-play-state: paused\n    bottom: 0\n    left: auto\n    opacity: $progress-linear-stream-opacity\n    pointer-events: none\n    position: absolute\n    transition: inherit\n    transition-property: width, left, right\n\n  // Modifiers\n  .v-progress-linear--reverse\n    .v-progress-linear__background,\n    .v-progress-linear__determinate,\n    .v-progress-linear__content\n      left: auto\n      right: 0\n\n    .v-progress-linear__indeterminate\n      .long, .short\n        left: auto\n        right: 0\n\n      .long\n        animation-name: indeterminate-rtl\n\n      .short\n        animation-name: indeterminate-short-rtl\n\n    .v-progress-linear__stream\n      right: auto\n\n  .v-progress-linear--absolute,\n  .v-progress-linear--fixed\n    left: 0\n    z-index: 1\n\n  .v-progress-linear--absolute\n    position: absolute\n\n  .v-progress-linear--fixed\n    position: fixed\n\n  .v-progress-linear--rounded\n    @include tools.rounded($progress-linear-border-radius)\n\n    &.v-progress-linear--rounded-bar\n      .v-progress-linear__determinate,\n      .v-progress-linear__indeterminate\n        border-radius: inherit\n\n  .v-progress-linear--striped\n    .v-progress-linear__determinate\n      animation: $progress-linear-striped-animation\n      background-image: $progress-linear-stripe-gradient\n      background-repeat: repeat\n      background-size: $progress-linear-striped-size\n\n  .v-progress-linear--active\n    .v-progress-linear__indeterminate\n      .long, .short\n        animation-play-state: running\n\n    .v-progress-linear__stream\n      animation-play-state: running\n\n  .v-progress-linear--rounded-bar\n    .v-progress-linear__determinate,\n    .v-progress-linear__indeterminate,\n    .v-progress-linear__stream + .v-progress-linear__background\n      @include tools.rounded($progress-linear-border-radius)\n\n    .v-progress-linear__determinate\n      border-start-start-radius: 0\n      border-end-start-radius: 0\n\n  // Keyframes\n  @keyframes indeterminate-ltr\n    0%\n      left: -90%\n      right: 100%\n    60%\n      left: -90%\n      right: 100%\n    100%\n      left: 100%\n      right: -35%\n\n  @keyframes indeterminate-rtl\n    0%\n      left: 100%\n      right: -90%\n    60%\n      left: 100%\n      right: -90%\n    100%\n      left: -35%\n      right: 100%\n\n  @keyframes indeterminate-short-ltr\n    0%\n      left: -200%\n      right: 100%\n    60%\n      left: 107%\n      right: -8%\n    100%\n      left: 107%\n      right: -8%\n\n  @keyframes indeterminate-short-rtl\n    0%\n      left: 100%\n      right: -200%\n    60%\n      left: -8%\n      right: 107%\n    100%\n      left: -8%\n      right: 107%\n\n  @keyframes stream\n    to\n      transform: translateX(var(--v-progress-linear-stream-to))\n\n  @keyframes progress-linear-stripes\n    0%\n      background-position-x: $progress-linear-striped-size\n"
  },
  {
    "path": "packages/vuetify/src/components/VProgressLinear/VProgressLinear.tsx",
    "content": "// Styles\nimport './VProgressLinear.sass'\n\n// Composables\nimport { useBackgroundColor, useTextColor } from '@/composables/color'\nimport { makeComponentProps } from '@/composables/component'\nimport { useIntersectionObserver } from '@/composables/intersectionObserver'\nimport { useRtl } from '@/composables/locale'\nimport { makeLocationProps, useLocation } from '@/composables/location'\nimport { useProxiedModel } from '@/composables/proxiedModel'\nimport { useResizeObserver } from '@/composables/resizeObserver'\nimport { makeRoundedProps, useRounded } from '@/composables/rounded'\nimport { makeTagProps } from '@/composables/tag'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\nimport { useToggleScope } from '@/composables/toggleScope'\n\n// Utilities\nimport { computed, ref, shallowRef, Transition, watchEffect } from 'vue'\nimport { makeChunksProps, useChunks } from './chunks'\nimport { clamp, convertToUnit, genericComponent, propsFactory, useRender } from '@/util'\n\ntype VProgressLinearSlots = {\n  default: { value: number, buffer: number }\n}\n\nexport const makeVProgressLinearProps = propsFactory({\n  absolute: Boolean,\n  active: {\n    type: Boolean,\n    default: true,\n  },\n  bgColor: String,\n  bgOpacity: [Number, String],\n  bufferValue: {\n    type: [Number, String],\n    default: 0,\n  },\n  bufferColor: String,\n  bufferOpacity: [Number, String],\n  clickable: Boolean,\n  color: String,\n  height: {\n    type: [Number, String],\n    default: 4,\n  },\n  indeterminate: Boolean,\n  max: {\n    type: [Number, String],\n    default: 100,\n  },\n  modelValue: {\n    type: [Number, String],\n    default: 0,\n  },\n  opacity: [Number, String],\n  reverse: Boolean,\n  stream: Boolean,\n  striped: Boolean,\n  roundedBar: Boolean,\n\n  ...makeChunksProps(),\n  ...makeComponentProps(),\n  ...makeLocationProps({ location: 'top' } as const),\n  ...makeRoundedProps(),\n  ...makeTagProps(),\n  ...makeThemeProps(),\n}, 'VProgressLinear')\n\nexport const VProgressLinear = genericComponent<VProgressLinearSlots>()({\n  name: 'VProgressLinear',\n\n  props: makeVProgressLinearProps(),\n\n  emits: {\n    'update:modelValue': (value: number) => true,\n  },\n\n  setup (props, { slots }) {\n    const root = ref<HTMLElement>()\n\n    const progress = useProxiedModel(props, 'modelValue')\n    const { isRtl, rtlClasses } = useRtl()\n    const { themeClasses } = provideTheme(props)\n    const { locationStyles } = useLocation(props)\n    const { textColorClasses, textColorStyles } = useTextColor(() => props.color)\n    const {\n      backgroundColorClasses,\n      backgroundColorStyles,\n    } = useBackgroundColor(() => props.bgColor || props.color)\n    const {\n      backgroundColorClasses: bufferColorClasses,\n      backgroundColorStyles: bufferColorStyles,\n    } = useBackgroundColor(() => props.bufferColor || props.bgColor || props.color)\n    const {\n      backgroundColorClasses: barColorClasses,\n      backgroundColorStyles: barColorStyles,\n    } = useBackgroundColor(() => props.color)\n    const { roundedClasses } = useRounded(props)\n    const { intersectionRef, isIntersecting } = useIntersectionObserver()\n\n    const max = computed(() => parseFloat(props.max))\n    const height = computed(() => parseFloat(props.height))\n    const normalizedBuffer = computed(() => clamp(parseFloat(props.bufferValue) / max.value * 100, 0, 100))\n    const normalizedValue = computed(() => clamp(parseFloat(progress.value) / max.value * 100, 0, 100))\n    const isReversed = computed(() => isRtl.value !== props.reverse)\n    const transition = computed(() => props.indeterminate ? 'fade-transition' : 'slide-x-transition')\n\n    const containerWidth = shallowRef(0)\n    const { hasChunks, chunksMaskStyles, snapValueToChunk } = useChunks(props, containerWidth)\n    useToggleScope(hasChunks, () => {\n      const { resizeRef } = useResizeObserver(entries => containerWidth.value = entries[0].contentRect.width)\n      watchEffect(() => resizeRef.value = root.value)\n    })\n\n    const bufferWidth = computed(() => {\n      return hasChunks.value\n        ? snapValueToChunk(normalizedBuffer.value)\n        : normalizedBuffer.value\n    })\n\n    const barWidth = computed(() => {\n      return hasChunks.value\n        ? snapValueToChunk(normalizedValue.value)\n        : normalizedValue.value\n    })\n\n    function handleClick (e: MouseEvent) {\n      if (!intersectionRef.value) return\n\n      const { left, right, width } = intersectionRef.value.getBoundingClientRect()\n      const value = isReversed.value ? (width - e.clientX) + (right - width) : e.clientX - left\n\n      progress.value = Math.round(value / width * max.value)\n    }\n\n    watchEffect(() => {\n      intersectionRef.value = root.value\n    })\n\n    useRender(() => (\n      <props.tag\n        ref={ root }\n        class={[\n          'v-progress-linear',\n          {\n            'v-progress-linear--absolute': props.absolute,\n            'v-progress-linear--active': props.active && isIntersecting.value,\n            'v-progress-linear--reverse': isReversed.value,\n            'v-progress-linear--rounded': props.rounded,\n            'v-progress-linear--rounded-bar': props.roundedBar,\n            'v-progress-linear--striped': props.striped,\n            'v-progress-linear--clickable': props.clickable,\n          },\n          roundedClasses.value,\n          themeClasses.value,\n          rtlClasses.value,\n          props.class,\n        ]}\n        style={[\n          {\n            bottom: props.location === 'bottom' ? 0 : undefined,\n            top: props.location === 'top' ? 0 : undefined,\n            height: props.active ? convertToUnit(height.value) : 0,\n            '--v-progress-linear-height': convertToUnit(height.value),\n            ...(props.absolute ? locationStyles.value : {}),\n          },\n          chunksMaskStyles.value,\n          props.style,\n        ]}\n        role=\"progressbar\"\n        aria-hidden={ props.active ? 'false' : 'true' }\n        aria-valuemin=\"0\"\n        aria-valuemax={ props.max }\n        aria-valuenow={ props.indeterminate ? undefined : Math.min(parseFloat(progress.value), max.value) }\n        onClick={ props.clickable && handleClick }\n      >\n        { props.stream && (\n          <div\n            key=\"stream\"\n            class={[\n              'v-progress-linear__stream',\n              textColorClasses.value,\n            ]}\n            style={{\n              ...textColorStyles.value,\n              [isReversed.value ? 'left' : 'right']: convertToUnit(-height.value),\n              borderTop: `${convertToUnit(height.value / 2)} dotted`,\n              opacity: parseFloat(props.bufferOpacity!),\n              top: `calc(50% - ${convertToUnit(height.value / 4)})`,\n              width: convertToUnit(100 - normalizedBuffer.value, '%'),\n              '--v-progress-linear-stream-to': convertToUnit(height.value * (isReversed.value ? 1 : -1)),\n            }}\n          />\n        )}\n\n        <div\n          class={[\n            'v-progress-linear__background',\n            backgroundColorClasses.value,\n          ]}\n          style={[\n            backgroundColorStyles.value,\n            {\n              opacity: parseFloat(props.bgOpacity!),\n              width: props.stream ? 0 : undefined,\n            },\n          ]}\n        />\n\n        <div\n          class={[\n            'v-progress-linear__buffer',\n            bufferColorClasses.value,\n          ]}\n          style={[\n            bufferColorStyles.value,\n            {\n              opacity: parseFloat(props.bufferOpacity!),\n              width: convertToUnit(bufferWidth.value, '%'),\n            },\n          ]}\n        />\n\n        <Transition name={ transition.value }>\n          { !props.indeterminate ? (\n            <div\n              class={[\n                'v-progress-linear__determinate',\n                barColorClasses.value,\n              ]}\n              style={[\n                barColorStyles.value,\n                { width: convertToUnit(barWidth.value, '%') },\n              ]}\n            />\n          ) : (\n            <div class=\"v-progress-linear__indeterminate\">\n              {['long', 'short'].map(bar => (\n                <div\n                  key={ bar }\n                  class={[\n                    'v-progress-linear__indeterminate',\n                    bar,\n                    barColorClasses.value,\n                  ]}\n                  style={ barColorStyles.value }\n                />\n              ))}\n            </div>\n          )}\n        </Transition>\n\n        { slots.default && (\n          <div class=\"v-progress-linear__content\">\n            { slots.default({ value: normalizedValue.value, buffer: normalizedBuffer.value }) }\n          </div>\n        )}\n      </props.tag>\n    ))\n\n    return {}\n  },\n})\n\nexport type VProgressLinear = InstanceType<typeof VProgressLinear>\n"
  },
  {
    "path": "packages/vuetify/src/components/VProgressLinear/__tests__/VProgressLinear.spec.browser.tsx",
    "content": "// Components\nimport { VProgressLinear } from '../VProgressLinear'\nimport { VLocaleProvider } from '@/components/VLocaleProvider'\n\n// Utilities\nimport { render, screen, showcase, userEvent, wait } from '@test'\nimport { ref } from 'vue'\n\nconst stories = {\n  'With value': <VProgressLinear modelValue=\"25\" />,\n  'With height': <VProgressLinear modelValue=\"25\" height=\"50\" />,\n  'With reverse': <VProgressLinear modelValue=\"25\" reverse />,\n  'With rtl': (\n    <VLocaleProvider rtl>\n      <VProgressLinear modelValue=\"25\" />\n    </VLocaleProvider>\n  ),\n  'With rtl and reverse': (\n    <VLocaleProvider rtl>\n      <VProgressLinear modelValue=\"25\" reverse />\n    </VLocaleProvider>\n  ),\n  'With colors': <VProgressLinear modelValue=\"25\" color=\"secondary\" bgColor=\"error\" />,\n  Hidden: <VProgressLinear modelValue=\"25\" active={ false } />,\n  'With slot': (\n    <VProgressLinear modelValue=\"25\" height=\"20\">\n      {{\n        default: props => <div>{ props.value }%</div>,\n      }}\n    </VProgressLinear>\n  ),\n}\n\ndescribe('VProgressLinear', () => {\n  it('supports clickable prop', async () => {\n    const model = ref(0)\n    render(() => (\n      <VProgressLinear\n        v-model={ model.value }\n        style=\"width: 100px\"\n        clickable\n      />\n    ))\n\n    await userEvent.click(screen.getByCSS('.v-progress-linear'))\n    expect(model.value).toBe(50)\n    await wait(300)\n    expect(screen.getByCSS('.v-progress-linear__determinate').clientWidth).toBe(50)\n  })\n\n  showcase({ stories })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VProgressLinear/_variables.scss",
    "content": "@use 'sass:map';\n@use '../../styles/settings';\n\n// VProgressLinear\n$progress-linear-background: currentColor !default;\n$progress-linear-background-background: $progress-linear-background !default;\n$progress-linear-background-opacity: var(--v-border-opacity) !default;\n$progress-linear-border-radius: map.get(settings.$rounded, 'pill') !default;\n$progress-linear-stream-opacity: 0.3 !default;\n$progress-linear-stripe-background-size: 40px 40px !default;\n$progress-linear-stream-border-width: 4px !default;\n$progress-linear-stripe-gradient: linear-gradient(\n  135deg,\n  hsla(0, 0%, 100%, .25) 25%,\n  transparent 0,\n  transparent 50%,\n  hsla(0, 0%, 100%, .25) 0,\n  hsla(0, 0%, 100%, .25) 75%,\n  transparent 0,\n  transparent\n) !default;\n$progress-linear-indeterminate-animation-duration: 2.2s !default;\n$progress-linear-stream-animation: stream .25s infinite linear !default;\n$progress-linear-striped-animation: progress-linear-stripes 1s infinite linear !default;\n$progress-linear-striped-size: var(--v-progress-linear-height) !default;\n$progress-linear-transition: .2s settings.$standard-easing !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VProgressLinear/chunks.ts",
    "content": "// Utilities\nimport { computed, toRef, toValue } from 'vue'\nimport { clamp, convertToUnit, propsFactory } from '@/util'\n\n// Types\nimport type { MaybeRefOrGetter } from 'vue'\n\nexport interface ChunksProps {\n  chunkCount: number | string\n  chunkWidth: number | string\n  chunkGap: number | string\n}\n\n// Composables\nexport const makeChunksProps = propsFactory({\n  chunkCount: {\n    type: [Number, String],\n    default: null,\n  },\n  chunkWidth: {\n    type: [Number, String],\n    default: null,\n  },\n  chunkGap: {\n    type: [Number, String],\n    default: 4,\n  },\n}, 'chunks')\n\nexport function useChunks (\n  props: ChunksProps,\n  containerWidth: MaybeRefOrGetter<number | undefined>,\n) {\n  const hasChunks = toRef(() => !!props.chunkCount || !!props.chunkWidth)\n\n  const chunkWidth = computed(() => {\n    const containerSize = toValue(containerWidth)\n    if (!containerSize) {\n      return 0\n    }\n\n    if (!props.chunkCount) {\n      return Number(props.chunkWidth)\n    }\n\n    const count = Number(props.chunkCount)\n    const availableWidth = containerSize - Number(props.chunkGap) * (count - 1)\n    return availableWidth / count\n  })\n\n  const chunkGap = toRef(() => Number(props.chunkGap))\n  const chunksMaskStyles = computed(() => {\n    if (!hasChunks.value) {\n      return {}\n    }\n\n    const chunkGapPx = convertToUnit(chunkGap.value)\n    const chunkWidthPx = convertToUnit(chunkWidth.value)\n\n    return {\n      maskRepeat: 'repeat-x',\n      maskImage: `linear-gradient(90deg, #000, #000 ${chunkWidthPx}, transparent ${chunkWidthPx}, transparent)`,\n      maskSize: `calc(${chunkWidthPx} + ${chunkGapPx}) 100%`,\n    }\n  })\n\n  function snapValueToChunk (val: number) {\n    const containerSize = toValue(containerWidth)\n    if (!containerSize) {\n      return val\n    }\n\n    const gapRelativeSize = 100 * chunkGap.value / containerSize\n    const chunkRelativeSize = 100 * (chunkWidth.value + chunkGap.value) / containerSize\n    const filledChunks = Math.floor((val + gapRelativeSize) / chunkRelativeSize)\n    return clamp(0, filledChunks * chunkRelativeSize - gapRelativeSize / 2, 100)\n  }\n\n  return {\n    hasChunks,\n    chunksMaskStyles,\n    snapValueToChunk,\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VProgressLinear/index.ts",
    "content": "export { VProgressLinear } from './VProgressLinear'\n"
  },
  {
    "path": "packages/vuetify/src/components/VRadio/VRadio.tsx",
    "content": "// Components\nimport { makeVSelectionControlProps, VSelectionControl } from '@/components/VSelectionControl/VSelectionControl'\n\n// Utilities\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { VSelectionControlSlots } from '@/components/VSelectionControl/VSelectionControl'\n\nexport const makeVRadioProps = propsFactory({\n  ...makeVSelectionControlProps({\n    falseIcon: '$radioOff',\n    trueIcon: '$radioOn',\n  }),\n}, 'VRadio')\n\nexport const VRadio = genericComponent<VSelectionControlSlots>()({\n  name: 'VRadio',\n\n  props: makeVRadioProps(),\n\n  setup (props, { slots }) {\n    useRender(() => {\n      const controlProps = VSelectionControl.filterProps(props)\n\n      return (\n        <VSelectionControl\n          { ...controlProps }\n          class={[\n            'v-radio',\n            props.class,\n          ]}\n          style={ props.style }\n          type=\"radio\"\n          v-slots={ slots }\n        />\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VRadio = InstanceType<typeof VRadio>\n"
  },
  {
    "path": "packages/vuetify/src/components/VRadio/index.ts",
    "content": "export { VRadio } from './VRadio'\n"
  },
  {
    "path": "packages/vuetify/src/components/VRadioGroup/VRadioGroup.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-radio-group\n    > .v-input__control\n      flex-direction: column\n\n      > .v-label\n        margin-inline-start: $radio-group-label-margin-inline-start\n\n        + .v-selection-control-group\n          padding-inline-start: $radio-group-label-selection-group-padding-inline\n          margin-top: $radio-group-label-selection-group-margin-top\n"
  },
  {
    "path": "packages/vuetify/src/components/VRadioGroup/VRadioGroup.tsx",
    "content": "// Styles\nimport './VRadioGroup.sass'\n\n// Components\nimport { makeVInputProps, VInput } from '@/components/VInput/VInput'\nimport { VLabel } from '@/components/VLabel'\nimport { VSelectionControl } from '@/components/VSelectionControl'\nimport { makeSelectionControlGroupProps, VSelectionControlGroup } from '@/components/VSelectionControlGroup/VSelectionControlGroup'\n\n// Composables\nimport { forwardRefs } from '@/composables/forwardRefs'\nimport { IconValue } from '@/composables/icons'\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { computed, ref, useId } from 'vue'\nimport { filterInputAttrs, genericComponent, omit, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { VInputSlots } from '@/components/VInput/VInput'\nimport type { GenericProps } from '@/util'\n\nexport type VRadioGroupSlots = Omit<VInputSlots, 'default'> & {\n  default: never\n  label: {\n    label: string | undefined\n    props: Record<string, any>\n  }\n}\n\nexport const makeVRadioGroupProps = propsFactory({\n  height: {\n    type: [Number, String],\n    default: 'auto',\n  },\n\n  ...omit(makeVInputProps(), ['direction']),\n  ...omit(makeSelectionControlGroupProps(), ['multiple']),\n\n  trueIcon: {\n    type: IconValue,\n    default: '$radioOn',\n  },\n  falseIcon: {\n    type: IconValue,\n    default: '$radioOff',\n  },\n  type: {\n    type: String,\n    default: 'radio',\n  },\n}, 'VRadioGroup')\n\nexport const VRadioGroup = genericComponent<new <T>(\n  props: {\n    modelValue?: T | null\n    'onUpdate:modelValue'?: (value: T | null) => void\n  },\n  slots: VRadioGroupSlots,\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VRadioGroup',\n\n  inheritAttrs: false,\n\n  props: makeVRadioGroupProps(),\n\n  emits: {\n    'update:modelValue': (value: any) => true,\n  },\n\n  setup (props, { attrs, slots }) {\n    const uid = useId()\n    const id = computed(() => props.id || `radio-group-${uid}`)\n    const model = useProxiedModel(props, 'modelValue')\n    const inputRef = ref<VInput>()\n\n    useRender(() => {\n      const [rootAttrs, controlAttrs] = filterInputAttrs(attrs)\n      const inputProps = VInput.filterProps(props)\n      const controlProps = VSelectionControl.filterProps(props)\n      const label = slots.label\n        ? slots.label({\n          label: props.label,\n          props: { for: id.value },\n        })\n        : props.label\n\n      return (\n        <VInput\n          ref={ inputRef }\n          class={[\n            'v-radio-group',\n            props.class,\n          ]}\n          style={ props.style }\n          { ...rootAttrs }\n          { ...inputProps }\n          v-model={ model.value }\n          id={ id.value }\n        >\n          {{\n            ...slots,\n            default: ({\n              id,\n              messagesId,\n              isDisabled,\n              isReadonly,\n            }) => (\n              <>\n                { label && (\n                  <VLabel id={ id.value }>\n                    { label }\n                  </VLabel>\n                )}\n\n                <VSelectionControlGroup\n                  { ...controlProps }\n                  id={ id.value }\n                  aria-describedby={ messagesId.value }\n                  defaultsTarget=\"VRadio\"\n                  trueIcon={ props.trueIcon }\n                  falseIcon={ props.falseIcon }\n                  type={ props.type }\n                  disabled={ isDisabled.value }\n                  readonly={ isReadonly.value }\n                  aria-labelledby={ label ? id.value : undefined }\n                  multiple={ false }\n                  { ...controlAttrs }\n                  v-model={ model.value }\n                  v-slots={ slots }\n                />\n              </>\n            ),\n          }}\n        </VInput>\n      )\n    })\n\n    return forwardRefs({}, inputRef)\n  },\n})\n\nexport type VRadioGroup = InstanceType<typeof VRadioGroup>\n"
  },
  {
    "path": "packages/vuetify/src/components/VRadioGroup/_variables.scss",
    "content": "$radio-group-label-margin-inline-start: 16px !default;\n$radio-group-label-selection-group-margin-top: 8px !default;\n$radio-group-label-selection-group-padding-inline: 6px !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VRadioGroup/index.ts",
    "content": "export { VRadioGroup } from './VRadioGroup'\n"
  },
  {
    "path": "packages/vuetify/src/components/VRangeSlider/VRangeSlider.tsx",
    "content": "// Styles\nimport '../VSlider/VSlider.sass'\n\n// Components\nimport { makeVInputProps, VInput } from '@/components/VInput/VInput'\nimport { VLabel } from '@/components/VLabel'\nimport { getOffset, makeSliderProps, useSlider, useSteps } from '@/components/VSlider/slider'\nimport { VSliderThumb } from '@/components/VSlider/VSliderThumb'\nimport { VSliderTrack } from '@/components/VSlider/VSliderTrack'\n\n// Composables\nimport { makeFocusProps, useFocus } from '@/composables/focus'\nimport { forwardRefs } from '@/composables/forwardRefs'\nimport { useRtl } from '@/composables/locale'\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { computed, ref } from 'vue'\nimport { filterInputAttrs, genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType, WritableComputedRef } from 'vue'\nimport type { VSliderSlots } from '../VSlider/VSlider'\n\nexport const makeVRangeSliderProps = propsFactory({\n  ...makeFocusProps(),\n  ...makeVInputProps(),\n  ...makeSliderProps(),\n\n  strict: Boolean,\n  modelValue: {\n    type: Array as PropType<readonly (string | number)[]>,\n    default: () => ([0, 0]),\n  },\n}, 'VRangeSlider')\n\nexport const VRangeSlider = genericComponent<VSliderSlots>()({\n  name: 'VRangeSlider',\n\n  inheritAttrs: false,\n\n  props: makeVRangeSliderProps(),\n\n  emits: {\n    'update:focused': (value: boolean) => true,\n    'update:modelValue': (value: [number, number]) => true,\n    end: (value: [number, number]) => true,\n    start: (value: [number, number]) => true,\n  },\n\n  setup (props, { slots, emit, attrs }) {\n    const startThumbRef = ref<VSliderThumb>()\n    const stopThumbRef = ref<VSliderThumb>()\n    const inputRef = ref<VInput>()\n    const { rtlClasses } = useRtl()\n\n    function getActiveThumb (e: MouseEvent | TouchEvent) {\n      if (!startThumbRef.value || !stopThumbRef.value) return\n\n      const startOffset = getOffset(e, startThumbRef.value.$el, props.direction)\n      const stopOffset = getOffset(e, stopThumbRef.value.$el, props.direction)\n\n      const a = Math.abs(startOffset)\n      const b = Math.abs(stopOffset)\n\n      return (a < b || (a === b && startOffset < 0)) ? startThumbRef.value.$el : stopThumbRef.value.$el\n    }\n\n    const steps = useSteps(props)\n\n    const model = useProxiedModel(\n      props,\n      'modelValue',\n      undefined,\n      arr => {\n        if (!arr?.length) return [0, 0]\n\n        return arr.map(value => steps.roundValue(value))\n      },\n    ) as WritableComputedRef<[number, number]> & { readonly externalValue: number[] }\n\n    const {\n      activeThumbRef,\n      hasLabels,\n      max,\n      min,\n      mousePressed,\n      onSliderMousedown,\n      onSliderTouchstart,\n      position,\n      trackContainerRef,\n      disabled,\n      readonly,\n    } = useSlider({\n      props,\n      steps,\n      onSliderStart: () => {\n        if (disabled.value || readonly.value) {\n          activeThumbRef.value?.blur()\n          return\n        }\n        emit('start', model.value)\n      },\n      onSliderEnd: ({ value }) => {\n        if (disabled.value || readonly.value) {\n          activeThumbRef.value?.blur()\n        } else {\n          const newValue: [number, number] =\n            activeThumbRef.value === startThumbRef.value?.$el\n              ? [value, model.value[1]]\n              : [model.value[0], value]\n\n          if (!props.strict && newValue[0] < newValue[1]) {\n            model.value = newValue\n          }\n        }\n\n        emit('end', model.value)\n      },\n      onSliderMove: ({ value }) => {\n        const [start, stop] = model.value\n\n        if (disabled.value || readonly.value) {\n          activeThumbRef.value?.blur()\n          return\n        }\n\n        if (!props.strict && start === stop && start !== min.value) {\n          activeThumbRef.value =\n            value > start ? stopThumbRef.value?.$el : startThumbRef.value?.$el\n          activeThumbRef.value?.focus()\n        }\n\n        if (activeThumbRef.value === startThumbRef.value?.$el) {\n          model.value = [Math.min(value, stop), stop]\n        } else {\n          model.value = [start, Math.max(start, value)]\n        }\n      },\n      getActiveThumb,\n    })\n\n    const { isFocused, focus, blur } = useFocus(props)\n    const trackStart = computed(() => position(model.value[0]))\n    const trackStop = computed(() => position(model.value[1]))\n\n    useRender(() => {\n      const inputProps = VInput.filterProps(props)\n      const [rootAttrs, inputAttrs] = filterInputAttrs(attrs)\n      const hasPrepend = !!(props.label || slots.label || slots.prepend)\n\n      return (\n        <VInput\n          class={[\n            'v-slider',\n            'v-range-slider',\n            {\n              'v-slider--has-labels': !!slots['tick-label'] || hasLabels.value,\n              'v-slider--focused': isFocused.value,\n              'v-slider--pressed': mousePressed.value,\n              'v-slider--disabled': disabled.value,\n            },\n            rtlClasses.value,\n            props.class,\n          ]}\n          style={ props.style }\n          ref={ inputRef }\n          { ...inputProps }\n          { ...rootAttrs }\n          focused={ isFocused.value }\n        >\n          {{\n            ...slots,\n            prepend: hasPrepend ? slotProps => (\n              <>\n                { slots.label?.(slotProps) ?? (\n                  props.label\n                    ? (\n                      <VLabel\n                        class=\"v-slider__label\"\n                        text={ props.label }\n                      />\n                    ) : undefined\n                )}\n\n                { slots.prepend?.(slotProps) }\n              </>\n            ) : undefined,\n            default: ({ id, messagesId }) => (\n              <div\n                class=\"v-slider__container\"\n                onMousedown={ !readonly.value ? onSliderMousedown : undefined }\n                onTouchstartPassive={ !readonly.value ? onSliderTouchstart : undefined }\n              >\n                <input\n                  id={ `${id.value}_start` }\n                  name={ props.name || id.value }\n                  disabled={ disabled.value }\n                  readonly={ readonly.value }\n                  tabindex=\"-1\"\n                  value={ model.value[0] }\n                />\n\n                <input\n                  id={ `${id.value}_stop` }\n                  name={ props.name || id.value }\n                  disabled={ disabled.value }\n                  readonly={ readonly.value }\n                  tabindex=\"-1\"\n                  value={ model.value[1] }\n                />\n\n                <VSliderTrack\n                  ref={ trackContainerRef }\n                  start={ trackStart.value }\n                  stop={ trackStop.value }\n                >\n                  {{ 'tick-label': slots['tick-label'] }}\n                </VSliderTrack>\n\n                <VSliderThumb\n                  ref={ startThumbRef }\n                  aria-describedby={ messagesId.value }\n                  focused={ isFocused && activeThumbRef.value === startThumbRef.value?.$el }\n                  modelValue={ model.value[0] }\n                  onUpdate:modelValue={ v => (model.value = [v, model.value[1]]) }\n                  onFocus={ (e: FocusEvent) => {\n                    focus()\n                    activeThumbRef.value = startThumbRef.value?.$el\n\n                    // Make sure second thumb is focused if\n                    // the thumbs are on top of each other\n                    // and they are both at minimum value\n                    // but only if focused from outside.\n                    if (\n                      max.value !== min.value &&\n                      model.value[0] === model.value[1] &&\n                      model.value[1] === min.value &&\n                      e.relatedTarget !== stopThumbRef.value?.$el\n                    ) {\n                      startThumbRef.value?.$el.blur()\n                      stopThumbRef.value?.$el.focus()\n                    }\n                  }}\n                  onBlur={ () => {\n                    blur()\n                    activeThumbRef.value = undefined\n                  }}\n                  min={ min.value }\n                  max={ model.value[1] }\n                  position={ trackStart.value }\n                  ripple={ props.ripple }\n                  { ...inputAttrs }\n                >\n                  {{ 'thumb-label': slots['thumb-label'] }}\n                </VSliderThumb>\n\n                <VSliderThumb\n                  ref={ stopThumbRef }\n                  aria-describedby={ messagesId.value }\n                  focused={ isFocused && activeThumbRef.value === stopThumbRef.value?.$el }\n                  modelValue={ model.value[1] }\n                  onUpdate:modelValue={ v => (model.value = [model.value[0], v]) }\n                  onFocus={ (e: FocusEvent) => {\n                    focus()\n                    activeThumbRef.value = stopThumbRef.value?.$el\n\n                    // Make sure first thumb is focused if\n                    // the thumbs are on top of each other\n                    // and they are both at maximum value\n                    // but only if focused from outside.\n                    if (\n                      max.value !== min.value &&\n                      model.value[0] === model.value[1] &&\n                      model.value[0] === max.value &&\n                      e.relatedTarget !== startThumbRef.value?.$el\n                    ) {\n                      stopThumbRef.value?.$el.blur()\n                      startThumbRef.value?.$el.focus()\n                    }\n                  }}\n                  onBlur={ () => {\n                    blur()\n                    activeThumbRef.value = undefined\n                  }}\n                  min={ model.value[0] }\n                  max={ max.value }\n                  position={ trackStop.value }\n                  ripple={ props.ripple }\n                  { ...inputAttrs }\n                >\n                  {{ 'thumb-label': slots['thumb-label'] }}\n                </VSliderThumb>\n              </div>\n            ),\n          }}\n        </VInput>\n      )\n    })\n\n    return forwardRefs({\n      focus: () => startThumbRef.value?.$el.focus(),\n    }, inputRef)\n  },\n})\n\nexport type VRangeSlider = InstanceType<typeof VRangeSlider>\n"
  },
  {
    "path": "packages/vuetify/src/components/VRangeSlider/index.ts",
    "content": "export { VRangeSlider } from './VRangeSlider'\n"
  },
  {
    "path": "packages/vuetify/src/components/VRating/VRating.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  // Block\n  .v-rating\n    max-width: 100%\n    display: inline-flex\n    white-space: $rating-white-space\n\n    &--readonly\n      pointer-events: none\n\n  // Element\n  .v-rating__wrapper\n    align-items: $rating-item-align-items\n    display: inline-flex\n    flex-direction: column\n\n    &--bottom\n      flex-direction: column-reverse\n\n  .v-rating__item\n    display: inline-flex\n    position: relative\n\n    label\n      cursor: pointer\n\n    .v-btn--variant-plain\n      opacity: $rating-item-button-opacity\n\n    .v-btn\n      transition-property: $rating-item-button-transition-property\n\n      .v-icon\n        transition: inherit\n        transition-timing-function: $rating-item-transition-timing-function\n\n    &:hover:not(.v-rating__item--focused)\n      .v-rating--hover &\n        .v-btn\n          transform: $rating-item-icon-transform\n\n    &--half\n      overflow: hidden\n      position: absolute\n      clip-path: polygon(0 0, 50% 0, 50% 100%, 0 100%)\n      z-index: 1\n\n      .v-btn__overlay,\n      &:hover .v-btn__overlay\n        opacity: 0\n\n  .v-rating__hidden\n    height: 0\n    opacity: 0\n    position: absolute\n    width: 0\n"
  },
  {
    "path": "packages/vuetify/src/components/VRating/VRating.tsx",
    "content": "// Styles\nimport './VRating.sass'\n\n// Components\nimport { VBtn } from '@/components/VBtn'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { makeDensityProps } from '@/composables/density'\nimport { IconValue } from '@/composables/icons'\nimport { useLocale } from '@/composables/locale'\nimport { useProxiedModel } from '@/composables/proxiedModel'\nimport { makeSizeProps } from '@/composables/size'\nimport { makeTagProps } from '@/composables/tag'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\n\n// Utilities\nimport { computed, nextTick, ref, shallowRef, useId } from 'vue'\nimport { clamp, createRange, genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { Prop } from 'vue'\nimport type { Variant } from '@/composables/variant'\n\ntype VRatingItemSlot = {\n  value: number\n  index: number\n  isFilled: boolean\n  isHovered: boolean\n  icon: IconValue\n  color?: string\n  props: Record<string, unknown>\n  rating: number\n}\n\ntype VRatingItemLabelSlot = {\n  value: number\n  index: number\n  label?: string\n}\n\ntype VRatingSlots = {\n  item: VRatingItemSlot\n  'item-label': VRatingItemLabelSlot\n}\n\nexport const makeVRatingProps = propsFactory({\n  name: String,\n  itemAriaLabel: {\n    type: String,\n    default: '$vuetify.rating.ariaLabel.item',\n  },\n  activeColor: String,\n  color: String,\n  clearable: Boolean,\n  disabled: Boolean,\n  emptyIcon: {\n    type: IconValue,\n    default: '$ratingEmpty',\n  },\n  fullIcon: {\n    type: IconValue,\n    default: '$ratingFull',\n  },\n  halfIncrements: Boolean,\n  hover: Boolean,\n  length: {\n    type: [Number, String],\n    default: 5,\n  },\n  readonly: Boolean,\n  modelValue: {\n    type: [Number, String],\n    default: 0,\n  },\n  itemLabels: Array as Prop<string[]>,\n  itemLabelPosition: {\n    type: String,\n    default: 'top',\n    validator: (v: any) => ['top', 'bottom'].includes(v),\n  },\n  ripple: Boolean,\n\n  ...makeComponentProps(),\n  ...makeDensityProps(),\n  ...makeSizeProps(),\n  ...makeTagProps(),\n  ...makeThemeProps(),\n}, 'VRating')\n\nexport const VRating = genericComponent<VRatingSlots>()({\n  name: 'VRating',\n\n  props: makeVRatingProps(),\n\n  emits: {\n    'update:modelValue': (value: number | string) => true,\n  },\n\n  setup (props, { slots }) {\n    const { t } = useLocale()\n    const { themeClasses } = provideTheme(props)\n    const root = ref<HTMLElement>()\n    const rating = useProxiedModel(props, 'modelValue')\n    const normalizedValue = computed(() => clamp(parseFloat(rating.value), 0, Number(props.length)))\n\n    const range = computed(() => createRange(Number(props.length), 1))\n    const increments = computed(() => range.value.flatMap(v => props.halfIncrements ? [v - 0.5, v] : [v]))\n    const hoverIndex = shallowRef(-1)\n\n    const itemState = computed(() => increments.value.map(value => {\n      const isHovering = props.hover && hoverIndex.value > -1\n      const isFilled = normalizedValue.value >= value\n      const isHovered = hoverIndex.value >= value\n      const isFullIcon = isHovering ? isHovered : isFilled\n      const icon = isFullIcon ? props.fullIcon : props.emptyIcon\n      const activeColor = props.activeColor ?? props.color\n      const color = (isFilled || isHovered) ? activeColor : props.color\n\n      return { isFilled, isHovered, icon, color }\n    }))\n\n    const eventState = computed(() => [0, ...increments.value].map(value => {\n      function onMouseenter () {\n        hoverIndex.value = value\n      }\n\n      function onMouseleave () {\n        hoverIndex.value = -1\n      }\n\n      function onClick () {\n        if (props.disabled || props.readonly) return\n        rating.value = normalizedValue.value === value && props.clearable ? 0 : value\n      }\n\n      return {\n        onMouseenter: props.hover ? onMouseenter : undefined,\n        onMouseleave: props.hover ? onMouseleave : undefined,\n        onClick,\n      }\n    }))\n\n    const currentItemIndex = computed(() => {\n      return props.halfIncrements\n        ? 1 + Math.floor(Math.max(0, Number(rating.value ?? 0) - 0.5)) * 2\n        : Math.floor(Math.max(0, Number(rating.value ?? 0) - 1))\n    })\n\n    function moveCurrentFocus () {\n      const currentItem = root.value?.querySelector('[tabindex=\"0\"]') as HTMLElement\n      currentItem?.focus()\n    }\n\n    function onItemKeydown (event: KeyboardEvent) {\n      if (props.disabled || props.readonly) return\n      if (event.ctrlKey || event.altKey) return\n\n      const step = props.halfIncrements ? 0.5 : 1\n\n      if (event.key === 'ArrowRight') {\n        const newValue = Math.min(Number(props.length), Number(rating.value ?? 0) + step)\n        rating.value = newValue\n        nextTick(() => moveCurrentFocus())\n      }\n      if (event.key === 'ArrowLeft') {\n        const newValue = Math.max(0, Number(rating.value ?? 0) - step)\n        rating.value = newValue\n        nextTick(() => moveCurrentFocus())\n      }\n    }\n\n    const uid = useId()\n    const name = computed(() => props.name ?? `v-rating-${uid}`)\n\n    function VRatingItem ({ value, index, showStar = true }: { value: number, index: number, showStar?: boolean }) {\n      const { onMouseenter, onMouseleave, onClick } = eventState.value[index + 1]\n      const id = `${name.value}-${String(value).replace('.', '-')}`\n      const isFocusable = index === currentItemIndex.value\n      const btnProps = {\n        color: itemState.value[index]?.color,\n        density: props.density,\n        disabled: props.disabled,\n        icon: itemState.value[index]?.icon,\n        ripple: props.ripple,\n        size: props.size,\n        variant: 'plain' as Variant,\n        tabindex: isFocusable ? 0 : -1,\n        onKeydown: onItemKeydown,\n      }\n\n      return (\n        <>\n          <label\n            for={ id }\n            class={{\n              'v-rating__item--half': props.halfIncrements && value % 1 > 0,\n              'v-rating__item--full': props.halfIncrements && value % 1 === 0,\n            }}\n            onMouseenter={ onMouseenter }\n            onMouseleave={ onMouseleave }\n            onClick={ onClick }\n          >\n            <span class=\"v-rating__hidden\">{ t(props.itemAriaLabel, value, props.length) }</span>\n            {\n              !showStar ? undefined\n              : slots.item ? slots.item({\n                ...itemState.value[index],\n                props: btnProps,\n                value,\n                index,\n                rating: normalizedValue.value,\n              })\n              : (\n                <VBtn\n                  aria-label={ t(props.itemAriaLabel, value, props.length) }\n                  { ...btnProps }\n                />\n              )\n            }\n          </label>\n\n          <input\n            class=\"v-rating__hidden\"\n            name={ name.value }\n            id={ id }\n            type=\"radio\"\n            value={ value }\n            checked={ normalizedValue.value === value }\n            tabindex={ -1 }\n            readonly={ props.readonly }\n            disabled={ props.disabled }\n          />\n        </>\n      )\n    }\n\n    function createLabel (labelProps: { value: number, index: number, label?: string }) {\n      if (slots['item-label']) return slots['item-label'](labelProps)\n\n      if (labelProps.label) return <span>{ labelProps.label }</span>\n\n      return <span>&nbsp;</span>\n    }\n\n    useRender(() => {\n      const hasLabels = !!props.itemLabels?.length || slots['item-label']\n\n      return (\n        <props.tag\n          class={[\n            'v-rating',\n            {\n              'v-rating--hover': props.hover,\n              'v-rating--readonly': props.readonly,\n            },\n            themeClasses.value,\n            props.class,\n          ]}\n          style={ props.style }\n          ref={ root }\n        >\n          <VRatingItem value={ 0 } index={ -1 } showStar={ false } />\n\n          { range.value.map((value, i) => (\n            <div class=\"v-rating__wrapper\">\n              {\n                hasLabels && props.itemLabelPosition === 'top'\n                  ? createLabel({ value, index: i, label: props.itemLabels?.[i] })\n                  : undefined\n              }\n              <div class=\"v-rating__item\">\n                { props.halfIncrements ? (\n                  <>\n                    <VRatingItem value={ value - 0.5 } index={ i * 2 } />\n                    <VRatingItem value={ value } index={ (i * 2) + 1 } />\n                  </>\n                ) : (\n                  <VRatingItem value={ value } index={ i } />\n                )}\n              </div>\n              {\n                hasLabels && props.itemLabelPosition === 'bottom'\n                  ? createLabel({ value, index: i, label: props.itemLabels?.[i] })\n                  : undefined\n              }\n            </div>\n          ))}\n        </props.tag>\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VRating = InstanceType<typeof VRating>\n"
  },
  {
    "path": "packages/vuetify/src/components/VRating/__tests__/VRating.spec.browser.tsx",
    "content": "// Components\nimport { VRating } from '../VRating'\nimport { VBtn } from '@/components/VBtn'\n\n// Utilities\nimport { click, render, screen, showcase, userEvent } from '@test'\nimport { nextTick, ref } from 'vue'\n\nconst stories = {\n  'Item labels': <VRating itemLabels={['1', '', '', '', '5']} />,\n  'Item slot': (\n    <VRating modelValue={ 1 }>\n      {{\n        item: ({ value, rating }) => (\n          <VBtn\n            variant=\"tonal\"\n            class=\"mx-1\"\n            color={ rating === value ? 'primary' : undefined }\n            text={ value }\n          />\n        ),\n      }}\n    </VRating>\n  ),\n  'Item label slot': (\n    <VRating>\n      {{\n        'item-label': props => <>C{ props.value }</>,\n      }}\n    </VRating>\n  ),\n}\n\ndescribe('VRating', () => {\n  it('should response to user interaction', async () => {\n    const model = ref<number>()\n    render(() => <VRating v-model={ model.value } />)\n\n    const option = screen.getAllByCSS('.v-rating__item')[3]\n    await userEvent.click(option)\n    expect(model.value).toBe(4)\n  })\n\n  it('should respond to prop value changes', () => {\n    const model = ref<number>()\n    render(() => <VRating v-model={ model.value } />)\n\n    model.value = 4\n\n    const icons = screen.getAllByCSS('.v-rating__item .v-icon')\n\n    icons.forEach((el, i) => {\n      expect(el.outerHTML).to.equal(icons[i < 4 ? 0 : 4].outerHTML)\n    })\n  })\n\n  it('should clear value if using clearable prop', async () => {\n    const clearable = ref<boolean>()\n    const model = ref<number>()\n    render(() => (\n      <VRating\n        clearable={ clearable.value }\n        v-model={ model.value }\n      />\n    ))\n\n    const buttons = screen.getAllByCSS('.v-rating__item .v-btn')\n\n    await userEvent.click(buttons[1])\n    expect(model.value).toBe(2)\n\n    clearable.value = true\n\n    await userEvent.click(buttons[1])\n    expect(model.value).toBe(0)\n  })\n\n  it('should not react to click events when readonly', async () => {\n    const model = ref<number>()\n    render(() => <VRating v-model={ model.value } readonly />)\n\n    const buttons = screen.getAllByCSS('.v-rating__item .v-btn')\n\n    await click(buttons[1])\n    await nextTick()\n    expect(model.value).toBeUndefined()\n\n    model.value = 4\n    await click(buttons[0])\n    await nextTick()\n    expect(model.value).toBe(4)\n  })\n\n  it('should not react to keyboard events when readonly', async () => {\n    const model = ref<number>()\n    render(() => <VRating v-model={ model.value } readonly />)\n\n    await userEvent.tab()\n    await userEvent.keyboard('{ArrowRight}')\n    await nextTick()\n    expect(model.value).toBeUndefined()\n\n    model.value = 4\n    await userEvent.keyboard('{ArrowLeft}')\n    await nextTick()\n    expect(model.value).toBe(4)\n  })\n\n  it('should change icon on hover', async () => {\n    render(() => <VRating hover />)\n\n    const buttons = screen.getAllByCSS('.v-rating__item .v-btn')\n    await userEvent.hover(buttons[2])\n\n    const icons = screen.getAllByCSS('.v-rating__item .v-icon')\n\n    icons.forEach((el, i) => {\n      expect(el.outerHTML).to.equal(icons[i < 3 ? 0 : 3].outerHTML)\n    })\n  })\n\n  it('should support half-increments', () => {\n    const model = ref<number | null>(null)\n    render(() => <VRating v-model={ model.value } halfIncrements />)\n\n    expect(screen.getAllByCSS('.v-rating__item input')).toHaveLength(10)\n\n    screen.getAllByCSS('.v-rating__item--half')[3].click()\n    expect(model.value).toBe(3.5)\n  })\n\n  it('should support half-increments and custom size', () => {\n    const model = ref<number | null>(null)\n    render(() => <VRating v-model={ model.value } halfIncrements size=\"64\" />)\n\n    expect(screen.getAllByCSS('.v-rating__item input')).toHaveLength(10)\n\n    screen.getAllByCSS('.v-rating__item--half')[3].click()\n    expect(model.value).toBe(3.5)\n  })\n\n  it('should support correct keyboard navigation', async () => {\n    const model = ref<number | null>(null)\n    render(() => (\n      <div>\n        <VRating v-model={ model.value } />\n        <input type=\"text\" />\n      </div>\n    ))\n\n    const buttons = screen.getAllByCSS('.v-rating__item .v-btn')\n    const inputBelow = screen.getByCSS('input[type=\"text\"]')\n\n    await userEvent.tab()\n    expect(buttons[0]).toHaveFocus()\n    await userEvent.keyboard('{Space}')\n    expect(model.value).toBe(1)\n\n    await userEvent.tab() // should escape the VRating\n    expect(inputBelow).toHaveFocus()\n\n    await userEvent.tab({ shift: true }) // should return\n    expect(buttons[0]).toHaveFocus()\n\n    await userEvent.keyboard('{ArrowRight}{ArrowRight}')\n    expect(buttons[2]).toHaveFocus()\n\n    await userEvent.keyboard('{ArrowLeft}')\n    expect(model.value).toBe(2)\n  })\n\n  showcase({ stories })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VRating/_variables.scss",
    "content": "@use '../../styles/settings';\n\n// Defaults\n$rating-item-focused-button-overlay-opacity: var(--v-hover-opacity) !default;\n$rating-item-align-items: center !default;\n$rating-item-button-opacity: 1 !default;\n$rating-item-button-transition-property: transform !default;\n$rating-item-icon-transform: scale(1.25) !default;\n$rating-item-transition-timing-function: settings.$decelerated-easing !default;\n$rating-white-space: nowrap !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VRating/index.ts",
    "content": "export { VRating } from './VRating'\n"
  },
  {
    "path": "packages/vuetify/src/components/VResponsive/VResponsive.sass",
    "content": "@use '../../styles/settings'\n@use '../../styles/tools'\n\n@include tools.layer('components')\n  .v-responsive\n    display: flex\n    flex: 1 0 auto\n    max-height: 100%\n    max-width: 100%\n    overflow: hidden\n    position: relative\n\n    &--inline\n      display: inline-flex\n      flex: 0 0 auto\n\n  .v-responsive__content\n    flex: 1 0 0px\n    max-width: 100%\n\n  .v-responsive__sizer ~ .v-responsive__content\n    margin-inline-start: -100%\n\n  .v-responsive__sizer\n    flex: 1 0 0px\n    transition: padding-bottom 0.2s settings.$standard-easing\n    pointer-events: none\n"
  },
  {
    "path": "packages/vuetify/src/components/VResponsive/VResponsive.tsx",
    "content": "// Styles\nimport './VResponsive.sass'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { makeDimensionProps, useDimension } from '@/composables/dimensions'\n\n// Utilities\nimport { computed } from 'vue'\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\nexport type VResponsiveSlots = {\n  default: never\n  additional: never\n}\n\nexport function useAspectStyles (props: { aspectRatio?: string | number }) {\n  return {\n    aspectStyles: computed(() => {\n      const ratio = Number(props.aspectRatio)\n\n      return ratio\n        ? { paddingBottom: String(1 / ratio * 100) + '%' }\n        : undefined\n    }),\n  }\n}\n\nexport const makeVResponsiveProps = propsFactory({\n  aspectRatio: [String, Number],\n  contentClass: null,\n  inline: Boolean,\n\n  ...makeComponentProps(),\n  ...makeDimensionProps(),\n}, 'VResponsive')\n\nexport const VResponsive = genericComponent<VResponsiveSlots>()({\n  name: 'VResponsive',\n\n  props: makeVResponsiveProps(),\n\n  setup (props, { slots }) {\n    const { aspectStyles } = useAspectStyles(props)\n    const { dimensionStyles } = useDimension(props)\n\n    useRender(() => (\n      <div\n        class={[\n          'v-responsive',\n          { 'v-responsive--inline': props.inline },\n          props.class,\n        ]}\n        style={[\n          dimensionStyles.value,\n          props.style,\n        ]}\n      >\n        <div class=\"v-responsive__sizer\" style={ aspectStyles.value } />\n\n        { slots.additional?.() }\n\n        { slots.default && (\n          <div class={['v-responsive__content', props.contentClass]}>{ slots.default() }</div>\n        )}\n      </div>\n    ))\n\n    return {}\n  },\n})\n\nexport type VResponsive = InstanceType<typeof VResponsive>\n"
  },
  {
    "path": "packages/vuetify/src/components/VResponsive/__tests__/VResponsive.spec.ts",
    "content": "// Components\nimport { VResponsive } from '..'\n\n// Utilities\nimport { mount } from '@vue/test-utils'\nimport { h } from 'vue'\nimport { createVuetify } from '@/framework'\n\ndescribe('VResponsive', () => {\n  const vuetify = createVuetify()\n\n  function mountFunction (options = {}) {\n    return mount(VResponsive, {\n      global: { plugins: [vuetify] },\n      ...options,\n    })\n  }\n\n  it('should force aspect ratio', () => {\n    const wrapper = mountFunction({\n      propsData: { aspectRatio: 16 / 9 },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render content', () => {\n    const wrapper = mountFunction({\n      slots: {\n        default: () => h('div', ['content']),\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should set height', () => {\n    const wrapper = mountFunction({\n      propsData: { height: 100, maxHeight: 200 },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VResponsive/__tests__/__snapshots__/VResponsive.spec.ts.snap",
    "content": "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html\n\nexports[`VResponsive > should force aspect ratio 1`] = `\n\"<div class=\"v-responsive\">\n  <div class=\"v-responsive__sizer\" style=\"padding-bottom: 56.25%;\"></div>\n  <!---->\n  <!---->\n</div>\"\n`;\n\nexports[`VResponsive > should render content 1`] = `\n\"<div class=\"v-responsive\">\n  <div class=\"v-responsive__sizer\"></div>\n  <!---->\n  <div class=\"v-responsive__content\">\n    <div>content</div>\n  </div>\n</div>\"\n`;\n\nexports[`VResponsive > should set height 1`] = `\n\"<div class=\"v-responsive\" style=\"height: 100px; max-height: 200px;\">\n  <div class=\"v-responsive__sizer\"></div>\n  <!---->\n  <!---->\n</div>\"\n`;\n"
  },
  {
    "path": "packages/vuetify/src/components/VResponsive/index.ts",
    "content": "export { VResponsive } from './VResponsive'\n"
  },
  {
    "path": "packages/vuetify/src/components/VSelect/VSelect.sass",
    "content": "@use 'sass:selector'\n@use 'sass:math'\n@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n@use './mixins' as *\n\n@include tools.layer('components')\n  .v-select\n    @include select-compact-chip-label\n\n    .v-field\n      .v-text-field__prefix,\n      .v-text-field__suffix,\n      .v-field__input,\n      &.v-field\n        cursor: pointer\n\n    .v-field\n      .v-field__input\n        > input\n          align-self: flex-start\n          opacity: 1\n          flex: 0 0\n          position: absolute\n          left: 0\n          right: 0\n          width: 100%\n          transition: none\n          pointer-events: none\n          caret-color: transparent\n          padding-inline: inherit\n\n    .v-field--dirty\n      .v-select__selection\n        margin-inline-end: 2px\n\n    .v-select__selection-text\n      overflow: hidden\n      text-overflow: ellipsis\n      white-space: nowrap\n\n    &__content\n      overflow: hidden\n      @include tools.elevation($select-content-elevation)\n\n      @at-root #{selector.append('.v-menu > .v-overlay__content', &)}\n        @include tools.rounded($select-content-border-radius)\n\n      > .v-sheet\n        display: flex\n        flex-direction: column\n\n    &__mask\n      background: rgb(var(--v-theme-surface-light))\n\n    &__selection\n      display: inline-flex\n      align-items: center\n      letter-spacing: inherit\n      line-height: inherit\n      max-width: 100%\n\n    .v-select__selection\n      &:first-child\n        margin-inline-start: 0\n\n    &--selected\n      .v-field\n        .v-field__input\n          > input\n            opacity: 0\n\n    &__menu-icon\n      margin-inline-start: 4px\n      transition: $select-transition\n\n      .v-select--active-menu &\n        transform: rotate(180deg)\n"
  },
  {
    "path": "packages/vuetify/src/components/VSelect/VSelect.tsx",
    "content": "// Styles\nimport './VSelect.sass'\n\n// Components\nimport { VDialogTransition } from '@/components/transitions'\nimport { VAvatar } from '@/components/VAvatar'\nimport { VCheckboxBtn } from '@/components/VCheckbox'\nimport { VChip } from '@/components/VChip'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\nimport { VDivider } from '@/components/VDivider'\nimport { VIcon } from '@/components/VIcon'\nimport { useInputIcon } from '@/components/VInput/InputIcon'\nimport { VList, VListItem, VListSubheader } from '@/components/VList'\nimport { VMenu } from '@/components/VMenu'\nimport { VSheet } from '@/components/VSheet'\nimport { makeVTextFieldProps, VTextField } from '@/components/VTextField/VTextField'\nimport { VVirtualScroll } from '@/components/VVirtualScroll'\n\n// Composables\nimport { useScrolling } from './useScrolling'\nimport { useFocusGroups } from '../../composables/focusGroups'\nimport { useAutocomplete } from '@/composables/autocomplete'\nimport { highlightResult, makeFilterProps, useFilter } from '@/composables/filter'\nimport { useForm } from '@/composables/form'\nimport { forwardRefs } from '@/composables/forwardRefs'\nimport { IconValue } from '@/composables/icons'\nimport { makeItemsProps, useItems } from '@/composables/list-items'\nimport { useLocale } from '@/composables/locale'\nimport { makeMenuActivatorProps, useMenuActivator } from '@/composables/menuActivator'\nimport { useProxiedModel } from '@/composables/proxiedModel'\nimport { makeTransitionProps } from '@/composables/transition'\n\n// Utilities\nimport { computed, mergeProps, nextTick, ref, shallowRef, toRef, watch } from 'vue'\nimport {\n  camelizeProps,\n  checkPrintable,\n  deepEqual,\n  ensureValidVNode,\n  genericComponent,\n  IN_BROWSER,\n  matchesSelector,\n  omit,\n  propsFactory,\n  useRender,\n  wrapInArray,\n} from '@/util'\n\n// Types\nimport type { Component, PropType, Ref } from 'vue'\nimport type { VFieldSlots } from '@/components/VField/VField'\nimport type { VInputSlots } from '@/components/VInput/VInput'\nimport type { ListItem } from '@/composables/list-items'\nimport type { GenericProps, SelectItemKey } from '@/util'\n\ntype Primitive = string | number | boolean | symbol\n\ntype Val <T, ReturnObject extends boolean> = [T] extends [Primitive]\n  ? T\n  : (ReturnObject extends true ? T : any)\n\ntype Value <T, ReturnObject extends boolean, Multiple extends boolean> =\n  Multiple extends true\n    ? readonly Val<T, ReturnObject>[]\n    : Val<T, ReturnObject> | null\n\nexport const makeSelectProps = propsFactory({\n  chips: Boolean,\n  closableChips: Boolean,\n  eager: Boolean,\n  hideNoData: Boolean,\n  hideSelected: Boolean,\n  listProps: {\n    type: Object as PropType<VList['$props']>,\n  },\n  menu: Boolean,\n  menuElevation: [Number, String],\n  menuIcon: {\n    type: IconValue,\n    default: '$dropdown',\n  },\n  menuProps: {\n    type: Object as PropType<VMenu['$props']>,\n  },\n  multiple: Boolean,\n  noDataText: {\n    type: String,\n    default: '$vuetify.noDataText',\n  },\n  openOnClear: Boolean,\n  itemColor: String,\n  noAutoScroll: Boolean,\n\n  ...makeMenuActivatorProps(),\n  ...makeItemsProps({ itemChildren: false }),\n}, 'Select')\n\nexport const makeVSelectProps = propsFactory({\n  search: String,\n\n  ...makeFilterProps({ filterKeys: ['title'] }),\n  ...makeSelectProps(),\n  ...omit(makeVTextFieldProps({\n    modelValue: null,\n    role: 'combobox',\n  }), ['validationValue', 'dirty']),\n  ...makeTransitionProps({ transition: { component: VDialogTransition as Component } }),\n}, 'VSelect')\n\ntype ItemType<T> = T extends readonly (infer U)[] ? U : never\n\nexport const VSelect = genericComponent<new <\n  T extends readonly any[],\n  Item = ItemType<T>,\n  ReturnObject extends boolean = false,\n  Multiple extends boolean = false,\n  V extends Value<Item, ReturnObject, Multiple> = Value<Item, ReturnObject, Multiple>\n>(\n  props: {\n    items?: T\n    itemTitle?: SelectItemKey<ItemType<T>>\n    itemValue?: SelectItemKey<ItemType<T>>\n    itemProps?: SelectItemKey<ItemType<T>>\n    returnObject?: ReturnObject\n    multiple?: Multiple\n    modelValue?: V | null\n    'onUpdate:modelValue'?: (value: V) => void\n  },\n  slots: Omit<VInputSlots & VFieldSlots, 'default'> & {\n    item: { item: Item, internalItem: ListItem<Item>, index: number, props: Record<string, unknown> }\n    chip: { item: Item, internalItem: ListItem<Item>, index: number, props: Record<string, unknown> }\n    selection: { item: Item, internalItem: ListItem<Item>, index: number }\n    subheader: { props: Record<string, unknown>, index: number }\n    divider: { props: Record<string, unknown>, index: number }\n    'prepend-item': never\n    'append-item': never\n    'no-data': never\n    'menu-header': { search: Ref<string | undefined>, filteredItems: ListItem<Item>[] }\n    'menu-footer': { search: Ref<string | undefined>, filteredItems: ListItem<Item>[] }\n  }\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VSelect',\n\n  props: makeVSelectProps(),\n\n  emits: {\n    'update:focused': (focused: boolean) => true,\n    'update:modelValue': (value: any) => true,\n    'update:menu': (ue: boolean) => true,\n    'update:search': (value: string) => true,\n  },\n\n  setup (props, { slots }) {\n    const { t } = useLocale()\n    const vTextFieldRef = ref<VTextField>()\n    const vMenuRef = ref<VMenu>()\n    const headerRef = ref<HTMLElement>()\n    const footerRef = ref<HTMLElement>()\n    const vVirtualScrollRef = ref<VVirtualScroll>()\n    const { items, transformIn, transformOut } = useItems(props)\n    const search = useProxiedModel(props, 'search', '')\n    const { filteredItems, getMatches } = useFilter(props, items, () => search.value)\n    const model = useProxiedModel(\n      props,\n      'modelValue',\n      [],\n      v => transformIn(v === null ? [null] : wrapInArray(v)),\n      v => {\n        const transformed = transformOut(v)\n        return props.multiple ? transformed : (transformed[0] ?? null)\n      }\n    )\n    const counterValue = computed(() => {\n      return typeof props.counterValue === 'function' ? props.counterValue(model.value)\n        : typeof props.counterValue === 'number' ? props.counterValue\n        : model.value.length\n    })\n    const form = useForm(props)\n    const autocomplete = useAutocomplete(props)\n    const selectedValues = computed(() => model.value.map(selection => selection.value))\n    const isFocused = shallowRef(false)\n    const closableChips = toRef(() => props.closableChips && !form.isReadonly.value && !form.isDisabled.value)\n    const { InputIcon } = useInputIcon(props)\n\n    let keyboardLookupPrefix = ''\n    let keyboardLookupIndex = 0\n    let keyboardLookupLastTime: number\n\n    const displayItems = computed(() => {\n      const baseItems = search.value ? filteredItems.value : items.value\n      if (props.hideSelected) {\n        return baseItems.filter(item => !model.value.some(s => (props.valueComparator || deepEqual)(s, item)))\n      }\n      return baseItems\n    })\n\n    const menuDisabled = computed(() => (\n      (props.hideNoData && !displayItems.value.length) ||\n      form.isReadonly.value || form.isDisabled.value\n    ))\n    const _menu = useProxiedModel(props, 'menu')\n    const menu = computed({\n      get: () => _menu.value,\n      set: v => {\n        if (_menu.value && !v && vMenuRef.value?.ΨopenChildren.size) return\n        if (v && menuDisabled.value) return\n        _menu.value = v\n      },\n    })\n\n    const { menuId, ariaExpanded, ariaControls } = useMenuActivator(props, menu)\n\n    const computedMenuProps = computed(() => {\n      return {\n        ...props.menuProps,\n        activatorProps: {\n          ...(props.menuProps?.activatorProps || {}),\n          'aria-haspopup': 'listbox', // Set aria-haspopup to 'listbox'\n        },\n      }\n    })\n\n    const listRef = ref<VList>()\n    const listEvents = useScrolling(listRef, vTextFieldRef)\n    const { onTabKeydown } = useFocusGroups({\n      groups: [\n        { type: 'element' as const, contentRef: headerRef },\n        { type: 'list' as const, contentRef: listRef, displayItemsCount: () => displayItems.value.length },\n        { type: 'element' as const, contentRef: footerRef },\n      ],\n      onLeave: () => {\n        menu.value = false\n        vTextFieldRef.value?.focus()\n      },\n    })\n\n    function onClear (e: MouseEvent | KeyboardEvent) {\n      if (props.openOnClear) {\n        menu.value = true\n      }\n    }\n    function onMousedownControl () {\n      if (menuDisabled.value) return\n\n      menu.value = !menu.value\n    }\n\n    function onMenuKeydown (e: KeyboardEvent) {\n      if (e.key === 'Tab') {\n        onTabKeydown(e)\n      }\n\n      if (listRef.value?.$el.contains(e.target) && checkPrintable(e)) {\n        onKeydown(e)\n      }\n    }\n\n    function onKeydown (e: KeyboardEvent) {\n      if (!e.key || form.isReadonly.value) return\n\n      if (['Enter', ' ', 'ArrowDown', 'ArrowUp', 'Home', 'End'].includes(e.key)) {\n        e.preventDefault()\n      }\n\n      if (['Enter', 'ArrowDown', ' '].includes(e.key)) {\n        menu.value = true\n      }\n\n      if (['Escape', 'Tab'].includes(e.key)) {\n        menu.value = false\n      }\n\n      if (props.clearable && e.key === 'Backspace') {\n        e.preventDefault()\n        model.value = []\n        onClear(e)\n        return\n      }\n\n      if (e.key === 'Home') {\n        listRef.value?.focus('first')\n      } else if (e.key === 'End') {\n        listRef.value?.focus('last')\n      }\n\n      // html select hotkeys\n      const KEYBOARD_LOOKUP_THRESHOLD = 1000 // milliseconds\n\n      if (!checkPrintable(e)) return\n\n      const now = performance.now()\n      if (now - keyboardLookupLastTime > KEYBOARD_LOOKUP_THRESHOLD) {\n        keyboardLookupPrefix = ''\n        keyboardLookupIndex = 0\n      }\n      keyboardLookupPrefix += e.key.toLowerCase()\n      keyboardLookupLastTime = now\n\n      const items = displayItems.value\n      function findItem () {\n        let result = findItemBase()\n        if (result) return result\n\n        if (keyboardLookupPrefix.at(-1) === keyboardLookupPrefix.at(-2)) {\n          // No matches but we have a repeated letter, try the next item with that prefix\n          keyboardLookupPrefix = keyboardLookupPrefix.slice(0, -1)\n          keyboardLookupIndex++\n          result = findItemBase()\n          if (result) return result\n        }\n\n        // Still nothing, wrap around to the top\n        keyboardLookupIndex = 0\n        result = findItemBase()\n        if (result) return result\n\n        // Still nothing, try just the new letter\n        keyboardLookupPrefix = e.key.toLowerCase()\n        return findItemBase()\n      }\n      function findItemBase () {\n        for (let i = keyboardLookupIndex; i < items.length; i++) {\n          const _item = items[i]\n          if (_item.title.toLowerCase().startsWith(keyboardLookupPrefix)) {\n            return [_item, i] as const\n          }\n        }\n        return undefined\n      }\n\n      const result = findItem()\n      if (!result) return\n\n      const [item, index] = result\n      keyboardLookupIndex = index\n      listRef.value?.focus(index)\n      if (!props.multiple) {\n        model.value = [item]\n      }\n    }\n\n    /** @param set - null means toggle */\n    function select (item: ListItem, set: boolean | null = true) {\n      if (item.props.disabled) return\n\n      if (props.multiple) {\n        const index = model.value.findIndex(selection => (props.valueComparator || deepEqual)(selection.value, item.value))\n        const add = set == null ? !~index : set\n\n        if (~index) {\n          const value = add ? [...model.value, item] : [...model.value]\n          value.splice(index, 1)\n          model.value = value\n        } else if (add) {\n          model.value = [...model.value, item]\n        }\n      } else {\n        const add = set !== false\n        model.value = add ? [item] : []\n\n        nextTick(() => {\n          menu.value = false\n        })\n      }\n    }\n    function onBlur (e: FocusEvent) {\n      const target = e.target as Element\n      if (!vTextFieldRef.value?.$el.contains(target)) {\n        menu.value = false\n      }\n    }\n    function getSelectedIndex () {\n      return displayItems.value.findIndex(\n        item => model.value.some(s => (props.valueComparator || deepEqual)(s.value, item.value))\n      )\n    }\n    function getSelectedFocusableIndex () {\n      if (!model.value.length) return -1\n      const comparator = props.valueComparator || deepEqual\n      let focusableIndex = 0\n      for (const item of displayItems.value) {\n        const isSelected = model.value.some(s => comparator(s.value, item.value))\n        if (isSelected) return item.props.disabled ? -1 : focusableIndex\n        if (!item.props.disabled) focusableIndex++\n      }\n      return -1\n    }\n    function onAfterEnter () {\n      if (props.eager) {\n        vVirtualScrollRef.value?.calculateVisibleItems()\n      }\n      if (listRef.value && isFocused.value) {\n        const index = getSelectedFocusableIndex()\n        listRef.value.focus(index >= 0 ? index : 'first')\n      }\n    }\n    function onAfterLeave () {\n      search.value = ''\n      if (isFocused.value) {\n        vTextFieldRef.value?.focus()\n      }\n    }\n    function onFocusin (e: FocusEvent) {\n      isFocused.value = true\n    }\n    function onFocusout (e: FocusEvent) {\n      if (!vTextFieldRef.value?.$el.contains(e.relatedTarget as Node)) {\n        isFocused.value = false\n      }\n    }\n    function onModelUpdate (v: any) {\n      if (v == null) model.value = []\n      else if (matchesSelector(vTextFieldRef.value, ':autofill') || matchesSelector(vTextFieldRef.value, ':-webkit-autofill')) {\n        const item = items.value.find(item => item.title === v)\n        if (item) {\n          select(item)\n        }\n      } else if (vTextFieldRef.value) {\n        vTextFieldRef.value.value = ''\n      }\n    }\n\n    watch(menu, () => {\n      if (!props.hideSelected && menu.value && model.value.length) {\n        const index = getSelectedIndex()\n        IN_BROWSER && !props.noAutoScroll && window.requestAnimationFrame(() => {\n          index >= 0 && vVirtualScrollRef.value?.scrollToIndex(index)\n        })\n      }\n    })\n\n    watch(items, (newVal, oldVal) => {\n      if (menu.value) return\n\n      if (isFocused.value && props.hideNoData && !oldVal.length && newVal.length) {\n        menu.value = true\n      }\n    })\n\n    useRender(() => {\n      const hasChips = !!(props.chips || slots.chip)\n      const hasList = !!(\n        (!props.hideNoData || displayItems.value.length) ||\n        slots['prepend-item'] ||\n        slots['append-item'] ||\n        slots['no-data']\n      )\n      const isDirty = model.value.length > 0\n      const textFieldProps = VTextField.filterProps(props)\n\n      const placeholder = isDirty || (\n        !isFocused.value &&\n        props.label &&\n        !props.persistentPlaceholder\n      ) ? undefined : props.placeholder\n\n      const menuSlotProps = {\n        search,\n        filteredItems: filteredItems.value,\n      }\n\n      return (\n        <VTextField\n          ref={ vTextFieldRef }\n          { ...textFieldProps }\n          modelValue={ model.value.map(v => v.props.title).join(', ') }\n          name={ undefined }\n          onUpdate:modelValue={ onModelUpdate }\n          v-model:focused={ isFocused.value }\n          validationValue={ model.externalValue }\n          counterValue={ counterValue.value }\n          dirty={ isDirty }\n          class={[\n            'v-select',\n            {\n              'v-select--active-menu': menu.value,\n              'v-select--chips': !!props.chips,\n              [`v-select--${props.multiple ? 'multiple' : 'single'}`]: true,\n              'v-select--selected': model.value.length,\n              'v-select--selection-slot': !!slots.selection,\n            },\n            props.class,\n          ]}\n          style={ props.style }\n          inputmode=\"none\"\n          placeholder={ placeholder }\n          onClick:clear={ onClear }\n          onMousedown:control={ onMousedownControl }\n          onBlur={ onBlur }\n          onKeydown={ onKeydown }\n          aria-expanded={ ariaExpanded.value }\n          aria-controls={ ariaControls.value }\n        >\n          {{\n            ...slots,\n            default: ({ id }) => (\n              <>\n                <select\n                  hidden\n                  multiple={ props.multiple }\n                  name={ autocomplete.fieldName.value }\n                >\n                  { items.value.map(item => (\n                    <option\n                      key={ item.value }\n                      value={ item.value }\n                      selected={ selectedValues.value.includes(item.value) }\n                    />\n                  ))}\n                </select>\n\n                <VMenu\n                  id={ menuId.value }\n                  ref={ vMenuRef }\n                  v-model={ menu.value }\n                  activator=\"parent\"\n                  contentClass=\"v-select__content\"\n                  disabled={ menuDisabled.value }\n                  eager={ props.eager }\n                  maxHeight={ 310 }\n                  openOnClick={ false }\n                  closeOnContentClick={ false }\n                  transition={ props.transition }\n                  onAfterEnter={ onAfterEnter }\n                  onAfterLeave={ onAfterLeave }\n                  { ...computedMenuProps.value }\n                >\n                  <VSheet\n                    elevation={ props.menuElevation }\n                    onFocusin={ onFocusin }\n                    onFocusout={ onFocusout }\n                    onKeydown={ onMenuKeydown }\n                  >\n                    { slots['menu-header'] && (\n                      <header ref={ headerRef }>\n                        { slots['menu-header'](menuSlotProps) }\n                      </header>\n                    )}\n\n                    { hasList && (\n                      <VList\n                        key=\"select-list\"\n                        ref={ listRef }\n                        selected={ selectedValues.value }\n                        selectStrategy={ props.multiple ? 'independent' : 'single-independent' }\n                        tabindex=\"-1\"\n                        selectable={ !!displayItems.value.length }\n                        aria-live=\"polite\"\n                        aria-labelledby={ `${id.value}-label` }\n                        aria-multiselectable={ props.multiple }\n                        color={ props.itemColor ?? props.color }\n                        { ...listEvents }\n                        { ...props.listProps }\n                      >\n                        { slots['prepend-item']?.() }\n\n                        { !displayItems.value.length && !props.hideNoData && (slots['no-data']?.() ?? (\n                          <VListItem key=\"no-data\" title={ t(props.noDataText) } />\n                        ))}\n\n                        <VVirtualScroll ref={ vVirtualScrollRef } renderless items={ displayItems.value } itemKey=\"value\">\n                          { ({ item, index, itemRef }) => {\n                            const camelizedProps = camelizeProps(item.props)\n\n                            const itemProps = mergeProps(item.props, {\n                              ref: itemRef,\n                              key: item.value,\n                              onClick: () => select(item, null),\n                              'aria-posinset': index + 1,\n                              'aria-setsize': displayItems.value.length,\n                            })\n\n                            if (item.type === 'divider') {\n                              return slots.divider?.({ props: item.raw, index }) ?? (\n                                <VDivider { ...item.props } key={ `divider-${index}` } />\n                              )\n                            }\n\n                            if (item.type === 'subheader') {\n                              return slots.subheader?.({ props: item.raw, index }) ?? (\n                                <VListSubheader { ...item.props } key={ `subheader-${index}` } />\n                              )\n                            }\n\n                            return slots.item?.({\n                              item: item.raw,\n                              internalItem: item,\n                              index,\n                              props: itemProps,\n                            }) ?? (\n                              <VListItem { ...itemProps } role=\"option\">\n                                {{\n                                  prepend: ({ isSelected }) => (\n                                    <>\n                                      { props.multiple && !props.hideSelected ? (\n                                        <VCheckboxBtn\n                                          key={ item.value }\n                                          modelValue={ isSelected }\n                                          ripple={ false }\n                                          tabindex=\"-1\"\n                                          aria-hidden\n                                          onClick={ (event: MouseEvent) => event.preventDefault() }\n                                        />\n                                      ) : undefined }\n\n                                      { camelizedProps.prependAvatar && (\n                                        <VAvatar image={ camelizedProps.prependAvatar } />\n                                      )}\n\n                                      { camelizedProps.prependIcon && (\n                                        <VIcon icon={ camelizedProps.prependIcon } />\n                                      )}\n                                    </>\n                                  ),\n                                  title: () => {\n                                    return search.value\n                                      ? highlightResult('v-select', item.title, getMatches(item)?.title)\n                                      : item.title\n                                  },\n                                }}\n                              </VListItem>\n                            )\n                          }}\n                        </VVirtualScroll>\n\n                        { slots['append-item']?.() }\n                      </VList>\n                    )}\n\n                    { slots['menu-footer'] && (\n                      <footer ref={ footerRef }>\n                        { slots['menu-footer'](menuSlotProps) }\n                      </footer>\n                    )}\n                  </VSheet>\n                </VMenu>\n\n                { model.value.map((item, index) => {\n                  function onChipClose (e: Event) {\n                    e.stopPropagation()\n                    e.preventDefault()\n\n                    select(item, false)\n                  }\n\n                  const slotProps = mergeProps(VChip.filterProps(item.props), {\n                    'onClick:close': onChipClose,\n                    onKeydown (e: KeyboardEvent) {\n                      if (e.key !== 'Enter' && e.key !== ' ') return\n\n                      e.preventDefault()\n                      e.stopPropagation()\n\n                      onChipClose(e)\n                    },\n                    onMousedown (e: MouseEvent) {\n                      e.preventDefault()\n                      e.stopPropagation()\n                    },\n                    modelValue: true,\n                    'onUpdate:modelValue': undefined,\n                  })\n\n                  const hasSlot = hasChips ? !!slots.chip : !!slots.selection\n                  const slotContent = hasSlot\n                    ? ensureValidVNode(\n                      hasChips\n                        ? slots.chip!({ item: item.raw, internalItem: item, index, props: slotProps })\n                        : slots.selection!({ item: item.raw, internalItem: item, index })\n                    )\n                    : undefined\n\n                  if (hasSlot && !slotContent) return undefined\n\n                  return (\n                    <div key={ item.value } class=\"v-select__selection\">\n                      { hasChips ? (\n                        !slots.chip ? (\n                          <VChip\n                            key=\"chip\"\n                            closable={ closableChips.value }\n                            size=\"small\"\n                            text={ item.title }\n                            disabled={ item.props.disabled }\n                            { ...slotProps }\n                          />\n                        ) : (\n                          <VDefaultsProvider\n                            key=\"chip-defaults\"\n                            defaults={{\n                              VChip: {\n                                closable: closableChips.value,\n                                size: 'small',\n                                text: item.title,\n                              },\n                            }}\n                          >\n                            { slotContent }\n                          </VDefaultsProvider>\n                        )\n                      ) : (\n                        slotContent ?? (\n                          <span class=\"v-select__selection-text\">\n                            { item.title }\n                            { props.multiple && (index < model.value.length - 1) && (\n                              <span class=\"v-select__selection-comma\">,</span>\n                            )}\n                          </span>\n                        )\n                      )}\n                    </div>\n                  )\n                })}\n              </>\n            ),\n            'append-inner': (...args) => (\n              <>\n                { slots['append-inner']?.(...args) }\n                { props.menuIcon ? (\n                  <VIcon\n                    class=\"v-select__menu-icon\"\n                    color={ vTextFieldRef.value?.fieldIconColor }\n                    icon={ props.menuIcon }\n                    aria-hidden\n                  />\n                ) : undefined }\n                { props.appendInnerIcon && (\n                  <InputIcon\n                    key=\"append-icon\"\n                    name=\"appendInner\"\n                    color={ args[0].iconColor.value }\n                  />\n                )}\n              </>\n            ),\n          }}\n        </VTextField>\n      )\n    })\n\n    return forwardRefs({\n      isFocused,\n      menu,\n      search,\n      filteredItems,\n      select,\n    }, vTextFieldRef)\n  },\n})\n\nexport type VSelect = InstanceType<typeof VSelect>\n"
  },
  {
    "path": "packages/vuetify/src/components/VSelect/__tests__/VSelect.spec.browser.tsx",
    "content": "// Components\nimport { VSelect } from '../VSelect'\nimport { VForm } from '@/components/VForm'\nimport { VListItem } from '@/components/VList'\nimport { VTextField } from '@/components/VTextField'\n\n// Utilities\nimport { commands, render, screen, showcase, userEvent, wait, waitForClickable } from '@test'\nimport { getAllByRole, waitFor } from '@testing-library/vue'\nimport { cloneVNode, computed, nextTick, ref } from 'vue'\n\nconst variants = ['underlined', 'outlined', 'filled', 'solo', 'plain'] as const\nconst densities = ['default', 'comfortable', 'compact'] as const\nconst items = ['California', 'Colorado', 'Florida', 'Georgia', 'Texas', 'Wyoming'] as const\n\nconst stories = Object.fromEntries(Object.entries({\n  'Default input': <VSelect items={ items } />,\n  Disabled: <VSelect items={ items } disabled />,\n  Affixes: <VSelect items={ items } prefix=\"prefix\" suffix=\"suffix\" />,\n  'Prepend/append': <VSelect items={ items } prependIcon=\"$vuetify\" appendIcon=\"$vuetify\" />,\n  'Prepend/append inner': <VSelect items={ items } prependInnerIcon=\"$vuetify\" appendInnerIcon=\"$vuetify\" />,\n  Placeholder: <VSelect items={ items } placeholder=\"placeholder\" persistentPlaceholder />,\n}).map(([k, v]) => [k, (\n  <div class=\"d-flex flex-column flex-grow-1\">\n    { variants.map(variant => (\n      densities.map(density => (\n        <div class=\"d-flex align-start\" style=\"gap: 0.4rem; height: 100px;\">\n          { cloneVNode(v, { variant, density, label: `${variant} ${density}` }) }\n          { cloneVNode(v, { variant, density, label: `with value`, modelValue: ['California'] }) }\n          { cloneVNode(v, { variant, density, label: `chips`, chips: true, modelValue: ['California'] }) }\n          <VSelect\n            variant={ variant }\n            density={ density }\n            modelValue={['California']}\n            label=\"selection slot\"\n            { ...v.props }\n          >{{\n            selection: ({ item }) => {\n              return item\n            },\n          }}\n          </VSelect>\n        </div>\n      ))\n    )).flat()}\n  </div>\n)]))\n\ndescribe('VSelect', () => {\n  it('should toggle menu with dropdown icon', async () => {\n    const { element } = render(() => (\n      <VSelect items={['Item #1', 'Item #2']} />\n    ))\n\n    const menuIcon = screen.getByCSS('.v-icon')\n    expect(screen.queryAllByCSS('.v-list-item')).toHaveLength(0)\n    expect(element).not.toHaveClass('v-select--active-menu')\n\n    await userEvent.click(menuIcon)\n    await expect.poll(() => screen.queryAllByCSS('.v-list-item')).toHaveLength(2)\n    expect(element).toHaveClass('v-select--active-menu')\n\n    await userEvent.click(menuIcon)\n    await expect.poll(() => screen.queryAllByCSS('.v-list-item')).toHaveLength(0)\n    expect(element).not.toHaveClass('v-select--active-menu')\n  })\n\n  it('should render selection slot', () => {\n    const items = [\n      { title: 'a' },\n      { title: 'b' },\n      { title: 'c' },\n    ]\n    let model: { title: string }[] = [{ title: 'b' }]\n\n    render(() => (\n      <VSelect\n        multiple\n        returnObject\n        items={ items }\n        modelValue={ model }\n        onUpdate:modelValue={ val => model = val }\n      >\n        {{\n          selection: ({ item, index }) => {\n            return item.title.toUpperCase()\n          },\n        }}\n      </VSelect>\n    ))\n\n    expect(screen.getByCSS('.v-select__selection')).toHaveTextContent('B')\n  })\n\n  it('should render prepend-item slot', () => {\n    render(() => (\n      <VSelect menu items={['Item #1', 'Item #2']}>\n        {{\n          'prepend-item': () => (\n            <VListItem title=\"Foo\"></VListItem>\n          ),\n        }}\n      </VSelect>\n    ))\n\n    expect(screen.getAllByCSS('.v-list-item')[0]).toHaveTextContent('Foo')\n  })\n\n  it('should render append-item slot', () => {\n    render(() => (\n      <VSelect menu items={['Item #1', 'Item #2']}>\n        {{\n          'append-item': () => (\n            <VListItem title=\"Foo\"></VListItem>\n          ),\n        }}\n      </VSelect>\n    ))\n    expect(screen.getAllByCSS('.v-list-item').at(-1)).toHaveTextContent('Foo')\n  })\n\n  it('should close only first chip', async () => {\n    const items = ['Item 1', 'Item 2', 'Item 3', 'Item 4']\n\n    const selectedItems = ['Item 1', 'Item 2', 'Item 3']\n\n    render(() => (\n      <VSelect\n        items={ items }\n        modelValue={ selectedItems }\n        chips\n        closableChips\n        multiple\n      />\n    ))\n\n    await userEvent.click(screen.getAllByTestId('close-chip')[0])\n    await expect.poll(() => screen.getAllByCSS('.v-chip')).toHaveLength(2)\n  })\n\n  describe('prefilled data', () => {\n    it('should work with array of strings when using multiple', async () => {\n      const items = ['California', 'Colorado', 'Florida']\n\n      const selectedItems = ref(['California', 'Colorado'])\n\n      const { element } = render(() => (\n        <VSelect v-model={ selectedItems.value } items={ items } multiple chips closableChips />\n      ))\n\n      await userEvent.click(element)\n      await expect(screen.findAllByRole('option', { selected: true })).resolves.toHaveLength(2)\n\n      const option = screen.getAllByRole('option')[2]\n      await waitForClickable(option)\n      await userEvent.click(option)\n      expect(selectedItems.value).toStrictEqual(['California', 'Colorado', 'Florida'])\n\n      await userEvent.click(screen.getAllByTestId('close-chip')[0])\n      expect(screen.getAllByCSS('.v-chip')).toHaveLength(2)\n      expect(selectedItems.value).toStrictEqual(['Colorado', 'Florida'])\n    })\n\n    it('should work with objects when using multiple', async () => {\n      const items = [\n        {\n          title: 'Item 1',\n          value: 'item1',\n        },\n        {\n          title: 'Item 2',\n          value: 'item2',\n        },\n        {\n          title: 'Item 3',\n          value: 'item3',\n        },\n      ]\n\n      const selectedItems = ref(\n        [\n          {\n            title: 'Item 1',\n            value: 'item1',\n          },\n          {\n            title: 'Item 2',\n            value: 'item2',\n          },\n        ]\n      )\n\n      const { element } = render(() => (\n        <VSelect\n          v-model={ selectedItems.value }\n          items={ items }\n          multiple\n          chips\n          closableChips\n          returnObject\n        />\n      ))\n\n      await userEvent.click(element)\n      await expect(screen.findAllByRole('option', { selected: true })).resolves.toHaveLength(2)\n      const option = screen.getAllByRole('option')[2]\n      await waitForClickable(option)\n      await userEvent.click(option)\n      expect(selectedItems.value).toStrictEqual([\n        {\n          title: 'Item 1',\n          value: 'item1',\n        },\n        {\n          title: 'Item 2',\n          value: 'item2',\n        },\n        {\n          title: 'Item 3',\n          value: 'item3',\n        },\n      ])\n\n      await userEvent.click(screen.getAllByTestId('close-chip')[0])\n      expect(screen.getAllByCSS('.v-chip')).toHaveLength(2)\n      expect(selectedItems.value).toStrictEqual([\n        {\n          title: 'Item 2',\n          value: 'item2',\n        },\n        {\n          title: 'Item 3',\n          value: 'item3',\n        },\n      ])\n    })\n\n    it('should work with objects when using multiple and item-value', async () => {\n      const items = [\n        {\n          text: 'Item 1',\n          id: 'item1',\n        },\n        {\n          text: 'Item 2',\n          id: 'item2',\n        },\n        {\n          text: 'Item 3',\n          id: 'item3',\n        },\n      ]\n\n      const selectedItems = ref([\n        {\n          text: 'Item 1',\n          id: 'item1',\n        },\n        {\n          text: 'Item 2',\n          id: 'item2',\n        },\n      ])\n\n      const { element } = render(() => (\n        <VSelect\n          v-model={ selectedItems.value }\n          items={ items }\n          multiple\n          returnObject\n          itemTitle=\"text\"\n          itemValue=\"id\"\n        />\n      ))\n\n      await userEvent.click(element)\n      await commands.waitStable('.v-list')\n      const options = screen.getAllByRole('option', { selected: true })\n      expect(options).toHaveLength(2)\n      expect(element).toHaveTextContent('Item 1')\n      expect(element).toHaveTextContent('Item 2')\n\n      await waitForClickable(options[0])\n      await userEvent.click(options[0])\n      expect(selectedItems.value).toStrictEqual([{\n        text: 'Item 2',\n        id: 'item2',\n      }])\n    })\n  })\n\n  it('should not be clickable when in readonly', async () => {\n    const items = ['Item 1', 'Item 2', 'Item 3', 'Item 4']\n\n    const selectedItems = 'Item 1'\n\n    const { element } = render(() => (\n      <VSelect\n        items={ items }\n        modelValue={ selectedItems }\n        readonly\n      />\n    ))\n\n    await userEvent.click(element)\n\n    expect(screen.queryAllByRole('option')).toHaveLength(0)\n    expect(screen.queryAllByRole('listbox')).toHaveLength(0)\n\n    await userEvent.keyboard('{ArrowDown}')\n    expect(screen.queryAllByRole('option')).toHaveLength(0)\n    expect(screen.queryAllByRole('listbox')).toHaveLength(0)\n  })\n\n  it('should not be clickable when in readonly form', async () => {\n    const items = ['Item 1', 'Item 2', 'Item 3', 'Item 4']\n\n    const selectedItems = 'Item 1'\n\n    const { element } = render(() => (\n      <VForm readonly>\n        <VSelect\n          items={ items }\n          modelValue={ selectedItems }\n          readonly\n        />\n      </VForm>\n    ))\n\n    await userEvent.click(element)\n\n    expect(screen.queryAllByRole('option')).toHaveLength(0)\n    expect(screen.queryAllByRole('listbox')).toHaveLength(0)\n\n    await userEvent.keyboard('{ArrowDown}')\n    expect(screen.queryAllByRole('option')).toHaveLength(0)\n    expect(screen.queryAllByRole('listbox')).toHaveLength(0)\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/16442\n  describe('null value', () => {\n    it('should allow null as legit itemValue', async () => {\n      const items = [\n        { name: 'Default Language', code: null },\n        { code: 'en-US', name: 'English' },\n        { code: 'de-DE', name: 'German' },\n      ]\n\n      const selectedItems = null\n\n      const { element } = render(() => (\n        <VSelect\n          items={ items }\n          modelValue={ selectedItems }\n          itemTitle=\"name\"\n          itemValue=\"code\"\n        />\n      ))\n      expect(element).toHaveTextContent('Default Language')\n    })\n    it('should mark input as \"not dirty\" when the v-model is null, but null is not present in the items', async () => {\n      const items = [\n        { code: 'en-US', name: 'English' },\n        { code: 'de-DE', name: 'German' },\n      ]\n\n      render(() => (\n        <VSelect\n          label=\"Language\"\n          items={ items }\n          modelValue={ null }\n          itemTitle=\"name\"\n          itemValue=\"code\"\n        />\n      ))\n      expect(screen.queryAllByCSS('.v-field--dirty')).toHaveLength(0)\n    })\n  })\n\n  it('should conditionally show placeholder', async () => {\n    const { rerender } = render(VSelect, {\n      props: { placeholder: 'Placeholder' },\n    })\n\n    const input = screen.getByCSS('input')\n    await expect.element(input).toHaveAttribute('placeholder', 'Placeholder')\n\n    await rerender({ label: 'Label' })\n    await expect.element(input).not.toHaveAttribute('placeholder')\n    input.focus()\n    await expect.element(input).toHaveAttribute('placeholder', 'Placeholder')\n    input.blur()\n    await expect.element(input).not.toHaveAttribute('placeholder')\n\n    await rerender({ persistentPlaceholder: true })\n    await expect.element(input).toHaveAttribute('placeholder', 'Placeholder')\n\n    await rerender({ modelValue: 'Foobar' })\n    await expect.element(input).not.toHaveAttribute('placeholder')\n\n    await rerender({ multiple: true, modelValue: ['Foobar'] })\n    await expect.element(input).not.toHaveAttribute('placeholder')\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/16210\n  it('should return item object as the argument of item-title function', async () => {\n    const items = [\n      { id: 1, name: 'a' },\n      { id: 2, name: 'b' },\n    ]\n\n    const selectedItems = ref(null)\n\n    const itemTitleFunc = vi.fn((item: any) => (\n      'Item: ' + JSON.stringify(item)\n    ))\n\n    const { element } = render(() => (\n      <VSelect\n        items={ items }\n        modelValue={ selectedItems }\n        itemTitle={ itemTitleFunc }\n        itemValue=\"id\"\n      />\n    ))\n\n    await userEvent.click(element)\n    await commands.waitStable('.v-list')\n    await userEvent.click(screen.getAllByRole('option')[0])\n    expect(selectedItems.value).toBe(1)\n    expect(itemTitleFunc).toHaveBeenCalledWith({ id: 1, name: 'a' }, expect.anything())\n    expect(element).toHaveTextContent(`Item: {\"id\":1,\"name\":\"a\"}`)\n  })\n\n  describe('hide-selected', () => {\n    it('should hide selected item(s)', async () => {\n      const items = ['Item 1', 'Item 2', 'Item 3', 'Item 4']\n\n      const selectedItems = ref(['Item 1', 'Item 2'])\n\n      const { element } = render(() => (\n        <VSelect v-model={ selectedItems.value } items={ items } multiple hideSelected />\n      ))\n\n      await userEvent.click(element)\n      await commands.waitStable('.v-list')\n      const options = screen.getAllByRole('option')\n      expect(options).toHaveLength(2)\n      expect(options[0]).toHaveTextContent('Item 3')\n      expect(options[1]).toHaveTextContent('Item 4')\n    })\n\n    // https://github.com/vuetifyjs/vuetify/issues/19806\n    it('should hide selected item(s) with return-object', async () => {\n      const selectedItem = ref({ text: 'Item 1', id: 'item1' })\n      const items = [\n        {\n          text: 'Item 1',\n          id: 'item1',\n        },\n        {\n          text: 'Item 2',\n          id: 'item2',\n        },\n        {\n          text: 'Item 3',\n          id: 'item3',\n        },\n      ]\n      const { element } = render(() => (\n        <VSelect\n          v-model={ selectedItem.value }\n          hideSelected\n          items={ items }\n          itemTitle=\"text\"\n          itemValue=\"id\"\n          returnObject\n        />\n      ))\n\n      await userEvent.click(element)\n      await commands.waitStable('.v-list')\n      expect(screen.queryAllByRole('option', { selected: true })).toHaveLength(0)\n      let options = screen.getAllByRole('option')\n      expect(options).toHaveLength(2)\n      expect(options[0]).toHaveTextContent('Item 2')\n\n      await waitForClickable(options[0])\n      await userEvent.click(options[0])\n      expect(selectedItem.value).toStrictEqual({ text: 'Item 2', id: 'item2' })\n      expect(screen.queryAllByRole('option', { selected: true })).toHaveLength(0)\n      options = screen.getAllByRole('option')\n      expect(options).toHaveLength(2)\n      expect(options[0]).toHaveTextContent('Item 1')\n    })\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/16055\n  it('should select item after typing its first few letters', async () => {\n    const items = ['aaa', 'foo', 'faa']\n    const selectedItems = ref()\n\n    const { element } = render(() => (\n      <VSelect\n        v-model={ selectedItems.value }\n        items={ items }\n      />\n    ))\n\n    await userEvent.click(element)\n    await commands.waitStable('.v-list')\n    await userEvent.keyboard('f')\n    expect(screen.getAllByRole('option')).toHaveLength(3)\n    expect(selectedItems.value).toBe('foo')\n  })\n\n  it('should keep TextField focused while selecting items from open menu', async () => {\n    const { element } = render(() => (\n      <VSelect\n        items={['California', 'Colorado', 'Florida', 'Georgia', 'Texas', 'Wyoming']}\n      />\n    ))\n\n    await userEvent.click(element)\n    await commands.waitStable('.v-list')\n    await userEvent.keyboard('{ArrowDown}')\n    await userEvent.keyboard('{ArrowDown}')\n    await userEvent.keyboard('{ArrowDown}')\n    expect(screen.getByCSS('.v-field')).toHaveClass('v-field--focused')\n  })\n\n  it('should not open menu when closing a chip', async () => {\n    const { element } = render(() => (\n      <VSelect\n        chips\n        closableChips\n        items={['foo', 'bar']}\n        label=\"Select\"\n        modelValue={['foo', 'bar']}\n        multiple\n      />\n    ))\n\n    await expect.poll(() => screen.queryByRole('listbox')).toBeNull()\n    await userEvent.click(screen.getAllByTestId('close-chip')[1])\n    await expect.poll(() => screen.queryByRole('listbox')).toBeNull()\n    await userEvent.click(screen.getByTestId('close-chip'))\n    await expect.poll(() => screen.queryByRole('listbox')).toBeNull()\n    await userEvent.click(element)\n    await expect.poll(() => screen.queryByRole('listbox')).toBeVisible()\n    await userEvent.keyboard('{Escape}')\n    await expect.poll(() => screen.queryByRole('listbox')).toBeNull()\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/19235\n  it('should update v-model when click closable chip', async () => {\n    const selectedItem = ref('abc')\n\n    render(() => (\n      <VSelect\n        v-model={ selectedItem.value }\n        chips\n        closableChips\n        items={['abc', 'def']}\n      />\n    ))\n\n    await userEvent.click(screen.getByTestId('close-chip'))\n    expect(selectedItem.value).toBeNull()\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/19261\n  it('should not toggle v-model to null when clicking already selected item in single selection mode', async () => {\n    const selectedItem = ref('abc')\n\n    const { element } = render(() => (\n      <VSelect\n        v-model={ selectedItem.value }\n        items={['abc', 'def']}\n      />\n    ))\n\n    await userEvent.click(element)\n    await commands.waitStable('.v-list')\n    const options = screen.getAllByRole('option')\n    expect(options).toHaveLength(2)\n    await userEvent.click(options[0])\n    expect(selectedItem.value).toBe('abc')\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/18556\n  // https://github.com/vuetifyjs/vuetify/issues/21205\n  it('should show menu if focused and items are added when hideNoData is true\"', async () => {\n    const items = ref()\n    render(() => <VSelect items={ items.value } hideNoData />)\n\n    await userEvent.keyboard('{Tab}')\n    expect(screen.queryByRole('listbox')).toBeNull()\n\n    items.value = ['Foo', 'Bar']\n    await nextTick()\n    await expect.poll(() => screen.queryByRole('listbox')).toBeVisible()\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/21205\n  it('should not show menu if focused and items are added when hideNoData is false', async () => {\n    const items = ref()\n    render(() => <VSelect items={ items.value } />)\n\n    await userEvent.keyboard('{Tab}')\n    expect(screen.queryByRole('listbox')).toBeNull()\n\n    items.value = ['Foo', 'Bar']\n    await nextTick()\n    await expect.poll(() => screen.queryByRole('listbox')).toBeNull()\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/19346\n  it('should not show menu when focused and existing non-empty items are changed', async () => {\n    const { element, rerender } = render(VSelect, {\n      props: { items: ['Foo', 'Bar'] },\n    })\n\n    await userEvent.click(element)\n    await expect.poll(() => screen.queryByRole('listbox')).toBeVisible()\n    await userEvent.click(screen.getAllByRole('option')[0])\n\n    await rerender({ items: ['Foo', 'Bar', 'test', 'test 2'] })\n    await expect.poll(() => screen.queryByRole('listbox')).toBeNull()\n  })\n\n  describe('reactivity', () => {\n    it('adds a new item', async () => {\n      const items = ref(['Foo'])\n      const { element } = render(() => (\n        <VSelect items={ items.value } />\n      ))\n\n      await userEvent.click(element)\n      await expect.poll(() => screen.queryByRole('listbox')).toBeVisible()\n\n      items.value.push('Bar')\n      await expect.poll(() => screen.getByText('Bar')).toBeVisible()\n    })\n\n    it('removes an item', async () => {\n      const items = ref(['Foo', 'Bar'])\n      const { element } = render(() => (\n        <VSelect items={ items.value } />\n      ))\n\n      await userEvent.click(element)\n      await expect.poll(() => screen.queryByRole('listbox')).toBeVisible()\n\n      items.value.splice(1, 1)\n      await expect.element(screen.getByText('Bar')).not.toBeVisible()\n    })\n\n    it('updates an item title', async () => {\n      const items = ref([{ title: 'Foo' }])\n      const { element } = render(() => (\n        <VSelect items={ items.value } />\n      ))\n\n      await userEvent.click(element)\n      await expect.poll(() => screen.queryByRole('listbox')).toBeVisible()\n\n      items.value[0].title = 'Bar'\n      await expect.poll(() => screen.getByText('Bar')).toBeVisible()\n    })\n\n    it('adds a selection externally', async () => {\n      const items = ref(['Foo', 'Bar'])\n      const selection = ref(['Foo'])\n      const { element } = render(() => (\n        <VSelect v-model={ selection.value } items={ items.value } multiple />\n      ))\n\n      await userEvent.click(element)\n      const menu = await screen.findByRole('listbox')\n      await expect.element(menu).toBeVisible()\n\n      selection.value.push('Bar')\n      await expect.poll(() => screen.getAllByText('Bar')).toHaveLength(2)\n      expect(getAllByRole(menu, 'option', { selected: true })).toHaveLength(2)\n    })\n\n    it('removes a selection externally', async () => {\n      const items = ref(['Foo', 'Bar'])\n      const selection = ref(['Foo', 'Bar'])\n      const { element } = render(() => (\n        <VSelect v-model={ selection.value } items={ items.value } multiple />\n      ))\n\n      await userEvent.click(element)\n      const menu = await screen.findByRole('listbox')\n      await expect.element(menu).toBeVisible()\n\n      selection.value.splice(1, 1)\n      await expect.poll(() => screen.getAllByText('Bar')).toHaveLength(1)\n      expect(getAllByRole(menu, 'option', { selected: true })).toHaveLength(1)\n    })\n\n    it('adds a selected item', async () => {\n      const items = ref(['Foo'])\n      const selection = ref(['Foo'])\n      const { element } = render(() => (\n        <VSelect v-model={ selection.value } items={ items.value } multiple />\n      ))\n\n      await userEvent.click(element)\n      const menu = await screen.findByRole('listbox')\n      await expect.element(menu).toBeVisible()\n\n      items.value.push('Bar')\n      selection.value.push('Bar')\n      await expect.poll(() => screen.getAllByText('Bar')).toHaveLength(2)\n      expect(getAllByRole(menu, 'option', { selected: true })).toHaveLength(2)\n    })\n\n    it('should not fire @update:focus twice when clicking bottom of input', async () => {\n      const onFocus = vi.fn()\n      const { element } = render(() => (\n        <VSelect onUpdate:focused={ onFocus } />\n      ))\n\n      await userEvent.click(element, { position: { x: 10, y: 55 } })\n\n      expect(onFocus).toHaveBeenCalledTimes(1)\n    })\n  })\n\n  it('should have reactive accessibility attributes', async () => {\n    const { getByRole } = render(() => (\n      <VSelect items={['Foo']} />\n    ))\n\n    const inputField = getByRole('combobox', { expanded: false })\n    expect(inputField).toHaveAttribute('aria-expanded', 'false')\n    expect(inputField.getAttribute('aria-controls')).toMatch(/^menu-v-\\d+/)\n\n    await userEvent.click(inputField, { force: true })\n    await commands.waitStable('.v-list')\n\n    expect(inputField).toHaveAttribute('aria-expanded', 'true')\n\n    await commands.waitStable('.v-list')\n    await userEvent.click(screen.getAllByRole('option')[0])\n\n    expect(inputField).toHaveAttribute('aria-expanded', 'false')\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/22052\n  it('should keep the checkboxes in sync with the model', async () => {\n    const items = [\n      { title: 'Both', value: 'both' },\n      { title: 'Option A', value: 'a' },\n      { title: 'Option B', value: 'b' },\n    ]\n\n    const model = ref<string[]>([])\n    const selectModel = computed({\n      get: () => model.value.length === 2 ? ['both'] : model.value,\n      set: val => model.value = val.includes('both') ? ['a', 'b'] : val,\n    })\n\n    const { element } = render(() => (\n      <VSelect\n        v-model={ selectModel.value }\n        items={ items }\n        multiple\n        itemProps={ (item: any) =>\n          (selectModel.value?.includes('both') && item.value !== 'both') ? { disabled: true } : {}\n        }\n      />\n    ))\n\n    await userEvent.click(element)\n    await commands.waitStable('.v-list')\n\n    const options = screen.getAllByRole('option')\n    expect(options).toHaveLength(3)\n\n    await userEvent.click(screen.getAllByCSS('.v-checkbox-btn input')[1])\n    await userEvent.click(screen.getAllByCSS('.v-checkbox-btn input')[2])\n\n    await expect.poll(() => model.value).toStrictEqual(['a', 'b'])\n    expect(selectModel.value).toStrictEqual(['both'])\n    expect(screen.getAllByCSS('.v-checkbox-btn input')[0]).toBeChecked()\n    expect(screen.getAllByCSS('.v-checkbox-btn input:checked')).toHaveLength(1)\n  })\n\n  describe('clear with backspace', () => {\n    it('should clear selection in single selection mode', async () => {\n      const selectedItem = ref('Item 1')\n\n      const { element } = render(() => (\n        <VSelect\n          clearable\n          v-model={ selectedItem.value }\n          items={['Item 1', 'Item 2', 'Item 3']}\n        />\n      ))\n\n      expect(selectedItem.value).toBe('Item 1')\n\n      await userEvent.click(element)\n      await userEvent.keyboard('{Backspace}')\n\n      expect(selectedItem.value).toBeNull()\n    })\n\n    it('should clear selection in multiple selection mode', async () => {\n      const selectedItems = ref(['Item 1', 'Item 2'])\n\n      const { element } = render(() => (\n        <VSelect\n          clearable\n          v-model={ selectedItems.value }\n          items={['Item 1', 'Item 2', 'Item 3']}\n          multiple\n        />\n      ))\n\n      expect(selectedItems.value).toHaveLength(2)\n\n      await userEvent.click(element)\n      await userEvent.keyboard('{Backspace}')\n\n      expect(selectedItems.value).toHaveLength(0)\n    })\n\n    it('should open menu with openOnClear prop', async () => {\n      const selectedItem = ref('Item 1')\n\n      const { element } = render(() => (\n        <VSelect\n          clearable\n          v-model={ selectedItem.value }\n          items={['Item 1', 'Item 2', 'Item 3']}\n          openOnClear\n        />\n      ))\n\n      expect(selectedItem.value).toBe('Item 1')\n      expect(screen.queryByRole('listbox')).toBeNull()\n\n      await userEvent.click(element)\n      await userEvent.keyboard('{Backspace}')\n\n      expect(selectedItem.value).toBeNull()\n      await expect.poll(() => screen.queryByRole('listbox')).toBeVisible()\n    })\n\n    it('should not clear in readonly mode', async () => {\n      const selectedItem = ref('Item 1')\n\n      const { element } = render(() => (\n        <VSelect\n          clearable\n          v-model={ selectedItem.value }\n          items={['Item 1', 'Item 2', 'Item 3']}\n          readonly\n        />\n      ))\n\n      expect(selectedItem.value).toBe('Item 1')\n\n      await userEvent.click(element)\n      await userEvent.keyboard('{Backspace}')\n\n      expect(selectedItem.value).toBe('Item 1')\n    })\n  })\n\n  describe('native form submission', () => {\n    const items = [\n      { title: 'Item 1', value: 1 },\n      { title: 'Item 2', value: 2 },\n      { title: 'Item 3', value: 3 },\n    ]\n\n    it('should include selected value in form data for single selection', async () => {\n      let submittedData: FormData | null = null\n\n      render(() => (\n        <form\n          onSubmit={ e => {\n            e.preventDefault()\n            submittedData = new FormData(e.target as HTMLFormElement)\n          }}\n        >\n          <VSelect\n            name=\"select\"\n            items={ items }\n            modelValue={ items[0] }\n          />\n          <button type=\"submit\">Submit</button>\n        </form>\n      ))\n\n      const submitButton = screen.getByRole('button', { name: 'Submit' })\n      await userEvent.click(submitButton)\n\n      expect(submittedData).not.toBeNull()\n      expect(submittedData!.get('select')).toBe('1')\n    })\n\n    it('should include selected values in form data for multiple selection', async () => {\n      let submittedData: FormData | null = null\n\n      render(() => (\n        <form\n          onSubmit={ e => {\n            e.preventDefault()\n            submittedData = new FormData(e.target as HTMLFormElement)\n          }}\n        >\n          <VSelect\n            multiple\n            name=\"select\"\n            items={ items }\n            modelValue={[items[0], items[1]]}\n          />\n          <button type=\"submit\">Submit</button>\n        </form>\n      ))\n\n      const submitButton = screen.getByRole('button', { name: 'Submit' })\n      await userEvent.click(submitButton)\n\n      expect(submittedData).not.toBeNull()\n      const select = submittedData!.getAll('select')\n      expect(select).toHaveLength(2)\n      expect(select).toContain('1')\n      expect(select).toContain('2')\n    })\n  })\n\n  describe('menu-header and menu-footer slots', () => {\n    it('should render menu-header and menu-footer slots', async () => {\n      const { element } = render(() => (\n        <VSelect menu items={['Item #1', 'Item #2']}>\n          {{\n            'menu-header': () => (\n              <div data-testid=\"header-content\">My Header</div>\n            ),\n            'menu-footer': () => (\n              <div data-testid=\"footer-content\">My Footer</div>\n            ),\n          }}\n        </VSelect>\n      ))\n\n      await userEvent.click(element)\n      await commands.waitStable('.v-list')\n\n      expect(screen.getByTestId('header-content')).toHaveTextContent('My Header')\n      expect(screen.getByTestId('footer-content')).toHaveTextContent('My Footer')\n    })\n\n    it('should navigate freely between interactive elements with Tab', async () => {\n      const { element } = render(() => (\n        <VSelect items={ Array.from({ length: 20 }, (_, i) => `Item #${i + 1}`) }>\n          {{\n            'menu-header': () => (\n              <div>\n                <VTextField data-testid=\"textfield-1\" placeholder=\"Search...\" />\n              </div>\n            ),\n            'menu-footer': () => (\n              <div class=\"d-flex justify-between\">\n                <button data-testid=\"button-1\">Button 1</button>\n                <button data-testid=\"button-2\">Button 2</button>\n              </div>\n            ),\n          }}\n        </VSelect>\n      ))\n\n      await userEvent.click(element, { force: true })\n      await commands.waitStable('.v-list')\n\n      const menu = await screen.findByRole('listbox')\n      await expect.element(menu).toBeVisible()\n\n      await waitFor(() => {\n        expect(screen.getAllByRole('option').at(0)).toHaveFocus()\n      }, { timeout: 3000 })\n\n      await wait(400)\n      await userEvent.keyboard('{Tab}')\n      expect(screen.getByTestId('button-1')).toHaveFocus()\n\n      await userEvent.keyboard('{Tab}')\n      expect(screen.getByTestId('button-2')).toHaveFocus()\n\n      // Tab past footer closes menu\n      await userEvent.keyboard('{Tab}')\n      await expect.poll(() => screen.queryByRole('listbox')).toBeNull()\n    })\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/22697\n  it('should not steal focus from another input when menu closes', async () => {\n    render(() => (\n      <div>\n        <VTextField label=\"Text\" data-testid=\"textfield\" />\n        <VSelect label=\"Select\" items={['Item 1', 'Item 2']} />\n      </div>\n    ))\n\n    await userEvent.click(screen.getByCSS('.v-select'))\n    await commands.waitStable('.v-list')\n\n    await waitFor(() => {\n      expect(screen.getAllByRole('option').at(0)).toHaveFocus()\n    }, { timeout: 3000 })\n\n    const textfield = screen.getByTestId('textfield')\n    await userEvent.click(textfield)\n\n    await expect.poll(() => screen.queryByRole('listbox')).toBeNull()\n    await wait(300)\n\n    expect(textfield.querySelector('input')).toHaveFocus()\n    expect(screen.getByCSS('.v-select .v-field')).not.toHaveClass('v-field--focused')\n  })\n\n  showcase({ stories })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VSelect/_mixins.scss",
    "content": "@mixin select-compact-chip-label {\n  &--chips.v-input--density-compact {\n    .v-field--variant-solo,\n    .v-field--variant-solo-inverted,\n    .v-field--variant-filled,\n    .v-field--variant-solo-filled {\n      .v-label.v-field-label {\n        &--floating {\n          top: 0px;\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VSelect/_variables.scss",
    "content": "@use '../../styles/settings';\n\n// Defaults\n$select-content-border-radius: 4px !default;\n$select-content-elevation: 2 !default;\n$select-line-height: 1.75 !default;\n$select-transition: .2s settings.$standard-easing !default;\n$select-chips-control-min-height: null !default;\n$select-chips-margin-top: null !default;\n$select-chips-margin-bottom: null !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VSelect/index.ts",
    "content": "export { VSelect } from './VSelect'\n"
  },
  {
    "path": "packages/vuetify/src/components/VSelect/useScrolling.ts",
    "content": "// Utilities\nimport { shallowRef, watch } from 'vue'\n\n// Types\nimport type { Ref } from 'vue'\nimport type { VList } from '@/components/VList'\nimport type { VTextField } from '@/components/VTextField'\n\nexport function useScrolling (listRef: Ref<VList | undefined>, textFieldRef: Ref<VTextField | undefined>) {\n  const isScrolling = shallowRef(false)\n  let scrollTimeout: number\n  function onListScroll (e: Event) {\n    cancelAnimationFrame(scrollTimeout)\n    isScrolling.value = true\n    scrollTimeout = requestAnimationFrame(() => {\n      scrollTimeout = requestAnimationFrame(() => {\n        isScrolling.value = false\n      })\n    })\n  }\n  async function finishScrolling () {\n    await new Promise(resolve => requestAnimationFrame(resolve))\n    await new Promise(resolve => requestAnimationFrame(resolve))\n    await new Promise(resolve => requestAnimationFrame(resolve))\n    await new Promise<void>(resolve => {\n      if (isScrolling.value) {\n        const stop = watch(isScrolling, () => {\n          stop()\n          resolve()\n        })\n      } else resolve()\n    })\n  }\n  async function onListKeydown (e: KeyboardEvent) {\n    if (e.key === 'Tab') {\n      textFieldRef.value?.focus()\n    }\n\n    if (!['PageDown', 'PageUp', 'Home', 'End'].includes(e.key)) return\n    const el: HTMLElement = listRef.value?.$el\n    if (!el) return\n\n    if (e.key === 'Home' || e.key === 'End') {\n      el.scrollTo({\n        top: e.key === 'Home' ? 0 : el.scrollHeight,\n        behavior: 'smooth',\n      })\n    }\n\n    await finishScrolling()\n\n    const children = el.querySelectorAll(':scope > :not(.v-virtual-scroll__spacer)')\n\n    if (e.key === 'PageDown' || e.key === 'Home') {\n      const top = el.getBoundingClientRect().top\n      for (const child of children) {\n        if (child.getBoundingClientRect().top >= top) {\n          (child as HTMLElement).focus()\n          break\n        }\n      }\n    } else {\n      const bottom = el.getBoundingClientRect().bottom\n      for (const child of [...children].reverse()) {\n        if (child.getBoundingClientRect().bottom <= bottom) {\n          (child as HTMLElement).focus()\n          break\n        }\n      }\n    }\n  }\n\n  return {\n    onScrollPassive: onListScroll,\n    onKeydown: onListKeydown,\n  } as Record<string, Function> // typescript doesn't know about vue's event merging\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VSelectionControl/VSelectionControl.sass",
    "content": "@use 'sass:map'\n@use 'sass:list'\n@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-selection-control\n    align-items: center\n    contain: layout\n    display: flex\n    flex: 1 0\n    grid-area: control\n    position: relative\n    user-select: none\n\n    .v-label\n      white-space: normal\n      word-break: break-word\n      height: 100%\n      opacity: 1\n\n    &--disabled\n      opacity: var(--v-disabled-opacity)\n      pointer-events: none\n\n    &--error:not(.v-selection-control--disabled)\n      .v-label\n        color: rgb(var(--v-theme-error))\n\n    &--inline\n      display: inline-flex\n      flex: 0 0 auto\n      min-width: 0\n      max-width: 100%\n\n      .v-label\n        width: auto\n\n    @at-root\n      @include tools.density('v-selection-control', $selection-control-density) using ($modifier)\n        --v-selection-control-size: #{$selection-control-size + $modifier}\n\n  .v-selection-control__wrapper\n    width: var(--v-selection-control-size)\n    height: var(--v-selection-control-size)\n    display: inline-flex\n    align-items: center\n    position: relative\n    justify-content: center\n    flex: none\n\n  .v-selection-control__input\n    width: var(--v-selection-control-size)\n    height: var(--v-selection-control-size)\n    align-items: center\n    display: flex\n    flex: none\n    justify-content: center\n    position: relative\n    border-radius: 50%\n\n    input\n      cursor: pointer\n      position: absolute\n      left: 0\n      top: 0\n      width: 100%\n      height: 100%\n      opacity: 0\n\n    &::before\n      border-radius: 100%\n      background-color: currentColor\n      opacity: 0\n      pointer-events: none\n      @include tools.absolute(true)\n\n    &:hover::before\n      opacity: calc(#{map.get(settings.$states, 'hover')} * var(--v-theme-overlay-multiplier))\n\n    > .v-icon\n      opacity: var(--v-medium-emphasis-opacity)\n\n    .v-selection-control--disabled &,\n    .v-selection-control--dirty &,\n    .v-selection-control--error &\n      > .v-icon\n        opacity: 1\n\n    .v-selection-control--error:not(.v-selection-control--disabled) &\n      > .v-icon\n        color: rgb(var(--v-theme-error))\n\n    .v-selection-control--focus-visible &::before\n      opacity: calc(#{map.get(settings.$states, 'focus')} * var(--v-theme-overlay-multiplier))\n"
  },
  {
    "path": "packages/vuetify/src/components/VSelectionControl/VSelectionControl.tsx",
    "content": "// Styles\nimport './VSelectionControl.sass'\n\n// Components\nimport { VIcon } from '@/components/VIcon'\nimport { VLabel } from '@/components/VLabel'\nimport { makeSelectionControlGroupProps, VSelectionControlGroupSymbol } from '@/components/VSelectionControlGroup/VSelectionControlGroup'\n\n// Composables\nimport { useBackgroundColor, useTextColor } from '@/composables/color'\nimport { makeComponentProps } from '@/composables/component'\nimport { useDensity } from '@/composables/density'\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Directives\nimport vRipple from '@/directives/ripple'\n\n// Utilities\nimport { computed, inject, nextTick, ref, shallowRef, toRef, useId } from 'vue'\nimport {\n  filterInputAttrs,\n  genericComponent,\n  matchesSelector,\n  propsFactory,\n  useRender,\n  wrapInArray,\n} from '@/util'\n\n// Types\nimport type { CSSProperties, ExtractPropTypes, Ref, VNode, WritableComputedRef } from 'vue'\nimport type { IconValue } from '@/composables/icons'\nimport type { EventProp, GenericProps } from '@/util'\n\nexport type SelectionControlSlot = {\n  model: WritableComputedRef<boolean>\n  textColorClasses: Ref<string[]>\n  textColorStyles: Ref<CSSProperties>\n  backgroundColorClasses: Ref<string[]>\n  backgroundColorStyles: Ref<CSSProperties>\n  inputNode: VNode\n  icon: IconValue | undefined\n  props: {\n    onBlur: (e: Event) => void\n    onFocus: (e: FocusEvent) => void\n    id: string\n  }\n}\n\nexport type VSelectionControlSlots = {\n  default: {\n    backgroundColorClasses: Ref<string[]>\n    backgroundColorStyles: Ref<CSSProperties>\n  }\n  label: { label: string | undefined, props: Record<string, unknown> }\n  input: SelectionControlSlot\n}\n\nexport const makeVSelectionControlProps = propsFactory({\n  label: String,\n  baseColor: String,\n  trueValue: null,\n  falseValue: null,\n  value: null,\n\n  ...makeComponentProps(),\n  ...makeSelectionControlGroupProps(),\n}, 'VSelectionControl')\n\nexport function useSelectionControl (\n  props: ExtractPropTypes<ReturnType<typeof makeVSelectionControlProps>> & {\n    'onUpdate:modelValue': EventProp | undefined\n  }\n) {\n  const group = inject(VSelectionControlGroupSymbol, undefined)\n  const { densityClasses } = useDensity(props)\n  const modelValue = useProxiedModel(props, 'modelValue')\n  const trueValue = computed(() => (\n    props.trueValue !== undefined ? props.trueValue\n    : props.value !== undefined ? props.value\n    : true\n  ))\n  const falseValue = computed(() => props.falseValue !== undefined ? props.falseValue : false)\n  const isMultiple = computed(() => (\n    !!props.multiple ||\n    (props.multiple == null && Array.isArray(modelValue.value))\n  ))\n  const model = computed({\n    get () {\n      const val = group ? group.modelValue.value : modelValue.value\n\n      return isMultiple.value\n        ? wrapInArray(val).some((v: any) => props.valueComparator(v, trueValue.value))\n        : props.valueComparator(val, trueValue.value)\n    },\n    set (val: boolean) {\n      if (props.readonly) return\n\n      const currentValue = val ? trueValue.value : falseValue.value\n\n      let newVal = currentValue\n\n      if (isMultiple.value) {\n        newVal = val\n          ? [...wrapInArray(modelValue.value), currentValue]\n          : wrapInArray(modelValue.value).filter((item: any) => !props.valueComparator(item, trueValue.value))\n      }\n\n      if (group) {\n        group.modelValue.value = newVal\n      } else {\n        modelValue.value = newVal\n      }\n    },\n  })\n  const { textColorClasses, textColorStyles } = useTextColor(() => {\n    if (props.error || props.disabled) return undefined\n\n    return model.value ? props.color : props.baseColor\n  })\n  const { backgroundColorClasses, backgroundColorStyles } = useBackgroundColor(() => {\n    return (\n      model.value &&\n      !props.error &&\n      !props.disabled\n    ) ? props.color : props.baseColor\n  })\n  const icon = computed(() => model.value ? props.trueIcon : props.falseIcon)\n\n  return {\n    group,\n    densityClasses,\n    trueValue,\n    falseValue,\n    model,\n    textColorClasses,\n    textColorStyles,\n    backgroundColorClasses,\n    backgroundColorStyles,\n    icon,\n  }\n}\n\nexport const VSelectionControl = genericComponent<new <T>(\n  props: {\n    modelValue?: T\n    'onUpdate:modelValue'?: (value: T) => void\n  },\n  slots: VSelectionControlSlots,\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VSelectionControl',\n\n  directives: { vRipple },\n\n  inheritAttrs: false,\n\n  props: makeVSelectionControlProps(),\n\n  emits: {\n    'update:modelValue': (value: any) => true,\n  },\n\n  setup (props, { attrs, slots }) {\n    const {\n      group,\n      densityClasses,\n      icon,\n      model,\n      textColorClasses,\n      textColorStyles,\n      backgroundColorClasses,\n      backgroundColorStyles,\n      trueValue,\n    } = useSelectionControl(props)\n    const uid = useId()\n    const isFocused = shallowRef(false)\n    const isFocusVisible = shallowRef(false)\n    const input = ref<HTMLInputElement>()\n    const id = toRef(() => props.id || `input-${uid}`)\n    const isInteractive = toRef(() => !props.disabled && !props.readonly)\n\n    group?.onForceUpdate(() => {\n      if (input.value) {\n        input.value.checked = model.value\n      }\n    })\n\n    function onFocus (e: FocusEvent) {\n      if (!isInteractive.value) return\n\n      isFocused.value = true\n      if (matchesSelector(e.target as HTMLElement, ':focus-visible') !== false) {\n        isFocusVisible.value = true\n      }\n    }\n\n    function onBlur () {\n      isFocused.value = false\n      isFocusVisible.value = false\n    }\n\n    function onClickLabel (e: Event) {\n      e.stopPropagation()\n    }\n\n    function onInput (e: Event) {\n      if (!isInteractive.value) {\n        if (input.value) {\n          // model value is not updated when input is not interactive\n          // but the internal checked state of the input is still updated,\n          // so here it's value is restored\n          input.value.checked = model.value\n        }\n\n        return\n      }\n\n      if (props.readonly && group) {\n        nextTick(() => group.forceUpdate())\n      }\n      model.value = (e.target as HTMLInputElement).checked\n    }\n\n    useRender(() => {\n      const label = slots.label\n        ? slots.label({\n          label: props.label,\n          props: { for: id.value },\n        })\n        : props.label\n      const [rootAttrs, inputAttrs] = filterInputAttrs(attrs)\n\n      const inputNode = (\n        <input\n          ref={ input }\n          checked={ model.value }\n          disabled={ !!props.disabled }\n          id={ id.value }\n          onBlur={ onBlur }\n          onFocus={ onFocus }\n          onInput={ onInput }\n          aria-disabled={ !!props.disabled }\n          aria-label={ props.label }\n          type={ props.type }\n          value={ trueValue.value }\n          name={ props.name }\n          aria-checked={ props.type === 'checkbox' ? model.value : undefined }\n          { ...inputAttrs }\n        />\n      )\n\n      return (\n        <div\n          class={[\n            'v-selection-control',\n            {\n              'v-selection-control--dirty': model.value,\n              'v-selection-control--disabled': props.disabled,\n              'v-selection-control--error': props.error,\n              'v-selection-control--focused': isFocused.value,\n              'v-selection-control--focus-visible': isFocusVisible.value,\n              'v-selection-control--inline': props.inline,\n            },\n            densityClasses.value,\n            props.class,\n          ]}\n          { ...rootAttrs }\n          style={ props.style }\n        >\n          <div\n            class={[\n              'v-selection-control__wrapper',\n              textColorClasses.value,\n            ]}\n            style={ textColorStyles.value }\n          >\n            { slots.default?.({\n              backgroundColorClasses,\n              backgroundColorStyles,\n            })}\n\n            <div\n              class={[\n                'v-selection-control__input',\n              ]}\n              v-ripple={[\n                !props.disabled && !props.readonly && props.ripple,\n                null,\n                ['center', 'circle'],\n              ]}\n            >\n              { slots.input?.({\n                model,\n                textColorClasses,\n                textColorStyles,\n                backgroundColorClasses,\n                backgroundColorStyles,\n                inputNode,\n                icon: icon.value,\n                props: {\n                  onFocus,\n                  onBlur,\n                  id: id.value,\n                },\n              } satisfies SelectionControlSlot) ?? (\n                <>\n                  { icon.value && <VIcon key=\"icon\" icon={ icon.value } /> }\n\n                  { inputNode }\n                </>\n              )}\n            </div>\n          </div>\n\n          { label && (\n            <VLabel for={ id.value } onClick={ onClickLabel }>\n              { label }\n            </VLabel>\n          )}\n        </div>\n      )\n    })\n\n    return {\n      isFocused,\n      input,\n    }\n  },\n})\n\nexport type VSelectionControl = InstanceType<typeof VSelectionControl>\n"
  },
  {
    "path": "packages/vuetify/src/components/VSelectionControl/__tests__/VSelectionControl.spec.tsx",
    "content": "// Components\nimport { makeVSelectionControlProps, useSelectionControl } from '../VSelectionControl'\n\n// Utilities\nimport { mount } from '@vue/test-utils'\nimport { defineComponent, nextTick } from 'vue'\nimport { createVuetify } from '@/framework'\n\ndescribe('VSelectionControl', () => {\n  const vuetify = createVuetify()\n\n  function mountFunction (options = {}) {\n    return mount(defineComponent({\n      props: makeVSelectionControlProps(),\n      setup (props) {\n        return useSelectionControl(props as any)\n      },\n      render: () => undefined,\n    }), {\n      global: { plugins: [vuetify] },\n      ...options,\n    })\n  }\n\n  it('should use value', async () => {\n    const wrapper = mountFunction({\n      props: {\n        value: 'foo',\n      },\n    })\n    expect(wrapper.vm.model).toBe(false)\n    wrapper.setProps({ modelValue: 'foo' })\n    await nextTick()\n    expect(wrapper.vm.model).toBe(true)\n  })\n\n  it('should use trueValue', async () => {\n    const update = vi.fn()\n    const wrapper = mountFunction({\n      props: {\n        trueValue: 'on',\n        falseValue: 'off',\n        modelValue: 'off',\n        'onUpdate:modelValue': update,\n      },\n    })\n    expect(wrapper.vm.model).toBe(false)\n    wrapper.vm.model = true\n    expect(update).toHaveBeenCalledTimes(1)\n    expect(update).toHaveBeenCalledWith('on')\n  })\n\n  it('should use falseValue', async () => {\n    const update = vi.fn()\n    const wrapper = mountFunction({\n      props: {\n        trueValue: 'on',\n        falseValue: 'off',\n        modelValue: 'on',\n        'onUpdate:modelValue': update,\n      },\n    })\n    expect(wrapper.vm.model).toBe(true)\n    wrapper.vm.model = false\n    await nextTick()\n    expect(update).toHaveBeenCalledTimes(1)\n    expect(update).toHaveBeenCalledWith('off')\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VSelectionControl/_variables.scss",
    "content": "@use 'sass:map';\n@use '../../styles/settings';\n@use '../../styles/tools';\n\n// VSelectionControl\n$selection-control-disabled-color: tools.theme-color('on-surface', var(--v-disabled-opacity)) !default;\n$selection-control-error-color: rgb(var(--v-theme-error)) !default;\n$selection-control-density: ('default': 0, 'comfortable': -1, 'compact': -3) !default;\n$selection-control-color: tools.theme-color('on-surface', var(--v-high-emphasis-opacity)) !default;\n$selection-control-size: 40px !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VSelectionControl/index.ts",
    "content": "export { VSelectionControl } from './VSelectionControl'\n"
  },
  {
    "path": "packages/vuetify/src/components/VSelectionControlGroup/VSelectionControlGroup.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-selection-control-group\n    grid-area: $selection-control-group-grid-area\n    display: flex\n    flex-direction: column\n\n    &--inline\n      flex-direction: row\n      flex-wrap: wrap\n"
  },
  {
    "path": "packages/vuetify/src/components/VSelectionControlGroup/VSelectionControlGroup.tsx",
    "content": "// Styles\nimport './VSelectionControlGroup.sass'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { provideDefaults } from '@/composables/defaults'\nimport { makeDensityProps } from '@/composables/density'\nimport { IconValue } from '@/composables/icons'\nimport { useProxiedModel } from '@/composables/proxiedModel'\nimport { makeThemeProps } from '@/composables/theme'\n\n// Utilities\nimport { onScopeDispose, provide, toRef, useId } from 'vue'\nimport { deepEqual, genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { InjectionKey, PropType, Ref } from 'vue'\nimport type { RippleDirectiveBinding } from '@/directives/ripple'\nimport type { GenericProps, ValueComparator } from '@/util'\n\nexport interface VSelectionGroupContext {\n  modelValue: Ref<any>\n  forceUpdate: () => void\n  onForceUpdate: (fn: () => void) => void\n}\n\nexport const VSelectionControlGroupSymbol: InjectionKey<VSelectionGroupContext> = Symbol.for('vuetify:selection-control-group')\n\nexport const makeSelectionControlGroupProps = propsFactory({\n  color: String,\n  disabled: {\n    type: Boolean as PropType<boolean | null>,\n    default: null,\n  },\n  defaultsTarget: String,\n  error: Boolean,\n  id: String,\n  inline: Boolean,\n  falseIcon: IconValue,\n  trueIcon: IconValue,\n  ripple: {\n    type: [Boolean, Object] as PropType<RippleDirectiveBinding['value']>,\n    default: true,\n  },\n  multiple: {\n    type: Boolean as PropType<boolean | null>,\n    default: null,\n  },\n  name: String,\n  readonly: {\n    type: Boolean as PropType<boolean | null>,\n    default: null,\n  },\n  modelValue: null,\n  type: String,\n  valueComparator: {\n    type: Function as PropType<ValueComparator>,\n    default: deepEqual,\n  },\n\n  ...makeComponentProps(),\n  ...makeDensityProps(),\n  ...makeThemeProps(),\n}, 'SelectionControlGroup')\n\nexport const makeVSelectionControlGroupProps = propsFactory({\n  ...makeSelectionControlGroupProps({\n    defaultsTarget: 'VSelectionControl',\n  }),\n}, 'VSelectionControlGroup')\n\nexport const VSelectionControlGroup = genericComponent<new <T>(\n  props: {\n    modelValue?: T\n    'onUpdate:modelValue'?: (value: T) => void\n  },\n  slots: { default: never },\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VSelectionControlGroup',\n\n  props: makeVSelectionControlGroupProps(),\n\n  emits: {\n    'update:modelValue': (value: any) => true,\n  },\n\n  setup (props, { slots }) {\n    const modelValue = useProxiedModel(props, 'modelValue')\n    const uid = useId()\n    const id = toRef(() => props.id || `v-selection-control-group-${uid}`)\n    const name = toRef(() => props.name || id.value)\n\n    const updateHandlers = new Set<() => void>()\n    provide(VSelectionControlGroupSymbol, {\n      modelValue,\n      forceUpdate: () => {\n        updateHandlers.forEach(fn => fn())\n      },\n      onForceUpdate: cb => {\n        updateHandlers.add(cb)\n        onScopeDispose(() => {\n          updateHandlers.delete(cb)\n        })\n      },\n    })\n\n    provideDefaults({\n      [props.defaultsTarget]: {\n        color: toRef(() => props.color),\n        disabled: toRef(() => props.disabled),\n        density: toRef(() => props.density),\n        error: toRef(() => props.error),\n        inline: toRef(() => props.inline),\n        modelValue,\n        multiple: toRef(() => !!props.multiple || (props.multiple == null && Array.isArray(modelValue.value))),\n        name,\n        falseIcon: toRef(() => props.falseIcon),\n        trueIcon: toRef(() => props.trueIcon),\n        readonly: toRef(() => props.readonly),\n        ripple: toRef(() => props.ripple),\n        type: toRef(() => props.type),\n        valueComparator: toRef(() => props.valueComparator),\n      },\n    })\n\n    useRender(() => (\n      <div\n        class={[\n          'v-selection-control-group',\n          { 'v-selection-control-group--inline': props.inline },\n          props.class,\n        ]}\n        style={ props.style }\n        role={ props.type === 'radio' ? 'radiogroup' : undefined }\n      >\n        { slots.default?.() }\n      </div>\n    ))\n\n    return {}\n  },\n})\n\nexport type VSelectionControlGroup = InstanceType<typeof VSelectionControlGroup>\n"
  },
  {
    "path": "packages/vuetify/src/components/VSelectionControlGroup/_variables.scss",
    "content": "$selection-control-group-grid-area: control !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VSelectionControlGroup/index.ts",
    "content": "export { VSelectionControlGroup } from './VSelectionControlGroup'\n"
  },
  {
    "path": "packages/vuetify/src/components/VSheet/VSheet.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-sheet\n    display: block\n\n    @include tools.border($sheet-border...)\n    @include tools.elevation($sheet-elevation)\n    @include tools.position($sheet-positions)\n    @include tools.rounded($sheet-border-radius)\n    @include tools.theme($sheet-theme...)\n\n    &--rounded\n      @include tools.rounded($sheet-rounded-border-radius)\n"
  },
  {
    "path": "packages/vuetify/src/components/VSheet/VSheet.tsx",
    "content": "// Styles\nimport './VSheet.sass'\n\n// Composables\nimport { makeBorderProps, useBorder } from '@/composables/border'\nimport { useBackgroundColor } from '@/composables/color'\nimport { makeComponentProps } from '@/composables/component'\nimport { makeDimensionProps, useDimension } from '@/composables/dimensions'\nimport { makeElevationProps, useElevation } from '@/composables/elevation'\nimport { makeLocationProps, useLocation } from '@/composables/location'\nimport { makePositionProps, usePosition } from '@/composables/position'\nimport { makeRoundedProps, useRounded } from '@/composables/rounded'\nimport { makeTagProps } from '@/composables/tag'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\n\n// Utilities\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\nexport const makeVSheetProps = propsFactory({\n  color: String,\n\n  ...makeBorderProps(),\n  ...makeComponentProps(),\n  ...makeDimensionProps(),\n  ...makeElevationProps(),\n  ...makeLocationProps(),\n  ...makePositionProps(),\n  ...makeRoundedProps(),\n  ...makeTagProps(),\n  ...makeThemeProps(),\n}, 'VSheet')\n\nexport const VSheet = genericComponent()({\n  name: 'VSheet',\n\n  props: makeVSheetProps(),\n\n  setup (props, { slots }) {\n    const { themeClasses } = provideTheme(props)\n    const { backgroundColorClasses, backgroundColorStyles } = useBackgroundColor(() => props.color)\n    const { borderClasses } = useBorder(props)\n    const { dimensionStyles } = useDimension(props)\n    const { elevationClasses } = useElevation(props)\n    const { locationStyles } = useLocation(props)\n    const { positionClasses } = usePosition(props)\n    const { roundedClasses } = useRounded(props)\n\n    useRender(() => (\n      <props.tag\n        class={[\n          'v-sheet',\n          themeClasses.value,\n          backgroundColorClasses.value,\n          borderClasses.value,\n          elevationClasses.value,\n          positionClasses.value,\n          roundedClasses.value,\n          props.class,\n        ]}\n        style={[\n          backgroundColorStyles.value,\n          dimensionStyles.value,\n          locationStyles.value,\n          props.style,\n        ]}\n        v-slots={ slots }\n      />\n    ))\n\n    return {}\n  },\n})\n\nexport type VSheet = InstanceType<typeof VSheet>\n"
  },
  {
    "path": "packages/vuetify/src/components/VSheet/_variables.scss",
    "content": "@use '../../styles/settings';\n@use '../../styles/tools';\n\n// VSheet\n$sheet-background: rgb(var(--v-theme-surface)) !default;\n$sheet-border-color: settings.$border-color-root !default;\n$sheet-border-radius: 0 !default;\n$sheet-border-style: settings.$border-style-root !default;\n$sheet-border-thin-width: thin !default;\n$sheet-border-width: 0 !default;\n$sheet-color: tools.theme-color('on-surface', var(--v-high-emphasis-opacity)) !default;\n$sheet-elevation: 0 !default;\n$sheet-positions: absolute fixed relative sticky !default;\n$sheet-rounded-border-radius: settings.$border-radius-root !default;\n\n// Lists\n$sheet-border: (\n  $sheet-border-color,\n  $sheet-border-style,\n  $sheet-border-width,\n  $sheet-border-thin-width\n) !default;\n\n$sheet-theme: (\n  $sheet-background,\n  $sheet-color\n) !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VSheet/index.ts",
    "content": "export { VSheet } from './VSheet'\n"
  },
  {
    "path": "packages/vuetify/src/components/VSkeletonLoader/VSkeletonLoader.sass",
    "content": "// Imports\n@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-skeleton-loader\n    align-items: center\n    background: $skeleton-loader-background\n    border-radius: $skeleton-loader-border-radius\n    display: flex\n    flex-wrap: wrap\n    position: relative\n    vertical-align: top\n\n    &__actions\n      justify-content: end\n\n    .v-skeleton-loader__ossein\n      height: 100%\n\n    .v-skeleton-loader__avatar,\n    .v-skeleton-loader__button,\n    .v-skeleton-loader__chip,\n    .v-skeleton-loader__divider,\n    .v-skeleton-loader__heading,\n    .v-skeleton-loader__image,\n    .v-skeleton-loader__ossein,\n    .v-skeleton-loader__text\n      background: $skeleton-loader-text-background\n\n      @media (forced-colors: active)\n        background: canvastext\n\n    .v-skeleton-loader__list-item,\n    .v-skeleton-loader__list-item-avatar,\n    .v-skeleton-loader__list-item-text,\n    .v-skeleton-loader__list-item-two-line,\n    .v-skeleton-loader__list-item-avatar-two-line,\n    .v-skeleton-loader__list-item-three-line,\n    .v-skeleton-loader__list-item-avatar-three-line\n      border-radius: $skeleton-loader-border-radius\n\n    &__bone\n      align-items: center\n      border-radius: inherit\n      display: flex\n      flex: 1 1 100%\n      flex-wrap: wrap\n      overflow: hidden\n      position: relative\n\n      &::after\n        animation: $skeleton-loader-loading-animation\n        background: $skeleton-loader-bone-background\n        transform: $skeleton-loader-loading-transform\n        contain: content\n        will-change: transform\n        z-index: 1\n        @include tools.absolute(true)\n\n      @media (forced-colors: active) and (pointer: fine)\n        cursor: progress\n\n    &__avatar\n      border-radius: 50%\n      flex: 0 1 auto\n      margin: $skeleton-loader-avatar-margin\n      max-height: $skeleton-loader-avatar-height\n      min-height: $skeleton-loader-avatar-height\n      height: $skeleton-loader-avatar-height\n      max-width: $skeleton-loader-avatar-width\n      min-width: $skeleton-loader-avatar-width\n      width: $skeleton-loader-avatar-width\n\n      + .v-skeleton-loader__bone\n        flex: 1 1 auto\n        margin-inline-start: 0\n\n      + .v-skeleton-loader__sentences,\n      + .v-skeleton-loader__paragraph\n        > .v-skeleton-loader__text\n          margin-inline-start: 0\n\n    &__button\n      border-radius: $skeleton-loader-button-border-radius\n      height: $skeleton-loader-button-height\n      margin: $skeleton-loader-gutter\n      max-width: $skeleton-loader-button-width\n\n      + .v-skeleton-loader__bone\n        flex: 1 1 auto\n        margin-inline-start: 0\n\n      + .v-skeleton-loader__sentences,\n      + .v-skeleton-loader__paragraph\n        > .v-skeleton-loader__text\n          margin-inline-start: 0\n\n    &__chip\n      border-radius: $skeleton-loader-chip-border-radius\n      margin: $skeleton-loader-gutter\n      height: $skeleton-loader-chip-height\n      max-width: $skeleton-loader-chip-width\n\n      + .v-skeleton-loader__bone\n        flex: 1 1 auto\n        margin-inline-start: 0\n\n      + .v-skeleton-loader__sentences,\n      + .v-skeleton-loader__paragraph\n        > .v-skeleton-loader__text\n          margin-inline-start: 0\n\n    &__date-picker\n      border-radius: $skeleton-loader-date-picker-border-radius\n\n      .v-skeleton-loader__list-item:first-child\n        .v-skeleton-loader__text\n          max-width: $skeleton-loader-date-picker-text-max-width\n          width: $skeleton-loader-date-picker-text-width\n\n      .v-skeleton-loader__heading\n        max-width: $skeleton-loader-date-picker-heading-max-width\n        width: $skeleton-loader-date-picker-heading-width\n\n    &__date-picker-days\n      flex-wrap: wrap\n      margin: $skeleton-loader-gutter\n\n      .v-skeleton-loader__avatar\n        border-radius: $skeleton-loader-border-radius\n        margin: $skeleton-loader-date-picker-days-margin\n        max-width: 100%\n\n    &__date-picker-options\n      flex-wrap: nowrap\n\n      .v-skeleton-loader__text\n        flex: 1 1 auto\n\n    &__divider\n      border-radius: $skeleton-loader-divider-border-radius\n      height: $skeleton-loader-divider-height\n\n    &__heading\n      border-radius: $skeleton-loader-heading-border-radius\n      margin: $skeleton-loader-gutter\n      height: $skeleton-loader-heading-height\n\n      + .v-skeleton-loader__subtitle\n        margin-top: -$skeleton-loader-gutter\n\n    &__image\n      height: $skeleton-loader-image-height\n      border-radius: 0\n\n    &__card\n      .v-skeleton-loader__image\n        border-radius: 0\n\n    &__list-item\n      margin: $skeleton-loader-gutter\n\n      .v-skeleton-loader__text\n        margin: 0\n\n    &__table-thead\n      justify-content: space-between\n\n      .v-skeleton-loader__heading\n        margin-top: $skeleton-loader-gutter\n        max-width: $skeleton-loader-gutter\n\n    &__table-tfoot\n      flex-wrap: nowrap\n\n      > .v-skeleton-loader__text.v-skeleton-loader__bone\n        margin-top: $skeleton-loader-gutter\n\n    &__table-row\n      align-items: baseline\n      margin: $skeleton-loader-table-row-margin\n      justify-content: space-evenly\n      flex-wrap: nowrap\n\n      > .v-skeleton-loader__text.v-skeleton-loader__bone\n        margin-inline: $skeleton-loader-table-row-text-margin\n\n      + .v-skeleton-loader__divider\n        margin: 0 $skeleton-loader-gutter\n\n    &__table-cell\n      align-items: center\n      display: flex\n      height: $skeleton-loader-table-cell-height\n      width: $skeleton-loader-table-cell-width\n\n      .v-skeleton-loader__text\n        margin-bottom: 0\n\n    &__subtitle\n      max-width: $skeleton-loader-subtitle-max-width\n\n      > .v-skeleton-loader__text\n        height: $skeleton-loader-subtitle-text-height\n        border-radius: $skeleton-loader-subtitle-text-border-radius\n\n    &__text\n      border-radius: $skeleton-loader-text-border-radius\n      margin: $skeleton-loader-gutter\n      height: $skeleton-loader-text-height\n\n      + .v-skeleton-loader__text\n        margin-top: $skeleton-loader-text-two-text-margin-top\n        max-width: $skeleton-loader-text-two-text-max-width\n\n        + .v-skeleton-loader__text\n          max-width: $skeleton-loader-text-three-text-max-width\n\n    &--boilerplate\n      .v-skeleton-loader__bone:after\n        display: none\n\n    &--is-loading\n      overflow: hidden\n\n    &--tile\n      border-radius: 0\n\n      .v-skeleton-loader__bone\n        border-radius: 0\n\n  @keyframes loading\n    100%\n      transform: translateX(100%)\n"
  },
  {
    "path": "packages/vuetify/src/components/VSkeletonLoader/VSkeletonLoader.tsx",
    "content": "// Styles\nimport './VSkeletonLoader.sass'\n\n// Composables\nimport { useBackgroundColor } from '@/composables/color'\nimport { makeDimensionProps, useDimension } from '@/composables/dimensions'\nimport { makeElevationProps, useElevation } from '@/composables/elevation'\nimport { useLocale } from '@/composables/locale'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\n\n// Utilities\nimport { computed } from 'vue'\nimport { genericComponent, propsFactory, useRender, wrapInArray } from '@/util'\n\n// Types\nimport type { PropType, VNode } from 'vue'\n\ntype VSkeletonBone<T> = T | VSkeletonBone<T>[]\n\nexport type VSkeletonBones = VSkeletonBone<VNode>\nexport type VSkeletonLoaderType = keyof typeof rootTypes\n\nexport const rootTypes = {\n  actions: 'button@2',\n  article: 'heading, paragraph',\n  avatar: 'avatar',\n  button: 'button',\n  card: 'image, heading',\n  'card-avatar': 'image, list-item-avatar',\n  chip: 'chip',\n  'date-picker': 'list-item, heading, divider, date-picker-options, date-picker-days, actions',\n  'date-picker-options': 'text, avatar@2',\n  'date-picker-days': 'avatar@28',\n  divider: 'divider',\n  heading: 'heading',\n  image: 'image',\n  'list-item': 'text',\n  'list-item-avatar': 'avatar, text',\n  'list-item-two-line': 'sentences',\n  'list-item-avatar-two-line': 'avatar, sentences',\n  'list-item-three-line': 'paragraph',\n  'list-item-avatar-three-line': 'avatar, paragraph',\n  ossein: 'ossein',\n  paragraph: 'text@3',\n  sentences: 'text@2',\n  subtitle: 'text',\n  table: 'table-heading, table-thead, table-tbody, table-tfoot',\n  'table-heading': 'chip, text',\n  'table-thead': 'heading@6',\n  'table-tbody': 'table-row-divider@6',\n  'table-row-divider': 'table-row, divider',\n  'table-row': 'text@6',\n  'table-tfoot': 'text@2, avatar@2',\n  text: 'text',\n} as const\n\nfunction genBone (type: string, children: VSkeletonBones = []) {\n  return (\n    <div\n      class={[\n        'v-skeleton-loader__bone',\n        `v-skeleton-loader__${type}`,\n      ]}\n    >\n      { children }\n    </div>\n  )\n}\n\nfunction genBones (bone: string) {\n  // e.g. 'text@3'\n  const [type, length] = bone.split('@') as [VSkeletonLoaderType, number]\n\n  // Generate a length array based upon\n  // value after @ in the bone string\n  return Array.from({ length }).map(() => genStructure(type))\n}\n\nfunction genStructure (type?: string): VSkeletonBones {\n  let children: VSkeletonBones = []\n\n  if (!type) return children\n\n  // TODO: figure out a better way to type this\n  const bone = (rootTypes as Record<string, string>)[type]\n\n  // End of recursion, do nothing\n  /* eslint-disable-next-line no-empty, brace-style */\n  if (type === bone) {}\n  // Array of values - e.g. 'heading, paragraph, text@2'\n  else if (type.includes(',')) return mapBones(type)\n  // Array of values - e.g. 'paragraph@4'\n  else if (type.includes('@')) return genBones(type)\n  // Array of values - e.g. 'card@2'\n  else if (bone.includes(',')) children = mapBones(bone)\n  // Array of values - e.g. 'list-item@2'\n  else if (bone.includes('@')) children = genBones(bone)\n  // Single value - e.g. 'card-heading'\n  else if (bone) children.push(genStructure(bone))\n\n  return [genBone(type, children)]\n}\n\nfunction mapBones (bones: string) {\n  // Remove spaces and return array of structures\n  return bones.replace(/\\s/g, '').split(',').map(genStructure)\n}\n\nexport const makeVSkeletonLoaderProps = propsFactory({\n  boilerplate: Boolean,\n  color: String,\n  loading: Boolean,\n  loadingText: {\n    type: String,\n    default: '$vuetify.loading',\n  },\n  type: {\n    type: [String, Array] as PropType<\n      | VSkeletonLoaderType | (string & {})\n      | ReadonlyArray<VSkeletonLoaderType | (string & {})>\n    >,\n    default: 'ossein',\n  },\n\n  ...makeDimensionProps(),\n  ...makeElevationProps(),\n  ...makeThemeProps(),\n}, 'VSkeletonLoader')\n\nexport const VSkeletonLoader = genericComponent()({\n  name: 'VSkeletonLoader',\n\n  inheritAttrs: false,\n\n  props: makeVSkeletonLoaderProps(),\n\n  setup (props, { attrs, slots }) {\n    const { backgroundColorClasses, backgroundColorStyles } = useBackgroundColor(() => props.color)\n    const { dimensionStyles } = useDimension(props)\n    const { elevationClasses } = useElevation(props)\n    const { themeClasses } = provideTheme(props)\n    const { t } = useLocale()\n\n    const items = computed(() => genStructure(wrapInArray(props.type).join(',')))\n\n    useRender(() => {\n      const isLoading = !slots.default || props.loading\n      const loadingProps = (props.boilerplate || !isLoading) ? {} : {\n        ariaLive: 'polite',\n        ariaLabel: t(props.loadingText),\n        role: 'alert',\n      }\n\n      return isLoading\n        ? (\n          <div\n            class={[\n              'v-skeleton-loader',\n              {\n                'v-skeleton-loader--boilerplate': props.boilerplate,\n              },\n              themeClasses.value,\n              backgroundColorClasses.value,\n              elevationClasses.value,\n            ]}\n            style={[\n              backgroundColorStyles.value,\n              dimensionStyles.value,\n            ]}\n            { ...loadingProps }\n            { ...attrs }\n          >\n            { items.value }\n          </div>\n        )\n        : <>{ slots.default?.() }</>\n    })\n\n    return {}\n  },\n})\n\nexport type VSkeletonLoader = InstanceType<typeof VSkeletonLoader>\n"
  },
  {
    "path": "packages/vuetify/src/components/VSkeletonLoader/_variables.scss",
    "content": "@use '../../styles/settings';\n@use '../../styles/tools';\n\n$skeleton-loader-actions-button-margin: 12px !default;\n$skeleton-loader-actions-padding: 16px 16px 8px !default;\n$skeleton-loader-avatar-height: 48px !default;\n$skeleton-loader-avatar-margin: 8px 16px !default;\n$skeleton-loader-avatar-width: 48px !default;\n$skeleton-loader-background: rgb(var(--v-theme-surface)) !default;\n$skeleton-loader-bone-background: linear-gradient(90deg, tools.theme-color('surface', 0), tools.theme-color('surface', .3), tools.theme-color('surface', 0)) !default;\n$skeleton-loader-border-radius: settings.$border-radius-root !default;\n$skeleton-loader-button-border-radius: settings.$border-radius-root !default;\n$skeleton-loader-button-height: 36px !default;\n$skeleton-loader-button-width: 64px !default;\n$skeleton-loader-chip-border-radius: 16px !default;\n$skeleton-loader-chip-height: 32px !default;\n$skeleton-loader-chip-width: 96px !default;\n$skeleton-loader-date-picker-border-radius: inherit !default;\n$skeleton-loader-date-picker-days-margin: 4px !default;\n$skeleton-loader-date-picker-heading-max-width: 256px !default;\n$skeleton-loader-date-picker-heading-width: 40% !default;\n$skeleton-loader-date-picker-text-max-width: 88px !default;\n$skeleton-loader-date-picker-text-width: 20% !default;\n$skeleton-loader-divider-border-radius: 1px !default;\n$skeleton-loader-divider-height: 2px !default;\n$skeleton-loader-gutter: 16px !default;\n$skeleton-loader-heading-border-radius: 12px !default;\n$skeleton-loader-heading-height: 24px !default;\n$skeleton-loader-image-height: 150px !default;\n$skeleton-loader-loading-animation: loading 1.5s infinite !default;\n$skeleton-loader-loading-transform: translateX(-100%) !default;\n$skeleton-loader-subtitle-max-width: 70% !default;\n$skeleton-loader-subtitle-text-border-radius: 8px !default;\n$skeleton-loader-subtitle-text-height: 16px !default;\n$skeleton-loader-table-cell-height: 48px !default;\n$skeleton-loader-table-cell-width: 88px !default;\n$skeleton-loader-table-row-margin: 0 8px !default;\n$skeleton-loader-table-row-text-margin: 8px !default;\n$skeleton-loader-text-background: tools.theme-color('on-surface', var(--v-border-opacity)) !default;\n$skeleton-loader-text-border-radius: 6px !default;\n$skeleton-loader-text-height: 12px !default;\n$skeleton-loader-text-three-text-max-width: 70% !default;\n$skeleton-loader-text-two-text-margin-top: -8px !default;\n$skeleton-loader-text-two-text-max-width: 50% !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VSkeletonLoader/index.ts",
    "content": "export { VSkeletonLoader } from './VSkeletonLoader'\n"
  },
  {
    "path": "packages/vuetify/src/components/VSlideGroup/VSlideGroup.sass",
    "content": "@use 'sass:math'\n@use 'sass:map'\n@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  // Block\n  .v-slide-group\n    display: flex\n    overflow: hidden\n\n  // Element\n  .v-slide-group__next,\n  .v-slide-group__prev\n    align-items: center\n    display: flex\n    flex: 0 1 $slide-group-prev-basis\n    justify-content: center\n    min-width: $slide-group-prev-basis\n    cursor: pointer\n\n    &--disabled\n      pointer-events: none\n      opacity: var(--v-disabled-opacity)\n\n  .v-slide-group__content\n    display: flex\n    flex: 1 0 auto\n    position: relative\n    transition: 0.2s all settings.$standard-easing\n    white-space: nowrap\n\n    > *\n      white-space: initial\n\n  .v-slide-group__container\n    contain: content\n    display: flex\n    flex: 1 1 auto\n    overflow-x: auto\n    overflow-y: hidden\n\n    scrollbar-width: none\n    scrollbar-color: rgba(0, 0, 0, 0)\n\n    &::-webkit-scrollbar\n      display: none\n\n  // Modifiers\n  .v-slide-group--vertical\n    max-height: inherit\n\n    &,\n    .v-slide-group__container,\n    .v-slide-group__content\n      flex-direction: column\n\n    .v-slide-group__container\n      overflow-x: hidden\n      overflow-y: auto\n"
  },
  {
    "path": "packages/vuetify/src/components/VSlideGroup/VSlideGroup.tsx",
    "content": "// Styles\nimport './VSlideGroup.sass'\n\n// Components\nimport { VFadeTransition } from '@/components/transitions'\nimport { VIcon } from '@/components/VIcon'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { makeDisplayProps, useDisplay } from '@/composables/display'\nimport { useGoTo } from '@/composables/goto'\nimport { makeGroupProps, useGroup } from '@/composables/group'\nimport { IconValue } from '@/composables/icons'\nimport { useRtl } from '@/composables/locale'\nimport { useResizeObserver } from '@/composables/resizeObserver'\nimport { makeTagProps } from '@/composables/tag'\n\n// Utilities\nimport { computed, shallowRef, watch } from 'vue'\nimport {\n  calculateCenteredTarget,\n  calculateUpdatedTarget,\n  getOffsetSize,\n  getScrollPosition,\n  getScrollSize,\n} from './helpers'\nimport { focusableChildren, genericComponent, IN_BROWSER, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { InjectionKey, PropType } from 'vue'\nimport type { GoToOptions } from '@/composables/goto'\nimport type { GroupProvide } from '@/composables/group'\nimport type { GenericProps } from '@/util'\n\nexport const VSlideGroupSymbol: InjectionKey<GroupProvide> = Symbol.for('vuetify:v-slide-group')\n\ninterface SlideGroupSlot {\n  next: GroupProvide['next']\n  prev: GroupProvide['prev']\n  select: GroupProvide['select']\n  isSelected: GroupProvide['isSelected']\n}\n\nexport type VSlideGroupSlots = {\n  default: SlideGroupSlot\n  prev: SlideGroupSlot\n  next: SlideGroupSlot\n}\n\nexport const makeVSlideGroupProps = propsFactory({\n  centerActive: Boolean,\n  scrollToActive: {\n    type: Boolean,\n    default: true,\n  },\n  contentClass: null,\n  direction: {\n    type: String as PropType<'horizontal' | 'vertical'>,\n    default: 'horizontal',\n  },\n  symbol: {\n    type: null,\n    default: VSlideGroupSymbol,\n  },\n  nextIcon: {\n    type: IconValue,\n    default: '$next',\n  },\n  prevIcon: {\n    type: IconValue,\n    default: '$prev',\n  },\n  showArrows: {\n    type: [Boolean, String],\n    validator: (v: any) => (\n      typeof v === 'boolean' || [\n        'always',\n        'desktop',\n        'mobile',\n        'never',\n      ].includes(v)\n    ),\n  },\n\n  ...makeComponentProps(),\n  ...makeDisplayProps({ mobile: null }),\n  ...makeTagProps(),\n  ...makeGroupProps({\n    selectedClass: 'v-slide-group-item--active',\n  }),\n}, 'VSlideGroup')\n\nexport const VSlideGroup = genericComponent<new <T>(\n  props: {\n    modelValue?: T\n    'onUpdate:modelValue'?: (value: T) => void\n  },\n  slots: VSlideGroupSlots,\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VSlideGroup',\n\n  props: makeVSlideGroupProps(),\n\n  emits: {\n    'update:modelValue': (value: any) => true,\n  },\n\n  setup (props, { slots }) {\n    const { isRtl } = useRtl()\n    const { displayClasses, mobile } = useDisplay(props)\n    const group = useGroup(props, props.symbol)\n    const isOverflowing = shallowRef(false)\n    const scrollOffset = shallowRef(0)\n    const containerSize = shallowRef(0)\n    const contentSize = shallowRef(0)\n    const isHorizontal = computed(() => props.direction === 'horizontal')\n\n    const { resizeRef: containerRef, contentRect: containerRect } = useResizeObserver()\n    const { resizeRef: contentRef, contentRect } = useResizeObserver()\n\n    const goTo = useGoTo()\n    const goToOptions = computed<Partial<GoToOptions>>(() => {\n      return {\n        container: containerRef.el,\n        duration: 200,\n        easing: 'easeOutQuart',\n      }\n    })\n\n    const firstSelectedIndex = computed(() => {\n      if (!group.selected.value.length) return -1\n\n      return group.items.value.findIndex(item => item.id === group.selected.value[0])\n    })\n\n    const lastSelectedIndex = computed(() => {\n      if (!group.selected.value.length) return -1\n\n      return group.items.value.findIndex(item => item.id === group.selected.value[group.selected.value.length - 1])\n    })\n\n    if (IN_BROWSER) {\n      let frame = -1\n      watch(() => [group.selected.value, containerRect.value, contentRect.value, isHorizontal.value], () => {\n        cancelAnimationFrame(frame)\n        frame = requestAnimationFrame(() => {\n          if (containerRect.value && contentRect.value) {\n            const sizeProperty = isHorizontal.value ? 'width' : 'height'\n\n            containerSize.value = containerRect.value[sizeProperty]\n            contentSize.value = contentRect.value[sizeProperty]\n\n            isOverflowing.value = containerSize.value + 1 < contentSize.value\n          }\n\n          if (props.scrollToActive && firstSelectedIndex.value >= 0 && contentRef.el) {\n            // TODO: Is this too naive? Should we store element references in group composable?\n            const selectedElement = contentRef.el.children[lastSelectedIndex.value] as HTMLElement\n\n            scrollToChildren(selectedElement, props.centerActive)\n          }\n        })\n      })\n    }\n\n    const isFocused = shallowRef(false)\n\n    function scrollToChildren (children: HTMLElement, center?: boolean) {\n      let target = 0\n\n      if (center) {\n        target = calculateCenteredTarget({\n          containerElement: containerRef.el!,\n          isHorizontal: isHorizontal.value,\n          selectedElement: children,\n        })\n      } else {\n        target = calculateUpdatedTarget({\n          containerElement: containerRef.el!,\n          isHorizontal: isHorizontal.value,\n          isRtl: isRtl.value,\n          selectedElement: children,\n        })\n      }\n\n      scrollToPosition(target)\n    }\n\n    function scrollToPosition (newPosition: number) {\n      if (!IN_BROWSER || !containerRef.el) return\n\n      const offsetSize = getOffsetSize(isHorizontal.value, containerRef.el)\n      const scrollPosition = getScrollPosition(isHorizontal.value, isRtl.value, containerRef.el)\n      const scrollSize = getScrollSize(isHorizontal.value, containerRef.el)\n\n      if (\n        scrollSize <= offsetSize ||\n        // Prevent scrolling by only a couple of pixels, which doesn't look smooth\n        Math.abs(newPosition - scrollPosition) < 16\n      ) return\n\n      if (isHorizontal.value && isRtl.value && containerRef.el) {\n        const { scrollWidth, offsetWidth: containerWidth } = containerRef.el!\n\n        newPosition = (scrollWidth - containerWidth) - newPosition\n      }\n\n      if (isHorizontal.value) {\n        goTo.horizontal(newPosition, goToOptions.value)\n      } else {\n        goTo(newPosition, goToOptions.value)\n      }\n    }\n\n    function onScroll (e: Event) {\n      const { scrollTop, scrollLeft } = e.target as HTMLElement\n\n      scrollOffset.value = isHorizontal.value ? scrollLeft : scrollTop\n    }\n\n    function onFocusin (e: FocusEvent) {\n      isFocused.value = true\n\n      if (!isOverflowing.value || !contentRef.el) return\n\n      // Focused element is likely to be the root of an item, so a\n      // breadth-first search will probably find it in the first iteration\n      for (const el of e.composedPath()) {\n        for (const item of contentRef.el.children) {\n          if (item === el) {\n            scrollToChildren(item as HTMLElement)\n            return\n          }\n        }\n      }\n    }\n\n    function onFocusout (e: FocusEvent) {\n      isFocused.value = false\n    }\n\n    // Affix clicks produce onFocus that we have to ignore to avoid extra scrollToChildren\n    let ignoreFocusEvent = false\n    function onFocus (e: FocusEvent) {\n      if (\n        !ignoreFocusEvent &&\n        !isFocused.value &&\n        !(e.relatedTarget && contentRef.el?.contains(e.relatedTarget as Node))\n      ) focus()\n\n      ignoreFocusEvent = false\n    }\n\n    function onFocusAffixes () {\n      ignoreFocusEvent = true\n    }\n\n    function onKeydown (e: KeyboardEvent) {\n      if (!contentRef.el) return\n\n      function toFocus (location: Parameters<typeof focus>[0]) {\n        e.preventDefault()\n        focus(location)\n      }\n\n      if (isHorizontal.value) {\n        if (e.key === 'ArrowRight') {\n          toFocus(isRtl.value ? 'prev' : 'next')\n        } else if (e.key === 'ArrowLeft') {\n          toFocus(isRtl.value ? 'next' : 'prev')\n        }\n      } else {\n        if (e.key === 'ArrowDown') {\n          toFocus('next')\n        } else if (e.key === 'ArrowUp') {\n          toFocus('prev')\n        }\n      }\n\n      if (e.key === 'Home') {\n        toFocus('first')\n      } else if (e.key === 'End') {\n        toFocus('last')\n      }\n    }\n\n    function getSiblingElement (el: HTMLElement | null, location: 'next' | 'prev') {\n      if (!el) return undefined\n      let sibling: HTMLElement | null = el\n      do {\n        sibling = sibling?.[location === 'next' ? 'nextElementSibling' : 'previousElementSibling'] as HTMLElement | null\n      } while (sibling?.hasAttribute('disabled'))\n      return sibling\n    }\n\n    function focus (location?: 'next' | 'prev' | 'first' | 'last') {\n      if (!contentRef.el) return\n\n      let el: HTMLElement | null | undefined\n\n      if (!location) {\n        const focusable = focusableChildren(contentRef.el)\n        el = focusable[0]\n      } else if (location === 'next') {\n        el = getSiblingElement(contentRef.el.querySelector(':focus'), location)\n\n        if (!el) return focus('first')\n      } else if (location === 'prev') {\n        el = getSiblingElement(contentRef.el.querySelector(':focus'), location)\n\n        if (!el) return focus('last')\n      } else if (location === 'first') {\n        el = (contentRef.el.firstElementChild as HTMLElement)\n\n        if (el?.hasAttribute('disabled')) el = getSiblingElement(el, 'next')\n      } else if (location === 'last') {\n        el = (contentRef.el.lastElementChild as HTMLElement)\n\n        if (el?.hasAttribute('disabled')) el = getSiblingElement(el, 'prev')\n      }\n\n      if (el) {\n        el.focus({ preventScroll: true })\n      }\n    }\n\n    function scrollTo (location: 'prev' | 'next') {\n      const direction = isHorizontal.value && isRtl.value ? -1 : 1\n\n      const offsetStep = (location === 'prev' ? -direction : direction) * containerSize.value\n\n      let newPosition = scrollOffset.value + offsetStep\n\n      // TODO: improve it\n      if (isHorizontal.value && isRtl.value && containerRef.el) {\n        const { scrollWidth, offsetWidth: containerWidth } = containerRef.el!\n\n        newPosition += scrollWidth - containerWidth\n      }\n\n      scrollToPosition(newPosition)\n    }\n\n    const slotProps = computed(() => ({\n      next: group.next,\n      prev: group.prev,\n      select: group.select,\n      isSelected: group.isSelected,\n    }))\n\n    const hasOverflowOrScroll = computed(() => isOverflowing.value || Math.abs(scrollOffset.value) > 0)\n\n    const hasAffixes = computed(() => {\n      switch (props.showArrows) {\n        case 'never': return false\n\n        // Always show arrows on desktop & mobile\n        case 'always': return true\n\n        // Always show arrows on desktop\n        case 'desktop': return !mobile.value\n\n        // Show arrows on mobile when overflowing.\n        // This matches the default 2.2 behavior\n        case true: return hasOverflowOrScroll.value\n\n        // Always show on mobile\n        case 'mobile': return (\n          mobile.value ||\n          hasOverflowOrScroll.value\n        )\n\n        // https://material.io/components/tabs#scrollable-tabs\n        // Always show arrows when\n        // overflowed on desktop\n        default: return (\n          !mobile.value &&\n          hasOverflowOrScroll.value\n        )\n      }\n    })\n\n    const hasPrev = computed(() => {\n      // 1 pixel in reserve, may be lost after rounding\n      return Math.abs(scrollOffset.value) > 1\n    })\n\n    const hasNext = computed(() => {\n      if (!hasOverflowOrScroll.value) return false\n\n      const scrollSizeMax = contentSize.value - containerSize.value\n\n      // 1 pixel in reserve, may be lost after rounding\n      return scrollSizeMax - Math.abs(scrollOffset.value) > 1\n    })\n\n    useRender(() => (\n      <props.tag\n        class={[\n          'v-slide-group',\n          {\n            'v-slide-group--vertical': !isHorizontal.value,\n            'v-slide-group--has-affixes': hasAffixes.value,\n            'v-slide-group--is-overflowing': isOverflowing.value,\n          },\n          displayClasses.value,\n          props.class,\n        ]}\n        style={ props.style }\n        tabindex={ (isFocused.value || group.selected.value.length) ? -1 : 0 }\n        onFocus={ onFocus }\n      >\n        { hasAffixes.value && (\n          <div\n            key=\"prev\"\n            class={[\n              'v-slide-group__prev',\n              { 'v-slide-group__prev--disabled': !hasPrev.value },\n            ]}\n            onMousedown={ onFocusAffixes }\n            onClick={ () => hasPrev.value && scrollTo('prev') }\n          >\n            { slots.prev?.(slotProps.value) ?? (\n              <VFadeTransition>\n                <VIcon icon={ isRtl.value ? props.nextIcon : props.prevIcon }></VIcon>\n              </VFadeTransition>\n            )}\n          </div>\n        )}\n\n        <div\n          key=\"container\"\n          ref={ containerRef }\n          class={[\n            'v-slide-group__container',\n            props.contentClass,\n          ]}\n          onScroll={ onScroll }\n        >\n          <div\n            ref={ contentRef }\n            class=\"v-slide-group__content\"\n            onFocusin={ onFocusin }\n            onFocusout={ onFocusout }\n            onKeydown={ onKeydown }\n          >\n            { slots.default?.(slotProps.value) }\n          </div>\n        </div>\n\n        { hasAffixes.value && (\n          <div\n            key=\"next\"\n            class={[\n              'v-slide-group__next',\n              { 'v-slide-group__next--disabled': !hasNext.value },\n            ]}\n            onMousedown={ onFocusAffixes }\n            onClick={ () => hasNext.value && scrollTo('next') }\n          >\n            { slots.next?.(slotProps.value) ?? (\n              <VFadeTransition>\n                <VIcon icon={ isRtl.value ? props.prevIcon : props.nextIcon }></VIcon>\n              </VFadeTransition>\n            )}\n          </div>\n        )}\n      </props.tag>\n    ))\n\n    return {\n      selected: group.selected,\n      scrollTo,\n      scrollOffset,\n      focus,\n      hasPrev,\n      hasNext,\n    }\n  },\n})\n\nexport type VSlideGroup = InstanceType<typeof VSlideGroup>\n"
  },
  {
    "path": "packages/vuetify/src/components/VSlideGroup/VSlideGroupItem.tsx",
    "content": "// Composables\nimport { makeGroupItemProps, useGroupItem } from '@/composables/group'\n\n// Utilities\nimport { VSlideGroupSymbol } from './VSlideGroup'\nimport { genericComponent } from '@/util'\n\n// Types\nimport type { UnwrapRef } from 'vue'\nimport type { GroupItemProvide } from '@/composables/group'\n\ntype VSlideGroupItemSlots = {\n  default: {\n    isSelected: UnwrapRef<GroupItemProvide['isSelected']>\n    select: GroupItemProvide['select']\n    toggle: GroupItemProvide['toggle']\n    selectedClass: UnwrapRef<GroupItemProvide['selectedClass']>\n  }\n}\n\nexport const VSlideGroupItem = genericComponent<VSlideGroupItemSlots>()({\n  name: 'VSlideGroupItem',\n\n  props: makeGroupItemProps(),\n\n  emits: {\n    'group:selected': (val: { value: boolean }) => true,\n  },\n\n  setup (props, { slots }) {\n    const slideGroupItem = useGroupItem(props, VSlideGroupSymbol)\n\n    return () => slots.default?.({\n      isSelected: slideGroupItem.isSelected.value,\n      select: slideGroupItem.select,\n      toggle: slideGroupItem.toggle,\n      selectedClass: slideGroupItem.selectedClass.value,\n    })\n  },\n})\n\nexport type VSlideGroupItem = InstanceType<typeof VSlideGroupItem>\n"
  },
  {
    "path": "packages/vuetify/src/components/VSlideGroup/__tests__/VSlideGroup.spec.cy.tsx",
    "content": "/* eslint-disable sonarjs/no-identical-functions */\n/// <reference types=\"../../../../types/cypress\" />\n\n// Components\nimport { VSlideGroup, VSlideGroupItem } from '../'\nimport { Application, CenteredGrid } from '../../../../cypress/templates'\nimport { VCard } from '@/components/VCard'\n\n// Utilities\nimport { createRange } from '@/util'\nimport { VBtn } from '../../VBtn'\n\ndescribe('VSlideGroup', () => {\n  it('should support default scoped slot with selection', () => {\n    cy.mount(() => (\n      <Application>\n        <CenteredGrid width=\"400px\">\n          <VSlideGroup showArrows=\"always\" selectedClass=\"bg-primary\">\n            { createRange(6).map(i => (\n              <VSlideGroupItem key={ i } value={ i }>\n                { props => (\n                  <VCard\n                    class={['ma-4', props.selectedClass]}\n                    color=\"grey\"\n                    width=\"50\"\n                    height=\"100\"\n                    onClick={ props.toggle }\n                  >{ i }</VCard>\n                )}\n              </VSlideGroupItem>\n            ))}\n          </VSlideGroup>\n        </CenteredGrid>\n      </Application>\n    ))\n\n    cy.get('.v-card').eq(0).click().should('have.class', 'bg-primary')\n\n    cy.get('.v-card').eq(3).click().should('have.class', 'bg-primary')\n  })\n\n  // TODO: fails in headless mode\n  it.skip('should disable affixes when appropriate', () => {\n    cy.mount(() => (\n      <Application>\n        <CenteredGrid width=\"400px\">\n          <VSlideGroup showArrows=\"always\">\n            { createRange(6).map(i => (\n              <VSlideGroupItem key={ i }>\n                <VCard class=\"ma-4\" color=\"grey\" width=\"50\" height=\"100\">{ i }</VCard>\n              </VSlideGroupItem>\n            ))}\n          </VSlideGroup>\n        </CenteredGrid>\n      </Application>\n    ))\n\n    cy.get('.v-slide-group__prev').should('exist').should('have.css', 'pointer-events', 'none')\n\n    cy.get('.v-slide-group__next').should('exist').click().should('have.css', 'pointer-events', 'none')\n\n    cy.get('.v-slide-group__prev').should('exist').should('not.have.css', 'pointer-events', 'none').click()\n  })\n\n  it('should accept scoped prev/next slots', () => {\n    cy.mount(() => (\n      <Application>\n        <CenteredGrid width=\"400px\">\n          <VSlideGroup showArrows=\"always\">\n            {{\n              prev: props => <div { ...props }>prev</div>,\n              next: props => <div { ...props }>next</div>,\n              default: () => createRange(6).map(i => (\n                <VSlideGroupItem key={ i }>\n                  <VCard class=\"ma-4\" color=\"grey\" width=\"50\" height=\"100\">{ i }</VCard>\n                </VSlideGroupItem>\n              )),\n            }}\n          </VSlideGroup>\n        </CenteredGrid>\n      </Application>\n    ))\n\n    cy.get('.v-slide-group__next').should('exist').should('have.text', 'next').click()\n    // on CI pointer-events still with none, we just force the click to avoid CI issues\n    cy.get('.v-slide-group__prev').should('exist').should('have.text', 'prev').click({ force: true })\n  })\n\n  it('should always showArrows', () => {\n    cy.mount(() => (\n      <Application>\n        <CenteredGrid width=\"400px\">\n          <VSlideGroup showArrows=\"always\">\n            { createRange(6).map(i => (\n              <VSlideGroupItem key={ i }>\n                <VCard class=\"ma-4\" color=\"grey\" width=\"50\" height=\"100\">{ i }</VCard>\n              </VSlideGroupItem>\n            ))}\n          </VSlideGroup>\n        </CenteredGrid>\n      </Application>\n    ))\n\n    cy.get('.v-slide-group__prev').should('exist')\n    cy.get('.v-slide-group__next').should('exist')\n  })\n\n  it('should show arrows on desktop only', () => {\n    cy.mount(() => (\n      <Application>\n        <CenteredGrid width=\"400px\">\n          <VSlideGroup showArrows=\"desktop\">\n            { createRange(6).map(i => (\n              <VSlideGroupItem key={ i }>\n                <VCard class=\"ma-4\" color=\"grey\" width=\"50\" height=\"100\">{ i }</VCard>\n              </VSlideGroupItem>\n            ))}\n          </VSlideGroup>\n        </CenteredGrid>\n      </Application>\n    ), null, {\n      display: {\n        mobileBreakpoint: 'sm',\n      },\n    })\n\n    cy.viewport(500, 600)\n\n    cy.get('.v-slide-group__prev').should('not.exist')\n    cy.get('.v-slide-group__next').should('not.exist')\n\n    cy.viewport(800, 600)\n\n    cy.get('.v-slide-group__prev').should('exist')\n    cy.get('.v-slide-group__next').should('exist')\n  })\n\n  it('should show arrows on mobile only', () => {\n    cy.viewport(800, 600)\n\n    cy.mount(() => (\n      <Application>\n        <CenteredGrid width=\"400px\">\n          <VSlideGroup showArrows=\"mobile\">\n            { createRange(3).map(i => (\n              <VSlideGroupItem key={ i }>\n                <VCard class=\"ma-4\" color=\"grey\" width=\"50\" height=\"100\">{ i }</VCard>\n              </VSlideGroupItem>\n            ))}\n          </VSlideGroup>\n        </CenteredGrid>\n      </Application>\n    ), null, {\n      display: {\n        mobileBreakpoint: 'sm',\n      },\n    })\n\n    cy.get('.v-slide-group__prev').should('not.exist')\n    cy.get('.v-slide-group__next').should('not.exist')\n\n    cy.viewport(500, 400)\n\n    cy.get('.v-slide-group__prev').should('exist')\n    cy.get('.v-slide-group__next').should('exist')\n  })\n\n  it('should show arrows when overflowed', () => {\n    cy.viewport(800, 200)\n\n    cy.mount(() => (\n      <Application>\n        <VSlideGroup showArrows>\n          { createRange(6).map(i => (\n            <VSlideGroupItem key={ i }>\n              <VCard class=\"ma-4\" color=\"grey\" width=\"50\" height=\"100\">{ i }</VCard>\n            </VSlideGroupItem>\n          ))}\n        </VSlideGroup>\n      </Application>\n    ))\n\n    cy.get('.v-slide-group__prev').should('not.exist')\n      .get('.v-slide-group__next').should('not.exist')\n\n    cy.viewport(400, 200)\n\n    cy.get('.v-slide-group__prev').should('exist')\n      .get('.v-slide-group__next').should('exist')\n  })\n\n  it('should scroll active item into view', () => {\n    cy.mount(() => (\n      <Application>\n        <CenteredGrid width=\"400px\">\n          <VSlideGroup modelValue={ 7 } showArrows=\"always\" selectedClass=\"bg-primary\">\n            { createRange(10).map(i => (\n              <VSlideGroupItem key={ i } value={ i }>\n                { props => <VCard color=\"grey\" width=\"50\" height=\"100\" class={['ma-4', props.selectedClass]}>{ i }</VCard> }\n              </VSlideGroupItem>\n            ))}\n          </VSlideGroup>\n        </CenteredGrid>\n      </Application>\n    ))\n\n    cy.get('.v-card').eq(7).should('exist').should('be.visible').should('have.class', 'bg-primary')\n  })\n\n  it('supports native scroll', () => {\n    cy.viewport(1280, 768)\n      .mount(() => (\n        <Application>\n          <CenteredGrid width=\"400px\">\n            <VSlideGroup selectedClass=\"bg-primary\">\n              { createRange(8).map(i => (\n                <VSlideGroupItem key={ i } value={ i }>\n                  { props => <VCard color=\"grey\" width=\"50\" height=\"100\" class={['ma-4', props.selectedClass, `item-${i}`]}>{ i }</VCard> }\n                </VSlideGroupItem>\n              ))}\n            </VSlideGroup>\n          </CenteredGrid>\n        </Application>\n      ))\n\n    cy.get('.v-slide-group__container').should('exist').scrollTo(450, 0, { ensureScrollable: true })\n\n    cy.get('.item-1').should('not.be.visible')\n    cy.get('.item-7').should('be.visible')\n  })\n\n  it('should support rtl', () => {\n    cy.mount(() => (\n      <Application rtl>\n        <CenteredGrid width=\"400px\">\n          <VSlideGroup selectedClass=\"bg-primary\" showArrows>\n            { createRange(8).map(i => (\n              <VSlideGroupItem key={ i } value={ i }>\n                { props => <VCard color=\"grey\" width=\"50\" height=\"100\" class={['ma-4', props.selectedClass, `item-${i}`]}>{ i }</VCard> }\n              </VSlideGroupItem>\n            ))}\n          </VSlideGroup>\n        </CenteredGrid>\n      </Application>\n    ))\n\n    cy.get('.item-7').should('exist').should('not.be.visible')\n\n    cy.get('.v-slide-group__prev--disabled').should('exist')\n    cy.get('.v-slide-group__next--disabled').should('not.exist')\n\n    cy.get('.v-slide-group__next').click().click()\n\n    cy.get('.item-7').should('exist').should('be.visible')\n  })\n\n  it('Skip disabled elements when moving focus', () => {\n    cy.mount(() => (\n      <Application>\n        <VSlideGroup selectedClass=\"bg-primary\">\n          { createRange(5).map(i => (\n            <VSlideGroupItem key={ i }>\n              <VBtn class={[`btn${i}`]} disabled={ i === 2 || i === 3 }>{ i }</VBtn>\n            </VSlideGroupItem>\n          ))}\n        </VSlideGroup>\n      </Application>\n    ))\n\n    cy.get('.btn0').focus().type('{rightArrow}{rightArrow}')\n    cy.focused().should('have.class', 'btn4')\n\n    cy.focused().type('{leftArrow}')\n    cy.focused().should('have.class', 'btn1')\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VSlideGroup/_variables.scss",
    "content": "$slide-group-prev-basis: 52px !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VSlideGroup/helpers.ts",
    "content": "export function calculateUpdatedTarget ({\n  selectedElement,\n  containerElement,\n  isRtl,\n  isHorizontal,\n}: {\n  selectedElement: HTMLElement\n  containerElement: HTMLElement\n  isRtl: boolean\n  isHorizontal: boolean\n}): number {\n  const containerSize = getOffsetSize(isHorizontal, containerElement)\n  const scrollPosition = getScrollPosition(isHorizontal, isRtl, containerElement)\n\n  const childrenSize = getOffsetSize(isHorizontal, selectedElement)\n  const childrenStartPosition = getOffsetPosition(isHorizontal, selectedElement)\n\n  const additionalOffset = childrenSize * 0.4\n\n  if (scrollPosition > childrenStartPosition) {\n    return childrenStartPosition - additionalOffset\n  } else if (scrollPosition + containerSize < childrenStartPosition + childrenSize) {\n    return childrenStartPosition - containerSize + childrenSize + additionalOffset\n  }\n\n  return scrollPosition\n}\n\nexport function calculateCenteredTarget ({\n  selectedElement,\n  containerElement,\n  isHorizontal,\n}: {\n  selectedElement: HTMLElement\n  containerElement: HTMLElement\n  isHorizontal: boolean\n}): number {\n  const containerOffsetSize = getOffsetSize(isHorizontal, containerElement)\n  const childrenOffsetPosition = getOffsetPosition(isHorizontal, selectedElement)\n  const childrenOffsetSize = getOffsetSize(isHorizontal, selectedElement)\n\n  return childrenOffsetPosition - (containerOffsetSize / 2) + (childrenOffsetSize / 2)\n}\n\nexport function getScrollSize (isHorizontal: boolean, element?: HTMLElement) {\n  const key = isHorizontal ? 'scrollWidth' : 'scrollHeight'\n  return element?.[key] || 0\n}\n\nexport function getScrollPosition (isHorizontal: boolean, rtl: boolean, element?: HTMLElement) {\n  if (!element) {\n    return 0\n  }\n\n  const {\n    scrollLeft,\n    offsetWidth,\n    scrollWidth,\n  } = element\n\n  if (isHorizontal) {\n    return rtl\n      ? scrollWidth - offsetWidth + scrollLeft\n      : scrollLeft\n  }\n\n  return element.scrollTop\n}\n\nexport function getOffsetSize (isHorizontal: boolean, element?: HTMLElement) {\n  const key = isHorizontal ? 'offsetWidth' : 'offsetHeight'\n  return element?.[key] || 0\n}\n\nexport function getOffsetPosition (isHorizontal: boolean, element?: HTMLElement) {\n  const key = isHorizontal ? 'offsetLeft' : 'offsetTop'\n  return element?.[key] || 0\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VSlideGroup/index.ts",
    "content": "export { VSlideGroup } from './VSlideGroup'\nexport { VSlideGroupItem } from './VSlideGroupItem'\n"
  },
  {
    "path": "packages/vuetify/src/components/VSlider/VSlider.sass",
    "content": "@use 'sass:map'\n@use 'sass:selector'\n@forward '../VInput/variables'\n@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n@use '../VInput/variables' as *\n\n@include tools.layer('components')\n  // Block\n  .v-slider\n    .v-slider__container\n      input\n        cursor: default\n        padding: 0\n        width: 100%\n        display: none\n\n    > .v-input__append,\n    > .v-input__prepend\n      padding: 0\n\n  // Elements\n  .v-slider__container\n    position: relative\n    min-height: inherit\n    width: 100%\n    height: 100%\n    display: flex\n    justify-content: center\n    align-items: center\n    cursor: pointer\n\n    .v-input--disabled &\n      opacity: var(--v-disabled-opacity)\n\n    .v-input--error:not(.v-input--disabled) &\n      color: rgb(var(--v-theme-error))\n\n  // Modifiers\n  .v-slider.v-input--horizontal\n    align-items: center\n\n    > .v-input__prepend\n      margin-inline-end: max(0px, calc($input-affix-margin-inside - $slider-horizontal-start))\n\n    > .v-input__append\n      margin-inline-start: max(0px, calc($input-affix-margin-inside - $slider-horizontal-end))\n\n    > .v-input__control\n      margin-inline: $slider-horizontal-start $slider-horizontal-end\n      min-height: $slider-horizontal-min-height\n      display: flex\n      align-items: center\n\n  .v-slider.v-input--vertical\n    justify-content: center\n    margin-top: $slider-vertical-margin-top\n    margin-bottom: $slider-vertical-margin-bottom\n\n    > .v-input__control\n      min-height: $slider-vertical-min-height\n\n  .v-slider.v-input--disabled\n    pointer-events: none\n\n  .v-slider--has-labels > .v-input__control\n    margin-bottom: $slider-tick-label-margin-top * .5\n\n  .v-slider__label\n    margin-inline-end: $slider-label-margin-end\n"
  },
  {
    "path": "packages/vuetify/src/components/VSlider/VSlider.tsx",
    "content": "// Styles\nimport './VSlider.sass'\n\n// Components\nimport { VSliderThumb } from './VSliderThumb'\nimport { VSliderTrack } from './VSliderTrack'\nimport { makeVInputProps, VInput } from '@/components/VInput/VInput'\nimport { VLabel } from '@/components/VLabel'\n\n// Composables\nimport { makeSliderProps, useSlider, useSteps } from './slider'\nimport { makeFocusProps, useFocus } from '@/composables/focus'\nimport { forwardRefs } from '@/composables/forwardRefs'\nimport { useRtl } from '@/composables/locale'\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { computed, ref } from 'vue'\nimport { filterInputAttrs, genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { VSliderThumbSlots } from './VSliderThumb'\nimport type { VSliderTrackSlots } from './VSliderTrack'\nimport type { VInputSlot, VInputSlots } from '@/components/VInput/VInput'\n\nexport type VSliderSlots = VInputSlots & VSliderThumbSlots & VSliderTrackSlots & {\n  label: VInputSlot\n}\n\nexport const makeVSliderProps = propsFactory({\n  ...makeFocusProps(),\n  ...makeSliderProps(),\n  ...makeVInputProps(),\n\n  modelValue: {\n    type: [Number, String],\n    default: 0,\n  },\n}, 'VSlider')\n\nexport const VSlider = genericComponent<VSliderSlots>()({\n  name: 'VSlider',\n\n  inheritAttrs: false,\n\n  props: makeVSliderProps(),\n\n  emits: {\n    'update:focused': (value: boolean) => true,\n    'update:modelValue': (v: number) => true,\n    start: (value: number) => true,\n    end: (value: number) => true,\n  },\n\n  setup (props, { slots, emit, attrs }) {\n    const thumbContainerRef = ref<VSliderThumb>()\n    const inputRef = ref<VInput>()\n    const { rtlClasses } = useRtl()\n\n    const steps = useSteps(props)\n\n    const model = useProxiedModel(\n      props,\n      'modelValue',\n      undefined,\n      value => {\n        return steps.roundValue(value == null ? steps.min.value : value)\n      },\n    )\n\n    const {\n      min,\n      max,\n      mousePressed,\n      roundValue,\n      onSliderMousedown,\n      onSliderTouchstart,\n      trackContainerRef,\n      position,\n      hasLabels,\n      disabled,\n      readonly,\n      noKeyboard,\n    } = useSlider({\n      props,\n      steps,\n      onSliderStart: () => {\n        if (!disabled.value && !readonly.value) {\n          emit('start', model.value)\n        }\n      },\n      onSliderEnd: ({ value }) => {\n        const roundedValue = roundValue(value)\n\n        if (!disabled.value && !readonly.value) {\n          model.value = roundedValue\n        }\n\n        emit('end', roundedValue)\n      },\n      onSliderMove: ({ value }) => {\n        if (!disabled.value && !readonly.value) {\n          model.value = roundValue(value)\n        }\n      },\n      getActiveThumb: () => thumbContainerRef.value?.$el,\n    })\n\n    const { isFocused, focus, blur } = useFocus(props)\n    const trackStop = computed(() => position(model.value))\n\n    useRender(() => {\n      const inputProps = VInput.filterProps(props)\n      const [rootAttrs, inputAttrs] = filterInputAttrs(attrs)\n      const hasPrepend = !!(props.label || slots.label || slots.prepend)\n\n      return (\n        <VInput\n          ref={ inputRef }\n          class={[\n            'v-slider',\n            {\n              'v-slider--has-labels': !!slots['tick-label'] || hasLabels.value,\n              'v-slider--focused': isFocused.value,\n              'v-slider--pressed': mousePressed.value,\n              'v-slider--disabled': disabled.value,\n            },\n            rtlClasses.value,\n            props.class,\n          ]}\n          style={ props.style }\n          { ...inputProps }\n          { ...rootAttrs }\n          focused={ isFocused.value }\n        >\n          {{\n            ...slots,\n            prepend: hasPrepend ? slotProps => (\n              <>\n                { slots.label?.(slotProps) ?? (\n                  props.label\n                    ? (\n                      <VLabel\n                        id={ slotProps.id.value }\n                        class=\"v-slider__label\"\n                        text={ props.label }\n                      />\n                    ) : undefined\n                )}\n\n                { slots.prepend?.(slotProps) }\n              </>\n            ) : undefined,\n            default: ({ id, messagesId }) => (\n              <div\n                class=\"v-slider__container\"\n                onMousedown={ !readonly.value ? onSliderMousedown : undefined }\n                onTouchstartPassive={ !readonly.value ? onSliderTouchstart : undefined }\n              >\n                <input\n                  id={ id.value }\n                  name={ props.name || id.value }\n                  disabled={ disabled.value }\n                  readonly={ readonly.value }\n                  tabindex=\"-1\"\n                  value={ model.value }\n                />\n\n                <VSliderTrack\n                  ref={ trackContainerRef }\n                  start={ 0 }\n                  stop={ trackStop.value }\n                >\n                  {{ 'tick-label': slots['tick-label'] }}\n                </VSliderTrack>\n\n                <VSliderThumb\n                  ref={ thumbContainerRef }\n                  aria-describedby={ messagesId.value }\n                  focused={ isFocused.value }\n                  noKeyboard={ noKeyboard.value }\n                  min={ min.value }\n                  max={ max.value }\n                  modelValue={ model.value }\n                  onUpdate:modelValue={ v => (model.value = v) }\n                  position={ trackStop.value }\n                  elevation={ props.elevation }\n                  onFocus={ focus }\n                  onBlur={ blur }\n                  ripple={ props.ripple }\n                  name={ props.name }\n                  { ...inputAttrs }\n                >\n                  {{ 'thumb-label': slots['thumb-label'] }}\n                </VSliderThumb>\n              </div>\n            ),\n          }}\n        </VInput>\n      )\n    })\n\n    return forwardRefs({\n      focus: () => thumbContainerRef.value?.$el.focus(),\n    }, inputRef)\n  },\n})\n\nexport type VSlider = InstanceType<typeof VSlider>\n"
  },
  {
    "path": "packages/vuetify/src/components/VSlider/VSliderThumb.sass",
    "content": "@use 'sass:map'\n@use 'sass:selector'\n@use 'sass:math'\n@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  // Theme\n  .v-slider-thumb\n    touch-action: none\n    color: rgb(var(--v-theme-surface-variant))\n\n    .v-input--error:not(.v-input--disabled) &\n      color: inherit\n\n  .v-slider-thumb__label\n    background: tools.theme-color('surface-variant', .7)\n    color: rgb(var(--v-theme-on-surface-variant))\n\n    > .v-slider-thumb__label-wedge\n      background: inherit\n\n  // Block\n  .v-slider-thumb\n    outline: none\n    position: absolute\n    transition: $slider-transition\n\n  .v-slider-thumb__surface\n    cursor: pointer\n    width: var(--v-slider-thumb-size)\n    height: var(--v-slider-thumb-size)\n    border-radius: $slider-thumb-border-radius\n    user-select: none\n    background-color: currentColor\n\n    @media (forced-colors: active)\n      background-color: highlight\n\n    &::before\n      transition: 0.3s settings.$standard-easing\n      content: ''\n      color: inherit\n      top: 0\n      left: 0\n      width: 100%\n      height: 100%\n      border-radius: $slider-thumb-border-radius\n      background: currentColor\n      position: absolute\n      pointer-events: none\n      opacity: 0\n\n    &::after\n      content: ''\n      width: $slider-thumb-touch-size\n      height: $slider-thumb-touch-size\n      position: absolute\n      top: 50%\n      left: 50%\n      transform: translate(-50%, -50%)\n\n  .v-slider-thumb__label-container\n    position: absolute\n    transition: $slider-thumb-label-transition\n\n  .v-slider-thumb__label\n    display: flex\n    align-items: center\n    justify-content: center\n    font-size: $slider-thumb-label-font-size\n    min-width: $slider-thumb-label-min-width\n    height: $slider-thumb-label-height\n    border-radius: $slider-thumb-label-border-radius\n    padding: $slider-thumb-label-padding\n    position: absolute\n    user-select: none\n    transition: $slider-thumb-label-transition\n\n    > .v-slider-thumb__label-wedge\n      width: $slider-thumb-label-wedge-size * 2\n      height: $slider-thumb-label-wedge-size * 2\n      position: absolute\n\n  .v-slider-thumb__ripple\n    position: absolute\n    left: calc(var(--v-slider-thumb-size) / -2)\n    top: calc(var(--v-slider-thumb-size) / -2)\n    width: calc(var(--v-slider-thumb-size) * 2)\n    height: calc(var(--v-slider-thumb-size) * 2)\n    background: inherit\n\n  // Horizontal\n  .v-slider.v-input--horizontal\n    .v-slider-thumb\n      top: 50%\n      transform: translateY(-50%)\n      inset-inline-start: calc(var(--v-slider-thumb-position) - var(--v-slider-thumb-size) / 2)\n\n    .v-slider-thumb__label-container\n      left: calc(var(--v-slider-thumb-size) / 2)\n      top: 0\n\n    .v-slider-thumb__label\n      bottom: $slider-thumb-label-offset\n\n      @include tools.ltr()\n        transform: translateX(-50%)\n      @include tools.rtl()\n        transform: translateX(50%)\n\n      > .v-slider-thumb__label-wedge\n        clip-path: polygon(50% 100%, 0 50%, 100% 50%)\n        bottom: calc(#{-$slider-thumb-label-wedge-size} + 0.2px)\n\n  // Vertical\n  .v-slider.v-input--vertical\n    .v-slider-thumb\n      top: calc(var(--v-slider-thumb-position) - var(--v-slider-thumb-size) / 2)\n\n    .v-slider-thumb__label-container\n      top: calc(var(--v-slider-thumb-size) / 2)\n      right: 0\n\n    .v-slider-thumb__label\n      top: math.div($slider-thumb-label-height, -2)\n      left: $slider-thumb-label-offset\n\n      > .v-slider-thumb__label-wedge\n        clip-path: polygon(0 50%, 50% 0, 50% 100%)\n        left: calc(#{-$slider-thumb-label-wedge-size} + 0.2px)\n\n  // Modifiers\n  .v-slider-thumb--focused\n    .v-slider-thumb__surface::before\n      transform: scale(2)\n      opacity: $slider-thumb-focus-opacity\n\n  .v-slider-thumb--pressed\n    transition: none\n\n    .v-slider-thumb__surface::before\n      opacity: $slider-thumb-pressed-opacity\n\n  @media (hover: hover)\n    .v-slider-thumb:hover\n      .v-slider-thumb__surface::before\n        transform: scale(2)\n\n    .v-slider-thumb:hover:not(.v-slider-thumb--focused)\n      .v-slider-thumb__surface::before\n        opacity: $slider-thumb-hover-opacity\n"
  },
  {
    "path": "packages/vuetify/src/components/VSlider/VSliderThumb.tsx",
    "content": "// Styles\nimport './VSliderThumb.sass'\n\n// Components\nimport { VSliderSymbol } from './slider'\nimport { VScaleTransition } from '../transitions'\n\n// Composables\nimport { useBackgroundColor, useTextColor } from '@/composables/color'\nimport { makeComponentProps } from '@/composables/component'\nimport { useElevation } from '@/composables/elevation'\nimport { useRtl } from '@/composables/locale'\n\n// Directives\nimport vRipple from '@/directives/ripple'\n\n// Utilities\nimport { computed, inject, shallowRef, watch } from 'vue'\nimport { convertToUnit, genericComponent, keyValues, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { RippleDirectiveBinding } from '@/directives/ripple'\n\nexport type VSliderThumbSlots = {\n  'thumb-label': { modelValue: number }\n}\n\nexport const makeVSliderThumbProps = propsFactory({\n  focused: Boolean,\n  max: {\n    type: Number,\n    required: true,\n  },\n  min: {\n    type: Number,\n    required: true,\n  },\n  modelValue: {\n    type: Number,\n    required: true,\n  },\n  position: {\n    type: Number,\n    required: true,\n  },\n  ripple: {\n    type: [Boolean, Object] as PropType<RippleDirectiveBinding['value']>,\n    default: true,\n  },\n  name: String,\n  noKeyboard: Boolean,\n\n  ...makeComponentProps(),\n}, 'VSliderThumb')\n\nexport const VSliderThumb = genericComponent<VSliderThumbSlots>()({\n  name: 'VSliderThumb',\n\n  directives: { vRipple },\n\n  props: makeVSliderThumbProps(),\n\n  emits: {\n    'update:modelValue': (v: number) => true,\n  },\n\n  setup (props, { slots, emit }) {\n    const slider = inject(VSliderSymbol)\n    const { isRtl, rtlClasses } = useRtl()\n    if (!slider) throw new Error('[Vuetify] v-slider-thumb must be used inside v-slider or v-range-slider')\n\n    const {\n      min,\n      max,\n      thumbColor,\n      thumbLabelColor,\n      step,\n      disabled,\n      thumbSize,\n      thumbLabel,\n      direction,\n      isReversed,\n      vertical,\n      readonly,\n      elevation,\n      mousePressed,\n      decimals,\n      indexFromEnd,\n    } = slider\n\n    const isHovered = shallowRef(false)\n    const isHidden = shallowRef(false)\n\n    const elevationProps = computed(() => !disabled.value ? elevation.value : undefined)\n    const { elevationClasses } = useElevation(elevationProps)\n    const { textColorClasses, textColorStyles } = useTextColor(thumbColor)\n    const { backgroundColorClasses, backgroundColorStyles } = useBackgroundColor(thumbLabelColor)\n\n    const { pageup, pagedown, end, home, left, right, down, up } = keyValues\n    const relevantKeys = [pageup, pagedown, end, home, left, right, down, up]\n\n    const multipliers = computed(() => {\n      if (step.value) return [1, 2, 3]\n      else return [1, 5, 10]\n    })\n\n    function parseKeydown (e: KeyboardEvent, value: number) {\n      if (props.noKeyboard || disabled.value) return\n      if (!relevantKeys.includes(e.key)) return\n\n      e.preventDefault()\n\n      const _step = step.value || 0.1\n      const steps = (max.value - min.value) / _step\n      if ([left, right, down, up].includes(e.key)) {\n        const increase = vertical.value\n          ? [isRtl.value ? left : right, isReversed.value ? down : up]\n          : indexFromEnd.value !== isRtl.value ? [left, up] : [right, up]\n        const direction = increase.includes(e.key) ? 1 : -1\n        const multiplier = e.shiftKey ? 2 : (e.ctrlKey ? 1 : 0)\n\n        if (direction === -1 && value === max.value && !multiplier && !Number.isInteger(steps)) {\n          value = value - (steps % 1) * _step\n        } else {\n          value = value + (direction * _step * multipliers.value[multiplier])\n        }\n      } else if (e.key === home) {\n        value = min.value\n      } else if (e.key === end) {\n        value = max.value\n      } else {\n        const direction = e.key === pagedown ? 1 : -1\n        value = value - (direction * _step * (steps > 100 ? steps / 10 : 10))\n      }\n\n      return Math.max(props.min, Math.min(props.max, value))\n    }\n\n    function onKeydown (e: KeyboardEvent) {\n      const newValue = parseKeydown(e, props.modelValue)\n\n      if (newValue != null) {\n        isHidden.value = false\n\n        emit('update:modelValue', newValue)\n      }\n    }\n\n    watch(() => props.focused, val => {\n      if (val) {\n        isHidden.value = false\n      }\n    })\n\n    useRender(() => {\n      const positionPercentage = convertToUnit(indexFromEnd.value ? 100 - props.position : props.position, '%')\n\n      const thumbLabelVisible = thumbLabel.value === 'always' ||\n        (thumbLabel.value === true && props.focused) ||\n        (thumbLabel.value === 'hover' && (isHovered.value || (props.focused && !isHidden.value)))\n\n      return (\n        <div\n          class={[\n            'v-slider-thumb',\n            {\n              'v-slider-thumb--focused': props.focused,\n              'v-slider-thumb--pressed': props.focused && mousePressed.value,\n            },\n            props.class,\n            rtlClasses.value,\n          ]}\n          style={[\n            {\n              '--v-slider-thumb-position': positionPercentage,\n              '--v-slider-thumb-size': convertToUnit(thumbSize.value),\n            },\n            props.style,\n          ]}\n          role=\"slider\"\n          tabindex={ disabled.value ? -1 : 0 }\n          aria-label={ props.name }\n          aria-valuemin={ min.value }\n          aria-valuemax={ max.value }\n          aria-valuenow={ props.modelValue }\n          aria-readonly={ !!readonly.value }\n          aria-orientation={ direction.value }\n          onKeydown={ !readonly.value ? onKeydown : undefined }\n          onMouseenter={ () => { isHovered.value = true } }\n          onMouseleave={ () => { isHovered.value = false; isHidden.value = true } }\n        >\n          <div\n            class={[\n              'v-slider-thumb__surface',\n              textColorClasses.value,\n              elevationClasses.value,\n            ]}\n            style={ textColorStyles.value }\n          />\n          <div\n            class={[\n              'v-slider-thumb__ripple',\n              textColorClasses.value,\n            ]}\n            style={ textColorStyles.value }\n            v-ripple={[props.ripple, null, ['circle', 'center']]}\n          />\n          <VScaleTransition origin=\"bottom center\">\n            <div\n              class=\"v-slider-thumb__label-container\"\n              v-show={ thumbLabelVisible }\n            >\n              <div\n                class={[\n                  'v-slider-thumb__label',\n                  backgroundColorClasses.value,\n                ]}\n                style={ backgroundColorStyles.value }\n              >\n                <div>\n                  { slots['thumb-label']?.({ modelValue: props.modelValue }) ?? props.modelValue.toFixed(step.value ? decimals.value : 1) }\n                </div>\n                <div class=\"v-slider-thumb__label-wedge\" />\n              </div>\n            </div>\n          </VScaleTransition>\n        </div>\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VSliderThumb = InstanceType<typeof VSliderThumb>\n"
  },
  {
    "path": "packages/vuetify/src/components/VSlider/VSliderTrack.sass",
    "content": "@use 'sass:map'\n@use 'sass:selector'\n@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  // Theme\n  .v-slider-track__background\n    background-color: rgb(var(--v-theme-surface-variant))\n\n    @media (forced-colors: active)\n      background-color: highlight\n\n  .v-slider-track__fill\n    background-color: rgb(var(--v-theme-surface-variant))\n\n    @media (forced-colors: active)\n      background-color: highlight\n\n  .v-slider-track__tick\n    background-color: rgb(var(--v-theme-surface-variant))\n\n    &--filled\n      background-color: $slider-tick-background\n\n  // Elements\n  .v-slider-track\n    border-radius: $slider-track-border-radius\n\n    @media (forced-colors: active)\n      border: thin solid buttontext\n\n  .v-slider-track\n    &__background, &__fill\n      position: absolute\n      transition: $slider-transition\n      border-radius: inherit\n\n      .v-slider--pressed &\n        transition: none\n\n      .v-input--error:not(.v-input--disabled) &\n        background-color: currentColor\n\n  .v-slider-track__ticks\n    height: 100%\n    width: 100%\n    position: relative\n\n  .v-slider-track__tick\n    position: absolute\n    opacity: 0\n    transition: 0.2s opacity settings.$standard-easing\n    border-radius: $slider-tick-border-radius\n    width: var(--v-slider-tick-size)\n    height: var(--v-slider-tick-size)\n    transform: translate(calc(var(--v-slider-tick-size) / -2), calc(var(--v-slider-tick-size) / -2))\n\n    &--first .v-slider-track__tick-label\n      @include tools.ltr()\n        transform: none\n\n      @include tools.rtl()\n        transform: translateX(100%)\n\n    &--last .v-slider-track__tick-label\n      @include tools.ltr()\n        transform: translateX(-100%)\n\n      @include tools.rtl()\n        transform: none\n\n  .v-slider-track__tick-label\n    position: absolute\n    user-select: none\n    white-space: nowrap\n\n  // Horizontal\n  .v-slider.v-input--horizontal\n    .v-slider-track\n      display: flex\n      align-items: center\n      width: 100%\n      height: $slider-track-active-size\n      touch-action: pan-y\n\n      &__background\n        height: var(--v-slider-track-size)\n\n      &__fill\n        height: inherit\n\n    .v-slider-track__tick\n      margin-top: calc(#{$slider-track-active-size} / 2)\n\n      @include tools.rtl()\n        transform: translate(calc(var(--v-slider-tick-size) / 2), calc(var(--v-slider-tick-size) / -2))\n\n      .v-slider-track__tick-label\n        margin-top: calc(var(--v-slider-track-size) / 2 + #{$slider-tick-label-margin-top})\n\n        @include tools.ltr()\n          transform: translateX(-50%)\n\n        @include tools.rtl()\n          transform: translateX(50%)\n\n      &--first\n        margin-inline-start: calc(var(--v-slider-tick-size) + 1px)\n\n        .v-slider-track__tick-label\n          @include tools.ltr()\n            transform: translateX(0%)\n\n          @include tools.rtl()\n            transform: translateX(0%)\n\n      &--last\n        margin-inline-start: calc(100% - var(--v-slider-tick-size) - 1px)\n\n        .v-slider-track__tick-label\n          @include tools.ltr()\n            transform: translateX(-100%)\n\n          @include tools.rtl()\n            transform: translateX(100%)\n\n  // Vertical\n  .v-slider.v-input--vertical\n    .v-slider-track\n      height: 100%\n      display: flex\n      justify-content: center\n      width: $slider-track-active-size\n      touch-action: pan-x\n\n      &__background\n        width: var(--v-slider-track-size)\n\n      &__fill\n        width: inherit\n\n    .v-slider-track__ticks\n      height: 100%\n\n    .v-slider-track__tick\n      margin-inline-start: calc(#{$slider-track-active-size} / 2)\n      transform: translate(calc(var(--v-slider-tick-size) / -2), calc(var(--v-slider-tick-size) / 2))\n\n      @include tools.rtl()\n        transform: translate(calc(var(--v-slider-tick-size) / 2), calc(var(--v-slider-tick-size) / 2))\n\n      &--first\n        bottom: calc(0% + var(--v-slider-tick-size) + 1px)\n      &--last\n        bottom: calc(100% - var(--v-slider-tick-size) - 1px)\n\n      .v-slider-track__tick-label\n        margin-inline-start: calc(var(--v-slider-track-size) / 2 + #{$slider-tick-label-margin-start})\n        transform: translateY(-50%)\n\n  // Modifiers\n  .v-slider-track__ticks--always-show, .v-slider--focused\n    .v-slider-track__tick\n      opacity: 1\n\n  .v-slider-track__background--opacity\n    opacity: 0.38\n"
  },
  {
    "path": "packages/vuetify/src/components/VSlider/VSliderTrack.tsx",
    "content": "// Styles\nimport './VSliderTrack.sass'\n\n// Components\nimport { VSliderSymbol } from './slider'\n\n// Composables\nimport { useBackgroundColor } from '@/composables/color'\nimport { makeComponentProps } from '@/composables/component'\nimport { useRounded } from '@/composables/rounded'\n\n// Utilities\nimport { computed, inject } from 'vue'\nimport { convertToUnit, genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { Tick } from './slider'\n\nexport type VSliderTrackSlots = {\n  'tick-label': { tick: Tick, index: number }\n}\n\nexport const makeVSliderTrackProps = propsFactory({\n  start: {\n    type: Number,\n    required: true,\n  },\n  stop: {\n    type: Number,\n    required: true,\n  },\n\n  ...makeComponentProps(),\n}, 'VSliderTrack')\n\nexport const VSliderTrack = genericComponent<VSliderTrackSlots>()({\n  name: 'VSliderTrack',\n\n  props: makeVSliderTrackProps(),\n\n  emits: {},\n\n  setup (props, { slots }) {\n    const slider = inject(VSliderSymbol)\n\n    if (!slider) throw new Error('[Vuetify] v-slider-track must be inside v-slider or v-range-slider')\n\n    const {\n      color,\n      parsedTicks,\n      rounded,\n      showTicks,\n      tickSize,\n      trackColor,\n      trackFillColor,\n      trackSize,\n      vertical,\n      min,\n      max,\n      indexFromEnd,\n    } = slider\n\n    const { roundedClasses } = useRounded(rounded)\n\n    const {\n      backgroundColorClasses: trackFillColorClasses,\n      backgroundColorStyles: trackFillColorStyles,\n    } = useBackgroundColor(trackFillColor)\n\n    const {\n      backgroundColorClasses: trackColorClasses,\n      backgroundColorStyles: trackColorStyles,\n    } = useBackgroundColor(trackColor)\n\n    const startDir = computed(() => `inset-${vertical.value ? 'block' : 'inline'}-${indexFromEnd.value ? 'end' : 'start'}`)\n    const endDir = computed(() => vertical.value ? 'height' : 'width')\n\n    const backgroundStyles = computed(() => {\n      return {\n        [startDir.value]: '0%',\n        [endDir.value]: '100%',\n      }\n    })\n\n    const trackFillWidth = computed(() => props.stop - props.start)\n\n    const trackFillStyles = computed(() => {\n      return {\n        [startDir.value]: convertToUnit(props.start, '%'),\n        [endDir.value]: convertToUnit(trackFillWidth.value, '%'),\n      }\n    })\n\n    const computedTicks = computed(() => {\n      if (!showTicks.value) return []\n\n      const ticks = vertical.value ? parsedTicks.value.slice().reverse() : parsedTicks.value\n\n      return ticks.map((tick, index) => {\n        const directionValue = tick.value !== min.value && tick.value !== max.value ? convertToUnit(tick.position, '%') : undefined\n\n        return (\n          <div\n            key={ tick.value }\n            class={[\n              'v-slider-track__tick',\n              {\n                'v-slider-track__tick--filled': tick.position >= props.start && tick.position <= props.stop,\n                'v-slider-track__tick--first': tick.value === min.value,\n                'v-slider-track__tick--last': tick.value === max.value,\n              },\n            ]}\n            style={{ [startDir.value]: directionValue }}\n          >\n            {\n              (tick.label || slots['tick-label']) && (\n                <div class=\"v-slider-track__tick-label\">\n                  { slots['tick-label']?.({ tick, index }) ?? tick.label }\n                </div>\n              )\n            }\n          </div>\n        )\n      })\n    })\n\n    useRender(() => {\n      return (\n        <div\n          class={[\n            'v-slider-track',\n            roundedClasses.value,\n            props.class,\n          ]}\n          style={[\n            {\n              '--v-slider-track-size': convertToUnit(trackSize.value),\n              '--v-slider-tick-size': convertToUnit(tickSize.value),\n            },\n            props.style,\n          ]}\n        >\n          <div\n            class={[\n              'v-slider-track__background',\n              trackColorClasses.value,\n              {\n                'v-slider-track__background--opacity': !!color.value || !trackFillColor.value,\n              },\n            ]}\n            style={{\n              ...backgroundStyles.value,\n              ...trackColorStyles.value,\n            }}\n          />\n          <div\n            class={[\n              'v-slider-track__fill',\n              trackFillColorClasses.value,\n            ]}\n            style={{\n              ...trackFillStyles.value,\n              ...trackFillColorStyles.value,\n            }}\n          />\n\n          { showTicks.value && (\n            <div\n              class={[\n                'v-slider-track__ticks',\n                {\n                  'v-slider-track__ticks--always-show': showTicks.value === 'always',\n                },\n              ]}\n            >\n              { computedTicks.value }\n            </div>\n          )}\n        </div>\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VSliderTrack = InstanceType<typeof VSliderTrack>\n"
  },
  {
    "path": "packages/vuetify/src/components/VSlider/__tests__/VSlider.spec.browser.tsx",
    "content": "// Components\nimport { VSlider } from '../VSlider'\n\n// Utilities\nimport { commands, page, render, screen, showcase, userEvent } from '@test'\nimport { ref } from 'vue'\n\nconst stories = {\n  'Thumb label': <VSlider thumbLabel=\"always\" />,\n  'With icons': <VSlider prependIcon=\"$vuetify\" appendIcon=\"$vuetify\" />,\n  'With messages': <VSlider messages=\"This is a message\" />,\n  Disabled: <VSlider disabled />,\n  Ticks: (\n    <>\n      <VSlider ticks={[0, 2, 8, 10]} min=\"0\" max=\"10\" step=\"1\" showTicks=\"always\" />\n      <VSlider ticks={{ 0: 'a', 5: 'b', 10: 'c' }} min=\"0\" max=\"10\" step=\"1\" showTicks=\"always\" />\n    </>\n  ),\n  Vertical: (\n    <>\n      <VSlider direction=\"vertical\" thumbLabel=\"always\" />\n      <VSlider direction=\"vertical\" prependIcon=\"$vuetify\" appendIcon=\"$vuetify\" />\n      <VSlider direction=\"vertical\" messages=\"This is a message\" />\n      <VSlider direction=\"vertical\" ticks={[0, 2, 8, 10]} min=\"0\" max=\"10\" step=\"1\" showTicks=\"always\" />\n      <VSlider direction=\"vertical\" ticks={{ 0: 'a', 5: 'b', 10: 'c' }} min=\"0\" max=\"10\" step=\"1\" showTicks=\"always\" />\n    </>\n  ),\n}\n\ndescribe('VSlider', () => {\n  it('should react to clicking on track', async () => {\n    const model = ref()\n    render(() => <VSlider v-model={ model.value } />)\n\n    await userEvent.click(screen.getByCSS('.v-slider-track'))\n    expect(model.value).toBeDefined()\n  })\n\n  it('should allow user to drag thumb', async () => {\n    const model = ref()\n    render(() => <VSlider v-model={ model.value } />)\n\n    await commands.drag([100, 15], [200, 15])\n    expect(model.value).toBeDefined()\n  })\n\n  it('should allow user to interact using keyboard', async () => {\n    const values: number[] = []\n\n    render(() => (\n      <VSlider\n        max=\"20\"\n        step=\"1\"\n        onUpdate:modelValue={ (v: number) => values.push(v) }\n      />\n    ))\n\n    await userEvent.tab()\n    await userEvent.keyboard('{ArrowRight}{ArrowRight}')\n    await userEvent.keyboard('{ArrowLeft}')\n    await userEvent.keyboard('{Control>}{ArrowRight}')\n    await userEvent.keyboard('{Control>}{ArrowLeft}')\n    await userEvent.keyboard('{Shift>}{ArrowRight}')\n    await userEvent.keyboard('{Shift>}{ArrowLeft}')\n    await userEvent.keyboard('{PageUp}')\n    await userEvent.keyboard('{PageDown}')\n    await userEvent.keyboard('{End}')\n    await userEvent.keyboard('{Home}')\n\n    expect(values).toEqual([1, 2, 1, 3, 1, 4, 1, 11, 1, 20, 0])\n  })\n\n  it('should show thumb-label when focused', async () => {\n    render(() => (\n      <VSlider class=\"ma-8\" thumbLabel />\n    ))\n\n    expect(screen.getByCSS('.v-slider-thumb__label')).not.toBeVisible()\n    await userEvent.click(screen.getByCSS('.v-slider-thumb'))\n    await expect.element(screen.getByCSS('.v-slider-thumb__label')).toBeVisible()\n  })\n\n  it('should respect step prop', async () => {\n    const model = ref()\n    render(() => (\n      <VSlider\n        min=\"0\"\n        max=\"10\"\n        step=\"2\"\n        v-model={ model.value }\n      />\n    ))\n\n    await userEvent.tab()\n    await userEvent.keyboard('{ArrowRight}')\n    expect(model.value).toBe(2)\n  })\n\n  it('should render icons with actions', async () => {\n    const onClickPrepend = vi.fn()\n    const onClickAppend = vi.fn()\n\n    render(() => (\n      <VSlider\n        prependIcon=\"mdi-magnify-minus-outline\"\n        appendIcon=\"mdi-magnify-plus-outline\"\n        onClick:prepend={ onClickPrepend }\n        onClick:append={ onClickAppend }\n      />\n    ))\n\n    await userEvent.click(screen.getByCSS('.mdi-magnify-minus-outline'))\n    await userEvent.click(screen.getByCSS('.mdi-magnify-plus-outline'))\n\n    expect(onClickPrepend).toHaveBeenCalledOnce()\n    expect(onClickAppend).toHaveBeenCalledOnce()\n  })\n\n  it('should emit start and end events', async () => {\n    await page.viewport(500, 500)\n\n    const onStart = vi.fn()\n    const onEnd = vi.fn()\n    const model = ref()\n\n    render(() => (\n      <VSlider\n        onStart={ onStart }\n        onEnd={ onEnd }\n        v-model={ model.value }\n      />\n    ))\n\n    await commands.drag([8, 16], [250, 16])\n\n    expect(onStart).toHaveBeenCalledExactlyOnceWith(0)\n    expect(onEnd).toHaveBeenCalledOnce()\n    expect(model.value).toBeCloseTo(50, 0)\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/16634\n  it('should respect the decimals from both step and min', async () => {\n    await page.viewport(500, 500)\n\n    const values: number[] = []\n\n    render(() => (\n      <VSlider\n        modelValue={ 1.001 }\n        step={ 1.001 }\n        min={ 1.0001 }\n        max={ 10 }\n        thumbLabel\n        onUpdate:modelValue={ (v: number) => values.push(v) }\n      />\n    ))\n\n    await commands.drag(\n      [15, 15],\n      [80, 15], // move to 1st step\n      [300, 15], // move to 2nd step\n      [500, 15], // move to 3rd step\n    )\n\n    expect(new Set(values)).toEqual(new Set([2.0011, 6.0051, 10]))\n  })\n\n  showcase({ stories })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VSlider/_variables.scss",
    "content": "@use '../../styles/settings';\n@use '../../styles/tools';\n\n$slider-horizontal-start: 8px !default;\n$slider-horizontal-min-height: 32px !default;\n$slider-horizontal-end: 8px !default;\n$slider-label-margin-end: 12px !default;\n$slider-label-margin-start: 12px !default;\n$slider-state-track-background-opacity: 0.4 !default;\n$slider-thumb-hover-opacity: var(--v-hover-opacity) !default;\n$slider-thumb-focus-opacity: var(--v-focus-opacity) !default;\n$slider-thumb-pressed-opacity: var(--v-pressed-opacity) !default;\n$slider-thumb-border-radius: 50% !default;\n$slider-thumb-focused-size-increase: 24px !default;\n$slider-thumb-label-font-size: tools.map-deep-get(settings.$typography, 'label-small', 'size') !default;\n$slider-thumb-label-border-radius: 4px !default;\n$slider-thumb-label-height: 25px !default;\n$slider-thumb-label-min-width: 35px !default;\n$slider-thumb-label-wedge-size: 6px !default;\n$slider-thumb-label-offset: calc(var(--v-slider-thumb-size) / 2) !default;\n$slider-thumb-label-transition: .2s settings.$accelerated-easing !default;\n$slider-thumb-label-padding: 6px !default;\n$slider-thumb-touch-size: 42px !default;\n$slider-tick-background: rgb(var(--v-theme-surface-light)) !default;\n$slider-tick-border-radius: 2px !default;\n$slider-tick-label-margin-top: 8px !default;\n$slider-tick-label-margin-start: 12px !default;\n$slider-track-border-radius: 6px !default;\n$slider-track-active-size-offset: 2px !default;\n$slider-transition: .3s cubic-bezier(0.25, 0.8, 0.5, 1) !default;\n$slider-vertical-margin-bottom: 12px !default;\n$slider-vertical-margin-top: 12px !default;\n$slider-vertical-min-height: 300px !default;\n\n$slider-track-active-size: calc(var(--v-slider-track-size) + #{$slider-track-active-size-offset}) !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VSlider/index.ts",
    "content": "export { VSlider } from './VSlider'\n"
  },
  {
    "path": "packages/vuetify/src/components/VSlider/slider.ts",
    "content": "/* eslint-disable max-statements */\n// Composables\nimport { makeElevationProps } from '@/composables/elevation'\nimport { useForm } from '@/composables/form'\nimport { useRtl } from '@/composables/locale'\nimport { makeRoundedProps } from '@/composables/rounded'\n\n// Utilities\nimport { computed, nextTick, onScopeDispose, provide, ref, shallowRef, toRef } from 'vue'\nimport { clamp, createRange, getDecimals, propsFactory } from '@/util'\n\n// Types\nimport type { ExtractPropTypes, InjectionKey, PropType, Ref } from 'vue'\nimport type { VSliderTrack } from './VSliderTrack'\n\nexport type Tick = {\n  value: number\n  position: number\n  label?: string\n}\n\ntype SliderProvide = {\n  activeThumbRef: Ref<HTMLElement | undefined>\n  color: Ref<string | undefined>\n  decimals: Ref<number>\n  direction: Ref<'vertical' | 'horizontal'>\n  disabled: Ref<boolean>\n  elevation: Ref<number | string | undefined>\n  min: Ref<number>\n  max: Ref<number>\n  mousePressed: Ref<boolean>\n  noKeyboard: Ref<boolean>\n  numTicks: Ref<number>\n  onSliderMousedown: (e: MouseEvent) => void\n  onSliderTouchstart: (e: TouchEvent) => void\n  parseMouseMove: (e: MouseEvent | TouchEvent) => number | void\n  position: (val: number) => number\n  readonly: Ref<boolean>\n  rounded: Ref<boolean | number | string | undefined>\n  roundValue: (value: number) => number\n  thumbLabel: Ref<boolean | string | undefined>\n  showTicks: Ref<boolean | 'always'>\n  startOffset: Ref<number>\n  step: Ref<number>\n  thumbSize: Ref<number>\n  thumbColor: Ref<string | undefined>\n  thumbLabelColor: Ref<string | undefined>\n  trackColor: Ref<string | undefined>\n  trackFillColor: Ref<string | undefined>\n  trackSize: Ref<number>\n  ticks: Ref<readonly number[] | Record<string, string> | undefined>\n  tickSize: Ref<number>\n  trackContainerRef: Ref<VSliderTrack | undefined>\n  vertical: Ref<boolean>\n  parsedTicks: Ref<Tick[]>\n  hasLabels: Ref<boolean>\n  isReversed: Ref<boolean>\n  indexFromEnd: Ref<boolean>\n}\n\nexport const VSliderSymbol: InjectionKey<SliderProvide> = Symbol.for('vuetify:v-slider')\n\nexport function getOffset (e: MouseEvent | TouchEvent, el: HTMLElement, direction: string) {\n  const vertical = direction === 'vertical'\n  const rect = el.getBoundingClientRect()\n  const touch = 'touches' in e ? e.touches[0] : e\n  return vertical\n    ? touch.clientY - (rect.top + rect.height / 2)\n    : touch.clientX - (rect.left + rect.width / 2)\n}\n\nfunction getPosition (e: MouseEvent | TouchEvent, position: 'clientX' | 'clientY'): number {\n  if ('touches' in e && e.touches.length) return e.touches[0][position]\n  else if ('changedTouches' in e && e.changedTouches.length) return e.changedTouches[0][position]\n  else return (e as MouseEvent)[position]\n}\n\nexport const makeSliderProps = propsFactory({\n  disabled: {\n    type: Boolean as PropType<boolean | null>,\n    default: null,\n  },\n  error: Boolean,\n  readonly: {\n    type: Boolean as PropType<boolean | null>,\n    default: null,\n  },\n  max: {\n    type: [Number, String],\n    default: 100,\n  },\n  min: {\n    type: [Number, String],\n    default: 0,\n  },\n  step: {\n    type: [Number, String],\n    default: 0,\n  },\n  thumbColor: String,\n  thumbLabel: {\n    type: [Boolean, String] as PropType<boolean | 'always' | 'hover' | undefined>,\n    default: undefined,\n    validator: (v: any) => typeof v === 'boolean' || v === 'always' || v === 'hover',\n  },\n  thumbSize: {\n    type: [Number, String],\n    default: 20,\n  },\n  showTicks: {\n    type: [Boolean, String] as PropType<boolean | 'always'>,\n    default: false,\n    validator: (v: any) => typeof v === 'boolean' || v === 'always',\n  },\n  ticks: {\n    type: [Array, Object] as PropType<readonly number[] | Record<number, string>>,\n  },\n  tickSize: {\n    type: [Number, String],\n    default: 2,\n  },\n  color: String,\n  trackColor: String,\n  trackFillColor: String,\n  trackSize: {\n    type: [Number, String],\n    default: 4,\n  },\n  direction: {\n    type: String as PropType<'horizontal' | 'vertical'>,\n    default: 'horizontal',\n    validator: (v: any) => ['vertical', 'horizontal'].includes(v),\n  },\n  reverse: Boolean,\n  noKeyboard: Boolean,\n\n  ...makeRoundedProps(),\n  ...makeElevationProps({\n    elevation: 1,\n  }),\n  ripple: {\n    type: Boolean,\n    default: true,\n  },\n}, 'Slider')\n\ntype SliderProps = ExtractPropTypes<ReturnType<typeof makeSliderProps>>\n\ntype SliderData = {\n  value: number\n}\n\nexport const useSteps = (props: SliderProps) => {\n  const min = computed(() => parseFloat(props.min))\n  const max = computed(() => parseFloat(props.max))\n  const step = computed(() => Number(props.step) > 0 ? parseFloat(props.step) : 0)\n  const decimals = computed(() => Math.max(getDecimals(step.value), getDecimals(min.value)))\n\n  function roundValue (value: string | number) {\n    value = parseFloat(value)\n\n    if (step.value <= 0) return value\n\n    const clamped = clamp(value, min.value, max.value)\n    const offset = min.value % step.value\n    let newValue = Math.round((clamped - offset) / step.value) * step.value + offset\n\n    if (clamped > newValue && newValue + step.value > max.value) {\n      newValue = max.value\n    }\n\n    return parseFloat(Math.min(newValue, max.value).toFixed(decimals.value))\n  }\n\n  return { min, max, step, decimals, roundValue }\n}\n\nexport const useSlider = ({\n  props,\n  steps,\n  onSliderStart,\n  onSliderMove,\n  onSliderEnd,\n  getActiveThumb,\n}: {\n  props: SliderProps\n  steps: ReturnType<typeof useSteps>\n  onSliderEnd: (data: SliderData) => void\n  onSliderStart: (data: SliderData) => void\n  onSliderMove: (data: SliderData) => void\n  getActiveThumb: (e: MouseEvent | TouchEvent) => HTMLElement\n}) => {\n  const form = useForm(props)\n  const { isRtl } = useRtl()\n  const isReversed = toRef(() => props.reverse)\n  const vertical = computed(() => props.direction === 'vertical')\n  const indexFromEnd = computed(() => vertical.value !== isReversed.value)\n\n  const { min, max, step, decimals, roundValue } = steps\n\n  const thumbSize = computed(() => parseInt(props.thumbSize, 10))\n  const tickSize = computed(() => parseInt(props.tickSize, 10))\n  const trackSize = computed(() => parseInt(props.trackSize, 10))\n  const numTicks = computed(() => (max.value - min.value) / step.value)\n\n  const thumbColor = computed(() => props.error || form.isDisabled.value ? undefined : props.thumbColor ?? props.color)\n  const thumbLabelColor = computed(() => props.error || form.isDisabled.value ? undefined : props.thumbColor)\n  const trackColor = computed(() => props.error || form.isDisabled.value ? undefined : props.trackColor ?? props.color)\n  const trackFillColor = computed(() => props.error || form.isDisabled.value ? undefined : props.trackFillColor ?? props.color)\n\n  const mousePressed = shallowRef(false)\n\n  const startOffset = shallowRef(0)\n  const trackContainerRef = ref<VSliderTrack | undefined>()\n  const activeThumbRef = ref<HTMLElement | undefined>()\n\n  function parseMouseMove (e: MouseEvent | TouchEvent): number | void {\n    const el: HTMLElement = trackContainerRef.value?.$el\n\n    if (!el) return\n\n    const vertical = props.direction === 'vertical'\n    const start = vertical ? 'top' : 'left'\n    const length = vertical ? 'height' : 'width'\n    const position = vertical ? 'clientY' : 'clientX'\n\n    const {\n      [start]: trackStart,\n      [length]: trackLength,\n    } = el.getBoundingClientRect()\n    const clickOffset = getPosition(e, position)\n\n    // It is possible for left to be NaN, force to number\n    let clickPos = clamp((clickOffset - trackStart - startOffset.value) / trackLength) || 0\n\n    if (vertical ? indexFromEnd.value : indexFromEnd.value !== isRtl.value) clickPos = 1 - clickPos\n\n    return roundValue(min.value + clickPos * (max.value - min.value))\n  }\n\n  const handleStop = (e: MouseEvent | TouchEvent) => {\n    const value = parseMouseMove(e)\n    if (value != null) {\n      onSliderEnd({ value })\n    }\n\n    mousePressed.value = false\n    startOffset.value = 0\n  }\n\n  const handleStart = (e: MouseEvent | TouchEvent) => {\n    const value = parseMouseMove(e)\n    activeThumbRef.value = getActiveThumb(e)\n\n    if (!activeThumbRef.value) return\n\n    mousePressed.value = true\n\n    if (activeThumbRef.value.contains(e.target as Node)) {\n      startOffset.value = getOffset(e, activeThumbRef.value, props.direction)\n    } else {\n      startOffset.value = 0\n      if (value != null) {\n        onSliderMove({ value })\n      }\n    }\n\n    if (value != null) {\n      onSliderStart({ value })\n    }\n    nextTick(() => activeThumbRef.value?.focus())\n  }\n\n  const moveListenerOptions = { passive: true, capture: true }\n\n  function onMouseMove (e: MouseEvent | TouchEvent) {\n    const value = parseMouseMove(e)\n    if (value != null) {\n      onSliderMove({ value })\n    }\n  }\n\n  function onSliderMouseUp (e: MouseEvent) {\n    e.stopPropagation()\n    e.preventDefault()\n\n    handleStop(e)\n\n    window.removeEventListener('mousemove', onMouseMove, moveListenerOptions)\n    window.removeEventListener('mouseup', onSliderMouseUp)\n  }\n\n  function onSliderTouchend (e: TouchEvent) {\n    handleStop(e)\n\n    window.removeEventListener('touchmove', onMouseMove, moveListenerOptions)\n    e.target?.removeEventListener('touchend', onSliderTouchend as EventListener)\n  }\n\n  function onSliderTouchstart (e: TouchEvent) {\n    handleStart(e)\n\n    window.addEventListener('touchmove', onMouseMove, moveListenerOptions)\n    e.target?.addEventListener('touchend', onSliderTouchend as EventListener, { passive: false })\n  }\n\n  function onSliderMousedown (e: MouseEvent) {\n    if (e.button !== 0) return\n\n    e.preventDefault()\n\n    handleStart(e)\n\n    window.addEventListener('mousemove', onMouseMove, moveListenerOptions)\n    window.addEventListener('mouseup', onSliderMouseUp, { passive: false })\n  }\n\n  onScopeDispose(() => {\n    window.removeEventListener('touchmove', onMouseMove)\n    window.removeEventListener('mousemove', onMouseMove)\n    window.removeEventListener('mouseup', onSliderMouseUp)\n  })\n\n  const position = (val: number) => {\n    const percentage = (val - min.value) / (max.value - min.value) * 100\n    return clamp(isNaN(percentage) ? 0 : percentage, 0, 100)\n  }\n\n  const showTicks = toRef(() => props.showTicks)\n  const parsedTicks = computed<Tick[]>(() => {\n    if (!showTicks.value) return []\n\n    if (!props.ticks) {\n      return numTicks.value !== Infinity ? createRange(numTicks.value + 1).map(t => {\n        const value = min.value + (t * step.value)\n        return {\n          value,\n          position: position(value),\n        }\n      }) : []\n    }\n    if (Array.isArray(props.ticks)) return props.ticks.map(t => ({ value: t, position: position(t), label: t.toString() }))\n    return Object.keys(props.ticks).map(key => ({\n      value: parseFloat(key),\n      position: position(parseFloat(key)),\n      label: (props.ticks as Record<string, string>)[key],\n    }))\n  })\n\n  const hasLabels = computed(() => parsedTicks.value.some(({ label }) => !!label))\n\n  const data: SliderProvide = {\n    activeThumbRef,\n    color: toRef(() => props.color),\n    decimals,\n    disabled: form.isDisabled,\n    direction: toRef(() => props.direction),\n    elevation: toRef(() => props.elevation),\n    hasLabels,\n    isReversed,\n    indexFromEnd,\n    min,\n    max,\n    mousePressed,\n    noKeyboard: toRef(() => props.noKeyboard),\n    numTicks,\n    onSliderMousedown,\n    onSliderTouchstart,\n    parsedTicks,\n    parseMouseMove,\n    position,\n    readonly: form.isReadonly,\n    rounded: toRef(() => props.rounded),\n    roundValue,\n    showTicks,\n    startOffset,\n    step,\n    thumbSize,\n    thumbColor,\n    thumbLabelColor,\n    thumbLabel: toRef(() => props.thumbLabel),\n    ticks: toRef(() => props.ticks),\n    tickSize,\n    trackColor,\n    trackContainerRef,\n    trackFillColor,\n    trackSize,\n    vertical,\n  }\n\n  provide(VSliderSymbol, data)\n\n  return data\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VSnackbar/VSnackbar.sass",
    "content": "@use 'sass:map'\n@use '../../styles/tools'\n@use '../../styles/settings'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-snackbar\n    justify-content: center\n    z-index: $snackbar-z-index\n    margin: $snackbar-wrapper-margin\n    margin-inline-end: calc(#{$snackbar-wrapper-margin} + var(--v-scrollbar-offset))\n    padding: var(--v-layout-top) var(--v-layout-right) var(--v-layout-bottom) var(--v-layout-left)\n\n    --v-snackbar-current-offset: var(--v-snackbar-offset)\n    transform: translateY(calc(var(--v-snackbar-direction) * (var(--v-snackbar-current-offset) + var(--v-snackbar-mobile-notch, 0px))))\n    transition: transform .2s settings.$standard-easing\n\n    &:not(.v-snackbar--center):not(.v-snackbar--top)\n      align-items: flex-end\n\n    &__wrapper\n      align-items: center\n      display: flex\n      flex-wrap: wrap\n      max-width: $snackbar-wrapper-max-width\n      min-height: $snackbar-wrapper-min-height\n      min-width: $snackbar-wrapper-min-width\n      overflow: hidden\n      padding: $snackbar-wrapper-padding\n\n      transition: .35s settings.$standard-easing\n      transition-property: height, width\n\n      @include tools.rounded($snackbar-border-radius)\n\n      @at-root .v-snackbar\n        @include tools.variant($snackbar-variants...)\n\n        &--variant-outlined,\n        &--variant-tonal\n          background: $snackbar-fallback-background\n\n      @media (forced-colors: active)\n        border: thick solid\n\n    &__header\n      flex-basis: 100%\n\n      &:after\n        content: ''\n        display: block\n        flex-basis: 100%\n\n    &__prepend\n      align-self: center\n      display: flex\n      margin-inline: $snackbar-prepend-margin-inline\n\n    &__prepend + &__content\n      padding-inline-start: 0\n\n    &__title\n      font-weight: $snackbar-title-font-weight\n\n    &__content\n      flex: 1 1\n      font-size: $snackbar-font-size\n      font-weight: $snackbar-font-weight\n      letter-spacing: $snackbar-letter-spacing\n      line-height: $snackbar-line-height\n      margin-right: auto\n      padding: $snackbar-content-padding\n      text-align: initial\n\n    &__actions\n      align-items: center\n      align-self: center\n      display: flex\n      margin-inline-end: $snackbar-action-margin\n\n      & > .v-btn\n        padding: $snackbar-btn-padding\n        min-width: auto\n\n    &__timer\n      width: 100%\n      position: absolute\n\n      &--top\n        top: 0\n\n      &--bottom\n        bottom: 0\n\n      .v-progress-linear\n        transition: .2s linear\n\n    &--absolute\n      position: absolute\n      z-index: $snackbar-absolute-z-index\n\n    &--vertical .v-snackbar__actions\n      flex-basis: 100%\n      justify-content: end\n      margin-bottom: $snackbar-vertical-action-margin-bottom\n\n      &:before\n        content: ''\n        display: block\n        flex-basis: 100%\n\n    &--center\n      align-items: center\n      justify-content: center\n\n    &--top\n      align-items: flex-start\n\n      @media #{map.get(settings.$display-breakpoints, 'sm-and-down')}\n        --v-snackbar-mobile-notch: max(env(safe-area-inset-top), 0px)\n\n    &--bottom\n      align-items: flex-end\n\n      @media #{map.get(settings.$display-breakpoints, 'sm-and-down')}\n        --v-snackbar-mobile-notch: max(env(safe-area-inset-bottom), 0px)\n\n    &--left,\n    &--start\n      justify-content: flex-start\n\n    &--right,\n    &--end\n      justify-content: flex-end\n\n    &--collapsed\n      --v-snackbar-current-offset: calc(var(--v-snackbar-gap) * var(--v-snackbar-index, 0))\n\n      .v-snackbar__wrapper\n        min-width: 0\n        width: calc(var(--v-snackbar-collapsed-width) - 2 * var(--v-snackbar-gap) * var(--v-snackbar-index, 0))\n        height: var(--v-snackbar-collapsed-height)\n\n        > *\n          opacity: 0\n\n      &.v-snackbar--start,\n      &.v-snackbar--left\n        .v-snackbar__wrapper\n          transform: translateX(calc(var(--v-snackbar-gap) * var(--v-snackbar-index, 0)))\n\n      &.v-snackbar--end,\n      &.v-snackbar--right\n        .v-snackbar__wrapper\n          transform: translateX(calc(-1 * var(--v-snackbar-gap) * var(--v-snackbar-index, 0)))\n\n      .v-progress-linear\n        opacity: 0\n\n    .v-avatar\n      background: transparent\n\n@include tools.layer('transitions')\n  .v-snackbar-transition\n    &-enter-active,\n    &-leave-active\n      transition-duration: .15s\n      transition-timing-function: settings.$decelerated-easing\n\n    &-enter-active\n      transition-property: opacity, transform\n\n      @media (prefers-reduced-motion: reduce)\n        transition-property: opacity\n\n    &-enter-from\n      opacity: 0\n      transform: scale($snackbar-transition-scale)\n\n    &-leave-active\n      transition-property: opacity\n\n    &-leave-to\n      opacity: 0\n"
  },
  {
    "path": "packages/vuetify/src/components/VSnackbar/VSnackbar.tsx",
    "content": "// Styles\nimport './VSnackbar.sass'\n\n// Components\nimport { VAvatar } from '@/components/VAvatar'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\nimport { VIcon } from '@/components/VIcon'\nimport { VOverlay } from '@/components/VOverlay'\nimport { makeVOverlayProps } from '@/components/VOverlay/VOverlay'\nimport { VProgressCircular } from '@/components/VProgressCircular'\nimport { VProgressLinear } from '@/components/VProgressLinear'\nimport { useSnackbarItem } from '@/components/VSnackbarQueue/queue'\n\n// Composables\nimport { useLayout } from '@/composables'\nimport { forwardRefs } from '@/composables/forwardRefs'\nimport { IconValue } from '@/composables/icons'\nimport { VuetifyLayoutKey } from '@/composables/layout'\nimport { makeLocationProps } from '@/composables/location'\nimport { makePositionProps, usePosition } from '@/composables/position'\nimport { useProxiedModel } from '@/composables/proxiedModel'\nimport { makeRoundedProps, useRounded } from '@/composables/rounded'\nimport { useScopeId } from '@/composables/scopeId'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\nimport { useToggleScope } from '@/composables/toggleScope'\nimport { genOverlays, makeVariantProps, useVariant } from '@/composables/variant'\n\n// Utilities\nimport { computed, inject, mergeProps, nextTick, onMounted, onScopeDispose, ref, shallowRef, watch, watchEffect } from 'vue'\nimport { convertToUnit, genericComponent, omit, propsFactory, refElement, useRender } from '@/util'\n\n// Types\nimport type { PropType, Ref } from 'vue'\n\ntype VSnackbarSlots = {\n  activator: { isActive: boolean, props: Record<string, any> }\n  default: never\n  prepend: never\n  actions: { isActive: Ref<boolean> }\n  header: never\n  title: never\n  text: never\n}\n\nfunction useCountdown (milliseconds: () => number) {\n  const time = shallowRef(milliseconds())\n  let timer = -1\n\n  function clear () {\n    clearInterval(timer)\n  }\n\n  function reset () {\n    clear()\n\n    nextTick(() => time.value = milliseconds())\n  }\n\n  function start (el?: HTMLElement) {\n    const style = el ? getComputedStyle(el) : { transitionDuration: 0.2 }\n    const interval = parseFloat(style.transitionDuration) * 1000 || 200\n\n    clear()\n\n    if (time.value <= 0) return\n\n    const startTime = performance.now()\n    timer = window.setInterval(() => {\n      const elapsed = performance.now() - startTime + interval\n      time.value = Math.max(milliseconds() - elapsed, 0)\n\n      if (time.value <= 0) clear()\n    }, interval)\n  }\n\n  onScopeDispose(clear)\n\n  return { clear, time, start, reset }\n}\n\nexport const makeVSnackbarProps = propsFactory({\n  collapsed: Object as PropType<{ width: number, height: number }>,\n  loading: Boolean,\n  prependAvatar: String,\n  prependIcon: IconValue,\n  queueGap: Number,\n  queueIndex: Number,\n  title: String,\n  text: String,\n  reverseTimer: Boolean,\n  timer: {\n    type: [Boolean, String] as PropType<boolean | 'top' | 'bottom'>,\n    default: false,\n  },\n  timerColor: String,\n  timeout: {\n    type: [Number, String],\n    default: 5000,\n  },\n  vertical: Boolean,\n\n  ...makeLocationProps({ location: 'bottom' } as const),\n  ...makePositionProps(),\n  ...makeRoundedProps(),\n  ...makeVariantProps(),\n  ...makeThemeProps(),\n  ...omit(makeVOverlayProps({\n    transition: 'v-snackbar-transition',\n  }), [\n    'persistent',\n    'noClickAnimation',\n    'offset',\n    'retainFocus',\n    'captureFocus',\n    'disableInitialFocus',\n    'scrim',\n    'scrollStrategy',\n    'stickToTarget',\n    'viewportMargin',\n  ]),\n}, 'VSnackbar')\n\nexport const VSnackbar = genericComponent<VSnackbarSlots>()({\n  name: 'VSnackbar',\n\n  props: makeVSnackbarProps(),\n\n  emits: {\n    'update:modelValue': (v: boolean) => true,\n  },\n\n  setup (props, { slots }) {\n    const isActive = useProxiedModel(props, 'modelValue')\n    const { positionClasses } = usePosition(props)\n    const { scopeId } = useScopeId()\n    const { themeClasses } = provideTheme(props)\n    const { colorClasses, colorStyles, variantClasses } = useVariant(props)\n    const { roundedClasses } = useRounded(props)\n    const countdown = useCountdown(() => Number(props.timeout))\n\n    const overlay = ref<VOverlay>()\n    const queueItem = useSnackbarItem(isActive, () => overlay.value?.contentEl)\n    let _lastOffset: string\n\n    const timerRef = ref<VProgressLinear>()\n    const isHovering = shallowRef(false)\n    const isFocused = shallowRef(false)\n    const startY = shallowRef(0)\n    const mainStyles = ref()\n    const hasLayout = inject(VuetifyLayoutKey, undefined)\n\n    useToggleScope(() => !!hasLayout, () => {\n      const layout = useLayout()\n\n      watchEffect(() => {\n        mainStyles.value = layout.mainStyles.value\n      })\n    })\n\n    watch(isActive, startTimeout)\n    watch(() => props.timeout, startTimeout)\n\n    onMounted(() => {\n      if (isActive.value) startTimeout()\n    })\n\n    let activeTimeout = -1\n    function startTimeout () {\n      countdown.reset()\n      window.clearTimeout(activeTimeout)\n      const timeout = Number(props.timeout)\n\n      if (!isActive.value || timeout === -1) return\n\n      const element = refElement(timerRef.value)\n\n      nextTick(() => countdown.start(element))\n\n      activeTimeout = window.setTimeout(() => {\n        isActive.value = false\n      }, timeout)\n    }\n\n    function clearTimeout () {\n      countdown.reset()\n      window.clearTimeout(activeTimeout)\n    }\n\n    function onPointerenter () {\n      isHovering.value = true\n      clearTimeout()\n    }\n\n    function onPointerleave () {\n      isHovering.value = false\n      if (!isFocused.value) startTimeout()\n    }\n\n    function onFocusin () {\n      isFocused.value = true\n      clearTimeout()\n    }\n\n    function onFocusout (event: FocusEvent) {\n      const contentEl = overlay.value?.contentEl\n      if (contentEl?.contains(event.relatedTarget as Node)) {\n        return\n      }\n      isFocused.value = false\n      if (!isHovering.value) startTimeout()\n    }\n\n    function onTouchstart (event: TouchEvent) {\n      startY.value = event.touches[0].clientY\n    }\n\n    function onTouchend (event: TouchEvent) {\n      if (Math.abs(startY.value - event.changedTouches[0].clientY) > 50) {\n        isActive.value = false\n      }\n    }\n\n    function onAfterLeave () {\n      if (isHovering.value) onPointerleave()\n      isFocused.value = false\n    }\n\n    const locationClasses = computed(() => {\n      return props.location.split(' ').reduce((acc, loc) => {\n        acc[`v-snackbar--${loc}`] = true\n\n        return acc\n      }, {} as Record<string, any>)\n    })\n\n    const queueDirection = computed(() => {\n      const [side, align] = props.location.split(' ')\n      return side === 'bottom' || (['left', 'right'].includes(side) && align === 'end') ? -1 : 1\n    })\n\n    const collapsedStyles = computed(() => {\n      if (!props.collapsed) return null\n      return {\n        '--v-snackbar-collapsed-height': convertToUnit(props.collapsed.height),\n        '--v-snackbar-collapsed-width': convertToUnit(props.collapsed.width),\n      }\n    })\n\n    const offset = computed(() => {\n      if (!queueItem) return {}\n\n      if (queueItem.offset.value === null) {\n        return _lastOffset\n      }\n\n      return _lastOffset = convertToUnit(queueItem.offset.value)\n    })\n\n    const transition = computed(() => {\n      if (typeof props.transition !== 'string' || !props.transition.endsWith('-auto')) {\n        return props.transition\n      }\n\n      const prefix = props.transition.replace('-auto', '')\n      const [side, align] = props.location.split(' ')\n      const axis = ['start', 'end', 'left', 'right'].includes(align) || ['left', 'right'].includes(side) ? 'x' : 'y'\n      const reverse = ['end', 'right'].includes(align) ||\n        (!['start', 'left'].includes(align) && ['bottom', 'right'].includes(side))\n        ? '-reverse'\n        : ''\n\n      return `${prefix}-${axis}${reverse}-transition`\n    })\n\n    useRender(() => {\n      const overlayProps = omit(VOverlay.filterProps(props), ['transition'])\n      const hasPrependMedia = !!(props.prependAvatar || props.prependIcon)\n      const hasPrepend = !!(hasPrependMedia || props.loading || slots.prepend)\n      const hasContent = !!(slots.default || slots.text || slots.title || props.text || props.title)\n\n      return (\n        <VOverlay\n          ref={ overlay }\n          class={[\n            'v-snackbar',\n            {\n              'v-snackbar--active': isActive.value,\n              'v-snackbar--collapsed': !!props.collapsed,\n              'v-snackbar--timer': !!props.timer,\n              'v-snackbar--vertical': props.vertical,\n            },\n            locationClasses.value,\n            positionClasses.value,\n            props.class,\n          ]}\n          style={[\n            mainStyles.value,\n            {\n              '--v-snackbar-offset': offset.value,\n              '--v-snackbar-gap': convertToUnit(props.queueGap),\n              '--v-snackbar-index': props.queueIndex,\n              '--v-snackbar-direction': queueDirection.value,\n            },\n            collapsedStyles.value,\n            props.style,\n          ]}\n          { ...overlayProps }\n          transition={ transition.value }\n          v-model={ isActive.value }\n          contentProps={ mergeProps({\n            class: [\n              'v-snackbar__wrapper',\n              themeClasses.value,\n              colorClasses.value,\n              roundedClasses.value,\n              variantClasses.value,\n            ],\n            style: [\n              colorStyles.value,\n            ],\n            onPointerenter,\n            onPointerleave,\n            onFocusin,\n            onFocusout,\n          }, overlayProps.contentProps)}\n          persistent\n          noClickAnimation\n          scrim={ false }\n          scrollStrategy=\"none\"\n          _disableGlobalStack\n          onTouchstartPassive={ onTouchstart }\n          onTouchend={ onTouchend }\n          onAfterLeave={ onAfterLeave }\n          { ...scopeId }\n          v-slots={{ activator: slots.activator }}\n        >\n          { genOverlays(false, 'v-snackbar') }\n\n          { slots.header && (\n            <div class=\"v-snackbar__header\">{ slots.header?.() }</div>\n          )}\n\n          { props.timer && countdown.time.value > 0 && !isHovering.value && (\n            <div\n              key=\"timer\"\n              class={[\n                'v-snackbar__timer',\n                `v-snackbar__timer--${props.timer === 'bottom' ? 'bottom' : 'top'}`,\n              ]}\n            >\n              <VProgressLinear\n                ref={ timerRef }\n                color={ props.timerColor ?? 'info' }\n                max={ props.timeout }\n                modelValue={ props.reverseTimer ? Number(props.timeout) - countdown.time.value : countdown.time.value }\n              />\n            </div>\n          )}\n\n          { hasPrepend && (\n            <VDefaultsProvider\n              key=\"prepend-defaults\"\n              disabled={ !hasPrependMedia && !props.loading }\n              defaults={{\n                VAvatar: {\n                  image: props.prependAvatar,\n                },\n                VIcon: {\n                  icon: props.prependIcon,\n                },\n                VProgressCircular: {\n                  indeterminate: true,\n                  size: 24,\n                  width: 3,\n                },\n              }}\n            >\n              <div class=\"v-snackbar__prepend\">\n                { slots.prepend\n                  ? slots.prepend()\n                  : (\n                    <>\n                      { props.loading && <VProgressCircular /> }\n                      { !props.loading && props.prependAvatar && <VAvatar /> }\n                      { !props.loading && props.prependIcon && <VIcon /> }\n                    </>\n                  )\n                }\n              </div>\n            </VDefaultsProvider>\n          )}\n\n          { hasContent && (\n            <div\n              key=\"content\"\n              class=\"v-snackbar__content\"\n              role=\"status\"\n              aria-live=\"polite\"\n            >\n              { slots.title?.() ?? (\n                props.title\n                  ? (<div class=\"v-snackbar__title\" key=\"title\">{ props.title }</div>)\n                  : ''\n              )}\n              { slots.text?.() ?? props.text }\n\n              { slots.default?.() }\n            </div>\n          )}\n\n          { slots.actions && (\n            <VDefaultsProvider\n              defaults={{\n                VBtn: {\n                  variant: 'text',\n                  ripple: false,\n                  slim: true,\n                },\n              }}\n            >\n              <div class=\"v-snackbar__actions\">\n                { slots.actions({ isActive }) }\n              </div>\n            </VDefaultsProvider>\n          )}\n        </VOverlay>\n      )\n    })\n\n    return forwardRefs({}, overlay)\n  },\n})\n\nexport type VSnackbar = InstanceType<typeof VSnackbar>\n"
  },
  {
    "path": "packages/vuetify/src/components/VSnackbar/_variables.scss",
    "content": "@use '../../styles/settings';\n@use '../../styles/tools';\n\n// VSnackbar\n$snackbar-absolute-z-index: 1 !default;\n$snackbar-action-margin: 8px !default;\n$snackbar-border-radius: settings.$border-radius-root !default;\n$snackbar-plain-opacity: .62 !default;\n$snackbar-btn-padding: 0 8px !default;\n$snackbar-background: rgb(var(--v-theme-surface-variant)) !default;\n$snackbar-fallback-background: rgb(var(--v-theme-surface)) !default;\n$snackbar-color: rgb(var(--v-theme-on-surface-variant)) !default;\n$snackbar-font-size: tools.map-deep-get(settings.$typography, 'body-medium', 'size') !default;\n$snackbar-font-weight: tools.map-deep-get(settings.$typography, 'body-medium', 'weight') !default;\n$snackbar-letter-spacing: tools.map-deep-get(settings.$typography, 'body-medium', 'letter-spacing') !default;\n$snackbar-line-height: tools.map-deep-get(settings.$typography, 'body-medium', 'line-height') !default;\n$snackbar-title-font-weight: 700 !default;\n$snackbar-content-padding: 14px 16px !default;\n$snackbar-prepend-margin-inline: 16px 12px !default;\n$snackbar-elevation: 2 !default;\n$snackbar-transition-scale: .8 !default;\n$snackbar-vertical-action-margin-bottom: 8px !default;\n$snackbar-wrapper-margin: 8px !default;\n$snackbar-wrapper-max-width: 672px !default;\n$snackbar-wrapper-min-height: 48px !default;\n$snackbar-wrapper-min-width: 344px !default;\n$snackbar-wrapper-padding: 0 !default;\n$snackbar-z-index: 10000 !default;\n\n// List\n$snackbar-variants: (\n  $snackbar-background,\n  $snackbar-color,\n  $snackbar-elevation,\n  $snackbar-plain-opacity,\n  'v-snackbar'\n) !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VSnackbar/index.ts",
    "content": "export { VSnackbar } from './VSnackbar'\n"
  },
  {
    "path": "packages/vuetify/src/components/VSnackbarQueue/VSnackbarQueue.tsx",
    "content": "// Components\nimport { VBtn } from '@/components/VBtn'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\nimport { makeVSnackbarProps, VSnackbar } from '@/components/VSnackbar/VSnackbar'\n\n// Composables\nimport { useSnackbarQueue } from './queue'\nimport { useDelay } from '@/composables/delay'\nimport { useDocumentVisibility } from '@/composables/documentVisibility'\nimport { useLocale } from '@/composables/locale'\n\n// Utilities\nimport { computed, mergeProps, ref, shallowRef, toRef, triggerRef, watch } from 'vue'\nimport { genericComponent, omit, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType, VNodeProps } from 'vue'\nimport type { GenericProps } from '@/util'\n\nexport type VSnackbarQueueSlots<T extends string | SnackbarMessage> = {\n  header: { item: T }\n  item: { item: T }\n  text: { item: T }\n  actions: {\n    item: T\n    props: {\n      onClick: () => void\n    }\n  }\n}\n\nexport type SnackbarMessageDismissType =\n  | 'dismissed'\n  | 'cleared'\n  | 'overflow'\n  | 'auto'\n\nexport type SnackbarMessage =\n  | string\n  | (Omit<\n    VSnackbar['$props'],\n    | 'modelValue'\n    | 'onUpdate:modelValue'\n    | 'activator'\n    | 'activatorProps'\n    | 'closeDelay'\n    | 'openDelay'\n    | 'openOnClick'\n    | 'openOnFocus'\n    | 'openOnHover'\n    | 'collapsed'\n    | 'style'\n    | '$children'\n    | 'v-slots'\n    | `v-slot:${string}`\n    | keyof VNodeProps\n  > & {\n    style?: any\n    collapsed?: { width: number, height: number }\n    promise?: Promise<unknown>\n    success?: (val?: unknown) => Exclude<SnackbarMessage, string>\n    error?: (val?: Error) => Exclude<SnackbarMessage, string>\n    onDismiss?: (reason: SnackbarMessageDismissType) => void\n  })\n\nexport type SnackbarQueueItem = {\n  id: number\n  item: Exclude<SnackbarMessage, string>\n  active: boolean\n  onDismiss?: (reason: SnackbarMessageDismissType) => void\n}\n\nexport const makeVSnackbarQueueProps = propsFactory({\n  // TODO: Port this to Snackbar on dev\n  closable: [Boolean, String],\n  closeText: {\n    type: String,\n    default: '$vuetify.dismiss',\n  },\n  collapsed: Boolean,\n  displayStrategy: {\n    type: String as PropType<'overflow' | 'hold'>,\n    default: 'hold',\n  },\n  modelValue: {\n    type: Array as PropType<readonly SnackbarMessage[]>,\n    default: () => [],\n  },\n  totalVisible: {\n    type: [Number, String],\n    default: 1,\n  },\n  gap: {\n    type: [Number, String],\n    default: 8,\n  },\n  ...omit(makeVSnackbarProps(), ['modelValue', 'collapsed', 'queueIndex', 'queueGap']),\n}, 'VSnackbarQueue')\n\nexport const VSnackbarQueue = genericComponent<new <T extends readonly SnackbarMessage[]> (\n  props: {\n    modelValue?: T\n    'onUpdate:modelValue'?: (val: T) => void\n  },\n  slots: VSnackbarQueueSlots<T[number]>,\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VSnackbarQueue',\n\n  inheritAttrs: false,\n\n  props: makeVSnackbarQueueProps(),\n\n  emits: {\n    'update:modelValue': (val: SnackbarMessage[]) => true,\n  },\n\n  setup (props, { attrs, emit, slots }) {\n    const { t } = useLocale()\n    const documentVisibility = useDocumentVisibility()\n    const queue = useSnackbarQueue(props)\n\n    const isHovered = shallowRef(false)\n    const { runOpenDelay, runCloseDelay } = useDelay(\n      { openDelay: 0, closeDelay: 500 },\n      val => {\n        isHovered.value = val\n        updateDynamicProps()\n      }\n    )\n\n    let _lastId = 0\n    const visibleItems = ref<SnackbarQueueItem[]>([])\n    const limit = toRef(() => Number(props.totalVisible))\n\n    watch(() => props.modelValue.length, showNext)\n\n    function removeItem (id: number) {\n      visibleItems.value = visibleItems.value.filter(x => x.id !== id)\n      if (visibleItems.value.length === 0) {\n        isHovered.value = false\n      }\n      showNext()\n    }\n\n    function showNext () {\n      if (!props.modelValue.length) return\n\n      const activeCount = visibleItems.value.filter(x => x.active).length\n      if (activeCount >= limit.value) {\n        if (props.displayStrategy !== 'overflow') return\n\n        // Dismiss oldest active items to make room\n        visibleItems.value\n          .filter(x => x.active)\n          .slice(limit.value - 1)\n          .forEach(item => {\n            item.active = false\n            item.onDismiss?.('overflow')\n          })\n      }\n\n      const [next, ...rest] = props.modelValue\n      emit('update:modelValue', rest)\n\n      const item = typeof next === 'string' ? { text: next } : next\n      const { promise, success, error, onDismiss, ...itemProps } = item\n\n      const newItem: SnackbarQueueItem = {\n        id: _lastId++,\n        item: {\n          ...promise ? { timeout: -1, loading: true } : {},\n          ...itemProps,\n        },\n        active: true,\n        onDismiss,\n      }\n      visibleItems.value.unshift(newItem)\n      updateDynamicProps()\n\n      promise?.then(\n        (data: any) => {\n          if (!newItem.active) return\n          newItem.item = success?.(data) ?? { ...newItem.item, timeout: 1 }\n          updateDynamicProps()\n          triggerRef(visibleItems)\n        },\n        (data: any) => {\n          if (!newItem.active) return\n          newItem.item = error?.(data) ?? { ...newItem.item, timeout: 1 }\n          updateDynamicProps()\n          triggerRef(visibleItems)\n        }\n      )\n    }\n\n    function dismiss (id: number, reason: SnackbarMessageDismissType) {\n      const item = visibleItems.value.find(x => x.id === id)\n      if (!item) return\n      item.active = false\n      item.onDismiss?.(reason)\n      updateDynamicProps()\n    }\n\n    function clear () {\n      emit('update:modelValue', [])\n      visibleItems.value\n        .toReversed()\n        .forEach((item, i) => setTimeout(() => {\n          item.active = false\n          item.onDismiss?.('cleared')\n        }, 100 * i))\n    }\n\n    const btnProps = computed(() => ({\n      color: typeof props.closable === 'string' ? props.closable : undefined,\n      text: t(props.closeText),\n    }))\n\n    function updateDynamicProps () {\n      let activeIndex = 0\n      visibleItems.value.forEach(({ item, active }) => {\n        item.queueIndex = activeIndex\n        if (active) activeIndex++\n      })\n\n      if (!props.collapsed || isHovered.value) {\n        visibleItems.value.forEach(({ item }) => item.collapsed = undefined)\n        return\n      }\n\n      for (const { item } of visibleItems.value) {\n        item.collapsed = item.queueIndex! > 0 ? {\n          width: queue.lastItemSize.value.width,\n          height: queue.lastItemSize.value.height,\n        } : undefined\n      }\n    }\n\n    watch(queue.lastItemSize, updateDynamicProps)\n    watch(() => props.collapsed, updateDynamicProps)\n\n    useRender(() => {\n      const hasActions = !!(props.closable || slots.actions)\n      const snackbarProps = omit(VSnackbar.filterProps(props as any), ['modelValue', 'collapsed'])\n      const pauseAll = documentVisibility.value === 'hidden' || (props.collapsed && isHovered.value)\n\n      return (\n        <>\n          { visibleItems.value.map(({ id, item, active }) => (\n            slots.item\n              ? (\n                <VDefaultsProvider defaults={{ VSnackbar: item }}>\n                  { slots.item({ item }) }\n                </VDefaultsProvider>\n              ) : (\n                <VSnackbar\n                  key={ id }\n                  { ...attrs }\n                  { ...snackbarProps }\n                  { ...item }\n                  { ...(pauseAll ? { timeout: -1 } : {}) }\n                  queueGap={ Number(props.gap) }\n                  contentProps={ mergeProps(snackbarProps.contentProps, {\n                    onMouseenter: runOpenDelay,\n                    onMouseleave: () => runCloseDelay(),\n                  })}\n                  modelValue={ active }\n                  onUpdate:modelValue={ () => dismiss(id, 'auto') }\n                  onAfterLeave={ () => removeItem(id) }\n                >\n                  {{\n                    header: slots.header ? () => slots.header?.({ item }) : undefined,\n                    text: slots.text ? () => slots.text?.({ item }) : undefined,\n                    actions: hasActions ? () => (\n                      <>\n                        { !slots.actions ? (\n                          <VBtn\n                            { ...btnProps.value }\n                            onClick={ () => dismiss(id, 'dismissed') }\n                          />\n                        ) : (\n                          <VDefaultsProvider defaults={{ VBtn: btnProps.value }}>\n                            { slots.actions({\n                              item,\n                              props: { onClick: () => dismiss(id, 'dismissed') },\n                            })}\n                          </VDefaultsProvider>\n                        )}\n                      </>\n                    ) : undefined,\n                  }}\n                </VSnackbar>\n              )\n          ))}\n        </>\n      )\n    })\n\n    return {\n      clear,\n    }\n  },\n})\n\nexport type VSnackbarQueue = InstanceType<typeof VSnackbarQueue>\n"
  },
  {
    "path": "packages/vuetify/src/components/VSnackbarQueue/index.ts",
    "content": "export { VSnackbarQueue } from './VSnackbarQueue'\n"
  },
  {
    "path": "packages/vuetify/src/components/VSnackbarQueue/queue.ts",
    "content": "// Composables\nimport { useResizeObserver } from '@/composables/resizeObserver'\n\n// Utilities\nimport { computed, inject, onBeforeUnmount, provide, ref, toRef, useId, watch } from 'vue'\n\n// Types\nimport type { InjectionKey, Ref } from 'vue'\n\nexport interface SnackbarQueueItemState {\n  height: number\n  width: number\n}\n\nexport interface SnackbarQueueProvide {\n  register: (id: string) => void\n  unregister: (id: string) => void\n  setSize: (id: string, height: number, width: number) => void\n  getOffset: (id: string) => number | null\n  items: Ref<Map<string, SnackbarQueueItemState>>\n  gap: Ref<number>\n  lastItemSize: Ref<{ height: number, width: number }>\n}\n\nexport const VSnackbarQueueSymbol: InjectionKey<SnackbarQueueProvide> = Symbol.for('vuetify:v-snackbar-queue')\n\nexport function useSnackbarQueue (props: { gap: string | number }): SnackbarQueueProvide {\n  const items = ref<Map<string, SnackbarQueueItemState>>(new Map())\n  const gap = toRef(() => Number(props.gap))\n\n  function register (id: string) {\n    items.value.set(id, { height: 0, width: 0 })\n  }\n\n  function unregister (id: string) {\n    items.value.delete(id)\n  }\n\n  function setSize (id: string, height: number, width: number) {\n    const item = items.value.get(id)\n    if (!item || (item.height === height && item.width === width)) return\n    item.height = height\n    item.width = width\n  }\n\n  const lastItemSize = computed(() => {\n    for (const { width, height } of [...items.value.values()].toReversed()) {\n      if (!width || !height) continue\n      return { width, height }\n    }\n    return { width: 0, height: 0 }\n  })\n\n  function getOffset (id: string): number | null {\n    if (!items.value.has(id)) return null\n\n    let offset = 0\n    for (const [itemId, state] of [...items.value.entries()].toReversed()) {\n      if (itemId === id) break\n      offset += state.height + gap.value\n    }\n    return offset\n  }\n\n  const state: SnackbarQueueProvide = {\n    register,\n    unregister,\n    setSize,\n    getOffset,\n    items,\n    gap,\n    lastItemSize,\n  }\n\n  provide(VSnackbarQueueSymbol, state)\n\n  return state\n}\n\nexport function useSnackbarItem (\n  isActive: Ref<boolean>,\n  contentEl: () => HTMLElement | undefined,\n) {\n  const queue = inject(VSnackbarQueueSymbol, null)\n\n  if (!queue) return null\n\n  const id = useId()\n\n  queue.register(id)\n  onBeforeUnmount(() => queue.unregister(id))\n  watch(isActive, val => !val && queue.unregister(id), { flush: 'sync' })\n\n  const { resizeRef, contentRect } = useResizeObserver()\n  watch(contentEl, el => { resizeRef.value = el ?? null })\n  watch(contentRect, rect => {\n    if (rect?.width) queue.setSize(id, rect.height, rect.width)\n  })\n\n  const offset = computed(() => queue.getOffset(id))\n\n  return {\n    id,\n    offset,\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VSparkline/VBarline.tsx",
    "content": "// Utilities\nimport { computed, useId } from 'vue'\nimport { makeLineProps } from './util/line'\nimport { genericComponent, getPropertyFromItem, PREFERS_REDUCED_MOTION, propsFactory, useRender } from '@/util'\n\n// Types\nexport type VBarlineSlots = {\n  default: void\n  label: { index: number, value: string }\n}\n\nexport type SparklineItem = number | { value: number }\n\nexport type SparklineText = {\n  x: number\n  value: string\n}\n\nexport interface Boundary {\n  minX: number\n  minY: number\n  maxX: number\n  maxY: number\n}\n\nexport interface Bar {\n  x: number\n  y: number\n  height: number\n  value: number\n}\n\nexport const makeVBarlineProps = propsFactory({\n  autoLineWidth: Boolean,\n\n  ...makeLineProps(),\n}, 'VBarline')\n\nexport const VBarline = genericComponent<VBarlineSlots>()({\n  name: 'VBarline',\n\n  props: makeVBarlineProps(),\n\n  setup (props, { slots }) {\n    const uid = useId()\n    const id = computed(() => props.id || `barline-${uid}`)\n    const autoDrawDuration = computed(() => Number(props.autoDrawDuration) || 500)\n\n    const hasLabels = computed(() => {\n      return Boolean(\n        props.showLabels ||\n        props.labels.length > 0 ||\n        !!slots?.label\n      )\n    })\n\n    const lineWidth = computed(() => parseFloat(props.lineWidth) || 4)\n\n    const totalWidth = computed(() => Math.max(props.modelValue.length * lineWidth.value, Number(props.width)))\n\n    const boundary = computed<Boundary>(() => {\n      return {\n        minX: 0,\n        maxX: totalWidth.value,\n        minY: 0,\n        maxY: parseInt(props.height, 10),\n      }\n    })\n    const items = computed(() => props.modelValue.map(item => getPropertyFromItem(item, props.itemValue, item)))\n\n    function genBars (\n      values: number[],\n      boundary: Boundary\n    ): Bar[] {\n      const { minX, maxX, minY, maxY } = boundary\n\n      const totalValues = values.length\n      let maxValue = props.max != null ? Number(props.max) : Math.max(...values)\n      let minValue = props.min != null ? Number(props.min) : Math.min(...values)\n\n      if (minValue > 0 && props.min == null) minValue = 0\n      if (maxValue < 0 && props.max == null) maxValue = 0\n\n      const gridX = maxX / (totalValues === 1 ? 2 : totalValues)\n      const gridY = (maxY - minY) / ((maxValue - minValue) || 1)\n      const horizonY = maxY - Math.abs(minValue * gridY)\n\n      return values.map((value, index) => {\n        const height = Math.abs(gridY * value)\n\n        return {\n          x: minX + index * gridX,\n          y: horizonY - height +\n            Number(value < 0) * height,\n          height,\n          value,\n        }\n      })\n    }\n\n    const parsedLabels = computed(() => {\n      const labels = []\n      const points = genBars(items.value, boundary.value)\n      const len = points.length\n\n      for (let i = 0; labels.length < len; i++) {\n        const item = points[i]\n        let value = props.labels[i]\n\n        if (!value) {\n          value = typeof item === 'object'\n            ? item.value\n            : item\n        }\n\n        labels.push({\n          x: item.x,\n          value: String(value),\n        })\n      }\n\n      return labels\n    })\n\n    const bars = computed(() => genBars(items.value, boundary.value))\n    const offsetX = computed(() => bars.value.length === 1\n      ? (boundary.value.maxX - lineWidth.value) / 2\n      : (Math.abs(bars.value[0].x - (bars.value[1].x)) - lineWidth.value) / 2\n    )\n    const smooth = computed(() => typeof props.smooth === 'boolean' ? (props.smooth ? 2 : 0) : Number(props.smooth))\n\n    useRender(() => {\n      const gradientData = !props.gradient.slice().length ? [''] : props.gradient.slice().reverse()\n      return (\n        <svg\n          display=\"block\"\n        >\n          <defs>\n            <linearGradient\n              id={ id.value }\n              gradientUnits=\"userSpaceOnUse\"\n              x1={ props.gradientDirection === 'left' ? '100%' : '0' }\n              y1={ props.gradientDirection === 'top' ? '100%' : '0' }\n              x2={ props.gradientDirection === 'right' ? '100%' : '0' }\n              y2={ props.gradientDirection === 'bottom' ? '100%' : '0' }\n            >\n              {\n                gradientData.map((color, index) => (\n                  <stop offset={ index / (Math.max(gradientData.length - 1, 1)) } stop-color={ color || 'currentColor' } />\n                ))\n              }\n            </linearGradient>\n          </defs>\n\n          <clipPath id={ `${id.value}-clip` }>\n            {\n              bars.value.map(item => (\n                <rect\n                    x={ item.x + offsetX.value }\n                    y={ item.y }\n                    width={ lineWidth.value }\n                    height={ item.height }\n                    rx={ smooth.value }\n                    ry={ smooth.value }\n                >\n                  { props.autoDraw && !PREFERS_REDUCED_MOTION() && (\n                    <>\n                      <animate\n                        attributeName=\"y\"\n                        from={ item.y + item.height }\n                        to={ item.y }\n                        dur={ `${autoDrawDuration.value}ms` }\n                        fill=\"freeze\"\n                      />\n                      <animate\n                        attributeName=\"height\"\n                        from=\"0\"\n                        to={ item.height }\n                        dur={ `${autoDrawDuration.value}ms` }\n                        fill=\"freeze\"\n                      />\n                    </>\n                  )}\n                </rect>\n              ))\n            }\n          </clipPath>\n\n          { hasLabels.value && (\n            <g\n              key=\"labels\"\n              style={{\n                textAnchor: 'middle',\n                dominantBaseline: 'mathematical',\n                fill: 'currentColor',\n              }}\n            >\n              {\n                parsedLabels.value.map((item, i) => (\n                  <text\n                    x={ item.x + offsetX.value + lineWidth.value / 2 }\n                    y={ (parseInt(props.height, 10) - 2) + (parseInt(props.labelSize, 10) || 7 * 0.75) }\n                    font-size={ Number(props.labelSize) || 7 }\n                  >\n                    { slots.label?.({ index: i, value: item.value }) ?? item.value }\n                  </text>\n                ))\n              }\n            </g>\n          )}\n\n          <g\n            clip-path={ `url(#${id.value}-clip)` }\n            fill={ `url(#${id.value})` }\n          >\n            <rect\n              x={ 0 }\n              y={ 0 }\n              width={ Math.max(props.modelValue.length * lineWidth.value, Number(props.width)) }\n              height={ props.height }\n            ></rect>\n          </g>\n        </svg>\n      )\n    })\n  },\n})\n\nexport type VBarline = InstanceType<typeof VBarline>\n"
  },
  {
    "path": "packages/vuetify/src/components/VSparkline/VSparkline.tsx",
    "content": "// Components\nimport { makeVBarlineProps, VBarline } from './VBarline'\nimport { makeVTrendlineProps, VTrendline } from './VTrendline'\n\n// Composables\nimport { useTextColor } from '@/composables/color'\n\n// Utilities\nimport { computed } from 'vue'\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\n// Types\n\nexport const makeVSparklineProps = propsFactory({\n  type: {\n    type: String as PropType<'trend' | 'bar'>,\n    default: 'trend',\n  },\n\n  ...makeVBarlineProps(),\n  ...makeVTrendlineProps(),\n}, 'VSparkline')\n\nexport type VSparklineSlots = {\n  default: void\n  label: { index: number, value: string }\n}\n\nexport const VSparkline = genericComponent<VSparklineSlots>()({\n  name: 'VSparkline',\n\n  props: makeVSparklineProps(),\n\n  setup (props, { slots }) {\n    const { textColorClasses, textColorStyles } = useTextColor(() => props.color)\n    const hasLabels = computed(() => {\n      return Boolean(\n        props.showLabels ||\n        props.labels.length > 0 ||\n        !!slots?.label\n      )\n    })\n    const totalHeight = computed(() => {\n      let height = parseInt(props.height, 10)\n\n      if (hasLabels.value) height += parseInt(props.labelSize, 10) * 1.5\n\n      return height\n    })\n\n    useRender(() => {\n      const Tag = props.type === 'trend' ? VTrendline : VBarline\n      const lineProps = props.type === 'trend' ? VTrendline.filterProps(props) : VBarline.filterProps(props)\n\n      return (\n        <Tag\n          key={ props.type }\n          class={ textColorClasses.value }\n          style={ textColorStyles.value }\n          viewBox={ `0 0 ${props.width} ${parseInt(totalHeight.value, 10)}` }\n          { ...lineProps }\n          v-slots={ slots }\n        />\n      )\n    })\n  },\n})\n\nexport type VSparkline = InstanceType<typeof VSparkline>\n"
  },
  {
    "path": "packages/vuetify/src/components/VSparkline/VTrendline.tsx",
    "content": "// Utilities\nimport { computed, nextTick, ref, useId, watch } from 'vue'\nimport { makeLineProps } from './util/line'\nimport { genPath as _genPath } from './util/path'\nimport { genericComponent, getPropertyFromItem, PREFERS_REDUCED_MOTION, propsFactory, useRender } from '@/util'\n\n// Types\nexport type VTrendlineSlots = {\n  default: void\n  label: { index: number, value: string }\n}\n\nexport type SparklineItem = number | { value: number }\n\nexport type SparklineText = {\n  x: number\n  value: string\n}\n\nexport interface Boundary {\n  minX: number\n  minY: number\n  maxX: number\n  maxY: number\n}\n\nexport interface Point {\n  x: number\n  y: number\n  value: number\n}\n\nexport const makeVTrendlineProps = propsFactory({\n  fill: Boolean,\n\n  ...makeLineProps(),\n}, 'VTrendline')\n\nexport const VTrendline = genericComponent<VTrendlineSlots>()({\n  name: 'VTrendline',\n\n  props: makeVTrendlineProps(),\n\n  setup (props, { slots }) {\n    const uid = useId()\n    const id = computed(() => props.id || `trendline-${uid}`)\n    const autoDrawDuration = computed(() => Number(props.autoDrawDuration) || (props.fill ? 500 : 2000))\n\n    const lastLength = ref(0)\n    const path = ref<SVGPathElement | null>(null)\n\n    function genPoints (\n      values: number[],\n      boundary: Boundary\n    ): Point[] {\n      const { minX, maxX, minY, maxY } = boundary\n\n      if (values.length === 1) {\n        values = [values[0], values[0]]\n      }\n\n      const totalValues = values.length\n      const maxValue = props.max != null ? Number(props.max) : Math.max(...values)\n      const minValue = props.min != null ? Number(props.min) : Math.min(...values)\n\n      const gridX = (maxX - minX) / (totalValues - 1)\n      const gridY = (maxY - minY) / ((maxValue - minValue) || 1)\n\n      return values.map((value, index) => {\n        return {\n          x: minX + index * gridX,\n          y: maxY - (value - minValue) * gridY,\n          value,\n        }\n      })\n    }\n    const hasLabels = computed(() => {\n      return Boolean(\n        props.showLabels ||\n        props.labels.length > 0 ||\n        !!slots?.label\n      )\n    })\n    const lineWidth = computed(() => {\n      return parseFloat(props.lineWidth) || 4\n    })\n    const totalWidth = computed(() => Number(props.width))\n\n    const boundary = computed<Boundary>(() => {\n      const padding = Number(props.padding)\n\n      return {\n        minX: padding,\n        maxX: totalWidth.value - padding,\n        minY: padding,\n        maxY: parseInt(props.height, 10) - padding,\n      }\n    })\n    const items = computed(() => props.modelValue.map(item => getPropertyFromItem(item, props.itemValue, item)))\n    const parsedLabels = computed(() => {\n      const labels = []\n      const points = genPoints(items.value, boundary.value)\n      const len = points.length\n\n      for (let i = 0; labels.length < len; i++) {\n        const item = points[i]\n        let value = props.labels[i]\n\n        if (!value) {\n          value = typeof item === 'object'\n            ? item.value\n            : item\n        }\n\n        labels.push({\n          x: item.x,\n          value: String(value),\n        })\n      }\n\n      return labels\n    })\n\n    watch(() => props.modelValue, async () => {\n      await nextTick()\n\n      if (!props.autoDraw || !path.value || PREFERS_REDUCED_MOTION()) return\n\n      const pathRef = path.value\n      const length = pathRef.getTotalLength()\n\n      if (!props.fill) {\n        // Initial setup to \"hide\" the line by using the stroke dash array\n        pathRef.style.strokeDasharray = `${length}`\n        pathRef.style.strokeDashoffset = `${length}`\n\n        // Force reflow to ensure the transition starts from this state\n        pathRef.getBoundingClientRect()\n\n        // Animate the stroke dash offset to \"draw\" the line\n        pathRef.style.transition = `stroke-dashoffset ${autoDrawDuration.value}ms ${props.autoDrawEasing}`\n        pathRef.style.strokeDashoffset = '0'\n      } else {\n        // Your existing logic for filled paths remains the same\n        pathRef.style.transformOrigin = 'bottom center'\n        pathRef.style.transition = 'none'\n        pathRef.style.transform = `scaleY(0)`\n        pathRef.getBoundingClientRect()\n        pathRef.style.transition = `transform ${autoDrawDuration.value}ms ${props.autoDrawEasing}`\n        pathRef.style.transform = `scaleY(1)`\n      }\n\n      lastLength.value = length\n    }, { immediate: true })\n\n    function genPath (fill: boolean) {\n      const smoothValue = typeof props.smooth === 'boolean' ? (props.smooth ? 8 : 0) : Number(props.smooth)\n\n      return _genPath(\n        genPoints(items.value, boundary.value),\n        smoothValue,\n        fill,\n        parseInt(props.height, 10)\n      )\n    }\n\n    useRender(() => {\n      const gradientData = !props.gradient.slice().length ? [''] : props.gradient.slice().reverse()\n\n      return (\n        <svg\n          display=\"block\"\n          stroke-width={ parseFloat(props.lineWidth) ?? 4 }\n        >\n          <defs>\n            <linearGradient\n              id={ id.value }\n              gradientUnits=\"userSpaceOnUse\"\n              x1={ props.gradientDirection === 'left' ? '100%' : '0' }\n              y1={ props.gradientDirection === 'top' ? '100%' : '0' }\n              x2={ props.gradientDirection === 'right' ? '100%' : '0' }\n              y2={ props.gradientDirection === 'bottom' ? '100%' : '0' }\n            >\n              {\n                gradientData.map((color, index) => (\n                  <stop offset={ index / (Math.max(gradientData.length - 1, 1)) } stop-color={ color || 'currentColor' } />\n                ))\n              }\n            </linearGradient>\n          </defs>\n\n          { hasLabels.value && (\n            <g\n              key=\"labels\"\n              style={{\n                textAnchor: 'middle',\n                dominantBaseline: 'mathematical',\n                fill: 'currentColor',\n              }}\n            >\n              {\n                parsedLabels.value.map((item, i) => (\n                  <text\n                    x={ item.x + (lineWidth.value / 2) + lineWidth.value / 2 }\n                    y={ (parseInt(props.height, 10) - 4) + (parseInt(props.labelSize, 10) || 7 * 0.75) }\n                    font-size={ Number(props.labelSize) || 7 }\n                  >\n                    { slots.label?.({ index: i, value: item.value }) ?? item.value }\n                  </text>\n                ))\n              }\n            </g>\n          )}\n\n          <path\n            ref={ path }\n            d={ genPath(props.fill) }\n            fill={ props.fill ? `url(#${id.value})` : 'none' }\n            stroke={ props.fill ? 'none' : `url(#${id.value})` }\n          />\n\n          { props.fill && (\n            <path\n              d={ genPath(false) }\n              fill=\"none\"\n              stroke={ props.color ?? props.gradient?.[0] }\n            />\n          )}\n        </svg>\n      )\n    })\n  },\n})\n\nexport type VTrendline = InstanceType<typeof VTrendline>\n"
  },
  {
    "path": "packages/vuetify/src/components/VSparkline/index.ts",
    "content": "export { VSparkline } from './VSparkline'\n"
  },
  {
    "path": "packages/vuetify/src/components/VSparkline/util/line.ts",
    "content": "// Utilities\nimport { propsFactory } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\nexport type SparklineItem = string | number | { value: number }\n\nexport const makeLineProps = propsFactory({\n  autoDraw: Boolean,\n  autoDrawDuration: [Number, String],\n  autoDrawEasing: {\n    type: String,\n    default: 'ease',\n  },\n  color: String,\n  gradient: {\n    type: Array as PropType<string[]>,\n    default: () => ([]),\n  },\n  gradientDirection: {\n    type: String as PropType<'top' | 'bottom' | 'left' | 'right'>,\n    validator: (val: string) => ['top', 'bottom', 'left', 'right'].includes(val),\n    default: 'top',\n  },\n  height: {\n    type: [String, Number],\n    default: 75,\n  },\n  labels: {\n    type: Array as PropType<SparklineItem[]>,\n    default: () => ([]),\n  },\n  labelSize: {\n    type: [Number, String],\n    default: 7,\n  },\n  lineWidth: {\n    type: [String, Number],\n    default: 4,\n  },\n  id: String,\n  itemValue: {\n    type: String,\n    default: 'value',\n  },\n  modelValue: {\n    type: Array as PropType<SparklineItem[]>,\n    default: () => ([]),\n  },\n  min: [String, Number],\n  max: [String, Number],\n  padding: {\n    type: [String, Number],\n    default: 8,\n  },\n  showLabels: Boolean,\n  smooth: [Boolean, String, Number],\n  width: {\n    type: [Number, String],\n    default: 300,\n  },\n}, 'Line')\n"
  },
  {
    "path": "packages/vuetify/src/components/VSparkline/util/path.ts",
    "content": "// @ts-nocheck\n/* eslint-disable */\n\nimport { Point } from '../VSparkline'\n// import { checkCollinear, getDistance, moveTo } from './math'\n\n/**\n * From https://github.com/unsplash/react-trend/blob/master/src/helpers/DOM.helpers.js#L18\n */\nexport function genPath (points: Point[], radius: number, fill = false, height = 75) {\n  if (points.length === 0) return ''\n  const start = points.shift()!\n  const end = points[points.length - 1]\n\n  return (\n    (fill ? `M${start.x} ${height - start.x + 2} L${start.x} ${start.y}` : `M${start.x} ${start.y}`) +\n    points\n      .map((point, index) => {\n        const next = points[index + 1]\n        const prev = points[index - 1] || start\n        const isCollinear = next && checkCollinear(next, point, prev)\n\n        if (!next || isCollinear) {\n          return `L${point.x} ${point.y}`\n        }\n\n        const threshold = Math.min(\n          getDistance(prev, point),\n          getDistance(next, point)\n        )\n        const isTooCloseForRadius = threshold / 2 < radius\n        const radiusForPoint = isTooCloseForRadius ? threshold / 2 : radius\n\n        const before = moveTo(prev, point, radiusForPoint)\n        const after = moveTo(next, point, radiusForPoint)\n\n        return `L${before.x} ${before.y}S${point.x} ${point.y} ${after.x} ${after.y}`\n      })\n      .join('') +\n    (fill ? `L${end.x} ${height - start.x + 2} Z` : '')\n  )\n}\n\nfunction int (value: string | number): number {\n  return parseInt(value, 10)\n}\n\n/**\n * https://en.wikipedia.org/wiki/Collinearity\n * x=(x1+x2)/2\n * y=(y1+y2)/2\n */\nexport function checkCollinear (p0: Point, p1: Point, p2: Point): boolean {\n  return int(p0.x + p2.x) === int(2 * p1.x) && int(p0.y + p2.y) === int(2 * p1.y)\n}\n\nexport function getDistance (p1: Point, p2: Point): number {\n  return Math.sqrt(\n    Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2)\n  )\n}\n\nexport function moveTo (to: Point, from: Point, radius: number) {\n  const vector = { x: to.x - from.x, y: to.y - from.y }\n  const length = Math.sqrt((vector.x * vector.x) + (vector.y * vector.y))\n  const unitVector = { x: vector.x / length, y: vector.y / length }\n\n  return {\n    x: from.x + unitVector.x * radius,\n    y: from.y + unitVector.y * radius,\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VSpeedDial/VSpeedDial.sass",
    "content": "@use '../../styles/tools'\n\n@include tools.layer('components')\n  .v-speed-dial__content\n    gap: 8px\n\n    &.v-overlay__content\n      &.v-speed-dial__content--end,\n      &.v-speed-dial__content--end-center,\n      &.v-speed-dial__content--right,\n      &.v-speed-dial__content--right-center\n        flex-direction: row\n\n      &.v-speed-dial__content--left,\n      &.v-speed-dial__content--left-center,\n      &.v-speed-dial__content--start,\n      &.v-speed-dial__content--start-center\n        flex-direction: row-reverse\n\n      &.v-speed-dial__content--top,\n      &.v-speed-dial__content--top-center\n        flex-direction: column-reverse\n\n    > *\n      &:nth-child(1)\n        transition-delay: 0.001s\n      @for $i from 2 through 10\n        &:nth-child(#{$i})\n          transition-delay: 0.05s * ($i - 1)\n"
  },
  {
    "path": "packages/vuetify/src/components/VSpeedDial/VSpeedDial.tsx",
    "content": "// Styles\nimport './VSpeedDial.sass'\n\n// Components\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\nimport { makeVMenuProps, VMenu } from '@/components/VMenu/VMenu'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { useProxiedModel } from '@/composables/proxiedModel'\nimport { MaybeTransition } from '@/composables/transition'\n\n// Utilities\nimport { computed, ref } from 'vue'\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { OverlaySlots } from '@/components/VOverlay/VOverlay'\nimport type { Anchor } from '@/util'\n\nexport const makeVSpeedDialProps = propsFactory({\n  ...makeComponentProps(),\n  ...makeVMenuProps({\n    offset: 8,\n    minWidth: 0,\n    openDelay: 0,\n    closeDelay: 100,\n    location: 'top center' as const,\n    transition: 'scale-transition',\n  }),\n}, 'VSpeedDial')\n\nexport const VSpeedDial = genericComponent<OverlaySlots>()({\n  name: 'VSpeedDial',\n\n  props: makeVSpeedDialProps(),\n\n  emits: {\n    'update:modelValue': (value: boolean) => true,\n  },\n\n  setup (props, { slots }) {\n    const model = useProxiedModel(props, 'modelValue')\n\n    const menuRef = ref<VMenu>()\n\n    const location = computed<Anchor>(() => {\n      const [y, x = 'center'] = props.location?.split(' ') ?? []\n\n      return `${y} ${x}` as Anchor\n    })\n\n    const locationClasses = computed(() => ({\n      [`v-speed-dial__content--${location.value.replace(' ', '-')}`]: true,\n    }))\n\n    useRender(() => {\n      const menuProps = VMenu.filterProps(props)\n\n      return (\n        <VMenu\n          { ...menuProps }\n          v-model={ model.value }\n          class={ props.class }\n          style={ props.style }\n          contentClass={[\n            'v-speed-dial__content',\n            locationClasses.value,\n            props.contentClass,\n          ]}\n          location={ location.value }\n          ref={ menuRef }\n          transition=\"fade-transition\"\n        >\n          {{\n            ...slots,\n            default: slotProps => (\n              <VDefaultsProvider\n                defaults={{\n                  VBtn: {\n                    size: 'small',\n                  },\n                }}\n              >\n                <MaybeTransition\n                  appear\n                  group\n                  transition={ props.transition }\n                >\n                  { slots.default?.(slotProps) }\n                </MaybeTransition>\n              </VDefaultsProvider>\n            ),\n          }}\n        </VMenu>\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VSpeedDial = InstanceType<typeof VSpeedDial>\n"
  },
  {
    "path": "packages/vuetify/src/components/VSpeedDial/index.ts",
    "content": "export { VSpeedDial } from './VSpeedDial'\n"
  },
  {
    "path": "packages/vuetify/src/components/VStepper/VStepper.sass",
    "content": "@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-stepper.v-sheet\n    overflow: hidden\n    @include tools.elevation($stepper-elevation)\n    @include tools.rounded($stepper-border-radius)\n\n    &.v-stepper--flat\n      @include tools.elevation(0)\n\n  .v-stepper-header\n    align-items: center\n    display: flex\n    position: relative\n    overflow-x: auto\n    justify-content: space-between\n    z-index: 1\n    @include tools.elevation($stepper-header-elevation)\n\n    .v-divider\n      margin: $stepper-header-divider-margin\n\n      &:last-child\n        margin-inline-end: 0\n\n      &:first-child\n        margin-inline-start: 0\n\n    .v-stepper--alt-labels &\n      height: auto\n\n      .v-divider\n        align-self: flex-start\n        margin: $stepper-alt-labels-header-divider\n\n  .v-stepper-window\n    margin: $stepper-window-margin\n\n  .v-stepper-actions\n    display: flex\n    align-items: center\n    justify-content: space-between\n    padding: $stepper-actions-padding\n\n    .v-stepper &\n      padding: $stepper-actions-stepper-padding\n\n    .v-stepper-window-item &\n      padding: $stepper-actions-stepper-window-item-padding\n"
  },
  {
    "path": "packages/vuetify/src/components/VStepper/VStepper.tsx",
    "content": "// Styles\nimport './VStepper.sass'\n\n// Components\nimport { VStepperSymbol } from './shared'\nimport { makeVStepperActionsProps, VStepperActions } from './VStepperActions'\nimport { VStepperHeader } from './VStepperHeader'\nimport { VStepperItem } from './VStepperItem'\nimport { VStepperWindow } from './VStepperWindow'\nimport { VStepperWindowItem } from './VStepperWindowItem'\nimport { VDivider } from '@/components/VDivider'\nimport { makeVSheetProps, VSheet } from '@/components/VSheet/VSheet'\n\n// Composables\nimport { provideDefaults } from '@/composables/defaults'\nimport { makeDisplayProps, useDisplay } from '@/composables/display'\nimport { makeGroupProps, useGroup } from '@/composables/group'\nimport { IconValue } from '@/composables/icons'\n\n// Utilities\nimport { computed, toRefs } from 'vue'\nimport { genericComponent, getPropertyFromItem, pick, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { StepperItem, StepperItemSlot } from './VStepperItem'\nimport type { GenericProps, SelectItemKey } from '@/util'\n\nexport type VStepperSlot = {\n  prev: () => void\n  next: () => void\n}\n\nexport type VStepperSlots = {\n  actions: VStepperSlot\n  default: VStepperSlot\n  header: StepperItem\n  'header-item': StepperItemSlot\n  icon: StepperItemSlot\n  title: StepperItemSlot\n  subtitle: StepperItemSlot\n  item: StepperItem\n  prev: never\n  next: never\n} & {\n  [key: `header-item.${string}`]: StepperItemSlot\n  [key: `item.${string}`]: StepperItem\n}\n\nexport const makeStepperProps = propsFactory({\n  altLabels: Boolean,\n  bgColor: String,\n  completeIcon: IconValue,\n  editIcon: IconValue,\n  editable: Boolean,\n  errorIcon: IconValue,\n  hideActions: Boolean,\n  items: {\n    type: Array as PropType<readonly StepperItem[]>,\n    default: () => ([]),\n  },\n  itemTitle: {\n    type: [String, Array, Function] as PropType<SelectItemKey>,\n    default: 'title',\n  },\n  itemValue: {\n    type: [String, Array, Function] as PropType<SelectItemKey>,\n    default: 'value',\n  },\n  itemProps: {\n    type: [Boolean, String, Array, Function] as PropType<SelectItemKey>,\n    default: 'props',\n  },\n  nonLinear: Boolean,\n  flat: Boolean,\n\n  ...makeDisplayProps(),\n}, 'Stepper')\n\nexport const makeVStepperProps = propsFactory({\n  ...makeStepperProps(),\n  ...makeGroupProps({\n    mandatory: 'force' as const,\n    selectedClass: 'v-stepper-item--selected',\n  }),\n  ...makeVSheetProps(),\n  ...pick(makeVStepperActionsProps(), ['prevText', 'nextText']),\n}, 'VStepper')\n\nexport const VStepper = genericComponent<new <TModel>(\n  props: {\n    modelValue?: TModel\n    'onUpdate:modelValue'?: (value: TModel) => void\n  },\n  slots: VStepperSlots\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VStepper',\n\n  props: makeVStepperProps(),\n\n  emits: {\n    'update:modelValue': (v: unknown) => true,\n  },\n\n  setup (props, { slots }) {\n    const { items: _items, next, prev, selected } = useGroup(props, VStepperSymbol)\n    const { displayClasses, mobile } = useDisplay(props)\n    const { completeIcon, editIcon, errorIcon, color, editable, prevText, nextText } = toRefs(props)\n\n    const items = computed(() => props.items.map((item, index) => {\n      const title = getPropertyFromItem(item, props.itemTitle, item)\n      const value = getPropertyFromItem(item, props.itemValue, index + 1)\n      const itemProps = props.itemProps === true\n        ? item\n        : getPropertyFromItem(item, props.itemProps)\n\n      const _props = {\n        title,\n        value,\n        ...itemProps,\n      }\n\n      return {\n        title: _props.title,\n        value: _props.value,\n        props: _props,\n        raw: item,\n      }\n    }))\n    const activeIndex = computed(() => {\n      return _items.value.findIndex(item => selected.value.includes(item.id))\n    })\n    const disabled = computed(() => {\n      if (props.disabled) return props.disabled\n      if (activeIndex.value === 0) return 'prev'\n      if (activeIndex.value === _items.value.length - 1) return 'next'\n\n      return false\n    })\n\n    provideDefaults({\n      VStepperItem: {\n        editable,\n        errorIcon,\n        completeIcon,\n        editIcon,\n        prevText,\n        nextText,\n      },\n      VStepperActions: {\n        color,\n        disabled,\n        prevText,\n        nextText,\n      },\n    })\n\n    useRender(() => {\n      const sheetProps = VSheet.filterProps(props)\n\n      const hasHeader = !!(slots.header || props.items.length)\n      const hasWindow = props.items.length > 0\n      const hasActions = !props.hideActions && !!(hasWindow || slots.actions)\n\n      return (\n        <VSheet\n          { ...sheetProps }\n          color={ props.bgColor }\n          class={[\n            'v-stepper',\n            {\n              'v-stepper--alt-labels': props.altLabels,\n              'v-stepper--flat': props.flat,\n              'v-stepper--non-linear': props.nonLinear,\n              'v-stepper--mobile': mobile.value,\n            },\n            displayClasses.value,\n            props.class,\n          ]}\n          style={ props.style }\n        >\n          { hasHeader && (\n            <VStepperHeader key=\"stepper-header\">\n              { items.value.map(({ raw, ...item }, index) => (\n                <>\n                  { !!index && (<VDivider />) }\n\n                  <VStepperItem\n                    { ...item.props }\n                    v-slots={{\n                      default: slots[`header-item.${item.value}`] ?? slots.header,\n                      icon: slots.icon,\n                      title: slots.title,\n                      subtitle: slots.subtitle,\n                    }}\n                  />\n                </>\n              ))}\n            </VStepperHeader>\n          )}\n\n          { hasWindow && (\n            <VStepperWindow key=\"stepper-window\">\n              { items.value.map(item => (\n                <VStepperWindowItem\n                  value={ item.value }\n                  v-slots={{\n                    default: () => slots[`item.${item.value}`]?.(item) ?? slots.item?.(item),\n                  }}\n                />\n              ))}\n            </VStepperWindow>\n          )}\n\n          { slots.default?.({ prev, next }) }\n\n          { hasActions && (\n            slots.actions?.({ next, prev }) ?? (\n              <VStepperActions\n                key=\"stepper-actions\"\n                onClick:prev={ prev }\n                onClick:next={ next }\n                v-slots={ slots }\n              />\n            )\n          )}\n        </VSheet>\n      )\n    })\n\n    return {\n      prev,\n      next,\n    }\n  },\n})\n\nexport type VStepper = InstanceType<typeof VStepper>\n"
  },
  {
    "path": "packages/vuetify/src/components/VStepper/VStepperActions.tsx",
    "content": "// Components\nimport { VBtn } from '@/components/VBtn/VBtn'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider/VDefaultsProvider'\n\n// Composables\nimport { useLocale } from '@/composables/locale'\n\n// Utilities\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\nexport type VStepperActionsSlots = {\n  prev: {\n    props: { onClick: () => void }\n  }\n  next: {\n    props: { onClick: () => void }\n  }\n}\n\nexport const makeVStepperActionsProps = propsFactory({\n  color: String,\n  disabled: {\n    type: [Boolean, String] as PropType<boolean | 'next' | 'prev'>,\n    default: false,\n  },\n  prevText: {\n    type: String,\n    default: '$vuetify.stepper.prev',\n  },\n  nextText: {\n    type: String,\n    default: '$vuetify.stepper.next',\n  },\n}, 'VStepperActions')\n\nexport const VStepperActions = genericComponent<VStepperActionsSlots>()({\n  name: 'VStepperActions',\n\n  props: makeVStepperActionsProps(),\n\n  emits: {\n    'click:prev': () => true,\n    'click:next': () => true,\n  },\n\n  setup (props, { emit, slots }) {\n    const { t } = useLocale()\n    function onClickPrev () {\n      emit('click:prev')\n    }\n\n    function onClickNext () {\n      emit('click:next')\n    }\n\n    useRender(() => {\n      const prevSlotProps = {\n        onClick: onClickPrev,\n      }\n      const nextSlotProps = {\n        onClick: onClickNext,\n      }\n\n      return (\n        <div class=\"v-stepper-actions\">\n          <VDefaultsProvider\n            defaults={{\n              VBtn: {\n                disabled: ['prev', true].includes(props.disabled),\n                text: t(props.prevText),\n                variant: 'text',\n              },\n            }}\n          >\n            { slots.prev?.({ props: prevSlotProps }) ?? (\n              <VBtn { ...prevSlotProps } />\n            )}\n          </VDefaultsProvider>\n\n          <VDefaultsProvider\n            defaults={{\n              VBtn: {\n                color: props.color,\n                disabled: ['next', true].includes(props.disabled),\n                text: t(props.nextText),\n                variant: 'tonal',\n              },\n            }}\n          >\n            { slots.next?.({ props: nextSlotProps }) ?? (\n              <VBtn { ...nextSlotProps } />\n            )}\n          </VDefaultsProvider>\n        </div>\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VStepperActions = InstanceType<typeof VStepperActions>\n"
  },
  {
    "path": "packages/vuetify/src/components/VStepper/VStepperHeader.ts",
    "content": "// Utilities\nimport { createSimpleFunctional } from '@/util'\n\nexport const VStepperHeader = createSimpleFunctional('v-stepper-header')\n\nexport type VStepperHeader = InstanceType<typeof VStepperHeader>\n"
  },
  {
    "path": "packages/vuetify/src/components/VStepper/VStepperItem.sass",
    "content": "@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-stepper-item\n    margin: 0\n    font: inherit\n    overflow: visible\n    text-transform: none\n    background-color: transparent\n    border-style: none\n    color: inherit\n    align-items: center\n    align-self: stretch\n    display: inline-flex\n    flex: none\n    outline: none\n    opacity: $stepper-item-opacity\n    padding: $stepper-item-padding\n    position: relative\n    transition-duration: $stepper-item-transition-duration\n    transition-property: $stepper-item-transition-property\n    transition-timing-function: $stepper-item-transition-timing-function\n\n    @include tools.states('.v-stepper-item__overlay')\n\n    .v-stepper--non-linear &\n      opacity: var(--v-high-emphasis-opacity)\n\n    &--selected\n      opacity: 1\n\n    &--error\n      color: rgb(var(--v-theme-error))\n\n    &--disabled\n      opacity: var(--v-medium-emphasis-opacity)\n\n    &[disabled],\n    &--disabled\n      pointer-events: none\n\n    .v-stepper--alt-labels &\n      flex-direction: column\n      justify-content: flex-start\n      align-items: center\n      flex-basis: $stepper-alt-labels-flex-basis\n\n  .v-stepper-item__avatar.v-avatar\n    background: $stepper-item-avatar-background\n    color: $stepper-item-avatar-color\n    font-size: $stepper-item-avatar-font-size\n    margin-inline-end: $stepper-item-avatar-margin-inline-end\n\n    .v-stepper--mobile &\n      margin-inline-end: 0\n\n    .v-icon\n      font-size: $stepper-item-avatar-icon-font-size\n\n    .v-stepper-item--selected &,\n    .v-stepper-item--complete &\n      background: rgb(var(--v-theme-surface-variant))\n\n    .v-stepper-item--error &\n      background: rgb(var(--v-theme-error))\n\n    .v-stepper--alt-labels &\n      margin-bottom: $stepper-item-alt-labels-margin-bottom\n      margin-inline-end: 0\n\n  .v-stepper-item__content\n    text-align: start\n\n    .v-stepper--alt-labels &\n      text-align: center\n\n  .v-stepper-item__title\n    line-height: $stepper-item-title-line-height\n\n    .v-stepper--mobile &\n      display: none\n\n  .v-stepper-item__subtitle\n    font-size: $stepper-item-subtitle-font-size\n    line-height: $stepper-item-subtitle-line-height\n    opacity: $stepper-item-subtitle-opacity\n\n    .v-stepper--mobile &\n      display: none\n\n  .v-stepper-item__overlay\n    background-color: currentColor\n    border-radius: inherit\n    opacity: 0\n    transition: opacity .2s ease-in-out\n\n  .v-stepper-item__overlay,\n  .v-stepper-item__underlay\n    pointer-events: none\n    @include tools.absolute()\n"
  },
  {
    "path": "packages/vuetify/src/components/VStepper/VStepperItem.tsx",
    "content": "// Styles\nimport './VStepperItem.sass'\n\n// Components\nimport { VAvatar } from '@/components/VAvatar/VAvatar'\nimport { VIcon } from '@/components/VIcon/VIcon'\n\n// Composables\nimport { makeGroupItemProps, useGroupItem } from '@/composables/group'\nimport { IconValue } from '@/composables/icons'\nimport { genOverlays } from '@/composables/variant'\n\n// Directives\nimport vRipple from '@/directives/ripple'\n\n// Utilities\nimport { computed } from 'vue'\nimport { VStepperSymbol } from './shared'\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { RippleDirectiveBinding } from '@/directives/ripple'\n\nexport type StepperItem = string | Record<string, any>\n\nexport type StepperItemSlot<T = any> = {\n  canEdit: boolean\n  hasError: boolean\n  hasCompleted: boolean\n  title?: string | number\n  subtitle?: string | number\n  step: T\n}\n\nexport type VStepperItemSlots<T = any> = {\n  default: StepperItemSlot<T>\n  icon: StepperItemSlot<T>\n  title: StepperItemSlot<T>\n  subtitle: StepperItemSlot<T>\n}\n\nexport type ValidationRule = () => string | boolean\n\nexport const makeStepperItemProps = propsFactory({\n  color: String,\n  title: String,\n  subtitle: String,\n  complete: Boolean,\n  completeIcon: {\n    type: IconValue,\n    default: '$complete',\n  },\n  editable: Boolean,\n  editIcon: {\n    type: IconValue,\n    default: '$edit',\n  },\n  error: Boolean,\n  errorIcon: {\n    type: IconValue,\n    default: '$error',\n  },\n  icon: IconValue,\n  ripple: {\n    type: [Boolean, Object] as PropType<RippleDirectiveBinding['value']>,\n    default: true,\n  },\n  rules: {\n    type: Array as PropType<readonly ValidationRule[]>,\n    default: () => ([]),\n  },\n}, 'StepperItem')\n\nexport const makeVStepperItemProps = propsFactory({\n  ...makeStepperItemProps(),\n  ...makeGroupItemProps(),\n}, 'VStepperItem')\n\nexport const VStepperItem = genericComponent<VStepperItemSlots>()({\n  name: 'VStepperItem',\n\n  directives: { vRipple },\n\n  props: makeVStepperItemProps(),\n\n  emits: {\n    'group:selected': (val: { value: boolean }) => true,\n  },\n\n  setup (props, { slots }) {\n    const group = useGroupItem(props, VStepperSymbol, true)\n    const step = computed(() => group?.value.value ?? props.value)\n    const isValid = computed(() => props.rules.every(handler => handler() === true))\n    const isClickable = computed(() => !props.disabled && props.editable)\n    const canEdit = computed(() => !props.disabled && props.editable)\n    const hasError = computed(() => props.error || !isValid.value)\n    const hasCompleted = computed(() => props.complete || (props.rules.length > 0 && isValid.value))\n    const icon = computed(() => {\n      if (hasError.value) return props.errorIcon\n      if (hasCompleted.value) return props.completeIcon\n      if (group.isSelected.value && props.editable) return props.editIcon\n\n      return props.icon\n    })\n    const slotProps = computed(() => ({\n      canEdit: canEdit.value,\n      hasError: hasError.value,\n      hasCompleted: hasCompleted.value,\n      title: props.title,\n      subtitle: props.subtitle,\n      step: step.value,\n      value: props.value,\n    }))\n\n    useRender(() => {\n      const hasColor = (\n        !group ||\n        group.isSelected.value ||\n        hasCompleted.value ||\n        canEdit.value\n      ) && (\n        !hasError.value &&\n        !props.disabled\n      )\n      const hasTitle = !!(props.title != null || slots.title)\n      const hasSubtitle = !!(props.subtitle != null || slots.subtitle)\n\n      function onClick () {\n        group?.toggle()\n      }\n\n      return (\n        <button\n          class={[\n            'v-stepper-item',\n            {\n              'v-stepper-item--complete': hasCompleted.value,\n              'v-stepper-item--disabled': props.disabled,\n              'v-stepper-item--error': hasError.value,\n            },\n            group?.selectedClass.value,\n          ]}\n          disabled={ !props.editable }\n          type=\"button\"\n          v-ripple={[\n            props.editable && props.ripple,\n            null,\n            null,\n          ]}\n          onClick={ onClick }\n        >\n          { isClickable.value && genOverlays(true, 'v-stepper-item') }\n\n          <VAvatar\n            key=\"stepper-avatar\"\n            class=\"v-stepper-item__avatar\"\n            color={ hasColor ? props.color : undefined }\n            size={ 24 }\n          >\n            { slots.icon?.(slotProps.value) ?? (\n              icon.value ? (\n                <VIcon icon={ icon.value }></VIcon>\n              ) : step.value\n            )}\n          </VAvatar>\n\n          <div class=\"v-stepper-item__content\">\n            { hasTitle && (\n              <div\n                key=\"title\"\n                class=\"v-stepper-item__title\"\n              >\n                { slots.title?.(slotProps.value) ?? props.title }\n              </div>\n            )}\n\n            { hasSubtitle && (\n              <div\n                key=\"subtitle\"\n                class=\"v-stepper-item__subtitle\"\n              >\n                { slots.subtitle?.(slotProps.value) ?? props.subtitle }\n              </div>\n            )}\n\n            { slots.default?.(slotProps.value) }\n          </div>\n        </button>\n      )\n    })\n    return {}\n  },\n})\n\nexport type VStepperItem = InstanceType<typeof VStepperItem>\n"
  },
  {
    "path": "packages/vuetify/src/components/VStepper/VStepperWindow.tsx",
    "content": "// Components\nimport { VStepperSymbol } from './shared'\nimport { makeVWindowProps, VWindow } from '@/components/VWindow/VWindow'\n\n// Composables\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { computed, inject } from 'vue'\nimport { genericComponent, omit, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { VWindowSlots } from '@/components/VWindow/VWindow'\nimport type { GenericProps } from '@/util'\n\nexport const makeVStepperWindowProps = propsFactory({\n  ...omit(makeVWindowProps(), ['continuous', 'nextIcon', 'prevIcon', 'showArrows', 'touch', 'mandatory']),\n}, 'VStepperWindow')\n\nexport const VStepperWindow = genericComponent<new <TModel>(\n  props: {\n    modelValue?: TModel\n    'onUpdate:modelValue'?: (value: TModel) => void\n  },\n  slots: VWindowSlots\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VStepperWindow',\n\n  props: makeVStepperWindowProps(),\n\n  emits: {\n    'update:modelValue': (v: unknown) => true,\n  },\n\n  setup (props, { slots }) {\n    const group = inject(VStepperSymbol, null)\n    const _model = useProxiedModel(props, 'modelValue')\n\n    const model = computed({\n      get () {\n        // Always return modelValue if defined\n        // or if not within a VStepper group\n        if (_model.value != null || !group) return _model.value\n\n        // If inside of a VStepper, find the currently selected\n        // item by id. Item value may be assigned by its index\n        return group.items.value.find(item => group.selected.value.includes(item.id))?.value\n      },\n      set (val) {\n        _model.value = val\n      },\n    })\n\n    useRender(() => {\n      const windowProps = VWindow.filterProps(props)\n\n      return (\n        <VWindow\n          _as=\"VStepperWindow\"\n          { ...windowProps }\n          v-model={ model.value }\n          class={[\n            'v-stepper-window',\n            props.class,\n          ]}\n          style={ props.style }\n          mandatory={ false }\n          touch={ false }\n          v-slots={ slots }\n        />\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VStepperWindow = InstanceType<typeof VStepperWindow>\n"
  },
  {
    "path": "packages/vuetify/src/components/VStepper/VStepperWindowItem.tsx",
    "content": "// Components\nimport { makeVWindowItemProps, VWindowItem } from '@/components/VWindow/VWindowItem'\n\n// Utilities\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\nexport const makeVStepperWindowItemProps = propsFactory({\n  ...makeVWindowItemProps(),\n}, 'VStepperWindowItem')\n\nexport const VStepperWindowItem = genericComponent()({\n  name: 'VStepperWindowItem',\n\n  props: makeVStepperWindowItemProps(),\n\n  setup (props, { slots }) {\n    useRender(() => {\n      const windowItemProps = VWindowItem.filterProps(props)\n\n      return (\n        <VWindowItem\n          _as=\"VStepperWindowItem\"\n          { ...windowItemProps }\n          class={[\n            'v-stepper-window-item',\n            props.class,\n          ]}\n          style={ props.style }\n          v-slots={ slots }\n        />\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VStepperWindowItem = InstanceType<typeof VStepperWindowItem>\n"
  },
  {
    "path": "packages/vuetify/src/components/VStepper/_variables.scss",
    "content": "@use '../../styles/settings';\n@use '../../styles/tools';\n\n$stepper-actions-padding: 1rem !default;\n$stepper-actions-stepper-padding: 0 1.5rem 1rem !default;\n$stepper-actions-stepper-window-item-padding: 1.5rem 0 0 !default;\n$stepper-alt-labels-flex-basis : 175px !default;\n$stepper-alt-labels-header-divider: 35px -67px 0 !default;\n$stepper-border-radius: 4px !default;\n$stepper-elevation: 1 !default;\n$stepper-item-opacity: var(--v-medium-emphasis-opacity) !default;\n$stepper-item-padding: 1.5rem !default;\n$stepper-item-transition-duration: .2s !default;\n$stepper-item-transition-property: opacity !default;\n$stepper-item-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1) !default;\n$stepper-header-divider-margin: 0 -16px !default;\n$stepper-header-elevation: 1 !default;\n$stepper-window-margin: 1.5rem !default;\n$stepper-item-avatar-background: tools.theme-color('surface-variant', var(--v-medium-emphasis-opacity)) !default;\n$stepper-item-avatar-color: rgb(var(--v-theme-on-surface-variant)) !default;\n$stepper-item-avatar-font-size: .75rem !default;\n$stepper-item-avatar-margin-inline-end: 8px !default;\n$stepper-item-avatar-icon-font-size: .875rem !default;\n$stepper-item-alt-labels-margin-bottom: 16px !default;\n$stepper-item-title-line-height: 1 !default;\n$stepper-item-subtitle-font-size: .75rem !default;\n$stepper-item-subtitle-line-height: 1 !default;\n$stepper-item-subtitle-opacity: var(--v-medium-emphasis-opacity) !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VStepper/index.ts",
    "content": "export { VStepper } from './VStepper'\nexport { VStepperActions } from './VStepperActions'\nexport { VStepperHeader } from './VStepperHeader'\nexport { VStepperItem } from './VStepperItem'\nexport { VStepperWindow } from './VStepperWindow'\nexport { VStepperWindowItem } from './VStepperWindowItem'\n"
  },
  {
    "path": "packages/vuetify/src/components/VStepper/shared.ts",
    "content": "// Types\nimport type { InjectionKey } from 'vue'\nimport type { GroupProvide } from '@/composables/group'\n\nexport const VStepperSymbol: InjectionKey<GroupProvide> = Symbol.for('vuetify:v-stepper')\n"
  },
  {
    "path": "packages/vuetify/src/components/VSwitch/VSwitch.sass",
    "content": "@use 'sass:selector'\n@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-switch\n    .v-label\n      padding-inline-start: $switch-label-margin-inline-start\n\n  .v-switch__loader\n    display: flex\n\n    .v-progress-circular\n      color: $switch-loader-color\n\n  .v-switch__track,\n  .v-switch__thumb\n    transition: none\n\n    .v-selection-control--error:not(.v-selection-control--disabled) &\n      background-color: $switch-error-background-color\n      color: $switch-error-color\n\n  .v-switch__track-true\n    margin-inline-end: auto\n\n    .v-selection-control:not(.v-selection-control--dirty) &\n      opacity: 0\n\n  .v-switch__track-false\n    margin-inline-start: auto\n\n    .v-selection-control--dirty &\n      opacity: 0\n\n  .v-switch__track\n    display: inline-flex\n    align-items: center\n    font-size: .5rem\n    padding: 0 5px\n    background-color: $switch-track-background\n    border-radius: $switch-track-radius\n    height: $switch-track-height\n    opacity: $switch-track-opacity\n    min-width: $switch-track-width\n    cursor: pointer\n    transition: $switch-track-transition\n\n    .v-switch--inset &\n      border-radius: $switch-inset-track-border-radius\n      font-size: .75rem\n      height: $switch-inset-track-height\n      min-width: $switch-inset-track-width\n\n  .v-switch__thumb\n    align-items: center\n    background-color: $switch-thumb-background\n    color: $switch-thumb-color\n    border-radius: $switch-thumb-radius\n    display: flex\n    font-size: .75rem\n    height: $switch-thumb-height\n    justify-content: center\n    width: $switch-thumb-width\n    pointer-events: none\n    transition: $switch-thumb-transition\n    position: relative\n    overflow: hidden\n\n    .v-switch:not(.v-switch--inset) &\n      @include tools.elevation($switch-thumb-elevation)\n\n    .v-switch.v-switch--flat:not(.v-switch--inset) &\n      background: $switch-thumb-flat-background\n      color: $switch-thumb-flat-color\n\n      @include tools.elevation(0)\n\n    .v-switch--inset &\n      height: $switch-inset-thumb-height\n      width: $switch-inset-thumb-width\n      transform: scale(calc($switch-inset-thumb-off-height / $switch-inset-thumb-height))\n\n      &--filled\n        transform: none\n\n    .v-switch--inset .v-selection-control--dirty &\n      transform: none\n      transition: .15s .05s transform settings.$decelerated-easing\n\n  .v-switch\n    $switch-thumb-transform: $switch-track-width * .5 - $switch-thumb-width * .5 + $switch-thumb-offset\n\n    &.v-input\n      flex: $switch-flex\n\n    .v-selection-control\n      min-height: var(--v-input-control-height)\n\n    .v-selection-control__input\n      border-radius: 50%\n      transition: $switch-control-input-transition\n      position: absolute\n      @include tools.ltr()\n        transform: translateX(-$switch-thumb-transform)\n      @include tools.rtl()\n        transform: translateX($switch-thumb-transform)\n\n      .v-icon\n        position: absolute\n\n    .v-selection-control--dirty\n      .v-selection-control__input\n        @include tools.ltr()\n          transform: translateX($switch-thumb-transform)\n        @include tools.rtl()\n          transform: translateX(-$switch-thumb-transform)\n\n    &.v-switch--indeterminate\n      .v-selection-control__input\n        transform: scale(.8)\n      .v-switch__thumb\n        transform: scale(.75)\n        box-shadow: none\n\n    &.v-switch--inset\n      .v-selection-control__wrapper\n        width: auto\n\n    &.v-input--vertical\n      .v-label\n        min-width: max-content\n\n      .v-selection-control__wrapper\n        transform: $switch-thumb-vertical-transform\n\n  @media (forced-colors: active)\n    .v-switch\n      .v-switch__loader\n        .v-progress-circular\n          color: currentColor\n\n      .v-switch__thumb\n        background-color: buttontext\n\n      .v-switch__track,\n      .v-switch__thumb\n        border: 1px solid\n        color: buttontext\n\n      &:not(.v-switch--loading):not(.v-input--disabled)\n        .v-selection-control--dirty\n          .v-switch__thumb\n            background-color: highlight\n\n      &:not(.v-input--disabled)\n        .v-selection-control--dirty\n          .v-switch__track\n            background-color: highlight\n\n          .v-switch__track,\n          .v-switch__thumb\n            color: highlight\n\n      &.v-switch--inset\n        .v-switch__track\n          border-width: 2px\n\n        &:not(.v-switch--loading):not(.v-input--disabled)\n          .v-selection-control--dirty\n            .v-switch__thumb\n              background-color: highlighttext\n              color: highlighttext\n\n      &.v-input--disabled\n        .v-switch__thumb\n          background-color: graytext\n\n        .v-switch__track,\n        .v-switch__thumb\n          color: graytext\n\n      &.v-switch--loading\n        .v-switch__thumb\n          background-color: canvas\n\n        &.v-switch--inset,\n        &.v-switch--indeterminate\n          .v-switch__thumb\n            border-width: 0\n"
  },
  {
    "path": "packages/vuetify/src/components/VSwitch/VSwitch.tsx",
    "content": "// Styles\nimport './VSwitch.sass'\n\n// Components\nimport { VScaleTransition } from '@/components/transitions'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider/VDefaultsProvider'\nimport { VIcon } from '@/components/VIcon'\nimport { makeVInputProps, VInput } from '@/components/VInput/VInput'\nimport { VProgressCircular } from '@/components/VProgressCircular'\nimport { makeVSelectionControlProps, VSelectionControl } from '@/components/VSelectionControl/VSelectionControl'\n\n// Composables\nimport { useFocus } from '@/composables/focus'\nimport { forwardRefs } from '@/composables/forwardRefs'\nimport { LoaderSlot, useLoader } from '@/composables/loader'\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { ref, toRef, useId } from 'vue'\nimport { filterInputAttrs, genericComponent, propsFactory, SUPPORTS_MATCH_MEDIA, useRender } from '@/util'\n\n// Types\nimport type { ComputedRef, Ref } from 'vue'\nimport type { VInputSlots } from '@/components/VInput/VInput'\nimport type { VSelectionControlSlots } from '@/components/VSelectionControl/VSelectionControl'\nimport type { IconValue } from '@/composables/icons'\nimport type { LoaderSlotProps } from '@/composables/loader'\nimport type { GenericProps } from '@/util'\n\nexport type VSwitchSlot = {\n  model: Ref<boolean>\n  isValid: ComputedRef<boolean | null>\n}\n\nexport type VSwitchSlots =\n  & VInputSlots\n  & VSelectionControlSlots\n  & {\n    loader: LoaderSlotProps\n    thumb: { icon: IconValue | undefined } & VSwitchSlot\n    'track-false': VSwitchSlot\n    'track-true': VSwitchSlot\n  }\n\nexport const makeVSwitchProps = propsFactory({\n  indeterminate: Boolean,\n  inset: Boolean,\n  flat: Boolean,\n  loading: {\n    type: [Boolean, String],\n    default: false,\n  },\n\n  ...makeVInputProps(),\n  ...makeVSelectionControlProps(),\n}, 'VSwitch')\n\nexport const VSwitch = genericComponent<new <T>(\n  props: {\n    modelValue?: T | null\n    'onUpdate:modelValue'?: (value: T | null) => void\n  },\n  slots: VSwitchSlots,\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VSwitch',\n\n  inheritAttrs: false,\n\n  props: makeVSwitchProps(),\n\n  emits: {\n    'update:focused': (focused: boolean) => true,\n    'update:modelValue': (value: any) => true,\n    'update:indeterminate': (value: boolean) => true,\n  },\n\n  setup (props, { attrs, slots }) {\n    const indeterminate = useProxiedModel(props, 'indeterminate')\n    const model = useProxiedModel(props, 'modelValue')\n    const { loaderClasses } = useLoader(props)\n    const { isFocused, focus, blur } = useFocus(props)\n    const control = ref<VSelectionControl>()\n    const inputRef = ref<VInput>()\n    const isForcedColorsModeActive = SUPPORTS_MATCH_MEDIA && window.matchMedia('(forced-colors: active)').matches\n\n    const loaderColor = toRef(() => {\n      return typeof props.loading === 'string' && props.loading !== ''\n        ? props.loading\n        : props.color\n    })\n\n    const uid = useId()\n    const id = toRef(() => props.id || `switch-${uid}`)\n\n    function onChange () {\n      if (indeterminate.value) {\n        indeterminate.value = false\n      }\n    }\n    function onTrackClick (e: Event) {\n      e.stopPropagation()\n      e.preventDefault()\n      control.value?.input?.click()\n    }\n\n    useRender(() => {\n      const [rootAttrs, controlAttrs] = filterInputAttrs(attrs)\n      const inputProps = VInput.filterProps(props)\n      const controlProps = VSelectionControl.filterProps(props)\n\n      return (\n        <VInput\n          ref={ inputRef }\n          class={[\n            'v-switch',\n            { 'v-switch--flat': props.flat },\n            { 'v-switch--inset': props.inset },\n            { 'v-switch--indeterminate': indeterminate.value },\n            loaderClasses.value,\n            props.class,\n          ]}\n          { ...rootAttrs }\n          { ...inputProps }\n          v-model={ model.value }\n          id={ id.value }\n          focused={ isFocused.value }\n          style={ props.style }\n        >\n          {{\n            ...slots,\n            default: ({\n              id,\n              messagesId,\n              isDisabled,\n              isReadonly,\n              isValid,\n            }) => {\n              const slotProps = {\n                model,\n                isValid,\n              }\n\n              return (\n                <VSelectionControl\n                  ref={ control }\n                  { ...controlProps }\n                  v-model={ model.value }\n                  id={ id.value }\n                  aria-describedby={ messagesId.value }\n                  type=\"checkbox\"\n                  onUpdate:modelValue={ onChange }\n                  aria-checked={ indeterminate.value ? 'mixed' : undefined }\n                  disabled={ isDisabled.value }\n                  readonly={ isReadonly.value }\n                  onFocus={ focus }\n                  onBlur={ blur }\n                  { ...controlAttrs }\n                >\n                  {{\n                    ...slots,\n                    default: ({ backgroundColorClasses, backgroundColorStyles }) => (\n                      <div\n                        class={[\n                          'v-switch__track',\n                          !isForcedColorsModeActive ? backgroundColorClasses.value : undefined,\n                        ]}\n                        style={ backgroundColorStyles.value }\n                        onClick={ onTrackClick }\n                      >\n                        { slots['track-true'] && (\n                          <div key=\"prepend\" class=\"v-switch__track-true\">\n                            { slots['track-true'](slotProps) }\n                          </div>\n                        )}\n\n                        { slots['track-false'] && (\n                          <div key=\"append\" class=\"v-switch__track-false\">\n                            { slots['track-false'](slotProps) }\n                          </div>\n                        )}\n                      </div>\n                    ),\n                    input: ({ inputNode, icon, backgroundColorClasses, backgroundColorStyles }) => (\n                      <>\n                        { inputNode }\n                        <div\n                          class={[\n                            'v-switch__thumb',\n                            { 'v-switch__thumb--filled': icon || props.loading },\n                            props.inset || isForcedColorsModeActive ? undefined : backgroundColorClasses.value,\n                          ]}\n                          style={ props.inset ? undefined : backgroundColorStyles.value }\n                        >\n                          { slots.thumb ? (\n                            <VDefaultsProvider\n                              defaults={{\n                                VIcon: {\n                                  icon,\n                                  size: 'x-small',\n                                },\n                              }}\n                            >\n                              { slots.thumb({ ...slotProps, icon }) }\n                            </VDefaultsProvider>\n                          ) : (\n                            <VScaleTransition>\n                              { !props.loading ? (\n                                (icon && (\n                                  <VIcon\n                                    key={ String(icon) }\n                                    icon={ icon }\n                                    size=\"x-small\"\n                                  />\n                                ))) : (\n                                <LoaderSlot\n                                  name=\"v-switch\"\n                                  active\n                                  color={ isValid.value === false ? undefined : loaderColor.value }\n                                >\n                                  { slotProps => (\n                                    slots.loader\n                                      ? slots.loader(slotProps)\n                                      : (\n                                        <VProgressCircular\n                                          active={ slotProps.isActive }\n                                          color={ slotProps.color }\n                                          indeterminate\n                                          size=\"16\"\n                                          width=\"2\"\n                                        />\n                                      )\n                                  )}\n                                </LoaderSlot>\n                              )}\n                            </VScaleTransition>\n                          )}\n                        </div>\n                      </>\n                    ),\n                  }}\n                </VSelectionControl>\n              )\n            },\n          }}\n        </VInput>\n      )\n    })\n\n    return forwardRefs({}, inputRef)\n  },\n})\n\nexport type VSwitch = InstanceType<typeof VSwitch>\n"
  },
  {
    "path": "packages/vuetify/src/components/VSwitch/__tests__/VSwitch.spec.browser.tsx",
    "content": "import { VSwitch } from '../VSwitch'\n\n// Utilities\nimport { gridOn, showcase } from '@test'\n\nconst contextColor = 'rgb(0, 0, 255)'\nconst color = 'rgb(255, 0, 0)'\nconst stories = {\n  'Explicit color': gridOn([undefined], [true, false], (_, active) => (\n    <div style={{ color: contextColor }}>\n      <VSwitch modelValue={ active } color={ color } />\n    </div>\n  )),\n  'Inherited color': gridOn([undefined], [true, false], (_, active) => (\n    <div style={{ color: contextColor }}>\n      <VSwitch modelValue={ active } />\n    </div>\n  )),\n  'No color': gridOn([undefined], [true, false], (_, active) => (\n    <VSwitch modelValue={ active } />\n  )),\n}\nconst props = {\n  loading: [true],\n  inset: [true],\n  indeterminate: [true],\n}\n\ndescribe('VSwitch', () => {\n  showcase({ stories, props, component: VSwitch })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VSwitch/_variables.scss",
    "content": "@use '../../styles/settings';\n\n// VSwitch\n$switch-flex: 0 1 auto !default;\n$switch-control-input-transition: .2s transform settings.$standard-easing !default;\n$switch-error-background-color: rgb(var(--v-theme-error)) !default;\n$switch-error-color: rgb(var(--v-theme-on-error)) !default;\n\n$switch-inset-thumb-height: 24px !default;\n$switch-inset-thumb-width: 24px !default;\n$switch-inset-thumb-off-height: 16px !default;\n$switch-inset-thumb-off-width: 16px !default;\n$switch-inset-track-border-radius: 9999px !default;\n$switch-inset-track-height: 32px !default;\n$switch-inset-track-width: 52px !default;\n\n$switch-label-margin-inline-start: 10px !default;\n$switch-loader-color: rgb(var(--v-theme-surface)) !default;\n\n$switch-thumb-background: rgb(var(--v-theme-surface-bright)) !default;\n$switch-thumb-color: rgb(var(--v-theme-on-surface-bright)) !default;\n$switch-thumb-flat-background: rgb(var(--v-theme-surface-variant)) !default;\n$switch-thumb-flat-color: rgb(var(--v-theme-on-surface-variant)) !default;\n$switch-thumb-elevation: 2 !default;\n$switch-thumb-height: 20px !default;\n$switch-thumb-width: 20px !default;\n$switch-thumb-offset: 2px !default;\n$switch-thumb-radius: 50% !default;\n$switch-thumb-transition: .15s .05s transform settings.$decelerated-easing, .2s color settings.$standard-easing, .2s background-color settings.$standard-easing !default;\n$switch-thumb-vertical-transform: rotate(-90deg) !default;\n\n$switch-track-background: rgb(var(--v-theme-surface-variant)) !default;\n$switch-track-radius: 9999px !default;\n$switch-track-width: 36px !default;\n$switch-track-height: 14px !default;\n$switch-track-opacity: .6 !default;\n$switch-track-transition: .2s background-color settings.$standard-easing !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VSwitch/index.ts",
    "content": "export { VSwitch } from './VSwitch'\n"
  },
  {
    "path": "packages/vuetify/src/components/VSystemBar/VSystemBar.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-system-bar\n    align-items: center\n    display: flex\n    flex: $system-bar-flex\n    height: $system-bar-height\n    justify-content: $system-bar-justify-content\n    max-width: 100%\n    padding-inline: $system-bar-padding-x\n    position: relative\n    text-align: $system-bar-text-align\n    width: 100%\n\n    .v-icon\n      opacity: $system-bar-icon-opacity\n\n    @include tools.elevation($system-bar-elevation)\n    @include tools.position($system-bar-positions)\n    @include tools.theme($system-bar-theme...)\n    @include tools.typography($system-bar-typography...)\n\n    &--rounded\n      @include tools.rounded($system-bar-border-radius)\n\n    &--window\n      height: $system-bar-window-height\n\n    &:not(.v-system-bar--absolute)\n      padding-inline-end: calc(var(--v-scrollbar-offset) + #{$system-bar-padding-x})\n"
  },
  {
    "path": "packages/vuetify/src/components/VSystemBar/VSystemBar.tsx",
    "content": "// Styles\nimport './VSystemBar.sass'\n\n// Composables\nimport { useBackgroundColor } from '@/composables/color'\nimport { makeComponentProps } from '@/composables/component'\nimport { makeElevationProps, useElevation } from '@/composables/elevation'\nimport { makeLayoutItemProps, useLayoutItem } from '@/composables/layout'\nimport { makeRoundedProps, useRounded } from '@/composables/rounded'\nimport { useSsrBoot } from '@/composables/ssrBoot'\nimport { makeTagProps } from '@/composables/tag'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\n\n// Utilities\nimport { computed, shallowRef, toRef } from 'vue'\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\nexport const makeVSystemBarProps = propsFactory({\n  color: String,\n  height: [Number, String],\n  window: Boolean,\n\n  ...makeComponentProps(),\n  ...makeElevationProps(),\n  ...makeLayoutItemProps(),\n  ...makeRoundedProps(),\n  ...makeTagProps(),\n  ...makeThemeProps(),\n}, 'VSystemBar')\n\nexport const VSystemBar = genericComponent()({\n  name: 'VSystemBar',\n\n  props: makeVSystemBarProps(),\n\n  setup (props, { slots }) {\n    const { themeClasses } = provideTheme(props)\n    const { backgroundColorClasses, backgroundColorStyles } = useBackgroundColor(() => props.color)\n    const { elevationClasses } = useElevation(props)\n    const { roundedClasses } = useRounded(props)\n    const { ssrBootStyles } = useSsrBoot()\n    const height = computed(() => props.height ?? (props.window ? 32 : 24))\n    const { layoutItemStyles } = useLayoutItem({\n      id: props.name,\n      order: computed(() => parseInt(props.order, 10)),\n      position: shallowRef('top'),\n      layoutSize: height,\n      elementSize: height,\n      active: computed(() => true),\n      absolute: toRef(() => props.absolute),\n    })\n\n    useRender(() => (\n      <props.tag\n        class={[\n          'v-system-bar',\n          { 'v-system-bar--window': props.window },\n          themeClasses.value,\n          backgroundColorClasses.value,\n          elevationClasses.value,\n          roundedClasses.value,\n          props.class,\n        ]}\n        style={[\n          backgroundColorStyles.value,\n          layoutItemStyles.value,\n          ssrBootStyles.value,\n          props.style,\n        ]}\n        v-slots={ slots }\n      />\n    ))\n\n    return {}\n  },\n})\n\nexport type VSystemBar = InstanceType<typeof VSystemBar>\n"
  },
  {
    "path": "packages/vuetify/src/components/VSystemBar/_variables.scss",
    "content": "@use 'sass:map';\n@use '../../styles/settings';\n@use '../../styles/tools';\n\n// VSystemBar\n$system-bar-background: rgba(var(--v-theme-surface-light)) !default;\n$system-bar-border-radius: map.get(settings.$rounded, 0) !default;\n$system-bar-color: tools.theme-color('on-surface-light', var(--v-high-emphasis-opacity)) !default;\n$system-bar-elevation: 0 !default;\n$system-bar-flex: 1 1 auto !default;\n$system-bar-font-size: tools.map-deep-get(settings.$typography, 'label-small', 'size') !default;\n$system-bar-font-weight: tools.map-deep-get(settings.$typography, 'label-small', 'weight') !default;\n$system-bar-height: 24px !default;\n$system-bar-icon-opacity: var(--v-medium-emphasis-opacity) !default;\n$system-bar-justify-content: flex-end !default;\n$system-bar-letter-spacing: tools.map-deep-get(settings.$typography, 'label-small', 'letter-spacing') !default;\n$system-bar-lights-out-background: tools.theme-color('background', 0.7) !default;\n$system-bar-line-height: tools.map-deep-get(settings.$typography, 'label-small', 'line-height') !default;\n$system-bar-padding-x: 8px !default;\n$system-bar-positions: absolute fixed !default;\n$system-bar-text-align: end !default;\n$system-bar-text-transform: none !default;\n$system-bar-window-height: 32px !default;\n\n// Lists\n$system-bar-theme: (\n  $system-bar-background,\n  $system-bar-color\n) !default;\n\n$system-bar-typography: (\n  $system-bar-font-size,\n  $system-bar-font-weight,\n  $system-bar-letter-spacing,\n  $system-bar-line-height,\n  $system-bar-text-transform\n) !default;\n\n// Deprecated\n$system-bar-padding: 0 8px !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VSystemBar/index.ts",
    "content": "export { VSystemBar } from './VSystemBar'\n"
  },
  {
    "path": "packages/vuetify/src/components/VTable/VTable.sass",
    "content": "@use '../../styles/tools'\n@use '../../styles/settings'\n@use './variables' as *\n@use './mixins' as *\n\n@include tools.layer('components')\n  // Theme\n  .v-table\n    font-size: $table-font-size\n    transition-duration: $table-transition-duration\n    transition-property: $table-transition-property\n    transition-timing-function: $table-transition-timing-function\n    @include tools.theme($table-theme...)\n\n    .v-table-divider\n      border-right: $table-border\n\n    .v-table__wrapper\n      > table\n        > thead\n          > tr\n            > th\n              border-bottom: $table-border\n\n        > tbody\n          > tr\n            &:not(:last-child)\n              > td,\n              > th\n                border-bottom: $table-border\n\n        > tfoot\n          > tr\n              > td,\n              > th\n                border-top: $table-border\n\n\n    &.v-table--hover\n      > .v-table__wrapper\n        > table\n          > tbody\n            > tr\n              > td\n                position: relative\n\n              &:hover > td::after\n                background: $table-hover-color\n                pointer-events: none\n                @include tools.absolute(true)\n\n    &.v-table--striped-even\n      > .v-table__wrapper\n        > table\n          > tbody\n            > tr:nth-child(even)\n              background-image: linear-gradient(0deg, $table-stripe-color, $table-stripe-color)\n\n    &.v-table--striped-odd\n      > .v-table__wrapper\n        > table\n          > tbody\n            > tr:nth-child(odd)\n              background-image: linear-gradient(0deg, $table-stripe-color, $table-stripe-color)\n\n    &.v-table--fixed-header\n      > .v-table__wrapper\n        > table\n          > thead\n            > tr\n              > th\n                background: $table-background\n                box-shadow: inset 0 -1px 0 $table-border-color\n                z-index: 1\n\n    &.v-table--fixed-footer\n      > tfoot\n        > tr\n          > th,\n          > td\n            background: $table-background\n            box-shadow: inset 0 1px 0 $table-border-color\n\n  // Block\n  .v-table\n    border-radius: inherit\n    // Do not inherit line-height\n    line-height: $table-line-height\n    max-width: 100%\n    display: flex\n    flex-direction: column\n\n    > .v-table__wrapper\n      > table\n        width: 100%\n        border-spacing: 0\n\n        > tbody,\n        > thead,\n        > tfoot\n          > tr\n            > td,\n            > th\n              padding: $table-column-padding\n              transition-duration: $table-transition-duration\n              transition-property: $table-transition-property\n              transition-timing-function: $table-transition-timing-function\n\n            > td\n              height: var(--v-table-row-height)\n\n            > th\n              height: var(--v-table-header-height)\n              font-weight: $table-header-font-weight\n              font-size: $table-header-font-size\n              user-select: none\n              text-align: start\n\n    @at-root\n      @include tools.density('v-table', $table-density) using ($modifier)\n        --v-table-header-height: #{$table-header-height + $modifier}\n        --v-table-row-height: #{$table-row-height + $modifier}\n\n  // Elements\n  .v-table__wrapper\n    border-radius: inherit\n    overflow: auto\n    flex: 1 1 auto\n\n  // Modifiers\n  .v-table--has-top\n    > .v-table__wrapper\n      border-top-left-radius: 0\n      border-top-right-radius: 0\n\n  .v-table--has-bottom\n    > .v-table__wrapper\n      border-bottom-left-radius: 0\n      border-bottom-right-radius: 0\n\n  .v-table--fixed-height\n    > .v-table__wrapper\n      overflow-y: auto\n\n  .v-table--fixed-header\n    > .v-table__wrapper\n      > table\n        > thead\n          position: sticky\n          top: 0\n          z-index: 2\n          > tr\n            > th\n              @include tools.layer('overrides')\n                border-bottom: 0px\n\n  .v-table--fixed-footer\n    > .v-table__wrapper\n      > table\n        > tfoot\n          > tr\n            position: sticky\n            bottom: 0\n            z-index: 1\n            > td,\n            > th\n              @include tools.layer('overrides')\n                border-top: 0px\n"
  },
  {
    "path": "packages/vuetify/src/components/VTable/VTable.tsx",
    "content": "// Styles\nimport './VTable.sass'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { makeDensityProps, useDensity } from '@/composables/density'\nimport { makeTagProps } from '@/composables/tag'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\n\n// Utilities\nimport { convertToUnit, genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\nexport type VTableSlots = {\n  default: never\n  top: never\n  bottom: never\n  wrapper: never\n}\n\nexport type Striped = null | 'odd' | 'even'\n\nexport const makeVTableProps = propsFactory({\n  fixedHeader: Boolean,\n  fixedFooter: Boolean,\n  height: [Number, String],\n  hover: Boolean,\n  striped: {\n    type: String as PropType<Striped>,\n    default: null,\n    validator: (v: any) => ['even', 'odd'].includes(v),\n  },\n\n  ...makeComponentProps(),\n  ...makeDensityProps(),\n  ...makeTagProps(),\n  ...makeThemeProps(),\n}, 'VTable')\n\nexport const VTable = genericComponent<VTableSlots>()({\n  name: 'VTable',\n\n  props: makeVTableProps(),\n\n  setup (props, { slots, emit }) {\n    const { themeClasses } = provideTheme(props)\n    const { densityClasses } = useDensity(props)\n\n    useRender(() => (\n      <props.tag\n        class={[\n          'v-table',\n          {\n            'v-table--fixed-height': !!props.height,\n            'v-table--fixed-header': props.fixedHeader,\n            'v-table--fixed-footer': props.fixedFooter,\n            'v-table--has-top': !!slots.top,\n            'v-table--has-bottom': !!slots.bottom,\n            'v-table--hover': props.hover,\n            'v-table--striped-even': props.striped === 'even',\n            'v-table--striped-odd': props.striped === 'odd',\n          },\n          themeClasses.value,\n          densityClasses.value,\n          props.class,\n        ]}\n        style={ props.style }\n      >\n        { slots.top?.() }\n\n        { slots.default ? (\n          <div\n            class=\"v-table__wrapper\"\n            style={{ height: convertToUnit(props.height) }}\n          >\n            <table>\n              { slots.default() }\n            </table>\n          </div>\n        ) : slots.wrapper?.()}\n\n        { slots.bottom?.() }\n      </props.tag>\n    ))\n\n    return {}\n  },\n})\n\nexport type VTable = InstanceType<typeof VTable>\n"
  },
  {
    "path": "packages/vuetify/src/components/VTable/_mixins.scss",
    "content": "@use 'sass:map';\n@use './variables' as *;\n\n@mixin table-density ($densities) {\n  @each $density, $properties in $densities {\n    .v-table--density-#{$density} {\n      > .v-table__wrapper {\n        > table {\n          > tbody,\n          > thead,\n          > tfoot {\n            > tr {\n              > th {\n                height: map.get($properties, header)\n              }\n              > td {\n                height: map.get($properties, row)\n              }\n            }\n          }\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VTable/_variables.scss",
    "content": "@use 'sass:math';\n@use 'sass:map';\n@use '../../styles/settings';\n@use '../../styles/tools';\n\n// VTable\n$table-background: rgb(var(--v-theme-surface)) !default;\n$table-color: tools.theme-color('on-surface', var(--v-high-emphasis-opacity)) !default;\n$table-density: ('default': 0, 'comfortable': -2, 'compact': -4) !default;\n$table-header-height: 56px !default;\n$table-header-font-weight: 500 !default;\n$table-header-font-size: inherit !default;\n$table-font-size: tools.map-deep-get(settings.$typography, 'body-medium', 'size') !default;\n$table-row-height: 52px !default;\n$table-row-font-size: tools.map-deep-get(settings.$typography, 'label-large', 'size') !default;\n$table-border-color: rgba(var(--v-border-color), var(--v-border-opacity)) !default;\n$table-border: thin solid $table-border-color !default;\n$table-hover-color: rgba(var(--v-border-color), var(--v-hover-opacity)) !default;\n$table-line-height: 1.5 !default;\n$table-column-padding: 0 16px !default;\n$table-stripe-color: rgba(var(--v-border-color), var(--v-hover-opacity)) !default;\n$table-transition-duration: 0.28s !default;\n$table-transition-property: box-shadow, opacity, background, height !default;\n$table-transition-timing-function: settings.$standard-easing !default;\n\n// Lists\n$table-theme: (\n  $table-background,\n  $table-color,\n) !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VTable/index.ts",
    "content": "export { VTable } from './VTable'\n"
  },
  {
    "path": "packages/vuetify/src/components/VTabs/VTab.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-tab\n    @include tools.layer('overrides')\n      height: var(--v-tabs-height)\n      border-radius: $tab-border-radius\n      min-width: $tab-min-width\n\n    .v-slide-group--horizontal &\n      max-width: $tab-max-width\n\n    .v-slide-group--vertical &\n      justify-content: start\n\n  .v-tab__slider\n    position: absolute\n    bottom: 0\n    left: 0\n    height: $tab-slider-size\n    width: 100%\n    background: currentColor\n    pointer-events: none\n    opacity: 0\n\n    .v-tab--selected &\n      opacity: 1\n\n    .v-slide-group--vertical &\n      top: 0\n      height: 100%\n      width: $tab-slider-size\n\n@include tools.layer('trumps')\n  @media (forced-colors: active)\n    .v-tab\n      &--selected.v-btn\n        color: highlight\n\n      &__slider\n        background: highlight\n"
  },
  {
    "path": "packages/vuetify/src/components/VTabs/VTab.tsx",
    "content": "// Styles\nimport './VTab.sass'\n\n// Components\nimport { makeVBtnProps, VBtn } from '@/components/VBtn/VBtn'\n\n// Composables\nimport { useBackgroundColor, useTextColor } from '@/composables/color'\nimport { forwardRefs } from '@/composables/forwardRefs'\n\n// Utilities\nimport { computed, ref } from 'vue'\nimport { VTabsSymbol } from './shared'\nimport { animate, genericComponent, omit, propsFactory, standardEasing, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { VBtnSlots } from '@/components/VBtn/VBtn'\n\nexport const makeVTabProps = propsFactory({\n  fixed: Boolean,\n\n  sliderColor: String,\n  sliderTransition: String as PropType<'shift' | 'grow' | 'fade'>,\n  sliderTransitionDuration: [String, Number],\n  hideSlider: Boolean,\n  inset: Boolean,\n\n  direction: {\n    type: String as PropType<'horizontal' | 'vertical'>,\n    default: 'horizontal',\n  },\n\n  ...omit(makeVBtnProps({\n    selectedClass: 'v-tab--selected',\n    variant: 'text' as const,\n  }), [\n    'active',\n    'block',\n    'flat',\n    'location',\n    'position',\n    'symbol',\n  ]),\n}, 'VTab')\n\nexport const VTab = genericComponent<VBtnSlots>()({\n  name: 'VTab',\n\n  props: makeVTabProps(),\n\n  setup (props, { slots, attrs }) {\n    const {\n      textColorClasses: sliderColorClasses,\n      textColorStyles: sliderColorStyles,\n    } = useTextColor(() => props.sliderColor)\n    const {\n      backgroundColorClasses: insetColorClasses,\n      backgroundColorStyles: insetColorStyles,\n    } = useBackgroundColor(() => props.sliderColor)\n\n    const rootEl = ref<VBtn>()\n    const sliderEl = ref<HTMLElement>()\n\n    const isHorizontal = computed(() => props.direction === 'horizontal')\n    const isSelected = computed(() => rootEl.value?.group?.isSelected.value ?? false)\n\n    function fade (nextEl: HTMLElement, prevEl: HTMLElement) {\n      return { opacity: [0, 1] }\n    }\n\n    function grow (nextEl: HTMLElement, prevEl: HTMLElement) {\n      return props.direction === 'vertical'\n        ? { transform: ['scaleY(0)', 'scaleY(1)'] }\n        : { transform: ['scaleX(0)', 'scaleX(1)'] }\n    }\n\n    function shift (nextEl: HTMLElement, prevEl: HTMLElement) {\n      const prevBox = prevEl.getBoundingClientRect()\n      const nextBox = nextEl.getBoundingClientRect()\n\n      const xy = isHorizontal.value ? 'x' : 'y'\n      const XY = isHorizontal.value ? 'X' : 'Y'\n      const rightBottom = isHorizontal.value ? 'right' : 'bottom'\n      const widthHeight = isHorizontal.value ? 'width' : 'height'\n\n      const prevPos = prevBox[xy]\n      const nextPos = nextBox[xy]\n      const delta = prevPos > nextPos\n        ? prevBox[rightBottom] - nextBox[rightBottom]\n        : prevBox[xy] - nextBox[xy]\n      const origin =\n        Math.sign(delta) > 0 ? (isHorizontal.value ? 'right' : 'bottom')\n        : Math.sign(delta) < 0 ? (isHorizontal.value ? 'left' : 'top')\n        : 'center'\n      const size = Math.abs(delta) + (Math.sign(delta) < 0 ? prevBox[widthHeight] : nextBox[widthHeight])\n      const scale = size / Math.max(prevBox[widthHeight], nextBox[widthHeight]) || 0\n      const initialScale = prevBox[widthHeight] / nextBox[widthHeight] || 0\n      const sigma = 1.5\n\n      return {\n        transform: [\n          `translate${XY}(${delta}px) scale${XY}(${initialScale})`,\n          `translate${XY}(${delta / sigma}px) scale${XY}(${(scale - 1) / sigma + 1})`,\n          'none',\n        ],\n        transformOrigin: Array(3).fill(origin),\n      }\n    }\n\n    function updateSlider ({ value }: { value: boolean }) {\n      if (value) {\n        const prevEl: HTMLElement | undefined = rootEl.value?.$el.parentElement?.querySelector('.v-tab--selected .v-tab__slider')\n        const nextEl = sliderEl.value\n\n        if (!prevEl || !nextEl) return\n\n        const color = getComputedStyle(prevEl).backgroundColor\n\n        const keyframes = { fade, grow, shift }[props.sliderTransition ?? 'shift'] ?? shift\n        const duration = Number(props.sliderTransitionDuration) ||\n          ({ fade: 400, grow: 350, shift: 225 }[props.sliderTransition ?? 'shift'] ?? 225)\n\n        animate(nextEl, {\n          backgroundColor: [color, color],\n          ...keyframes(nextEl, prevEl),\n        }, {\n          duration,\n          easing: standardEasing,\n        })\n      }\n    }\n\n    useRender(() => {\n      const btnProps = VBtn.filterProps(props)\n\n      return (\n        <VBtn\n          symbol={ VTabsSymbol }\n          ref={ rootEl }\n          class={[\n            'v-tab',\n            props.class,\n            isSelected.value && props.inset ? insetColorClasses.value : [],\n          ]}\n          style={[\n            props.style,\n            isSelected.value && props.inset ? insetColorStyles.value : [],\n            { backgroundColor: isSelected.value && props.inset ? 'transparent !important' : undefined },\n          ]}\n          tabindex={ isSelected.value ? 0 : -1 }\n          role=\"tab\"\n          aria-selected={ String(isSelected.value) }\n          active={ false }\n          { ...btnProps }\n          { ...attrs }\n          block={ props.fixed }\n          maxWidth={ props.fixed ? 300 : undefined }\n          onGroup:selected={ updateSlider }\n        >\n          {{\n            ...slots,\n            default: () => (\n              <>\n                { slots.default?.() ?? props.text }\n\n                { !props.hideSlider && (\n                  <div\n                    ref={ sliderEl }\n                    class={[\n                      'v-tab__slider',\n                      props.inset ? insetColorClasses.value : sliderColorClasses.value,\n                    ]}\n                    style={[\n                      sliderColorStyles.value,\n                      props.inset ? insetColorStyles.value : sliderColorClasses.value,\n                    ]}\n                  />\n                )}\n              </>\n            ),\n          }}\n        </VBtn>\n      )\n    })\n\n    return forwardRefs({}, rootEl)\n  },\n})\n\nexport type VTab = InstanceType<typeof VTab>\n"
  },
  {
    "path": "packages/vuetify/src/components/VTabs/VTabs.sass",
    "content": "@use 'sass:math'\n@use 'sass:map'\n@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-tabs\n    display: flex\n    height: var(--v-tabs-height)\n\n    @at-root\n      @include tools.density('v-tabs', $tabs-density) using ($modifier)\n        --v-tabs-height: #{$tabs-height + $modifier}\n\n        &.v-tabs--stacked\n          --v-tabs-height: #{$tabs-stacked-height + $modifier}\n\n    &.v-slide-group--vertical\n      height: auto\n      flex: none\n      --v-tabs-height: #{$tabs-height}\n\n  .v-tabs--align-tabs-title:not(.v-slide-group--has-affixes)\n    .v-tab:first-child\n      margin-inline-start: $tab-align-tabs-title-margin\n\n  .v-tabs--fixed-tabs,\n  .v-tabs--align-tabs-center\n    .v-slide-group__content > *:last-child\n      margin-inline-end: auto\n\n    .v-slide-group__content > *:first-child\n      margin-inline-start: auto\n\n  .v-tabs--grow\n    flex-grow: 1\n\n    .v-tab\n      flex: 1 0 auto\n      max-width: none\n\n  .v-tabs--align-tabs-end\n    .v-tab:first-child\n      margin-inline-start: auto\n\n    .v-tab:last-child\n      margin-inline-end: 0\n\n  .v-tabs--inset\n    --v-tabs-inset-radius: #{$tab-inset-radius}\n    --v-tabs-inset-padding: #{$tab-inset-padding}\n    --v-tabs-slider-background: rgba(var(--v-theme-on-surface), .2)\n\n    background: tools.theme-color('on-surface', 0.06)\n    box-shadow: inset 0 0 0 2px rgba(var(--v-border-color), var(--v-border-opacity))\n    border-radius: calc(var(--v-tabs-inset-radius) + var(--v-tabs-inset-padding))\n\n    .v-tab\n      margin: var(--v-tabs-inset-padding)\n      transition-property: box-shadow, transform, opacity, background, color\n\n      &.v-tab.v-btn\n        border-radius: var(--v-tabs-inset-radius)\n\n      &:focus-visible\n        outline: 2px solid rgb(var(--v-border-color))\n        outline-offset: 2px\n\n        &:after\n          opacity: 0\n\n    &:not(.v-tabs--fixed-tabs, .v-tabs--grow)\n      max-width: max-content\n\n    &.v-tabs--fixed-tabs .v-slide-group__content\n      padding-inline: var(--v-tabs-inset-padding)\n\n    .v-tab__slider\n      background: var(--v-tabs-slider-background)\n      inset: 0\n      border-radius: var(--v-tabs-inset-radius)\n      z-index: -1\n      width: auto\n\n    &.v-tabs--horizontal\n      height: calc(var(--v-tabs-height) + var(--v-tabs-inset-padding) * 2)\n      --v-tabs-inset-tab-radius: calc(var(--v-tabs-outer-radius) - var(--v-tabs-inset-padding) + 4px)\n\n    &.v-tabs--horizontal .v-tab__slider\n      height: auto\n\n    .v-btn__overlay\n      display: none\n\n    &.v-tabs--vertical .v-tab\n      grid-template-columns: max-content 1fr max-content\n      > .v-btn__content\n        justify-content: start\n\n      .v-tab__slider\n        width: auto\n\n  @media #{map.get(settings.$display-breakpoints, 'md-and-down')}\n    .v-tabs.v-slide-group--is-overflowing.v-slide-group--horizontal:not(.v-slide-group--has-affixes)\n      .v-tab:first-child\n        margin-inline-start: 52px\n      .v-tab:last-child\n        margin-inline-end: 52px\n"
  },
  {
    "path": "packages/vuetify/src/components/VTabs/VTabs.tsx",
    "content": "// Styles\nimport './VTabs.sass'\n\n// Components\nimport { makeVTabProps, VTab } from './VTab'\nimport { VTabsWindow } from './VTabsWindow'\nimport { VTabsWindowItem } from './VTabsWindowItem'\nimport { makeVSlideGroupProps, VSlideGroup } from '@/components/VSlideGroup/VSlideGroup'\n\n// Composables\nimport { useBackgroundColor } from '@/composables/color'\nimport { provideDefaults } from '@/composables/defaults'\nimport { makeDensityProps, useDensity } from '@/composables/density'\nimport { useProxiedModel } from '@/composables/proxiedModel'\nimport { useScopeId } from '@/composables/scopeId'\nimport { makeTagProps } from '@/composables/tag'\n\n// Utilities\nimport { computed, toRef } from 'vue'\nimport { VTabsSymbol } from './shared'\nimport { convertToUnit, genericComponent, isObject, pick, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { GenericProps } from '@/util'\n\nexport type TabItem = string | number | Record<string, any>\n\nexport type VTabsSlot<T> = {\n  item: T\n}\n\nexport type VTabsSlots<T> = {\n  default: never\n  tab: VTabsSlot<T>\n  item: VTabsSlot<T>\n  window: never\n  prev: never\n  next: never\n} & {\n  [key: `tab.${string}`]: VTabsSlot<T>\n  [key: `item.${string}`]: VTabsSlot<T>\n}\n\nfunction parseItems (items: readonly TabItem[] | undefined) {\n  if (!items) return []\n\n  return items.map(item => {\n    if (!isObject(item)) return { text: item, value: item }\n\n    return item\n  })\n}\n\nexport const makeVTabsProps = propsFactory({\n  alignTabs: {\n    type: String as PropType<'start' | 'title' | 'center' | 'end'>,\n    default: 'start',\n  },\n  color: String,\n  fixedTabs: Boolean,\n  items: {\n    type: Array as PropType<readonly TabItem[]>,\n    default: () => ([]),\n  },\n  stacked: Boolean,\n  bgColor: String,\n  grow: Boolean,\n  height: {\n    type: [Number, String],\n    default: undefined,\n  },\n  hideSlider: Boolean,\n  inset: Boolean,\n  insetPadding: [String, Number],\n  insetRadius: [String, Number],\n  sliderColor: String,\n\n  ...pick(makeVTabProps(), ['spaced', 'sliderTransition', 'sliderTransitionDuration']),\n  ...makeVSlideGroupProps({\n    mandatory: 'force' as const,\n    selectedClass: 'v-tab-item--selected',\n  }),\n  ...makeDensityProps(),\n  ...makeTagProps(),\n}, 'VTabs')\n\nexport const VTabs = genericComponent<new <TModel, T = TabItem>(\n  props: {\n    items?: T[]\n    modelValue?: TModel\n    'onUpdate:modelValue'?: (value: TModel) => void\n  },\n  slots: VTabsSlots<T>\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VTabs',\n\n  props: makeVTabsProps(),\n\n  emits: {\n    'update:modelValue': (v: unknown) => true,\n  },\n\n  setup (props, { attrs, slots }) {\n    const model = useProxiedModel(props, 'modelValue')\n    const items = computed(() => parseItems(props.items))\n    const { densityClasses } = useDensity(props)\n    const { backgroundColorClasses, backgroundColorStyles } = useBackgroundColor(() => props.bgColor)\n    const { scopeId } = useScopeId()\n\n    provideDefaults({\n      VTab: {\n        color: toRef(props, 'color'),\n        direction: toRef(props, 'direction'),\n        stacked: toRef(props, 'stacked'),\n        fixed: toRef(props, 'fixedTabs'),\n        inset: toRef(props, 'inset'),\n        sliderColor: toRef(props, 'sliderColor'),\n        sliderTransition: toRef(props, 'sliderTransition'),\n        sliderTransitionDuration: toRef(props, 'sliderTransitionDuration'),\n        hideSlider: toRef(props, 'hideSlider'),\n      },\n    })\n\n    useRender(() => {\n      const slideGroupProps = VSlideGroup.filterProps(props)\n      const hasWindow = !!(slots.window || props.items.length > 0)\n\n      return (\n        <>\n          <VSlideGroup\n            { ...slideGroupProps }\n            v-model={ model.value }\n            class={[\n              'v-tabs',\n              `v-tabs--${props.direction}`,\n              `v-tabs--align-tabs-${props.alignTabs}`,\n              {\n                'v-tabs--fixed-tabs': props.fixedTabs,\n                'v-tabs--grow': props.grow,\n                'v-tabs--inset': props.inset,\n                'v-tabs--stacked': props.stacked,\n              },\n              densityClasses.value,\n              backgroundColorClasses.value,\n              props.class,\n            ]}\n            style={[\n              {\n                '--v-tabs-height': convertToUnit(props.height),\n                '--v-tabs-inset-padding': props.inset ? convertToUnit(props.insetPadding) : undefined,\n                '--v-tabs-inset-radius': props.inset ? convertToUnit(props.insetRadius) : undefined,\n              },\n              backgroundColorStyles.value,\n              props.style,\n            ]}\n            role=\"tablist\"\n            symbol={ VTabsSymbol }\n            { ...scopeId }\n            { ...attrs }\n          >\n            {{\n              default: slots.default ?? (() => items.value.map(item => (\n                slots.tab?.({ item }) ?? (\n                  <VTab\n                    { ...item }\n                    key={ item.text }\n                    value={ item.value }\n                    spaced={ props.spaced }\n                    v-slots={{\n                      default: slots[`tab.${item.value}`] ? () => slots[`tab.${item.value}`]?.({ item }) : undefined,\n                    }}\n                  />\n                )\n              ))),\n              prev: slots.prev,\n              next: slots.next,\n            }}\n          </VSlideGroup>\n\n          { hasWindow && (\n            <VTabsWindow\n              v-model={ model.value }\n              key=\"tabs-window\"\n              { ...scopeId }\n            >\n              { items.value.map(item => slots.item?.({ item }) ?? (\n                <VTabsWindowItem\n                  value={ item.value }\n                  v-slots={{\n                    default: () => slots[`item.${item.value}`]?.({ item }),\n                  }}\n                />\n              ))}\n\n              { slots.window?.() }\n            </VTabsWindow>\n          )}\n        </>\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VTabs = InstanceType<typeof VTabs>\n"
  },
  {
    "path": "packages/vuetify/src/components/VTabs/VTabsWindow.tsx",
    "content": "// Components\nimport { makeVWindowProps, VWindow } from '@/components/VWindow/VWindow'\n\n// Composables\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { computed, inject } from 'vue'\nimport { genericComponent, omit, propsFactory, useRender } from '@/util'\n\n// Types\nimport { VTabsSymbol } from './shared'\nimport type { VWindowSlots } from '@/components/VWindow/VWindow'\nimport type { GenericProps } from '@/util'\n\nexport const makeVTabsWindowProps = propsFactory({\n  ...omit(makeVWindowProps(), ['continuous', 'nextIcon', 'prevIcon', 'showArrows', 'touch', 'mandatory']),\n}, 'VTabsWindow')\n\nexport const VTabsWindow = genericComponent<new <TModel>(\n  props: {\n    modelValue?: TModel\n    'onUpdate:modelValue'?: (value: TModel) => void\n  },\n  slots: VWindowSlots\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VTabsWindow',\n\n  props: makeVTabsWindowProps(),\n\n  emits: {\n    'update:modelValue': (v: any) => true,\n  },\n\n  setup (props, { slots }) {\n    const group = inject(VTabsSymbol, null)\n    const _model = useProxiedModel(props, 'modelValue')\n\n    const model = computed({\n      get () {\n        // Always return modelValue if defined\n        // or if not within a VTabs group\n        if (_model.value != null || !group) return _model.value\n\n        // If inside of a VTabs, find the currently selected\n        // item by id. Item value may be assigned by its index\n        return group.items.value.find(item => group.selected.value.includes(item.id))?.value\n      },\n      set (val) {\n        _model.value = val\n      },\n    })\n\n    useRender(() => {\n      const windowProps = VWindow.filterProps(props)\n\n      return (\n        <VWindow\n          _as=\"VTabsWindow\"\n          { ...windowProps }\n          v-model={ model.value }\n          class={[\n            'v-tabs-window',\n            props.class,\n          ]}\n          style={ props.style }\n          mandatory={ false }\n          touch={ false }\n          v-slots={ slots }\n        />\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VTabsWindow = InstanceType<typeof VTabsWindow>\n"
  },
  {
    "path": "packages/vuetify/src/components/VTabs/VTabsWindowItem.tsx",
    "content": "// Components\nimport { makeVWindowItemProps, VWindowItem } from '@/components/VWindow/VWindowItem'\n\n// Utilities\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\nexport const makeVTabsWindowItemProps = propsFactory({\n  ...makeVWindowItemProps(),\n}, 'VTabsWindowItem')\n\nexport const VTabsWindowItem = genericComponent()({\n  name: 'VTabsWindowItem',\n\n  props: makeVTabsWindowItemProps(),\n\n  setup (props, { slots }) {\n    useRender(() => {\n      const windowItemProps = VWindowItem.filterProps(props)\n\n      return (\n        <VWindowItem\n          _as=\"VTabsWindowItem\"\n          { ...windowItemProps }\n          class={[\n            'v-tabs-window-item',\n            props.class,\n          ]}\n          style={ props.style }\n          v-slots={ slots }\n        />\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VTabsWindowItem = InstanceType<typeof VTabsWindowItem>\n"
  },
  {
    "path": "packages/vuetify/src/components/VTabs/__tests__/VTabs.spec.browser.tsx",
    "content": "// Components\nimport { VTab, VTabs } from '..'\n\n// Utilities\nimport { render, screen, showcase, userEvent } from '@test'\nimport { nextTick, ref } from 'vue'\nimport { createRouter, createWebHistory } from 'vue-router'\n\nconst FAKE_ITEMS = [\n  { text: 'A', value: 1 },\n  { text: 'B', value: 2 },\n  { text: 'C', value: 3 },\n]\n\nconst stories = {\n  'With items': <VTabs items={ FAKE_ITEMS } />,\n  'Without slider': <VTabs items={ FAKE_ITEMS } hideSlider />,\n  Vertical: <VTabs items={ FAKE_ITEMS } direction=\"vertical\" />,\n}\n\ndescribe('VTabs', () => {\n  it('should respond to clicks', async () => {\n    const update = vi.fn()\n    render(() => (\n      <VTabs onUpdate:modelValue={ update }>\n        <VTab value=\"foo\">foo</VTab>\n        <VTab value=\"bar\">bar</VTab>\n      </VTabs>\n    ))\n\n    await userEvent.click(screen.getAllByCSS('.v-tab')[1])\n\n    expect(update).toHaveBeenCalledTimes(2)\n    expect(update).toHaveBeenNthCalledWith(1, 'foo')\n    expect(update).toHaveBeenNthCalledWith(2, 'bar')\n  })\n\n  it('should respond to v-model changes', async () => {\n    const model = ref('foo')\n    render(() => (\n      <VTabs modelValue={ model.value }>\n        <VTab value=\"foo\">foo</VTab>\n        <VTab value=\"bar\">bar</VTab>\n      </VTabs>\n    ))\n\n    await nextTick()\n    expect(screen.getAllByCSS('.v-tab')[0]).toHaveClass('v-tab--selected')\n\n    model.value = 'bar'\n    await nextTick()\n\n    expect(screen.getAllByCSS('.v-tab')[0]).not.toHaveClass('v-tab--selected')\n    expect(screen.getAllByCSS('.v-tab')[1]).toHaveClass('v-tab--selected')\n  })\n\n  it('should react to router changes', async () => {\n    const router = createRouter({\n      history: createWebHistory(),\n      routes: [\n        { path: '/', component: { template: 'Home' } },\n        { path: '/about', component: { template: 'About' } },\n        { path: '/__vitest_test__/:path(.*)', component: { template: 'Test' } },\n      ],\n    })\n\n    render(() => (\n      <VTabs>\n        <VTab to=\"/\">foo</VTab>\n        <VTab to=\"/about\">bar</VTab>\n      </VTabs>\n    ), {\n      global: {\n        plugins: [router],\n      },\n    })\n\n    await userEvent.click(screen.getAllByCSS('.v-tab')[1])\n\n    expect(router.currentRoute.value.path).toBe('/about')\n\n    await router.push('/')\n\n    expect(screen.getAllByCSS('.v-tab')[0]).not.toHaveClass('v-tab--selected')\n    expect(screen.getAllByCSS('.v-tab')[1]).toHaveClass('v-tab--selected')\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/15237\n  it('should not change model value if tab items are hidden with v-show', async () => {\n    const model = ref('B')\n    const show = ref(true)\n    render(() => (\n      <div v-show={ show }>\n        <VTabs v-model={ model.value }>\n          <VTab value=\"A\">A</VTab>\n          <VTab value=\"B\">B</VTab>\n          <VTab value=\"C\">C</VTab>\n        </VTabs>\n      </div>\n    ))\n\n    expect(model.value).toBe('B')\n    show.value = false\n    expect(model.value).toBe('B')\n    show.value = true\n    expect(model.value).toBe('B')\n  })\n\n  showcase({ stories })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VTabs/_variables.scss",
    "content": "@use 'sass:math';\n@use 'sass:map';\n@use '../../styles/settings';\n\n// VTabs\n$tabs-density: ( 'default': 0, 'comfortable' : -1, 'compact': -3) !default;\n$tabs-height: 48px !default;\n$tabs-stacked-height: 72px !default;\n\n// VTab\n$tab-align-tabs-title-margin: 42px !default;\n$tab-border-radius: 0 !default;\n$tab-max-width: 360px !default;\n$tab-min-width: 90px !default;\n$tab-slider-size: 2px !default;\n\n$tab-inset-radius: settings.$border-radius-root !default;\n$tab-inset-padding: 4px !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VTabs/index.ts",
    "content": "export { VTab } from './VTab'\nexport { VTabs } from './VTabs'\nexport { VTabsWindow } from './VTabsWindow'\nexport { VTabsWindowItem } from './VTabsWindowItem'\n"
  },
  {
    "path": "packages/vuetify/src/components/VTabs/shared.ts",
    "content": "// Types\nimport type { InjectionKey } from 'vue'\nimport type { GroupProvide } from '@/composables/group'\n\nexport const VTabsSymbol: InjectionKey<GroupProvide> = Symbol.for('vuetify:v-tabs')\n"
  },
  {
    "path": "packages/vuetify/src/components/VTextField/VTextField.sass",
    "content": "@use 'sass:selector'\n@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  /* region BLOCK */\n  .v-text-field\n    input\n      color: inherit\n      flex: $text-field-input-flex\n      transition: $text-field-input-transition\n      min-width: 0\n\n      &:focus,\n      &:active\n        outline: none\n\n      // Remove Firefox red outline\n      &:invalid\n        box-shadow: none\n\n    .v-field\n      cursor: text\n\n      &:not(.v-field--reverse)\n        .v-field__input\n          @at-root #{selector.append('.v-text-field--prefixed', &)}\n            --v-field-padding-start: #{$text-field-input-padding-start}\n\n          @at-root #{selector.append('.v-text-field--suffixed', &)}\n            --v-field-padding-end: #{$text-field-input-padding-end}\n\n      &.v-field--reverse\n        .v-field__input\n          @at-root #{selector.append('.v-text-field--prefixed', &)}\n            --v-field-padding-end: #{$text-field-input-padding-start}\n\n          @at-root #{selector.append('.v-text-field--suffixed', &)}\n            --v-field-padding-start: #{$text-field-input-padding-end}\n\n      &:not(.v-field--no-label, .v-field--active)\n        input::placeholder\n          opacity: 0\n\n    .v-field--single-line\n      input\n        transition: none\n\n  /* endregion */\n  /* region ELEMENTS */\n  .v-text-field\n    &__prefix,\n    &__suffix\n      align-items: center\n      color: $text-field-affix-color\n      cursor: default\n      display: flex\n      opacity: 0\n      transition: inherit\n      white-space: nowrap\n      min-height: $field-input-min-height\n      padding-top: calc(var(--v-field-padding-top, 4px) + var(--v-input-padding-top, 0))\n      padding-bottom: var(--v-field-padding-bottom, 6px)\n\n      .v-field--active &\n        opacity: 1\n\n      .v-field--disabled &\n        color: $text-field-disabled-affix-color\n\n    &__prefix\n      @at-root #{selector.nest('.v-field:not(.v-field--reverse)', &)}\n        padding-inline-start: var(--v-field-padding-start)\n      @at-root #{selector.nest('.v-field.v-field--reverse', &)}\n        padding-inline-end: var(--v-field-padding-end)\n\n    &__suffix\n      @at-root #{selector.nest('.v-field:not(.v-field--reverse)', &)}\n        padding-inline-end: var(--v-field-padding-end)\n      @at-root #{selector.nest('.v-field.v-field--reverse', &)}\n        padding-inline-start: var(--v-field-padding-start)\n\n  /* endregion */\n"
  },
  {
    "path": "packages/vuetify/src/components/VTextField/VTextField.tsx",
    "content": "// Styles\nimport './VTextField.sass'\n\n// Components\nimport { VCounter } from '@/components/VCounter/VCounter'\nimport { makeVFieldProps, VField } from '@/components/VField/VField'\nimport { makeVInputProps, VInput } from '@/components/VInput/VInput'\n\n// Composables\nimport { makeAutocompleteProps, useAutocomplete } from '@/composables/autocomplete'\nimport { useAutofocus } from '@/composables/autofocus'\nimport { useFocus } from '@/composables/focus'\nimport { forwardRefs } from '@/composables/forwardRefs'\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Directives\nimport vIntersect from '@/directives/intersect'\n\n// Utilities\nimport { cloneVNode, computed, nextTick, ref, withDirectives } from 'vue'\nimport { callEvent, filterInputAttrs, genericComponent, omit, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType, Ref } from 'vue'\nimport type { VCounterSlot } from '@/components/VCounter/VCounter'\nimport type { VFieldSlots } from '@/components/VField/VField'\nimport type { VInputSlots } from '@/components/VInput/VInput'\n\nconst activeTypes = ['color', 'file', 'time', 'date', 'datetime-local', 'week', 'month']\n\nexport const makeVTextFieldProps = propsFactory({\n  autofocus: Boolean,\n  counter: [Boolean, Number, String],\n  counterValue: [Number, Function] as PropType<number | ((value: any) => number)>,\n  prefix: String,\n  placeholder: String,\n  persistentPlaceholder: Boolean,\n  persistentCounter: Boolean,\n  suffix: String,\n  role: String,\n  type: {\n    type: String,\n    default: 'text',\n  },\n  modelModifiers: Object as PropType<Record<string, boolean>>,\n\n  ...makeAutocompleteProps(),\n  ...omit(makeVInputProps(), ['direction']),\n  ...makeVFieldProps(),\n}, 'VTextField')\n\nexport type VTextFieldSlots = Omit<VInputSlots & VFieldSlots, 'default'> & {\n  default: { id: Readonly<Ref<string>> }\n  counter: VCounterSlot\n}\n\nexport const VTextField = genericComponent<VTextFieldSlots>()({\n  name: 'VTextField',\n\n  directives: { vIntersect },\n\n  inheritAttrs: false,\n\n  props: makeVTextFieldProps(),\n\n  emits: {\n    'click:control': (e: MouseEvent) => true,\n    'mousedown:control': (e: MouseEvent) => true,\n    'update:focused': (focused: boolean) => true,\n    'update:modelValue': (val: string) => true,\n  },\n\n  setup (props, { attrs, emit, slots }) {\n    const model = useProxiedModel(props, 'modelValue', undefined, v => {\n      if (Object.is(v, -0)) return '-0'\n      return v\n    })\n    const { isFocused, focus, blur } = useFocus(props)\n    const { onIntersect } = useAutofocus(props)\n    const counterValue = computed(() => {\n      return typeof props.counterValue === 'function' ? props.counterValue(model.value)\n        : typeof props.counterValue === 'number' ? props.counterValue\n        : (model.value ?? '').toString().length\n    })\n    const max = computed(() => {\n      if (attrs.maxlength) return attrs.maxlength as unknown as undefined\n\n      if (\n        !props.counter ||\n        (typeof props.counter !== 'number' &&\n        typeof props.counter !== 'string')\n      ) return undefined\n\n      return props.counter\n    })\n\n    const isPlainOrUnderlined = computed(() => ['plain', 'underlined'].includes(props.variant))\n\n    const vInputRef = ref<VInput>()\n    const vFieldRef = ref<VField>()\n    const inputRef = ref<HTMLInputElement>()\n    const autocomplete = useAutocomplete(props)\n    const isActive = computed(() => (\n      activeTypes.includes(props.type) ||\n      props.persistentPlaceholder ||\n      isFocused.value ||\n      props.active\n    ))\n    function onFocus () {\n      if (autocomplete.isSuppressing.value) {\n        autocomplete.update()\n      }\n\n      if (!isFocused.value) focus()\n\n      nextTick(() => {\n        if (inputRef.value !== document.activeElement) {\n          inputRef.value?.focus()\n        }\n      })\n    }\n    function onControlMousedown (e: MouseEvent) {\n      emit('mousedown:control', e)\n\n      if (e.target === inputRef.value) return\n\n      onFocus()\n      e.preventDefault()\n    }\n    function onControlClick (e: MouseEvent) {\n      emit('click:control', e)\n    }\n    function onClear (e: MouseEvent, reset: () => void) {\n      e.stopPropagation()\n\n      onFocus()\n\n      nextTick(() => {\n        reset()\n\n        callEvent(props['onClick:clear'], e)\n      })\n    }\n    function onInput (e: Event) {\n      const el = e.target as HTMLInputElement\n\n      if (!(\n        props.modelModifiers?.trim &&\n        ['text', 'search', 'password', 'tel', 'url'].includes(props.type)\n      )) {\n        model.value = el.value\n        return\n      }\n\n      const value = el.value\n      const start = el.selectionStart\n      const end = el.selectionEnd\n\n      model.value = value\n\n      nextTick(() => {\n        let offset = 0\n        if (value.trimStart().length === el.value.length) {\n          // #22307 - Whitespace has been removed from the\n          // start, offset the caret position to compensate\n          offset = value.length - el.value.length\n        }\n        if (start != null) el.selectionStart = start - offset\n        if (end != null) el.selectionEnd = end - offset\n      })\n    }\n\n    useRender(() => {\n      const hasCounter = !!(slots.counter || (props.counter !== false && props.counter != null))\n      const hasDetails = !!(hasCounter || slots.details)\n      const [rootAttrs, inputAttrs] = filterInputAttrs(attrs)\n      const { modelValue: _, ...inputProps } = VInput.filterProps(props)\n      const fieldProps = VField.filterProps(props)\n\n      return (\n        <VInput\n          ref={ vInputRef }\n          v-model={ model.value }\n          class={[\n            'v-text-field',\n            {\n              'v-text-field--prefixed': props.prefix,\n              'v-text-field--suffixed': props.suffix,\n              'v-input--plain-underlined': isPlainOrUnderlined.value,\n            },\n            props.class,\n          ]}\n          style={ props.style }\n          { ...rootAttrs }\n          { ...inputProps }\n          centerAffix={ !isPlainOrUnderlined.value }\n          focused={ isFocused.value }\n          indentDetails={ props.indentDetails ?? !isPlainOrUnderlined.value }\n        >\n          {{\n            ...slots,\n            default: ({\n              id,\n              isDisabled,\n              isDirty,\n              isReadonly,\n              isValid,\n              hasDetails,\n              reset,\n            }) => (\n              <VField\n                ref={ vFieldRef }\n                onMousedown={ onControlMousedown }\n                onClick={ onControlClick }\n                onClick:clear={ (e: MouseEvent) => onClear(e, reset) }\n                role={ props.role }\n                { ...omit(fieldProps, ['onClick:clear']) }\n                id={ id.value }\n                labelId={ `${id.value}-label` }\n                active={ isActive.value || isDirty.value }\n                dirty={ isDirty.value || props.dirty }\n                disabled={ isDisabled.value }\n                focused={ isFocused.value }\n                details={ hasDetails.value }\n                error={ isValid.value === false }\n              >\n                {{\n                  ...slots,\n                  default: ({\n                    props: { class: fieldClass, ...slotProps },\n                    controlRef,\n                  }) => {\n                    const inputNode = (\n                      <input\n                        ref={ val => inputRef.value = controlRef.value = val as HTMLInputElement }\n                        value={ model.value }\n                        onInput={ onInput }\n                        autofocus={ props.autofocus }\n                        readonly={ isReadonly.value }\n                        disabled={ isDisabled.value }\n                        name={ autocomplete.fieldName.value }\n                        autocomplete={ autocomplete.fieldAutocomplete.value }\n                        placeholder={ props.placeholder }\n                        size={ 1 }\n                        role={ props.role }\n                        type={ props.type }\n                        onFocus={ focus }\n                        onBlur={ blur }\n                        aria-labelledby={ `${id.value}-label` }\n                        { ...slotProps }\n                        { ...inputAttrs }\n                      />\n                    )\n\n                    return (\n                      <>\n                        { props.prefix && (\n                          <span class=\"v-text-field__prefix\">\n                            <span class=\"v-text-field__prefix__text\">\n                              { props.prefix }\n                            </span>\n                          </span>\n                        )}\n\n                        { withDirectives(\n                          slots.default ? (\n                            <div\n                              class={ fieldClass }\n                              data-no-activator=\"\"\n                            >\n                              { slots.default({ id }) }\n                              { inputNode }\n                            </div>\n                          ) : cloneVNode(inputNode, { class: fieldClass }),\n                          [[vIntersect, onIntersect, null, { once: true }]],\n                        )}\n\n                        { props.suffix && (\n                          <span class=\"v-text-field__suffix\">\n                            <span class=\"v-text-field__suffix__text\">\n                              { props.suffix }\n                            </span>\n                          </span>\n                        )}\n                      </>\n                    )\n                  },\n                }}\n              </VField>\n            ),\n            details: hasDetails ? slotProps => (\n              <>\n                { slots.details?.(slotProps) }\n\n                { hasCounter && (\n                  <>\n                    <span />\n\n                    <VCounter\n                      active={ props.persistentCounter || isFocused.value }\n                      value={ counterValue.value }\n                      max={ max.value }\n                      disabled={ props.disabled }\n                      v-slots:default={ slots.counter }\n                    />\n                  </>\n                )}\n              </>\n            ) : undefined,\n          }}\n        </VInput>\n      )\n    })\n\n    return forwardRefs({}, vInputRef, vFieldRef, inputRef)\n  },\n})\n\nexport type VTextField = InstanceType<typeof VTextField>\n"
  },
  {
    "path": "packages/vuetify/src/components/VTextField/__tests__/VTextField.spec.browser.tsx",
    "content": "// Components\nimport { VTextField } from '../VTextField'\nimport { VBtn } from '@/components/VBtn'\nimport { VMenu } from '@/components/VMenu'\n\n// Utilities\nimport { commands, render, screen, showcase, userEvent, wait } from '@test'\nimport { cloneVNode, ref } from 'vue'\n\nconst variants = ['underlined', 'outlined', 'filled', 'solo', 'plain'] as const\nconst densities = ['default', 'comfortable', 'compact'] as const\n\nconst stories = Object.fromEntries(Object.entries({\n  'Default input': <VTextField />,\n  Disabled: <VTextField disabled />,\n  Affixes: <VTextField prefix=\"prefix\" suffix=\"suffix\" />,\n  'Prepend/append': <VTextField prependIcon=\"$vuetify\" appendIcon=\"$vuetify\" />,\n  'Prepend/append inner': <VTextField prependInnerIcon=\"$vuetify\" appendInnerIcon=\"$vuetify\" />,\n  Placeholder: <VTextField placeholder=\"placeholder\" persistentPlaceholder />,\n}).map(([k, v]) => [k, (\n  <div class=\"d-flex flex-column flex-grow-1\">\n    { variants.map(variant => (\n      densities.map(density => (\n        <div class=\"d-flex align-start\" style=\"gap: 0.4rem; height: 100px;\">\n          { cloneVNode(v, { variant, density, label: `${variant} ${density}` }) }\n          { cloneVNode(v, { variant, density, label: `with value`, modelValue: 'Value' }) }\n        </div>\n      ))\n    )).flat()}\n  </div>\n)]))\n\ndescribe('VTextField', () => {\n  it('validates input on mount', async () => {\n    const rule = vi.fn(v => v?.length > 4 || 'Error!')\n\n    const { element } = render(() => (\n      <VTextField rules={[rule]} />\n    ))\n\n    expect(element).not.toHaveClass('v-input--error')\n    expect(rule).toHaveBeenCalledOnce()\n    expect(rule).toHaveBeenCalledWith(undefined)\n    await userEvent.click(element)\n    await userEvent.keyboard('Hello')\n    expect(rule).toHaveBeenCalledTimes(6)\n    expect(element).not.toHaveClass('v-input--error')\n  })\n\n  it('does not validate on mount when using validate-on lazy', async () => {\n    const rule = vi.fn(v => v?.length > 5 || 'Error!')\n\n    const { element } = render(() => (\n      <VTextField rules={[rule]} validateOn=\"lazy\" />\n    ))\n\n    expect(element).not.toHaveClass('v-input--error')\n    expect(rule).not.toHaveBeenCalled()\n    await userEvent.click(element)\n    await userEvent.keyboard('Hello')\n    expect(rule).toHaveBeenCalledTimes(5)\n    expect(element).toHaveClass('v-input--error')\n    expect(element).toHaveTextContent('Error!')\n  })\n\n  it('does not trigger infinite loop when autofilled by password manager', async () => {\n    render(() => (\n      <div>\n        <VTextField label=\"username\" name=\"username\" type=\"email\" />\n        <VTextField label=\"password\" name=\"password\" type=\"password\" />\n        <VBtn>\n          Some button\n          <VMenu activator=\"parent\">\n            <div class=\"my-menu-content\">Some text in menu</div>\n          </VMenu>\n        </VBtn>\n      </div>\n    ))\n\n    const input1 = screen.getByCSS('input[name=\"username\"]') as HTMLInputElement\n    const input2 = screen.getByCSS('input[name=\"password\"]') as HTMLInputElement\n\n    await commands.abortAfter(5000, 'VTextField infinite loop detection')\n\n    input1.focus()\n    input1.value = 'my username'\n    input1.dispatchEvent(new InputEvent('input', { bubbles: true, inputType: 'insertFromPaste' }))\n    input1.dispatchEvent(new Event('change', { bubbles: true }))\n\n    input2.focus()\n    input2.value = 'my password'\n    input2.dispatchEvent(new InputEvent('input', { bubbles: true, inputType: 'insertFromPaste' }))\n    input2.dispatchEvent(new Event('change', { bubbles: true }))\n\n    await wait(100)\n    const button = screen.getByCSS('.v-btn')\n    await userEvent.click(button)\n    await wait(100)\n\n    const menuContent = screen.getByCSS('.my-menu-content')\n    expect(menuContent).toBeVisible()\n\n    await commands.clearAbortTimeout()\n  })\n\n  it('handles multiple options in validate-on prop', async () => {\n    const rule = vi.fn(v => v?.length > 5 || 'Error!')\n\n    const { element } = render(() => (\n      <VTextField validateOn=\"blur lazy\" rules={[rule]} />\n    ))\n\n    expect(element).not.toHaveClass('v-input--error')\n    expect(rule).not.toHaveBeenCalled()\n\n    await userEvent.click(element)\n    await userEvent.keyboard('Hello')\n    expect(element).not.toHaveClass('v-input--error')\n    expect(rule).not.toHaveBeenCalled()\n\n    await userEvent.click(document.body)\n    expect(rule).toHaveBeenCalledOnce()\n    expect(element).toHaveClass('v-input--error')\n    expect(element).toHaveTextContent('Error!')\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/15231\n  it('renders details if using hide-details=\"auto\" and counter prop', async () => {\n    const { element } = render(() => (\n      <VTextField hideDetails=\"auto\" counter></VTextField>\n    ))\n    await userEvent.click(element)\n    expect(element).toHaveTextContent('0')\n  })\n\n  it('keeps -0 with v-model.number', async () => {\n    const model = ref()\n    const { element } = render(() => (\n      <VTextField v-model_number={ model.value }></VTextField>\n    ))\n    await userEvent.click(element)\n    await userEvent.keyboard('-0.1')\n    await expect.element(await screen.findByRole('textbox')).toHaveValue('-0.1')\n    expect(model.value).toBe(-0.1)\n  })\n\n  showcase({ stories })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VTextField/__tests__/VTextField.spec.tsx",
    "content": "import { VTextField } from '../VTextField'\n\n// Utilities\nimport { mount } from '@vue/test-utils'\nimport { createVuetify } from '@/framework'\n\ndescribe('VTextField', () => {\n  const vuetify = createVuetify()\n\n  function mountFunction (component: any, options = {}) {\n    return mount(component, {\n      global: {\n        plugins: [vuetify],\n      },\n      ...options,\n    })\n  }\n\n  it('has affixed icons', () => {\n    const wrapper = mountFunction(\n      <VTextField\n        prependIcon=\"$vuetify\"\n        prependInnerIcon=\"$vuetify\"\n        appendInnerIcon=\"$vuetify\"\n        appendIcon=\"$vuetify\"\n      />\n    )\n\n    let el = wrapper.find('.v-input__prepend .v-icon')\n    expect(el.attributes('aria-hidden')).toBe('true')\n    expect(el.attributes('aria-label')).toBeUndefined()\n\n    el = wrapper.find('.v-field__prepend-inner .v-icon')\n    expect(el.attributes('aria-hidden')).toBe('true')\n    expect(el.attributes('aria-label')).toBeUndefined()\n\n    el = wrapper.find('.v-field__append-inner .v-icon')\n    expect(el.attributes('aria-hidden')).toBe('true')\n    expect(el.attributes('aria-label')).toBeUndefined()\n\n    el = wrapper.find('.v-input__append .v-icon')\n    expect(el.attributes('aria-hidden')).toBe('true')\n    expect(el.attributes('aria-label')).toBeUndefined()\n  })\n\n  it('has affixed icons with actions', () => {\n    const onClickPrepend = vi.fn()\n    const onClickPrependInner = vi.fn()\n    const onClickAppendInner = vi.fn()\n    const onClickAppend = vi.fn()\n\n    const wrapper = mountFunction(\n      <VTextField\n        prependIcon=\"$vuetify\"\n        prependInnerIcon=\"$vuetify\"\n        appendInnerIcon=\"$vuetify\"\n        appendIcon=\"$vuetify\"\n        onClick:prepend={ onClickPrepend }\n        onClick:prependInner={ onClickPrependInner }\n        onClick:appendInner={ onClickAppendInner }\n        onClick:append={ onClickAppend }\n      />\n    )\n\n    expect(onClickPrepend).toHaveBeenCalledTimes(0)\n    expect(onClickPrependInner).toHaveBeenCalledTimes(0)\n    expect(onClickAppendInner).toHaveBeenCalledTimes(0)\n    expect(onClickAppend).toHaveBeenCalledTimes(0)\n\n    let el = wrapper.find('.v-input__prepend .v-icon')\n    expect(el.attributes('aria-hidden')).toBe('false')\n    expect(el.attributes('aria-label')).toBeTruthy()\n    el.trigger('click')\n    expect(onClickPrepend).toHaveBeenCalledTimes(1)\n\n    el = wrapper.find('.v-field__prepend-inner .v-icon')\n    expect(el.attributes('aria-hidden')).toBe('false')\n    expect(el.attributes('aria-label')).toBeTruthy()\n    el.trigger('click')\n    expect(onClickPrependInner).toHaveBeenCalledTimes(1)\n\n    el = wrapper.find('.v-field__append-inner .v-icon')\n    expect(el.attributes('aria-hidden')).toBe('false')\n    expect(el.attributes('aria-label')).toBeTruthy()\n    el.trigger('click')\n    expect(onClickAppendInner).toHaveBeenCalledTimes(1)\n\n    el = wrapper.find('.v-input__append .v-icon')\n    expect(el.attributes('aria-hidden')).toBe('false')\n    expect(el.attributes('aria-label')).toBeTruthy()\n    el.trigger('click')\n    expect(onClickAppend).toHaveBeenCalledTimes(1)\n\n    expect(onClickPrepend).toHaveBeenCalledTimes(1)\n    expect(onClickPrependInner).toHaveBeenCalledTimes(1)\n    expect(onClickAppendInner).toHaveBeenCalledTimes(1)\n  })\n\n  describe('hide-details behavior', () => {\n    it('should not have aria-describedby when hide-details is true', () => {\n      const wrapper = mountFunction(\n        <VTextField hideDetails />\n      )\n\n      const input = wrapper.find('input')\n      expect(input.attributes('aria-describedby')).toBeUndefined()\n\n      // Should not have details section\n      const details = wrapper.find('.v-input__details')\n      expect(details.exists()).toBe(false)\n    })\n\n    it('should have aria-describedby when hide-details is false or undefined', () => {\n      const wrapper = mountFunction(\n        <VTextField id=\"input-1\" />\n      )\n\n      const input = wrapper.find('input')\n      expect(input.attributes('aria-describedby')).toBe('input-1-messages')\n\n      // Should have details section\n      const details = wrapper.find('.v-input__details')\n      expect(details.exists()).toBe(true)\n      expect(details.attributes('id')).toBe('input-1-messages')\n    })\n\n    it('should have aria-describedby when hide-details is \"auto\" and has messages', () => {\n      const wrapper = mountFunction(\n        <VTextField\n          id=\"input-2\"\n          messages={['Hello World!']}\n          hideDetails=\"auto\"\n        />\n      )\n\n      const input = wrapper.find('input')\n      expect(input.attributes('aria-describedby')).toBe('input-2-messages')\n\n      // Should have details section with messages\n      const details = wrapper.find('.v-input__details')\n      expect(details.exists()).toBe(true)\n      expect(details.attributes('id')).toBe('input-2-messages')\n\n      const messages = wrapper.find('.v-messages')\n      expect(messages.exists()).toBe(true)\n    })\n\n    it('should not have aria-describedby when hide-details is \"auto\" and no messages', () => {\n      const wrapper = mountFunction(\n        <VTextField\n          id=\"input-3\"\n          hideDetails=\"auto\"\n        />\n      )\n\n      const input = wrapper.find('input')\n      expect(input.attributes('aria-describedby')).toBeUndefined()\n\n      // Should not have details section\n      const details = wrapper.find('.v-input__details')\n      expect(details.exists()).toBe(false)\n    })\n\n    it('should have aria-describedby when hide-details is \"auto\" and has error messages', () => {\n      const wrapper = mountFunction(\n        <VTextField\n          id=\"input-4\"\n          errorMessages={['This field is required']}\n          hideDetails=\"auto\"\n        />\n      )\n\n      const input = wrapper.find('input')\n      expect(input.attributes('aria-describedby')).toBe('input-4-messages')\n\n      // Should have details section with error messages\n      const details = wrapper.find('.v-input__details')\n      expect(details.exists()).toBe(true)\n      expect(details.attributes('id')).toBe('input-4-messages')\n    })\n\n    it('should have aria-describedby when hide-details is \"auto\" and has counter', () => {\n      const wrapper = mountFunction(\n        <VTextField\n          id=\"input-5\"\n          counter={ 10 }\n          hideDetails=\"auto\"\n        />\n      )\n\n      const input = wrapper.find('input')\n      expect(input.attributes('aria-describedby')).toBe('input-5-messages')\n\n      // Should have details section with counter\n      const details = wrapper.find('.v-input__details')\n      expect(details.exists()).toBe(true)\n      expect(details.attributes('id')).toBe('input-5-messages')\n    })\n\n    it('should have aria-describedby when hide-details is \"auto\" and has details slot', () => {\n      const wrapper = mountFunction(\n        <VTextField\n          id=\"input-6\"\n          hideDetails=\"auto\"\n          v-slots={{\n            details: () => <div>Custom details</div>,\n          }}\n        />\n      )\n\n      const input = wrapper.find('input')\n      expect(input.attributes('aria-describedby')).toBe('input-6-messages')\n\n      // Should have details section with custom content\n      const details = wrapper.find('.v-input__details')\n      expect(details.exists()).toBe(true)\n      expect(details.attributes('id')).toBe('input-6-messages')\n      expect(details.text()).toContain('Custom details')\n    })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VTextField/_variables.scss",
    "content": "@forward '../VField/variables';\n@use '../../styles/settings';\n@use '../../styles/tools';\n\n// VTextField\n$text-field-affix-color: tools.theme-color('on-surface', var(--v-medium-emphasis-opacity)) !default;\n$text-field-border-radius: settings.$border-radius-root !default;\n$text-field-disabled-affix-color: tools.theme-color('on-surface', var(--v-disabled-opacity)) !default;\n$text-field-input-flex: 1 !default;\n$text-field-input-padding-end: 0 !default;\n$text-field-input-padding-start: 6px !default;\n$text-field-input-transition: .15s opacity settings.$standard-easing !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VTextField/index.ts",
    "content": "export { VTextField } from './VTextField'\n"
  },
  {
    "path": "packages/vuetify/src/components/VTextarea/VTextarea.sass",
    "content": "@use 'sass:math'\n@use 'sass:selector'\n@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-textarea\n    --v-textarea-max-height: initial\n\n    .v-field\n      --v-textarea-control-height: var(--v-input-control-height)\n\n      &:not(.v-field--no-label, .v-field--active)\n        textarea::placeholder\n          opacity: 0\n\n    .v-field__field\n      --v-input-control-height: var(--v-textarea-control-height)\n\n    .v-field__input\n      max-height: var(--v-textarea-max-height)\n\n      $a: calc((var(--v-field-padding-top, 0) + var(--v-input-padding-top, 0)) - 6px)\n      $b: calc(var(--v-field-padding-top, 0) + var(--v-input-padding-top, 0) + 4px)\n      $c: calc(100% - var(--v-textarea-scroll-bar-width, 16px))\n\n      flex: 1 1 auto\n      outline: none\n\n      -webkit-mask-image: linear-gradient(to bottom, transparent, transparent $a, black $b), linear-gradient(to right, transparent, transparent $c, black $c)\n      mask-image: linear-gradient(to bottom, transparent, transparent $a, black $b), linear-gradient(to right, transparent, transparent $c, black $c)\n\n      &.v-textarea__sizer\n        visibility: hidden\n        position: absolute\n        top: 0\n        left: 0\n        pointer-events: none\n\n        @include tools.layer('overrides')\n          height: 0\n          min-height: 0\n\n    &--no-resize\n      .v-field__input\n        resize: none\n\n    textarea\n      flex: 1\n      min-width: 0\n      height: 100%\n      transition: .15s opacity settings.$standard-easing\n\n      &:focus,\n      &:active\n        outline: none\n\n      // Remove Firefox red outline\n      &:invalid\n        box-shadow: none\n"
  },
  {
    "path": "packages/vuetify/src/components/VTextarea/VTextarea.tsx",
    "content": "// Styles\nimport './VTextarea.sass'\nimport '../VTextField/VTextField.sass'\n\n// Components\nimport { VCounter } from '@/components/VCounter/VCounter'\nimport { VField } from '@/components/VField'\nimport { makeVFieldProps } from '@/components/VField/VField'\nimport { makeVInputProps, VInput } from '@/components/VInput/VInput'\n\n// Composables\nimport { useDisplay } from '@/composables'\nimport { makeAutocompleteProps, useAutocomplete } from '@/composables/autocomplete'\nimport { useAutofocus } from '@/composables/autofocus'\nimport { useFocus } from '@/composables/focus'\nimport { forwardRefs } from '@/composables/forwardRefs'\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Directives\nimport vIntersect from '@/directives/intersect'\n\n// Utilities\nimport { computed, nextTick, onBeforeUnmount, onMounted, ref, shallowRef, watch, watchEffect } from 'vue'\nimport { callEvent, clamp, convertToUnit, filterInputAttrs, genericComponent, omit, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { VCounterSlot } from '@/components/VCounter/VCounter'\nimport type { VFieldSlots } from '@/components/VField/VField'\nimport type { VInputSlots } from '@/components/VInput/VInput'\n\nexport const makeVTextareaProps = propsFactory({\n  autoGrow: Boolean,\n  autofocus: Boolean,\n  counter: [Boolean, Number, String] as PropType<true | number | string>,\n  counterValue: Function as PropType<(value: any) => number>,\n  prefix: String,\n  placeholder: String,\n  persistentPlaceholder: Boolean,\n  persistentCounter: Boolean,\n  noResize: Boolean,\n  rows: {\n    type: [Number, String],\n    default: 5,\n    validator: (v: any) => !isNaN(parseFloat(v)),\n  },\n  maxHeight: {\n    type: [Number, String],\n    validator: (v: any) => !isNaN(parseFloat(v)),\n  },\n  maxRows: {\n    type: [Number, String],\n    validator: (v: any) => !isNaN(parseFloat(v)),\n  },\n  suffix: String,\n  modelModifiers: Object as PropType<Record<string, boolean>>,\n\n  ...makeAutocompleteProps(),\n  ...omit(makeVInputProps(), ['direction']),\n  ...makeVFieldProps(),\n}, 'VTextarea')\n\ntype VTextareaSlots = Omit<VInputSlots & VFieldSlots, 'default'> & {\n  counter: VCounterSlot\n}\n\nexport const VTextarea = genericComponent<VTextareaSlots>()({\n  name: 'VTextarea',\n\n  directives: { vIntersect },\n\n  inheritAttrs: false,\n\n  props: makeVTextareaProps(),\n\n  emits: {\n    'click:control': (e: MouseEvent) => true,\n    'mousedown:control': (e: MouseEvent) => true,\n    'update:focused': (focused: boolean) => true,\n    'update:modelValue': (val: string) => true,\n    'update:rows': (rows: number) => true,\n  },\n\n  setup (props, { attrs, emit, slots }) {\n    const model = useProxiedModel(props, 'modelValue')\n    const { isFocused, focus, blur } = useFocus(props)\n    const { onIntersect } = useAutofocus(props)\n    const counterValue = computed(() => {\n      return typeof props.counterValue === 'function'\n        ? props.counterValue(model.value)\n        : (model.value || '').toString().length\n    })\n    const max = computed(() => {\n      if (attrs.maxlength) return attrs.maxlength as string | number\n\n      if (\n        !props.counter ||\n        (typeof props.counter !== 'number' &&\n        typeof props.counter !== 'string')\n      ) return undefined\n\n      return props.counter\n    })\n\n    const vInputRef = ref<VInput>()\n    const vFieldRef = ref<VField>()\n    const controlHeight = shallowRef('')\n    const textareaRef = ref<HTMLTextAreaElement>()\n    const scrollbarWidth = ref(0)\n    const { platform } = useDisplay()\n    const autocomplete = useAutocomplete(props)\n    const isActive = computed(() => (\n      props.persistentPlaceholder ||\n      isFocused.value ||\n      props.active\n    ))\n\n    function onFocus () {\n      if (autocomplete.isSuppressing.value) {\n        autocomplete.update()\n      }\n\n      if (textareaRef.value !== document.activeElement) {\n        textareaRef.value?.focus()\n      }\n\n      if (!isFocused.value) focus()\n    }\n    function onControlClick (e: MouseEvent) {\n      onFocus()\n\n      emit('click:control', e)\n    }\n    function onControlMousedown (e: MouseEvent) {\n      emit('mousedown:control', e)\n    }\n    function onClear (e: MouseEvent) {\n      e.stopPropagation()\n\n      onFocus()\n\n      nextTick(() => {\n        model.value = ''\n\n        callEvent(props['onClick:clear'], e)\n      })\n    }\n    function onInput (e: Event) {\n      const el = e.target as HTMLTextAreaElement\n      if (!props.modelModifiers?.trim) {\n        model.value = el.value\n        return\n      }\n\n      const value = el.value\n      const start = el.selectionStart\n      const end = el.selectionEnd\n\n      model.value = value\n\n      nextTick(() => {\n        let offset = 0\n        if (value.trimStart().length === el.value.length) {\n          // #22307 - Whitespace has been removed from the\n          // start, offset the caret position to compensate\n          offset = value.length - el.value.length\n        }\n        if (start != null) el.selectionStart = start - offset\n        if (end != null) el.selectionEnd = end - offset\n      })\n    }\n\n    const sizerRef = ref<HTMLTextAreaElement>()\n    const rows = ref(Number(props.rows))\n    const isPlainOrUnderlined = computed(() => ['plain', 'underlined'].includes(props.variant))\n    watchEffect(() => {\n      if (!props.autoGrow) rows.value = Number(props.rows)\n    })\n    function calculateInputHeight () {\n      nextTick(() => {\n        if (!textareaRef.value) return\n        if (platform.value.firefox) {\n          scrollbarWidth.value = 12\n          return\n        }\n        const { offsetWidth, clientWidth } = textareaRef.value\n        scrollbarWidth.value = Math.max(0, offsetWidth - clientWidth)\n      })\n\n      if (!props.autoGrow) return\n\n      nextTick(() => {\n        if (!sizerRef.value || !vFieldRef.value) return\n\n        const style = getComputedStyle(sizerRef.value)\n        const fieldStyle = getComputedStyle(vFieldRef.value.$el)\n\n        const padding = parseFloat(style.getPropertyValue('--v-field-padding-top')) +\n          parseFloat(style.getPropertyValue('--v-input-padding-top')) +\n          parseFloat(style.getPropertyValue('--v-field-padding-bottom'))\n\n        const height = sizerRef.value.scrollHeight\n        const lineHeight = parseFloat(style.lineHeight)\n        const minHeight = Math.max(\n          parseFloat(props.rows) * lineHeight + padding,\n          parseFloat(fieldStyle.getPropertyValue('--v-input-control-height'))\n        )\n\n        const maxHeight = props.maxHeight\n          ? parseFloat(props.maxHeight!)\n          : parseFloat(props.maxRows!) * lineHeight + padding || Infinity\n\n        const newHeight = clamp(height ?? 0, minHeight, maxHeight)\n        rows.value = Math.floor((newHeight - padding) / lineHeight)\n\n        controlHeight.value = convertToUnit(newHeight)\n      })\n    }\n\n    onMounted(calculateInputHeight)\n    watch(model, calculateInputHeight)\n    watch(() => props.rows, calculateInputHeight)\n    watch(() => props.maxHeight, calculateInputHeight)\n    watch(() => props.maxRows, calculateInputHeight)\n    watch(() => props.density, calculateInputHeight)\n    watch(rows, val => {\n      emit('update:rows', val)\n    })\n\n    let observer: ResizeObserver | undefined\n    watch(sizerRef, val => {\n      if (val) {\n        observer = new ResizeObserver(calculateInputHeight)\n        observer.observe(sizerRef.value!)\n      } else {\n        observer?.disconnect()\n      }\n    })\n    onBeforeUnmount(() => {\n      observer?.disconnect()\n    })\n\n    useRender(() => {\n      const hasCounter = !!(slots.counter || props.counter || props.counterValue)\n      const hasDetails = !!(hasCounter || slots.details)\n      const [rootAttrs, inputAttrs] = filterInputAttrs(attrs)\n      const { modelValue: _, ...inputProps } = VInput.filterProps(props)\n      const fieldProps = {\n        ...VField.filterProps(props),\n        'onClick:clear': onClear,\n      }\n\n      return (\n        <VInput\n          ref={ vInputRef }\n          v-model={ model.value }\n          class={[\n            'v-textarea v-text-field',\n            {\n              'v-textarea--prefixed': props.prefix,\n              'v-textarea--suffixed': props.suffix,\n              'v-text-field--prefixed': props.prefix,\n              'v-text-field--suffixed': props.suffix,\n              'v-textarea--auto-grow': props.autoGrow,\n              'v-textarea--no-resize': props.noResize || props.autoGrow,\n              'v-input--plain-underlined': isPlainOrUnderlined.value,\n            },\n            props.class,\n          ]}\n          style={[\n            {\n              '--v-textarea-max-height': props.maxHeight ? convertToUnit(props.maxHeight) : undefined,\n              '--v-textarea-scroll-bar-width': convertToUnit(scrollbarWidth.value),\n            },\n            props.style,\n          ]}\n          { ...rootAttrs }\n          { ...inputProps }\n          centerAffix={ rows.value === 1 && !isPlainOrUnderlined.value }\n          focused={ isFocused.value }\n          indentDetails={ props.indentDetails ?? !isPlainOrUnderlined.value }\n        >\n          {{\n            ...slots,\n            default: ({\n              id,\n              isDisabled,\n              isDirty,\n              isReadonly,\n              isValid,\n              hasDetails,\n            }) => (\n              <VField\n                ref={ vFieldRef }\n                style={{\n                  '--v-textarea-control-height': controlHeight.value,\n                }}\n                onClick={ onControlClick }\n                onMousedown={ onControlMousedown }\n                onClick:prependInner={ props['onClick:prependInner'] }\n                onClick:appendInner={ props['onClick:appendInner'] }\n                { ...fieldProps }\n                id={ id.value }\n                active={ isActive.value || isDirty.value }\n                labelId={ `${id.value}-label` }\n                centerAffix={ rows.value === 1 && !isPlainOrUnderlined.value }\n                dirty={ isDirty.value || props.dirty }\n                disabled={ isDisabled.value }\n                focused={ isFocused.value }\n                details={ hasDetails.value }\n                error={ isValid.value === false }\n              >\n                {{\n                  ...slots,\n                  default: ({\n                    props: { class: fieldClass, ...slotProps },\n                    controlRef,\n                  }) => (\n                    <>\n                      { props.prefix && (\n                        <span class=\"v-text-field__prefix\">\n                          { props.prefix }\n                        </span>\n                      )}\n\n                      <textarea\n                        ref={ val => textareaRef.value = controlRef.value = val as HTMLTextAreaElement }\n                        class={ fieldClass }\n                        value={ model.value }\n                        onInput={ onInput }\n                        v-intersect={[{\n                          handler: onIntersect,\n                        }, null, ['once']]}\n                        autofocus={ props.autofocus }\n                        readonly={ isReadonly.value }\n                        disabled={ isDisabled.value }\n                        placeholder={ props.placeholder }\n                        rows={ props.rows }\n                        name={ autocomplete.fieldName.value }\n                        autocomplete={ autocomplete.fieldAutocomplete.value }\n                        onFocus={ onFocus }\n                        onBlur={ blur }\n                        aria-labelledby={ `${id.value}-label` }\n                        { ...slotProps }\n                        { ...inputAttrs }\n                      />\n\n                      { props.autoGrow && (\n                        <textarea\n                          class={[\n                            fieldClass,\n                            'v-textarea__sizer',\n                          ]}\n                          id={ `${slotProps.id}-sizer` }\n                          v-model={ model.value }\n                          ref={ sizerRef }\n                          readonly\n                          aria-hidden=\"true\"\n                        />\n                      )}\n\n                      { props.suffix && (\n                        <span class=\"v-text-field__suffix\">\n                          { props.suffix }\n                        </span>\n                      )}\n                    </>\n                  ),\n                }}\n              </VField>\n            ),\n            details: hasDetails ? slotProps => (\n              <>\n                { slots.details?.(slotProps) }\n\n                { hasCounter && (\n                  <>\n                    <span />\n\n                    <VCounter\n                      active={ props.persistentCounter || isFocused.value }\n                      value={ counterValue.value }\n                      max={ max.value }\n                      disabled={ props.disabled }\n                      v-slots:default={ slots.counter }\n                    />\n                  </>\n                )}\n              </>\n            ) : undefined,\n          }}\n        </VInput>\n      )\n    })\n\n    return forwardRefs({}, vInputRef, vFieldRef, textareaRef)\n  },\n})\n\nexport type VTextarea = InstanceType<typeof VTextarea>\n"
  },
  {
    "path": "packages/vuetify/src/components/VTextarea/__tests__/VTextarea.spec.browser.tsx",
    "content": "import { VTextarea } from '..'\n\n// Utilities\nimport { Application, page, render, screen, userEvent } from '@test'\nimport { ref } from 'vue'\n\n// Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n\ndescribe('VTextarea', () => {\n  it('should auto-grow', async () => {\n    await page.viewport(500, 500)\n    const model = ref('Lorem ipsum dolor sit amet, consectetur adipiscing elit')\n\n    render(() => (\n      <Application>\n        <div>\n          <VTextarea autoGrow rows=\"1\" v-model={ model.value } />\n        </div>\n      </Application>\n    ))\n\n    const el = screen.getByCSS('textarea[rows]')\n\n    expect(el.offsetHeight).toBe(56)\n\n    await userEvent.tab()\n    await userEvent.keyboard('sed d')\n    await expect.poll(() => el.offsetHeight).toBe(56)\n\n    await userEvent.keyboard('{Enter}')\n    await expect.poll(() => el.offsetHeight).toBe(80)\n  })\n\n  it('should respect max-rows', async () => {\n    await page.viewport(500, 500)\n    const model = ref('Lorem ipsum dolor sit amet, consectetur adipiscing elit')\n\n    render(() => (\n      <Application>\n        <div>\n          <VTextarea autoGrow rows=\"1\" maxRows=\"2\" v-model={ model.value } />\n        </div>\n      </Application>\n    ))\n\n    const el = screen.getByCSS('textarea[rows]')\n\n    expect(el.offsetHeight).toBe(56)\n\n    await userEvent.tab()\n    await userEvent.keyboard('Lorem ipsum dolor sit amet consectetur adipisicing elit. ')\n    await expect.poll(() => el.offsetHeight).toBe(80)\n\n    await userEvent.keyboard('Lorem ipsum dolor sit amet consectetur adipisicing elit. ')\n    await expect.poll(() => el.offsetHeight).toBe(80)\n  })\n\n  it('should emit update rows', async () => {\n    await page.viewport(500, 500)\n    const model = ref('Lorem ipsum dolor sit amet, consectetur adipiscing elit')\n    const rows = ref(1)\n    render(() => (\n      <Application>\n        <div>\n          <VTextarea autoGrow rows=\"1\" v-model={ model.value } onUpdate:rows={ val => { rows.value = val } } />\n        </div>\n      </Application>\n    ))\n    await userEvent.tab()\n    await userEvent.keyboard('Lorem ipsum dolor')\n    expect(rows.value).toBe(2)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VTextarea/__tests__/VTextarea.spec.tsx",
    "content": "import { VTextarea } from '../VTextarea'\n\n// Utilities\nimport { mount } from '@vue/test-utils'\nimport { createVuetify } from '@/framework'\n\ndescribe('VTextarea', () => {\n  const vuetify = createVuetify()\n\n  function mountFunction (component: any, options = {}) {\n    return mount(component, {\n      global: {\n        plugins: [vuetify],\n      },\n      ...options,\n    })\n  }\n\n  it('has affixed icons', () => {\n    const wrapper = mountFunction(\n      <VTextarea\n        prependIcon=\"$vuetify\"\n        prependInnerIcon=\"$vuetify\"\n        appendInnerIcon=\"$vuetify\"\n        appendIcon=\"$vuetify\"\n      />\n    )\n\n    let el = wrapper.find('.v-input__prepend .v-icon')\n    expect(el.attributes('aria-hidden')).toBe('true')\n    expect(el.attributes('aria-label')).toBeUndefined()\n\n    el = wrapper.find('.v-field__prepend-inner .v-icon')\n    expect(el.attributes('aria-hidden')).toBe('true')\n    expect(el.attributes('aria-label')).toBeUndefined()\n\n    el = wrapper.find('.v-field__append-inner .v-icon')\n    expect(el.attributes('aria-hidden')).toBe('true')\n    expect(el.attributes('aria-label')).toBeUndefined()\n\n    el = wrapper.find('.v-input__append .v-icon')\n    expect(el.attributes('aria-hidden')).toBe('true')\n    expect(el.attributes('aria-label')).toBeUndefined()\n  })\n\n  it('has affixed icons with actions', () => {\n    const onClickPrepend = vi.fn()\n    const onClickPrependInner = vi.fn()\n    const onClickAppendInner = vi.fn()\n    const onClickAppend = vi.fn()\n\n    const wrapper = mountFunction(\n      <VTextarea\n        prependIcon=\"$vuetify\"\n        prependInnerIcon=\"$vuetify\"\n        appendInnerIcon=\"$vuetify\"\n        appendIcon=\"$vuetify\"\n        onClick:prepend={ onClickPrepend }\n        onClick:prependInner={ onClickPrependInner }\n        onClick:appendInner={ onClickAppendInner }\n        onClick:append={ onClickAppend }\n      />\n    )\n\n    expect(onClickPrepend).toHaveBeenCalledTimes(0)\n    expect(onClickPrependInner).toHaveBeenCalledTimes(0)\n    expect(onClickAppendInner).toHaveBeenCalledTimes(0)\n    expect(onClickAppend).toHaveBeenCalledTimes(0)\n\n    let el = wrapper.find('.v-input__prepend .v-icon')\n    expect(el.attributes('aria-hidden')).toBe('false')\n    expect(el.attributes('aria-label')).toBeTruthy()\n    el.trigger('click')\n    expect(onClickPrepend).toHaveBeenCalledTimes(1)\n\n    el = wrapper.find('.v-field__prepend-inner .v-icon')\n    expect(el.attributes('aria-hidden')).toBe('false')\n    expect(el.attributes('aria-label')).toBeTruthy()\n    el.trigger('click')\n    expect(onClickPrependInner).toHaveBeenCalledTimes(1)\n\n    el = wrapper.find('.v-field__append-inner .v-icon')\n    expect(el.attributes('aria-hidden')).toBe('false')\n    expect(el.attributes('aria-label')).toBeTruthy()\n    el.trigger('click')\n    expect(onClickAppendInner).toHaveBeenCalledTimes(1)\n\n    el = wrapper.find('.v-input__append .v-icon')\n    expect(el.attributes('aria-hidden')).toBe('false')\n    expect(el.attributes('aria-label')).toBeTruthy()\n    el.trigger('click')\n    expect(onClickAppend).toHaveBeenCalledTimes(1)\n\n    expect(onClickPrepend).toHaveBeenCalledTimes(1)\n    expect(onClickPrependInner).toHaveBeenCalledTimes(1)\n    expect(onClickAppendInner).toHaveBeenCalledTimes(1)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VTextarea/_variables.scss",
    "content": "@use '../../styles/settings';\n\n// VTextarea\n$textarea-box-enclosed-prefix-margin-top: 24px !default;\n$textarea-box-enclosed-single-outlined-label-top: 18px !default;\n$textarea-box-enclosed-single-outlined-margin-top: 10px !default;\n$textarea-dense-box-enclosed-single-outlined-margin-top: 6px !default;\n$textarea-dense-append-prepend-margin-top: 8px !default;\n$textarea-enclosed-text-slot-margin: -12px !default;\n$textarea-enclosed-text-slot-padding: 12px !default;\n$textarea-prefix-padding-top: 2px !default;\n$textarea-solo-append-padding: 12px !default;\n$textarea-solo-append-prepend-margin-top: 12px !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VTextarea/index.ts",
    "content": "export { VTextarea } from './VTextarea'\n"
  },
  {
    "path": "packages/vuetify/src/components/VThemeProvider/VThemeProvider.sass",
    "content": "@use '../../styles/tools'\n\n@include tools.layer('components')\n  .v-theme-provider\n    background: rgb(var(--v-theme-background))\n    color: rgb(var(--v-theme-on-background))\n"
  },
  {
    "path": "packages/vuetify/src/components/VThemeProvider/VThemeProvider.tsx",
    "content": "// Styles\nimport './VThemeProvider.sass'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { makeTagProps } from '@/composables/tag'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\n\n// Utilities\nimport { genericComponent, propsFactory } from '@/util'\n\nexport const makeVThemeProviderProps = propsFactory({\n  withBackground: Boolean,\n\n  ...makeComponentProps(),\n  ...makeThemeProps(),\n  ...makeTagProps(),\n}, 'VThemeProvider')\n\nexport const VThemeProvider = genericComponent()({\n  name: 'VThemeProvider',\n\n  props: makeVThemeProviderProps(),\n\n  setup (props, { slots }) {\n    const { themeClasses } = provideTheme(props)\n\n    return () => {\n      if (!props.withBackground) return slots.default?.()\n\n      return (\n        <props.tag\n          class={[\n            'v-theme-provider',\n            themeClasses.value,\n            props.class,\n          ]}\n          style={ props.style }\n        >\n          { slots.default?.() }\n        </props.tag>\n      )\n    }\n  },\n})\n\nexport type VThemeProvider = InstanceType<typeof VThemeProvider>\n"
  },
  {
    "path": "packages/vuetify/src/components/VThemeProvider/__tests__/VThemeProvider.spec.browser.tsx",
    "content": "// Components\nimport { VThemeProvider } from '../VThemeProvider'\nimport { VBtn } from '@/components/VBtn'\n\n// Utilities\nimport { render, screen } from '@test'\n\ndescribe('VThemeProvider', () => {\n  it('should use provided theme', () => {\n    render(() => (\n      <VThemeProvider theme=\"dark\">\n        <VBtn color=\"primary\">button</VBtn>\n      </VThemeProvider>\n    ))\n\n    expect(screen.getByCSS('.v-btn')).toHaveClass('v-theme--dark')\n  })\n\n  it('should use theme defined in prop', () => {\n    render(() => (\n      <VThemeProvider theme=\"dark\">\n        <VBtn color=\"primary\" theme=\"light\">button</VBtn>\n      </VThemeProvider>\n    ))\n\n    expect(screen.getByCSS('.v-btn')).toHaveClass('v-theme--light')\n  })\n\n  it('should render element when using with-background prop', async () => {\n    render(() => (\n      <VThemeProvider theme=\"dark\" withBackground>\n        <VBtn color=\"primary\">button</VBtn>\n      </VThemeProvider>\n    ))\n\n    await expect(screen.getByCSS('.v-theme-provider')).toBeVisible()\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VThemeProvider/index.ts",
    "content": "export { VThemeProvider } from './VThemeProvider'\n"
  },
  {
    "path": "packages/vuetify/src/components/VTimePicker/VTimePicker.sass",
    "content": "@use '../../styles/tools'\n@use '../../styles/settings'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-time-picker\n    &.v-picker\n      min-width: $time-picker-width\n\n    .v-picker__body,\n    &-controls__field-label,\n    .v-field\n      transition-duration: .25s\n      transition-timing-function: settings.$standard-easing\n      transition-property: transform, max-height, opacity, font-size\n\n      @media (prefers-reduced-motion: reduce)\n        transition: none\n\n    .v-picker__body\n      transition-behavior: allow-discrete\n      max-height: calc-size(max-content, size)\n\n    &--variant-input\n      .v-picker__body\n        transform: scale(0)\n        max-height: 0\n"
  },
  {
    "path": "packages/vuetify/src/components/VTimePicker/VTimePicker.tsx",
    "content": "// Styles\nimport './VTimePicker.sass'\n\n// Components\nimport { VTimePickerClock } from './VTimePickerClock'\nimport { VTimePickerControls } from './VTimePickerControls'\nimport { makeVPickerProps, VPicker } from '@/labs/VPicker/VPicker'\n\n// Composables\nimport { makeDensityProps, useDensity } from '@/composables/density'\nimport { useLocale } from '@/composables/locale'\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { computed, onMounted, ref, toRef, watch } from 'vue'\nimport { makeTimeValidationProps, useTimeValidation } from './useTimeValidation'\nimport { convert12to24, convert24to12, pad } from './util'\nimport { genericComponent, omit, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { Period, VTimePickerViewMode } from './shared'\nimport type { VPickerSlots } from '@/labs/VPicker/VPicker'\n\nexport type VTimePickerSlots = Omit<VPickerSlots, 'header'>\n\ntype Variant = 'dial' | 'input'\n\nexport const makeVTimePickerProps = propsFactory({\n  disabled: Boolean,\n  format: {\n    type: String as PropType<'ampm' | '24hr'>,\n    default: 'ampm',\n  },\n  viewMode: {\n    type: String as PropType<VTimePickerViewMode>,\n    default: 'hour',\n  },\n  period: {\n    type: String as PropType<Period>,\n    default: 'am',\n    validator: (v: any) => ['am', 'pm'].includes(v),\n  },\n  modelValue: null as any as PropType<any>,\n  readonly: Boolean,\n  scrollable: Boolean,\n  useSeconds: Boolean,\n  variant: {\n    type: String as PropType<Variant>,\n    default: 'dial',\n  },\n  ...makeTimeValidationProps(),\n  ...omit(makeVPickerProps({ title: '$vuetify.timePicker.title' }), ['landscape']),\n  ...makeDensityProps(),\n}, 'VTimePicker')\n\nexport const VTimePicker = genericComponent<VTimePickerSlots>()({\n  name: 'VTimePicker',\n\n  props: makeVTimePickerProps(),\n\n  emits: {\n    'update:hour': (val: number) => true,\n    'update:minute': (val: number) => true,\n    'update:period': (val: Period) => true,\n    'update:second': (val: number) => true,\n    'update:modelValue': (val: string | null) => true,\n    'update:viewMode': (val: VTimePickerViewMode) => true,\n  },\n\n  setup (props, { emit, slots }) {\n    const { t } = useLocale()\n    const { densityClasses } = useDensity(props)\n    const inputHour = ref(null as number | null)\n    const inputMinute = ref(null as number | null)\n    const inputSecond = ref(null as number | null)\n    const lazyInputHour = ref(null as number | null)\n    const lazyInputMinute = ref(null as number | null)\n    const lazyInputSecond = ref(null as number | null)\n    const period = useProxiedModel(props, 'period', 'am')\n    const viewMode = useProxiedModel(props, 'viewMode', 'hour')\n    const controlsRef = ref<VTimePickerControls | null>(null)\n    const clockRef = ref<VTimePickerClock | null>(null)\n\n    const isAmPm = computed((): boolean => {\n      return props.format === 'ampm'\n    })\n\n    const {\n      isAllowedHour,\n      isAllowedMinute,\n      isAllowedSecond,\n    } = useTimeValidation(props)\n\n    const shouldClear = toRef(() => {\n      return props.modelValue !== null &&\n        inputHour.value === null &&\n        inputMinute.value === null &&\n        (!props.useSeconds || inputSecond.value === null)\n    })\n\n    function emitValue () {\n      const value = genValue()\n\n      if (value !== null && value !== props.modelValue) {\n        emit('update:modelValue', value)\n      }\n      if (shouldClear.value) {\n        emit('update:modelValue', null)\n      }\n    }\n\n    watch(inputHour, emitValue)\n    watch(inputMinute, emitValue)\n    watch(inputSecond, emitValue)\n\n    watch(period, (newPeriod, oldPeriod) => {\n      if (inputHour.value == null || newPeriod === oldPeriod) return\n      if (newPeriod === 'pm' && inputHour.value < 12) {\n        inputHour.value = inputHour.value + 12\n      } else if (newPeriod === 'am' && inputHour.value >= 12) {\n        inputHour.value = inputHour.value - 12\n      }\n    })\n\n    watch(() => props.modelValue, val => setInputData(val))\n\n    watch(() => props.useSeconds, (val, old) => {\n      if (old && !val && viewMode.value === 'second') {\n        viewMode.value = 'minute'\n      }\n      if (!val && inputSecond.value !== null) {\n        inputSecond.value = null\n      }\n    })\n\n    onMounted(() => {\n      setInputData(props.modelValue)\n    })\n\n    function genValue () {\n      if (inputHour.value != null && inputMinute.value != null && (!props.useSeconds || inputSecond.value != null)) {\n        return `${pad(inputHour.value)}:${pad(inputMinute.value)}` + (props.useSeconds ? `:${pad(inputSecond.value!)}` : '')\n      }\n\n      return null\n    }\n\n    function setInputData (value: string | null | Date) {\n      if (value == null || value === '') {\n        inputHour.value = null\n        inputMinute.value = null\n        inputSecond.value = null\n      } else if (value instanceof Date) {\n        inputHour.value = value.getHours()\n        inputMinute.value = value.getMinutes()\n        inputSecond.value = value.getSeconds()\n      } else {\n        const [hour, , minute, , second, period] = value.trim().toLowerCase().match(/^(\\d+):(\\d+)(:(\\d+))?([ap]m)?$/) || new Array(6)\n\n        inputHour.value = period ? convert12to24(parseInt(hour, 10), period as Period) : parseInt(hour, 10)\n        inputMinute.value = parseInt(minute, 10)\n        inputSecond.value = parseInt(second || 0, 10)\n      }\n\n      period.value = (inputHour.value == null || inputHour.value < 12) ? 'am' : 'pm'\n    }\n\n    function onInput (value: number) {\n      if (viewMode.value === 'hour') {\n        inputHour.value = isAmPm.value ? convert12to24(value, period.value) : value\n      } else if (viewMode.value === 'minute') {\n        inputMinute.value = value\n      } else {\n        inputSecond.value = value\n      }\n    }\n\n    function onChange (value: number) {\n      switch (viewMode.value || 'hour') {\n        case 'hour':\n          emit('update:hour', value)\n          break\n        case 'minute':\n          emit('update:minute', value)\n          break\n        case 'second':\n          emit('update:second', value)\n          break\n        default:\n          break\n      }\n\n      const emitChange = inputHour.value !== null && inputMinute.value !== null && (props.useSeconds ? inputSecond.value !== null : true)\n      if (viewMode.value === 'hour') {\n        viewMode.value = 'minute'\n      } else if (props.useSeconds && viewMode.value === 'minute') {\n        viewMode.value = 'second'\n      }\n\n      if (inputHour.value === lazyInputHour.value &&\n        inputMinute.value === lazyInputMinute.value &&\n        (!props.useSeconds || inputSecond.value === lazyInputSecond.value)\n      ) return\n\n      const time = genValue()\n      if (time === null) return\n\n      lazyInputHour.value = inputHour.value\n      lazyInputMinute.value = inputMinute.value\n      props.useSeconds && (lazyInputSecond.value = inputSecond.value)\n\n      emitChange && emitValue()\n    }\n\n    useRender(() => {\n      const pickerProps = omit(VPicker.filterProps(props), ['hideHeader'])\n      const timePickerControlsProps = VTimePickerControls.filterProps(props)\n      const timePickerClockProps = VTimePickerClock.filterProps(omit(props, ['format', 'modelValue', 'min', 'max']))\n\n      const clockValidation = viewMode.value === 'hour'\n        ? isAllowedHour.value\n        : viewMode.value === 'minute'\n          ? (v: number) => isAllowedMinute.value(inputHour.value, v)\n          : (v: number) => isAllowedSecond.value(inputHour.value, inputMinute.value, v)\n\n      return (\n        <VPicker\n          { ...pickerProps }\n          color={ undefined }\n          class={[\n            'v-time-picker',\n            `v-time-picker--variant-${props.variant}`,\n            props.class,\n            densityClasses.value,\n          ]}\n          hideHeader={ props.hideHeader && props.variant !== 'input' }\n          style={ props.style }\n          v-slots={{\n            title: () => slots.title?.() ?? (\n              <div class=\"v-time-picker__title\">\n                { t(props.title) }\n              </div>\n            ),\n            header: () => (\n              <VTimePickerControls\n                { ...timePickerControlsProps }\n                ampm={ isAmPm.value }\n                hour={ inputHour.value as number }\n                minute={ inputMinute.value as number }\n                period={ period.value }\n                second={ inputSecond.value as number }\n                viewMode={ viewMode.value }\n                inputHints={ props.variant === 'input' }\n                onUpdate:hour={ (val: number) => inputHour.value = val }\n                onUpdate:minute={ (val: number) => inputMinute.value = val }\n                onUpdate:second={ (val: number) => inputSecond.value = val }\n                onUpdate:period={ (val: Period) => period.value = val }\n                onUpdate:viewMode={ (value: VTimePickerViewMode) => (viewMode.value = value) }\n                ref={ controlsRef }\n              />\n            ),\n            default: () => (\n              <VTimePickerClock\n                { ...timePickerClockProps }\n                allowedValues={ clockValidation }\n                double={ viewMode.value === 'hour' && !isAmPm.value }\n                format={ viewMode.value === 'hour'\n                  ? (isAmPm.value ? convert24to12 : (val: number) => val)\n                  : (val: number) => pad(val, 2)\n                }\n                max={ viewMode.value === 'hour' ? (isAmPm.value && period.value === 'am' ? 11 : 23) : 59 }\n                min={ viewMode.value === 'hour' && isAmPm.value && period.value === 'pm' ? 12 : 0 }\n                size={ 20 }\n                step={ viewMode.value === 'hour' ? 1 : 5 }\n                modelValue={ viewMode.value === 'hour'\n                  ? inputHour.value as number\n                  : (viewMode.value === 'minute'\n                    ? inputMinute.value as number\n                    : inputSecond.value as number)\n                }\n                onChange={ onChange }\n                onInput={ onInput }\n                ref={ clockRef }\n              />\n            ),\n            actions: slots.actions,\n          }}\n        />\n      )\n    })\n  },\n})\n\nexport type VTimePicker = InstanceType<typeof VTimePicker>\n"
  },
  {
    "path": "packages/vuetify/src/components/VTimePicker/VTimePickerClock.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  // Theme\n  .v-time-picker-clock\n    background: rgb(var(--v-theme-background))\n    color: rgb(var(--v-theme-on-background))\n\n    &:after\n      color: rgb(var(--v-theme-primary))\n\n    .v-time-picker-clock__item--active\n      background-color: rgb(var(--v-theme-surface-variant))\n      color: rgb(var(--v-theme-on-surface-variant))\n\n  .v-time-picker-clock\n    margin: $time-picker-padding\n    background: rgb(var(--v-theme-surface-light))\n    border-radius: 50%\n    position: relative\n    transition: none\n    user-select: none\n    max-width: 256px\n    aspect-ratio: 1\n    flex: 100%\n\n    &__container\n      display: flex\n      flex-direction: column\n      flex-basis: 290px\n      justify-content: center\n      padding: $time-picker-clock-padding\n\n    &__hand\n      background-color: currentColor\n      height: $time-picker-clock-hand-height\n      width: $time-picker-clock-hand-width\n      bottom: 50%\n      left: $time-picker-clock-hand-left\n      transform-origin: center bottom\n      position: absolute\n      will-change: transform\n      z-index: 1\n\n      &:before\n        background: transparent\n        border-width: $time-picker-clock-end-border-width\n        border-style: $time-picker-clock-end-border-style\n        border-color: $time-picker-clock-end-border-color\n        border-radius: 100%\n        width: $time-picker-clock-end-size\n        height: $time-picker-clock-end-size\n        content: ''\n        position: absolute\n        top: $time-picker-clock-end-top\n        left: 50%\n        transform: translate(-50%, -50%)\n\n      &:after\n        content: ''\n        position: absolute\n        height: $time-picker-clock-center-size\n        width: $time-picker-clock-center-size\n        top: 100%\n        left: 50%\n        border-radius: 100%\n        background-color: currentColor\n        transform: translate(-50%, -50%)\n\n      &--inner:after\n        height: $time-picker-clock-inner-hand-height\n\n    &--readonly\n      pointer-events: none\n\n    .v-time-picker-clock__item--disabled\n      opacity: var(--v-disabled-opacity)\n\n  .v-picker--full-width\n    .v-time-picker-clock__container\n      max-width: $time-picker-clock-max-width\n\n  .v-time-picker-clock__inner\n    position: absolute\n    bottom: $time-picker-clock-inner-offset\n    left: $time-picker-clock-inner-offset\n    right: $time-picker-clock-inner-offset\n    top: $time-picker-clock-inner-offset\n\n  .v-time-picker-clock__item\n    align-items: center\n    border-radius: 100%\n    cursor: default\n    display: flex\n    font-size: $time-picker-number-font-size\n    justify-content: center\n    height: $time-picker-indicator-size\n    position: absolute\n    text-align: center\n    width: $time-picker-indicator-size\n    user-select: none\n    transform: translate(-50%, -50%)\n\n    > span\n      z-index: 1\n\n    &:before, &:after\n      content: ''\n      border-radius: 100%\n      position: absolute\n      top: 50%\n      left: 50%\n      height: 14px\n      width: 14px\n      transform: translate(-50%, -50%)\n\n    &:after, &:before\n      height: $time-picker-indicator-size\n      width: $time-picker-indicator-size\n\n    &--active\n      cursor: default\n      z-index: 2\n\n    &--disabled\n      pointer-events: none\n\n  .v-picker--landscape\n    .v-time-picker-clock\n      &__container\n        flex-direction: row\n\n@include tools.layer('trumps')\n  @media (forced-colors: active)\n    .v-time-picker-clock\n      &__hand\n        background-color: highlight\n        &:before\n          border-color: highlight\n        &:after\n          background-color: highlight\n\n      &__item--active\n        outline: 2px solid highlight\n"
  },
  {
    "path": "packages/vuetify/src/components/VTimePicker/VTimePickerClock.tsx",
    "content": "// Styles\nimport './VTimePickerClock.sass'\n\n// Composables\nimport { useBackgroundColor, useTextColor } from '@/composables/color'\n\n// Utilities\nimport { computed, onScopeDispose, ref, watch } from 'vue'\nimport { debounce, genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\ninterface Point {\n  x: number\n  y: number\n}\n\nexport const makeVTimePickerClockProps = propsFactory({\n  allowedValues: Function as PropType<(value: number) => boolean>,\n  ampm: Boolean,\n  color: String,\n  disabled: Boolean,\n  displayedValue: null,\n  double: Boolean,\n  format: {\n    type: Function,\n    default: (val: string | number) => val,\n  },\n  max: {\n    type: Number,\n    required: true,\n  },\n  min: {\n    type: Number,\n    required: true,\n  },\n  scrollable: Boolean,\n  readonly: Boolean,\n  rotate: {\n    type: Number,\n    default: 0,\n  },\n  step: {\n    type: Number,\n    default: 1,\n  },\n  modelValue: {\n    type: Number,\n  },\n}, 'VTimePickerClock')\n\nexport const VTimePickerClock = genericComponent()({\n  name: 'VTimePickerClock',\n\n  props: makeVTimePickerClockProps(),\n\n  emits: {\n    change: (val: number) => true,\n    input: (val: number) => true,\n  },\n\n  setup (props, { emit }) {\n    const clockRef = ref<HTMLElement | null>(null)\n    const innerClockRef = ref<HTMLElement | null>(null)\n    const inputValue = ref<number | undefined>(undefined)\n    const isDragging = ref(false)\n    const valueOnMouseDown = ref(null as number | null)\n    const valueOnMouseUp = ref(null as number | null)\n    const emitChangeDebounced = debounce((value: number) => emit('change', value), 750)\n\n    const { textColorClasses, textColorStyles } = useTextColor(() => props.color)\n    const { backgroundColorClasses, backgroundColorStyles } = useBackgroundColor(() => props.color)\n\n    const count = computed(() => props.max - props.min + 1)\n    const roundCount = computed(() => props.double ? (count.value / 2) : count.value)\n    const degreesPerUnit = computed(() => 360 / roundCount.value)\n    const degrees = computed(() => degreesPerUnit.value * Math.PI / 180)\n    const displayedValue = computed(() => props.modelValue == null ? props.min : props.modelValue)\n    const innerRadiusScale = computed(() => 0.62)\n\n    const genChildren = computed(() => {\n      const children = []\n      for (let value = props.min; value <= props.max; value = value + props.step) {\n        children.push(value)\n      }\n      return children\n    })\n\n    watch(() => props.modelValue, val => {\n      inputValue.value = val\n    })\n\n    function update (value: number) {\n      if (inputValue.value !== value) {\n        inputValue.value = value\n      }\n      emit('input', value)\n    }\n\n    function isAllowed (value: number) {\n      return !props.allowedValues || props.allowedValues(value)\n    }\n\n    function wheel (e: WheelEvent) {\n      if (!props.scrollable || props.disabled) return\n\n      e.preventDefault()\n\n      const delta = Math.sign(-e.deltaY || 1)\n      let value = displayedValue.value\n      do {\n        value = value + delta\n        value = (value - props.min + count.value) % count.value + props.min\n      } while (!isAllowed(value) && value !== displayedValue.value)\n\n      if (value !== props.displayedValue) {\n        update(value)\n      }\n\n      emitChangeDebounced(value)\n    }\n\n    function isInner (value: number) {\n      return props.double && (value - props.min >= roundCount.value)\n    }\n\n    function handScale (value: number) {\n      return isInner(value) ? innerRadiusScale.value : 1\n    }\n\n    function getPosition (value: number) {\n      const rotateRadians = props.rotate * Math.PI / 180\n      return {\n        x: Math.sin((value - props.min) * degrees.value + rotateRadians) * handScale(value),\n        y: -Math.cos((value - props.min) * degrees.value + rotateRadians) * handScale(value),\n      }\n    }\n\n    function angleToValue (angle: number, insideClick: boolean): number {\n      const value = (\n        Math.round(angle / degreesPerUnit.value) +\n        (insideClick ? roundCount.value : 0)\n      ) % count.value + props.min\n\n      // Necessary to fix edge case when selecting left part of the value(s) at 12 o'clock\n      if (angle < (360 - degreesPerUnit.value / 2)) return value\n\n      return insideClick ? props.max - roundCount.value + 1 : props.min\n    }\n\n    function getTransform (i: number) {\n      const { x, y } = getPosition(i)\n      return {\n        left: `${Math.round(50 + x * 50)}%`,\n        top: `${Math.round(50 + y * 50)}%`,\n      }\n    }\n\n    function euclidean (p0: Point, p1: Point) {\n      const dx = p1.x - p0.x\n      const dy = p1.y - p0.y\n\n      return Math.sqrt(dx * dx + dy * dy)\n    }\n\n    function angle (center: Point, p1: Point) {\n      const value = 2 * Math.atan2(p1.y - center.y - euclidean(center, p1), p1.x - center.x)\n      return Math.abs(value * 180 / Math.PI)\n    }\n\n    function setMouseDownValue (value: number) {\n      if (valueOnMouseDown.value === null) {\n        valueOnMouseDown.value = value\n      }\n\n      valueOnMouseUp.value = value\n      update(value)\n    }\n\n    function onDragMove (e: MouseEvent | TouchEvent) {\n      e.preventDefault()\n      if ((!isDragging.value && e.type !== 'click') || !clockRef.value) return\n      const { width, top, left } = clockRef.value?.getBoundingClientRect()\n      const { width: innerWidth }: DOMRect = innerClockRef.value?.getBoundingClientRect() ?? { width: 0 } as DOMRect\n      const { clientX, clientY } = 'touches' in e ? e.touches[0] : e\n      const center = { x: width / 2, y: -width / 2 }\n      const coords = { x: clientX - left, y: top - clientY }\n      const handAngle = Math.round(angle(center, coords) - props.rotate + 360) % 360\n      const insideClick = props.double && euclidean(center, coords) < (innerWidth as number + innerWidth * innerRadiusScale.value) / 4\n      const checksCount = Math.ceil(15 / degreesPerUnit.value)\n      let value\n\n      for (let i = 0; i < checksCount; i++) {\n        value = angleToValue(handAngle + i * degreesPerUnit.value, insideClick)\n        if (isAllowed(value)) return setMouseDownValue(value)\n\n        value = angleToValue(handAngle - i * degreesPerUnit.value, insideClick)\n        if (isAllowed(value)) return setMouseDownValue(value)\n      }\n    }\n\n    function onMouseDown (e: MouseEvent | TouchEvent) {\n      if (props.disabled) return\n\n      e.preventDefault()\n\n      window.addEventListener('mousemove', onDragMove)\n      window.addEventListener('touchmove', onDragMove)\n      window.addEventListener('mouseup', onMouseUp)\n      window.addEventListener('touchend', onMouseUp)\n      valueOnMouseDown.value = null\n      valueOnMouseUp.value = null\n      isDragging.value = true\n      onDragMove(e)\n    }\n\n    function onMouseUp (e: MouseEvent | TouchEvent) {\n      e.stopPropagation()\n      removeListeners()\n\n      isDragging.value = false\n      if (valueOnMouseUp.value !== null && isAllowed(valueOnMouseUp.value)) {\n        emit('change', valueOnMouseUp.value)\n      }\n    }\n\n    function removeListeners () {\n      window.removeEventListener('mousemove', onDragMove)\n      window.removeEventListener('touchmove', onDragMove)\n      window.removeEventListener('mouseup', onMouseUp)\n      window.removeEventListener('touchend', onMouseUp)\n    }\n\n    onScopeDispose(removeListeners)\n\n    useRender(() => {\n      return (\n        <div\n          class={[\n            {\n              'v-time-picker-clock': true,\n              'v-time-picker-clock--indeterminate': props.modelValue == null,\n              'v-time-picker-clock--readonly': props.readonly,\n            },\n          ]}\n          onMousedown={ onMouseDown }\n          onTouchstart={ onMouseDown }\n          onWheel={ wheel }\n          ref={ clockRef }\n        >\n          <div class=\"v-time-picker-clock__inner\" ref={ innerClockRef }>\n            <div\n              class={[\n                {\n                  'v-time-picker-clock__hand': true,\n                  'v-time-picker-clock__hand--inner': isInner(props.modelValue as number),\n                },\n                textColorClasses.value,\n              ]}\n              style={[\n                {\n                  transform: `rotate(${props.rotate + degreesPerUnit.value * (displayedValue.value - props.min)}deg) scaleY(${handScale(displayedValue.value)})`,\n                },\n                textColorStyles.value,\n              ]}\n            />\n\n            {\n              genChildren.value.map(value => {\n                const isActive = value === displayedValue.value\n\n                return (\n                  <div\n                    class={[\n                      {\n                        'v-time-picker-clock__item': true,\n                        'v-time-picker-clock__item--active': isActive,\n                        'v-time-picker-clock__item--disabled': props.disabled || !isAllowed(value),\n                      },\n                      isActive && backgroundColorClasses.value,\n                    ]}\n                    style={[\n                      getTransform(value),\n                      isActive && backgroundColorStyles.value,\n                    ]}\n                  >\n                    <span>{ props.format(value) }</span>\n                  </div>\n                )\n              })\n            }\n          </div>\n        </div>\n      )\n    })\n  },\n})\n\nexport type VTimePickerClock = InstanceType<typeof VTimePickerClock>\n"
  },
  {
    "path": "packages/vuetify/src/components/VTimePicker/VTimePickerControls.sass",
    "content": "@use 'sass:map'\n@use '../../styles/tools'\n@use '../../styles/settings'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-time-picker-controls\n    display: flex\n    align-items: center\n    justify-content: center\n    font-size: .875rem\n    margin-inline: $time-picker-padding\n    margin-bottom: 12px\n\n    &__text\n      padding-bottom: 12px\n\n    &__time\n      display: flex\n      white-space: nowrap\n      direction: ltr\n      justify-content: center\n      align-items: start\n\n  .v-time-picker-controls__time__separator\n    width: $time-picker-controls-separator-width\n    text-align: center\n\n    .v-time-picker--density-compact &\n      font-weight: bold\n\n    @at-root\n      @include tools.density('v-time-picker', $time-picker-controls-field-density) using ($modifier)\n        .v-time-picker-controls__time__separator\n          font-size: $time-picker-controls-btn-font + $modifier\n          line-height: $time-picker-controls-separator-line-height + $modifier\n\n          .v-time-picker--variant-input &\n            line-height: $time-picker-controls-input-separator-line-height + $modifier\n\n          .v-time-picker-controls__time--with-seconds &\n            height: $time-picker-controls-seconds-btn-height + $modifier\n            font-size: $time-picker-controls-btn-font + $modifier\n\n  .v-time-picker-controls__time__field\n    width: $time-picker-controls-field-width\n\n    .v-field\n      width: $time-picker-controls-field-width\n      background-color: $time-picker-controls-field-background\n      color: inherit\n      transition: color .25s settings.$standard-easing\n\n      > .v-field__overlay\n        opacity: $time-picker-controls-field-overlay-opacity\n\n    &--active .v-field > .v-field__overlay\n      opacity: calc((#{$time-picker-controls-field-overlay-opacity} + #{map.get(settings.$states, 'focus')}) * var(--v-theme-overlay-multiplier))\n\n    .v-time-picker--variant-input &\n      width: $time-picker-controls-input-field-width\n\n      .v-field\n        width: $time-picker-controls-input-field-width\n\n    .v-time-picker-controls__time--with-seconds &\n      width: $time-picker-controls-seconds-field-width\n\n      .v-time-picker--variant-input &\n        width: $time-picker-controls-input-seconds-field-width\n\n    .v-field__input\n      padding: 0\n      font-weight: 500\n      text-align: center\n      line-height: 1\n      align-self: center\n\n      &:focus::placeholder\n        opacity: 0\n\n    &.v-input > .v-input__details\n      font-size: $time-picker-field-label-font-size\n      letter-spacing: $time-picker-field-label-letter-spacing\n      padding-inline: 0\n      white-space: normal\n\n      > .v-messages\n        opacity: 1\n\n    &.v-input--error .v-field__input\n      color: rgb(var(--v-theme-error))\n\n  .v-time-picker-controls__ampm\n    margin-left: 12px\n    display: flex\n    flex-direction: column\n    text-transform: uppercase\n\n    &--readonly\n      pointer-events: none\n\n    &--readonly\n      .v-picker__title__btn.v-picker__title__btn--active\n        opacity: $picker-inactive-btn-opacity\n\n    &__btn.v-btn\n      min-width: 52px\n      padding: 0 8px\n\n      &.v-time-picker-controls__ampm__am\n        border-radius: $time-picker-controls-ampm-am-border-radius\n        border: 1px solid\n\n      &.v-time-picker-controls__ampm__pm\n        border-radius: $time-picker-controls-ampm-pm-border-radius\n        border: 1px solid\n        border-top: none\n\n      &__active\n        background: rgb(var(--v-theme-primary))\n\n  @at-root\n    @include tools.density('v-time-picker', $time-picker-controls-field-density) using ($modifier)\n      .v-time-picker-controls__time__field .v-input__control\n        height: $time-picker-controls-field-height + $modifier\n\n        .v-field\n          font-size: $time-picker-controls-field-font + $modifier\n\n          .v-field__input\n            min-height: $time-picker-controls-field-height + $modifier\n\n      &.v-time-picker--variant-input .v-time-picker-controls__time__field .v-input__control\n        height: $time-picker-controls-input-field-height + $modifier\n\n        .v-field\n          font-size: $time-picker-controls-input-field-font + $modifier * .75\n\n          .v-field__input\n            min-height: $time-picker-controls-input-field-height + $modifier\n\n      .v-time-picker-controls__time--with-seconds .v-time-picker-controls__time__field .v-field\n        font-size: $time-picker-controls-seconds-field-font + $modifier * .5\n\n      .v-time-picker-controls__ampm__btn.v-btn\n        font-size: $time-picker-ampm-title-font-size + $modifier * .25\n        height: $time-picker-controls-ampm-height + $modifier * .5\n\n      &.v-time-picker--variant-input .v-time-picker-controls__ampm__btn.v-btn\n        height: $time-picker-controls-input-ampm-height + $modifier * .5\n\n  .v-picker__title--landscape\n    .v-time-picker-controls\n      flex-direction: column\n      justify-content: center\n      height: 100%\n\n    .v-time-picker-controls__time\n      text-align: right\n\n      .v-picker__title__btn,\n      span\n        height: $time-picker-landscape-title-btn-height\n        font-size: $time-picker-landscape-title-btn-height\n\n    .v-time-picker-controls__ampm\n      margin: $time-picker-landscape-ampm-title-margin\n      align-self: initial\n      text-align: center\n\n  .v-picker--time .v-picker__title--landscape\n    padding: 0\n\n    .v-time-picker-controls__time\n      text-align: center\n\n@include tools.layer('trumps')\n  @media (forced-colors: active)\n    .v-time-picker-controls\n      &__time__field:has(input:focus-visible)\n        outline: 2px solid highlight\n        outline-offset: 2px\n\n      &__ampm__btn.v-btn--active\n        color: highlight\n        forced-color-adjust: preserve-parent-color\n"
  },
  {
    "path": "packages/vuetify/src/components/VTimePicker/VTimePickerControls.tsx",
    "content": "// Styles\nimport './VTimePickerControls.sass'\n\n// Components\nimport { VTimePickerField } from './VTimePickerField'\nimport { VBtn } from '@/components/VBtn'\n\n// Composables\nimport { useLocale } from '@/composables/locale'\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { computed, nextTick, ref, watch } from 'vue'\nimport { makeTimeValidationProps, useTimeValidation } from './useTimeValidation'\nimport { convert12to24, convert24to12, extractInteger, pad } from './util'\nimport { clamp, genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType, Ref } from 'vue'\nimport type { Period, VTimePickerViewMode } from './shared'\n\nexport const makeVTimePickerControlsProps = propsFactory({\n  ampm: Boolean,\n  color: String,\n  disabled: Boolean,\n  inputHints: Boolean,\n  hour: [Number, String] as PropType<number | string | null>,\n  minute: [Number, String] as PropType<number | string | null>,\n  second: [Number, String] as PropType<number | string | null>,\n  period: String as PropType<Period>,\n  readonly: Boolean,\n  useSeconds: Boolean,\n  value: Number,\n  viewMode: String as PropType<VTimePickerViewMode>,\n  ...makeTimeValidationProps(),\n}, 'VTimePickerControls')\n\nexport const VTimePickerControls = genericComponent()({\n  name: 'VTimePickerControls',\n\n  props: makeVTimePickerControlsProps(),\n\n  emits: {\n    'update:period': (data: Period) => true,\n    'update:viewMode': (data: VTimePickerViewMode) => true,\n    'update:hour': (v: number) => true,\n    'update:minute': (v: number) => true,\n    'update:second': (v: number) => true,\n  },\n\n  setup (props, { emit }) {\n    const { t } = useLocale()\n\n    const {\n      isAllowedHour,\n      isAllowedMinute,\n      isAllowedSecond,\n      findNextAllowed,\n    } = useTimeValidation(props)\n\n    const currentHour = computed(() =>\n      props.hour !== null\n        ? props.ampm\n          ? convert12to24(Number(props.hour), props.period ?? 'am')\n          : Number(props.hour)\n        : null\n    )\n    const currentMinute = computed(() => props.minute !== null ? Number(props.minute) : null)\n\n    const isHourValid = computed(() => {\n      if (props.hour === null) return true\n      return isAllowedHour.value?.(Number(currentHour.value)) ?? true\n    })\n    const isMinuteValid = computed(() => {\n      if (props.minute === null) return true\n      return isAllowedMinute.value?.(currentHour.value, Number(props.minute)) ?? true\n    })\n    const isSecondValid = computed(() => {\n      if (props.second === null) return true\n      return isAllowedSecond.value?.(currentHour.value, currentMinute.value, Number(props.second)) ?? true\n    })\n\n    const transformHours = {\n      in: (v?: number | string | null) => {\n        if (v == null || isNaN(Number(v))) return null\n        const val = Number(v)\n        return props.ampm\n          ? pad(convert24to12(val))\n          : pad(val)\n      },\n      out: (v: number | string | null) => {\n        if (isNaN(Number(v)) || v == null || v === '') return null\n        const val = typeof v === 'string' ? extractInteger(v) : Number(v)\n        if (val === null) return null\n        return props.ampm\n          ? convert12to24(val, props.period ?? 'am')\n          : clamp(val, 0, 23)\n      },\n    }\n\n    const hour: Ref<string | number | null> = useProxiedModel(props, 'hour', undefined, transformHours.in, transformHours.out)\n\n    const transformMinutesOrSeconds = {\n      in: (v?: number | string | null) => v != null && !isNaN(Number(v)) ? pad(`${v}`) : null,\n      out: (v: number | string | null) => {\n        if (isNaN(Number(v)) || v == null || v === '') return null\n        const val = typeof v === 'string' ? extractInteger(v) : Number(v)\n        return val !== null\n          ? clamp(val, 0, 59)\n          : null\n      },\n    }\n\n    const minute: Ref<string | number | null> = useProxiedModel(\n      props,\n      'minute',\n      undefined,\n      transformMinutesOrSeconds.in,\n      transformMinutesOrSeconds.out,\n    )\n\n    const second: Ref<string | number | null> = useProxiedModel(\n      props,\n      'second',\n      undefined,\n      transformMinutesOrSeconds.in,\n      transformMinutesOrSeconds.out,\n    )\n\n    function onHourFieldKeydown (e: KeyboardEvent) {\n      if (!['ArrowUp', 'ArrowDown'].includes(e.key)) return\n      e.preventDefault()\n      e.stopPropagation()\n\n      const isAm = props.period === 'am'\n      const current = props.ampm\n        ? convert12to24(Number(hour.value ?? 0), isAm ? 'am' : 'pm')\n        : Number(hour.value ?? 0)\n\n      const next = findNextAllowed('hour', current, e.key === 'ArrowUp')\n      const togglePeriod = (isAm && next >= 12) || (!isAm && next < 12)\n\n      if (props.ampm && togglePeriod) {\n        emit('update:period', props.period === 'am' ? 'pm' : 'am')\n        nextTick(() => hour.value = pad(next))\n      } else {\n        hour.value = pad(next)\n      }\n    }\n\n    function onMinuteFieldKeydown (e: KeyboardEvent) {\n      if (!['ArrowUp', 'ArrowDown'].includes(e.key)) return\n      e.preventDefault()\n      e.stopPropagation()\n\n      const current = Number(minute.value ?? 0)\n      const next = findNextAllowed('minute', current, e.key === 'ArrowUp', currentHour.value)\n      minute.value = pad(next)\n    }\n\n    function onSecondFieldKeydown (e: KeyboardEvent) {\n      if (!['ArrowUp', 'ArrowDown'].includes(e.key)) return\n      e.preventDefault()\n      e.stopPropagation()\n\n      const current = Number(second.value ?? 0)\n      const next = findNextAllowed('second', current, e.key === 'ArrowUp', currentHour.value, currentMinute.value)\n      second.value = pad(next)\n    }\n\n    function createInputInterceptor (\n      valueTransformOut: (v: string) => number | null,\n      compare: (v: number | null) => boolean,\n      apply: (v: string) => void,\n    ) {\n      return (e: InputEvent) => {\n        if (!e.data) return\n        const inputElement = e.target as HTMLInputElement\n        const { value: existingTxt, selectionStart, selectionEnd } = inputElement ?? {}\n\n        if (extractInteger(e.data) === null) {\n          e.preventDefault()\n          return\n        }\n\n        const potentialNewInputVal =\n          existingTxt\n            ? existingTxt.slice(0, selectionStart as number | undefined) + e.data + existingTxt.slice(selectionEnd as number | undefined)\n            : e.data\n\n        if (potentialNewInputVal.length > 2) {\n          if (selectionStart === selectionEnd && selectionEnd === 0 && e.data.trim().startsWith('0')) {\n            e.preventDefault()\n            inputElement!.value = potentialNewInputVal.trim().substring(0, 2)\n            apply(inputElement!.value)\n            if (e.data.trim().length === 1) {\n              inputElement!.setSelectionRange(1, 1)\n            }\n            return\n          }\n          if (selectionStart === selectionEnd && selectionEnd === 1 && existingTxt.startsWith('0')) {\n            e.preventDefault()\n            inputElement!.value = potentialNewInputVal.trim().substring(0, 2)\n            apply(inputElement!.value)\n            return\n          }\n\n          const maxValue = props.viewMode === 'hour' ? (props.ampm ? 12 : 23) : 59\n          const value = extractInteger(potentialNewInputVal)!\n          if (value > maxValue) {\n            e.preventDefault()\n            inputElement!.value = pad(String(extractInteger(e.data)).substring(0, 2))\n            apply(inputElement!.value)\n            return\n          }\n        }\n\n        const potentialNewNumber = valueTransformOut(potentialNewInputVal)\n        if (compare(potentialNewNumber)) {\n          // ignore input when results in the same number\n          // prevents typing more digits\n          e.preventDefault()\n        }\n      }\n    }\n\n    function setPeriod (val: Period) {\n      emit('update:period', val)\n    }\n\n    const hourInputRef = ref<VTimePickerField>()\n    const minuteInputRef = ref<VTimePickerField>()\n    const secondInputRef = ref<VTimePickerField>()\n\n    watch(() => props.viewMode, (_, old) => {\n      switch (old) {\n        case 'hour': hourInputRef.value!.blur(); break\n        case 'minute': minuteInputRef.value!.blur(); break\n        case 'second': secondInputRef.value!.blur(); break\n      }\n    })\n\n    const hourInputFilter = createInputInterceptor(\n      transformHours.out,\n      (v: number | null) => transformHours.in(v) === hour.value,\n      (v: string) => hour.value = v,\n    )\n\n    const minuteInputFilter = createInputInterceptor(\n      transformMinutesOrSeconds.out,\n      (v: number | null) => transformMinutesOrSeconds.in(v) === minute.value,\n      (v: string) => minute.value = v,\n    )\n\n    const secondInputFilter = createInputInterceptor(\n      transformMinutesOrSeconds.out,\n      (v: number | null) => transformMinutesOrSeconds.in(v) === second.value,\n      (v: string) => second.value = v,\n    )\n\n    useRender(() => {\n      return (\n        <div class=\"v-time-picker-controls\">\n          <div\n            class={{\n              'v-time-picker-controls__time': true,\n              'v-time-picker-controls__time--with-ampm': props.ampm,\n              'v-time-picker-controls__time--with-seconds': props.useSeconds,\n            }}\n          >\n            <VTimePickerField\n              ref={ hourInputRef }\n              active={ props.viewMode === 'hour' }\n              color={ props.color }\n              disabled={ props.disabled }\n              label={ t('$vuetify.timePicker.hour') }\n              showHint={ props.inputHints }\n              error={ isHourValid.value ? undefined : t('$vuetify.timePicker.notAllowed') }\n              modelValue={ hour.value }\n              onUpdate:modelValue={ v => hour.value = v }\n              onKeydown={ onHourFieldKeydown }\n              onBeforeinput={ hourInputFilter }\n              onFocus={ () => emit('update:viewMode', 'hour') }\n            />\n\n            <span class=\"v-time-picker-controls__time__separator\">:</span>\n\n            <VTimePickerField\n              ref={ minuteInputRef }\n              active={ props.viewMode === 'minute' }\n              color={ props.color }\n              disabled={ props.disabled }\n              label={ t('$vuetify.timePicker.minute') }\n              showHint={ props.inputHints }\n              error={ isMinuteValid.value ? undefined : t('$vuetify.timePicker.notAllowed') }\n              modelValue={ minute.value }\n              onUpdate:modelValue={ v => minute.value = v }\n              onKeydown={ onMinuteFieldKeydown }\n              onBeforeinput={ minuteInputFilter }\n              onFocus={ () => emit('update:viewMode', 'minute') }\n            />\n\n            { props.useSeconds && (\n              <span key=\"secondsDivider\" class=\"v-time-picker-controls__time__separator\">:</span>\n            )}\n\n            { props.useSeconds && (\n              <>\n                <VTimePickerField\n                  key=\"secondsVal\"\n                  ref={ secondInputRef }\n                  active={ props.viewMode === 'second' }\n                  color={ props.color }\n                  disabled={ props.disabled }\n                  label={ t('$vuetify.timePicker.second') }\n                  showHint={ props.inputHints }\n                  error={ isSecondValid.value ? undefined : t('$vuetify.timePicker.notAllowed') }\n                  modelValue={ second.value }\n                  onUpdate:modelValue={ v => second.value = v }\n                  onKeydown={ onSecondFieldKeydown }\n                  onBeforeinput={ secondInputFilter }\n                  onFocus={ () => emit('update:viewMode', 'second') }\n                />\n              </>\n            )}\n\n            { props.ampm && (\n              <div class=\"v-time-picker-controls__ampm\">\n                <VBtn\n                  active={ props.period === 'am' }\n                  color={ props.period === 'am' ? props.color : undefined }\n                  class={{\n                    'v-time-picker-controls__ampm__am': true,\n                    'v-time-picker-controls__ampm__btn': true,\n                    'v-time-picker-controls__ampm__btn__active': props.period === 'am',\n                  }}\n                  disabled={ props.disabled }\n                  text={ t('$vuetify.timePicker.am') }\n                  variant={ props.disabled && props.period === 'am' ? 'elevated' : 'tonal' }\n                  onClick={ () => props.period !== 'am' ? setPeriod('am') : null }\n                />\n\n                <VBtn\n                  active={ props.period === 'pm' }\n                  color={ props.period === 'pm' ? props.color : undefined }\n                  class={{\n                    'v-time-picker-controls__ampm__pm': true,\n                    'v-time-picker-controls__ampm__btn': true,\n                    'v-time-picker-controls__ampm__btn__active': props.period === 'pm',\n                  }}\n                  disabled={ props.disabled }\n                  text={ t('$vuetify.timePicker.pm') }\n                  variant={ props.disabled && props.period === 'pm' ? 'elevated' : 'tonal' }\n                  onClick={ () => props.period !== 'pm' ? setPeriod('pm') : null }\n                />\n              </div>\n            )}\n          </div>\n        </div>\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VTimePickerControls = InstanceType<typeof VTimePickerControls>\n"
  },
  {
    "path": "packages/vuetify/src/components/VTimePicker/VTimePickerField.tsx",
    "content": "// Components\nimport { VTextField } from '@/components/VTextField'\n\n// Composables\nimport { useTextColor } from '@/composables/color'\nimport { forwardRefs } from '@/composables/forwardRefs'\n\n// Utilities\nimport { ref, shallowRef } from 'vue'\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\nexport const makeVTimePickerFieldProps = propsFactory({\n  active: Boolean,\n  color: String,\n  disabled: Boolean,\n  label: String,\n  modelValue: String as PropType<string | number | null>,\n  error: String,\n  showHint: Boolean,\n  readonly: Boolean,\n}, 'VTimePickerField')\n\nexport const VTimePickerField = genericComponent()({\n  name: 'VTimePickerField',\n\n  props: makeVTimePickerFieldProps(),\n\n  emits: {\n    'update:modelValue': (v: string | null) => true,\n  },\n\n  setup (props, { emit }) {\n    const { textColorClasses, textColorStyles } = useTextColor(() => props.color)\n\n    const vTextInputRef = ref<VTextField>()\n    const isFocused = shallowRef(false)\n\n    function onKeydown (e: KeyboardEvent) {\n      if (['Backspace', 'Delete'].includes(e.key)) {\n        e.preventDefault()\n\n        const target = e.target as HTMLInputElement\n        target.value = ''\n        emit('update:modelValue', null)\n      }\n    }\n\n    useRender(() => {\n      return (\n        <VTextField\n          ref={ vTextInputRef }\n          _as=\"VTimePickerField\"\n          autocomplete=\"off\"\n          class={[\n            'v-time-picker-controls__time__field',\n            { 'v-time-picker-controls__time__field--active': props.active },\n            props.active ? textColorClasses.value : [],\n          ]}\n          style={ props.active ? textColorStyles.value : [] }\n          disabled={ props.disabled }\n          variant=\"solo-filled\"\n          inputmode=\"numeric\"\n          hideDetails=\"auto\"\n          aria-label={ props.label }\n          aria-invalid={ !!props.error }\n          aria-errormessage={ props.error }\n          error={ !!props.error }\n          hint={ props.showHint ? props.label : undefined }\n          persistentHint\n          flat\n          modelValue={ props.modelValue ?? (isFocused.value ? '' : '--') }\n          onUpdate:modelValue={ v => emit('update:modelValue', v) }\n          onKeydown={ onKeydown }\n          onFocus={ () => isFocused.value = true }\n          onBlur={ () => isFocused.value = false }\n        />\n      )\n    })\n\n    return forwardRefs({}, vTextInputRef)\n  },\n})\n\nexport type VTimePickerField = InstanceType<typeof VTimePickerField>\n"
  },
  {
    "path": "packages/vuetify/src/components/VTimePicker/__tests__/VTimePicker.spec.browser.tsx",
    "content": "// Components\nimport { VTimePicker } from '../VTimePicker'\n\n// Utilities\nimport { render, screen, userEvent } from '@test'\nimport { ref } from 'vue'\n\ndescribe('VTimePicker', () => {\n  describe('variant input', () => {\n    it('constrains typing to emit valid time', async () => {\n      const model = ref<string | null>(null)\n      render(() => (\n        <VTimePicker\n          v-model={ model.value }\n          variant=\"input\"\n        />\n      ))\n\n      const input = screen.getAllByCSS('input')\n      await userEvent.click(input[0])\n      await userEvent.keyboard('7')\n      await userEvent.click(input[1])\n      await userEvent.keyboard('5')\n\n      expect(model.value).toBe('07:05')\n      await userEvent.keyboard('2')\n      expect(model.value).toBe('07:52')\n      await userEvent.keyboard('4')\n      expect(model.value).toBe('07:04')\n      await userEvent.keyboard('9')\n      expect(model.value).toBe('07:49')\n      await userEvent.keyboard('8')\n      expect(model.value).toBe('07:08')\n      await userEvent.keyboard('8')\n      expect(model.value).toBe('07:08') // ignored, cannot set 88\n\n      await userEvent.click(input[0])\n      await userEvent.keyboard('3')\n      expect(model.value).toBe('03:08')\n      await userEvent.keyboard('1')\n      expect(model.value).toBe('01:08')\n      await userEvent.keyboard('2')\n      expect(model.value).toBe('00:08') // 12:08 AM\n      await userEvent.keyboard('2')\n      expect(model.value).toBe('02:08')\n      await userEvent.keyboard('2')\n      expect(model.value).toBe('02:08') // ignored, cannot set 22\n    })\n\n    it('emits correct value when using arrows up/down', async () => {\n      const model = ref<string | null>('00:02')\n      render(() => (\n        <VTimePicker\n          v-model={ model.value }\n          variant=\"input\"\n        />\n      ))\n\n      const input = screen.getAllByCSS('input')\n      await userEvent.click(input[0])\n      await userEvent.keyboard('{ArrowDown}')\n      expect(model.value).toBe('23:02') // cycle hours\n      await userEvent.keyboard('{ArrowUp}')\n      expect(model.value).toBe('00:02')\n      await userEvent.keyboard('{ArrowUp}')\n      expect(model.value).toBe('01:02')\n\n      await userEvent.click(input[1])\n      await userEvent.keyboard('{ArrowDown}')\n      expect(model.value).toBe('01:01')\n      await userEvent.keyboard('{ArrowDown}')\n      expect(model.value).toBe('01:00')\n      await userEvent.keyboard('{ArrowDown}')\n      expect(model.value).toBe('01:59') // cycle minutes\n      await userEvent.keyboard('{ArrowUp}')\n      expect(model.value).toBe('01:00')\n    })\n\n    describe('allowed values', () => {\n      it('skips over disallowed values when using arrows up/down', async () => {\n        const model = ref<string | null>('10:30')\n        render(() => (\n          <VTimePicker\n            v-model={ model.value }\n            variant=\"input\"\n            allowedHours={[8, 10, 12, 14]}\n            allowedMinutes={[0, 15, 30, 45]}\n          />\n        ))\n\n        const input = screen.getAllByCSS('input')\n\n        await userEvent.click(input[0])\n        await userEvent.keyboard('{ArrowUp}')\n        expect(model.value).toBe('12:30') // up, skip over 11\n        await userEvent.keyboard('{ArrowUp}')\n        expect(model.value).toBe('14:30') // up, skip over 13\n        await userEvent.keyboard('{ArrowDown}')\n        expect(model.value).toBe('12:30') // down, skip over 13\n\n        await userEvent.click(input[1])\n        await userEvent.keyboard('{ArrowUp}')\n        expect(model.value).toBe('12:45') // up, 30 -> 45\n        await userEvent.keyboard('{ArrowUp}')\n        expect(model.value).toBe('12:00') // up, 45 -> 00\n        await userEvent.keyboard('{ArrowDown}')\n        expect(model.value).toBe('12:45') // down, 00 -> 45\n      })\n\n      it('highlights invalid input when typing', async () => {\n        const model = ref<string | null>('10:30')\n        render(() => (\n          <VTimePicker\n            v-model={ model.value }\n            variant=\"input\"\n            allowedHours={[8, 10, 12, 14]}\n            allowedMinutes={[0, 15, 30, 45]}\n          />\n        ))\n\n        const inputs = screen.getAllByCSS('.v-input')\n        const hourInput = inputs[0]\n        const minuteInput = inputs[1]\n\n        expect(hourInput).not.toHaveClass('v-input--error')\n        expect(minuteInput).not.toHaveClass('v-input--error')\n\n        // typing disallowed hour\n        await userEvent.click(hourInput.querySelector('input')!)\n        await userEvent.keyboard('1')\n        expect(hourInput).toHaveClass('v-input--error')\n        expect(minuteInput).not.toHaveClass('v-input--error')\n\n        await userEvent.keyboard('8')\n        expect(hourInput).not.toHaveClass('v-input--error')\n\n        // typing disallowed minute\n        await userEvent.click(minuteInput.querySelector('input')!)\n        await userEvent.keyboard('19')\n        expect(minuteInput).toHaveClass('v-input--error')\n\n        await userEvent.keyboard('30')\n        expect(minuteInput).not.toHaveClass('v-input--error')\n\n        // typing disallowed hour again, should keep minute valid\n        await userEvent.click(hourInput.querySelector('input')!)\n        await userEvent.keyboard('1')\n        expect(hourInput).toHaveClass('v-input--error')\n        expect(minuteInput).not.toHaveClass('v-input--error')\n      })\n    })\n\n    describe('AM/PM period toggle', () => {\n      it('should preserve hour value when switching between AM and PM', async () => {\n        const model = ref<string | null>('09:45')\n        render(() => (\n          <VTimePicker\n            v-model={ model.value }\n            variant=\"input\"\n          />\n        ))\n\n        expect(model.value).toBe('09:45')\n        await userEvent.click(screen.getByCSS('.v-time-picker-controls__ampm__pm'))\n        expect(model.value).toBe('21:45')\n        await userEvent.click(screen.getByCSS('.v-time-picker-controls__ampm__am'))\n        expect(model.value).toBe('09:45')\n      })\n\n      it('should preserve hour 12 when switching periods', async () => {\n        const model = ref<string | null>('00:15')\n        render(() => (\n          <VTimePicker\n            v-model={ model.value }\n            variant=\"input\"\n          />\n        ))\n\n        expect(model.value).toBe('00:15')\n        await userEvent.click(screen.getByCSS('.v-time-picker-controls__ampm__pm'))\n        expect(model.value).toBe('12:15')\n        await userEvent.click(screen.getByCSS('.v-time-picker-controls__ampm__am'))\n        expect(model.value).toBe('00:15')\n      })\n    })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VTimePicker/_variables.scss",
    "content": "@forward '../../labs/VPicker/variables';\n\n$time-picker-padding: 24px !default;\n$time-picker-controls-btn-font: 56px !default;\n$time-picker-controls-btn-height: 80px !default;\n$time-picker-controls-btn-width: 96px !default;\n$time-picker-controls-seconds-btn-width: 64px !default;\n$time-picker-controls-seconds-btn-height: 80px !default;\n$time-picker-controls-seconds-btn-font: 40px !default;\n$time-picker-controls-separator-width: 24px !default;\n$time-picker-controls-separator-line-height: 74px !default;\n$time-picker-controls-ampm-btn-width: 96px !default;\n$time-picker-controls-ampm-btn-height: 80px !default;\n$time-picker-controls-ampm-height: 40px !default;\n\n$time-picker-controls-field-background: rgb(var(--v-theme-surface-light)) !default;\n$time-picker-controls-field-overlay-opacity: 0.04 !default;\n\n$time-picker-controls-field-font: 56px !default;\n$time-picker-controls-field-height: 80px !default;\n$time-picker-controls-field-width: 96px !default;\n$time-picker-controls-seconds-field-width: 64px !default;\n$time-picker-controls-seconds-field-font: 40px !default;\n$time-picker-controls-field-density: ('default': 0, 'comfortable': -4, 'compact': -6) !default;\n\n$time-picker-controls-input-field-font: 44px !default;\n$time-picker-controls-input-field-height: 72px !default;\n$time-picker-controls-input-field-width: 96px !default;\n$time-picker-controls-input-seconds-field-width: 64px !default;\n$time-picker-controls-input-seconds-field-font: 40px !default;\n\n$time-picker-controls-input-separator-line-height: 64px !default;\n$time-picker-controls-input-ampm-height: 36px !default;\n\n$time-picker-controls-ampm-am-border-radius: 4px 4px 0 0 !default;\n$time-picker-controls-ampm-pm-border-radius: 0 0 4px 4px !default;\n$time-picker-ampm-title-font-size: 18px !default;\n$time-picker-number-font-size: 16px !default;\n$time-picker-field-label-font-size: 12px !default;\n$time-picker-field-label-letter-spacing: .0333333333em !default;\n$time-picker-indicator-size: 40px !default;\n$time-picker-clock-padding: 10px !default;\n$time-picker-clock-max-width: 290px !default;\n$time-picker-clock-hand-height: calc(50% - 4px) !default;\n$time-picker-clock-hand-width: 2px !default;\n$time-picker-clock-hand-left: calc(50% - 1px) !default;\n$time-picker-clock-center-size: 8px !default;\n$time-picker-clock-end-size: 10px !default;\n$time-picker-clock-end-top: -4px !default;\n$time-picker-clock-inner-hand-height: 14px !default;\n$time-picker-clock-inner-offset: 27px !default;\n$time-picker-clock-end-border-width: 2px !default;\n$time-picker-clock-end-border-style: solid !default;\n$time-picker-clock-end-border-color: currentColor !default;\n$time-picker-width: 328px !default;\n$time-picker-landscape-title-btn-height: 55px !default;\n$time-picker-landscape-ampm-title-margin: 16px 0 0 !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VTimePicker/index.ts",
    "content": "export { VTimePicker } from './VTimePicker'\nexport { VTimePickerClock } from './VTimePickerClock'\nexport { VTimePickerControls } from './VTimePickerControls'\n"
  },
  {
    "path": "packages/vuetify/src/components/VTimePicker/shared.ts",
    "content": "export type Period = 'am' | 'pm'\nexport type VTimePickerViewMode = 'hour' | 'minute' | 'second'\n"
  },
  {
    "path": "packages/vuetify/src/components/VTimePicker/useTimeValidation.ts",
    "content": "// Utilities\nimport { computed } from 'vue'\nimport { incrementHour, incrementMinuteOrSecond } from './util'\nimport { propsFactory } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { VTimePickerViewMode } from './shared'\n\nexport type AllowFunction = (val: number) => boolean\n\nexport const makeTimeValidationProps = propsFactory({\n  allowedHours: [Function, Array] as PropType<AllowFunction | number[]>,\n  allowedMinutes: [Function, Array] as PropType<AllowFunction | number[]>,\n  allowedSeconds: [Function, Array] as PropType<AllowFunction | number[]>,\n  max: String,\n  min: String,\n}, 'time-validation')\n\nexport interface TimeValidationProps {\n  allowedHours?: AllowFunction | number[]\n  allowedMinutes?: AllowFunction | number[]\n  allowedSeconds?: AllowFunction | number[]\n  min?: string\n  max?: string\n}\n\nexport function useTimeValidation (props: TimeValidationProps) {\n  const isAllowedHour = computed(() => {\n    const minHour = props.min ? Number(props.min.split(':')[0]) : 0\n    const maxHour = props.max ? Number(props.max.split(':')[0]) : 23\n\n    return (val: number) => {\n      if (val < minHour) return false\n      if (val > maxHour) return false\n      if (Array.isArray(props.allowedHours)) return props.allowedHours.includes(val)\n      if (typeof props.allowedHours === 'function') return props.allowedHours(val)\n      return true\n    }\n  })\n\n  const isAllowedMinute = computed(() => {\n    const [minHour, minMinute] = props.min ? props.min.split(':').map(Number) : [0, 0]\n    const [maxHour, maxMinute] = props.max ? props.max.split(':').map(Number) : [23, 59]\n    const minTime = minHour * 60 + minMinute\n    const maxTime = maxHour * 60 + maxMinute\n\n    return (hour24hr: number | null, val: number) => {\n      if (hour24hr !== null) {\n        const time = 60 * hour24hr + val\n        if (time < minTime) return false\n        if (time > maxTime) return false\n      }\n      if (Array.isArray(props.allowedMinutes)) return props.allowedMinutes.includes(val)\n      if (typeof props.allowedMinutes === 'function') return props.allowedMinutes(val)\n      return true\n    }\n  })\n\n  const isAllowedSecond = computed(() => {\n    const [minHour, minMinute, minSecond] = props.min ? props.min.split(':').map(Number) : [0, 0, 0]\n    const [maxHour, maxMinute, maxSecond] = props.max ? props.max.split(':').map(Number) : [23, 59, 59]\n    const minTime = minHour * 3600 + minMinute * 60 + (minSecond || 0)\n    const maxTime = maxHour * 3600 + maxMinute * 60 + (maxSecond || 0)\n\n    return (hour24hr: number | null, minute: number | null, val: number) => {\n      if (hour24hr !== null && minute !== null) {\n        const time = 3600 * hour24hr + 60 * minute + val\n        if (time < minTime) return false\n        if (time > maxTime) return false\n      }\n      if (Array.isArray(props.allowedSeconds)) return props.allowedSeconds.includes(val)\n      if (typeof props.allowedSeconds === 'function') return props.allowedSeconds(val)\n      return true\n    }\n  })\n\n  function findNextAllowed (\n    type: VTimePickerViewMode,\n    value: number,\n    increment: boolean,\n    currentHour: number | null = null,\n    currentMinute: number | null = null\n  ): number {\n    const isAllowed = type === 'hour'\n      ? isAllowedHour.value\n      : type === 'minute'\n        ? (v: number) => isAllowedMinute.value(currentHour, v)\n        : (v: number) => isAllowedSecond.value(currentHour, currentMinute, v)\n\n    const nextValue = type === 'hour'\n      ? (v: number) => incrementHour(v, increment, null).value\n      : (v: number) => incrementMinuteOrSecond(v, increment)\n\n    const limit = type === 'hour' ? 24 : 60\n    for (let i = 1; i <= limit; i++) {\n      value = nextValue(value)\n      if (isAllowed(value)) break\n    }\n    return value\n  }\n\n  return {\n    isAllowedHour,\n    isAllowedMinute,\n    isAllowedSecond,\n    findNextAllowed,\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VTimePicker/util.ts",
    "content": "// Types\nimport type { Period } from './shared'\n\nexport function pad (n: string | number, length = 2) {\n  return String(n).padStart(length, '0')\n}\n\nexport function convert24to12 (hour: number) {\n  return hour ? ((hour - 1) % 12 + 1) : 12\n}\n\nexport function convert12to24 (hour: number, period: Period) {\n  return hour % 12 + (period === 'pm' ? 12 : 0)\n}\n\nexport function extractInteger (v: string): number | null {\n  const digits = v.replaceAll(/\\D/g, '')\n  return digits.length > 0\n    ? Number(digits)\n    : null\n}\n\nexport function incrementHour (hour: number, increment: boolean, period: Period | null) {\n  if (period) {\n    if (hour === 12 && increment) { return { value: 1 } }\n    if (hour === 11 && increment) { return { value: 12, togglePeriod: true } }\n    if (hour === 12 && !increment) { return { value: 11, togglePeriod: true } }\n    if (hour === 1 && !increment) { return { value: 12 } }\n  } else {\n    if (hour === 23 && increment) { return { value: 0 } }\n    if (hour === 0 && !increment) { return { value: 23 } }\n  }\n  return { value: hour + (increment ? 1 : -1) }\n}\n\nexport function incrementMinuteOrSecond (val: number, increment: boolean) {\n  if (val === 59 && increment) return 0\n  if (val === 0 && !increment) return 59\n  return val + (increment ? 1 : -1)\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/VTimeline/VTimeline.sass",
    "content": "@use 'sass:map'\n@use 'sass:math'\n@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n@use './mixins' as *\n\n@include tools.layer('components')\n  // VTimeline\n  .v-timeline\n    .v-timeline-divider__dot\n      background: $timeline-dot-divider-background\n\n      @include tools.layer('trumps')\n        @media (forced-colors: active)\n          border: 2px solid\n\n    .v-timeline-divider__inner-dot\n      background: $timeline-inner-dot-divider-background\n\n      @include tools.layer('trumps')\n        @media (forced-colors: active)\n          background-color: transparent\n\n  .v-timeline\n    --v-timeline-dot-border-size: #{map.get($timeline-dot-border-sizes, 'default')}\n\n    display: grid\n    grid-auto-flow: dense\n    position: relative\n\n    @include horizontal(true)\n      grid-column-gap: $timeline-item-padding\n      width: 100%\n\n      .v-timeline--side-end > .v-timeline-item,\n      &:not(.v-timeline--side-start) > .v-timeline-item--side-end,\n      &:not(.v-timeline--side-start) > .v-timeline-item:nth-child(2n+1):not(.v-timeline-item--side-start)\n        .v-timeline-item__body\n          grid-row: 3\n          align-self: flex-start\n          padding-block-start: $timeline-item-padding\n\n        .v-timeline-item__opposite\n          grid-row: 1\n          align-self: flex-end\n          padding-block-end: $timeline-item-padding\n\n      .v-timeline--side-start > .v-timeline-item,\n      &:not(.v-timeline--side-end) > .v-timeline-item--side-start,\n      &:not(.v-timeline--side-end) > .v-timeline-item:nth-child(2n):not(.v-timeline-item--side-end)\n        .v-timeline-item__body\n          grid-row: 1\n          align-self: flex-end\n          padding-block-end: $timeline-item-padding\n\n        .v-timeline-item__opposite\n          grid-row: 3\n          align-self: flex-start\n          padding-block-start: $timeline-item-padding\n\n    @include vertical(true)\n      row-gap: $timeline-item-padding\n      height: 100%\n\n      @include timeline-first-item()\n        padding-block-start: $timeline-item-padding\n\n      @include timeline-last-item()\n        padding-block-end: $timeline-item-padding\n\n      .v-timeline--side-start > .v-timeline-item,\n      &:not(.v-timeline--side-end) > .v-timeline-item--side-start,\n      &:not(.v-timeline--side-end) > .v-timeline-item:nth-child(2n):not(.v-timeline-item--side-end)\n        .v-timeline-item__body\n          grid-column: 1\n          justify-self: flex-end\n          padding-inline-end: $timeline-item-padding\n\n        .v-timeline-item__opposite\n          grid-column: 3\n          justify-self: flex-start\n          padding-inline-start: $timeline-item-padding\n\n      .v-timeline--side-end > .v-timeline-item,\n      &:not(.v-timeline--side-start) > .v-timeline-item--side-end,\n      &:not(.v-timeline--side-start) > .v-timeline-item:nth-child(2n+1):not(.v-timeline-item--side-start)\n        .v-timeline-item__body\n          grid-column: 3\n          justify-self: flex-start\n          padding-inline-start: $timeline-item-padding\n\n        .v-timeline-item__opposite\n          grid-column: 1\n          justify-self: flex-end\n          padding-inline-end: $timeline-item-padding\n\n  // VTimelineItem\n  .v-timeline-item\n    display: contents\n\n  // VTimelineDivider\n  .v-timeline-divider\n    position: relative\n    display: flex\n    align-items: center\n\n    @include horizontal\n      flex-direction: row\n      grid-row: 2\n      width: 100%\n\n    @include vertical\n      height: 100%\n      flex-direction: column\n      grid-column: 2\n\n  $timeline-line-size: calc(var(--v-timeline-line-size-base) + #{math.div($timeline-item-padding, 2)} - var(--v-timeline-line-inset))\n  $timeline-line-start: math.div(-$timeline-item-padding, 2)\n  $timeline-line-size-first-last: calc(var(--v-timeline-line-size-base) - var(--v-timeline-line-inset) + var(--v-timeline-line-size-offset))\n\n  .v-timeline-divider__before\n    background: $timeline-divider-line-background\n    position: absolute\n\n    @include horizontal\n      height: $timeline-divider-line-thickness\n      width: $timeline-line-size\n      inset-inline-start: $timeline-line-start\n      inset-inline-end: initial\n\n    @include vertical\n      height: $timeline-line-size\n      width: $timeline-divider-line-thickness\n      top: $timeline-line-start\n\n    @media (forced-colors: active)\n      background: canvastext\n\n  .v-timeline-divider__after\n    background: $timeline-divider-line-background\n    position: absolute\n\n    @include horizontal\n      height: $timeline-divider-line-thickness\n      width: $timeline-line-size\n      inset-inline-end: $timeline-line-start\n      inset-inline-start: initial\n\n    @include vertical\n      height: $timeline-line-size\n      width: $timeline-divider-line-thickness\n      bottom: $timeline-line-start\n\n    @media (forced-colors: active)\n      background: canvastext\n\n  .v-timeline-item:first-child\n    .v-timeline-divider__before\n      @include vertical\n        height: $timeline-line-size\n        top: 0\n\n      @include horizontal\n        width: $timeline-line-size\n        inset-inline-start: 0\n        inset-inline-end: initial\n\n    .v-timeline-divider__after\n      @include vertical\n        height: $timeline-line-size-first-last\n\n      @include horizontal\n        width: $timeline-line-size-first-last\n        inset-inline-end: $timeline-line-start\n        inset-inline-start: initial\n\n  .v-timeline-item:last-child\n    .v-timeline-divider__before\n      @include vertical\n        height: $timeline-line-size-first-last\n\n      @include horizontal\n        width: $timeline-line-size-first-last\n\n    .v-timeline-divider__after\n      @include vertical\n        height: calc(var(--v-timeline-line-size-base) + #{math.div($timeline-item-padding, 2)} - var(--v-timeline-line-inset))\n        bottom: 0\n\n      @include horizontal\n        width: calc(var(--v-timeline-line-size-base) + #{math.div($timeline-item-padding, 2)} - var(--v-timeline-line-inset))\n        inset-inline-end: 0\n        inset-inline-start: initial\n\n  .v-timeline-item:only-child\n    .v-timeline-divider__after\n      @include vertical\n        height: calc(var(--v-timeline-line-size-base) - var(--v-timeline-line-inset))\n\n  .v-timeline-divider__dot\n    z-index: 1\n    flex-shrink: 0\n    border-radius: $timeline-dot-border-radius\n    display: flex\n    justify-content: center\n    align-items: center\n\n    @include tools.elevation($timeline-divider-dot-elevation)\n\n    @each $name, $multiplier in settings.$size-scales\n      $size: $timeline-dot-size + (8 * $multiplier)\n\n      &--size-#{$name}\n        --v-timeline-dot-border-size: #{map.get($timeline-dot-border-sizes, $name)}\n        height: $size\n        width: $size\n\n  .v-timeline-divider__inner-dot\n    align-items: center\n    border-radius: $timeline-dot-border-radius\n    display: flex\n    justify-content: center\n    height: calc(100% - var(--v-timeline-dot-border-size))\n    width: calc(100% - var(--v-timeline-dot-border-size))\n\n  /** Modifiers **/\n\n  // Justify\n  .v-timeline--justify-center\n    @include horizontal(true)\n      grid-template-rows: $timeline-item-grid-template-center\n\n    @include vertical(true)\n      grid-template-columns: $timeline-item-grid-template-center\n\n  .v-timeline--justify-auto\n    @include horizontal(true)\n      grid-template-rows: $timeline-item-grid-template-auto\n\n    @include vertical(true)\n      grid-template-columns: $timeline-item-grid-template-auto\n\n  // Density\n  .v-timeline--density-comfortable\n    @include horizontal(true)\n      height: 100%\n\n      &.v-timeline--side-end\n        grid-template-rows: $timeline-density-comfortable-grid-template-end\n\n      &.v-timeline--side-start\n        grid-template-rows: $timeline-density-comfortable-grid-template-start\n\n    @include vertical(true)\n      width: 100%\n\n      &.v-timeline--side-end\n        grid-template-columns: $timeline-density-comfortable-grid-template-end\n\n      &.v-timeline--side-start\n        grid-template-columns: $timeline-density-comfortable-grid-template-start\n\n  .v-timeline--density-compact\n    @include horizontal(true)\n      &.v-timeline--side-end\n        grid-template-rows: $timeline-density-compact-grid-template-end\n\n      &.v-timeline--side-start\n        grid-template-rows: $timeline-density-compact-grid-template-start\n\n      .v-timeline-item__body\n        grid-row: 1\n\n    @include vertical(true)\n      &.v-timeline--side-end\n        grid-template-columns: $timeline-density-compact-grid-template-end\n\n      &.v-timeline--side-start\n        grid-template-columns: $timeline-density-compact-grid-template-start\n\n      .v-timeline-item__body\n        grid-column: 3\n\n  // Side\n  .v-timeline.v-timeline--side-end\n    .v-timeline-item\n      @include horizontal(true)\n        .v-timeline-item__body\n          grid-row: 3\n          align-self: flex-start\n          padding-block-end: initial\n          padding-block-start: $timeline-item-padding\n\n        .v-timeline-item__opposite\n          grid-row: 1\n          align-self: flex-end\n          padding-block-end: $timeline-item-padding\n          padding-block-start: initial\n\n      @include vertical(true)\n        .v-timeline-item__body\n          grid-column: 3\n          justify-self: flex-start\n          padding-inline-start: $timeline-item-padding\n          padding-inline-end: initial\n\n        .v-timeline-item__opposite\n          grid-column: 1\n          justify-self: flex-end\n          padding-inline-end: $timeline-item-padding\n          padding-inline-start: initial\n\n  .v-timeline.v-timeline--side-start\n    .v-timeline-item\n      @include horizontal(true)\n        .v-timeline-item__body\n          grid-row: 1\n          align-self: flex-end\n          padding-block-end: $timeline-item-padding\n          padding-block-start: initial\n\n        .v-timeline-item__opposite\n          grid-row: 3\n          align-self: flex-start\n          padding-block-end: initial\n          padding-block-start: $timeline-item-padding\n\n      @include vertical(true)\n        .v-timeline-item__body\n          grid-column: 1\n          justify-self: flex-end\n          padding-inline-end: $timeline-item-padding\n\n        .v-timeline-item__opposite\n          grid-column: 3\n          justify-self: flex-start\n          padding-inline-start: $timeline-item-padding\n\n  // Fill dot\n  .v-timeline-divider--fill-dot\n    .v-timeline-divider__inner-dot\n      height: inherit\n      width: inherit\n\n  // Alignment\n  .v-timeline--align-center\n    --v-timeline-line-size-base: 50%\n    --v-timeline-line-size-offset: 0px\n\n    @include horizontal(true)\n      justify-items: center\n\n      .v-timeline-item__body\n        padding-inline: math.div($timeline-item-padding, 2)\n\n      .v-timeline-item__opposite\n        padding-inline: math.div($timeline-item-padding, 2)\n\n      .v-timeline-divider\n        justify-content: center\n\n    @include vertical(true)\n      align-items: center\n\n      .v-timeline-divider\n        justify-content: center\n\n  .v-timeline--align-start\n    --v-timeline-line-size-base: 100%\n    --v-timeline-line-size-offset: #{math.div($timeline-item-padding, 2)}\n\n    $timeline-line-size-before: calc(var(--v-timeline-line-size-offset) + var(--v-timeline-dot-size) / 2 - var(--v-timeline-line-inset))\n    $timeline-line-size-after: calc(var(--v-timeline-line-size-base) - var(--v-timeline-dot-size) / 2 + var(--v-timeline-line-size-offset) - var(--v-timeline-line-inset))\n\n    .v-timeline-item:first-child\n      .v-timeline-divider__before\n        --v-timeline-line-size-offset: #{$timeline-item-padding}\n\n      .v-timeline-divider__after\n        --v-timeline-line-size-offset: -#{math.div($timeline-item-padding, 2)}\n\n    .v-timeline-item:last-child\n      .v-timeline-divider__after\n        --v-timeline-line-size-offset: 0px\n\n    @include horizontal(true)\n      justify-items: flex-start\n\n      .v-timeline-divider\n        justify-content: flex-start\n\n        .v-timeline-divider__before\n          width: $timeline-line-size-before\n\n        .v-timeline-divider__after\n          width: $timeline-line-size-after\n\n    @include vertical(true)\n      align-items: flex-start\n\n      .v-timeline-divider\n        justify-content: flex-start\n\n        .v-timeline-divider__before\n          height: $timeline-line-size-before\n\n        .v-timeline-divider__after\n          height: $timeline-line-size-after\n\n  // Truncate start\n  .v-timeline--truncate-line-start\n    .v-timeline-item:first-child\n      .v-timeline-divider__before\n        display: none\n\n      .v-timeline-divider__after\n        --v-timeline-line-size-offset: #{math.div($timeline-item-padding, 2)}\n\n    @include vertical(true)\n      @include timeline-first-item()\n        padding-block-start: 0\n\n    @include horizontal(true)\n      @include timeline-first-item()\n        padding-inline-start: 0\n\n  // Truncate end\n  .v-timeline--truncate-line-end\n    .v-timeline-item:last-child\n      .v-timeline-divider__after\n        display: none\n\n      .v-timeline-divider__before\n        --v-timeline-line-size-offset: #{math.div($timeline-item-padding, 2)}\n\n    @include vertical(true)\n      @include timeline-last-item()\n        padding-block-end: 0\n\n    @include horizontal(true)\n      @include timeline-last-item()\n        padding-inline-end: 0\n"
  },
  {
    "path": "packages/vuetify/src/components/VTimeline/VTimeline.tsx",
    "content": "// Styles\nimport './VTimeline.sass'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { provideDefaults } from '@/composables/defaults'\nimport { makeDensityProps, useDensity } from '@/composables/density'\nimport { useRtl } from '@/composables/locale'\nimport { makeTagProps } from '@/composables/tag'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\n\n// Utilities\nimport { computed, toRef } from 'vue'\nimport { convertToUnit, genericComponent, pick, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { Prop } from 'vue'\nimport { makeVTimelineItemProps } from './VTimelineItem'\n\nexport type TimelineDirection = 'vertical' | 'horizontal'\nexport type TimelineSide = 'start' | 'end' | undefined\nexport type TimelineAlign = 'center' | 'start'\nexport type TimelineJustify = 'auto' | 'center'\nexport type TimelineTruncateLine = 'start' | 'end' | 'both' | undefined\n\nexport const makeVTimelineProps = propsFactory({\n  align: {\n    type: String,\n    default: 'center',\n    validator: (v: any) => ['center', 'start'].includes(v),\n  } as Prop<TimelineAlign>,\n  direction: {\n    type: String,\n    default: 'vertical',\n    validator: (v: any) => ['vertical', 'horizontal'].includes(v),\n  } as Prop<TimelineDirection>,\n  justify: {\n    type: String,\n    default: 'auto',\n    validator: (v: any) => ['auto', 'center'].includes(v),\n  } as Prop<TimelineJustify>,\n  side: {\n    type: String,\n    validator: (v: any) => v == null || ['start', 'end'].includes(v),\n  } as Prop<TimelineSide>,\n  lineThickness: {\n    type: [String, Number],\n    default: 2,\n  },\n  lineColor: String,\n  truncateLine: {\n    type: String,\n    validator: (v: any) => ['start', 'end', 'both'].includes(v),\n  } as Prop<TimelineTruncateLine>,\n\n  ...pick(makeVTimelineItemProps({\n    lineInset: 0,\n  }), ['dotColor', 'fillDot', 'hideOpposite', 'iconColor', 'lineInset', 'size']),\n  ...makeComponentProps(),\n  ...makeDensityProps(),\n  ...makeTagProps(),\n  ...makeThemeProps(),\n}, 'VTimeline')\n\nexport const VTimeline = genericComponent()({\n  name: 'VTimeline',\n\n  props: makeVTimelineProps(),\n\n  setup (props, { slots }) {\n    const { themeClasses } = provideTheme(props)\n    const { densityClasses } = useDensity(props)\n    const { rtlClasses } = useRtl()\n\n    provideDefaults({\n      VTimelineDivider: {\n        lineColor: toRef(() => props.lineColor),\n      },\n      VTimelineItem: {\n        density: toRef(() => props.density),\n        dotColor: toRef(() => props.dotColor),\n        fillDot: toRef(() => props.fillDot),\n        hideOpposite: toRef(() => props.hideOpposite),\n        iconColor: toRef(() => props.iconColor),\n        lineColor: toRef(() => props.lineColor),\n        lineInset: toRef(() => props.lineInset),\n        size: toRef(() => props.size),\n      },\n    })\n\n    const sideClasses = computed(() => {\n      const side = props.side ? props.side : props.density !== 'default' ? 'end' : null\n\n      return side && `v-timeline--side-${side}`\n    })\n\n    const truncateClasses = computed(() => {\n      const classes = [\n        'v-timeline--truncate-line-start',\n        'v-timeline--truncate-line-end',\n      ]\n\n      switch (props.truncateLine) {\n        case 'both': return classes\n        case 'start': return classes[0]\n        case 'end': return classes[1]\n        default: return null\n      }\n    })\n\n    useRender(() => (\n      <props.tag\n        class={[\n          'v-timeline',\n          `v-timeline--${props.direction}`,\n          `v-timeline--align-${props.align}`,\n          `v-timeline--justify-${props.justify}`,\n          truncateClasses.value,\n          {\n            'v-timeline--inset-line': !!props.lineInset,\n          },\n          themeClasses.value,\n          densityClasses.value,\n          sideClasses.value,\n          rtlClasses.value,\n          props.class,\n        ]}\n        style={[\n          {\n            '--v-timeline-line-thickness': convertToUnit(props.lineThickness),\n          },\n          props.style,\n        ]}\n        v-slots={ slots }\n      />\n    ))\n\n    return {}\n  },\n})\n\nexport type VTimeline = InstanceType<typeof VTimeline>\n"
  },
  {
    "path": "packages/vuetify/src/components/VTimeline/VTimelineDivider.tsx",
    "content": "// Components\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\nimport { VIcon } from '@/components/VIcon'\n\n// Composables\nimport { useBackgroundColor } from '@/composables/color'\nimport { makeComponentProps } from '@/composables/component'\nimport { makeElevationProps, useElevation } from '@/composables/elevation'\nimport { IconValue } from '@/composables/icons'\nimport { makeRoundedProps, useRounded } from '@/composables/rounded'\nimport { makeSizeProps, useSize } from '@/composables/size'\n\n// Utilities\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\nexport const makeVTimelineDividerProps = propsFactory({\n  dotColor: String,\n  fillDot: Boolean,\n  hideDot: Boolean,\n  icon: IconValue,\n  iconColor: String,\n  lineColor: String,\n\n  ...makeComponentProps(),\n  ...makeRoundedProps(),\n  ...makeSizeProps(),\n  ...makeElevationProps(),\n}, 'VTimelineDivider')\n\nexport const VTimelineDivider = genericComponent()({\n  name: 'VTimelineDivider',\n\n  props: makeVTimelineDividerProps(),\n\n  setup (props, { slots }) {\n    const { sizeClasses, sizeStyles } = useSize(props, 'v-timeline-divider__dot')\n    const { backgroundColorStyles, backgroundColorClasses } = useBackgroundColor(() => props.dotColor)\n    const { roundedClasses } = useRounded(props, 'v-timeline-divider__dot')\n    const { elevationClasses } = useElevation(props)\n    const {\n      backgroundColorClasses: lineColorClasses,\n      backgroundColorStyles: lineColorStyles,\n    } = useBackgroundColor(() => props.lineColor)\n\n    useRender(() => (\n      <div\n        class={[\n          'v-timeline-divider',\n          {\n            'v-timeline-divider--fill-dot': props.fillDot,\n          },\n          props.class,\n        ]}\n        style={ props.style }\n      >\n        <div\n          class={[\n            'v-timeline-divider__before',\n            lineColorClasses.value,\n          ]}\n          style={ lineColorStyles.value }\n        />\n\n        { !props.hideDot && (\n          <div\n            key=\"dot\"\n            class={[\n              'v-timeline-divider__dot',\n              elevationClasses.value,\n              roundedClasses.value,\n              sizeClasses.value,\n            ]}\n            style={ sizeStyles.value }\n          >\n            <div\n              class={[\n                'v-timeline-divider__inner-dot',\n                backgroundColorClasses.value,\n                roundedClasses.value,\n              ]}\n              style={ backgroundColorStyles.value }\n            >\n              { !slots.default ? (\n                <VIcon\n                  key=\"icon\"\n                  color={ props.iconColor }\n                  icon={ props.icon }\n                  size={ props.size }\n                />\n              ) : (\n                <VDefaultsProvider\n                  key=\"icon-defaults\"\n                  disabled={ !props.icon }\n                  defaults={{\n                    VIcon: {\n                      color: props.iconColor,\n                      icon: props.icon,\n                      size: props.size,\n                    },\n                  }}\n                  v-slots:default={ slots.default }\n                />\n              )}\n            </div>\n          </div>\n        )}\n\n        <div\n          class={[\n            'v-timeline-divider__after',\n            lineColorClasses.value,\n          ]}\n          style={ lineColorStyles.value }\n        />\n      </div>\n    ))\n\n    return {}\n  },\n})\n\nexport type VTimelineDivider = InstanceType<typeof VTimelineDivider>\n"
  },
  {
    "path": "packages/vuetify/src/components/VTimeline/VTimelineItem.tsx",
    "content": "// Components\nimport { VTimelineDivider } from './VTimelineDivider'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { makeDimensionProps, useDimension } from '@/composables/dimensions'\nimport { makeElevationProps } from '@/composables/elevation'\nimport { IconValue } from '@/composables/icons'\nimport { makeRoundedProps } from '@/composables/rounded'\nimport { makeSizeProps } from '@/composables/size'\nimport { makeTagProps } from '@/composables/tag'\n\n// Utilities\nimport { ref, shallowRef, watch } from 'vue'\nimport { convertToUnit, genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { Prop, PropType } from 'vue'\n\n// Types\nexport type TimelineItemSide = 'start' | 'end' | undefined\nexport type VTimelineItemSlots = {\n  default: never\n  icon: never\n  opposite: never\n}\n\nexport const makeVTimelineItemProps = propsFactory({\n  density: String as PropType<'default' | 'compact'>,\n  dotColor: String,\n  fillDot: Boolean,\n  hideDot: Boolean,\n  hideOpposite: {\n    type: Boolean,\n    default: undefined,\n  },\n  icon: IconValue,\n  iconColor: String,\n  lineInset: [Number, String],\n  side: {\n    type: String,\n    validator: (v: any) => v == null || ['start', 'end'].includes(v),\n  } as Prop<TimelineItemSide>,\n\n  ...makeComponentProps(),\n  ...makeDimensionProps(),\n  ...makeElevationProps(),\n  ...makeRoundedProps(),\n  ...makeSizeProps(),\n  ...makeTagProps(),\n}, 'VTimelineItem')\n\nexport const VTimelineItem = genericComponent<VTimelineItemSlots>()({\n  name: 'VTimelineItem',\n\n  props: makeVTimelineItemProps(),\n\n  setup (props, { slots }) {\n    const { dimensionStyles } = useDimension(props)\n\n    const dotSize = shallowRef(0)\n    const dotRef = ref<VTimelineDivider>()\n    watch(dotRef, newValue => {\n      if (!newValue) return\n      dotSize.value = newValue.$el.querySelector('.v-timeline-divider__dot')?.getBoundingClientRect().width ?? 0\n    }, {\n      flush: 'post',\n    })\n\n    useRender(() => (\n      <div\n        class={[\n          'v-timeline-item',\n          {\n            'v-timeline-item--fill-dot': props.fillDot,\n            'v-timeline-item--side-start': props.side === 'start',\n            'v-timeline-item--side-end': props.side === 'end',\n          },\n          props.class,\n        ]}\n        style={[\n          {\n            '--v-timeline-dot-size': convertToUnit(dotSize.value),\n            '--v-timeline-line-inset': props.lineInset ? `calc(var(--v-timeline-dot-size) / 2 + ${convertToUnit(props.lineInset)})` : convertToUnit(0),\n          },\n          props.style,\n        ]}\n      >\n        <div\n          class=\"v-timeline-item__body\"\n          style={ dimensionStyles.value }\n        >\n          { slots.default?.() }\n        </div>\n\n        <VTimelineDivider\n          ref={ dotRef }\n          hideDot={ props.hideDot }\n          icon={ props.icon }\n          iconColor={ props.iconColor }\n          size={ props.size }\n          elevation={ props.elevation }\n          dotColor={ props.dotColor }\n          fillDot={ props.fillDot }\n          rounded={ props.rounded }\n          v-slots={{ default: slots.icon }}\n        />\n\n        { props.density !== 'compact' && (\n          <div class=\"v-timeline-item__opposite\">\n            { !props.hideOpposite && slots.opposite?.() }\n          </div>\n        )}\n      </div>\n    ))\n\n    return {}\n  },\n})\n\nexport type VTimelineItem = InstanceType<typeof VTimelineItem>\n"
  },
  {
    "path": "packages/vuetify/src/components/VTimeline/__tests__/VTimeline.spec.browser.tsx",
    "content": "// Components\nimport { VTimeline, VTimelineItem } from '..'\n\n// Utilities\nimport { render, screen, showcase } from '@test'\nimport { nextTick, ref } from 'vue'\n\n// Types\nimport type {\n  TimelineAlign,\n  TimelineSide,\n  TimelineTruncateLine,\n} from '../VTimeline'\n\nconst stories = {\n  Vertical: (\n    <VTimeline>\n      <VTimelineItem key=\"1\">\n        {{\n          default: () => 'Content',\n          opposite: () => 'Opposite',\n        }}\n      </VTimelineItem>\n      <VTimelineItem key=\"2\">\n        {{\n          default: () => <div class=\"mb-10\">Content</div>,\n          opposite: () => 'Opposite',\n        }}\n      </VTimelineItem>\n    </VTimeline>\n  ),\n  Horizontal: (\n    <VTimeline direction=\"horizontal\">\n      <VTimelineItem key=\"1\">\n        {{\n          default: () => 'Content',\n          opposite: () => 'Opposite',\n        }}\n      </VTimelineItem>\n      <VTimelineItem key=\"2\">\n        {{\n          default: () => <div class=\"mb-10\">Content</div>,\n          opposite: () => 'Opposite',\n        }}\n      </VTimelineItem>\n    </VTimeline>\n  ),\n}\n\ndescribe('VTimeline', () => {\n  describe('vertical', () => {\n    it('should support truncate-line', async () => {\n      const truncateLine = ref<TimelineTruncateLine>()\n      render(() => (\n        <VTimeline truncateLine={ truncateLine.value }>\n          <VTimelineItem key=\"1\">\n            {{\n              default: () => 'Content',\n              opposite: () => 'Opposite',\n            }}\n          </VTimelineItem>\n          <VTimelineItem key=\"2\">\n            {{\n              default: () => <div class=\"mb-10\">Content</div>,\n              opposite: () => 'Opposite',\n            }}\n          </VTimelineItem>\n        </VTimeline>\n      ))\n\n      const timeline = screen.getByCSS('.v-timeline')\n\n      expect(timeline).not.toHaveClass('v-timeline--truncate-line-start')\n      expect(timeline).not.toHaveClass('v-timeline--truncate-line-end')\n\n      truncateLine.value = 'start'\n      await nextTick()\n\n      expect(timeline).toHaveClass('v-timeline--truncate-line-start')\n      expect(timeline).not.toHaveClass('v-timeline--truncate-line-end')\n\n      truncateLine.value = 'end'\n      await nextTick()\n\n      expect(timeline).not.toHaveClass('v-timeline--truncate-line-start')\n      expect(timeline).toHaveClass('v-timeline--truncate-line-end')\n\n      truncateLine.value = 'both'\n      await nextTick()\n\n      expect(timeline).toHaveClass('v-timeline--truncate-line-start')\n      expect(timeline).toHaveClass('v-timeline--truncate-line-end')\n    })\n\n    it('should support align', async () => {\n      const align = ref<TimelineAlign>('center')\n\n      render(() => (\n        <VTimeline align={ align.value }>\n          <VTimelineItem key=\"1\">\n            {{\n              default: () => (\n                <div>\n                  <div class=\"headline-small\">Title</div>\n                  <div class=\"label-large\">Subtitle</div>\n                </div>\n              ),\n              opposite: () => 'Opposite',\n            }}\n          </VTimelineItem>\n          <VTimelineItem key=\"2\">\n            {{\n              default: () => (\n                <div>\n                  <div class=\"headline-small\">Title</div>\n                  <div class=\"label-large\">Subtitle</div>\n                </div>\n              ),\n              opposite: () => 'Opposite',\n            }}\n          </VTimelineItem>\n        </VTimeline>\n      ))\n\n      const timeline = screen.getByCSS('.v-timeline')\n      expect(timeline).toHaveClass('v-timeline--align-center')\n\n      align.value = 'start'\n      await nextTick()\n\n      expect(timeline).toHaveClass('v-timeline--align-start')\n    })\n\n    it('should support side', async () => {\n      const side = ref<TimelineSide>('start')\n\n      render(() => (\n        <VTimeline side={ side.value }>\n          <VTimelineItem key=\"1\">\n            {{\n              default: () => (\n                <div>\n                  <div class=\"headline-small\">Title</div>\n                  <div class=\"label-large\">Subtitle</div>\n                </div>\n              ),\n              opposite: () => 'Opposite',\n            }}\n          </VTimelineItem>\n          <VTimelineItem key=\"2\">\n            {{\n              default: () => (\n                <div>\n                  <div class=\"headline-small\">Title</div>\n                  <div class=\"label-large\">Subtitle</div>\n                </div>\n              ),\n              opposite: () => 'Opposite',\n            }}\n          </VTimelineItem>\n        </VTimeline>\n      ))\n\n      const timeline = screen.getByCSS('.v-timeline')\n      expect(timeline).toHaveClass('v-timeline--side-start')\n\n      side.value = 'end'\n      await nextTick()\n\n      expect(timeline).toHaveClass('v-timeline--side-end')\n    })\n  })\n\n  it('should not fill dot when size is a number and fill-dot is false', async () => {\n    render(() => (\n      <VTimeline>\n        <VTimelineItem size={ 40 } fillDot={ false }>\n          {{ default: () => 'Content' }}\n        </VTimelineItem>\n      </VTimeline>\n    ))\n\n    const outerDot = screen.getByCSS('.v-timeline-divider__dot')\n    const innerDot = screen.getByCSS('.v-timeline-divider__inner-dot')\n\n    expect(outerDot.getBoundingClientRect().width).toBe(40)\n    expect(innerDot.getBoundingClientRect().width).toBe(32)\n    expect(innerDot.getBoundingClientRect().height).toBe(32)\n  })\n\n  it('should fill dot when size is a number and fill-dot is true', async () => {\n    render(() => (\n      <VTimeline>\n        <VTimelineItem size={ 40 } fillDot>\n          {{ default: () => 'Content' }}\n        </VTimelineItem>\n      </VTimeline>\n    ))\n\n    const outerDot = screen.getByCSS('.v-timeline-divider__dot')\n    const innerDot = screen.getByCSS('.v-timeline-divider__inner-dot')\n\n    expect(outerDot.getBoundingClientRect().width).toBe(40)\n    expect(innerDot.getBoundingClientRect().width).toBe(40)\n    expect(innerDot.getBoundingClientRect().height).toBe(40)\n  })\n\n  showcase({ stories })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VTimeline/_mixins.sass",
    "content": "@mixin vertical($immediate: false)\n  $selector: '.v-timeline--vertical'\n  @if $immediate\n    $selector: '#{$selector}#{&}'\n  @else\n    $selector: '#{$selector} #{&}'\n  @at-root #{$selector}\n    @content\n\n@mixin horizontal($immediate: false)\n  $selector: '.v-timeline--horizontal'\n  @if $immediate\n    $selector: '#{$selector}#{&}'\n  @else\n    $selector: '#{$selector} #{&}'\n  @at-root #{$selector}\n    @content\n\n@mixin timeline-first-item()\n  .v-timeline-item:first-child\n    .v-timeline-divider, .v-timeline-item__body, .v-timeline-item__opposite\n      @content\n\n@mixin timeline-last-item()\n  .v-timeline-item:last-child\n    .v-timeline-divider, .v-timeline-item__body, .v-timeline-item__opposite\n      @content\n"
  },
  {
    "path": "packages/vuetify/src/components/VTimeline/_variables.scss",
    "content": "@use '../../styles/tools';\n\n// VTimeline\n$timeline-density-comfortable-grid-template-end: min-content min-content auto !default;\n$timeline-density-comfortable-grid-template-start: auto min-content min-content !default;\n$timeline-density-compact-grid-template-end: 0 min-content auto !default;\n$timeline-density-compact-grid-template-start: auto min-content 0 !default;\n$timeline-dot-border-radius: 50% !default;\n$timeline-dot-divider-background: rgb(var(--v-theme-surface-light)) !default;\n$timeline-dot-size: 38px !default;\n$timeline-inner-dot-divider-background: rgb(var(--v-theme-on-surface)) !default;\n$timeline-inset-divider-line: var(--v-timeline-line-inset) !default;\n$timeline-inset-line-size: 4px !default;\n\n// VTimelineDivider\n$timeline-divider-dot-elevation: 0 !default;\n$timeline-divider-line-background: rgba(var(--v-border-color), var(--v-border-opacity)) !default;\n$timeline-divider-line-horizontal-width: var(--v-timeline-line-inset, 0px) !default;\n$timeline-divider-line-thickness: var(--v-timeline-line-thickness) !default;\n\n// VTimelineItem\n$timeline-item-grid-template-center: minmax(auto, 50%) min-content minmax(auto, 50%) !default;\n$timeline-item-grid-template-auto: auto min-content auto !default;\n$timeline-item-padding: 24px !default;\n\n// Lists\n$timeline-dot-border-sizes: () !default;\n$timeline-dot-border-sizes: tools.map-deep-merge(\n  (\n    'x-small': 6px,\n    'small': 8px,\n    'default': 8px,\n    'large': 8px,\n    'x-large': 10px,\n  ),\n  $timeline-dot-border-sizes\n);\n"
  },
  {
    "path": "packages/vuetify/src/components/VTimeline/index.ts",
    "content": "export { VTimeline } from './VTimeline'\nexport { VTimelineItem } from './VTimelineItem'\n"
  },
  {
    "path": "packages/vuetify/src/components/VToolbar/VToolbar.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  // Block\n  .v-toolbar\n    align-items: flex-start\n    display: flex\n    flex: $toolbar-flex\n    flex-direction: column\n    justify-content: space-between\n    max-width: 100%\n    position: relative\n    transition: $toolbar-transition\n    transition-property: height, width, transform, max-width, left, right, top, bottom, box-shadow\n    width: 100%\n\n    @media (prefers-reduced-motion: reduce)\n      transition-property: box-shadow\n\n    @include tools.border($toolbar-border...)\n    @include tools.elevation($toolbar-elevation)\n    @include tools.rounded($toolbar-border-radius)\n    @include tools.theme($toolbar-theme...)\n\n    &--absolute\n      position: absolute\n\n    &--collapse\n      max-width: $toolbar-collapsed-max-width\n      overflow: hidden\n\n      &-end\n        margin-inline-start: auto\n\n      &.v-toolbar--collapse-start\n        border-end-end-radius: $toolbar-collapsed-border-radius\n\n      &.v-toolbar--collapse-end\n        border-end-start-radius: $toolbar-collapsed-border-radius\n\n      .v-toolbar-title\n        display: none\n\n    &--flat\n      @include tools.elevation($toolbar-flat-elevation)\n\n    &--floating\n      display: inline-flex\n      width: auto\n\n    &--rounded\n      @include tools.rounded($toolbar-rounded-border-radius)\n\n  .v-toolbar__content,\n  .v-toolbar__extension\n    align-items: center\n    display: flex\n    flex: 0 0 auto\n    position: relative\n    transition: inherit\n    width: 100%\n\n  .v-toolbar__content\n    overflow: hidden\n\n    > .v-btn:first-child\n      margin-inline-start: $toolbar-prepend-btn-margin-start\n\n    > .v-btn:last-child\n      margin-inline-end: $toolbar-append-btn-margin-end\n\n    > .v-toolbar-title\n        margin-inline-start: $toolbar-title-margin\n\n    .v-toolbar--density-prominent &\n      align-items: flex-start\n\n  .v-toolbar__image\n    display: flex\n    opacity: var(--v-toolbar-image-opacity, 1)\n    transition-property: opacity\n    @include tools.absolute()\n\n  .v-toolbar__prepend,\n  .v-toolbar__append\n    align-items: center\n    align-self: stretch\n    display: flex\n\n  .v-toolbar__prepend\n    margin-inline: $toolbar-prepend-btn-margin-start auto\n\n  .v-toolbar__append\n    margin-inline: auto $toolbar-append-btn-margin-end\n\n  .v-toolbar-title\n    flex: 1 1\n    font-size: $toolbar-title-font-size\n    min-width: 0\n\n    @include tools.typography($toolbar-title-typography...)\n\n    .v-toolbar--density-prominent &\n      align-self: flex-end\n      padding-bottom: 6px\n\n      @include tools.typography($toolbar-prominent-title-typography...)\n\n  .v-toolbar-title__placeholder\n    overflow: hidden\n    text-overflow: ellipsis\n    white-space: nowrap\n\n  .v-toolbar-items\n    display: flex\n    height: inherit\n    align-self: stretch\n\n    > .v-btn\n      border-radius: 0\n"
  },
  {
    "path": "packages/vuetify/src/components/VToolbar/VToolbar.tsx",
    "content": "// Styles\nimport './VToolbar.sass'\n\n// Components\nimport { VToolbarTitle } from './VToolbarTitle'\nimport { VExpandTransition } from '@/components/transitions'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\nimport { VImg } from '@/components/VImg'\n\n// Composables\nimport { makeBorderProps, useBorder } from '@/composables/border'\nimport { useBackgroundColor } from '@/composables/color'\nimport { makeComponentProps } from '@/composables/component'\nimport { provideDefaults } from '@/composables/defaults'\nimport { makeElevationProps, useElevation } from '@/composables/elevation'\nimport { useRtl } from '@/composables/locale'\nimport { makeLocationProps, useLocation } from '@/composables/location'\nimport { makeRoundedProps, useRounded } from '@/composables/rounded'\nimport { makeTagProps } from '@/composables/tag'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\n\n// Utilities\nimport { computed, shallowRef } from 'vue'\nimport { convertToUnit, genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\nconst allowedDensities = [null, 'prominent', 'default', 'comfortable', 'compact'] as const\n\nexport type Density = null | 'prominent' | 'default' | 'comfortable' | 'compact'\n\nexport const makeVToolbarProps = propsFactory({\n  absolute: Boolean,\n  collapse: Boolean,\n  collapsePosition: {\n    type: String as PropType<'start' | 'end'>,\n    default: 'start',\n  },\n  color: String,\n  density: {\n    type: String as PropType<Density>,\n    default: 'default',\n    validator: (v: any) => allowedDensities.includes(v),\n  },\n  extended: {\n    type: Boolean,\n    default: null,\n  },\n  extensionHeight: {\n    type: [Number, String],\n    default: 48,\n  },\n  flat: Boolean,\n  floating: Boolean,\n  height: {\n    type: [Number, String],\n    default: 64,\n  },\n  image: String,\n  title: String,\n\n  ...makeBorderProps(),\n  ...makeComponentProps(),\n  ...makeElevationProps(),\n  ...makeLocationProps(),\n  ...makeRoundedProps(),\n  ...makeTagProps({ tag: 'header' }),\n  ...makeThemeProps(),\n}, 'VToolbar')\n\nexport type VToolbarSlots = {\n  default: never\n  image: never\n  prepend: never\n  append: never\n  title: never\n  extension: never\n}\n\nexport const VToolbar = genericComponent<VToolbarSlots>()({\n  name: 'VToolbar',\n\n  props: makeVToolbarProps(),\n\n  setup (props, { slots }) {\n    const { backgroundColorClasses, backgroundColorStyles } = useBackgroundColor(() => props.color)\n    const { borderClasses } = useBorder(props)\n    const { elevationClasses } = useElevation(props)\n    const { locationStyles } = useLocation(props)\n    const { roundedClasses } = useRounded(props)\n    const { themeClasses } = provideTheme(props)\n    const { rtlClasses } = useRtl()\n\n    const isExtended = shallowRef(props.extended === null ? !!(slots.extension?.()) : props.extended)\n    const contentHeight = computed(() => parseInt((\n      Number(props.height) +\n      (props.density === 'prominent' ? Number(props.height) : 0) -\n      (props.density === 'comfortable' ? 8 : 0) -\n      (props.density === 'compact' ? 16 : 0)\n    ), 10))\n    const extensionHeight = computed(() => isExtended.value\n      ? parseInt((\n        Number(props.extensionHeight) +\n        (props.density === 'prominent' ? Number(props.extensionHeight) : 0) -\n        (props.density === 'comfortable' ? 4 : 0) -\n        (props.density === 'compact' ? 8 : 0)\n      ), 10)\n      : 0\n    )\n\n    provideDefaults({\n      VBtn: {\n        variant: 'text',\n      },\n    })\n\n    useRender(() => {\n      const hasTitle = !!(props.title || slots.title)\n      const hasImage = !!(slots.image || props.image)\n\n      const extension = slots.extension?.()\n      isExtended.value = props.extended === null ? !!extension : props.extended\n\n      return (\n        <props.tag\n          class={[\n            'v-toolbar',\n            `v-toolbar--collapse-${props.collapsePosition}`,\n            {\n              'v-toolbar--absolute': props.absolute,\n              'v-toolbar--collapse': props.collapse,\n              'v-toolbar--flat': props.flat,\n              'v-toolbar--floating': props.floating,\n              [`v-toolbar--density-${props.density}`]: true,\n            },\n            backgroundColorClasses.value,\n            borderClasses.value,\n            elevationClasses.value,\n            roundedClasses.value,\n            themeClasses.value,\n            rtlClasses.value,\n            props.class,\n          ]}\n          style={[\n            backgroundColorStyles.value,\n            locationStyles.value,\n            props.style,\n          ]}\n        >\n          { hasImage && (\n            <div key=\"image\" class=\"v-toolbar__image\">\n              { !slots.image ? (\n                <VImg\n                  key=\"image-img\"\n                  cover\n                  src={ props.image }\n                />\n              ) : (\n                <VDefaultsProvider\n                  key=\"image-defaults\"\n                  disabled={ !props.image }\n                  defaults={{\n                    VImg: {\n                      cover: true,\n                      src: props.image,\n                    },\n                  }}\n                  v-slots:default={ slots.image }\n                />\n              )}\n            </div>\n          )}\n\n          <VDefaultsProvider\n            defaults={{\n              VTabs: {\n                height: convertToUnit(contentHeight.value),\n              },\n            }}\n          >\n            <div\n              class=\"v-toolbar__content\"\n              style={{ height: convertToUnit(contentHeight.value) }}\n            >\n              { slots.prepend && (\n                <div class=\"v-toolbar__prepend\">\n                  { slots.prepend?.() }\n                </div>\n              )}\n\n              { hasTitle && (\n                <VToolbarTitle key=\"title\" text={ props.title }>\n                  {{ text: slots.title }}\n                </VToolbarTitle>\n              )}\n\n              { slots.default?.() }\n\n              { slots.append && (\n                <div class=\"v-toolbar__append\">\n                  { slots.append?.() }\n                </div>\n              )}\n            </div>\n          </VDefaultsProvider>\n\n          <VDefaultsProvider\n            defaults={{\n              VTabs: {\n                height: convertToUnit(extensionHeight.value),\n              },\n            }}\n          >\n            <VExpandTransition>\n              { isExtended.value && (\n                <div\n                  class=\"v-toolbar__extension\"\n                  style={{ height: convertToUnit(extensionHeight.value) }}\n                >\n                  { extension }\n                </div>\n              )}\n            </VExpandTransition>\n          </VDefaultsProvider>\n        </props.tag>\n      )\n    })\n\n    return {\n      contentHeight,\n      extensionHeight,\n    }\n  },\n})\n\nexport type VToolbar = InstanceType<typeof VToolbar>\n"
  },
  {
    "path": "packages/vuetify/src/components/VToolbar/VToolbarItems.tsx",
    "content": "// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { provideDefaults } from '@/composables/defaults'\nimport { makeVariantProps } from '@/composables/variant'\n\n// Utilities\nimport { toRef } from 'vue'\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\nexport const makeVToolbarItemsProps = propsFactory({\n  ...makeComponentProps(),\n  ...makeVariantProps({ variant: 'text' } as const),\n}, 'VToolbarItems')\n\nexport const VToolbarItems = genericComponent()({\n  name: 'VToolbarItems',\n\n  props: makeVToolbarItemsProps(),\n\n  setup (props, { slots }) {\n    provideDefaults({\n      VBtn: {\n        color: toRef(() => props.color),\n        height: 'inherit',\n        variant: toRef(() => props.variant),\n      },\n    })\n\n    useRender(() => (\n      <div\n        class={[\n          'v-toolbar-items',\n          props.class,\n        ]}\n        style={ props.style }\n      >\n        { slots.default?.() }\n      </div>\n    ))\n\n    return {}\n  },\n})\n\nexport type VToolbarItems = InstanceType<typeof VToolbarItems>\n"
  },
  {
    "path": "packages/vuetify/src/components/VToolbar/VToolbarTitle.tsx",
    "content": "// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { makeTagProps } from '@/composables/tag'\n\n// Utilities\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\nexport const makeVToolbarTitleProps = propsFactory({\n  text: String,\n\n  ...makeComponentProps(),\n  ...makeTagProps(),\n}, 'VToolbarTitle')\n\nexport type VToolbarTitleSlots = {\n  default: never\n  text: never\n}\n\nexport const VToolbarTitle = genericComponent<VToolbarTitleSlots>()({\n  name: 'VToolbarTitle',\n\n  props: makeVToolbarTitleProps(),\n\n  setup (props, { slots }) {\n    useRender(() => {\n      const hasText = !!(slots.default || slots.text || props.text)\n\n      return (\n        <props.tag\n          class={[\n            'v-toolbar-title',\n            props.class,\n          ]}\n          style={ props.style }\n        >\n          { hasText && (\n            <div class=\"v-toolbar-title__placeholder\">\n              { slots.text ? slots.text() : props.text }\n\n              { slots.default?.() }\n            </div>\n          )}\n        </props.tag>\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VToolbarTitle = InstanceType<typeof VToolbarTitle>\n"
  },
  {
    "path": "packages/vuetify/src/components/VToolbar/__tests__/VToolbar.spec.browser.tsx",
    "content": "// Components\nimport { VToolbar } from '..'\nimport { VBtn } from '@/components/VBtn'\n\n// Utilities\nimport { showcase } from '@test'\n\nconst stories = {\n  'With title': <VToolbar title=\"foo\" />,\n  'With color': <VToolbar color=\"primary\" title=\"bar\" />,\n  'With slots': (\n    <VToolbar>\n      {{\n        prepend: () => <VBtn>Prepend</VBtn>,\n        append: () => <VBtn>Append</VBtn>,\n      }}\n    </VToolbar>\n  ),\n  'With location': <div class=\"position: relative; width: 100%; height: 100px; border: 1px dashed #ccc\">\n    <VToolbar absolute floating class=\"pr-5\" location=\"top right\" title=\"top right\" />\n    <VToolbar absolute floating class=\"pr-5\" location=\"bottom center\" title=\"bottom center\" />\n  </div>,\n}\n\ndescribe('VToolbar', () => {\n  showcase({ stories })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VToolbar/_variables.scss",
    "content": "@use \"sass:map\";\n@use '../../styles/settings';\n@use \"../../styles/settings/variables\";\n@use \"../../styles/tools/functions\";\n\n// VToolbar\n$toolbar-background: rgb(var(--v-theme-surface-light)) !default;\n$toolbar-color: functions.theme-color('on-surface-light', var(--v-high-emphasis-opacity)) !default;\n$toolbar-border-color: settings.$border-color-root !default;\n$toolbar-border-radius: map.get(settings.$rounded, 0) !default;\n$toolbar-border-style: settings.$border-style-root !default;\n$toolbar-border-thin-width: thin !default;\n$toolbar-border-width: 0 !default;\n$toolbar-btn-icon-size: 48px !default;\n$toolbar-collapsed-border-radius: 24px !default;\n$toolbar-collapsed-max-width: 112px !default;\n$toolbar-elevation: 0 !default;\n$toolbar-flat-elevation: 0 !default;\n$toolbar-flex: none !default;\n$toolbar-prepend-btn-margin-start: 4px !default;\n$toolbar-append-btn-margin-end: 4px !default;\n$toolbar-rounded-border-radius: variables.$border-radius-root !default;\n$toolbar-transition: .2s variables.$standard-easing !default;\n\n// VToolbarTitle\n$toolbar-title-margin: 20px !default;\n$toolbar-title-font-size: 1.25rem !default;\n$toolbar-title-font-weight: 400 !default;\n$toolbar-title-letter-spacing: 0 !default;\n$toolbar-title-line-height: 1.75rem !default;\n$toolbar-title-text-transform: none !default;\n$toolbar-prominent-title-font-size: 1.5rem !default;\n$toolbar-prominent-title-font-weight: 400 !default;\n$toolbar-prominent-title-letter-spacing: 0 !default;\n$toolbar-prominent-title-line-height: 2.25rem !default;\n$toolbar-prominent-title-text-transform: none !default;\n\n// Lists\n$toolbar-border: (\n  $toolbar-border-color,\n  $toolbar-border-style,\n  $toolbar-border-width,\n  $toolbar-border-thin-width\n) !default;\n\n$toolbar-title-typography: (\n  $toolbar-title-font-size,\n  $toolbar-title-font-weight,\n  $toolbar-title-letter-spacing,\n  $toolbar-title-line-height,\n  $toolbar-title-text-transform\n) !default;\n\n$toolbar-prominent-title-typography: (\n  $toolbar-prominent-title-font-size,\n  $toolbar-prominent-title-font-weight,\n  $toolbar-prominent-title-letter-spacing,\n  $toolbar-prominent-title-line-height,\n  $toolbar-prominent-title-text-transform\n) !default;\n\n$toolbar-theme: (\n  $toolbar-background,\n  $toolbar-color\n) !default;\n\n\n// Deprecated\n$toolbar-content-padding-x: 16px !default;\n$toolbar-content-padding-y: 4px !default;\n$toolbar-title-extended-padding: 56px !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VToolbar/index.ts",
    "content": "export { VToolbar } from './VToolbar'\nexport { VToolbarTitle } from './VToolbarTitle'\nexport { VToolbarItems } from './VToolbarItems'\n"
  },
  {
    "path": "packages/vuetify/src/components/VTooltip/VTooltip.sass",
    "content": "@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-tooltip\n    > .v-overlay__content\n      background: $tooltip-background-color\n      color: $tooltip-text-color\n      border-radius: $tooltip-border-radius\n      font-size: $tooltip-font-size\n      line-height: $tooltip-line-height\n      display: inline-block\n      padding: $tooltip-padding\n      text-transform: initial\n      width: auto\n      opacity: 1\n      transition-property: opacity, transform\n      overflow-wrap: $tooltip-overflow-wrap\n\n    &:not(.v-tooltip--interactive)\n      > .v-overlay__content\n        pointer-events: none\n\n@include tools.layer('overrides')\n  .v-tooltip > .v-overlay__content\n    &[class*=\"enter-active\"]\n      transition-timing-function: settings.$decelerated-easing\n      transition-duration: $tooltip-transition-enter-duration\n\n    &[class*=\"leave-active\"]\n      transition-timing-function: settings.$accelerated-easing\n      transition-duration: $tooltip-transition-leave-duration\n"
  },
  {
    "path": "packages/vuetify/src/components/VTooltip/VTooltip.tsx",
    "content": "// Styles\nimport './VTooltip.sass'\n\n// Components\nimport { VOverlay } from '@/components/VOverlay'\nimport { makeVOverlayProps } from '@/components/VOverlay/VOverlay'\n\n// Composables\nimport { forwardRefs } from '@/composables/forwardRefs'\nimport { useProxiedModel } from '@/composables/proxiedModel'\nimport { useScopeId } from '@/composables/scopeId'\n\n// Utilities\nimport { computed, mergeProps, ref, toRef, useId } from 'vue'\nimport { genericComponent, omit, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { StrategyProps } from '@/components/VOverlay/locationStrategies'\nimport type { OverlaySlots } from '@/components/VOverlay/VOverlay'\n\nexport const makeVTooltipProps = propsFactory({\n  id: String,\n  interactive: Boolean,\n  text: String,\n\n  ...omit(makeVOverlayProps({\n    closeOnBack: false,\n    location: 'end' as const,\n    locationStrategy: 'connected' as const,\n    eager: true,\n    minWidth: 0,\n    offset: 10,\n    openOnClick: false,\n    openOnHover: true,\n    origin: 'auto' as const,\n    scrim: false,\n    scrollStrategy: 'reposition' as const,\n    transition: null,\n  }), [\n    'absolute',\n    'retainFocus',\n    'captureFocus',\n    'disableInitialFocus',\n  ]),\n}, 'VTooltip')\n\nexport const VTooltip = genericComponent<OverlaySlots>()({\n  name: 'VTooltip',\n\n  props: makeVTooltipProps(),\n\n  emits: {\n    'update:modelValue': (value: boolean) => true,\n  },\n\n  setup (props, { slots }) {\n    const isActive = useProxiedModel(props, 'modelValue')\n    const { scopeId } = useScopeId()\n\n    const uid = useId()\n    const id = toRef(() => props.id || `v-tooltip-${uid}`)\n\n    const overlay = ref<VOverlay>()\n\n    const location = computed(() => {\n      return props.location.split(' ').length > 1\n        ? props.location\n        : props.location + ' center' as StrategyProps['location']\n    })\n\n    const origin = computed(() => {\n      return (\n        props.origin === 'auto' ||\n        props.origin === 'overlap' ||\n        props.origin.split(' ').length > 1 ||\n        props.location.split(' ').length > 1\n      ) ? props.origin\n        : props.origin + ' center' as StrategyProps['origin']\n    })\n\n    const transition = toRef(() => {\n      if (props.transition != null) return props.transition\n      return isActive.value ? 'scale-transition' : 'fade-transition'\n    })\n\n    const activatorProps = computed(() =>\n      mergeProps({\n        'aria-describedby': id.value,\n      }, props.activatorProps)\n    )\n\n    useRender(() => {\n      const overlayProps = VOverlay.filterProps(props)\n\n      return (\n        <VOverlay\n          ref={ overlay }\n          class={[\n            'v-tooltip',\n            { 'v-tooltip--interactive': props.interactive },\n            props.class,\n          ]}\n          style={ props.style }\n          id={ id.value }\n          { ...overlayProps }\n          v-model={ isActive.value }\n          transition={ transition.value }\n          absolute\n          location={ location.value }\n          origin={ origin.value }\n          role=\"tooltip\"\n          activatorProps={ activatorProps.value }\n          _disableGlobalStack\n          { ...scopeId }\n        >\n          {{\n            activator: slots.activator,\n            default: (...args) => slots.default?.(...args) ?? props.text,\n          }}\n        </VOverlay>\n      )\n    })\n\n    return forwardRefs({}, overlay)\n  },\n})\n\nexport type VTooltip = InstanceType<typeof VTooltip>\n"
  },
  {
    "path": "packages/vuetify/src/components/VTooltip/_variables.scss",
    "content": "@use '../../styles/settings';\n\n// VTooltip\n$tooltip-background-color: rgb(var(--v-theme-surface-variant)) !default;\n$tooltip-text-color: rgb(var(--v-theme-on-surface-variant)) !default;\n$tooltip-border-radius: settings.$border-radius-root !default;\n$tooltip-font-size: .875rem !default;\n$tooltip-line-height: 1.6 !default;\n$tooltip-transition-enter-duration: 150ms !default;\n$tooltip-transition-leave-duration: 75ms !default;\n$tooltip-padding: 5px 16px !default;\n$tooltip-overflow-wrap: break-word !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VTooltip/index.ts",
    "content": "export { VTooltip } from './VTooltip'\n"
  },
  {
    "path": "packages/vuetify/src/components/VTreeview/VTreeview.tsx",
    "content": "// Components\nimport { makeVTreeviewChildrenProps, VTreeviewChildren } from './VTreeviewChildren'\nimport { makeVListProps, useListItems, VList } from '@/components/VList/VList'\nimport { VListItem } from '@/components/VList/VListItem'\n\n// Composables\nimport { useLocale } from '@/composables'\nimport { provideDefaults } from '@/composables/defaults'\nimport { makeFilterProps, useFilter } from '@/composables/filter'\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { computed, provide, ref, toRaw, toRef } from 'vue'\nimport { genericComponent, omit, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport { VTreeviewSymbol } from './shared'\nimport type { VTreeviewChildrenSlots } from './VTreeviewChildren'\nimport type { InternalListItem } from '@/components/VList/VList'\nimport type { ListItem } from '@/composables/list-items'\nimport type { GenericProps, IndentLinesVariant } from '@/util'\n\nfunction flatten (items: ListItem[], flat: ListItem[] = []) {\n  for (const item of items) {\n    flat.push(item)\n    if (item.children) flatten(item.children, flat)\n  }\n  return flat\n}\n\nexport const makeVTreeviewProps = propsFactory({\n  openAll: Boolean,\n  indentLines: [Boolean, String] as PropType<boolean | IndentLinesVariant>,\n  indentLinesColor: String,\n  indentLinesOpacity: [String, Number],\n  search: String,\n  hideNoData: Boolean,\n  noDataText: {\n    type: String,\n    default: '$vuetify.noDataText',\n  },\n\n  ...makeFilterProps({ filterKeys: ['title'] }),\n  ...omit(makeVTreeviewChildrenProps(), [\n    'index',\n    'path',\n    'indentLinesVariant',\n    'parentIndentLines',\n    'isLastGroup',\n  ]),\n  ...omit(makeVListProps({\n    collapseIcon: '$treeviewCollapse',\n    expandIcon: '$treeviewExpand',\n    slim: true,\n  }), ['nav', 'openStrategy']),\n\n  modelValue: Array,\n}, 'VTreeview')\n\nexport const VTreeview = genericComponent<new <T, O, A, S, M>(\n  props: {\n    items?: T[]\n    opened?: O\n    activated?: A\n    selected?: S\n    modelValue?: M\n    'onUpdate:opened'?: (value: O) => void\n    'onUpdate:activated'?: (value: A) => void\n    'onUpdate:selected'?: (value: S) => void\n    'onUpdate:modelValue'?: (value: M) => void\n  },\n  slots: VTreeviewChildrenSlots<T> & {\n    'no-data': never\n  }\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VTreeview',\n\n  props: makeVTreeviewProps(),\n\n  emits: {\n    'update:opened': (val: unknown) => true,\n    'update:activated': (val: unknown) => true,\n    'update:selected': (val: unknown) => true,\n    'update:modelValue': (val: unknown) => true,\n    'click:open': (value: { id: unknown, value: boolean, path: unknown[] }) => true,\n    'click:select': (value: { id: unknown, value: boolean, path: unknown[] }) => true,\n  },\n\n  setup (props, { slots, emit }) {\n    const { t } = useLocale()\n    const { items } = useListItems(props)\n    const activeColor = toRef(() => props.activeColor)\n    const baseColor = toRef(() => props.baseColor)\n    const color = toRef(() => props.color)\n    const activated = useProxiedModel(props, 'activated')\n    const _selected = useProxiedModel(props, 'selected')\n\n    const selected = computed({\n      get: () => props.modelValue ?? _selected.value,\n      set (val) {\n        _selected.value = val\n        emit('update:modelValue', val)\n      },\n    })\n\n    const vListRef = ref<VList>()\n\n    const opened = computed(() => props.openAll ? openAll(items.value) : props.opened)\n    const flatItems = computed(() => flatten(items.value))\n    const search = toRef(() => props.search)\n    const { filteredItems } = useFilter(props, flatItems, search)\n    const visibleIds = computed(() => {\n      if (!search.value) return null\n      const getPath = vListRef.value?.getPath\n      if (!getPath) return null\n      return new Set(filteredItems.value.flatMap(item => {\n        const itemVal = props.returnObject ? item.raw : item.props.value\n        return [\n          ...getPath(itemVal),\n          ...getChildren(itemVal),\n        ].map(toRaw)\n      }))\n    })\n\n    function getChildren (id: unknown) {\n      const arr: unknown[] = []\n      const queue = ((vListRef.value?.children.get(id) ?? []).slice())\n      while (queue.length) {\n        const child = queue.shift()\n        if (!child) continue\n        arr.push(child)\n        queue.push(...((vListRef.value?.children.get(child) ?? []).slice()))\n      }\n      return arr\n    }\n\n    function openAll (items: InternalListItem<any>[]) {\n      let ids: any[] = []\n\n      for (const i of items) {\n        if (!i.children) continue\n\n        ids.push(props.returnObject ? toRaw(i.raw) : i.value)\n\n        if (i.children) {\n          ids = ids.concat(openAll(i.children))\n        }\n      }\n\n      return ids\n    }\n\n    provide(VTreeviewSymbol, { visibleIds })\n\n    provideDefaults({\n      VTreeviewGroup: {\n        activeColor,\n        baseColor,\n        color,\n        collapseIcon: toRef(() => props.collapseIcon),\n        expandIcon: toRef(() => props.expandIcon),\n      },\n      VTreeviewItem: {\n        activeClass: toRef(() => props.activeClass),\n        activeColor,\n        baseColor,\n        color,\n        density: toRef(() => props.density),\n        disabled: toRef(() => props.disabled),\n        lines: toRef(() => props.lines),\n        variant: toRef(() => props.variant),\n      },\n    })\n\n    useRender(() => {\n      const listProps = VList.filterProps(props)\n      const treeviewChildrenProps = VTreeviewChildren.filterProps(props)\n      const indentLinesVariant = typeof props.indentLines === 'boolean' ? 'default' : props.indentLines\n\n      return (\n        <VList\n          ref={ vListRef }\n          { ...listProps }\n          class={[\n            'v-treeview',\n            {\n              'v-treeview--fluid': props.fluid,\n            },\n            props.class,\n          ]}\n          role=\"tree\"\n          openStrategy=\"multiple\"\n          style={[\n            {\n              '--v-treeview-indent-line-color': props.indentLinesColor,\n              '--v-treeview-indent-line-opacity': props.indentLinesOpacity,\n            },\n            props.style,\n          ]}\n          opened={ opened.value }\n          v-model:activated={ activated.value }\n          v-model:selected={ selected.value }\n        >\n          { visibleIds.value?.size === 0 && !props.hideNoData && (\n            slots['no-data']?.() ?? (<VListItem key=\"no-data\" title={ t(props.noDataText) } />)\n          )}\n          <VTreeviewChildren\n            { ...treeviewChildrenProps }\n            density={ props.density }\n            returnObject={ props.returnObject }\n            items={ items.value }\n            parentIndentLines={ props.indentLines ? [] : undefined }\n            indentLinesVariant={ indentLinesVariant }\n            v-slots={ slots }\n          ></VTreeviewChildren>\n        </VList>\n      )\n    })\n\n    return { }\n  },\n})\n\nexport type VTreeview = InstanceType<typeof VTreeview>\n"
  },
  {
    "path": "packages/vuetify/src/components/VTreeview/VTreeviewChildren.tsx",
    "content": "// Components\nimport { VTreeviewGroup } from './VTreeviewGroup'\nimport { makeVTreeviewItemProps, VTreeviewItem } from './VTreeviewItem'\nimport { VCheckboxBtn } from '@/components/VCheckbox'\nimport { VDivider } from '@/components/VDivider'\nimport { VListItemAction, VListSubheader } from '@/components/VList'\n\n// Composables\nimport { makeDensityProps } from '@/composables/density'\nimport { IconValue } from '@/composables/icons'\n\n// Utilities\nimport { computed, reactive, ref, toRaw } from 'vue'\nimport { genericComponent, getIndentLines, pick, propsFactory, renderSlot } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { VTreeviewItemSlots } from './VTreeviewItem'\nimport type { InternalListItem } from '@/components/VList/VList'\nimport type { SelectStrategyProp } from '@/composables/nested/nested'\nimport type { GenericProps, IndentLinesVariant, IndentLineType } from '@/util'\n\nexport type VTreeviewChildrenSlots<T> = {\n  [K in keyof Omit<VTreeviewItemSlots, 'default'>]: VTreeviewItemSlots[K] & {\n    item: T\n    internalItem: InternalListItem<T>\n  }\n} & {\n  default: never\n  item: {\n    props: InternalListItem['props']\n    item: T\n    internalItem: InternalListItem<T>\n  }\n  header: {\n    props: InternalListItem['props']\n    item: T\n    internalItem: InternalListItem<T>\n    loading: boolean\n  }\n  footer: {\n    props: { indentLines?: IndentLineType[] }\n    item: T\n    internalItem: InternalListItem<T>\n    loading: boolean\n  }\n  divider: { props: InternalListItem['props'] }\n  subheader: { props: InternalListItem['props'] }\n}\n\nexport const makeVTreeviewChildrenProps = propsFactory({\n  fluid: Boolean,\n  disabled: Boolean,\n  loadChildren: Function as PropType<(item: unknown) => Promise<void>>,\n  loadingIcon: {\n    type: String,\n    default: '$loading',\n  },\n  items: Array as PropType<readonly InternalListItem[]>,\n  openOnClick: {\n    type: Boolean,\n    default: undefined,\n  },\n  indeterminateIcon: {\n    type: IconValue,\n    default: '$checkboxIndeterminate',\n  },\n  falseIcon: IconValue,\n  trueIcon: IconValue,\n  returnObject: Boolean,\n  activatable: Boolean,\n  selectable: Boolean,\n  selectedColor: String,\n  selectStrategy: [String, Function, Object] as PropType<SelectStrategyProp>,\n  index: Number,\n  isLastGroup: Boolean,\n  separateRoots: Boolean,\n  parentIndentLines: Array as PropType<IndentLineType[]>,\n  indentLinesVariant: String as PropType<IndentLinesVariant>,\n  path: {\n    type: Array as PropType<number[]>,\n    default: () => [],\n  },\n  ...pick(makeVTreeviewItemProps(), ['hideActions']),\n  ...makeDensityProps(),\n}, 'VTreeviewChildren')\n\nexport const VTreeviewChildren = genericComponent<new <T extends InternalListItem>(\n  props: {\n    items?: readonly T[]\n  },\n  slots: VTreeviewChildrenSlots<T>\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VTreeviewChildren',\n\n  props: makeVTreeviewChildrenProps(),\n\n  setup (props, { slots }) {\n    const isLoading = reactive(new Set<unknown>())\n    const activatorItems = ref<VTreeviewItem[]>([])\n\n    const isClickOnOpen = computed(() => (\n      !props.disabled && (\n        props.openOnClick != null\n          ? props.openOnClick\n          : props.selectable && !props.activatable\n      )))\n\n    async function checkChildren (item: InternalListItem) {\n      try {\n        if (!props.items?.length || !props.loadChildren) return\n\n        if (item?.children?.length === 0) {\n          isLoading.add(item.value)\n          await props.loadChildren(item.raw)\n        }\n      } finally {\n        isLoading.delete(item.value)\n      }\n    }\n\n    function selectItem (select: (value: boolean) => void, isSelected: boolean) {\n      if (props.selectable) {\n        select(isSelected)\n      }\n    }\n\n    return () => slots.default?.() ?? props.items?.map((item, index, items) => {\n      const { children, props: itemProps } = item\n      const loading = isLoading.has(item.value)\n      const nextItemHasChildren = !!items.at(index + 1)?.children\n\n      const depth = props.path?.length ?? 0\n      const isLast = items.length - 1 === index\n      const treeItemProps = {\n        index,\n        depth,\n        isFirst: index === 0,\n        isLast,\n        path: [...props.path, index],\n        hideAction: props.hideActions,\n      }\n\n      const indentLines = getIndentLines({\n        depth,\n        isLast,\n        isLastGroup: props.isLastGroup,\n        leafLinks: !props.hideActions && !props.fluid,\n        separateRoots: props.separateRoots,\n        parentIndentLines: props.parentIndentLines,\n        variant: props.indentLinesVariant,\n      })\n\n      const slotsWithItem = {\n        toggle: slots.toggle\n          ? slotProps => slots.toggle?.({ ...slotProps, ...treeItemProps, item: item.raw, internalItem: item, loading })\n          : undefined,\n        prepend: slotProps => (\n          <>\n            { props.selectable && (!children || (children && !['leaf', 'single-leaf'].includes(props.selectStrategy as string))) && (\n              <VListItemAction start>\n                <VCheckboxBtn\n                  key={ item.value }\n                  modelValue={ slotProps.isSelected }\n                  disabled={ props.disabled || itemProps.disabled }\n                  loading={ loading }\n                  color={ props.selectedColor }\n                  density={ props.density }\n                  indeterminate={ slotProps.isIndeterminate }\n                  indeterminateIcon={ props.indeterminateIcon }\n                  falseIcon={ props.falseIcon }\n                  trueIcon={ props.trueIcon }\n                  onUpdate:modelValue={ v => selectItem(slotProps.select, v) }\n                  onClick={ (e: PointerEvent) => e.stopPropagation() }\n                  onKeydown={ (e: KeyboardEvent) => {\n                    if (!['Enter', 'Space'].includes(e.key)) return\n                    e.stopPropagation()\n                    selectItem(slotProps.select, slotProps.isSelected)\n                  }}\n                />\n              </VListItemAction>\n            )}\n\n            { slots.prepend?.({ ...slotProps, ...treeItemProps, item: item.raw, internalItem: item }) }\n          </>\n        ),\n        append: slots.append\n          ? slotProps => slots.append?.({ ...slotProps, ...treeItemProps, item: item.raw, internalItem: item })\n          : undefined,\n        title: slots.title ? slotProps => slots.title?.({ ...slotProps, item: item.raw, internalItem: item }) : undefined,\n        subtitle: slots.subtitle ? slotProps => slots.subtitle?.({ ...slotProps, item: item.raw, internalItem: item }) : undefined,\n      } satisfies VTreeviewItem['$props']['$children']\n\n      const treeviewGroupProps = VTreeviewGroup.filterProps(itemProps)\n      const treeviewChildrenProps = VTreeviewChildren.filterProps({ ...props, ...treeItemProps })\n\n      const footerProps = {\n        hideActions: props.hideActions,\n        indentLines: indentLines.footer,\n      }\n\n      return children ? (\n        <VTreeviewGroup\n          { ...treeviewGroupProps }\n          value={ props.returnObject ? item.raw : treeviewGroupProps?.value }\n          rawId={ treeviewGroupProps?.value }\n        >\n          {{\n            activator: ({ props: activatorProps, isOpen }) => {\n              const listItemProps = {\n                ...itemProps,\n                ...activatorProps,\n                value: itemProps?.value,\n                hideActions: props.hideActions,\n                indentLines: indentLines.node,\n                ariaExpanded: isOpen,\n                onToggleExpand: [() => checkChildren(item), activatorProps.onClick] as any,\n                onClick: props.disabled || itemProps.disabled\n                  ? undefined\n                  : isClickOnOpen.value\n                    ? [() => checkChildren(item), activatorProps.onClick] as any\n                    : () => selectItem(activatorItems.value[index]?.select, !activatorItems.value[index]?.isSelected),\n              }\n\n              return renderSlot(\n                slots.header,\n                { props: listItemProps, item: item.raw, internalItem: item, loading },\n                () => (\n                  <VTreeviewItem\n                    ref={ el => activatorItems.value[index] = el as VTreeviewItem }\n                    { ...listItemProps }\n                    hasCustomPrepend={ !!slots.prepend }\n                    value={ props.returnObject ? item.raw : itemProps.value }\n                    loading={ loading }\n                    v-slots={ slotsWithItem }\n                  />\n                )\n              )\n            },\n            default: () => (\n              <>\n                <VTreeviewChildren\n                  { ...treeviewChildrenProps }\n                  items={ children }\n                  indentLinesVariant={ props.indentLinesVariant }\n                  parentIndentLines={ indentLines.children }\n                  isLastGroup={ nextItemHasChildren }\n                  returnObject={ props.returnObject }\n                  v-slots={ slots }\n                />\n                { slots.footer?.({ props: footerProps, item: item.raw, internalItem: item, loading }) }\n              </>\n            ),\n          }}\n        </VTreeviewGroup>\n      ) : renderSlot(\n        slots.item,\n        { props: itemProps, item: item.raw, internalItem: item },\n        () => {\n          if (item.type === 'divider') {\n            return renderSlot(\n              slots.divider,\n              { props: item.raw },\n              () => <VDivider { ...item.props } />,\n            )\n          }\n          if (item.type === 'subheader') {\n            return renderSlot(\n              slots.subheader,\n              { props: item.raw },\n              () => <VListSubheader { ...item.props } />,\n            )\n          }\n          return (\n            <VTreeviewItem\n              { ...itemProps }\n              hasCustomPrepend={ !!slots.prepend }\n              hideActions={ props.hideActions }\n              indentLines={ indentLines.leaf }\n              value={ props.returnObject ? toRaw(item.raw) : itemProps.value }\n              v-slots={ slotsWithItem }\n            />\n          )\n        })\n    })\n  },\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VTreeview/VTreeviewGroup.tsx",
    "content": "// Components\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\nimport { makeVListGroupProps, VListGroup } from '@/components/VList/VListGroup'\n\n// Utilities\nimport { computed, ref } from 'vue'\nimport { genericComponent, omit, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { VListGroupSlots } from '@/components/VList/VListGroup'\n\nexport const makeVTreeviewGroupProps = propsFactory({\n  ...omit(makeVListGroupProps({\n    collapseIcon: '$treeviewCollapse',\n    expandIcon: '$treeviewExpand',\n  }), ['subgroup']),\n}, 'VTreeviewGroup')\n\nexport const VTreeviewGroup = genericComponent<VListGroupSlots>()({\n  name: 'VTreeviewGroup',\n\n  props: makeVTreeviewGroupProps(),\n\n  setup (props, { slots }) {\n    const vListGroupRef = ref<VListGroup>()\n    const toggleIcon = computed(() => vListGroupRef.value?.isOpen ? props.collapseIcon : props.expandIcon)\n\n    const activatorDefaults = computed(() => ({\n      VTreeviewItem: {\n        prependIcon: undefined,\n        appendIcon: undefined,\n        toggleIcon: toggleIcon.value,\n      },\n    }))\n\n    useRender(() => {\n      const listGroupProps = VListGroup.filterProps(props)\n\n      return (\n        <VListGroup\n          { ...listGroupProps }\n          ref={ vListGroupRef }\n          class={[\n            'v-treeview-group',\n            props.class,\n          ]}\n          subgroup\n        >\n          {{\n            ...slots,\n            activator: slots.activator ? slotProps => (\n              <>\n                <VDefaultsProvider defaults={ activatorDefaults.value }>\n                  { slots.activator?.(slotProps) }\n                </VDefaultsProvider>\n              </>\n            ) : undefined,\n          }}\n        </VListGroup>\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VTreeviewGroup = InstanceType<typeof VTreeviewGroup>\n"
  },
  {
    "path": "packages/vuetify/src/components/VTreeview/VTreeviewItem.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-treeview-item\n    --list-indent-size: #{$treeview-indent-size}\n    &.v-treeview-item--filtered\n      display: none\n\n    &.v-list-item--disabled:not(a)\n      pointer-events: auto\n\n      .v-selection-control\n        pointer-events: none\n\n\n    &__level\n      width: #{$treeview-indent-size}\n\n      .v-treeview--fluid &\n        width: 0\n\n  .v-treeview\n    --v-treeview-indent-line-color: #{$treeview-indent-line-color}\n    --v-treeview-indent-line-opacity: #{$treeview-indent-lines-opacity}\n\n    &.v-list\n      --indent-padding: #{$treeview-indent-padding}\n\n    &.v-list--disabled .v-list-item__prepend\n      pointer-events: auto\n\n    .v-list-item--slim > .v-list-item__prepend\n      > .v-icon ~ .v-list-item__spacer\n        width: var(--v-list-prepend-gap, $treeview-item-spacer-width)\n\n      &:not(:has(.v-list-item-action))\n        > .v-icon\n          margin-inline-start: $treeview-item-first-icon-margin-start\n\n    &:has(.v-treeview-indent-lines)\n      .v-list-item-action:first-child,\n      .v-treeview-indent-lines + .v-list-item-action\n        > .v-selection-control\n          margin-inline: min(0px, calc(-1 * (var(--v-selection-control-size) - #{$treeview-indent-size}) / 2))\n\n  .v-treeview-indent-lines\n    position: absolute\n    inset-inline-start: 0\n    height: 100%\n    display: grid\n    padding-inline-start: $treeview-indent-lines-padding-left\n    padding-block: $treeview-indent-lines-gap\n    grid-template-columns: repeat(var(--v-indent-parts, 1), var(--prepend-width))\n    opacity: var(--v-treeview-indent-line-opacity)\n    pointer-events: none\n\n  .v-treeview-indent-line\n    &,\n    &::before\n      border: 0px $treeview-indent-line-style var(--v-treeview-indent-line-color)\n\n    &--leaf,\n    &--line\n      border-inline-start-width: $treeview-indent-line-width\n      height: 100%\n      width: calc(50% + #{$treeview-indent-line-width-half})\n      justify-self: end\n\n    &--leaf\n      position: relative\n\n      &::before\n        content: ''\n        position: absolute\n        border-bottom-width: $treeview-indent-line-width\n        height: calc(50% + #{$treeview-indent-line-width-half})\n        width: 100%\n\n      &:last-child::before\n        width: calc(100% - $treeview-indent-line-leaf-margin-right)\n\n    &--leaf-link\n      border-bottom-width: $treeview-indent-line-width\n      height: calc(50% + #{$treeview-indent-line-width-half})\n      margin-inline-start: $treeview-indent-lines-gap\n      margin-inline-end: $treeview-indent-line-leaf-link-margin-right\n\n    &--last-leaf\n      border-inline-start-width: $treeview-indent-line-width\n      border-bottom-width: $treeview-indent-line-width\n      height: calc(50% + #{$treeview-indent-line-width-half})\n      margin-inline-start: calc(50% - #{$treeview-indent-line-width-half})\n      border-bottom-left-radius: $treeview-indent-line-border-radius\n\n      @include tools.rtl()\n        border-bottom-left-radius: 0\n        border-bottom-right-radius: $treeview-indent-line-border-radius\n\n      &:last-child\n        margin-inline-end: $treeview-indent-line-leaf-margin-right\n\n  .v-treeview-group.v-list-group\n    --list-indent-size: 0px\n\n    & > .v-treeview-item__level\n      width: 0px\n\n    .v-list-group__items .v-list-item\n      @include tools.layer('overrides')\n        padding-inline-start: calc(var(--indent-padding))\n"
  },
  {
    "path": "packages/vuetify/src/components/VTreeview/VTreeviewItem.tsx",
    "content": "// Styles\nimport './VTreeviewItem.sass'\n\n// Components\nimport { VAvatar } from '@/components/VAvatar'\nimport { VBtn } from '@/components/VBtn'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\nimport { VIcon } from '@/components/VIcon'\nimport { VListItemAction } from '@/components/VList'\nimport { makeVListItemProps, VListItem } from '@/components/VList/VListItem'\nimport { VProgressCircular } from '@/components/VProgressCircular'\n\n// Composables\nimport { forwardRefs } from '@/composables/forwardRefs'\nimport { IconValue } from '@/composables/icons'\n\n// Utilities\nimport { computed, inject, ref, toRaw } from 'vue'\nimport { VTreeviewSymbol } from './shared'\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { ToggleListItemSlot } from './shared'\nimport type { VListItemSlots } from '@/components/VList/VListItem'\nimport type { IndentLineType } from '@/util'\n\nexport const makeVTreeviewItemProps = propsFactory({\n  loading: Boolean,\n  hideActions: Boolean,\n  hasCustomPrepend: Boolean,\n  indentLines: Array as PropType<IndentLineType[]>,\n  toggleIcon: IconValue,\n\n  ...makeVListItemProps({ slim: true }),\n}, 'VTreeviewItem')\n\nexport type VTreeviewItemSlots = VListItemSlots & {\n  toggle: ToggleListItemSlot & { loading: boolean }\n}\n\nexport const VTreeviewItem = genericComponent<VTreeviewItemSlots>()({\n  name: 'VTreeviewItem',\n\n  props: makeVTreeviewItemProps(),\n\n  emits: {\n    toggleExpand: (value: PointerEvent) => true,\n  },\n\n  setup (props, { slots, emit }) {\n    const visibleIds = inject(VTreeviewSymbol, { visibleIds: ref() }).visibleIds\n\n    const vListItemRef = ref<VListItem>()\n\n    const isActivatableGroupActivator = computed(() =>\n      (vListItemRef.value?.root.activatable.value) &&\n      vListItemRef.value?.isGroupActivator\n    )\n    const vListItemRefIsClickable = computed(() => (\n      vListItemRef.value?.link.isClickable.value ||\n      (props.value != null && !!vListItemRef.value?.list)\n    ))\n    const isClickable = computed(() =>\n      !props.disabled &&\n      props.link !== false &&\n      (props.link || vListItemRefIsClickable.value || isActivatableGroupActivator.value)\n    )\n    const isFiltered = computed(() => visibleIds.value && !visibleIds.value.has(toRaw(vListItemRef.value?.id)))\n\n    function activateGroupActivator (e: MouseEvent | KeyboardEvent) {\n      if (isClickable.value && isActivatableGroupActivator.value) {\n        vListItemRef.value?.activate(!vListItemRef.value?.isActivated, e)\n      }\n    }\n\n    function onClickAction (e: PointerEvent) {\n      e.preventDefault()\n      e.stopPropagation()\n      emit('toggleExpand', e)\n    }\n\n    useRender(() => {\n      const listItemProps = VListItem.filterProps(props)\n      const hasPrepend = slots.prepend ||\n        props.toggleIcon ||\n        props.indentLines ||\n        props.prependIcon ||\n        props.prependAvatar\n\n      return (\n        <VListItem\n          ref={ vListItemRef }\n          { ...listItemProps }\n          active={ vListItemRef.value?.isActivated || undefined }\n          class={[\n            'v-treeview-item',\n            {\n              'v-treeview-item--activatable-group-activator': isActivatableGroupActivator.value,\n              'v-treeview-item--filtered': isFiltered.value,\n            },\n            props.class,\n          ]}\n          role=\"treeitem\"\n          ripple={ false }\n          onClick={ activateGroupActivator }\n        >\n          {{\n            ...slots,\n            prepend: hasPrepend ? slotProps => {\n              return (\n                <>\n                  { props.indentLines && props.indentLines.length > 0 ? (\n                    <div\n                      key=\"indent-lines\"\n                      class=\"v-treeview-indent-lines\"\n                      style={{ '--v-indent-parts': props.indentLines.length }}\n                    >\n                      { props.indentLines.map(type => (\n                        <div class={ `v-treeview-indent-line v-treeview-indent-line--${type}` } />\n                      ))}\n                    </div>\n                  ) : '' }\n                  { !props.hideActions && (\n                    <VListItemAction start>\n                      { props.toggleIcon ? (\n                        <>\n                          { !slots.toggle ? (\n                            <VBtn\n                              key=\"prepend-toggle\"\n                              density=\"compact\"\n                              icon={ props.toggleIcon }\n                              loading={ props.loading }\n                              variant=\"text\"\n                              onClick={ onClickAction }\n                            >\n                              {{\n                                loader: () => (\n                                  <VProgressCircular\n                                    indeterminate=\"disable-shrink\"\n                                    size=\"20\"\n                                    width=\"2\"\n                                  />\n                                ),\n                              }}\n                            </VBtn>\n                          ) : (\n                            <VDefaultsProvider\n                              key=\"prepend-defaults\"\n                              defaults={{\n                                VBtn: {\n                                  density: 'compact',\n                                  icon: props.toggleIcon,\n                                  variant: 'text',\n                                  loading: props.loading,\n                                },\n                                VProgressCircular: {\n                                  indeterminate: 'disable-shrink',\n                                  size: 20,\n                                  width: 2,\n                                },\n                              }}\n                            >\n                              { slots.toggle({\n                                ...slotProps,\n                                loading: props.loading,\n                                props: {\n                                  onClick: onClickAction,\n                                },\n                              })}\n                            </VDefaultsProvider>\n                          )}\n                        </>\n                      ) : (\n                        <div class=\"v-treeview-item__level\" />\n                      )}\n                    </VListItemAction>\n                  )}\n\n                  { !props.hasCustomPrepend ? (\n                    <>\n                      { slots.prepend?.(slotProps) }\n                      { props.prependAvatar && (\n                        <VAvatar\n                          key=\"prepend-avatar\"\n                          density={ props.density }\n                          image={ props.prependAvatar }\n                        />\n                      )}\n\n                      { props.prependIcon && (\n                        <VIcon\n                          key=\"prepend-icon\"\n                          density={ props.density }\n                          icon={ props.prependIcon }\n                        />\n                      )}\n                    </>\n                  ) : (\n                    <VDefaultsProvider\n                      key=\"prepend-defaults\"\n                      defaults={{\n                        VAvatar: {\n                          density: props.density,\n                          image: props.appendAvatar,\n                        },\n                        VIcon: {\n                          density: props.density,\n                          icon: props.appendIcon,\n                        },\n                        VListItemAction: {\n                          start: true,\n                        },\n                      }}\n                    >\n                      { slots.prepend?.(slotProps) }\n                    </VDefaultsProvider>\n                  )}\n                </>\n              )\n            } : undefined,\n          }}\n        </VListItem>\n      )\n    })\n\n    return forwardRefs({}, vListItemRef)\n  },\n})\n\nexport type VTreeviewItem = InstanceType<typeof VTreeviewItem>\n"
  },
  {
    "path": "packages/vuetify/src/components/VTreeview/__tests__/VTreeview.spec.browser.tsx",
    "content": "// Components\nimport { VTreeview } from '../VTreeview'\n\n// Utilities\nimport { render, screen, userEvent, wait, waitAnimationFrame, waitIdle } from '@test'\nimport { nextTick, reactive, ref, shallowRef } from 'vue'\n\nconst items = [\n  {\n    id: 1,\n    title: 'Vuetify Human Resources',\n    children: [\n      {\n        id: 2,\n        title: 'Core team',\n        children: [\n          {\n            id: 201,\n            title: 'John',\n          },\n          {\n            id: 202,\n            title: 'Kael',\n          },\n          {\n            id: 203,\n            title: 'Nekosaur',\n            disabled: true,\n          },\n          {\n            id: 204,\n            title: 'Jacek',\n          },\n          {\n            id: 205,\n            title: 'Andrew',\n          },\n        ],\n      },\n      {\n        id: 3,\n        title: 'Administrators',\n        children: [\n          {\n            id: 301,\n            title: 'Mike',\n          },\n          {\n            id: 302,\n            title: 'Hunt',\n          },\n        ],\n      },\n      {\n        id: 4,\n        title: 'Other contributors',\n      },\n    ],\n  },\n]\n\ndescribe.each([\n  ['plain', 'render', items],\n  ['reactive', 'render', reactive(items)],\n  ['plain', 'props', items],\n  ['reactive', 'props', reactive(items)],\n] as const)('VTreeview with %s items and %s registration', (_, itemsRegistration, items) => {\n  describe('activate', () => {\n    it('single-leaf strategy', async () => {\n      const activated = ref([])\n      render(() => (\n        <VTreeview\n          v-model:activated={ activated.value }\n          openAll\n          items={ items }\n          itemValue=\"id\"\n          activatable\n          activeStrategy=\"single-leaf\"\n          itemsRegistration={ itemsRegistration }\n        />\n      ))\n\n      await userEvent.click(screen.getByText(/Administrators/))\n      expect(activated.value).toStrictEqual([])\n\n      await userEvent.click(screen.getByText(/John/))\n      await userEvent.click(screen.getByText(/Kael/))\n      await userEvent.click(screen.getByText(/Nekosaur/))\n      expect(activated.value).toStrictEqual([203])\n    })\n\n    it('leaf strategy', async () => {\n      const activated = ref([])\n      render(() => (\n        <VTreeview\n          v-model:activated={ activated.value }\n          openAll\n          items={ items }\n          itemValue=\"id\"\n          activatable\n          activeStrategy=\"leaf\"\n          itemsRegistration={ itemsRegistration }\n        />\n      ))\n\n      await userEvent.click(screen.getByText(/Administrators/))\n      expect(activated.value).toStrictEqual([])\n\n      await userEvent.click(screen.getByText(/John/))\n      await userEvent.click(screen.getByText(/Kael/))\n      await userEvent.click(screen.getByText(/Nekosaur/))\n      expect(activated.value).toStrictEqual([201, 202, 203])\n    })\n\n    it('independent strategy', async () => {\n      const activated = ref([])\n      render(() => (\n        <VTreeview\n          v-model:activated={ activated.value }\n          openAll\n          items={ items }\n          itemValue=\"id\"\n          activatable\n          activeStrategy=\"independent\"\n          itemsRegistration={ itemsRegistration }\n        />\n      ))\n\n      await userEvent.click(screen.getByText(/Administrators/))\n      expect(activated.value).toStrictEqual([3])\n\n      await userEvent.click(screen.getByText(/John/))\n      await userEvent.click(screen.getByText(/Kael/))\n      await userEvent.click(screen.getByText(/Nekosaur/))\n      expect(activated.value).toStrictEqual([3, 201, 202, 203])\n\n      await userEvent.click(screen.getByText(/Core team/))\n      expect(activated.value).toStrictEqual([3, 201, 202, 203, 2])\n    })\n\n    it('single-independent strategy', async () => {\n      const activated = ref([])\n      render(() => (\n        <VTreeview\n          v-model:activated={ activated.value }\n          openAll\n          items={ items }\n          itemValue=\"id\"\n          activatable\n          activeStrategy=\"single-independent\"\n          itemsRegistration={ itemsRegistration }\n        />\n      ))\n\n      await userEvent.click(screen.getByText(/Administrators/))\n      expect(activated.value).toStrictEqual([3])\n\n      await userEvent.click(screen.getByText(/John/))\n      await userEvent.click(screen.getByText(/Kael/))\n      await userEvent.click(screen.getByText(/Nekosaur/))\n      expect(activated.value).toStrictEqual([203])\n\n      await userEvent.click(screen.getByText(/Core team/))\n      expect(activated.value).toStrictEqual([2])\n    })\n\n    // https://github.com/vuetifyjs/vuetify/issues/20665\n    it('should emit only once', async () => {\n      const onActivated = vi.fn()\n      render(() => (\n        <VTreeview\n          openAll\n          items={ items }\n          itemValue=\"id\"\n          activatable\n          activeStrategy=\"independent\"\n          onUpdate:activated={ onActivated }\n          itemsRegistration={ itemsRegistration }\n        />\n      ))\n\n      await userEvent.click(screen.getByText(/John/))\n      expect(onActivated).toHaveBeenCalledOnce()\n\n      await userEvent.click(screen.getByText(/Human Resources/))\n      expect(onActivated).toHaveBeenCalledTimes(2)\n    })\n  })\n\n  describe('select', () => {\n    it('single-leaf strategy', async () => {\n      const selected = ref([])\n      render(() => (\n        <VTreeview\n          v-model:selected={ selected.value }\n          openAll\n          items={ items }\n          itemValue=\"id\"\n          selectable\n          selectStrategy=\"single-leaf\"\n          itemsRegistration={ itemsRegistration }\n        />\n      ))\n\n      expect(screen.getAllByCSS('.v-checkbox-btn')).toHaveLength(8)\n      await userEvent.click(screen.getByText(/Mike/))\n      await userEvent.click(screen.getByText(/Hunt/))\n      expect(selected.value).toStrictEqual([302])\n      await userEvent.click(screen.getByText(/contributors/))\n      expect(selected.value).toStrictEqual([4])\n    })\n\n    it('leaf strategy', async () => {\n      const selected = ref([])\n      render(() => (\n        <VTreeview\n          v-model:selected={ selected.value }\n          openAll\n          items={ items }\n          itemValue=\"id\"\n          selectable\n          selectStrategy=\"leaf\"\n          itemsRegistration={ itemsRegistration }\n        />\n      ))\n\n      expect(screen.getAllByCSS('.v-checkbox-btn')).toHaveLength(8)\n      await userEvent.click(screen.getByText(/Mike/))\n      await userEvent.click(screen.getByText(/Hunt/))\n      expect(selected.value).toStrictEqual([301, 302])\n      await userEvent.click(screen.getByText(/contributors/))\n      expect(selected.value).toStrictEqual([301, 302, 4])\n    })\n\n    it('independent strategy', async () => {\n      const selected = ref([])\n      render(() => (\n        <VTreeview\n          v-model:selected={ selected.value }\n          openAll\n          items={ items }\n          itemValue=\"id\"\n          selectable\n          selectStrategy=\"independent\"\n          itemsRegistration={ itemsRegistration }\n        />\n      ))\n\n      expect(screen.getAllByCSS('.v-checkbox-btn')).toHaveLength(11)\n      await userEvent.click(screen.getByText(/Mike/))\n      await userEvent.click(screen.getByText(/Hunt/))\n      expect(selected.value).toStrictEqual([301, 302])\n      await userEvent.click(screen.getByText(/contributors/))\n      expect(selected.value).toStrictEqual([301, 302, 4])\n      await userEvent.click(screen.getByText(/Core/).parentElement!.previousElementSibling!)\n      await userEvent.click(screen.getByText(/Vuetify/).parentElement!.previousElementSibling!)\n      expect(selected.value).toStrictEqual([301, 302, 4, 2, 1])\n    })\n\n    it('single-independent strategy', async () => {\n      const selected = ref([])\n      render(() => (\n        <VTreeview\n          v-model:selected={ selected.value }\n          openAll\n          items={ items }\n          itemValue=\"id\"\n          selectable\n          selectStrategy=\"single-independent\"\n          itemsRegistration={ itemsRegistration }\n        />\n      ))\n\n      expect(screen.getAllByCSS('.v-checkbox-btn')).toHaveLength(11)\n      await userEvent.click(screen.getByText(/John/))\n      await userEvent.click(screen.getByText(/Kael/))\n      expect(selected.value).toStrictEqual([202])\n      await userEvent.click(screen.getByText(/Core/).parentElement!.previousElementSibling!)\n      await userEvent.click(screen.getByText(/Vuetify/).parentElement!.previousElementSibling!)\n      expect(selected.value).toStrictEqual([1])\n    })\n\n    it('classic strategy', async () => {\n      const selected = ref([])\n      render(() => (\n        <VTreeview\n          v-model:selected={ selected.value }\n          openAll\n          items={ items }\n          itemValue=\"id\"\n          selectable\n          selectStrategy=\"classic\"\n          itemsRegistration={ itemsRegistration }\n        />\n      ))\n\n      expect(screen.getAllByCSS('.v-checkbox-btn')).toHaveLength(11)\n      await userEvent.click(screen.getByText(/Mike/))\n      await userEvent.click(screen.getByText(/Hunt/))\n      expect(selected.value).toStrictEqual([301, 302])\n      await userEvent.click(screen.getByText(/Administrators/).parentElement!.previousElementSibling!)\n      expect(selected.value).toStrictEqual([])\n      await userEvent.click(screen.getByText(/Vuetify/).parentElement!.previousElementSibling!)\n      expect(selected.value).toStrictEqual([4, 201, 202, 203, 204, 205, 301, 302])\n    })\n  })\n\n  describe('return-object', () => {\n    describe('open', () => {\n      it('open and collapse should both work', async () => {\n        render(() => (\n          <VTreeview\n            items={ items }\n            itemValue=\"id\"\n            returnObject\n            itemsRegistration={ itemsRegistration }\n          />\n        ))\n\n        await userEvent.click(screen.getByText(/Vuetify/).parentElement!.previousElementSibling!)\n        await expect.element(screen.getByText(/Core/)).toBeVisible()\n        await userEvent.click(screen.getByText(/Vuetify/).parentElement!.previousElementSibling!)\n        // eslint-disable-next-line vitest/no-conditional-in-test\n        if (itemsRegistration === 'render') {\n          // eslint-disable-next-line vitest/no-conditional-expect\n          await expect.poll(() => screen.queryByText(/Core/)).not.toBeVisible()\n        } else {\n          // eslint-disable-next-line vitest/no-conditional-expect\n          await expect.poll(() => screen.queryByText(/Core/)).toBeNull()\n        }\n      })\n\n      it('open-all should work', async () => {\n        render(() => (\n          <VTreeview\n            openAll\n            items={ items }\n            itemValue=\"id\"\n            returnObject\n            itemsRegistration={ itemsRegistration }\n          />\n        ))\n\n        const itemEl = screen.getAllByCSS('.v-treeview-item')\n        expect(itemEl).toHaveLength(11)\n        itemEl.forEach(el => {\n          expect(el).toBeVisible()\n        })\n      })\n\n      it('should return opened object to v-model:opened', async () => {\n        const opened = ref<any[]>([])\n        render(() => (\n          <VTreeview\n            v-model:opened={ opened.value }\n            items={ items }\n            itemValue=\"id\"\n            returnObject\n            itemsRegistration={ itemsRegistration }\n          />\n        ))\n\n        await userEvent.click(screen.getByText(/Vuetify/).parentElement!.previousElementSibling!)\n        await expect.poll(() => opened.value).toEqual([\n          expect.objectContaining({ id: 1 }),\n        ])\n\n        await waitAnimationFrame()\n        await userEvent.click(screen.getByText(/Core/).parentElement!.previousElementSibling!)\n        await expect.poll(() => opened.value).toEqual([\n          expect.objectContaining({ id: 1 }),\n          expect.objectContaining({ id: 2 }),\n        ])\n      })\n    })\n\n    describe('activate', () => {\n      it('single-leaf strategy', async () => {\n        const activated = ref([])\n        render(() => (\n          <VTreeview\n            v-model:activated={ activated.value }\n            openAll\n            items={ items }\n            itemValue=\"id\"\n            activatable\n            activeStrategy=\"single-leaf\"\n            returnObject\n          />\n        ))\n\n        await userEvent.click(screen.getByText(/Human Resources/))\n        expect(activated.value).toStrictEqual([])\n\n        await userEvent.click(screen.getByText(/John/))\n        await userEvent.click(screen.getByText(/Kael/))\n        await userEvent.click(screen.getByText(/Nekosaur/))\n        expect(activated.value).toStrictEqual([\n          expect.objectContaining({ id: 203 }),\n        ])\n      })\n\n      it('leaf strategy', async () => {\n        const activated = ref([])\n        render(() => (\n          <VTreeview\n            v-model:activated={ activated.value }\n            openAll\n            items={ items }\n            itemValue=\"id\"\n            activatable\n            activeStrategy=\"leaf\"\n            returnObject\n            itemsRegistration={ itemsRegistration }\n          />\n        ))\n\n        await userEvent.click(screen.getByText(/Human Resources/))\n        expect(activated.value).toStrictEqual([])\n\n        await userEvent.click(screen.getByText(/John/))\n        await userEvent.click(screen.getByText(/Kael/))\n        await userEvent.click(screen.getByText(/Nekosaur/))\n        expect(activated.value).toStrictEqual([\n          expect.objectContaining({ id: 201 }),\n          expect.objectContaining({ id: 202 }),\n          expect.objectContaining({ id: 203 })]\n        )\n      })\n\n      it('independent strategy', async () => {\n        const activated = ref([])\n        render(() => (\n          <VTreeview\n            v-model:activated={ activated.value }\n            openAll\n            items={ items }\n            itemValue=\"id\"\n            activatable\n            activeStrategy=\"independent\"\n            returnObject\n            itemsRegistration={ itemsRegistration }\n          />\n        ))\n\n        await userEvent.click(screen.getByText(/Human Resources/))\n        expect(activated.value).toStrictEqual([\n          expect.objectContaining({ id: 1 }),\n        ])\n\n        await userEvent.click(screen.getByText(/Core team/))\n        expect(activated.value).toStrictEqual([\n          expect.objectContaining({ id: 1 }),\n          expect.objectContaining({ id: 2 }),\n        ])\n\n        await userEvent.click(screen.getByText(/John/))\n        await userEvent.click(screen.getByText(/Kael/))\n        await userEvent.click(screen.getByText(/Nekosaur/))\n        expect(activated.value).toStrictEqual([\n          expect.objectContaining({ id: 1 }),\n          expect.objectContaining({ id: 2 }),\n          expect.objectContaining({ id: 201 }),\n          expect.objectContaining({ id: 202 }),\n          expect.objectContaining({ id: 203 }),\n        ])\n      })\n\n      it('single-independent strategy', async () => {\n        const activated = ref([])\n        render(() => (\n          <VTreeview\n            v-model:activated={ activated.value }\n            openAll\n            items={ items }\n            itemValue=\"id\"\n            activatable\n            activeStrategy=\"single-independent\"\n            returnObject\n            itemsRegistration={ itemsRegistration }\n          />\n        ))\n\n        await userEvent.click(screen.getByText(/Human Resources/))\n        expect(activated.value).toStrictEqual([\n          expect.objectContaining({ id: 1 }),\n        ])\n\n        await userEvent.click(screen.getByText(/Core team/))\n        expect(activated.value).toStrictEqual([\n          expect.objectContaining({ id: 2 }),\n        ])\n\n        await userEvent.click(screen.getByText(/John/))\n        await userEvent.click(screen.getByText(/Kael/))\n        await userEvent.click(screen.getByText(/Nekosaur/))\n        expect(activated.value).toStrictEqual([\n          expect.objectContaining({ id: 203 }),\n        ])\n      })\n    })\n\n    describe('select', () => {\n      it('single-leaf strategy', async () => {\n        const selected = ref([])\n        render(() => (\n          <VTreeview\n            v-model:selected={ selected.value }\n            openAll\n            items={ items }\n            itemValue=\"id\"\n            returnObject\n            selectable\n            selectStrategy=\"single-leaf\"\n            itemsRegistration={ itemsRegistration }\n          />\n        ))\n\n        expect(screen.getAllByCSS('.v-checkbox-btn')).toHaveLength(8)\n        await userEvent.click(screen.getByText(/Mike/))\n        await userEvent.click(screen.getByText(/Hunt/))\n        expect(selected.value).toStrictEqual([\n          expect.objectContaining({ id: 302 }),\n        ])\n        await userEvent.click(screen.getByText(/contributors/))\n        expect(selected.value).toStrictEqual([\n          expect.objectContaining({ id: 4 }),\n        ])\n      })\n\n      it('leaf strategy', async () => {\n        const selected = ref([])\n        render(() => (\n          <VTreeview\n            v-model:selected={ selected.value }\n            openAll\n            items={ items }\n            itemValue=\"id\"\n            returnObject\n            selectable\n            selectStrategy=\"leaf\"\n            itemsRegistration={ itemsRegistration }\n          />\n        ))\n\n        expect(screen.getAllByCSS('.v-checkbox-btn')).toHaveLength(8)\n        await userEvent.click(screen.getByText(/Mike/))\n        await userEvent.click(screen.getByText(/Hunt/))\n        expect(selected.value).toStrictEqual([\n          expect.objectContaining({ id: 301 }),\n          expect.objectContaining({ id: 302 }),\n        ])\n        await userEvent.click(screen.getByText(/contributors/))\n        expect(selected.value).toStrictEqual([\n          expect.objectContaining({ id: 301 }),\n          expect.objectContaining({ id: 302 }),\n          expect.objectContaining({ id: 4 }),\n        ])\n      })\n\n      it('independent strategy', async () => {\n        const selected = ref([])\n        render(() => (\n          <VTreeview\n            v-model:selected={ selected.value }\n            openAll\n            items={ items }\n            itemValue=\"id\"\n            returnObject\n            selectable\n            selectStrategy=\"independent\"\n            itemsRegistration={ itemsRegistration }\n          />\n        ))\n\n        expect(screen.getAllByCSS('.v-checkbox-btn')).toHaveLength(11)\n        await userEvent.click(screen.getByText(/Mike/))\n        await userEvent.click(screen.getByText(/Hunt/))\n        expect(selected.value).toStrictEqual([\n          expect.objectContaining({ id: 301 }),\n          expect.objectContaining({ id: 302 }),\n        ])\n        await userEvent.click(screen.getByText(/contributors/))\n        expect(selected.value).toStrictEqual([\n          expect.objectContaining({ id: 301 }),\n          expect.objectContaining({ id: 302 }),\n          expect.objectContaining({ id: 4 }),\n        ])\n        await userEvent.click(screen.getByText(/Core/).parentElement!.previousElementSibling!)\n        await userEvent.click(screen.getByText(/Vuetify/).parentElement!.previousElementSibling!)\n        expect(selected.value).toStrictEqual([\n          expect.objectContaining({ id: 301 }),\n          expect.objectContaining({ id: 302 }),\n          expect.objectContaining({ id: 4 }),\n          expect.objectContaining({ id: 2 }),\n          expect.objectContaining({ id: 1 }),\n        ])\n      })\n\n      it('single-independent strategy', async () => {\n        const selected = ref([])\n        render(() => (\n          <VTreeview\n            v-model:selected={ selected.value }\n            openAll\n            items={ items }\n            itemValue=\"id\"\n            returnObject\n            selectable\n            selectStrategy=\"single-independent\"\n            itemsRegistration={ itemsRegistration }\n          />\n        ))\n\n        expect(screen.getAllByCSS('.v-checkbox-btn')).toHaveLength(11)\n        await userEvent.click(screen.getByText(/John/))\n        await userEvent.click(screen.getByText(/Kael/))\n        expect(selected.value).toStrictEqual([\n          expect.objectContaining({ id: 202 }),\n        ])\n        await userEvent.click(screen.getByText(/Core/).parentElement!.previousElementSibling!)\n        await userEvent.click(screen.getByText(/Vuetify/).parentElement!.previousElementSibling!)\n        expect(selected.value).toStrictEqual([\n          expect.objectContaining({ id: 1 }),\n        ])\n      })\n\n      it('classic strategy', async () => {\n        const selected = ref([])\n        render(() => (\n          <VTreeview\n            v-model:selected={ selected.value }\n            openAll\n            items={ items }\n            itemValue=\"id\"\n            itemProps={ item => ({ disabled: item.disabled }) }\n            selectable\n            returnObject\n            selectStrategy=\"classic\"\n            itemsRegistration={ itemsRegistration }\n          />\n        ))\n\n        expect(screen.getAllByCSS('.v-checkbox-btn')).toHaveLength(11)\n        await userEvent.click(screen.getByText(/Mike/))\n        await userEvent.click(screen.getByText(/Hunt/))\n        expect(selected.value).toStrictEqual([\n          expect.objectContaining({ id: 301 }),\n          expect.objectContaining({ id: 302 }),\n        ])\n        await userEvent.click(screen.getByText(/Administrators/).parentElement!.previousElementSibling!)\n        expect(selected.value).toStrictEqual([])\n        await userEvent.click(screen.getByText(/Vuetify/).parentElement!.previousElementSibling!)\n        expect(selected.value).toStrictEqual([\n          expect.objectContaining({ id: 4 }),\n          expect.objectContaining({ id: 201 }),\n          expect.objectContaining({ id: 202 }),\n          // expect.objectContaining({ id: 203 }), // disabled\n          expect.objectContaining({ id: 204 }),\n          expect.objectContaining({ id: 205 }),\n          expect.objectContaining({ id: 301 }),\n          expect.objectContaining({ id: 302 }),\n        ])\n      })\n    })\n\n    describe('search', () => {\n      // https://github.com/vuetifyjs/vuetify/issues/20488\n      it('should filter items based on the search text and return the correct result', async () => {\n        const search = shallowRef('')\n        render(() => (\n          <VTreeview\n            search={ search.value }\n            items={ items }\n            itemValue=\"id\"\n            openAll\n            returnObject\n            itemsRegistration={ itemsRegistration }\n          />\n        ))\n\n        await nextTick()\n        search.value = 'j'\n        await nextTick()\n        expect(screen.getByText(/Vuetify/)).toBeVisible()\n        expect(screen.getByText(/Core/)).toBeVisible()\n        expect(screen.getByText(/John/)).toBeVisible()\n        expect(screen.getByText(/Jacek/)).toBeVisible()\n        expect(screen.getByText(/Andrew/)).not.toBeVisible()\n        expect(screen.getByText(/Administrators/)).not.toBeVisible()\n      })\n    })\n  })\n\n  it('should have all items visible when open-all is applied', async () => {\n    render(() => (\n      <VTreeview\n        openAll\n        items={ items }\n        itemValue=\"id\"\n        itemsRegistration={ itemsRegistration }\n      />\n    ))\n\n    const itemEl = screen.getAllByCSS('.v-treeview-item')\n    expect(itemEl).toHaveLength(11)\n    itemEl.forEach(el => {\n      expect(el).toBeVisible()\n    })\n  })\n\n  // https://github.com/vuetifyjs/vuetify/issues/20830\n  it('should return correct isOpen state in prepend slot', async () => {\n    render(() => (\n      <VTreeview\n        items={ items }\n        itemValue=\"id\"\n        openOnClick\n        returnObject\n        itemsRegistration={ itemsRegistration }\n      >\n        {{\n          prepend: ({ isOpen }) => (<span class=\"prepend-is-open\">{ `${isOpen}` }</span>),\n        }}\n      </VTreeview>\n    ))\n\n    await userEvent.click(screen.getByText(/Vuetify Human Resources/))\n    await waitIdle()\n    const itemsPrepend = screen.getAllByCSS('.v-treeview-item .v-list-item__prepend .prepend-is-open')\n    expect(itemsPrepend[0]).toHaveTextContent(/^true$/)\n    expect(itemsPrepend[1]).toHaveTextContent(/^false$/)\n\n    await userEvent.click(screen.getByText(/Core team/))\n    await waitIdle()\n    expect(itemsPrepend[0]).toHaveTextContent(/^true$/)\n    expect(itemsPrepend[1]).toHaveTextContent(/^true$/)\n\n    await userEvent.click(screen.getByText(/Core team/))\n    await waitIdle()\n    expect(itemsPrepend[0]).toHaveTextContent(/^true$/)\n    expect(itemsPrepend[1]).toHaveTextContent(/^false$/)\n\n    await userEvent.click(screen.getByText(/Vuetify Human Resources/))\n    await waitIdle()\n    expect(itemsPrepend[0]).toHaveTextContent(/^false$/)\n  })\n})\n\ndescribe('VTreeview with loading', () => {\n  it('should respond to direct clicks on the toggle icon', async () => {\n    const loadSpy = vi.fn()\n\n    const items = ref([\n      { value: 1, title: '1.root', children: [] },\n      { value: 2, title: '2.another', children: [] },\n    ] as any[])\n\n    async function loadChildren (item: any) {\n      loadSpy(item)\n      await wait(50)\n      if (item.value === 1) {\n        items.value[0].children = [{ value: 3, title: '3.node', children: [] }]\n      }\n      if (item.value === 3) {\n        items.value[0].children[0].children = [{ value: 4, title: '4.leaf' }]\n      }\n    }\n    render(() => (\n      <VTreeview\n        items={ items.value }\n        loadChildren={ loadChildren }\n      />\n    ))\n\n    expect(screen.queryAllByText(/3.node/)).toHaveLength(0)\n    expect(screen.queryAllByText(/4.leaf/)).toHaveLength(0)\n\n    await userEvent.tab()\n    await userEvent.tab()\n    await userEvent.keyboard('{enter}')\n    expect(loadSpy).toHaveBeenCalledOnce()\n    await wait(350) // needs to fully render for the following click\n    expect(screen.getByText(/3.node/)).toBeVisible()\n\n    await userEvent.click(screen.getAllByCSS('.v-treeview-item .v-list-item-action .v-btn')[1])\n    expect(loadSpy).toHaveBeenCalledTimes(2)\n    await wait(200)\n    expect(screen.queryByText(/4.leaf/)).toBeVisible()\n\n    await userEvent.click(screen.getAllByCSS('.v-treeview-item .v-list-item-action .v-btn')[0])\n    await expect.poll(() => screen.getByText(/3.node/)).not.toBeVisible()\n    expect(screen.getByText(/4.leaf/)).not.toBeVisible()\n    expect(loadSpy).toHaveBeenCalledTimes(2)\n  })\n\n  it('should respond to full item click', async () => {\n    const loadSpy = vi.fn()\n\n    const items = ref([\n      { value: 1, title: '1.root', children: [] },\n      { value: 2, title: '2.another', children: [] },\n    ] as any[])\n\n    // eslint-disable-next-line sonarjs/no-identical-functions\n    async function loadChildren (item: any) {\n      loadSpy(item)\n      await wait(50)\n      if (item.value === 1) {\n        items.value[0].children = [{ value: 3, title: '3.node', children: [] }]\n      }\n      if (item.value === 3) {\n        items.value[0].children[0].children = [{ value: 4, title: '4.leaf' }]\n      }\n    }\n    render(() => (\n      <VTreeview\n        items={ items.value }\n        loadChildren={ loadChildren }\n        openOnClick\n      />\n    ))\n\n    expect(screen.queryAllByText(/3.node/)).toHaveLength(0)\n    expect(screen.queryAllByText(/4.leaf/)).toHaveLength(0)\n\n    await userEvent.tab() // single tab selects the whole item\n    await userEvent.keyboard(' ')\n    expect(loadSpy).toHaveBeenCalledOnce()\n    await wait(350) // needs to fully render for the following click\n    expect(screen.getByText(/3.node/)).toBeVisible()\n\n    await userEvent.click(screen.getByText(/3.node/))\n    await nextTick()\n    expect(loadSpy).toHaveBeenCalledTimes(2)\n    await wait(200)\n    expect(screen.queryByText(/4.leaf/)).toBeVisible()\n\n    await userEvent.click(screen.getAllByCSS('.v-treeview-item')[0])\n    await expect.poll(() => screen.getByText(/3.node/)).not.toBeVisible()\n    expect(screen.getByText(/4.leaf/)).not.toBeVisible()\n  })\n\n  it('should support toggle slot', async () => {\n    const loadSpy = vi.fn()\n\n    const items = ref([\n      { value: 1, title: '1.root', children: [] },\n      { value: 2, title: '2.another', children: [] },\n    ] as any[])\n\n    // eslint-disable-next-line sonarjs/no-identical-functions\n    async function loadChildren (item: any) {\n      loadSpy(item)\n      await wait(50)\n      if (item.value === 1) {\n        items.value[0].children = [{ value: 3, title: '3.node', children: [] }]\n      }\n      if (item.value === 3) {\n        items.value[0].children[0].children = [{ value: 4, title: '4.leaf' }]\n      }\n    }\n    render(() => (\n      <VTreeview\n        items={ items.value }\n        loadChildren={ loadChildren }\n      >\n        {{\n          toggle: ({ props, loading }) => loading\n            ? 'loading...'\n            : <div onClick={ (e: any) => props.onClick(e) } class=\"text-blue\">[toggle]</div>,\n        }}\n      </VTreeview>\n    ))\n\n    expect(screen.queryAllByText(/3.node/)).toHaveLength(0)\n    expect(screen.queryAllByText(/4.leaf/)).toHaveLength(0)\n\n    await userEvent.click(screen.queryAllByText('[toggle]')[0])\n    expect(loadSpy).toHaveBeenCalledOnce()\n    await wait(350) // needs to fully render for the following click\n    expect(screen.getByText(/3.node/)).toBeVisible()\n\n    await userEvent.click(screen.queryAllByText('[toggle]')[1])\n    await nextTick()\n    expect(loadSpy).toHaveBeenCalledTimes(2)\n    await expect.poll(() => screen.queryByText(/4.leaf/)).toBeVisible()\n\n    await userEvent.click(screen.queryAllByText('[toggle]')[0])\n    await expect.poll(() => screen.getByText(/3.node/)).not.toBeVisible()\n    expect(screen.getByText(/4.leaf/)).not.toBeVisible()\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VTreeview/_variables.scss",
    "content": "@use 'sass:map';\n@use 'sass:math';\n\n$treeview-item-spacer-width: 10px !default;\n$treeview-item-first-icon-margin-start: -6px !default;\n\n$treeview-indent-size: 28px !default; // 28px here to match the width of the expand toggle VBtn.\n$treeview-indent-padding: 16px !default;\n\n$treeview-indent-lines-padding-left: 8px !default;\n$treeview-indent-lines-gap: 0 !default;\n$treeview-indent-lines-opacity: .4 !default;\n$treeview-indent-line-width: 1px !default;\n$treeview-indent-line-width-half: math.round(math.div($treeview-indent-line-width, 2)) !default;\n$treeview-indent-line-color: rgb(var(--v-theme-on-surface)) !default;\n$treeview-indent-line-style: solid !default;\n$treeview-indent-line-leaf-link-margin-right: 6px !default;\n$treeview-indent-line-leaf-margin-right: 4px !default;\n$treeview-indent-line-border-radius: 4px !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VTreeview/index.ts",
    "content": "export { VTreeview } from './VTreeview'\nexport { VTreeviewItem } from './VTreeviewItem'\nexport { VTreeviewGroup } from './VTreeviewGroup'\n"
  },
  {
    "path": "packages/vuetify/src/components/VTreeview/shared.ts",
    "content": "// Types\nimport type { ComputedRef, InjectionKey } from 'vue'\nimport type { ListItemSlot } from '@/components/VList/VListItem'\n\nexport interface TreeViewProvide {\n  visibleIds: ComputedRef<Set<unknown> | null>\n}\n\nexport type ToggleListItemSlot = ListItemSlot & {\n  props: { onClick: (e: PointerEvent) => void }\n}\n\nexport const VTreeviewSymbol: InjectionKey<TreeViewProvide> = Symbol.for('vuetify:v-treeview')\n"
  },
  {
    "path": "packages/vuetify/src/components/VValidation/VValidation.tsx",
    "content": "// Composables\nimport { makeValidationProps, useValidation } from '@/composables/validation'\n\n// Utilities\nimport { genericComponent } from '@/util'\n\n// Types\nimport type { GenericProps } from '@/util'\n\nexport type VValidationSlots = {\n  default: ReturnType<typeof useValidation>\n}\n\nexport const VValidation = genericComponent<new <T>(\n  props: {\n    modelValue?: T | null\n    'onUpdate:modelValue'?: (value: T | null) => void\n  },\n  slots: VValidationSlots,\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VValidation',\n\n  props: makeValidationProps(),\n\n  emits: {\n    'update:modelValue': (value: any) => true,\n  },\n\n  setup (props, { slots }) {\n    const validation = useValidation(props, 'validation')\n\n    return () => slots.default?.(validation)\n  },\n})\n\nexport type VValidation = InstanceType<typeof VValidation>\n"
  },
  {
    "path": "packages/vuetify/src/components/VValidation/index.ts",
    "content": "export { VValidation } from './VValidation'\n"
  },
  {
    "path": "packages/vuetify/src/components/VVirtualScroll/VVirtualScroll.sass",
    "content": "@use '../../styles/tools'\n\n@include tools.layer('components')\n  .v-virtual-scroll\n    display: block\n    flex: 1 1 auto\n    max-width: 100%\n    overflow: auto\n    position: relative\n\n    &__container\n      display: block\n"
  },
  {
    "path": "packages/vuetify/src/components/VVirtualScroll/VVirtualScroll.tsx",
    "content": "// Styles\nimport './VVirtualScroll.sass'\n\n// Components\nimport { VVirtualScrollItem } from './VVirtualScrollItem'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { makeDimensionProps, useDimension } from '@/composables/dimensions'\nimport { useToggleScope } from '@/composables/toggleScope'\nimport { makeVirtualProps, useVirtual } from '@/composables/virtual'\n\n// Utilities\nimport { onMounted, onScopeDispose, toRef } from 'vue'\nimport {\n  convertToUnit,\n  genericComponent,\n  getCurrentInstance,\n  getScrollParent,\n  propsFactory,\n  useRender,\n} from '@/util'\n\n// Types\nimport type { PropType, Ref } from 'vue'\nimport type { GenericProps } from '@/util'\n\nexport interface VVirtualScrollSlot<T> {\n  item: T\n  index: number\n}\n\nexport const makeVVirtualScrollProps = propsFactory({\n  items: {\n    type: Array as PropType<readonly unknown[]>,\n    default: () => ([]),\n  },\n  renderless: Boolean,\n\n  ...makeVirtualProps(),\n  ...makeComponentProps(),\n  ...makeDimensionProps(),\n}, 'VVirtualScroll')\n\nexport const VVirtualScroll = genericComponent<new <T, Renderless extends boolean = false>(\n  props: {\n    items?: readonly T[]\n    renderless?: Renderless\n  },\n  slots: {\n    default: VVirtualScrollSlot<T> & (Renderless extends true ? {\n      itemRef: Ref<HTMLElement | undefined>\n    } : {})\n  }\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VVirtualScroll',\n\n  props: makeVVirtualScrollProps(),\n\n  setup (props, { slots }) {\n    const vm = getCurrentInstance('VVirtualScroll')\n    const { dimensionStyles } = useDimension(props)\n    const {\n      calculateVisibleItems,\n      containerRef,\n      markerRef,\n      handleScroll,\n      handleScrollend,\n      handleItemResize,\n      scrollToIndex,\n      paddingTop,\n      paddingBottom,\n      computedItems,\n    } = useVirtual(props, toRef(() => props.items))\n\n    useToggleScope(() => props.renderless, () => {\n      function handleListeners (add = false) {\n        const method = add ? 'addEventListener' : 'removeEventListener'\n\n        if (containerRef.value === document.documentElement) {\n          document[method]('scroll', handleScroll, { passive: true })\n          document[method]('scrollend', handleScrollend)\n        } else {\n          containerRef.value?.[method]('scroll', handleScroll, { passive: true })\n          containerRef.value?.[method]('scrollend', handleScrollend)\n        }\n      }\n\n      onMounted(() => {\n        containerRef.value = getScrollParent(vm.vnode.el as HTMLElement, true)\n        handleListeners(true)\n      })\n      onScopeDispose(handleListeners)\n    })\n\n    useRender(() => {\n      const children = computedItems.value.map(item => (\n        <VVirtualScrollItem\n          key={ item.key }\n          renderless={ props.renderless }\n          onUpdate:height={ height => handleItemResize(item.index, height) }\n        >\n          { slotProps => slots.default?.({ item: item.raw, index: item.index, ...slotProps }) }\n        </VVirtualScrollItem>\n      ))\n\n      return props.renderless ? (\n        <>\n          <div ref={ markerRef } class=\"v-virtual-scroll__spacer\" style={{ paddingTop: convertToUnit(paddingTop.value) }} />\n          { children }\n          <div class=\"v-virtual-scroll__spacer\" style={{ paddingBottom: convertToUnit(paddingBottom.value) }} />\n        </>\n      ) : (\n        <div\n          ref={ containerRef }\n          class={[\n            'v-virtual-scroll',\n            props.class,\n          ]}\n          onScrollPassive={ handleScroll }\n          onScrollend={ handleScrollend }\n          style={[\n            dimensionStyles.value,\n            props.style,\n          ]}\n        >\n          <div\n            ref={ markerRef }\n            class=\"v-virtual-scroll__container\"\n            style={{\n              paddingTop: convertToUnit(paddingTop.value),\n              paddingBottom: convertToUnit(paddingBottom.value),\n            }}\n          >\n            { children }\n          </div>\n        </div>\n      )\n    })\n\n    return {\n      calculateVisibleItems,\n      scrollToIndex,\n    }\n  },\n})\n\nexport type VVirtualScroll = InstanceType<typeof VVirtualScroll>\n"
  },
  {
    "path": "packages/vuetify/src/components/VVirtualScroll/VVirtualScrollItem.tsx",
    "content": "// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { useResizeObserver } from '@/composables/resizeObserver'\n\n// Utilities\nimport { watch } from 'vue'\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { GenericProps, TemplateRef } from '@/util'\n\nexport const makeVVirtualScrollItemProps = propsFactory({\n  renderless: Boolean,\n\n  ...makeComponentProps(),\n}, 'VVirtualScrollItem')\n\nexport const VVirtualScrollItem = genericComponent<new <Renderless extends boolean = false>(\n  props: {\n    renderless?: Renderless\n  },\n  slots: {\n    default: Renderless extends true ? {\n      itemRef: TemplateRef\n    } : never\n  }\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VVirtualScrollItem',\n\n  inheritAttrs: false,\n\n  props: makeVVirtualScrollItemProps(),\n\n  emits: {\n    'update:height': (height: number) => true,\n  },\n\n  setup (props, { attrs, emit, slots }) {\n    const { resizeRef, contentRect } = useResizeObserver(undefined, 'border')\n\n    watch(() => contentRect.value?.height, height => {\n      if (height != null) emit('update:height', height)\n    })\n\n    useRender(() => props.renderless ? (\n      <>\n        { slots.default?.({ itemRef: resizeRef }) }\n      </>\n    ) : (\n      <div\n        ref={ resizeRef }\n        class={[\n          'v-virtual-scroll__item',\n          props.class,\n        ]}\n        style={ props.style }\n        { ...attrs }\n      >\n        { (slots.default as any)?.() }\n      </div>\n    ))\n  },\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VVirtualScroll/__tests__/VVirtualScroll.spec.browser.tsx",
    "content": "// Components\nimport { VVirtualScroll } from '../VVirtualScroll'\n\n// Utilities\nimport { render, screen, scroll, waitIdle } from '@test'\nimport { createRange } from '@/util'\n\ndescribe('VVirtualScroll', () => {\n  it('only renders visible items', async () => {\n    const items = createRange(1000)\n\n    render(() => (\n      <VVirtualScroll height=\"400\" items={ items } itemHeight=\"24\">\n        {{\n          default: ({ index }) => (\n            <div>{ index }</div>\n          ),\n        }}\n      </VVirtualScroll>\n    ))\n\n    const elements = screen.getAllByCSS('.v-virtual-scroll__item')\n    expect(elements.length).toBeGreaterThan(16) // 400/24=16.6\n    expect(elements.length).toBeLessThan(50)\n  })\n\n  it('reuses the same elements', async () => {\n    const items = createRange(1000)\n\n    const result = render(() => (\n      <VVirtualScroll height=\"400\" items={ items }>\n        {{\n          default: ({ item, index }) => (\n            <div>{ index }</div>\n          ),\n        }}\n      </VVirtualScroll>\n    ))\n\n    const root = screen.getByCSS('.v-virtual-scroll')\n\n    await waitIdle()\n    const el = await result.findByText(16)\n    await scroll({ top: 400, behavior: 'smooth' }, root)\n    await expect(result.findByText(16)).resolves.toBe(el)\n\n    await scroll({ top: 800, behavior: 'smooth' }, root)\n    await scroll({ top: 200, behavior: 'smooth' }, root)\n    await expect(result.findByText(16)).resolves.not.toBe(el)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VVirtualScroll/index.ts",
    "content": "export { VVirtualScroll } from './VVirtualScroll'\n"
  },
  {
    "path": "packages/vuetify/src/components/VWindow/VWindow.sass",
    "content": "@use 'sass:selector'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-window\n    overflow: hidden\n\n    &__container\n      display: flex\n      flex-direction: column\n      height: inherit\n      position: relative\n      transition: $window-transition\n\n    &__controls\n      position: absolute\n      left: 0\n      top: 0\n      width: 100%\n      height: 100%\n      display: flex\n      align-items: center\n      justify-content: space-between\n      padding: $window-controls-padding\n      pointer-events: none\n\n      > *\n        pointer-events: auto\n\n    &--show-arrows-on-hover\n      overflow: hidden\n\n      .v-window__left\n        transform: translateX(-200%)\n\n      @at-root #{selector.append(':has(.v-window__controls--right)', &)}\n        .v-window__left\n          transform: translateX(200%)\n\n      .v-window__right\n        transform: translateX(200%)\n\n      @at-root #{selector.append(':has(.v-window__controls--left)', &)}\n        .v-window__right\n          transform: translateX(-200%)\n\n      &:hover\n        .v-window__left,\n        .v-window__right\n          transform: translateX(0)\n\n    &--vertical-arrows\n      .v-window__controls\n        flex-direction: column\n        justify-content: center\n        gap: $window-controls-vertical-gap\n\n        &--left\n          align-items: start\n\n        &--right\n          align-items: end\n\n        .v-window__left,\n        .v-window__right\n          .v-icon\n            transform: rotate(90deg)\n\n    &--crossfade > .v-window__container\n      isolation: isolate\n\n      > .v-window-item\n        mix-blend-mode: $window-crossfade-blend-mode\n\n@include tools.layer('overrides')\n  .v-window-item\n    transition-duration: var(--v-window-transition-duration, revert-layer)\n\n@include tools.layer('transitions')\n  .v-window\n    &-x-transition,\n    &-x-reverse-transition,\n    &-y-transition,\n    &-y-reverse-transition\n      &-enter-active,\n      &-leave-active\n        transition: $window-transition\n\n        @media (prefers-reduced-motion: reduce)\n          transition-duration: 0s\n\n      &-leave-from,\n      &-leave-to\n        position: absolute\n        top: 0\n        width: 100%\n\n    &-x-transition\n      &-enter-from\n        transform: translateX(100%)\n\n      &-leave-to\n        transform: translateX(-100%)\n\n    &-x-reverse-transition\n      &-enter-from\n        transform: translateX(-100%)\n\n      &-leave-to\n        transform: translateX(100%)\n\n    &-y-transition\n      &-enter-from\n        transform: translateY(100%)\n\n      &-leave-to\n        transform: translateY(-100%)\n\n    &-y-reverse-transition\n      &-enter-from\n        transform: translateY(-100%)\n\n      &-leave-to\n        transform: translateY(100%)\n\n  .v-window\n    &-crossfade-transition\n      &-enter-active,\n      &-leave-active\n        transition: $window-transition\n\n      &-leave-from,\n      &-leave-to\n        position: absolute\n        top: 0\n        width: 100%\n\n      &-enter-from,\n      &-leave-to\n        opacity: 0\n"
  },
  {
    "path": "packages/vuetify/src/components/VWindow/VWindow.tsx",
    "content": "// Styles\nimport './VWindow.sass'\n\n// Components\nimport { VBtn } from '@/components/VBtn'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { useGroup } from '@/composables/group'\nimport { useLocale, useRtl } from '@/composables/locale'\nimport { makeTagProps } from '@/composables/tag'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\n\n// Directives\nimport vTouch from '@/directives/touch'\n\n// Utilities\nimport { computed, nextTick, provide, ref, shallowRef, toRef, watch } from 'vue'\nimport { convertToUnit, genericComponent, IN_BROWSER, PREFERS_REDUCED_MOTION, propsFactory, useRender } from '@/util'\nimport { getScrollParent } from '@/util/getScrollParent'\n\n// Types\nimport type { ComputedRef, InjectionKey, PropType, Ref } from 'vue'\nimport type { GroupItemProvide, GroupProvide } from '@/composables/group'\nimport type { IconValue } from '@/composables/icons'\nimport type { TouchHandlers } from '@/directives/touch'\nimport type { GenericProps } from '@/util'\n\nexport type VWindowSlots = {\n  default: { group: GroupProvide }\n  additional: { group: GroupProvide }\n  prev: { props: ControlProps }\n  next: { props: ControlProps }\n}\n\ntype WindowProvide = {\n  transition: ComputedRef<undefined | string>\n  transitionCount: Ref<number>\n  transitionHeight: Ref<undefined | string>\n  isReversed: Ref<boolean>\n  rootRef: Ref<HTMLElement | undefined>\n}\n\ntype ControlProps = {\n  icon: IconValue\n  class: string\n  onClick: () => void\n  'aria-label': string\n}\n\nexport const VWindowSymbol: InjectionKey<WindowProvide> = Symbol.for('vuetify:v-window')\nexport const VWindowGroupSymbol: InjectionKey<GroupItemProvide> = Symbol.for('vuetify:v-window-group')\n\nexport const makeVWindowProps = propsFactory({\n  continuous: Boolean,\n  nextIcon: {\n    type: [Boolean, String, Function, Object] as PropType<IconValue>,\n    default: '$next',\n  },\n  prevIcon: {\n    type: [Boolean, String, Function, Object] as PropType<IconValue>,\n    default: '$prev',\n  },\n  reverse: Boolean,\n  showArrows: {\n    type: [Boolean, String],\n    validator: (v: any) => typeof v === 'boolean' || v === 'hover',\n  },\n  verticalArrows: [Boolean, String] as PropType<boolean | 'left' | 'right'>,\n  touch: {\n    type: [Object, Boolean] as PropType<boolean | TouchHandlers>,\n    default: undefined,\n  },\n  direction: {\n    type: String as PropType<'horizontal' | 'vertical'>,\n    default: 'horizontal',\n  },\n\n  modelValue: null,\n  disabled: Boolean,\n  selectedClass: {\n    type: String,\n    default: 'v-window-item--active',\n  },\n  // TODO: mandatory should probably not be exposed but do this for now\n  mandatory: {\n    type: [Boolean, String] as PropType<boolean | 'force'>,\n    default: 'force' as const,\n  },\n  crossfade: Boolean,\n  transitionDuration: Number,\n\n  ...makeComponentProps(),\n  ...makeTagProps(),\n  ...makeThemeProps(),\n}, 'VWindow')\n\nexport const VWindow = genericComponent<new <T>(\n  props: {\n    modelValue?: T\n    'onUpdate:modelValue'?: (value: T) => void\n  },\n  slots: VWindowSlots,\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VWindow',\n\n  directives: { vTouch },\n\n  props: makeVWindowProps(),\n\n  emits: {\n    'update:modelValue': (value: any) => true,\n  },\n\n  setup (props, { slots }) {\n    const { themeClasses } = provideTheme(props)\n    const { isRtl } = useRtl()\n    const { t } = useLocale()\n\n    const group = useGroup(props, VWindowGroupSymbol)\n\n    const rootRef = ref()\n    const isRtlReverse = computed(() => isRtl.value ? !props.reverse : props.reverse)\n    const isReversed = shallowRef(false)\n    const transition = computed(() => {\n      if (props.crossfade) {\n        return 'v-window-crossfade-transition'\n      }\n\n      const axis = props.direction === 'vertical' ? 'y' : 'x'\n      const reverse = isRtlReverse.value ? !isReversed.value : isReversed.value\n      const direction = reverse ? '-reverse' : ''\n\n      return `v-window-${axis}${direction}-transition`\n    })\n    const transitionCount = shallowRef(0)\n    const transitionHeight = ref<undefined | string>(undefined)\n\n    const activeIndex = computed(() => {\n      return group.items.value.findIndex(item => group.selected.value.includes(item.id))\n    })\n\n    // Fix for https://github.com/vuetifyjs/vuetify/issues/18447\n    watch(activeIndex, (newVal, oldVal) => {\n      let scrollableParent: HTMLElement | undefined\n      const savedScrollPosition = { left: 0, top: 0 }\n\n      if (IN_BROWSER && oldVal >= 0) {\n        scrollableParent = getScrollParent(rootRef.value)\n\n        savedScrollPosition.left = scrollableParent?.scrollLeft\n        savedScrollPosition.top = scrollableParent?.scrollTop\n      }\n\n      const itemsLength = group.items.value.length\n      const lastIndex = itemsLength - 1\n\n      if (itemsLength <= 2) {\n        isReversed.value = newVal < oldVal\n      } else if (newVal === lastIndex && oldVal === 0) {\n        isReversed.value = false\n      } else if (newVal === 0 && oldVal === lastIndex) {\n        isReversed.value = true\n      } else {\n        isReversed.value = newVal < oldVal\n      }\n\n      nextTick(() => {\n        if (!IN_BROWSER || !scrollableParent) return\n\n        const currentScrollY = scrollableParent.scrollTop\n\n        if (currentScrollY !== savedScrollPosition.top) {\n          scrollableParent.scrollTo({ ...savedScrollPosition, behavior: 'instant' })\n        }\n\n        requestAnimationFrame(() => {\n          if (!scrollableParent) return\n\n          const rafScrollY = scrollableParent.scrollTop\n\n          if (rafScrollY !== savedScrollPosition.top) {\n            scrollableParent.scrollTo({ ...savedScrollPosition, behavior: 'instant' })\n          }\n        })\n      })\n    }, { flush: 'sync' }) // Run synchronously before DOM updates\n\n    provide(VWindowSymbol, {\n      transition,\n      isReversed,\n      transitionCount,\n      transitionHeight,\n      rootRef,\n    })\n\n    const canMoveBack = toRef(() => props.continuous || activeIndex.value !== 0)\n    const canMoveForward = toRef(() => props.continuous || activeIndex.value !== group.items.value.length - 1)\n\n    function prev () {\n      canMoveBack.value && group.prev()\n    }\n\n    function next () {\n      canMoveForward.value && group.next()\n    }\n\n    const arrows = computed(() => {\n      const arrows = []\n\n      const prevProps = {\n        icon: isRtl.value ? props.nextIcon : props.prevIcon,\n        class: `v-window__${isRtlReverse.value ? 'right' : 'left'}`,\n        onClick: group.prev,\n        'aria-label': t('$vuetify.carousel.prev'),\n      }\n\n      arrows.push(canMoveBack.value\n        ? slots.prev\n          ? slots.prev({ props: prevProps })\n          : <VBtn { ...prevProps } />\n        : <div />\n      )\n\n      const nextProps = {\n        icon: isRtl.value ? props.prevIcon : props.nextIcon,\n        class: `v-window__${isRtlReverse.value ? 'left' : 'right'}`,\n        onClick: group.next,\n        'aria-label': t('$vuetify.carousel.next'),\n      }\n\n      arrows.push(canMoveForward.value\n        ? slots.next\n          ? slots.next({ props: nextProps })\n          : <VBtn { ...nextProps } />\n        : <div />\n      )\n\n      return arrows\n    })\n\n    const touchOptions = computed(() => {\n      if (props.touch === false) return props.touch\n\n      const options: TouchHandlers = {\n        left: () => {\n          isRtlReverse.value ? prev() : next()\n        },\n        right: () => {\n          isRtlReverse.value ? next() : prev()\n        },\n        start: ({ originalEvent }) => {\n          originalEvent.stopPropagation()\n        },\n      }\n\n      return {\n        ...options,\n        ...(props.touch === true ? {} : props.touch),\n      }\n    })\n\n    function onKeyDown (e: KeyboardEvent) {\n      if (\n        (props.direction === 'horizontal' && e.key === 'ArrowLeft') ||\n        (props.direction === 'vertical' && e.key === 'ArrowUp')\n      ) {\n        e.preventDefault()\n        prev()\n        nextTick(() => { canMoveBack.value ? focusArrow(0) : focusArrow(1) })\n      }\n\n      if (\n        (props.direction === 'horizontal' && e.key === 'ArrowRight') ||\n        (props.direction === 'vertical' && e.key === 'ArrowDown')\n      ) {\n        e.preventDefault()\n        next()\n        nextTick(() => { canMoveForward.value ? focusArrow(1) : focusArrow(0) })\n      }\n    }\n\n    function focusArrow (index: number) {\n      const arrow = arrows.value[index]\n\n      if (!arrow) return\n\n      const arrowEl = Array.isArray(arrow) ? arrow[0] : arrow\n      arrowEl.el?.focus()\n    }\n\n    useRender(() => (\n      <props.tag\n        ref={ rootRef }\n        class={[\n          'v-window',\n          {\n            'v-window--show-arrows-on-hover': props.showArrows === 'hover',\n            'v-window--vertical-arrows': !!props.verticalArrows,\n            'v-window--crossfade': !!props.crossfade,\n          },\n          themeClasses.value,\n          props.class,\n        ]}\n        style={[\n          props.style,\n          {\n            '--v-window-transition-duration': !PREFERS_REDUCED_MOTION()\n              ? convertToUnit(props.transitionDuration, 'ms')\n              : null,\n          },\n        ]}\n        v-touch={ touchOptions.value }\n      >\n        <div\n          class=\"v-window__container\"\n          style={{\n            height: transitionHeight.value,\n          }}\n        >\n          { slots.default?.({ group }) }\n\n          { props.showArrows !== false && (\n            <div\n              class={[\n                'v-window__controls',\n                { 'v-window__controls--left': props.verticalArrows === 'left' || props.verticalArrows === true },\n                { 'v-window__controls--right': props.verticalArrows === 'right' },\n              ]}\n              onKeydown={ onKeyDown }\n            >\n              { arrows.value }\n            </div>\n          )}\n        </div>\n\n        { slots.additional?.({ group }) }\n      </props.tag>\n    ))\n\n    return {\n      group,\n    }\n  },\n})\n\nexport type VWindow = InstanceType<typeof VWindow>\n"
  },
  {
    "path": "packages/vuetify/src/components/VWindow/VWindowItem.tsx",
    "content": "// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { makeGroupItemProps, useGroupItem } from '@/composables/group'\nimport { makeLazyProps, useLazy } from '@/composables/lazy'\nimport { useSsrBoot } from '@/composables/ssrBoot'\nimport { MaybeTransition } from '@/composables/transition'\n\n// Directives\nimport vTouch from '@/directives/touch'\n\n// Utilities\nimport { computed, inject, nextTick, shallowRef } from 'vue'\nimport { convertToUnit, genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport { VWindowGroupSymbol, VWindowSymbol } from './VWindow'\n\nexport const makeVWindowItemProps = propsFactory({\n  reverseTransition: {\n    type: [Boolean, String],\n    default: undefined,\n  },\n  transition: {\n    type: [Boolean, String],\n    default: undefined,\n  },\n\n  ...makeComponentProps(),\n  ...makeGroupItemProps(),\n  ...makeLazyProps(),\n}, 'VWindowItem')\n\nexport const VWindowItem = genericComponent()({\n  name: 'VWindowItem',\n\n  directives: { vTouch },\n\n  props: makeVWindowItemProps(),\n\n  emits: {\n    'group:selected': (val: { value: boolean }) => true,\n  },\n\n  setup (props, { slots }) {\n    const window = inject(VWindowSymbol)\n    const groupItem = useGroupItem(props, VWindowGroupSymbol)\n    const { isBooted } = useSsrBoot()\n\n    if (!window || !groupItem) throw new Error('[Vuetify] VWindowItem must be used inside VWindow')\n\n    const isTransitioning = shallowRef(false)\n    const hasTransition = computed(() => isBooted.value && (\n      window.isReversed.value\n        ? props.reverseTransition !== false\n        : props.transition !== false\n    ))\n\n    function onAfterTransition () {\n      if (!isTransitioning.value || !window) {\n        return\n      }\n\n      // Finalize transition state.\n      isTransitioning.value = false\n      if (window.transitionCount.value > 0) {\n        window.transitionCount.value -= 1\n\n        // Remove container height if we are out of transition.\n        if (window.transitionCount.value === 0) {\n          window.transitionHeight.value = undefined\n        }\n      }\n    }\n\n    function onBeforeTransition () {\n      if (isTransitioning.value || !window) {\n        return\n      }\n\n      // Initialize transition state here.\n      isTransitioning.value = true\n\n      if (window.transitionCount.value === 0) {\n        // Set initial height for height transition.\n        window.transitionHeight.value = convertToUnit(window.rootRef.value?.clientHeight)\n      }\n\n      window.transitionCount.value += 1\n    }\n\n    function onTransitionCancelled () {\n      onAfterTransition() // This should have the same path as normal transition end.\n    }\n\n    function onEnterTransition (el: Element) {\n      if (!isTransitioning.value) {\n        return\n      }\n\n      nextTick(() => {\n        // Do not set height if no transition or cancelled.\n        if (!hasTransition.value || !isTransitioning.value || !window) {\n          return\n        }\n\n        // Set transition target height.\n        window.transitionHeight.value = convertToUnit(el.clientHeight)\n      })\n    }\n\n    const transition = computed(() => {\n      const name = window.isReversed.value\n        ? props.reverseTransition\n        : props.transition\n\n      return !hasTransition.value ? false : {\n        name: typeof name !== 'string' ? window.transition.value : name,\n        onBeforeEnter: onBeforeTransition,\n        onAfterEnter: onAfterTransition,\n        onEnterCancelled: onTransitionCancelled,\n        onBeforeLeave: onBeforeTransition,\n        onAfterLeave: onAfterTransition,\n        onLeaveCancelled: onTransitionCancelled,\n        onEnter: onEnterTransition,\n      }\n    })\n\n    const { hasContent } = useLazy(props, groupItem.isSelected)\n\n    useRender(() => (\n      <MaybeTransition transition={ transition.value } disabled={ !isBooted.value }>\n        <div\n          class={[\n            'v-window-item',\n            groupItem.selectedClass.value,\n            props.class,\n          ]}\n          style={ props.style }\n          v-show={ groupItem.isSelected.value }\n        >\n          { hasContent.value && slots.default?.() }\n        </div>\n      </MaybeTransition>\n    ))\n\n    return { groupItem }\n  },\n})\n\nexport type VWindowItem = InstanceType<typeof VWindowItem>\n"
  },
  {
    "path": "packages/vuetify/src/components/VWindow/__tests__/VWindow.spec.browser.tsx",
    "content": "// Components\nimport { VWindow } from '../VWindow'\nimport { VWindowItem } from '../VWindowItem'\n\n// Utilities\nimport { commands, page, render, screen, showcase, userEvent } from '@test'\nimport { ref } from 'vue'\n\nconst stories = {\n  'Without arrows': (\n    <VWindow>\n      <VWindowItem>\n        <div class=\"bg-grey d-flex justify-center align-center\">\n          <h1>1. foo</h1>\n        </div>\n      </VWindowItem>\n      <VWindowItem>\n        <div class=\"bg-grey d-flex justify-center align-center\">\n          <h1>2. bar</h1>\n        </div>\n      </VWindowItem>\n    </VWindow>\n  ),\n  'With arrows': (\n    <VWindow showArrows>\n      <VWindowItem>\n        <div class=\"bg-grey d-flex justify-center align-center\">\n          <h1>1. foo</h1>\n        </div>\n      </VWindowItem>\n      <VWindowItem>\n        <div class=\"bg-grey d-flex justify-center align-center\">\n          <h1>2. bar</h1>\n        </div>\n      </VWindowItem>\n    </VWindow>\n  ),\n  Vertical: (\n    <VWindow direction=\"vertical\" verticalArrows=\"right\" continuous showArrows>\n      <VWindowItem value=\"one\">\n        <div class=\"bg-grey d-flex justify-center align-center py-16\">\n          <h1>1. foo</h1>\n        </div>\n      </VWindowItem>\n      <VWindowItem value=\"two\">\n        <div class=\"bg-grey d-flex justify-center align-center py-16\">\n          <h1>2. bar</h1>\n        </div>\n      </VWindowItem>\n    </VWindow>\n  ),\n}\n\ndescribe('VWindow', () => {\n  it('should have clickable arrows', async () => {\n    render(() => (\n      <VWindow showArrows>\n        <VWindowItem>\n          <div class=\"bg-grey d-flex justify-center align-center\">\n            <h1>1. foo</h1>\n          </div>\n        </VWindowItem>\n        <VWindowItem>\n          <div class=\"bg-grey d-flex justify-center align-center\">\n            <h1>2. bar</h1>\n          </div>\n        </VWindowItem>\n        <VWindowItem>\n          <div class=\"bg-grey d-flex justify-center align-center\">\n            <h1>3. baz</h1>\n          </div>\n        </VWindowItem>\n      </VWindow>\n    ))\n\n    await commands.waitStable('.v-window')\n\n    let arrows = screen.getAllByCSS('.v-window__controls > .v-btn')\n    expect(arrows).toHaveLength(1)\n    await userEvent.click(arrows[0])\n    arrows = screen.getAllByCSS('.v-window__controls > .v-btn')\n    expect(arrows).toHaveLength(2)\n    await userEvent.click(arrows[1])\n    arrows = screen.getAllByCSS('.v-window__controls > .v-btn')\n    expect(arrows).toHaveLength(1)\n  })\n\n  it('should not wrap around by default', async () => {\n    render(() => (\n      <VWindow showArrows>\n        <VWindowItem>\n          <div class=\"bg-grey d-flex justify-center align-center\">\n            <h1>1. foo</h1>\n          </div>\n        </VWindowItem>\n        <VWindowItem>\n          <div class=\"bg-grey d-flex justify-center align-center\">\n            <h1>2. bar</h1>\n          </div>\n        </VWindowItem>\n      </VWindow>\n    ))\n\n    await commands.waitStable('.v-window')\n    expect(screen.getByCSS('.v-window-item--active h1')).toHaveTextContent('1. foo')\n\n    let arrows = screen.getAllByCSS('.v-window__controls > .v-btn')\n    expect(arrows).toHaveLength(1)\n    await userEvent.click(arrows[0])\n\n    expect(screen.getByCSS('.v-window-item--active h1')).toHaveTextContent('2. bar')\n\n    arrows = screen.getAllByCSS('.v-window__controls > .v-btn')\n    expect(arrows).toHaveLength(1)\n    await userEvent.click(arrows[0])\n\n    expect(screen.getByCSS('.v-window-item--active h1')).toHaveTextContent('1. foo')\n  })\n\n  it('should wrap around when using continuous prop', async () => {\n    render(() => (\n      <VWindow showArrows continuous>\n        <VWindowItem>\n          <div class=\"bg-grey d-flex justify-center align-center\">\n            <h1>1. foo</h1>\n          </div>\n        </VWindowItem>\n        <VWindowItem>\n          <div class=\"bg-grey d-flex justify-center align-center\">\n            <h1>2. bar</h1>\n          </div>\n        </VWindowItem>\n      </VWindow>\n    ))\n\n    await commands.waitStable('.v-window')\n    expect(screen.getByCSS('.v-window-item--active h1')).toHaveTextContent('1. foo')\n    await userEvent.click(screen.getAllByCSS('.v-window__controls > .v-btn')[0])\n    expect(screen.getByCSS('.v-window-item--active h1')).toHaveTextContent('2. bar')\n    await userEvent.click(screen.getAllByCSS('.v-window__controls > .v-btn')[1])\n    expect(screen.getByCSS('.v-window-item--active h1')).toHaveTextContent('1. foo')\n  })\n\n  it('should emit new value when clicking arrows', async () => {\n    const values: string[] = []\n    render(() => (\n      <VWindow showArrows modelValue=\"two\" onUpdate:modelValue={ (v: string) => values.push(v) }>\n        <VWindowItem value=\"one\">\n          <div class=\"bg-grey d-flex justify-center align-center\">\n            <h1>1. foo</h1>\n          </div>\n        </VWindowItem>\n        <VWindowItem value=\"two\">\n          <div class=\"bg-grey d-flex justify-center align-center\">\n            <h1>2. bar</h1>\n          </div>\n        </VWindowItem>\n        <VWindowItem value=\"three\">\n          <div class=\"bg-grey d-flex justify-center align-center\">\n            <h1>3. baz</h1>\n          </div>\n        </VWindowItem>\n      </VWindow>\n    ))\n\n    await userEvent.click(screen.getAllByCSS('.v-window__controls > .v-btn')[0])\n    await userEvent.click(screen.getAllByCSS('.v-window__controls > .v-btn')[1])\n    expect(values).toEqual(['one', 'three'])\n  })\n\n  it('should support touch control', async () => {\n    await page.viewport(500, 300)\n\n    render(() => (\n      <VWindow>\n        <VWindowItem value=\"one\">\n          <div class=\"bg-grey d-flex justify-center align-center\">\n            <h1>1. foo</h1>\n          </div>\n        </VWindowItem>\n        <VWindowItem value=\"two\">\n          <div class=\"bg-grey d-flex justify-center align-center\">\n            <h1>2. bar</h1>\n          </div>\n        </VWindowItem>\n      </VWindow>\n    ))\n\n    await commands.waitStable('.v-window')\n    expect(screen.getByCSS('.v-window-item--active h1')).toHaveTextContent('1. foo')\n\n    await commands.drag([200, 15], [50, 15])\n    await commands.waitStable('.v-window')\n    expect(screen.getByCSS('.v-window-item--active h1')).toHaveTextContent('2. bar')\n\n    await commands.drag([50, 15], [200, 15])\n    await commands.waitStable('.v-window')\n    expect(screen.getByCSS('.v-window-item--active h1')).toHaveTextContent('1. foo')\n  })\n\n  it('should skip disabled items', async () => {\n    render(() => (\n      <VWindow showArrows>\n        <VWindowItem value=\"one\">\n          <div class=\"bg-grey d-flex justify-center align-center\">\n            <h1>1. foo</h1>\n          </div>\n        </VWindowItem>\n        <VWindowItem value=\"two\" disabled>\n          <div class=\"bg-grey d-flex justify-center align-center\">\n            <h1>2. bar</h1>\n          </div>\n        </VWindowItem>\n        <VWindowItem value=\"three\">\n          <div class=\"bg-grey d-flex justify-center align-center\">\n            <h1>3. baz</h1>\n          </div>\n        </VWindowItem>\n      </VWindow>\n    ))\n\n    await commands.waitStable('.v-window')\n    const arrows = screen.getAllByCSS('.v-window__controls > .v-btn')\n    await userEvent.click(arrows[0])\n    expect(screen.getByCSS('.v-window-item--active h1')).toHaveTextContent('3. baz')\n  })\n\n  it('should disable touch support', async () => {\n    await page.viewport(500, 300)\n\n    render(() => (\n      <VWindow touch={ false }>\n        <VWindowItem value=\"one\">\n          <div class=\"bg-grey d-flex justify-center align-center\">\n            <h1>1. foo</h1>\n          </div>\n        </VWindowItem>\n        <VWindowItem value=\"two\">\n          <div class=\"bg-grey d-flex justify-center align-center\">\n            <h1>1. bar</h1>\n          </div>\n        </VWindowItem>\n      </VWindow>\n    ))\n\n    await commands.drag([200, 15], [50, 15])\n    await commands.waitStable('.v-window')\n    expect(screen.getByCSS('.v-window-item--active h1')).toHaveTextContent('1. foo')\n  })\n\n  describe('keyboard controls', () => {\n    it('should support horizontal keyboard navigation', async () => {\n      const model = ref(1)\n\n      render(() => (\n        <VWindow v-model={ model.value } showArrows continuous>\n          <VWindowItem value={ 1 }>\n            <div class=\"bg-grey d-flex justify-center align-center\">\n              <h1>1. foo</h1>\n            </div>\n          </VWindowItem>\n          <VWindowItem value={ 2 }>\n            <div class=\"bg-grey d-flex justify-center align-center\">\n              <h1>2. bar</h1>\n            </div>\n          </VWindowItem>\n          <VWindowItem value={ 3 }>\n            <div class=\"bg-grey d-flex justify-center align-center\">\n              <h1>3. baz</h1>\n            </div>\n          </VWindowItem>\n        </VWindow>\n      ))\n\n      await commands.waitStable('.v-window')\n      const button = screen.getAllByCSS('.v-window__controls > .v-btn')[0]\n      await button.focus()\n\n      await userEvent.keyboard('{ArrowUp}')\n      expect(model.value).toBe(1)\n      await userEvent.keyboard('{ArrowRight}')\n      expect(model.value).toBe(2)\n      await userEvent.keyboard('{ArrowLeft}')\n      expect(model.value).toBe(1)\n      await userEvent.keyboard('{ArrowLeft}')\n      expect(model.value).toBe(3)\n      await userEvent.keyboard('{ArrowRight}')\n      expect(model.value).toBe(1)\n    })\n\n    it('should support vertical keyboard navigation', async () => {\n      const model = ref(1)\n\n      render(() => (\n        <VWindow v-model={ model.value } showArrows continuous direction=\"vertical\">\n          <VWindowItem value={ 1 }>\n            <div class=\"bg-grey d-flex justify-center align-center\">\n              <h1>1. foo</h1>\n            </div>\n          </VWindowItem>\n          <VWindowItem value={ 2 }>\n            <div class=\"bg-grey d-flex justify-center align-center\">\n              <h1>2. bar</h1>\n            </div>\n          </VWindowItem>\n          <VWindowItem value={ 3 }>\n            <div class=\"bg-grey d-flex justify-center align-center\">\n              <h1>3. baz</h1>\n            </div>\n          </VWindowItem>\n        </VWindow>\n      ))\n\n      await commands.waitStable('.v-window')\n      const button = screen.getAllByCSS('.v-window__controls > .v-btn')[0]\n      await button.focus()\n\n      await userEvent.keyboard('{ArrowLeft}')\n      expect(model.value).toBe(1)\n      await userEvent.keyboard('{ArrowDown}')\n      expect(model.value).toBe(2)\n      await userEvent.keyboard('{ArrowUp}')\n      expect(model.value).toBe(1)\n      await userEvent.keyboard('{ArrowUp}')\n      expect(model.value).toBe(3)\n      await userEvent.keyboard('{ArrowDown}')\n      expect(model.value).toBe(1)\n    })\n  })\n\n  showcase({ stories })\n})\n"
  },
  {
    "path": "packages/vuetify/src/components/VWindow/_variables.scss",
    "content": "@use '../../styles/settings';\n\n// VWindow\n$window-transition: .3s cubic-bezier(.25, .8, .50, 1) !default;\n$window-controls-padding: 0 16px !default;\n$window-controls-vertical-gap: 12px !default;\n$window-crossfade-blend-mode: plus-lighter !default;\n"
  },
  {
    "path": "packages/vuetify/src/components/VWindow/index.ts",
    "content": "export { VWindow } from './VWindow'\nexport { VWindowItem } from './VWindowItem'\n"
  },
  {
    "path": "packages/vuetify/src/components/index.ts",
    "content": "export * from './VApp'\nexport * from './VAppBar'\nexport * from './VAlert'\nexport * from './VAutocomplete'\nexport * from './VAvatar'\nexport * from './VBadge'\nexport * from './VBanner'\nexport * from './VBottomNavigation'\nexport * from './VBottomSheet'\nexport * from './VBreadcrumbs'\nexport * from './VBtn'\nexport * from './VBtnGroup'\nexport * from './VBtnToggle'\nexport * from './VCalendar'\nexport * from './VCard'\nexport * from './VCarousel'\nexport * from './VCheckbox'\nexport * from './VChip'\nexport * from './VChipGroup'\nexport * from './VCode'\nexport * from './VColorPicker'\nexport * from './VCombobox'\nexport * from './VConfirmEdit'\nexport * from './VCounter'\nexport * from './VDataIterator'\nexport * from './VDataTable'\nexport * from './VDatePicker'\nexport * from './VDefaultsProvider'\nexport * from './VDialog'\nexport * from './VDivider'\nexport * from './VEmptyState'\nexport * from './VExpansionPanel'\nexport * from './VFab'\nexport * from './VField'\nexport * from './VFileInput'\nexport * from './VFooter'\nexport * from './VForm'\nexport * from './VGrid'\nexport * from './VHotkey'\nexport * from './VHover'\nexport * from './VIcon'\nexport * from './VImg'\nexport * from './VInfiniteScroll'\nexport * from './VInput'\nexport * from './VItemGroup'\nexport * from './VKbd'\nexport * from './VLabel'\nexport * from './VLayout'\nexport * from './VLazy'\nexport * from './VList'\nexport * from './VLocaleProvider'\nexport * from './VMain'\nexport * from './VMenu'\nexport * from './VMessages'\nexport * from './VNavigationDrawer'\nexport * from './VNoSsr'\nexport * from './VNumberInput'\nexport * from './VOtpInput'\n// export * from './VOverflowBtn'\nexport * from './VOverlay'\nexport * from './VPagination'\nexport * from './VParallax'\n// export * from './VPie'\nexport * from './VProgressCircular'\nexport * from './VProgressLinear'\nexport * from './VRadio'\nexport * from './VRadioGroup'\nexport * from './VRangeSlider'\nexport * from './VRating'\nexport * from './VResponsive'\nexport * from './VSelect'\nexport * from './VSelectionControl'\nexport * from './VSelectionControlGroup'\nexport * from './VSheet'\nexport * from './VSkeletonLoader'\nexport * from './VSlideGroup'\nexport * from './VSlider'\nexport * from './VSnackbar'\nexport * from './VSnackbarQueue'\nexport * from './VSparkline'\nexport * from './VSpeedDial'\nexport * from './VStepper'\nexport * from './VSwitch'\nexport * from './VSystemBar'\nexport * from './VTabs'\nexport * from './VTable'\nexport * from './VTextarea'\nexport * from './VTextField'\nexport * from './VThemeProvider'\nexport * from './VTimeline'\nexport * from './VTimePicker'\nexport * from './VToolbar'\nexport * from './VTooltip'\nexport * from './VTreeview'\nexport * from './VValidation'\n// export * from './VVideo'\nexport * from './VVirtualScroll'\nexport * from './VWindow'\nexport * from './transitions'\n"
  },
  {
    "path": "packages/vuetify/src/components/transitions/createTransition.ts",
    "content": "// Utilities\nimport { h, Transition, TransitionGroup } from 'vue'\nimport { genericComponent, PREFERS_REDUCED_MOTION, propsFactory } from '@/util'\n\n// Types\nimport type { FunctionalComponent, PropType } from 'vue'\n\nexport const makeTransitionProps = propsFactory({\n  disabled: Boolean,\n  group: Boolean,\n  hideOnLeave: Boolean,\n  leaveAbsolute: Boolean,\n  mode: String,\n  origin: String,\n}, 'transition')\n\nexport function createCssTransition (\n  name: string,\n  origin?: string,\n  mode?: string\n) {\n  return genericComponent()({\n    name,\n\n    props: makeTransitionProps({\n      mode,\n      origin,\n    }),\n\n    setup (props, { slots }) {\n      const functions = {\n        onBeforeEnter (el: HTMLElement) {\n          if (props.origin) {\n            el.style.transformOrigin = props.origin\n          }\n        },\n        onLeave (el: HTMLElement) {\n          if (props.leaveAbsolute) {\n            const { offsetTop, offsetLeft, offsetWidth, offsetHeight } = el\n            el._transitionInitialStyles = {\n              position: el.style.position,\n              top: el.style.top,\n              left: el.style.left,\n              width: el.style.width,\n              height: el.style.height,\n            }\n            el.style.position = 'absolute'\n            el.style.top = `${offsetTop}px`\n            el.style.left = `${offsetLeft}px`\n            el.style.width = `${offsetWidth}px`\n            el.style.height = `${offsetHeight}px`\n          }\n\n          if (props.hideOnLeave) {\n            el.style.setProperty('display', 'none', 'important')\n          }\n        },\n        onAfterLeave (el: HTMLElement) {\n          if (props.leaveAbsolute && el?._transitionInitialStyles) {\n            const { position, top, left, width, height } = el._transitionInitialStyles\n            delete el._transitionInitialStyles\n            el.style.position = position || ''\n            el.style.top = top || ''\n            el.style.left = left || ''\n            el.style.width = width || ''\n            el.style.height = height || ''\n          }\n        },\n      }\n\n      return () => {\n        const tag = props.group ? TransitionGroup : Transition\n\n        return h(tag as FunctionalComponent, {\n          name: props.disabled ? '' : name,\n          css: !props.disabled,\n          ...(props.group ? undefined : { mode: props.mode }),\n          ...(props.disabled ? {} : functions),\n        }, slots.default)\n      }\n    },\n  })\n}\n\nexport function createJavascriptTransition (\n  name: string,\n  functions: Record<string, any>,\n  mode = 'in-out'\n) {\n  return genericComponent()({\n    name,\n\n    props: {\n      mode: {\n        type: String as PropType<'in-out' | 'out-in' | 'default'>,\n        default: mode,\n      },\n      disabled: {\n        type: Boolean,\n        default: PREFERS_REDUCED_MOTION(),\n      },\n      group: Boolean,\n      hideOnLeave: Boolean,\n    },\n\n    setup (props, { slots }) {\n      const tag = props.group ? TransitionGroup : Transition\n\n      return () => {\n        return h(tag as FunctionalComponent, {\n          name: props.disabled ? '' : name,\n          css: !props.disabled,\n          // mode: props.mode, // TODO: vuejs/vue-next#3104\n          ...(props.disabled ? {} : {\n            ...functions,\n            onLeave: (el: HTMLElement) => {\n              if (props.hideOnLeave) {\n                el.style.setProperty('display', 'none', 'important')\n              } else {\n                functions.onLeave?.(el)\n              }\n            },\n          }),\n        }, slots.default)\n      }\n    },\n  })\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/transitions/dialog-transition.tsx",
    "content": "// Utilities\nimport { Transition } from 'vue'\nimport {\n  acceleratedEasing,\n  animate,\n  deceleratedEasing,\n  genericComponent,\n  nullifyTransforms,\n  PREFERS_REDUCED_MOTION,\n  propsFactory,\n  standardEasing,\n} from '@/util'\nimport { getTargetBox } from '@/util/box'\n\n// Types\nimport type { PropType } from 'vue'\n\nexport const makeVDialogTransitionProps = propsFactory({\n  target: [Object, Array] as PropType<HTMLElement | [x: number, y: number]>,\n}, 'v-dialog-transition')\n\nconst saved = new WeakMap<Element, Dimensions>()\n\nexport const VDialogTransition = genericComponent()({\n  name: 'VDialogTransition',\n\n  props: makeVDialogTransitionProps(),\n\n  setup (props, { slots }) {\n    const functions = {\n      onBeforeEnter (el: Element) {\n        (el as HTMLElement).style.pointerEvents = 'none'\n        ;(el as HTMLElement).style.visibility = 'hidden'\n      },\n      async onEnter (el: Element, done: () => void) {\n        await new Promise(resolve => requestAnimationFrame(resolve))\n        await new Promise(resolve => requestAnimationFrame(resolve))\n        ;(el as HTMLElement).style.visibility = ''\n\n        const dimensions = getDimensions(props.target!, el as HTMLElement)\n        const { x, y, sx, sy, speed } = dimensions\n        saved.set(el, dimensions)\n\n        if (PREFERS_REDUCED_MOTION()) {\n          animate(el, [\n            { opacity: 0 },\n            {},\n          ], {\n            duration: 125 * speed,\n            easing: deceleratedEasing,\n          }).finished.then(() => done())\n        } else {\n          const animation = animate(el, [\n            { transform: `translate(${x}px, ${y}px) scale(${sx}, ${sy})`, opacity: 0 },\n            {},\n          ], {\n            duration: 225 * speed,\n            easing: deceleratedEasing,\n          })\n          getChildren(el)?.forEach(el => {\n            animate(el, [\n              { opacity: 0 },\n              { opacity: 0, offset: 0.33 },\n              {},\n            ], {\n              duration: 225 * 2 * speed,\n              easing: standardEasing,\n            })\n          })\n          animation.finished.then(() => done())\n        }\n      },\n      onAfterEnter (el: Element) {\n        (el as HTMLElement).style.removeProperty('pointer-events')\n      },\n      onBeforeLeave (el: Element) {\n        (el as HTMLElement).style.pointerEvents = 'none'\n      },\n      async onLeave (el: Element, done: () => void) {\n        await new Promise(resolve => requestAnimationFrame(resolve))\n\n        let dimensions\n        if (\n          !saved.has(el) ||\n          Array.isArray(props.target) ||\n          props.target!.offsetParent ||\n          props.target!.getClientRects().length\n        ) {\n          dimensions = getDimensions(props.target!, el as HTMLElement)\n        } else {\n          dimensions = saved.get(el)!\n        }\n        const { x, y, sx, sy, speed } = dimensions\n\n        if (PREFERS_REDUCED_MOTION()) {\n          animate(el, [\n            {},\n            { opacity: 0 },\n          ], {\n            duration: 85 * speed,\n            easing: acceleratedEasing,\n          }).finished.then(() => done())\n        } else {\n          const animation = animate(el, [\n            {},\n            { transform: `translate(${x}px, ${y}px) scale(${sx}, ${sy})`, opacity: 0 },\n          ], {\n            duration: 125 * speed,\n            easing: acceleratedEasing,\n          })\n          animation.finished.then(() => done())\n          getChildren(el)?.forEach(el => {\n            animate(el, [\n              {},\n              { opacity: 0, offset: 0.2 },\n              { opacity: 0 },\n            ], {\n              duration: 125 * 2 * speed,\n              easing: standardEasing,\n            })\n          })\n        }\n      },\n      onAfterLeave (el: Element) {\n        (el as HTMLElement).style.removeProperty('pointer-events')\n      },\n    }\n\n    return () => {\n      return props.target\n        ? (\n          <Transition\n            name=\"dialog-transition\"\n            { ...functions }\n            css={ false }\n            v-slots={ slots }\n          />\n        )\n        : <Transition name=\"dialog-transition\" v-slots={ slots } />\n    }\n  },\n})\n\n/** Animatable children (card, sheet, list) */\nfunction getChildren (el: Element) {\n  const els = el.querySelector(':scope > .v-card, :scope > .v-sheet, :scope > .v-list')?.children\n  return els && [...els]\n}\n\ntype Dimensions = {\n  x: number\n  y: number\n  sx: number\n  sy: number\n  speed: number\n}\n\nfunction getDimensions (target: HTMLElement | [x: number, y: number], el: HTMLElement): Dimensions {\n  const targetBox = getTargetBox(target)\n  const elBox = nullifyTransforms(el)\n  const [originX, originY] = getComputedStyle(el).transformOrigin.split(' ').map(v => parseFloat(v))\n\n  const [anchorSide, anchorOffset] = getComputedStyle(el).getPropertyValue('--v-overlay-anchor-origin').split(' ')\n\n  let offsetX = targetBox.left + targetBox.width / 2\n  if (anchorSide === 'left' || anchorOffset === 'left') {\n    offsetX -= targetBox.width / 2\n  } else if (anchorSide === 'right' || anchorOffset === 'right') {\n    offsetX += targetBox.width / 2\n  }\n\n  let offsetY = targetBox.top + targetBox.height / 2\n  if (anchorSide === 'top' || anchorOffset === 'top') {\n    offsetY -= targetBox.height / 2\n  } else if (anchorSide === 'bottom' || anchorOffset === 'bottom') {\n    offsetY += targetBox.height / 2\n  }\n\n  const tsx = targetBox.width / elBox.width\n  const tsy = targetBox.height / elBox.height\n  const maxs = Math.max(1, tsx, tsy)\n  const sx = tsx / maxs || 0\n  const sy = tsy / maxs || 0\n\n  // Animate elements larger than 12% of the screen area up to 1.5x slower\n  const asa = (elBox.width * elBox.height) / (window.innerWidth * window.innerHeight)\n  const speed = asa > 0.12\n    ? Math.min(1.5, (asa - 0.12) * 10 + 1)\n    : 1\n\n  return {\n    x: offsetX - (originX + elBox.left),\n    y: offsetY - (originY + elBox.top),\n    sx,\n    sy,\n    speed,\n  }\n}\n\nexport type VDialogTransition = InstanceType<typeof VDialogTransition>\n"
  },
  {
    "path": "packages/vuetify/src/components/transitions/expand-transition.ts",
    "content": "interface HTMLExpandElement extends HTMLElement {\n  _parent?: (Node & ParentNode & HTMLElement) | null\n  _initialStyle?: {\n    transition: string\n    overflow: string\n    height?: string | null\n    width?: string | null\n  }\n}\n\nexport default function (expandedParentClass = '', type: 'x' | 'y' | 'both' = 'y') {\n  return {\n    onBeforeEnter (el: HTMLExpandElement) {\n      el._parent = el.parentNode as (Node & ParentNode & HTMLElement) | null\n      el._initialStyle = {\n        transition: el.style.transition,\n        overflow: el.style.overflow,\n        width: el.style.width,\n        height: el.style.height,\n      }\n    },\n\n    onEnter (el: HTMLExpandElement) {\n      const initialStyle = el._initialStyle\n      if (!initialStyle) return\n\n      el.style.setProperty('transition', 'none', 'important')\n      // Hide overflow to account for collapsed margins in the calculated height\n      el.style.overflow = 'hidden'\n      const offsetWidth = `${el.offsetWidth}px`\n      const offsetHeight = `${el.offsetHeight}px`\n\n      if (['x', 'both'].includes(type)) el.style.width = '0'\n      if (['y', 'both'].includes(type)) el.style.height = '0'\n\n      void el.offsetHeight // force reflow\n\n      el.style.transition = initialStyle.transition\n\n      if (expandedParentClass && el._parent) {\n        el._parent.classList.add(expandedParentClass)\n      }\n\n      requestAnimationFrame(() => {\n        if (['x', 'both'].includes(type)) el.style.width = offsetWidth\n        if (['y', 'both'].includes(type)) el.style.height = offsetHeight\n      })\n    },\n\n    onAfterEnter: resetStyles,\n    onEnterCancelled: resetStyles,\n\n    onLeave (el: HTMLExpandElement) {\n      el._initialStyle = {\n        transition: '',\n        overflow: el.style.overflow,\n        width: el.style.width,\n        height: el.style.height,\n      }\n\n      el.style.overflow = 'hidden'\n      if (['x', 'both'].includes(type)) el.style.width = `${el.offsetWidth}px`\n      if (['y', 'both'].includes(type)) el.style.height = `${el.offsetHeight}px`\n      void el.offsetHeight // force reflow\n\n      requestAnimationFrame(() => {\n        if (['x', 'both'].includes(type)) el.style.width = '0'\n        if (['y', 'both'].includes(type)) el.style.height = '0'\n      })\n    },\n\n    onAfterLeave,\n    onLeaveCancelled: onAfterLeave,\n  }\n\n  function onAfterLeave (el: HTMLExpandElement) {\n    if (expandedParentClass && el._parent) {\n      el._parent.classList.remove(expandedParentClass)\n    }\n    resetStyles(el)\n  }\n\n  function resetStyles (el: HTMLExpandElement) {\n    if (!el._initialStyle) return\n\n    const { width: w, height: h } = el._initialStyle\n    el.style.overflow = el._initialStyle.overflow\n    if (w != null && ['x', 'both'].includes(type)) el.style.width = w\n    if (h != null && ['y', 'both'].includes(type)) el.style.height = h\n    delete el._initialStyle\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/components/transitions/index.ts",
    "content": "import {\n  createCssTransition,\n  createJavascriptTransition,\n} from './createTransition'\n\nimport ExpandTransitionGenerator from './expand-transition'\n\n// Component specific transitions\nexport const VFabTransition = createCssTransition('fab-transition', 'center center', 'out-in')\n\n// Generic transitions\nexport const VDialogBottomTransition = createCssTransition('dialog-bottom-transition')\nexport const VDialogTopTransition = createCssTransition('dialog-top-transition')\nexport const VFadeTransition = createCssTransition('fade-transition')\nexport const VScaleTransition = createCssTransition('scale-transition')\nexport const VScrollXTransition = createCssTransition('scroll-x-transition')\nexport const VScrollXReverseTransition = createCssTransition('scroll-x-reverse-transition')\nexport const VScrollYTransition = createCssTransition('scroll-y-transition')\nexport const VScrollYReverseTransition = createCssTransition('scroll-y-reverse-transition')\nexport const VSlideXTransition = createCssTransition('slide-x-transition')\nexport const VSlideXReverseTransition = createCssTransition('slide-x-reverse-transition')\nexport const VSlideYTransition = createCssTransition('slide-y-transition')\nexport const VSlideYReverseTransition = createCssTransition('slide-y-reverse-transition')\n\n// Javascript transitions\nexport const VExpandTransition = createJavascriptTransition('expand-transition', ExpandTransitionGenerator())\nexport const VExpandXTransition = createJavascriptTransition('expand-x-transition', ExpandTransitionGenerator('', 'x'))\nexport const VExpandBothTransition = createJavascriptTransition('expand-both-transition', ExpandTransitionGenerator('', 'both'))\n\nexport { VDialogTransition } from './dialog-transition'\n\nexport type VFabTransition = InstanceType<typeof VFabTransition>\nexport type VDialogBottomTransition = InstanceType<typeof VDialogBottomTransition>\nexport type VDialogTopTransition = InstanceType<typeof VDialogTopTransition>\nexport type VFadeTransition = InstanceType<typeof VFadeTransition>\nexport type VScaleTransition = InstanceType<typeof VScaleTransition>\nexport type VScrollXTransition = InstanceType<typeof VScrollXTransition>\nexport type VScrollXReverseTransition = InstanceType<typeof VScrollXReverseTransition>\nexport type VScrollYTransition = InstanceType<typeof VScrollYTransition>\nexport type VScrollYReverseTransition = InstanceType<typeof VScrollYReverseTransition>\nexport type VSlideXTransition = InstanceType<typeof VSlideXTransition>\nexport type VSlideXReverseTransition = InstanceType<typeof VSlideXReverseTransition>\nexport type VSlideYTransition = InstanceType<typeof VSlideYTransition>\nexport type VSlideYReverseTransition = InstanceType<typeof VSlideYReverseTransition>\nexport type VExpandTransition = InstanceType<typeof VExpandTransition>\nexport type VExpandXTransition = InstanceType<typeof VExpandXTransition>\n"
  },
  {
    "path": "packages/vuetify/src/composables/__tests__/__snapshots__/group.spec.ts.snap",
    "content": "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html\n\nexports[`group > with complex values > should accept new value 1`] = `\n\"<div>\n  <div class=\"\">{\"foo\":1}</div>\n  <div class=\"\">{\"bar\":2}</div>\n</div>\"\n`;\n\nexports[`group > with complex values > should accept new value 2`] = `\n\"<div>\n  <div class=\"selected\">{\"foo\":1}</div>\n  <div class=\"\">{\"bar\":2}</div>\n</div>\"\n`;\n\nexports[`group > with complex values > should emit selected value 1`] = `\n\"<div>\n  <div class=\"\">{\"foo\":1}</div>\n  <div class=\"selected\">{\"bar\":2}</div>\n</div>\"\n`;\n\nexports[`group > with explicit values > should emit new selection 1`] = `\n\"<div>\n  <div class=\"selected\">one</div>\n  <div class=\"\">two</div>\n</div>\"\n`;\n\nexports[`group > with explicit values > should not emit new selection if clicking disabled item 1`] = `\n\"<div>\n  <div class=\"\">one</div>\n  <div class=\"\">two</div>\n</div>\"\n`;\n\nexports[`group > with implicit values > should emit new selection 1`] = `\n\"<div>\n  <div class=\"selected\"></div>\n  <div class=\"\"></div>\n</div>\"\n`;\n\nexports[`group > with implicit values > should set first non-disabled item as value when forced mandatory 1`] = `\n\"<div>\n  <div class=\"\"></div>\n  <div class=\"selected\"></div>\n</div>\"\n`;\n"
  },
  {
    "path": "packages/vuetify/src/composables/__tests__/__snapshots__/theme.spec.ts.snap",
    "content": "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html\n\nexports[`createTheme > should allow for themes to be scoped 1`] = `\n<head>\n  <style\n    id=\"custom-vuetify-stylesheet-id\"\n    type=\"text/css\"\n  >\n    @layer vuetify-utilities {\n  @layer theme-base {\n  :root {\n    --v-theme-background: 255,255,255;\n    --v-theme-background-overlay-multiplier: 1;\n    --v-theme-surface: 255,255,255;\n    --v-theme-surface-overlay-multiplier: 1;\n    --v-theme-surface-bright: 255,255,255;\n    --v-theme-surface-bright-overlay-multiplier: 1;\n    --v-theme-surface-light: 238,238,238;\n    --v-theme-surface-light-overlay-multiplier: 1;\n    --v-theme-surface-variant: 66,66,66;\n    --v-theme-surface-variant-overlay-multiplier: 2;\n    --v-theme-on-surface-variant: 238,238,238;\n    --v-theme-primary: 24,103,192;\n    --v-theme-primary-overlay-multiplier: 2;\n    --v-theme-primary-darken-1: 31,85,146;\n    --v-theme-primary-darken-1-overlay-multiplier: 2;\n    --v-theme-secondary: 72,169,166;\n    --v-theme-secondary-overlay-multiplier: 1;\n    --v-theme-secondary-darken-1: 1,135,134;\n    --v-theme-secondary-darken-1-overlay-multiplier: 1;\n    --v-theme-error: 176,0,32;\n    --v-theme-error-overlay-multiplier: 2;\n    --v-theme-info: 33,150,243;\n    --v-theme-info-overlay-multiplier: 1;\n    --v-theme-success: 76,175,80;\n    --v-theme-success-overlay-multiplier: 1;\n    --v-theme-warning: 251,140,0;\n    --v-theme-warning-overlay-multiplier: 1;\n    --v-theme-on-background: 0,0,0;\n    --v-theme-on-surface: 0,0,0;\n    --v-theme-on-surface-bright: 0,0,0;\n    --v-theme-on-surface-light: 0,0,0;\n    --v-theme-on-primary: 255,255,255;\n    --v-theme-on-primary-darken-1: 255,255,255;\n    --v-theme-on-secondary: 255,255,255;\n    --v-theme-on-secondary-darken-1: 255,255,255;\n    --v-theme-on-error: 255,255,255;\n    --v-theme-on-info: 255,255,255;\n    --v-theme-on-success: 255,255,255;\n    --v-theme-on-warning: 255,255,255;\n    --v-border-color: 0, 0, 0;\n    --v-border-opacity: 0.12;\n    --v-shadow-color: 0, 0, 0;\n    --v-high-emphasis-opacity: 0.87;\n    --v-medium-emphasis-opacity: 0.6;\n    --v-disabled-opacity: 0.38;\n    --v-idle-opacity: 0.04;\n    --v-hover-opacity: 0.04;\n    --v-focus-opacity: 0.12;\n    --v-selected-opacity: 0.08;\n    --v-activated-opacity: 0.12;\n    --v-pressed-opacity: 0.12;\n    --v-dragged-opacity: 0.08;\n    --v-theme-kbd: 238, 238, 238;\n    --v-theme-on-kbd: 0, 0, 0;\n    --v-theme-code: 245, 245, 245;\n    --v-theme-on-code: 0, 0, 0;\n    --v-theme-on-dark: 255, 255, 255;\n    --v-theme-on-light: 0, 0, 0;\n    --v-elevation-overlay-color: black;\n    --v-elevation-overlay-opacity-step: 2%;\n  }\n  .v-theme--light {\n    color-scheme: normal;\n    --v-theme-background: 255,255,255;\n    --v-theme-background-overlay-multiplier: 1;\n    --v-theme-surface: 255,255,255;\n    --v-theme-surface-overlay-multiplier: 1;\n    --v-theme-surface-bright: 255,255,255;\n    --v-theme-surface-bright-overlay-multiplier: 1;\n    --v-theme-surface-light: 238,238,238;\n    --v-theme-surface-light-overlay-multiplier: 1;\n    --v-theme-surface-variant: 66,66,66;\n    --v-theme-surface-variant-overlay-multiplier: 2;\n    --v-theme-on-surface-variant: 238,238,238;\n    --v-theme-primary: 24,103,192;\n    --v-theme-primary-overlay-multiplier: 2;\n    --v-theme-primary-darken-1: 31,85,146;\n    --v-theme-primary-darken-1-overlay-multiplier: 2;\n    --v-theme-secondary: 72,169,166;\n    --v-theme-secondary-overlay-multiplier: 1;\n    --v-theme-secondary-darken-1: 1,135,134;\n    --v-theme-secondary-darken-1-overlay-multiplier: 1;\n    --v-theme-error: 176,0,32;\n    --v-theme-error-overlay-multiplier: 2;\n    --v-theme-info: 33,150,243;\n    --v-theme-info-overlay-multiplier: 1;\n    --v-theme-success: 76,175,80;\n    --v-theme-success-overlay-multiplier: 1;\n    --v-theme-warning: 251,140,0;\n    --v-theme-warning-overlay-multiplier: 1;\n    --v-theme-on-background: 0,0,0;\n    --v-theme-on-surface: 0,0,0;\n    --v-theme-on-surface-bright: 0,0,0;\n    --v-theme-on-surface-light: 0,0,0;\n    --v-theme-on-primary: 255,255,255;\n    --v-theme-on-primary-darken-1: 255,255,255;\n    --v-theme-on-secondary: 255,255,255;\n    --v-theme-on-secondary-darken-1: 255,255,255;\n    --v-theme-on-error: 255,255,255;\n    --v-theme-on-info: 255,255,255;\n    --v-theme-on-success: 255,255,255;\n    --v-theme-on-warning: 255,255,255;\n    --v-border-color: 0, 0, 0;\n    --v-border-opacity: 0.12;\n    --v-shadow-color: 0, 0, 0;\n    --v-high-emphasis-opacity: 0.87;\n    --v-medium-emphasis-opacity: 0.6;\n    --v-disabled-opacity: 0.38;\n    --v-idle-opacity: 0.04;\n    --v-hover-opacity: 0.04;\n    --v-focus-opacity: 0.12;\n    --v-selected-opacity: 0.08;\n    --v-activated-opacity: 0.12;\n    --v-pressed-opacity: 0.12;\n    --v-dragged-opacity: 0.08;\n    --v-theme-kbd: 238, 238, 238;\n    --v-theme-on-kbd: 0, 0, 0;\n    --v-theme-code: 245, 245, 245;\n    --v-theme-on-code: 0, 0, 0;\n    --v-theme-on-dark: 255, 255, 255;\n    --v-theme-on-light: 0, 0, 0;\n    --v-elevation-overlay-color: black;\n    --v-elevation-overlay-opacity-step: 2%;\n  }\n  .v-theme--dark {\n    color-scheme: dark;\n    --v-theme-background: 18,18,18;\n    --v-theme-background-overlay-multiplier: 1;\n    --v-theme-surface: 33,33,33;\n    --v-theme-surface-overlay-multiplier: 1;\n    --v-theme-surface-bright: 204,191,214;\n    --v-theme-surface-bright-overlay-multiplier: 2;\n    --v-theme-surface-light: 66,66,66;\n    --v-theme-surface-light-overlay-multiplier: 1;\n    --v-theme-surface-variant: 200,200,200;\n    --v-theme-surface-variant-overlay-multiplier: 2;\n    --v-theme-on-surface-variant: 0,0,0;\n    --v-theme-primary: 33,150,243;\n    --v-theme-primary-overlay-multiplier: 2;\n    --v-theme-primary-darken-1: 39,124,193;\n    --v-theme-primary-darken-1-overlay-multiplier: 2;\n    --v-theme-secondary: 84,182,178;\n    --v-theme-secondary-overlay-multiplier: 2;\n    --v-theme-secondary-darken-1: 72,169,166;\n    --v-theme-secondary-darken-1-overlay-multiplier: 2;\n    --v-theme-error: 207,102,121;\n    --v-theme-error-overlay-multiplier: 2;\n    --v-theme-info: 33,150,243;\n    --v-theme-info-overlay-multiplier: 2;\n    --v-theme-success: 76,175,80;\n    --v-theme-success-overlay-multiplier: 2;\n    --v-theme-warning: 251,140,0;\n    --v-theme-warning-overlay-multiplier: 2;\n    --v-theme-on-background: 255,255,255;\n    --v-theme-on-surface: 255,255,255;\n    --v-theme-on-surface-bright: 0,0,0;\n    --v-theme-on-surface-light: 255,255,255;\n    --v-theme-on-primary: 255,255,255;\n    --v-theme-on-primary-darken-1: 255,255,255;\n    --v-theme-on-secondary: 255,255,255;\n    --v-theme-on-secondary-darken-1: 255,255,255;\n    --v-theme-on-error: 255,255,255;\n    --v-theme-on-info: 255,255,255;\n    --v-theme-on-success: 255,255,255;\n    --v-theme-on-warning: 255,255,255;\n    --v-border-color: 255, 255, 255;\n    --v-border-opacity: 0.12;\n    --v-shadow-color: 0, 0, 0;\n    --v-high-emphasis-opacity: 1;\n    --v-medium-emphasis-opacity: 0.7;\n    --v-disabled-opacity: 0.5;\n    --v-idle-opacity: 0.1;\n    --v-hover-opacity: 0.04;\n    --v-focus-opacity: 0.12;\n    --v-selected-opacity: 0.08;\n    --v-activated-opacity: 0.12;\n    --v-pressed-opacity: 0.16;\n    --v-dragged-opacity: 0.08;\n    --v-theme-kbd: 66, 66, 66;\n    --v-theme-on-kbd: 255, 255, 255;\n    --v-theme-code: 52, 52, 52;\n    --v-theme-on-code: 204, 204, 204;\n    --v-theme-on-dark: 255, 255, 255;\n    --v-theme-on-light: 0, 0, 0;\n    --v-elevation-overlay-color: white;\n    --v-elevation-overlay-opacity-step: 2%;\n  }\n  }\n  @layer theme-background {\n    .bg-background {\n      --v-theme-overlay-multiplier: var(--v-theme-background-overlay-multiplier);\n      background-color: rgb(var(--v-theme-background));\n      color: rgb(var(--v-theme-on-background));\n    }\n    .bg-surface {\n      --v-theme-overlay-multiplier: var(--v-theme-surface-overlay-multiplier);\n      background-color: rgb(var(--v-theme-surface));\n      color: rgb(var(--v-theme-on-surface));\n    }\n    .bg-surface-bright {\n      --v-theme-overlay-multiplier: var(--v-theme-surface-bright-overlay-multiplier);\n      background-color: rgb(var(--v-theme-surface-bright));\n      color: rgb(var(--v-theme-on-surface-bright));\n    }\n    .bg-surface-light {\n      --v-theme-overlay-multiplier: var(--v-theme-surface-light-overlay-multiplier);\n      background-color: rgb(var(--v-theme-surface-light));\n      color: rgb(var(--v-theme-on-surface-light));\n    }\n    .bg-surface-variant {\n      --v-theme-overlay-multiplier: var(--v-theme-surface-variant-overlay-multiplier);\n      background-color: rgb(var(--v-theme-surface-variant));\n      color: rgb(var(--v-theme-on-surface-variant));\n    }\n    .bg-primary {\n      --v-theme-overlay-multiplier: var(--v-theme-primary-overlay-multiplier);\n      background-color: rgb(var(--v-theme-primary));\n      color: rgb(var(--v-theme-on-primary));\n    }\n    .bg-primary-darken-1 {\n      --v-theme-overlay-multiplier: var(--v-theme-primary-darken-1-overlay-multiplier);\n      background-color: rgb(var(--v-theme-primary-darken-1));\n      color: rgb(var(--v-theme-on-primary-darken-1));\n    }\n    .bg-secondary {\n      --v-theme-overlay-multiplier: var(--v-theme-secondary-overlay-multiplier);\n      background-color: rgb(var(--v-theme-secondary));\n      color: rgb(var(--v-theme-on-secondary));\n    }\n    .bg-secondary-darken-1 {\n      --v-theme-overlay-multiplier: var(--v-theme-secondary-darken-1-overlay-multiplier);\n      background-color: rgb(var(--v-theme-secondary-darken-1));\n      color: rgb(var(--v-theme-on-secondary-darken-1));\n    }\n    .bg-error {\n      --v-theme-overlay-multiplier: var(--v-theme-error-overlay-multiplier);\n      background-color: rgb(var(--v-theme-error));\n      color: rgb(var(--v-theme-on-error));\n    }\n    .bg-info {\n      --v-theme-overlay-multiplier: var(--v-theme-info-overlay-multiplier);\n      background-color: rgb(var(--v-theme-info));\n      color: rgb(var(--v-theme-on-info));\n    }\n    .bg-success {\n      --v-theme-overlay-multiplier: var(--v-theme-success-overlay-multiplier);\n      background-color: rgb(var(--v-theme-success));\n      color: rgb(var(--v-theme-on-success));\n    }\n    .bg-warning {\n      --v-theme-overlay-multiplier: var(--v-theme-warning-overlay-multiplier);\n      background-color: rgb(var(--v-theme-warning));\n      color: rgb(var(--v-theme-on-warning));\n    }\n  }\n  @layer theme-foreground {\n    .text-background {\n      color: rgb(var(--v-theme-background));\n    }\n    .border-background {\n      --v-border-color: var(--v-theme-background);\n    }\n    .text-surface {\n      color: rgb(var(--v-theme-surface));\n    }\n    .border-surface {\n      --v-border-color: var(--v-theme-surface);\n    }\n    .text-surface-bright {\n      color: rgb(var(--v-theme-surface-bright));\n    }\n    .border-surface-bright {\n      --v-border-color: var(--v-theme-surface-bright);\n    }\n    .text-surface-light {\n      color: rgb(var(--v-theme-surface-light));\n    }\n    .border-surface-light {\n      --v-border-color: var(--v-theme-surface-light);\n    }\n    .text-surface-variant {\n      color: rgb(var(--v-theme-surface-variant));\n    }\n    .border-surface-variant {\n      --v-border-color: var(--v-theme-surface-variant);\n    }\n    .on-surface-variant {\n      color: rgb(var(--v-theme-on-surface-variant));\n    }\n    .text-primary {\n      color: rgb(var(--v-theme-primary));\n    }\n    .border-primary {\n      --v-border-color: var(--v-theme-primary);\n    }\n    .text-primary-darken-1 {\n      color: rgb(var(--v-theme-primary-darken-1));\n    }\n    .border-primary-darken-1 {\n      --v-border-color: var(--v-theme-primary-darken-1);\n    }\n    .text-secondary {\n      color: rgb(var(--v-theme-secondary));\n    }\n    .border-secondary {\n      --v-border-color: var(--v-theme-secondary);\n    }\n    .text-secondary-darken-1 {\n      color: rgb(var(--v-theme-secondary-darken-1));\n    }\n    .border-secondary-darken-1 {\n      --v-border-color: var(--v-theme-secondary-darken-1);\n    }\n    .text-error {\n      color: rgb(var(--v-theme-error));\n    }\n    .border-error {\n      --v-border-color: var(--v-theme-error);\n    }\n    .text-info {\n      color: rgb(var(--v-theme-info));\n    }\n    .border-info {\n      --v-border-color: var(--v-theme-info);\n    }\n    .text-success {\n      color: rgb(var(--v-theme-success));\n    }\n    .border-success {\n      --v-border-color: var(--v-theme-success);\n    }\n    .text-warning {\n      color: rgb(var(--v-theme-warning));\n    }\n    .border-warning {\n      --v-border-color: var(--v-theme-warning);\n    }\n    .on-background {\n      color: rgb(var(--v-theme-on-background));\n    }\n    .on-surface {\n      color: rgb(var(--v-theme-on-surface));\n    }\n    .on-surface-bright {\n      color: rgb(var(--v-theme-on-surface-bright));\n    }\n    .on-surface-light {\n      color: rgb(var(--v-theme-on-surface-light));\n    }\n    .on-primary {\n      color: rgb(var(--v-theme-on-primary));\n    }\n    .on-primary-darken-1 {\n      color: rgb(var(--v-theme-on-primary-darken-1));\n    }\n    .on-secondary {\n      color: rgb(var(--v-theme-on-secondary));\n    }\n    .on-secondary-darken-1 {\n      color: rgb(var(--v-theme-on-secondary-darken-1));\n    }\n    .on-error {\n      color: rgb(var(--v-theme-on-error));\n    }\n    .on-info {\n      color: rgb(var(--v-theme-on-info));\n    }\n    .on-success {\n      color: rgb(var(--v-theme-on-success));\n    }\n    .on-warning {\n      color: rgb(var(--v-theme-on-warning));\n    }\n  }\n\n}\n  </style>\n  <style\n    id=\"vuetify-theme-stylesheet\"\n    type=\"text/css\"\n  >\n    @layer vuetify-utilities {\n  @layer theme-base {\n  :where(#my-app) {\n    --v-theme-background: 255,255,255;\n    --v-theme-background-overlay-multiplier: 1;\n    --v-theme-surface: 255,255,255;\n    --v-theme-surface-overlay-multiplier: 1;\n    --v-theme-surface-bright: 255,255,255;\n    --v-theme-surface-bright-overlay-multiplier: 1;\n    --v-theme-surface-light: 238,238,238;\n    --v-theme-surface-light-overlay-multiplier: 1;\n    --v-theme-surface-variant: 66,66,66;\n    --v-theme-surface-variant-overlay-multiplier: 2;\n    --v-theme-on-surface-variant: 238,238,238;\n    --v-theme-primary: 24,103,192;\n    --v-theme-primary-overlay-multiplier: 2;\n    --v-theme-primary-darken-1: 31,85,146;\n    --v-theme-primary-darken-1-overlay-multiplier: 2;\n    --v-theme-secondary: 72,169,166;\n    --v-theme-secondary-overlay-multiplier: 1;\n    --v-theme-secondary-darken-1: 1,135,134;\n    --v-theme-secondary-darken-1-overlay-multiplier: 1;\n    --v-theme-error: 176,0,32;\n    --v-theme-error-overlay-multiplier: 2;\n    --v-theme-info: 33,150,243;\n    --v-theme-info-overlay-multiplier: 1;\n    --v-theme-success: 76,175,80;\n    --v-theme-success-overlay-multiplier: 1;\n    --v-theme-warning: 251,140,0;\n    --v-theme-warning-overlay-multiplier: 1;\n    --v-theme-on-background: 0,0,0;\n    --v-theme-on-surface: 0,0,0;\n    --v-theme-on-surface-bright: 0,0,0;\n    --v-theme-on-surface-light: 0,0,0;\n    --v-theme-on-primary: 255,255,255;\n    --v-theme-on-primary-darken-1: 255,255,255;\n    --v-theme-on-secondary: 255,255,255;\n    --v-theme-on-secondary-darken-1: 255,255,255;\n    --v-theme-on-error: 255,255,255;\n    --v-theme-on-info: 255,255,255;\n    --v-theme-on-success: 255,255,255;\n    --v-theme-on-warning: 255,255,255;\n    --v-border-color: 0, 0, 0;\n    --v-border-opacity: 0.12;\n    --v-shadow-color: 0, 0, 0;\n    --v-high-emphasis-opacity: 0.87;\n    --v-medium-emphasis-opacity: 0.6;\n    --v-disabled-opacity: 0.38;\n    --v-idle-opacity: 0.04;\n    --v-hover-opacity: 0.04;\n    --v-focus-opacity: 0.12;\n    --v-selected-opacity: 0.08;\n    --v-activated-opacity: 0.12;\n    --v-pressed-opacity: 0.12;\n    --v-dragged-opacity: 0.08;\n    --v-theme-kbd: 238, 238, 238;\n    --v-theme-on-kbd: 0, 0, 0;\n    --v-theme-code: 245, 245, 245;\n    --v-theme-on-code: 0, 0, 0;\n    --v-theme-on-dark: 255, 255, 255;\n    --v-theme-on-light: 0, 0, 0;\n    --v-elevation-overlay-color: black;\n    --v-elevation-overlay-opacity-step: 2%;\n  }\n  :where(#my-app) .v-theme--light {\n    color-scheme: normal;\n    --v-theme-background: 255,255,255;\n    --v-theme-background-overlay-multiplier: 1;\n    --v-theme-surface: 255,255,255;\n    --v-theme-surface-overlay-multiplier: 1;\n    --v-theme-surface-bright: 255,255,255;\n    --v-theme-surface-bright-overlay-multiplier: 1;\n    --v-theme-surface-light: 238,238,238;\n    --v-theme-surface-light-overlay-multiplier: 1;\n    --v-theme-surface-variant: 66,66,66;\n    --v-theme-surface-variant-overlay-multiplier: 2;\n    --v-theme-on-surface-variant: 238,238,238;\n    --v-theme-primary: 24,103,192;\n    --v-theme-primary-overlay-multiplier: 2;\n    --v-theme-primary-darken-1: 31,85,146;\n    --v-theme-primary-darken-1-overlay-multiplier: 2;\n    --v-theme-secondary: 72,169,166;\n    --v-theme-secondary-overlay-multiplier: 1;\n    --v-theme-secondary-darken-1: 1,135,134;\n    --v-theme-secondary-darken-1-overlay-multiplier: 1;\n    --v-theme-error: 176,0,32;\n    --v-theme-error-overlay-multiplier: 2;\n    --v-theme-info: 33,150,243;\n    --v-theme-info-overlay-multiplier: 1;\n    --v-theme-success: 76,175,80;\n    --v-theme-success-overlay-multiplier: 1;\n    --v-theme-warning: 251,140,0;\n    --v-theme-warning-overlay-multiplier: 1;\n    --v-theme-on-background: 0,0,0;\n    --v-theme-on-surface: 0,0,0;\n    --v-theme-on-surface-bright: 0,0,0;\n    --v-theme-on-surface-light: 0,0,0;\n    --v-theme-on-primary: 255,255,255;\n    --v-theme-on-primary-darken-1: 255,255,255;\n    --v-theme-on-secondary: 255,255,255;\n    --v-theme-on-secondary-darken-1: 255,255,255;\n    --v-theme-on-error: 255,255,255;\n    --v-theme-on-info: 255,255,255;\n    --v-theme-on-success: 255,255,255;\n    --v-theme-on-warning: 255,255,255;\n    --v-border-color: 0, 0, 0;\n    --v-border-opacity: 0.12;\n    --v-shadow-color: 0, 0, 0;\n    --v-high-emphasis-opacity: 0.87;\n    --v-medium-emphasis-opacity: 0.6;\n    --v-disabled-opacity: 0.38;\n    --v-idle-opacity: 0.04;\n    --v-hover-opacity: 0.04;\n    --v-focus-opacity: 0.12;\n    --v-selected-opacity: 0.08;\n    --v-activated-opacity: 0.12;\n    --v-pressed-opacity: 0.12;\n    --v-dragged-opacity: 0.08;\n    --v-theme-kbd: 238, 238, 238;\n    --v-theme-on-kbd: 0, 0, 0;\n    --v-theme-code: 245, 245, 245;\n    --v-theme-on-code: 0, 0, 0;\n    --v-theme-on-dark: 255, 255, 255;\n    --v-theme-on-light: 0, 0, 0;\n    --v-elevation-overlay-color: black;\n    --v-elevation-overlay-opacity-step: 2%;\n  }\n  :where(#my-app) .v-theme--dark {\n    color-scheme: dark;\n    --v-theme-background: 18,18,18;\n    --v-theme-background-overlay-multiplier: 1;\n    --v-theme-surface: 33,33,33;\n    --v-theme-surface-overlay-multiplier: 1;\n    --v-theme-surface-bright: 204,191,214;\n    --v-theme-surface-bright-overlay-multiplier: 2;\n    --v-theme-surface-light: 66,66,66;\n    --v-theme-surface-light-overlay-multiplier: 1;\n    --v-theme-surface-variant: 200,200,200;\n    --v-theme-surface-variant-overlay-multiplier: 2;\n    --v-theme-on-surface-variant: 0,0,0;\n    --v-theme-primary: 33,150,243;\n    --v-theme-primary-overlay-multiplier: 2;\n    --v-theme-primary-darken-1: 39,124,193;\n    --v-theme-primary-darken-1-overlay-multiplier: 2;\n    --v-theme-secondary: 84,182,178;\n    --v-theme-secondary-overlay-multiplier: 2;\n    --v-theme-secondary-darken-1: 72,169,166;\n    --v-theme-secondary-darken-1-overlay-multiplier: 2;\n    --v-theme-error: 207,102,121;\n    --v-theme-error-overlay-multiplier: 2;\n    --v-theme-info: 33,150,243;\n    --v-theme-info-overlay-multiplier: 2;\n    --v-theme-success: 76,175,80;\n    --v-theme-success-overlay-multiplier: 2;\n    --v-theme-warning: 251,140,0;\n    --v-theme-warning-overlay-multiplier: 2;\n    --v-theme-on-background: 255,255,255;\n    --v-theme-on-surface: 255,255,255;\n    --v-theme-on-surface-bright: 0,0,0;\n    --v-theme-on-surface-light: 255,255,255;\n    --v-theme-on-primary: 255,255,255;\n    --v-theme-on-primary-darken-1: 255,255,255;\n    --v-theme-on-secondary: 255,255,255;\n    --v-theme-on-secondary-darken-1: 255,255,255;\n    --v-theme-on-error: 255,255,255;\n    --v-theme-on-info: 255,255,255;\n    --v-theme-on-success: 255,255,255;\n    --v-theme-on-warning: 255,255,255;\n    --v-border-color: 255, 255, 255;\n    --v-border-opacity: 0.12;\n    --v-shadow-color: 0, 0, 0;\n    --v-high-emphasis-opacity: 1;\n    --v-medium-emphasis-opacity: 0.7;\n    --v-disabled-opacity: 0.5;\n    --v-idle-opacity: 0.1;\n    --v-hover-opacity: 0.04;\n    --v-focus-opacity: 0.12;\n    --v-selected-opacity: 0.08;\n    --v-activated-opacity: 0.12;\n    --v-pressed-opacity: 0.16;\n    --v-dragged-opacity: 0.08;\n    --v-theme-kbd: 66, 66, 66;\n    --v-theme-on-kbd: 255, 255, 255;\n    --v-theme-code: 52, 52, 52;\n    --v-theme-on-code: 204, 204, 204;\n    --v-theme-on-dark: 255, 255, 255;\n    --v-theme-on-light: 0, 0, 0;\n    --v-elevation-overlay-color: white;\n    --v-elevation-overlay-opacity-step: 2%;\n  }\n  }\n  @layer theme-background {\n    :where(#my-app) .bg-background {\n      --v-theme-overlay-multiplier: var(--v-theme-background-overlay-multiplier);\n      background-color: rgb(var(--v-theme-background));\n      color: rgb(var(--v-theme-on-background));\n    }\n    :where(#my-app) .bg-surface {\n      --v-theme-overlay-multiplier: var(--v-theme-surface-overlay-multiplier);\n      background-color: rgb(var(--v-theme-surface));\n      color: rgb(var(--v-theme-on-surface));\n    }\n    :where(#my-app) .bg-surface-bright {\n      --v-theme-overlay-multiplier: var(--v-theme-surface-bright-overlay-multiplier);\n      background-color: rgb(var(--v-theme-surface-bright));\n      color: rgb(var(--v-theme-on-surface-bright));\n    }\n    :where(#my-app) .bg-surface-light {\n      --v-theme-overlay-multiplier: var(--v-theme-surface-light-overlay-multiplier);\n      background-color: rgb(var(--v-theme-surface-light));\n      color: rgb(var(--v-theme-on-surface-light));\n    }\n    :where(#my-app) .bg-surface-variant {\n      --v-theme-overlay-multiplier: var(--v-theme-surface-variant-overlay-multiplier);\n      background-color: rgb(var(--v-theme-surface-variant));\n      color: rgb(var(--v-theme-on-surface-variant));\n    }\n    :where(#my-app) .bg-primary {\n      --v-theme-overlay-multiplier: var(--v-theme-primary-overlay-multiplier);\n      background-color: rgb(var(--v-theme-primary));\n      color: rgb(var(--v-theme-on-primary));\n    }\n    :where(#my-app) .bg-primary-darken-1 {\n      --v-theme-overlay-multiplier: var(--v-theme-primary-darken-1-overlay-multiplier);\n      background-color: rgb(var(--v-theme-primary-darken-1));\n      color: rgb(var(--v-theme-on-primary-darken-1));\n    }\n    :where(#my-app) .bg-secondary {\n      --v-theme-overlay-multiplier: var(--v-theme-secondary-overlay-multiplier);\n      background-color: rgb(var(--v-theme-secondary));\n      color: rgb(var(--v-theme-on-secondary));\n    }\n    :where(#my-app) .bg-secondary-darken-1 {\n      --v-theme-overlay-multiplier: var(--v-theme-secondary-darken-1-overlay-multiplier);\n      background-color: rgb(var(--v-theme-secondary-darken-1));\n      color: rgb(var(--v-theme-on-secondary-darken-1));\n    }\n    :where(#my-app) .bg-error {\n      --v-theme-overlay-multiplier: var(--v-theme-error-overlay-multiplier);\n      background-color: rgb(var(--v-theme-error));\n      color: rgb(var(--v-theme-on-error));\n    }\n    :where(#my-app) .bg-info {\n      --v-theme-overlay-multiplier: var(--v-theme-info-overlay-multiplier);\n      background-color: rgb(var(--v-theme-info));\n      color: rgb(var(--v-theme-on-info));\n    }\n    :where(#my-app) .bg-success {\n      --v-theme-overlay-multiplier: var(--v-theme-success-overlay-multiplier);\n      background-color: rgb(var(--v-theme-success));\n      color: rgb(var(--v-theme-on-success));\n    }\n    :where(#my-app) .bg-warning {\n      --v-theme-overlay-multiplier: var(--v-theme-warning-overlay-multiplier);\n      background-color: rgb(var(--v-theme-warning));\n      color: rgb(var(--v-theme-on-warning));\n    }\n  }\n  @layer theme-foreground {\n    :where(#my-app) .text-background {\n      color: rgb(var(--v-theme-background));\n    }\n    :where(#my-app) .border-background {\n      --v-border-color: var(--v-theme-background);\n    }\n    :where(#my-app) .text-surface {\n      color: rgb(var(--v-theme-surface));\n    }\n    :where(#my-app) .border-surface {\n      --v-border-color: var(--v-theme-surface);\n    }\n    :where(#my-app) .text-surface-bright {\n      color: rgb(var(--v-theme-surface-bright));\n    }\n    :where(#my-app) .border-surface-bright {\n      --v-border-color: var(--v-theme-surface-bright);\n    }\n    :where(#my-app) .text-surface-light {\n      color: rgb(var(--v-theme-surface-light));\n    }\n    :where(#my-app) .border-surface-light {\n      --v-border-color: var(--v-theme-surface-light);\n    }\n    :where(#my-app) .text-surface-variant {\n      color: rgb(var(--v-theme-surface-variant));\n    }\n    :where(#my-app) .border-surface-variant {\n      --v-border-color: var(--v-theme-surface-variant);\n    }\n    :where(#my-app) .on-surface-variant {\n      color: rgb(var(--v-theme-on-surface-variant));\n    }\n    :where(#my-app) .text-primary {\n      color: rgb(var(--v-theme-primary));\n    }\n    :where(#my-app) .border-primary {\n      --v-border-color: var(--v-theme-primary);\n    }\n    :where(#my-app) .text-primary-darken-1 {\n      color: rgb(var(--v-theme-primary-darken-1));\n    }\n    :where(#my-app) .border-primary-darken-1 {\n      --v-border-color: var(--v-theme-primary-darken-1);\n    }\n    :where(#my-app) .text-secondary {\n      color: rgb(var(--v-theme-secondary));\n    }\n    :where(#my-app) .border-secondary {\n      --v-border-color: var(--v-theme-secondary);\n    }\n    :where(#my-app) .text-secondary-darken-1 {\n      color: rgb(var(--v-theme-secondary-darken-1));\n    }\n    :where(#my-app) .border-secondary-darken-1 {\n      --v-border-color: var(--v-theme-secondary-darken-1);\n    }\n    :where(#my-app) .text-error {\n      color: rgb(var(--v-theme-error));\n    }\n    :where(#my-app) .border-error {\n      --v-border-color: var(--v-theme-error);\n    }\n    :where(#my-app) .text-info {\n      color: rgb(var(--v-theme-info));\n    }\n    :where(#my-app) .border-info {\n      --v-border-color: var(--v-theme-info);\n    }\n    :where(#my-app) .text-success {\n      color: rgb(var(--v-theme-success));\n    }\n    :where(#my-app) .border-success {\n      --v-border-color: var(--v-theme-success);\n    }\n    :where(#my-app) .text-warning {\n      color: rgb(var(--v-theme-warning));\n    }\n    :where(#my-app) .border-warning {\n      --v-border-color: var(--v-theme-warning);\n    }\n    :where(#my-app) .on-background {\n      color: rgb(var(--v-theme-on-background));\n    }\n    :where(#my-app) .on-surface {\n      color: rgb(var(--v-theme-on-surface));\n    }\n    :where(#my-app) .on-surface-bright {\n      color: rgb(var(--v-theme-on-surface-bright));\n    }\n    :where(#my-app) .on-surface-light {\n      color: rgb(var(--v-theme-on-surface-light));\n    }\n    :where(#my-app) .on-primary {\n      color: rgb(var(--v-theme-on-primary));\n    }\n    :where(#my-app) .on-primary-darken-1 {\n      color: rgb(var(--v-theme-on-primary-darken-1));\n    }\n    :where(#my-app) .on-secondary {\n      color: rgb(var(--v-theme-on-secondary));\n    }\n    :where(#my-app) .on-secondary-darken-1 {\n      color: rgb(var(--v-theme-on-secondary-darken-1));\n    }\n    :where(#my-app) .on-error {\n      color: rgb(var(--v-theme-on-error));\n    }\n    :where(#my-app) .on-info {\n      color: rgb(var(--v-theme-on-info));\n    }\n    :where(#my-app) .on-success {\n      color: rgb(var(--v-theme-on-success));\n    }\n    :where(#my-app) .on-warning {\n      color: rgb(var(--v-theme-on-warning));\n    }\n  }\n\n}\n  </style>\n</head>\n`;\n\nexports[`createTheme > should create style element 1`] = `\n<head>\n  <style\n    id=\"vuetify-theme-stylesheet\"\n    type=\"text/css\"\n  >\n    @layer vuetify-utilities {\n  @layer theme-base {\n  :root {\n    --v-theme-background: 255,255,255;\n    --v-theme-background-overlay-multiplier: 1;\n    --v-theme-surface: 255,255,255;\n    --v-theme-surface-overlay-multiplier: 1;\n    --v-theme-surface-bright: 255,255,255;\n    --v-theme-surface-bright-overlay-multiplier: 1;\n    --v-theme-surface-light: 238,238,238;\n    --v-theme-surface-light-overlay-multiplier: 1;\n    --v-theme-surface-variant: 66,66,66;\n    --v-theme-surface-variant-overlay-multiplier: 2;\n    --v-theme-on-surface-variant: 238,238,238;\n    --v-theme-primary: 24,103,192;\n    --v-theme-primary-overlay-multiplier: 2;\n    --v-theme-primary-darken-1: 31,85,146;\n    --v-theme-primary-darken-1-overlay-multiplier: 2;\n    --v-theme-secondary: 72,169,166;\n    --v-theme-secondary-overlay-multiplier: 1;\n    --v-theme-secondary-darken-1: 1,135,134;\n    --v-theme-secondary-darken-1-overlay-multiplier: 1;\n    --v-theme-error: 176,0,32;\n    --v-theme-error-overlay-multiplier: 2;\n    --v-theme-info: 33,150,243;\n    --v-theme-info-overlay-multiplier: 1;\n    --v-theme-success: 76,175,80;\n    --v-theme-success-overlay-multiplier: 1;\n    --v-theme-warning: 251,140,0;\n    --v-theme-warning-overlay-multiplier: 1;\n    --v-theme-on-background: 0,0,0;\n    --v-theme-on-surface: 0,0,0;\n    --v-theme-on-surface-bright: 0,0,0;\n    --v-theme-on-surface-light: 0,0,0;\n    --v-theme-on-primary: 255,255,255;\n    --v-theme-on-primary-darken-1: 255,255,255;\n    --v-theme-on-secondary: 255,255,255;\n    --v-theme-on-secondary-darken-1: 255,255,255;\n    --v-theme-on-error: 255,255,255;\n    --v-theme-on-info: 255,255,255;\n    --v-theme-on-success: 255,255,255;\n    --v-theme-on-warning: 255,255,255;\n    --v-border-color: 0, 0, 0;\n    --v-border-opacity: 0.12;\n    --v-shadow-color: 0, 0, 0;\n    --v-high-emphasis-opacity: 0.87;\n    --v-medium-emphasis-opacity: 0.6;\n    --v-disabled-opacity: 0.38;\n    --v-idle-opacity: 0.04;\n    --v-hover-opacity: 0.04;\n    --v-focus-opacity: 0.12;\n    --v-selected-opacity: 0.08;\n    --v-activated-opacity: 0.12;\n    --v-pressed-opacity: 0.12;\n    --v-dragged-opacity: 0.08;\n    --v-theme-kbd: 238, 238, 238;\n    --v-theme-on-kbd: 0, 0, 0;\n    --v-theme-code: 245, 245, 245;\n    --v-theme-on-code: 0, 0, 0;\n    --v-theme-on-dark: 255, 255, 255;\n    --v-theme-on-light: 0, 0, 0;\n    --v-elevation-overlay-color: black;\n    --v-elevation-overlay-opacity-step: 2%;\n  }\n  .v-theme--light {\n    color-scheme: normal;\n    --v-theme-background: 255,255,255;\n    --v-theme-background-overlay-multiplier: 1;\n    --v-theme-surface: 255,255,255;\n    --v-theme-surface-overlay-multiplier: 1;\n    --v-theme-surface-bright: 255,255,255;\n    --v-theme-surface-bright-overlay-multiplier: 1;\n    --v-theme-surface-light: 238,238,238;\n    --v-theme-surface-light-overlay-multiplier: 1;\n    --v-theme-surface-variant: 66,66,66;\n    --v-theme-surface-variant-overlay-multiplier: 2;\n    --v-theme-on-surface-variant: 238,238,238;\n    --v-theme-primary: 24,103,192;\n    --v-theme-primary-overlay-multiplier: 2;\n    --v-theme-primary-darken-1: 31,85,146;\n    --v-theme-primary-darken-1-overlay-multiplier: 2;\n    --v-theme-secondary: 72,169,166;\n    --v-theme-secondary-overlay-multiplier: 1;\n    --v-theme-secondary-darken-1: 1,135,134;\n    --v-theme-secondary-darken-1-overlay-multiplier: 1;\n    --v-theme-error: 176,0,32;\n    --v-theme-error-overlay-multiplier: 2;\n    --v-theme-info: 33,150,243;\n    --v-theme-info-overlay-multiplier: 1;\n    --v-theme-success: 76,175,80;\n    --v-theme-success-overlay-multiplier: 1;\n    --v-theme-warning: 251,140,0;\n    --v-theme-warning-overlay-multiplier: 1;\n    --v-theme-on-background: 0,0,0;\n    --v-theme-on-surface: 0,0,0;\n    --v-theme-on-surface-bright: 0,0,0;\n    --v-theme-on-surface-light: 0,0,0;\n    --v-theme-on-primary: 255,255,255;\n    --v-theme-on-primary-darken-1: 255,255,255;\n    --v-theme-on-secondary: 255,255,255;\n    --v-theme-on-secondary-darken-1: 255,255,255;\n    --v-theme-on-error: 255,255,255;\n    --v-theme-on-info: 255,255,255;\n    --v-theme-on-success: 255,255,255;\n    --v-theme-on-warning: 255,255,255;\n    --v-border-color: 0, 0, 0;\n    --v-border-opacity: 0.12;\n    --v-shadow-color: 0, 0, 0;\n    --v-high-emphasis-opacity: 0.87;\n    --v-medium-emphasis-opacity: 0.6;\n    --v-disabled-opacity: 0.38;\n    --v-idle-opacity: 0.04;\n    --v-hover-opacity: 0.04;\n    --v-focus-opacity: 0.12;\n    --v-selected-opacity: 0.08;\n    --v-activated-opacity: 0.12;\n    --v-pressed-opacity: 0.12;\n    --v-dragged-opacity: 0.08;\n    --v-theme-kbd: 238, 238, 238;\n    --v-theme-on-kbd: 0, 0, 0;\n    --v-theme-code: 245, 245, 245;\n    --v-theme-on-code: 0, 0, 0;\n    --v-theme-on-dark: 255, 255, 255;\n    --v-theme-on-light: 0, 0, 0;\n    --v-elevation-overlay-color: black;\n    --v-elevation-overlay-opacity-step: 2%;\n  }\n  .v-theme--dark {\n    color-scheme: dark;\n    --v-theme-background: 18,18,18;\n    --v-theme-background-overlay-multiplier: 1;\n    --v-theme-surface: 33,33,33;\n    --v-theme-surface-overlay-multiplier: 1;\n    --v-theme-surface-bright: 204,191,214;\n    --v-theme-surface-bright-overlay-multiplier: 2;\n    --v-theme-surface-light: 66,66,66;\n    --v-theme-surface-light-overlay-multiplier: 1;\n    --v-theme-surface-variant: 200,200,200;\n    --v-theme-surface-variant-overlay-multiplier: 2;\n    --v-theme-on-surface-variant: 0,0,0;\n    --v-theme-primary: 33,150,243;\n    --v-theme-primary-overlay-multiplier: 2;\n    --v-theme-primary-darken-1: 39,124,193;\n    --v-theme-primary-darken-1-overlay-multiplier: 2;\n    --v-theme-secondary: 84,182,178;\n    --v-theme-secondary-overlay-multiplier: 2;\n    --v-theme-secondary-darken-1: 72,169,166;\n    --v-theme-secondary-darken-1-overlay-multiplier: 2;\n    --v-theme-error: 207,102,121;\n    --v-theme-error-overlay-multiplier: 2;\n    --v-theme-info: 33,150,243;\n    --v-theme-info-overlay-multiplier: 2;\n    --v-theme-success: 76,175,80;\n    --v-theme-success-overlay-multiplier: 2;\n    --v-theme-warning: 251,140,0;\n    --v-theme-warning-overlay-multiplier: 2;\n    --v-theme-on-background: 255,255,255;\n    --v-theme-on-surface: 255,255,255;\n    --v-theme-on-surface-bright: 0,0,0;\n    --v-theme-on-surface-light: 255,255,255;\n    --v-theme-on-primary: 255,255,255;\n    --v-theme-on-primary-darken-1: 255,255,255;\n    --v-theme-on-secondary: 255,255,255;\n    --v-theme-on-secondary-darken-1: 255,255,255;\n    --v-theme-on-error: 255,255,255;\n    --v-theme-on-info: 255,255,255;\n    --v-theme-on-success: 255,255,255;\n    --v-theme-on-warning: 255,255,255;\n    --v-border-color: 255, 255, 255;\n    --v-border-opacity: 0.12;\n    --v-shadow-color: 0, 0, 0;\n    --v-high-emphasis-opacity: 1;\n    --v-medium-emphasis-opacity: 0.7;\n    --v-disabled-opacity: 0.5;\n    --v-idle-opacity: 0.1;\n    --v-hover-opacity: 0.04;\n    --v-focus-opacity: 0.12;\n    --v-selected-opacity: 0.08;\n    --v-activated-opacity: 0.12;\n    --v-pressed-opacity: 0.16;\n    --v-dragged-opacity: 0.08;\n    --v-theme-kbd: 66, 66, 66;\n    --v-theme-on-kbd: 255, 255, 255;\n    --v-theme-code: 52, 52, 52;\n    --v-theme-on-code: 204, 204, 204;\n    --v-theme-on-dark: 255, 255, 255;\n    --v-theme-on-light: 0, 0, 0;\n    --v-elevation-overlay-color: white;\n    --v-elevation-overlay-opacity-step: 2%;\n  }\n  }\n  @layer theme-background {\n    .bg-background {\n      --v-theme-overlay-multiplier: var(--v-theme-background-overlay-multiplier);\n      background-color: rgb(var(--v-theme-background));\n      color: rgb(var(--v-theme-on-background));\n    }\n    .bg-surface {\n      --v-theme-overlay-multiplier: var(--v-theme-surface-overlay-multiplier);\n      background-color: rgb(var(--v-theme-surface));\n      color: rgb(var(--v-theme-on-surface));\n    }\n    .bg-surface-bright {\n      --v-theme-overlay-multiplier: var(--v-theme-surface-bright-overlay-multiplier);\n      background-color: rgb(var(--v-theme-surface-bright));\n      color: rgb(var(--v-theme-on-surface-bright));\n    }\n    .bg-surface-light {\n      --v-theme-overlay-multiplier: var(--v-theme-surface-light-overlay-multiplier);\n      background-color: rgb(var(--v-theme-surface-light));\n      color: rgb(var(--v-theme-on-surface-light));\n    }\n    .bg-surface-variant {\n      --v-theme-overlay-multiplier: var(--v-theme-surface-variant-overlay-multiplier);\n      background-color: rgb(var(--v-theme-surface-variant));\n      color: rgb(var(--v-theme-on-surface-variant));\n    }\n    .bg-primary {\n      --v-theme-overlay-multiplier: var(--v-theme-primary-overlay-multiplier);\n      background-color: rgb(var(--v-theme-primary));\n      color: rgb(var(--v-theme-on-primary));\n    }\n    .bg-primary-darken-1 {\n      --v-theme-overlay-multiplier: var(--v-theme-primary-darken-1-overlay-multiplier);\n      background-color: rgb(var(--v-theme-primary-darken-1));\n      color: rgb(var(--v-theme-on-primary-darken-1));\n    }\n    .bg-secondary {\n      --v-theme-overlay-multiplier: var(--v-theme-secondary-overlay-multiplier);\n      background-color: rgb(var(--v-theme-secondary));\n      color: rgb(var(--v-theme-on-secondary));\n    }\n    .bg-secondary-darken-1 {\n      --v-theme-overlay-multiplier: var(--v-theme-secondary-darken-1-overlay-multiplier);\n      background-color: rgb(var(--v-theme-secondary-darken-1));\n      color: rgb(var(--v-theme-on-secondary-darken-1));\n    }\n    .bg-error {\n      --v-theme-overlay-multiplier: var(--v-theme-error-overlay-multiplier);\n      background-color: rgb(var(--v-theme-error));\n      color: rgb(var(--v-theme-on-error));\n    }\n    .bg-info {\n      --v-theme-overlay-multiplier: var(--v-theme-info-overlay-multiplier);\n      background-color: rgb(var(--v-theme-info));\n      color: rgb(var(--v-theme-on-info));\n    }\n    .bg-success {\n      --v-theme-overlay-multiplier: var(--v-theme-success-overlay-multiplier);\n      background-color: rgb(var(--v-theme-success));\n      color: rgb(var(--v-theme-on-success));\n    }\n    .bg-warning {\n      --v-theme-overlay-multiplier: var(--v-theme-warning-overlay-multiplier);\n      background-color: rgb(var(--v-theme-warning));\n      color: rgb(var(--v-theme-on-warning));\n    }\n  }\n  @layer theme-foreground {\n    .text-background {\n      color: rgb(var(--v-theme-background));\n    }\n    .border-background {\n      --v-border-color: var(--v-theme-background);\n    }\n    .text-surface {\n      color: rgb(var(--v-theme-surface));\n    }\n    .border-surface {\n      --v-border-color: var(--v-theme-surface);\n    }\n    .text-surface-bright {\n      color: rgb(var(--v-theme-surface-bright));\n    }\n    .border-surface-bright {\n      --v-border-color: var(--v-theme-surface-bright);\n    }\n    .text-surface-light {\n      color: rgb(var(--v-theme-surface-light));\n    }\n    .border-surface-light {\n      --v-border-color: var(--v-theme-surface-light);\n    }\n    .text-surface-variant {\n      color: rgb(var(--v-theme-surface-variant));\n    }\n    .border-surface-variant {\n      --v-border-color: var(--v-theme-surface-variant);\n    }\n    .on-surface-variant {\n      color: rgb(var(--v-theme-on-surface-variant));\n    }\n    .text-primary {\n      color: rgb(var(--v-theme-primary));\n    }\n    .border-primary {\n      --v-border-color: var(--v-theme-primary);\n    }\n    .text-primary-darken-1 {\n      color: rgb(var(--v-theme-primary-darken-1));\n    }\n    .border-primary-darken-1 {\n      --v-border-color: var(--v-theme-primary-darken-1);\n    }\n    .text-secondary {\n      color: rgb(var(--v-theme-secondary));\n    }\n    .border-secondary {\n      --v-border-color: var(--v-theme-secondary);\n    }\n    .text-secondary-darken-1 {\n      color: rgb(var(--v-theme-secondary-darken-1));\n    }\n    .border-secondary-darken-1 {\n      --v-border-color: var(--v-theme-secondary-darken-1);\n    }\n    .text-error {\n      color: rgb(var(--v-theme-error));\n    }\n    .border-error {\n      --v-border-color: var(--v-theme-error);\n    }\n    .text-info {\n      color: rgb(var(--v-theme-info));\n    }\n    .border-info {\n      --v-border-color: var(--v-theme-info);\n    }\n    .text-success {\n      color: rgb(var(--v-theme-success));\n    }\n    .border-success {\n      --v-border-color: var(--v-theme-success);\n    }\n    .text-warning {\n      color: rgb(var(--v-theme-warning));\n    }\n    .border-warning {\n      --v-border-color: var(--v-theme-warning);\n    }\n    .on-background {\n      color: rgb(var(--v-theme-on-background));\n    }\n    .on-surface {\n      color: rgb(var(--v-theme-on-surface));\n    }\n    .on-surface-bright {\n      color: rgb(var(--v-theme-on-surface-bright));\n    }\n    .on-surface-light {\n      color: rgb(var(--v-theme-on-surface-light));\n    }\n    .on-primary {\n      color: rgb(var(--v-theme-on-primary));\n    }\n    .on-primary-darken-1 {\n      color: rgb(var(--v-theme-on-primary-darken-1));\n    }\n    .on-secondary {\n      color: rgb(var(--v-theme-on-secondary));\n    }\n    .on-secondary-darken-1 {\n      color: rgb(var(--v-theme-on-secondary-darken-1));\n    }\n    .on-error {\n      color: rgb(var(--v-theme-on-error));\n    }\n    .on-info {\n      color: rgb(var(--v-theme-on-info));\n    }\n    .on-success {\n      color: rgb(var(--v-theme-on-success));\n    }\n    .on-warning {\n      color: rgb(var(--v-theme-on-warning));\n    }\n  }\n\n}\n  </style>\n</head>\n`;\n\nexports[`createTheme > should not generate style element if disabled 1`] = `<head />`;\n"
  },
  {
    "path": "packages/vuetify/src/composables/__tests__/autocomplete.spec.ts",
    "content": "// Composables\nimport { makeAutocompleteProps, useAutocomplete } from '../autocomplete'\n\n// Utilities\nimport { mount } from '@vue/test-utils'\nimport { defineComponent, h, nextTick } from 'vue'\n\n// Types\nimport type { InputAutocompleteProps } from '../autocomplete'\n\ndescribe('input-autocomplete', () => {\n  function mountFunction (props: Partial<InputAutocompleteProps> = {}) {\n    return mount(defineComponent({\n      props: {\n        name: String,\n        ...makeAutocompleteProps(),\n      },\n      setup (props) {\n        const { fieldAutocomplete, fieldName, isSuppressing, update } = useAutocomplete(props)\n\n        return () => h('input', {\n          autocomplete: fieldAutocomplete.value,\n          name: fieldName.value,\n          onFocus: () => isSuppressing.value && update(),\n        })\n      },\n    }), { props })\n  }\n\n  it.each([\n    [{ autocomplete: undefined, name: undefined }],\n    [{ autocomplete: 'on', name: undefined }],\n    [{ autocomplete: undefined, name: 'username' }],\n    [{ autocomplete: 'current-password', name: 'password' }],\n    [{ autocomplete: 'shipping street-address', name: 'shipping-address' }],\n    [{ autocomplete: 'off', name: 'email' }],\n  ])('should pass through regular props', async (props: InputAutocompleteProps) => {\n    const wrapper = mountFunction(props)\n\n    expect(wrapper.vm.$el.autocomplete).toEqual(props.autocomplete ?? '')\n    expect(wrapper.vm.$el.name).toEqual(props.name ?? '')\n\n    wrapper.trigger('focus')\n    await nextTick()\n    expect(wrapper.vm.$el.name).toEqual(props.name ?? '')\n  })\n\n  it('[suppress] should update field name on focus', async () => {\n    const wrapper = mountFunction({ autocomplete: 'suppress', name: 'username' })\n\n    expect(wrapper.vm.$el.autocomplete).toBe('off')\n    expect(wrapper.vm.$el.name).toBe('username-v-0-0')\n\n    wrapper.trigger('focus')\n    await nextTick()\n    expect(wrapper.vm.$el.name).toMatch(/username-v-0-\\d{13}/)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/__tests__/border.spec.ts",
    "content": "// Composables\nimport { makeBorderProps, useBorder } from '../border'\n\n// Utilities\nimport { mount } from '@vue/test-utils'\n\n// Types\nimport type { BorderProps } from '../border'\n\ndescribe('border.ts', () => {\n  it('should create border props', () => {\n    const wrapper = mount({\n      props: makeBorderProps(),\n      template: '<div/>',\n    }, {\n      propsData: { border: true },\n    })\n\n    expect(wrapper.props().border).toBeDefined()\n  })\n\n  it.each([\n    // Invalid or empty\n    [{}, []],\n    [{ border: null }, []],\n    [{ border: 1 }, []],\n    // Border only\n    [{ border: true }, 'foo--border'],\n    [{ border: '' }, 'foo--border'],\n    // Border with 0 or false\n    [{ border: '0' }, ['border-0']],\n    [{ border: 0 }, ['border-0']],\n    // Border with a word\n    [{ border: 't' }, ['border-t']],\n    [{ border: 't opacity-50' }, ['border-t', 'border-opacity-50']],\n    [{ border: 'e-xl primary' }, ['border-e-xl', 'border-primary']],\n  ] as BorderProps[])('should have the correct class using %s', (props: BorderProps, expected: any) => {\n    const { borderClasses } = useBorder(props as BorderProps, 'foo')\n\n    expect(borderClasses.value).toEqual(expected)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/__tests__/calendar.spec.ts",
    "content": "// Composables\nimport { makeCalendarProps, useCalendar } from '@/composables/calendar'\nimport { useDate } from '@/composables/date'\n\n// Utilities\nimport { mount } from '@vue/test-utils'\nimport { defineComponent } from 'vue'\nimport { createVuetify } from '@/framework'\n\n// Types\nimport type { CalendarProps } from '@/composables/calendar'\n\ndescribe('calendar', () => {\n  it('renders days based upon displayValue', () => {\n    expect.assertions(2)\n    mount(defineComponent({\n      props: makeCalendarProps(),\n      setup (props) {\n        const calendar = useCalendar({ ...props, displayValue: '2021-10-10' } as any)\n        const date = useDate()\n\n        expect(date.format(calendar.displayValue.value, 'monthAndYear')).toMatchInlineSnapshot(`\"October 2021\"`)\n        expect(calendar.daysInMonth.value.map(day => day.isoDate)).toMatchInlineSnapshot(`\n          [\n            \"2021-09-26\",\n            \"2021-09-27\",\n            \"2021-09-28\",\n            \"2021-09-29\",\n            \"2021-09-30\",\n            \"2021-10-01\",\n            \"2021-10-02\",\n            \"2021-10-03\",\n            \"2021-10-04\",\n            \"2021-10-05\",\n            \"2021-10-06\",\n            \"2021-10-07\",\n            \"2021-10-08\",\n            \"2021-10-09\",\n            \"2021-10-10\",\n            \"2021-10-11\",\n            \"2021-10-12\",\n            \"2021-10-13\",\n            \"2021-10-14\",\n            \"2021-10-15\",\n            \"2021-10-16\",\n            \"2021-10-17\",\n            \"2021-10-18\",\n            \"2021-10-19\",\n            \"2021-10-20\",\n            \"2021-10-21\",\n            \"2021-10-22\",\n            \"2021-10-23\",\n            \"2021-10-24\",\n            \"2021-10-25\",\n            \"2021-10-26\",\n            \"2021-10-27\",\n            \"2021-10-28\",\n            \"2021-10-29\",\n            \"2021-10-30\",\n            \"2021-10-31\",\n            \"2021-11-01\",\n            \"2021-11-02\",\n            \"2021-11-03\",\n            \"2021-11-04\",\n            \"2021-11-05\",\n            \"2021-11-06\",\n          ]\n        `)\n\n        return () => {}\n      },\n    }), {\n      global: { plugins: [createVuetify()] },\n    })\n  })\n\n  it.each([\n    [{}, 'S,M,T,W,T,F,S'],\n    [{ weekdays: [1, 2, 3, 4, 5] }, 'M,T,W,T,F'],\n    [{ firstDayOfWeek: 1 }, 'M,T,W,T,F,S,S'],\n    [{ firstDayOfWeek: 2 }, 'T,W,T,F,S,S,M'],\n    [{ firstDayOfWeek: 3 }, 'W,T,F,S,S,M,T'],\n    [{ firstDayOfWeek: 1, weekdays: [1, 2, 3, 4] }, 'M,T,W,T'],\n    [{ firstDayOfWeek: 1, weekdays: [2, 3, 4] }, 'T,W,T'],\n    [{ firstDayOfWeek: 2, weekdays: [2, 3, 4] }, 'T,W,T'],\n    [{ firstDayOfWeek: 3, weekdays: [2, 3, 4] }, 'W,T,T'],\n  ] as [CalendarProps, string][])('calculates weekday labels correctly for %s', (customizedProps: CalendarProps, expected: string) => {\n    expect.assertions(1)\n    mount(defineComponent({\n      props: makeCalendarProps(customizedProps),\n      setup (props) {\n        const calendar = useCalendar(props as any)\n        expect(calendar.weekdayLabels.value.join(',')).toBe(expected)\n        return () => {}\n      },\n    }), {\n      global: { plugins: [createVuetify()] },\n    })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/__tests__/color.spec.ts",
    "content": "// Composables\nimport { useBackgroundColor, useColor, useTextColor } from '../color'\n\n// Utilities\nimport { reactive } from 'vue'\n\ndescribe('color.ts', () => {\n  describe('useBackgroundColor', () => {\n    it('should allow ref argument or return null', () => {\n      const props = reactive({ color: 'primary' })\n      const { backgroundColorClasses, backgroundColorStyles } = useBackgroundColor(() => props.color)\n\n      expect(backgroundColorClasses.value).toEqual(['bg-primary'])\n      expect(backgroundColorStyles.value).toEqual({})\n    })\n\n    it.each([\n      [{ bg: null }, [[], {}]],\n      [{ bg: '' }, [[], {}]],\n      [{ bg: 'primary' }, [['bg-primary'], {}]],\n      [{ bg: 'bg-primary' }, [['bg-primary'], {}]],\n      [{ bg: '#FF00FF' }, [['v-theme-on-dark'], { backgroundColor: '#FF00FF' }]],\n    ])('should return correct color classes and styles', (value, [classes, styles]) => {\n      const { backgroundColorClasses, backgroundColorStyles } = useBackgroundColor(() => value.bg)\n\n      expect(backgroundColorClasses.value).toEqual(classes)\n      expect(backgroundColorStyles.value).toEqual(styles)\n    })\n  })\n\n  describe('useColor', () => {\n    it.each([\n      [{ background: null }, [[], {}]],\n      [{ background: '' }, [[], {}]],\n      [{ background: 'primary' }, [['bg-primary'], {}]],\n      [{ background: 'bg-primary' }, [['bg-primary'], {}]],\n      [{ background: '#FF00FF' }, [['v-theme-on-dark'], { backgroundColor: '#FF00FF' }]],\n      [{ text: null }, [[], {}]],\n      [{ text: '' }, [[], {}]],\n      [{ text: 'primary' }, [['text-primary'], {}]],\n      [{ text: 'text-primary' }, [['text-primary'], {}]],\n      [{ text: '#FF00FF' }, [[], { caretColor: '#FF00FF', color: '#FF00FF' }]],\n    ])('should return correct color classes and styles', (value, [classes, styles]) => {\n      const { colorClasses, colorStyles } = useColor(value)\n\n      expect(colorClasses.value).toEqual(classes)\n      expect(colorStyles.value).toEqual(styles)\n    })\n  })\n\n  describe('useTextColor', () => {\n    it('should allow ref argument or return null', () => {\n      const props = reactive({ color: 'primary' })\n      const { textColorClasses, textColorStyles } = useTextColor(() => props.color)\n\n      expect(textColorClasses.value).toEqual(['text-primary'])\n      expect(textColorStyles.value).toEqual({})\n    })\n\n    it.each([\n      [{ color: '' }, [[], {}]],\n      [{ color: null }, [[], {}]],\n      [{ color: 'primary' }, [['text-primary'], {}]],\n      [{ color: 'text-primary' }, [['text-primary'], {}]],\n      [{ color: '#FF00FF' }, [[], { caretColor: '#FF00FF', color: '#FF00FF' }]],\n    ])('should return correct data', (value, [classes, styles]) => {\n      const { textColorClasses, textColorStyles } = useTextColor(() => value.color)\n\n      expect(textColorClasses.value).toEqual(classes)\n      expect(textColorStyles.value).toEqual(styles)\n    })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/__tests__/defaults.spec.ts",
    "content": "// Components\nimport { VBtn } from '@/components/VBtn'\n\n// Utilities\nimport { mount } from '@vue/test-utils'\nimport { createVuetify } from '@/framework'\n\ndescribe('defaults', () => {\n  it('applies global default class and style', () => {\n    const vuetify = createVuetify({\n      defaults: {\n        VBtn: {\n          class: 'foobar',\n          style: 'color: red;',\n        },\n      },\n    })\n\n    const wrapper = mount<any>(VBtn, {\n      global: {\n        plugins: [vuetify],\n      },\n    })\n\n    expect(wrapper.classes()).toContain('foobar')\n    expect(wrapper.attributes('style')).toContain('color: red;')\n  })\n\n  it('prefers local styles', () => {\n    const vuetify = createVuetify({\n      defaults: {\n        VBtn: {\n          class: 'foobar',\n          style: 'color: red; background: red;',\n        },\n      },\n    })\n\n    const wrapper = mount<any>(VBtn, {\n      props: {\n        class: 'baz',\n        style: 'background: blue; caret-color: blue;',\n      },\n      global: {\n        plugins: [vuetify],\n      },\n    })\n\n    expect(wrapper.classes()).toContain('foobar')\n    expect(wrapper.classes()).toContain('baz')\n    expect(wrapper.attributes('style')).toContain('color: red;')\n    expect(wrapper.attributes('style')).toContain('background: blue;')\n    expect(wrapper.attributes('style')).toContain('caret-color: blue;')\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/__tests__/delay.spec.ts",
    "content": "// Composables\nimport { makeDelayProps, useDelay } from '../delay'\n\n// Utilities\nimport { wait } from '@test'\nimport { mount } from '@vue/test-utils'\n\ndescribe('delayProps', () => {\n  it('should allow setting default values', () => {\n    const wrapper = mount({\n      template: '<div />',\n      props: makeDelayProps({\n        closeDelay: 42,\n        openDelay: 7,\n      }),\n    })\n\n    expect(wrapper.props()).toStrictEqual({\n      closeDelay: 42,\n      openDelay: 7,\n    })\n  })\n})\n\ndescribe('useDelay', () => {\n  it.each(['runOpenDelay', 'runCloseDelay'] as const)('should call %s - callback', async methodName => {\n    const cb = vi.fn()\n    const runDelay = useDelay({\n      openDelay: 50,\n      closeDelay: 50,\n    }, cb)[methodName]\n\n    runDelay()\n\n    await wait(30)\n    expect(cb).not.toHaveBeenCalled()\n\n    await wait(30)\n    expect(cb).toHaveBeenCalledWith(methodName === 'runOpenDelay')\n  })\n\n  it.each(['runOpenDelay', 'runCloseDelay'] as const)('should call %s - promise', async methodName => {\n    const cb = vi.fn(val => val)\n    const runDelay = useDelay({\n      openDelay: 50,\n      closeDelay: 50,\n    })[methodName]\n\n    const delay = runDelay().then(cb)\n\n    await Promise.race([\n      delay,\n      wait(30),\n    ])\n    expect(cb).not.toHaveBeenCalled()\n\n    await expect(delay).resolves.toBe(methodName === 'runOpenDelay')\n  })\n\n  it('should cancel delay when running a new one', async () => {\n    const cb = vi.fn()\n    const { runOpenDelay, runCloseDelay } = useDelay({\n      closeDelay: 50,\n      openDelay: 50,\n    }, cb)\n\n    runOpenDelay()\n    await wait(30)\n    runCloseDelay()\n    await wait(60)\n\n    expect(cb).toHaveBeenCalledTimes(1)\n    expect(cb).toHaveBeenCalledWith(false)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/__tests__/dimensions.spec.ts",
    "content": "// Utilities\nimport { useDimension } from '../dimensions'\n\n// Types\nimport type { DimensionProps } from '../dimensions'\n\ndescribe('dimensions.ts', () => {\n  it.each([\n    [{ height: null }, {}],\n    [{ height: 101 }, { height: '101px' }],\n    [{ maxHeight: 102 }, { maxHeight: '102px' }],\n    [{ maxWidth: 102 }, { maxWidth: '102px' }],\n    [{ minHeight: 103 }, { minHeight: '103px' }],\n    [{ minWidth: 104 }, { minWidth: '104px' }],\n    [{ width: 105 }, { width: '105px' }],\n  ])('should have proper styles', (props, expected) => {\n    const { dimensionStyles } = useDimension(props as DimensionProps)\n\n    expect(dimensionStyles.value).toEqual(expected)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/__tests__/display-components.spec.browser.tsx",
    "content": "/* eslint-disable max-len */\n\n// Components\nimport { VBanner } from '@/components/VBanner/VBanner'\nimport { VLayout } from '@/components/VLayout/VLayout'\nimport { VMain } from '@/components/VMain'\nimport { VNavigationDrawer } from '@/components/VNavigationDrawer/VNavigationDrawer'\nimport { VSlideGroup } from '@/components/VSlideGroup/VSlideGroup'\n\n// Utilities\nimport { page, render, screen } from '@test'\nimport { ref } from 'vue'\n\n// Types\nimport type { DisplayBreakpoint } from '@/composables/display'\n\ndescribe('display-components', () => {\n  it('should render items', async () => {\n    await page.viewport(960, 800)\n\n    const mobileBreakpoint = ref<number | DisplayBreakpoint>('lg')\n    render(() => (\n      <VLayout>\n        <VNavigationDrawer mobileBreakpoint={ mobileBreakpoint.value } />\n        <VMain>\n          <VBanner mobileBreakpoint={ mobileBreakpoint.value }>\n            Lorem ipsum dolor sit amet consectetur adipisicing elit. Dicta quaerat fugit ratione totam magnam, beatae consequuntur qui quam enim et sapiente autem accusantium id nesciunt maiores obcaecati minus molestiae! Ipsa.\n          </VBanner>\n          <VSlideGroup mobileBreakpoint={ mobileBreakpoint.value } />\n        </VMain>\n      </VLayout>\n    ))\n\n    const navigationDrawer = screen.getByCSS('.v-navigation-drawer')\n    const banner = screen.getByCSS('.v-banner')\n    const slideGroup = screen.getByCSS('.v-slide-group')\n\n    expect(navigationDrawer).toHaveClass('v-navigation-drawer--mobile')\n    expect(banner).toHaveClass('v-banner--mobile')\n    expect(slideGroup).toHaveClass('v-slide-group--mobile')\n\n    mobileBreakpoint.value = 959\n\n    await expect.poll(() => navigationDrawer).not.toHaveClass('v-navigation-drawer--mobile')\n    await expect.poll(() => banner).not.toHaveClass('v-banner--mobile')\n    await expect.poll(() => slideGroup).not.toHaveClass('v-slide-group--mobile')\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/__tests__/display.spec.browser.ts",
    "content": "// Composables\nimport { createDisplay } from '../display'\n\n// Utilities\nimport { page } from '@test'\nimport { effectScope } from 'vue'\n\nconst breakpoints = [\n  'xs',\n  'sm',\n  'md',\n  'lg',\n  'xl',\n  'xxl',\n  'smAndDown',\n  'smAndUp',\n  'mdAndDown',\n  'mdAndUp',\n  'lgAndDown',\n  'lgAndUp',\n  'xlAndDown',\n  'xlAndUp',\n] as const\n\ndescribe('display', () => {\n  it.each([\n    [\n      {\n        description: 'Huawei Smartwatch',\n        width: 400,\n        height: 400,\n        name: 'xs',\n      },\n      [\n        'xs',\n        'smAndDown',\n        'mdAndDown',\n        'lgAndDown',\n        'xlAndDown',\n      ],\n    ],\n    [\n      {\n        description: 'Galaxy S5 (portrait)',\n        width: 360,\n        height: 640,\n        name: 'xs',\n      },\n      [\n        'xs',\n        'smAndDown',\n        'mdAndDown',\n        'lgAndDown',\n        'xlAndDown',\n      ],\n    ],\n    [\n      {\n        description: 'Galaxy S5 (landscape)',\n        width: 640,\n        height: 360,\n        name: 'sm',\n      },\n      [\n        'sm',\n        'smAndDown',\n        'smAndUp',\n        'mdAndDown',\n        'lgAndDown',\n        'xlAndDown',\n      ],\n    ],\n    [\n      {\n        description: 'iPhone 6 (portrait)',\n        width: 375,\n        height: 667,\n        name: 'xs',\n      },\n      [\n        'xs',\n        'smAndDown',\n        'mdAndDown',\n        'lgAndDown',\n        'xlAndDown',\n      ],\n    ],\n    [\n      {\n        description: 'iPhone 6 (landscape)',\n        width: 667,\n        height: 375,\n        name: 'sm',\n      },\n      [\n        'sm',\n        'smAndDown',\n        'smAndUp',\n        'mdAndDown',\n        'lgAndDown',\n        'xlAndDown',\n      ],\n    ],\n    [\n      {\n        description: 'iPad (portrait)',\n        width: 768,\n        height: 1024,\n        name: 'sm',\n      },\n      [\n        'sm',\n        'smAndDown',\n        'smAndUp',\n        'mdAndDown',\n        'lgAndDown',\n        'xlAndDown',\n      ],\n    ],\n    [\n      {\n        description: 'iPad (landscape)',\n        width: 1024,\n        height: 768,\n        name: 'md',\n      },\n      [\n        'md',\n        'smAndUp',\n        'mdAndDown',\n        'mdAndUp',\n        'lgAndDown',\n        'xlAndDown',\n      ],\n    ],\n    [\n      {\n        description: 'iPad Pro (portrait)',\n        width: 1024,\n        height: 1366,\n        name: 'md',\n      },\n      [\n        'md',\n        'smAndUp',\n        'mdAndDown',\n        'mdAndUp',\n        'lgAndDown',\n        'xlAndDown',\n      ],\n    ],\n    [\n      {\n        description: 'iPad Pro (landscape)',\n        width: 1366,\n        height: 1024,\n        name: 'lg',\n      },\n      [\n        'lg',\n        'smAndUp',\n        'mdAndUp',\n        'lgAndDown',\n        'lgAndUp',\n        'xlAndDown',\n      ],\n    ],\n    [\n      {\n        description: 'WSXGA+ (portrait)',\n        width: 1050,\n        height: 1680,\n        name: 'md',\n      },\n      [\n        'md',\n        'smAndUp',\n        'mdAndDown',\n        'mdAndUp',\n        'lgAndDown',\n        'xlAndDown',\n      ],\n    ],\n    [\n      {\n        description: 'WSXGA+ (landscape)',\n        width: 1680,\n        height: 1050,\n        name: 'xl',\n      },\n      [\n        'xl',\n        'smAndUp',\n        'mdAndUp',\n        'lgAndUp',\n        'xlAndDown',\n        'xlAndUp',\n      ],\n    ],\n    [\n      {\n        description: 'FHD (portrait)',\n        width: 1080,\n        height: 1920,\n        name: 'md',\n      },\n      [\n        'md',\n        'smAndUp',\n        'mdAndDown',\n        'mdAndUp',\n        'lgAndDown',\n        'xlAndDown',\n      ],\n    ],\n    [\n      {\n        description: 'FHD (landscape)',\n        width: 1920,\n        height: 1080,\n        name: 'xl',\n      },\n      [\n        'xl',\n        'smAndUp',\n        'mdAndUp',\n        'lgAndUp',\n        'xlAndDown',\n        'xlAndUp',\n      ],\n    ],\n    [\n      {\n        description: 'WQHD (portrait)',\n        width: 1440,\n        height: 2560,\n        name: 'lg',\n      },\n      [\n        'lg',\n        'smAndUp',\n        'mdAndUp',\n        'lgAndDown',\n        'lgAndUp',\n        'xlAndDown',\n      ],\n    ],\n    [\n      {\n        description: 'WQHD (landscape)',\n        width: 2560,\n        height: 1440,\n        name: 'xxl',\n      },\n      [\n        'xxl',\n        'smAndUp',\n        'mdAndUp',\n        'lgAndUp',\n        'xlAndUp',\n      ],\n    ],\n  ])('should calculate breakpoint for $description', async (options, expected) => {\n    await page.viewport(options.width, options.height)\n\n    const scope = effectScope()\n    const display = scope.run(() => createDisplay())!\n\n    const matched = breakpoints.reduce<(typeof breakpoints[number])[]>((acc, breakpoint) => {\n      if (display[breakpoint].value) acc.push(breakpoint)\n      return acc\n    }, [])\n\n    expect(matched).toEqual(expected)\n  })\n\n  it('should override default thresholds', async () => {\n    const scope = effectScope()\n    const { name } = scope.run(() => createDisplay({\n      thresholds: { sm: 400 },\n    }))!\n\n    await page.viewport(400, 900)\n    await expect.poll(() => name.value).toBe('sm')\n\n    await page.viewport(399, 900)\n    await expect.poll(() => name.value).toBe('xs')\n  })\n\n  it('should allow breakpoint strings for mobileBreakpoint', async () => {\n    const scope = effectScope()\n    const { mobile } = scope.run(() => createDisplay({ mobileBreakpoint: 'lg' }))!\n\n    await page.viewport(1920, 900)\n    await expect.poll(() => mobile.value).toBe(false)\n\n    await page.viewport(600, 900)\n    await expect.poll(() => mobile.value).toBe(true)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/__tests__/elevation.spec.ts",
    "content": "// Composables\nimport { makeElevationProps, useElevation } from '../elevation'\n\n// Utilities\n\ndescribe('elevation.ts', () => {\n  it('should have the correct class', () => {\n    const values = [\n      [1, ['elevation-1']],\n      [undefined, []],\n      [null, []],\n      [5, ['elevation-5']],\n      [0, ['elevation-0']],\n      ['3', ['elevation-3']],\n    ] as const\n\n    for (const [elevation, equal] of values) {\n      const props = { elevation }\n      const { elevationClasses } = useElevation(props)\n\n      expect(elevationClasses.value).toEqual(equal)\n    }\n  })\n\n  it('should only allow numeric values at least 0 and no upper limit', () => {\n    const { elevation: { validator } } = makeElevationProps()\n    const validValues = [1, '5', 24]\n    const invalidValues = [-1, '-6.2', false, true] as any\n\n    for (const value of validValues) {\n      expect(validator(value)).toBe(true)\n    }\n\n    for (const value of invalidValues) {\n      expect(validator(value)).toBe(false)\n    }\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/__tests__/fileFilter.spec.ts",
    "content": "// Composables\nimport { useFileFilter } from '../fileFilter'\n\ndescribe('fileFilter', () => {\n  it('by extension', () => {\n    const { filterAccepted } = useFileFilter({ filterByType: '.pdf' })\n    const { accepted, rejected } = filterAccepted([\n      new File([], 'file_1.pdf', { type: 'application/pdf' }),\n      new File([], 'file_2.txt', { type: 'text/plain' }),\n      new File([], 'file_3.pdf', { type: 'application/pdf' }),\n      new File([], 'file_4.png', { type: 'image/png' }),\n    ])\n    expect(accepted.map(x => x.name)).toEqual(['file_1.pdf', 'file_3.pdf'])\n    expect(rejected.map(x => x.name)).toEqual(['file_2.txt', 'file_4.png'])\n  })\n\n  it('by type', () => {\n    const { filterAccepted } = useFileFilter({ filterByType: 'image/png, image/jpeg' })\n    const { accepted, rejected } = filterAccepted([\n      new File([], 'file_1.pdf', { type: 'application/pdf' }),\n      new File([], 'file_2.png', { type: 'image/png' }),\n      new File([], 'file_3.jpeg', { type: 'image/jpeg' }),\n      new File([], 'file_4.jpg', { type: 'image/jpeg' }),\n      new File([], 'file_5.htm', { type: 'text/html' }),\n    ])\n    expect(accepted.map(x => x.name)).toEqual(['file_2.png', 'file_3.jpeg', 'file_4.jpg'])\n    expect(rejected.map(x => x.name)).toEqual(['file_1.pdf', 'file_5.htm'])\n  })\n\n  it('by type with wildcard', () => {\n    const { filterAccepted } = useFileFilter({ filterByType: 'video/*' })\n    const { accepted, rejected } = filterAccepted([\n      new File([], 'file_1.mp4', { type: 'video/mp4' }),\n      new File([], 'file_2.mpeg', { type: 'video/mpeg' }),\n      new File([], 'file_3.gif', { type: 'image/gif' }),\n      new File([], 'file_4.wav', { type: 'audio/wav' }),\n    ])\n    expect(accepted.map(x => x.name)).toEqual(['file_1.mp4', 'file_2.mpeg'])\n    expect(rejected.map(x => x.name)).toEqual(['file_3.gif', 'file_4.wav'])\n  })\n\n  it('by mixed rules', () => {\n    const { filterAccepted } = useFileFilter({ filterByType: 'font/*,application/manifest+json,.zip' })\n    const { accepted, rejected } = filterAccepted([\n      new File([], 'file_1.css', { type: 'text/css' }),\n      new File([], 'file_2.jpg', { type: 'image/jpeg' }),\n      new File([], 'file_3.rar', { type: 'application/vnd.rar' }),\n      new File([], 'file_4.zip', { type: 'application/x-zip-compressed' }),\n      new File([], 'file_5.js', { type: 'text/javascript' }),\n      new File([], 'file_6.woff2', { type: 'font/woff2' }),\n      new File([], 'file_7.woff', { type: 'font/woff' }),\n      new File([], 'file_8.ico', { type: 'image/vnd.microsoft.icon' }),\n      new File([], 'file_9.webmanifest', { type: 'application/manifest+json' }),\n    ])\n    expect(accepted.map(x => x.name)).toEqual(['file_4.zip', 'file_6.woff2', 'file_7.woff', 'file_9.webmanifest'])\n    expect(rejected.map(x => x.name)).toEqual(['file_1.css', 'file_2.jpg', 'file_3.rar', 'file_5.js', 'file_8.ico'])\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/__tests__/filter.spec.ts",
    "content": "// Composables\nimport { defaultFilter, filterItems, useFilter } from '../filter'\nimport { transformItem, transformItems } from '../list-items'\n\n// Utilities\nimport { nextTick, ref } from 'vue'\nimport { deepEqual } from '@/util'\n\nconst itemProps = {\n  itemTitle: 'title',\n  itemValue: 'value',\n  itemType: 'type',\n  itemChildren: 'children',\n  itemProps: 'props',\n  returnObject: false,\n  valueComparator: deepEqual,\n}\n\ndescribe('filter', () => {\n  describe('defaultFilter', () => {\n    it.each([\n      [null, null, -1],\n      ['foo', null, -1],\n      ['foo', 'foo', [[0, 3]]],\n      ['foo', 'f', [[0, 1]]],\n      [null, 'foo', -1],\n      ['foo', 'bar', -1],\n      [1, '1', [[0, 1]]],\n      ['1', '1', [[0, 1]]],\n    ])('should compare %s to %s and return a match result', (text, query, expected) => {\n      // @ts-expect-error\n      expect(defaultFilter(text, query)).toStrictEqual(expected)\n    })\n  })\n\n  describe('filterItems', () => {\n    const items = Array.from({ length: 5 }, (v, k) => transformItem(itemProps, {\n      title: `Foo-${k}`,\n      value: `fizz-${k}`,\n    }))\n\n    it.each([\n      [['title'], 'foo', 5, [0, 1, 2, 3, 4]],\n      [['title', 'value'], 'fizz', 5, [0, 1, 2, 3, 4]],\n      [['title', 'value'], 'foo-0', 1, [0]],\n    ])('should filter items by some with %s filterKeys with query %s', (filterKeys: string[], query, expectedLength, expectedMatches) => {\n      const matches = filterItems(items, query, { filterKeys, filterMode: 'some' })\n      expect(matches).toHaveLength(expectedLength)\n      expect(matches.map(match => match.index)).toEqual(expectedMatches)\n    })\n\n    it.each([\n      [['title'], 'foo', 5],\n      [['title', 'value'], 'fizz', 0],\n      [['title', 'value'], 'foo-0', 0],\n      [['title', 'value'], '0', 1],\n    ])('should filter items by every with %s filterKeys with query %s', (filterKeys: string[], query, expected) => {\n      expect(filterItems(items, query, { filterKeys, filterMode: 'every' })).toHaveLength(expected)\n    })\n\n    it('should filter by mode using customKeyFilter', () => {\n      const customKeyFilter = {\n        title: (s: string, q: string) => s === q,\n        value: (s: string) => s === '1',\n      }\n      const items = [\n        { title: 'foo', subtitle: 'bar', value: '1', custom: '1' },\n        { title: 'fizz', subtitle: 'buzz', value: '1', custom: 'bar' },\n        { title: 'foobar', subtitle: 'fizzbuzz', value: '2', custom: 'bar' },\n        { title: 'buzz', subtitle: 'buzz', value: '1', custom: 'buzz' },\n      ] as any\n      const filterKeys = ['title', 'value', 'subtitle', 'custom']\n\n      expect(filterItems(items, 'foo', {\n        filterKeys,\n        customKeyFilter,\n        filterMode: 'some',\n      })).toHaveLength(3)\n\n      expect(filterItems(items, 'fizz', {\n        filterKeys,\n        customKeyFilter,\n        filterMode: 'union',\n      })).toHaveLength(2)\n\n      expect(filterItems(items, 'fizz', {\n        filterKeys,\n        customKeyFilter,\n        filterMode: 'intersection',\n      })).toHaveLength(0)\n\n      expect(filterItems(items, 'buzz', {\n        filterKeys,\n        customKeyFilter,\n        filterMode: 'every',\n      })).toHaveLength(1)\n    })\n\n    it('should filter by mode using customKeyFilter without query', () => {\n      const customKeyFilter = {\n        title: (s: string) => s.length < 5,\n        value: (s: string) => s === '1',\n      }\n      const items = [\n        { title: 'foo', subtitle: 'bar', value: '1' },\n        { title: 'fizz', subtitle: 'buzz', value: '1' },\n        { title: 'foobar', subtitle: 'fizzbuzz', value: '2' },\n        { title: 'buzz', subtitle: 'buzz', value: '2' },\n      ] as any\n      const filterKeys = ['title', 'value']\n\n      expect(filterItems(items, '', {\n        filterKeys,\n        customKeyFilter,\n        filterMode: 'some',\n      })).toHaveLength(3)\n\n      expect(filterItems(items, '', {\n        filterKeys,\n        customKeyFilter,\n        filterMode: 'union',\n      })).toHaveLength(2)\n\n      expect(filterItems(items, '', {\n        filterKeys,\n        customKeyFilter,\n        filterMode: 'intersection',\n      })).toHaveLength(2)\n\n      expect(filterItems(items, '', {\n        filterKeys,\n        customKeyFilter,\n        filterMode: 'every',\n      })).toHaveLength(2)\n    })\n\n    // https://github.com/vuetifyjs/vuetify/pull/21876\n    it('should return filtered rows when all columns have filters', () => {\n      const customKeyFilter = {\n        title: (s: string) => s.length < 5,\n        subtitle: (s: string) => s.startsWith('b'),\n        value: (s: any) => Number(s) > 0,\n      }\n      const items = [\n        { title: 'foo', subtitle: 'bar', value: 1 },\n        { title: 'fizz', subtitle: 'buzz', value: 1 },\n        { title: 'foobar', subtitle: 'fizzbuzz', value: 2 },\n      ] as any\n\n      expect(filterItems(items, '', {\n        customKeyFilter,\n        filterMode: 'intersection',\n      })).toHaveLength(2)\n    })\n  })\n\n  describe('useFilter', () => {\n    const items = Array.from({ length: 50 }, (v, k) => ({\n      text: `item-${k}`,\n      value: k,\n    }))\n\n    it.each([\n      ['', items.length],\n      [null, items.length],\n      ['1', 14],\n      [1, 14],\n      ['0', 5],\n      ['14', 1],\n      ['foo', 0],\n    ])('should return an array of filtered items from value %s', (text: any, expected: number) => {\n      const { filteredItems } = useFilter({}, ref(transformItems(itemProps, items)), ref(text))\n\n      expect(filteredItems.value).toHaveLength(expected)\n    })\n\n    it('should accept a custom filter function', async () => {\n      function filterFn (text: string, query?: string, item?: any) {\n        if (typeof query !== 'string') return true\n        return item.title.toLocaleLowerCase().includes(query.toLocaleLowerCase())\n      }\n      const query = ref('zz')\n      const props = { filterFn, filterKeys: ['title'] }\n      const items = ref(transformItems(itemProps, [\n        { title: 'foo' },\n        { title: 'bar' },\n        { title: 'fizz' },\n        { title: 'buzz' },\n      ]))\n      const { filteredItems } = useFilter(props, items, query)\n\n      expect(filteredItems.value.map(item => item.raw.title)).toEqual(['fizz', 'buzz'])\n\n      query.value = 'foo'\n      await nextTick()\n\n      expect(filteredItems.value.map(item => item.raw.title)).toEqual(['foo'])\n\n      items.value.push(transformItem(itemProps, { title: 'foobar' }))\n      await nextTick()\n\n      expect(filteredItems.value.map(item => item.raw.title)).toEqual(['foo', 'foobar'])\n    })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/__tests__/forwardRefs.spec.tsx",
    "content": "// Composables\nimport { forwardRefs } from '@/composables/forwardRefs'\n\n// Utilities\nimport { mount } from '@vue/test-utils'\nimport { defineComponent, ref } from 'vue'\nimport { useRender } from '@/util'\n\nconst VA = defineComponent({\n  name: 'VA',\n  setup () {\n    useRender(() => (\n      <div class=\"VA\"></div>\n    ))\n\n    return {\n      a: 1,\n    }\n  },\n})\nconst VB = defineComponent({\n  name: 'VB',\n\n  setup () {\n    const aRef = ref<InstanceType<typeof VA>>()\n\n    useRender(() => (\n      <div class=\"VB\">\n        <VA ref={ aRef } />\n      </div>\n    ))\n\n    return forwardRefs({\n      b: 2,\n    }, aRef)\n  },\n})\nconst VC = defineComponent({\n  name: 'VC',\n\n  setup () {\n    const bRef = ref<InstanceType<typeof VB>>()\n\n    useRender(() => (\n      <div class=\"VC\">\n        <VB ref={ bRef } />\n      </div>\n    ))\n\n    return forwardRefs({\n      c: 3,\n    }, bRef)\n  },\n})\nconst VD = defineComponent({\n  name: 'VD',\n\n  setup () {\n    const cRef = ref<InstanceType<typeof VC>>()\n\n    useRender(() => (\n      <div class=\"VD\">\n        <VC ref={ cRef } />\n      </div>\n    ))\n\n    return forwardRefs({\n      d: 4,\n    }, cRef)\n  },\n})\n\ndescribe('forwardRefs', () => {\n  it('one level', () => {\n    const wrapper = mount(VA)\n\n    expect(wrapper.vm.a).toBe(1)\n  })\n\n  it('two levels', () => {\n    const wrapper = mount(VB)\n\n    expect(wrapper.vm.b).toBe(2)\n    expect(wrapper.vm.a).toBe(1)\n  })\n\n  it('three levels', () => {\n    const wrapper = mount(VC)\n\n    expect(wrapper.vm.c).toBe(3)\n    expect(wrapper.vm.b).toBe(2)\n    expect(wrapper.vm.a).toBe(1)\n  })\n\n  it('four levels', () => {\n    const wrapper = mount(VD)\n\n    expect(wrapper.vm.d).toBe(4)\n    expect(wrapper.vm.c).toBe(3)\n    expect(wrapper.vm.b).toBe(2)\n    expect(wrapper.vm.a).toBe(1)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/__tests__/goto.spec.browser.tsx",
    "content": "// Utilities\nimport { render, screen, userEvent } from '@test'\nimport { defineComponent } from 'vue'\nimport { useGoTo } from '../goto'\n\nconst ComponentA = defineComponent({\n  props: {\n    target: String,\n  },\n\n  setup (props) {\n    const goTo = useGoTo()\n\n    function onClick () {\n      return goTo(props.target!)\n    }\n\n    return () => (\n      <button onClick={ onClick }>Click me</button>\n    )\n  },\n})\n\nconst ComponentB = defineComponent({\n  props: {\n    target: String,\n    container: String,\n  },\n\n  setup (props) {\n    const goTo = useGoTo()\n\n    function onClick () {\n      return goTo.horizontal(props.target!, { container: props.container })\n    }\n\n    return () => (\n      <button onClick={ onClick }>Click me</button>\n    )\n  },\n})\n\ndescribe('goto', () => {\n  it('scrolls vertically', async () => {\n    render(() => (\n      <div>\n        <ComponentA id=\"top\" target=\"#bottom\" />\n        <div style=\"height: 2000px\" />\n        <ComponentA id=\"bottom\" target=\"#top\" />\n      </div>\n    ))\n\n    const top = screen.getByCSS('#top')\n    const bottom = screen.getByCSS('#bottom')\n\n    await userEvent.click(top)\n    await expect.poll(() => window.scrollY).toBeCloseTo(1260, -1)\n\n    await userEvent.click(bottom)\n    await expect.poll(() => window.scrollY).toBe(0)\n  })\n\n  it('scrolls horizontally', async () => {\n    render(() => (\n      <div>\n        <ComponentB id=\"start\" target=\"#end\" />\n\n        <ComponentB id=\"end\" target=\"#start\" style=\"margin-inline-start: 2000px;\" />\n      </div>\n    ))\n\n    const start = screen.getByCSS('#start')\n    const end = screen.getByCSS('#end')\n\n    await userEvent.click(start)\n    await expect.poll(() => window.scrollX).toBeCloseTo(770, -1)\n\n    expect('target is not reachable').not.toHaveBeenTipped()\n\n    await userEvent.click(end)\n    await expect.poll(() => window.scrollX).toBe(0)\n\n    expect('target is not reachable').not.toHaveBeenTipped()\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/__tests__/group.spec.ts",
    "content": "// Utilities\nimport { mount } from '@vue/test-utils'\nimport { defineComponent, h, nextTick, reactive, useSlots } from 'vue'\nimport { makeGroupProps, useGroup, useGroupItem } from '../group'\n\ndescribe('group', () => {\n  describe('with complex values', () => {\n    const GroupItemComponent = defineComponent({\n      props: {\n        value: Object,\n      },\n      setup (props) {\n        // @ts-expect-error missing emit\n        const item = useGroupItem(props, Symbol.for('test'))\n        return () => h('div', {\n          class: {\n            selected: item.isSelected.value,\n          },\n          onClick: item.toggle,\n        }, [JSON.stringify(props.value)])\n      },\n    })\n\n    const GroupComponent = defineComponent({\n      props: {\n        modelValue: Object,\n      },\n      setup (props) {\n        // @ts-expect-error missing emit\n        useGroup(props, Symbol.for('test'))\n        return () => h('div', [\n          h(GroupItemComponent, { value: { foo: 1 } }),\n          h(GroupItemComponent, { value: { bar: 2 } }),\n        ])\n      },\n    })\n\n    it('should accept new value', async () => {\n      const wrapper = mount(GroupComponent)\n\n      expect(wrapper.html()).toMatchSnapshot()\n\n      await wrapper.setProps({ modelValue: { foo: 1 } })\n\n      expect(wrapper.html()).toMatchSnapshot()\n    })\n\n    it('should emit selected value', async () => {\n      const wrapper = mount(GroupComponent)\n\n      const item = wrapper.findAllComponents(GroupItemComponent)\n\n      await item[1].trigger('click')\n\n      expect(wrapper.emitted('update:modelValue')).toEqual([\n        [{ bar: 2 }],\n      ])\n\n      expect(wrapper.html()).toMatchSnapshot()\n    })\n  })\n\n  describe('with explicit values', () => {\n    const GroupItemComponent = defineComponent({\n      props: {\n        value: [String, Number],\n        disabled: Boolean,\n      },\n      setup (props) {\n        // @ts-expect-error missing emit\n        const item = useGroupItem(props, Symbol.for('test'))\n        return () => h('div', {\n          class: {\n            selected: item.isSelected.value,\n          },\n          onClick: item.toggle,\n        }, [props.value])\n      },\n    })\n\n    const GroupComponent = defineComponent({\n      props: {\n        ...makeGroupProps(),\n        disabledItems: Array,\n      },\n      setup (props) {\n        // @ts-expect-error missing emit\n        return useGroup(props, Symbol.for('test'))\n      },\n      render () {\n        return h('div', this.$slots.default?.() ?? [\n          h(GroupItemComponent, { value: 'one', disabled: !!this.disabledItems?.[0] }),\n          h(GroupItemComponent, { value: 'two', disabled: !!this.disabledItems?.[1] }),\n        ])\n      },\n    })\n\n    it('should emit new selection', async () => {\n      const wrapper = mount(GroupComponent)\n\n      const item = wrapper.findComponent(GroupItemComponent)\n\n      await item.trigger('click')\n\n      expect(wrapper.emitted('update:modelValue')).toEqual([\n        ['one'],\n      ])\n\n      expect(wrapper.html()).toMatchSnapshot()\n    })\n\n    it('should not emit new selection if clicking disabled item', async () => {\n      const wrapper = mount(GroupComponent, {\n        props: {\n          disabledItems: [true, false],\n        },\n      })\n\n      const item = wrapper.findComponent(GroupItemComponent)\n\n      await item.trigger('click')\n\n      expect(wrapper.emitted('update:modelValue')).toBeUndefined()\n\n      expect(wrapper.html()).toMatchSnapshot()\n    })\n\n    it('should accept initial value', async () => {\n      const wrapper = mount(GroupComponent, {\n        props: {\n          modelValue: 'two',\n          multiple: false,\n          mandatory: false,\n        },\n      })\n\n      const items = wrapper.findAllComponents(GroupItemComponent)\n\n      await items[1].trigger('click')\n      await items[0].trigger('click')\n\n      expect(wrapper.emitted('update:modelValue')).toEqual([\n        [undefined],\n        ['one'],\n      ])\n    })\n\n    it('should allow multiple selection', async () => {\n      const wrapper = mount(GroupComponent, {\n        props: {\n          multiple: true,\n          mandatory: false,\n        },\n      })\n\n      const items = wrapper.findAllComponents(GroupItemComponent)\n\n      await items[1].trigger('click')\n      await items[0].trigger('click')\n\n      expect(wrapper.emitted()['update:modelValue']).toEqual([\n        [['two']],\n        [['two', 'one']],\n      ])\n    })\n\n    it('should set first non-disabled item as value when forced mandatory', async () => {\n      const wrapper = mount(GroupComponent, {\n        props: {\n          mandatory: 'force',\n          multiple: false,\n          disabledItems: [true, false],\n        },\n      })\n\n      expect(wrapper.emitted()['update:modelValue']).toEqual([\n        ['two'],\n      ])\n    })\n\n    it('should not allow empty value when mandatory', async () => {\n      const wrapper = mount(GroupComponent, {\n        props: {\n          modelValue: 'one',\n          mandatory: true,\n          multiple: false,\n        },\n      })\n\n      wrapper.findAllComponents(GroupItemComponent)\n\n      const items = wrapper.findAllComponents(GroupItemComponent)\n\n      await items[0].trigger('click')\n\n      expect(wrapper.emitted()).not.toHaveProperty('update:modelValue')\n    })\n\n    it('should not allow selection bigger than max', async () => {\n      const wrapper = mount(GroupComponent, {\n        props: {\n          mandatory: false,\n          multiple: true,\n          max: 1,\n        },\n      })\n\n      wrapper.findAllComponents(GroupItemComponent)\n\n      const items = wrapper.findAllComponents(GroupItemComponent)\n\n      await items[0].trigger('click')\n      await items[1].trigger('click')\n\n      expect(wrapper.emitted()['update:modelValue']).toEqual([\n        [['one']],\n      ])\n    })\n\n    it('should select newly inserted value', async () => {\n      const values = reactive(['one', 'two'])\n      const wrapper = mount(GroupComponent, {\n        props: {\n          modelValue: 'one',\n          multiple: false,\n          mandatory: false,\n        },\n        slots: {\n          default () {\n            return values.map(value => h(GroupItemComponent, { value, key: value }))\n          },\n        },\n      })\n\n      values.splice(1, 0, 'three')\n      await nextTick()\n      wrapper.vm.next()\n      await nextTick()\n\n      expect(wrapper.emitted()['update:modelValue']).toEqual([\n        ['three'],\n      ])\n    })\n  })\n\n  describe('with implicit values', () => {\n    const GroupItemComponent = defineComponent({\n      props: {\n        disabled: Boolean,\n      },\n      setup (props) {\n        // @ts-expect-error missing emit\n        const item = useGroupItem(props, Symbol.for('test'))\n        return () => h('div', {\n          class: {\n            selected: item.isSelected.value,\n          },\n          onClick: item.toggle,\n        }, [])\n      },\n    })\n\n    const GroupComponent = defineComponent({\n      props: {\n        ...makeGroupProps(),\n        disabledItems: Array,\n      },\n      setup (props) {\n        // @ts-expect-error missing emit\n        useGroup(props, Symbol.for('test'))\n        const slot = useSlots()\n        return () => h('div', slot.default?.() ?? [\n          h(GroupItemComponent, { disabled: !!props.disabledItems?.[0] }),\n          h(GroupItemComponent, { disabled: !!props.disabledItems?.[1] }),\n        ])\n      },\n    })\n\n    it('should emit new selection', async () => {\n      const wrapper = mount(GroupComponent)\n\n      const item = wrapper.findComponent(GroupItemComponent)\n\n      await item.trigger('click')\n\n      expect(wrapper.emitted('update:modelValue')).toStrictEqual([[0]])\n      expect(wrapper.html()).toMatchSnapshot()\n    })\n\n    it('should default to single selection', async () => {\n      const wrapper = mount(GroupComponent)\n\n      const items = wrapper.findAllComponents(GroupItemComponent)\n\n      await items[1].trigger('click')\n      await items[0].trigger('click')\n\n      expect(wrapper.emitted('update:modelValue')).toStrictEqual([[1], [0]])\n    })\n\n    it('should allow multiple selection', async () => {\n      const wrapper = mount(GroupComponent, {\n        props: {\n          multiple: true,\n          mandatory: false,\n        },\n      })\n\n      const items = wrapper.findAllComponents(GroupItemComponent)\n\n      await items[1].trigger('click')\n      await items[0].trigger('click')\n\n      expect(wrapper.emitted('update:modelValue')).toStrictEqual([\n        [[1]],\n        [[1, 0]],\n      ])\n    })\n\n    it('should set first non-disabled item as value when forced mandatory', async () => {\n      const wrapper = mount(GroupComponent, {\n        props: {\n          mandatory: 'force',\n          multiple: false,\n          disabledItems: [true, false],\n        },\n      })\n\n      // selection happens in mounted so we need to await\n      // to be able to match snapshot\n      await wrapper.vm.$nextTick()\n\n      expect(wrapper.emitted()['update:modelValue']).toHaveLength(1)\n      expect(wrapper.html()).toMatchSnapshot()\n    })\n\n    it('should not allow empty value when mandatory', async () => {\n      const wrapper = mount(GroupComponent, {\n        props: {\n          mandatory: true,\n          multiple: false,\n        },\n      })\n\n      wrapper.findAllComponents(GroupItemComponent)\n\n      const items = wrapper.findAllComponents(GroupItemComponent)\n\n      await items[0].trigger('click')\n\n      expect(wrapper.emitted('update:modelValue')).toStrictEqual([[0]])\n    })\n\n    it('should not allow selection bigger than max', async () => {\n      const wrapper = mount(GroupComponent, {\n        props: {\n          multiple: true,\n          mandatory: false,\n          max: 1,\n        },\n      })\n\n      wrapper.findAllComponents(GroupItemComponent)\n\n      const items = wrapper.findAllComponents(GroupItemComponent)\n\n      await items[0].trigger('click')\n      await items[1].trigger('click')\n\n      expect(wrapper.emitted('update:modelValue')).toStrictEqual([[[0]]])\n    })\n\n    it('should update the items that use index as the value when delete', async () => {\n      const values = reactive(['one', 'two', 'three'])\n      const wrapper = mount(GroupComponent, {\n        props: {\n          multiple: false,\n          mandatory: false,\n        },\n        slots: {\n          default () {\n            return values.map(value => h(GroupItemComponent, { key: value }))\n          },\n        },\n      })\n      values.splice(1, 1)\n      values.push('four')\n      await nextTick()\n      let items = wrapper.findAllComponents(GroupItemComponent)\n\n      await items[1].trigger('click')\n      await items[2].trigger('click')\n\n      expect(wrapper.emitted()['update:modelValue']).toEqual([[1], [2]])\n\n      values.splice(1, 0, 'eight')\n      values.push('nine')\n      await nextTick()\n      items = wrapper.findAllComponents(GroupItemComponent)\n\n      await items[3].trigger('click')\n      await items[4].trigger('click')\n\n      expect(wrapper.emitted()['update:modelValue']).toEqual([[1], [2], [3], [4]])\n    })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/__tests__/icons.spec.ts",
    "content": "// Composables\nimport { useIcon } from '../icons'\n\n// Utilities\nimport { unfill } from '@test'\nimport { mount } from '@vue/test-utils'\nimport { defineComponent, toRef } from 'vue'\nimport { createVuetify } from '@/framework'\n\ndescribe('icons.tsx', () => {\n  const Component = defineComponent({\n    props: {\n      icon: String,\n    },\n    setup (props) {\n      const { iconData } = useIcon(toRef(props, 'icon'))\n\n      return () => iconData.value.icon\n    },\n  })\n\n  const vuetify = createVuetify({\n    icons: {\n      defaultSet: 'mdi',\n      sets: {\n        custom: {\n          component: () => null,\n        },\n      },\n    },\n  })\n\n  it.each([\n    // Default icon set.\n    ['success', 'success'],\n    ['https://example.com/icon.svg', 'https://example.com/icon.svg'],\n    // MDI icon set.\n    ['mdi:success', 'success'],\n    // Custom icon set.\n    ['custom:https://example.com/icon.png', 'https://example.com/icon.png'],\n  ])('should return the correct icon name', (icon, expected) => {\n    const wrapper = mount(Component, {\n      props: {\n        icon,\n      },\n      global: {\n        plugins: [vuetify],\n      },\n    })\n\n    expect(wrapper.text()).toEqual(expected)\n  })\n\n  it('has the same aliases in all presets', async () => {\n    const sets = {\n      fa: await import('@/iconsets/fa').then(m => m.aliases),\n      fa4: await import('@/iconsets/fa4').then(m => m.aliases),\n      faSvg: await import('@/iconsets/fa-svg').then(m => m.aliases),\n      md: await import('@/iconsets/md').then(m => m.aliases),\n      mdi: await import('@/iconsets/mdi').then(m => m.aliases),\n      mdiSvg: await import('@/iconsets/mdi-svg').then(m => m.aliases),\n      mdiUnoCss: await import('@/iconsets/mdi-unocss').then(m => m.aliases),\n    }\n    const mdi = unfill(sets.mdi)\n\n    for (const [name, value] of Object.entries(sets)) {\n      expect({ [name]: unfill(value) }).toStrictEqual(expect.objectContaining({ [name]: mdi }))\n    }\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/__tests__/list-items.spec.ts",
    "content": "// Composables\nimport { useItems } from '../list-items'\n\n// Utilities\nimport { deepEqual } from '@/util'\n\ndescribe('list-items', () => {\n  const defaults = {\n    itemTitle: 'title',\n    itemValue: 'value',\n    itemType: 'type',\n    itemChildren: 'children',\n    itemProps: () => ({}),\n    returnObject: false,\n    valueComparator: deepEqual,\n  }\n\n  it('should do nothing to empty array', () => {\n    const { items } = useItems({ ...defaults, items: [] })\n\n    expect(items.value).toEqual([])\n  })\n\n  it('should support string items', () => {\n    const { items } = useItems({ ...defaults, items: ['Foo'] })\n    expect(items.value).toEqual([\n      {\n        type: 'item',\n        title: 'Foo',\n        value: 'Foo',\n        props: {\n          title: 'Foo',\n          value: 'Foo',\n        },\n        raw: 'Foo',\n      },\n    ])\n  })\n\n  it('should use title as value if value is missing', () => {\n    const { items } = useItems({ ...defaults, items: [{ title: 'Foo' }] })\n    expect(items.value).toEqual([\n      {\n        type: 'item',\n        title: 'Foo',\n        value: 'Foo',\n        props: {\n          title: 'Foo',\n          value: 'Foo',\n        },\n        raw: { title: 'Foo' },\n      },\n    ])\n  })\n\n  it('should support custom itemTitle property', () => {\n    const { items } = useItems({ ...defaults, itemTitle: 'text', items: [{ text: 'Foo' }] })\n    expect(items.value).toEqual([\n      {\n        type: 'item',\n        title: 'Foo',\n        value: 'Foo',\n        props: {\n          title: 'Foo',\n          value: 'Foo',\n        },\n        raw: { text: 'Foo' },\n      },\n    ])\n  })\n\n  it('should support custom itemValue property', () => {\n    const { items } = useItems({ ...defaults, itemValue: 'id', items: [{ title: 'Foo', id: 1 }] })\n    expect(items.value).toEqual([\n      {\n        type: 'item',\n        title: 'Foo',\n        value: 1,\n        props: {\n          title: 'Foo',\n          value: 1,\n        },\n        raw: { title: 'Foo', id: 1 },\n      },\n    ])\n  })\n\n  it('should support nested items', () => {\n    const rawItems = [\n      {\n        title: 'Foo',\n        children: [\n          {\n            title: 'Bar',\n          },\n        ],\n      },\n    ]\n    const { items } = useItems({ ...defaults, items: rawItems })\n    expect(items.value).toEqual([\n      {\n        type: 'item',\n        title: 'Foo',\n        value: 'Foo',\n        props: {\n          title: 'Foo',\n          value: 'Foo',\n        },\n        children: [\n          {\n            type: 'item',\n            title: 'Bar',\n            value: 'Bar',\n            props: {\n              title: 'Bar',\n              value: 'Bar',\n            },\n            raw: rawItems[0].children[0],\n          },\n        ],\n        raw: rawItems[0],\n      },\n    ])\n  })\n\n  it('should support custom itemChildren property', () => {\n    const rawItems = [\n      {\n        title: 'Foo',\n        labels: [\n          {\n            title: 'Bar',\n          },\n        ],\n      },\n    ]\n    const { items } = useItems({ ...defaults, itemChildren: 'labels', items: rawItems })\n    expect(items.value).toEqual([\n      {\n        type: 'item',\n        title: 'Foo',\n        value: 'Foo',\n        props: {\n          title: 'Foo',\n          value: 'Foo',\n        },\n        children: [\n          {\n            type: 'item',\n            title: 'Bar',\n            value: 'Bar',\n            props: {\n              title: 'Bar',\n              value: 'Bar',\n            },\n            raw: rawItems[0].labels[0],\n          },\n        ],\n        raw: rawItems[0],\n      },\n    ])\n  })\n\n  it('should include itemProps', () => {\n    const rawItems = [\n      {\n        title: 'Foo',\n        prop: 1,\n      },\n      {\n        title: 'Bar',\n        prop: 2,\n      },\n    ]\n    const { items } = useItems({\n      ...defaults,\n      itemProps: item => ({ prop: item.prop, status: true }),\n      items: rawItems,\n    })\n\n    expect(items.value).toEqual([\n      {\n        type: 'item',\n        title: 'Foo',\n        value: 'Foo',\n        props: {\n          title: 'Foo',\n          value: 'Foo',\n          prop: 1,\n          status: true,\n        },\n        raw: rawItems[0],\n      },\n      {\n        type: 'item',\n        title: 'Bar',\n        value: 'Bar',\n        props: {\n          title: 'Bar',\n          value: 'Bar',\n          prop: 2,\n          status: true,\n        },\n        raw: rawItems[1],\n      },\n    ])\n  })\n\n  it('should return original objects when returnObject is true', () => {\n    const { items, transformOut } = useItems({ ...defaults, returnObject: true, items: [{ title: 'Foo', value: 1, status: true }] })\n    expect(transformOut(items.value)).toEqual([\n      { title: 'Foo', value: 1, status: true },\n    ])\n  })\n\n  it('should return value when returnObject is false', () => {\n    const { items, transformOut } = useItems({ ...defaults, returnObject: false, items: [{ title: 'Foo', value: 1, status: true }] })\n    expect(transformOut(items.value)).toEqual([\n      1,\n    ])\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/__tests__/loader.spec.ts",
    "content": "// Utilities\nimport { useLoader } from '../loader'\n\ndescribe('size', () => {\n  it.each([\n    [{ loading: true }, { 'v-component--loading': true }],\n    [{ loading: false }, { 'v-component--loading': false }],\n  ])('should return the correct class given value %p', (props, expected) => {\n    const { loaderClasses } = useLoader(props, 'v-component')\n\n    expect(loaderClasses.value).toEqual(expected)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/__tests__/location.spec.ts",
    "content": "// Composables\nimport { useLocation } from '../location'\n\n// Utilities\nimport { mount } from '@vue/test-utils'\n\n// Types\nimport { createVuetify } from '@/framework'\n\ndescribe('location', () => {\n  it.each([\n    ['top', { top: 0, left: '50%', transform: 'translateX(-50%)' }],\n    ['bottom', { bottom: 0, left: '50%', transform: 'translateX(-50%)' }],\n    ['start', { left: 0, top: '50%', transform: 'translateY(-50%)' }],\n    ['end', { right: 0, top: '50%', transform: 'translateY(-50%)' }],\n    ['center', { top: '50%', left: '50%', transform: 'translate(-50%, -50%)' }],\n    ['top start', { top: 0, left: 0 }],\n  ] as const)('placement=%s', (...args) => {\n    const [location, styles] = args\n    mount({\n      setup () {\n        const { locationStyles } = useLocation({ location })\n\n        expect(locationStyles.value).toEqual(styles)\n\n        return () => {}\n      },\n    }, {\n      global: {\n        plugins: [createVuetify()],\n      },\n    })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/__tests__/mutationObserver.spec.ts",
    "content": "// Composables\nimport { useMutationObserver } from '../mutationObserver'\n\n// Utilities\nimport { mount } from '@vue/test-utils'\nimport { h } from 'vue'\n\ndescribe('mutationObserver', () => {\n  it('should invoke callback on mounted', async () => {\n    const callback = vi.fn()\n    mount({\n      setup () {\n        const { mutationRef } = useMutationObserver(callback, { immediate: true })\n\n        return () => h('div', { ref: mutationRef }, ['foo'])\n      },\n    })\n\n    expect(callback).toHaveBeenCalledTimes(1)\n  })\n\n  it('should not invoke callback on mounted', async () => {\n    const callback = vi.fn()\n    mount({\n      setup () {\n        const { mutationRef } = useMutationObserver(callback)\n\n        return () => h('div', { ref: mutationRef }, ['foo'])\n      },\n    })\n\n    expect(callback).not.toHaveBeenCalled()\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/__tests__/position.spec.ts",
    "content": "// Composables\nimport { usePosition } from '../position'\n\n// Utilities\n\n// Types\nimport type { PositionProps } from '../position'\n\ndescribe('position', () => {\n  it.each([\n    [{ position: undefined }, undefined],\n    [{ position: false }, undefined],\n    [{ position: 'absolute' }, 'foo--absolute'],\n    [{ position: 'fixed' }, 'foo--fixed'],\n  ])('position=%s', (props, expected) => {\n    const { positionClasses } = usePosition(props as PositionProps, 'foo')\n\n    expect(positionClasses.value).toEqual(expected)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/__tests__/proxiedModel.spec.ts",
    "content": "// Composables\nimport { useProxiedModel } from '../proxiedModel'\n\n// Utilities\nimport { mount } from '@vue/test-utils'\nimport { defineComponent, h } from 'vue'\n\nconst TestComponent = defineComponent({\n  props: {\n    foo: String,\n  },\n  emits: ['update:foo'],\n  setup (props) {\n    const proxiedModel = useProxiedModel(props, 'foo', 'syncDefaultValue')\n    return () => h('div', {\n      onClick: () => proxiedModel.value = 'internal',\n    }, [props.foo, proxiedModel.value].join(','))\n  },\n})\n\nconst TestComponentWithPropDefaultValue = defineComponent({\n  props: {\n    foo: {\n      type: String,\n      default: 'propDefaultValue',\n    },\n  },\n  emits: ['update:foo'],\n  // eslint-disable-next-line sonarjs/no-identical-functions\n  setup (props) {\n    const proxiedModel = useProxiedModel(props, 'foo', 'syncDefaultValue')\n    // eslint-disable-next-line sonarjs/no-identical-functions\n    return () => h('div', {\n      onClick: () => proxiedModel.value = 'internal',\n    }, [props.foo, proxiedModel.value].join(','))\n  },\n})\n\nconst TestComponentWithModelValueProp = defineComponent({\n  props: {\n    modelValue: String,\n  },\n  emits: ['update:modelValue'],\n  setup (props) {\n    const proxiedModel = useProxiedModel(props, 'modelValue')\n    return () => h('div', {\n      onClick: () => proxiedModel.value = 'internal',\n    }, [props.modelValue, proxiedModel.value].join(','))\n  },\n})\n\ndescribe('useProxiedModel', () => {\n  it('should use default prop value as first value if defined', async () => {\n    const wrapper = mount(TestComponentWithPropDefaultValue)\n\n    expect(wrapper.element.textContent).toBe('propDefaultValue,propDefaultValue')\n\n    await wrapper.trigger('click')\n    expect(wrapper.element.textContent).toBe('propDefaultValue,internal')\n  })\n\n  it('should use prop value if defined with kebab case', async () => {\n    const wrapper = mount(TestComponentWithModelValueProp, {\n      props: {\n        'model-value': 'foobar',\n      },\n    })\n\n    expect(wrapper.element.textContent).toBe('foobar,foobar')\n  })\n\n  it('should use prop as initial value if defined', async () => {\n    const wrapper = mount(TestComponent, {\n      props: {\n        foo: 'bar',\n      },\n    })\n\n    expect(wrapper.element.textContent).toBe('bar,bar')\n\n    await wrapper.trigger('click')\n    expect(wrapper.emitted('update:foo')).toStrictEqual([['internal']])\n\n    expect(wrapper.element.textContent).toBe('bar,internal')\n\n    await wrapper.setProps({ foo: 'external' })\n    expect(wrapper.element.textContent).toBe('external,external')\n  })\n\n  it('should always use prop value if update listener defined', async () => {\n    const wrapper = mount(TestComponent, {\n      props: {\n        foo: 'bar',\n        'onUpdate:foo': () => {},\n      },\n    })\n\n    expect(wrapper.element.textContent).toBe('bar,bar')\n\n    await wrapper.trigger('click')\n    expect(wrapper.emitted('update:foo')).toStrictEqual([['internal']])\n\n    // internal value should not change until prop is updated\n    expect(wrapper.element.textContent).toBe('bar,bar')\n\n    await wrapper.setProps({ foo: 'external' })\n    expect(wrapper.element.textContent).toBe('external,external')\n  })\n\n  it('should use internal value if prop not defined', async () => {\n    const wrapper = mount(TestComponent, {\n      props: { foo: '' },\n    })\n\n    expect(wrapper.element.textContent).toBe(',')\n\n    await wrapper.trigger('click')\n    expect(wrapper.emitted('update:foo')).toStrictEqual([['internal']])\n\n    // internal value should have changed since prop is not defined\n    expect(wrapper.element.textContent).toBe(',internal')\n  })\n\n  it('should switch to using prop when it is defined', async () => {\n    const wrapper = mount(TestComponent, {\n      props: { foo: '' },\n    })\n\n    expect(wrapper.element.textContent).toBe(',')\n\n    await wrapper.trigger('click')\n\n    expect(wrapper.element.textContent).toBe(',internal')\n\n    await wrapper.setProps({ foo: 'new' })\n\n    expect(wrapper.element.textContent).toBe('new,new')\n  })\n\n  describe('transforms', () => {\n    const TestComponentTransformed = defineComponent({\n      props: {\n        foo: Array,\n      },\n      emits: ['update:foo'],\n      setup (props) {\n        const proxiedModel = useProxiedModel(props, 'foo', [],\n          arr => {\n            return (arr ?? []).map(String)\n          },\n          arr => {\n            return arr.map(v => parseInt(v, 10))\n          },\n        )\n\n        return () => h('div', {\n          onClick: () => proxiedModel.value = ['2', '3', '4'],\n        }, [JSON.stringify(proxiedModel.value)])\n      },\n    })\n\n    it('should transform prop value', async () => {\n      const wrapper = mount(TestComponentTransformed, {\n        props: {\n          foo: [1, 2, 3],\n        },\n      })\n\n      expect(wrapper.element.textContent).toBe('[\"1\",\"2\",\"3\"]')\n    })\n\n    it('should emit transformed value', async () => {\n      const wrapper = mount(TestComponentTransformed, {\n        props: {\n          foo: [1, 2, 3],\n        },\n      })\n\n      await wrapper.trigger('click')\n      expect(wrapper.emitted('update:foo')).toStrictEqual([[[2, 3, 4]]])\n    })\n\n    it('should use internal value if prop not defined', async () => {\n      const wrapper = mount(TestComponentTransformed)\n\n      expect(wrapper.element.textContent).toBe('[]')\n\n      await wrapper.trigger('click')\n      expect(wrapper.emitted('update:foo')).toStrictEqual([[[2, 3, 4]]])\n\n      expect(wrapper.element.textContent).toBe('[\"2\",\"3\",\"4\"]')\n    })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/__tests__/resizeObserver.spec.browser.tsx",
    "content": "// Composables\nimport { useResizeObserver } from '../resizeObserver'\n\n// Utilities\nimport { render, screen, waitIdle } from '@test'\n\ndescribe('resizeObserver', () => {\n  it('calls the callback after mount', async () => {\n    const callback = vi.fn()\n    render({\n      setup () {\n        const { resizeRef } = useResizeObserver(callback)\n\n        return () => <div ref={ resizeRef }>foo</div>\n      },\n    })\n\n    expect(screen.getByText('foo')).toBeVisible()\n\n    await waitIdle()\n\n    expect(callback).toHaveBeenCalledTimes(1)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/__tests__/rounded.spec.ts",
    "content": "// Composables\nimport { makeRoundedProps, useRounded } from '../rounded'\n\n// Utilities\nimport { mount } from '@vue/test-utils'\nimport { toRef } from 'vue'\n\n// Types\nimport type { RoundedProps } from '../rounded'\n\ndescribe('rounded.ts', () => {\n  it('should create rounded props', () => {\n    const wrapper = mount({\n      props: makeRoundedProps(),\n      template: '<div/>',\n    }, {\n      propsData: { rounded: true },\n    })\n\n    expect(wrapper.props().rounded).toBeDefined()\n  })\n\n  it.each([\n    // When should return nothing\n    [{}, []],\n    [{ rounded: null }, []],\n    [{ rounded: 1 }, []],\n    // Rounded only\n    [{ rounded: true }, ['foo--rounded']],\n    [{ rounded: '' }, ['foo--rounded']],\n    // Rounded with 0\n    [{ rounded: '0' }, ['rounded-0']],\n    [{ rounded: 0 }, ['rounded-0']],\n    [{ rounded: false }, ['rounded-0']],\n    // Rounded with a word\n    [{ rounded: 'circle' }, ['rounded-circle']],\n    [{ rounded: 'shaped' }, ['rounded-shaped']],\n    [{ rounded: 'pill' }, ['rounded-pill']],\n    // Corner and axis rounded\n    [{ rounded: 'te-xl be-lg' }, ['rounded-te-xl', 'rounded-be-lg']],\n  ] as RoundedProps[])('should return correct rounded classes', (props: RoundedProps, expected: any) => {\n    const { roundedClasses } = useRounded(props, 'foo')\n\n    expect(roundedClasses.value).toStrictEqual(expected)\n  })\n\n  it.each([\n    [null, []],\n    [1, []],\n    // Rounded only\n    [true, ['foo--rounded']],\n    ['', ['foo--rounded']],\n    // Rounded with 0\n    [0, ['rounded-0']],\n    [false, ['rounded-0']],\n    // Rounded with a word\n    ['circle', ['rounded-circle']],\n    // Corner and axis rounded\n    ['te-xl be-lg', ['rounded-te-xl', 'rounded-be-lg']],\n  ])('should return same result when props are passed as ref', (rounded: RoundedProps['rounded'], expected: any) => {\n    const { roundedClasses } = useRounded(toRef(() => rounded), 'foo')\n\n    expect(roundedClasses.value).toStrictEqual(expected)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/__tests__/router.spec.browser.tsx",
    "content": "// Utilities\nimport { render, screen, userEvent, wait } from '@test'\nimport { defineComponent, h, nextTick, ref, shallowRef } from 'vue'\nimport { createRouter, createWebHistory } from 'vue-router'\nimport { useLink } from '../router'\n\ndescribe('useLink', () => {\n  const TestComponent = defineComponent({\n    props: {\n      href: String,\n      replace: Boolean,\n      to: [String, Object],\n      exact: Boolean,\n      disabled: Boolean,\n    },\n    setup (props, { attrs }) {\n      const link = useLink(props, attrs)\n\n      return { link }\n    },\n    render () {\n      return h('a', {\n        ...this.link.linkProps,\n        onClick: this.link.navigate.value,\n      }, 'Test link')\n    },\n  })\n\n  let pageReloadAttempted = false\n  const preventPageReload = (e: MouseEvent) => {\n    if ((e.target as Element).closest('a[href]') && !e.defaultPrevented) {\n      e.preventDefault()\n      pageReloadAttempted = true\n    }\n  }\n\n  beforeEach(() => {\n    pageReloadAttempted = false\n    document.addEventListener('click', preventPageReload)\n  })\n\n  afterEach(() => {\n    document.removeEventListener('click', preventPageReload)\n  })\n\n  function createTestRouter () {\n    return createRouter({\n      history: createWebHistory(),\n      routes: [\n        { path: '/', name: 'home', component: { setup: () => () => h('div', 'home') } },\n        { path: '/page1', name: 'page1', component: { setup: () => () => h('div', 'page1') } },\n        { path: '/page2', name: 'page2', component: { setup: () => () => h('div', 'page2') } },\n      ],\n    })\n  }\n\n  it('should navigate to correct route', async () => {\n    const router = createTestRouter()\n    expect(router.currentRoute.value.fullPath).toBe('/')\n\n    render(() => (\n      <TestComponent to={{ name: 'page1' }} exact />\n    ), { global: { plugins: [router] } })\n\n    await userEvent.click(screen.getByCSS('a[href]'))\n    await nextTick()\n\n    expect(pageReloadAttempted).toBeFalsy()\n    expect(router.currentRoute.value.fullPath).toBe('/page1')\n  })\n\n  it('should adapt when props change', async () => {\n    const router = createTestRouter()\n    expect(router.currentRoute.value.fullPath).toBe('/')\n\n    const to = ref<{ name: string }>({ name: 'page1' })\n    const linkRef = shallowRef<InstanceType<typeof TestComponent>>()\n\n    render(() => (\n      <TestComponent ref={ linkRef } to={ to.value } exact />\n    ), { global: { plugins: [router] } })\n\n    const { link } = linkRef.value!\n\n    expect(link.route?.value?.fullPath).toBe('/page1')\n    await userEvent.click(screen.getByCSS('a[href]'))\n    await nextTick()\n\n    expect(pageReloadAttempted).toBeFalsy()\n    pageReloadAttempted = false\n    expect(router.currentRoute.value.fullPath).toBe('/page1')\n\n    to.value = { name: 'page2' }\n    await nextTick()\n    expect(link.route?.value?.fullPath).toBe('/page2')\n    await userEvent.click(screen.getByCSS('a[href]'))\n    await nextTick()\n\n    expect(pageReloadAttempted).toBeFalsy()\n    expect(router.currentRoute.value.fullPath).toBe('/page2')\n  })\n\n  it('should navigate without page reload when props are initialized with delay', async () => {\n    const router = createTestRouter()\n    expect(router.currentRoute.value.fullPath).toBe('/')\n\n    const to = ref<{ name: string } | undefined>(undefined)\n    const linkRef = shallowRef<InstanceType<typeof TestComponent>>()\n\n    render(() => (\n      <TestComponent ref={ linkRef } to={ to.value } exact />\n    ), { global: { plugins: [router] } })\n\n    expect(linkRef.value!.link.route.value).toBeUndefined()\n    await nextTick()\n\n    to.value = { name: 'page1' }\n    await nextTick()\n\n    const anchor = screen.getByCSS('a[href]')\n    expect(anchor.getAttribute('href')).toBe('/page1')\n\n    await userEvent.click(anchor)\n\n    expect(pageReloadAttempted).toBeFalsy()\n    expect(router.currentRoute.value.fullPath).toBe('/page1')\n  })\n\n  it('should correctly set active state', async () => {\n    const router = createTestRouter()\n    expect(router.currentRoute.value.fullPath).toBe('/')\n\n    const to = ref<{ name: string }>({ name: 'page1' })\n    const linkRef = shallowRef<InstanceType<typeof TestComponent>>()\n\n    render(() => (\n      <TestComponent ref={ linkRef } to={ to.value } exact />\n    ), { global: { plugins: [router] } })\n\n    const { link } = linkRef.value!\n\n    await userEvent.click(screen.getByCSS('a[href]'))\n    await nextTick()\n    expect(pageReloadAttempted).toBeFalsy()\n    expect(link.isActive?.value).toBe(true)\n\n    to.value = { name: 'page2' }\n    await wait()\n    expect(link.isActive?.value).toBe(false)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/__tests__/scroll.spec.browser.tsx",
    "content": "// Composables\nimport { makeScrollProps, useScroll } from '../scroll'\n\n// Utilities\nimport { render, scroll, wait } from '@test'\nimport { defineComponent, reactive } from 'vue'\n\n// Types\nimport type { UnwrapNestedRefs } from 'vue'\nimport type { ScrollProps } from '../scroll'\n\ndescribe('useScroll', () => {\n  function setup (props?: Partial<ScrollProps>) {\n    let data!: UnwrapNestedRefs<ReturnType<typeof useScroll>>\n    render(defineComponent({\n      props: makeScrollProps(),\n      setup (props) {\n        data = reactive(useScroll(props))\n        return () => <div style=\"height: 2000px\" />\n      },\n    }), { props })\n    return { data }\n  }\n\n  it('should set isScrollingUp', async () => {\n    const { data } = setup()\n\n    await scroll({ top: 1000 })\n    expect(data.isScrollingUp).toBe(false)\n\n    await scroll({ top: 0 })\n    expect(data.isScrollingUp).toBe(true)\n  })\n\n  it.todo('should use a custom target', async () => {\n    // const thresholdMetCallback = vi.fn()\n    // mountFunction({}, {\n    //   props: { scrollTarget: 'body', scrollThreshold: 300 },\n    // })\n    //\n    // await wait()\n    // expect(thresholdMetCallback).not.toHaveBeenCalled()\n    //\n    // await scroll({ top: 1000 }, document.body)\n    // await expect.poll(() => thresholdMetCallback).toHaveBeenCalled()\n  })\n\n  it.todo('should do nothing if !canScroll', async () => {\n    // const thresholdMetCallback = vi.fn()\n    // mountFunction({\n    //   canScroll: ref(false),\n    // }, {\n    //   props: { scrollTarget: 'body', scrollThreshold: 300 },\n    // })\n    //\n    // await wait()\n    // expect(thresholdMetCallback).not.toHaveBeenCalled()\n    //\n    // await scroll({ top: 1000 }, document.body)\n    // await expect.poll(() => thresholdMetCallback).not.toHaveBeenCalled()\n  })\n\n  it.todo('should do something if canScroll', async () => {\n    // const thresholdMetCallback = vi.fn()\n    // mountFunction({\n    //   canScroll: ref(true),\n    // }, {\n    //   props: { scrollTarget: 'body', scrollThreshold: 300 },\n    // })\n    //\n    // await wait()\n    // expect(thresholdMetCallback).not.toHaveBeenCalled()\n    //\n    // await scroll({ top: 1000 }, document.body)\n    // await expect.poll(() => thresholdMetCallback).toHaveBeenCalled()\n  })\n\n  it('should reset savedScroll when isActive state changes', async () => {\n    const { data } = setup()\n\n    await scroll({ top: 1000 })\n    expect(data.savedScroll).toBe(0)\n\n    await scroll({ top: 900 })\n    expect(data.savedScroll).toBe(900)\n\n    data.isScrollActive = true\n    await wait()\n    expect(data.savedScroll).toBe(0)\n  })\n\n  it(`should warn if target isn't present`, async () => {\n    setup({ scrollTarget: '#test' })\n\n    await wait()\n    expect('Unable to locate element with identifier #test').toHaveBeenTipped()\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/__tests__/size.spec.ts",
    "content": "// Composables\nimport { useSize } from '../size'\n\n// Utilities\n\n// Utilities\n\ndescribe('size', () => {\n  it.each([\n    [{ size: 'x-small' }, 'test--size-x-small'],\n    [{ size: 'small' }, 'test--size-small'],\n    [{ size: 'default' }, 'test--size-default'],\n    [{ size: 'large' }, 'test--size-large'],\n    [{ size: 'x-large' }, 'test--size-x-large'],\n    [{ size: '100px' }, undefined],\n    [{ size: 100 }, undefined],\n    [{ size: undefined }, undefined],\n  ] as const)('should return the correct class given value %p', (...args) => {\n    const [input, expected] = args\n    const { sizeClasses } = useSize(input, 'test')\n\n    expect(sizeClasses.value).toStrictEqual(expected)\n  })\n\n  it.each([\n    [{ size: 'x-small' }, undefined],\n    [{ size: 'small' }, undefined],\n    [{ size: 'default' }, undefined],\n    [{ size: 'large' }, undefined],\n    [{ size: 'x-large' }, undefined],\n    [{ size: '100px' }, { width: '100px', height: '100px' }],\n    [{ size: 50 }, { width: '50px', height: '50px' }],\n    [{ size: undefined }, undefined],\n  ] as const)('should return the correct styles given value %p', (...args) => {\n    const [input, expected] = args\n    const { sizeStyles } = useSize(input, 'test')\n\n    expect(sizeStyles.value).toStrictEqual(expected)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/__tests__/tag.spec.ts",
    "content": "// Composables\nimport { makeTagProps } from '../tag'\n\n// Utilities\nimport { mount } from '@vue/test-utils'\nimport { h } from 'vue'\n\n// Types\nimport type { TagProps } from '../tag'\n\ndescribe('tag.ts', () => {\n  it('should use custom tag on rendered output', () => {\n    const TestComponent = {\n      props: makeTagProps(),\n      render: (props: TagProps) => h(props.tag),\n    }\n\n    const wrapper = mount(TestComponent, {\n      props: { tag: 'span' },\n    })\n\n    expect(wrapper.element.tagName).toBe('SPAN')\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/__tests__/theme.spec.ts",
    "content": "/* eslint-disable vitest/no-commented-out-tests */\n// Composables\nimport { createTheme } from '../theme'\n\n// Utilities\nimport { createApp } from 'vue'\n\n// Types\nimport type { App } from 'vue'\n\ndescribe('createTheme', () => {\n  let app: App\n\n  beforeEach(() => {\n    const child = document.querySelector('#vuetify-theme-stylesheet')\n    child && document.head.removeChild(child)\n    app = createApp({})\n  })\n\n  it('should create style element', async () => {\n    const { install } = createTheme()\n\n    install(app)\n\n    expect(document.head).toMatchSnapshot()\n  })\n\n  it('should not generate style element if disabled', async () => {\n    const { install } = createTheme(false)\n\n    install(app)\n\n    expect(document.head).toMatchSnapshot()\n  })\n\n  it('should generate on-* colors', async () => {\n    const theme = createTheme()\n\n    theme.install(app)\n\n    const colors = [\n      'on-background',\n      'on-surface',\n      'on-primary',\n      'on-secondary',\n      'on-success',\n      'on-warning',\n      'on-error',\n      'on-info',\n    ]\n\n    for (const color of colors) {\n      expect(theme.computedThemes.value.light.colors).toHaveProperty(color)\n    }\n  })\n\n  it('should generate color variants', async () => {\n    const theme = createTheme({\n      variations: {\n        colors: ['primary', 'secondary'],\n        lighten: 2,\n        darken: 2,\n      },\n    })\n\n    theme.install(app)\n\n    for (const color of ['primary', 'secondary']) {\n      for (const variant of ['lighten', 'darken']) {\n        for (const amount of [1, 2]) {\n          expect(theme.computedThemes.value.light.colors).toHaveProperty(`${color}-${variant}-${amount}`)\n          expect(theme.computedThemes.value.light.colors).toHaveProperty(`on-${color}-${variant}-${amount}`)\n        }\n      }\n    }\n  })\n\n  it('should update existing theme', async () => {\n    const theme = createTheme({\n      variations: false,\n    })\n\n    theme.install(app)\n\n    expect(theme.computedThemes.value.light.colors.background).not.toBe('#FF0000')\n\n    theme.themes.value.light = {\n      ...theme.themes.value.light,\n      colors: {\n        ...theme.themes.value.light.colors,\n        background: '#FF0000',\n      },\n    }\n\n    expect(theme.computedThemes.value.light.colors.background).toBe('#FF0000')\n  })\n\n  it('should set a CSP nonce if configured', async () => {\n    const { install } = createTheme({ cspNonce: 'my-csp-nonce' })\n\n    install(app)\n\n    const styleElement = document.getElementById('vuetify-theme-stylesheet')\n    expect(styleElement?.getAttribute('nonce')).toBe('my-csp-nonce')\n  })\n\n  it('should not set a CSP nonce if option was left blank', async () => {\n    const { install } = createTheme({})\n\n    install(app)\n\n    const styleElement = document.getElementById('vuetify-theme-stylesheet')\n    expect(styleElement?.getAttribute('nonce')).toBeNull()\n  })\n\n  it('should merge custom theme based upon the supplied dark property', async () => {\n    for (const dark of [true, false, undefined]) {\n      const theme = createTheme({\n        defaultTheme: 'myTheme',\n        themes: { myTheme: { dark } },\n      })\n\n      theme.install(app)\n\n      expect(theme.computedThemes.value.myTheme.dark).toBe(dark)\n      expect(theme.computedThemes.value.myTheme.colors).toHaveProperty('primary')\n    }\n  })\n\n  it('should generate variations for custom color keys', async () => {\n    const theme = createTheme({\n      themes: {\n        light: {\n          colors: { color2: '#1697f6' },\n        },\n      },\n      variations: {\n        colors: ['color2'],\n        lighten: 1,\n        darken: 1,\n      },\n    })\n\n    theme.install(app)\n\n    expect(theme.computedThemes.value.light.colors).toHaveProperty('color2-darken-1')\n    expect(theme.computedThemes.value.light.colors).toHaveProperty('color2-lighten-1')\n  })\n\n  it('should allow for customization of the stylesheet id', () => {\n    const customStylesheetId = 'custom-vuetify-stylesheet-id'\n    const theme = createTheme({\n      stylesheetId: customStylesheetId,\n    })\n\n    theme.install(app)\n\n    expect(document.getElementById(customStylesheetId)).toBeDefined()\n  })\n\n  it('should allow for themes to be scoped', () => {\n    const theme = createTheme({\n      scope: '#my-app',\n    })\n\n    theme.install(app)\n\n    expect(document.head).toMatchSnapshot()\n  })\n\n  it('should properly integrate with unhead when available', async () => {\n    const mockPush = vi.fn().mockReturnValue({ patch: vi.fn() })\n    const mockUpdateHead = vi.fn()\n    const mockUseUnhead = {\n      push: mockPush,\n      updateDOM: mockUpdateHead,\n    }\n\n    // Mock the app context with head\n    app._context = {\n      provides: {\n        usehead: mockUseUnhead,\n      },\n    } as any\n\n    const theme = createTheme()\n    theme.install(app)\n\n    // Verify the head push method was called\n    expect(mockPush).toHaveBeenCalled()\n\n    // The push method should receive a function that returns an object with a style property\n    const headObj = mockPush.mock.calls[0][0]()\n    expect(headObj).toHaveProperty('style')\n    expect(Array.isArray(headObj.style)).toBe(true)\n    expect(headObj.style[0]).toHaveProperty('textContent')\n    expect(headObj.style[0]).toHaveProperty('id', 'vuetify-theme-stylesheet')\n  })\n\n  it('should work with legacy head client methods', async () => {\n    const mockAddHeadObjs = vi.fn()\n    const mockUpdateHead = vi.fn()\n    const mockLegacyHead = {\n      addHeadObjs: mockAddHeadObjs,\n      updateDOM: mockUpdateHead,\n    }\n\n    // Mock the app context with legacy head\n    app._context = {\n      provides: {\n        usehead: mockLegacyHead,\n      },\n    } as any\n\n    const theme = createTheme()\n    theme.install(app)\n\n    // Verify the legacy addHeadObjs method was called\n    expect(mockAddHeadObjs).toHaveBeenCalled()\n\n    // Verify updateDOM is called during reactivity\n    expect(mockUpdateHead).toHaveBeenCalled()\n  })\n\n  it('should change, toggle, and cycle theme', async () => {\n    const theme = createTheme({\n      defaultTheme: 'light',\n      themes: {\n        custom: { dark: false },\n        utopia: { dark: true },\n      },\n    })\n\n    // Test 1: Toggle through all available themes when no argument provided\n    expect(theme.name.value).toBe('light')\n\n    theme.toggle()\n    expect(theme.name.value).toBe('dark')\n\n    theme.toggle()\n    expect(theme.name.value).toBe('light')\n\n    // Test 2: Change to a specific theme\n    theme.change('dark')\n    expect(theme.name.value).toBe('dark')\n\n    // Test 3: Cycle between a limited set of themes\n    theme.cycle()\n    expect(theme.name.value).toBe('custom')\n\n    theme.cycle()\n    expect(theme.name.value).toBe('utopia')\n\n    theme.cycle()\n    expect(theme.name.value).toBe('light')\n\n    // Test 4: Cycle between a subset of themes\n    theme.cycle(['light', 'utopia'])\n    expect(theme.name.value).toBe('utopia')\n\n    theme.cycle(['light', 'utopia'])\n    expect(theme.name.value).toBe('light')\n\n    // Test 5: Error when changing to a non-existent theme\n    const consoleMock = vi.spyOn(console, 'warn').mockImplementation(() => {})\n    theme.change('nonexistent')\n    expect(consoleMock).toHaveBeenCalledWith('[Vue warn]: Vuetify: Theme \"nonexistent\" not found on the Vuetify theme instance')\n    consoleMock.mockReset()\n  })\n\n  it('should generate utility classes with a custom prefix', async () => {\n    // @ts-expect-error next-line\n    const theme = createTheme({ prefix: 'custom-' })\n\n    theme.install(app)\n\n    const stylesheet = document.getElementById('vuetify-theme-stylesheet')\n    const css = stylesheet!.innerHTML\n\n    expect(css).not.toContain('--v-theme-primary')\n    expect(css).toContain('--custom-theme-primary')\n  })\n\n  it('should use defined prefix for utility classes', async () => {\n    // @ts-expect-error next-line\n    const theme = createTheme({ prefix: 'custom-', scoped: true })\n\n    theme.install(app)\n\n    const stylesheet = document.getElementById('vuetify-theme-stylesheet')\n    const css = stylesheet!.innerHTML\n\n    expect(css).toContain('.custom-bg-primary')\n    expect(css).toContain('.custom-text-primary')\n    expect(css).toContain('.custom-border-primary')\n  })\n\n  it('should not generate utility classes if disabled', async () => {\n    const theme = createTheme({ utilities: false })\n\n    theme.install(app)\n\n    const stylesheet = document.getElementById('vuetify-theme-stylesheet')\n    const css = stylesheet!.innerHTML\n\n    expect(css).not.toContain('.bg-primary')\n    expect(css).not.toContain('.text-primary')\n    expect(css).not.toContain('.border-primary')\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/__tests__/validation.spec.ts",
    "content": "// Composables\nimport { makeValidationProps, useValidation } from '../validation'\n\n// Utilities\nimport { mount } from '@vue/test-utils'\nimport { defineComponent, nextTick } from 'vue'\n\n// Types\nimport type { ValidationProps } from '../validation'\n\ndescribe('validation', () => {\n  function mountFunction (props: Partial<ValidationProps> = {}) {\n    return mount(defineComponent({\n      props: makeValidationProps(),\n      emits: ['update:modelValue'],\n      setup (props) {\n        return useValidation(props, 'validation')\n      },\n      render: () => {}, // eslint-disable-line vue/require-render-return\n    }), { props })\n  }\n\n  it.each([\n    ['', [], []],\n    ['', ['foo'], ['foo']],\n    ['', [(v: any) => !!v || 'foo'], ['foo']],\n    ['', [(v: any) => !!v || ''], ['']],\n    ['', [(v: any) => Promise.resolve(!!v || 'fizz')], ['fizz']],\n    ['', [(v: any) => new Promise<boolean | string>(resolve => resolve(!!v || 'buzz'))], ['buzz']],\n    ['foo', [(v: any) => v === 'foo' || 'bar'], []],\n    ['foo', [(v: any) => v === 'bar' || 'fizz'], ['fizz']],\n    ['foo', [(v: any) => v === 'bar'], ['']],\n  ])('should validate rules and return array of errorMessages %#', async (modelValue, rules, expected) => {\n    const props = { rules, modelValue }\n    const wrapper = mountFunction(props)\n\n    expect(wrapper.vm.errorMessages).toEqual([])\n    await wrapper.vm.validate()\n    expect(wrapper.vm.errorMessages).toEqual(expected)\n  })\n\n  it.each([\n    [undefined, 1],\n    [0, 0],\n    [1, 1],\n    [2, 2],\n    [3, 3],\n    [4, 4],\n    [5, 4],\n  ])('only validate up to the maximum error count %s', async (maxErrors, expected) => {\n    const wrapper = mountFunction({\n      maxErrors,\n      rules: ['foo', 'bar', 'fizz', 'buzz'],\n    })\n\n    await wrapper.vm.validate()\n\n    expect(wrapper.vm.errorMessages).toHaveLength(expected)\n  })\n\n  it.each([\n    [undefined, 1],\n    [0, 0],\n    [1, 1],\n    [2, 2],\n    [3, 3],\n    [4, 4],\n    [5, 4],\n  ])('only display up to the maximum error count %s', async (maxErrors, expected) => {\n    const wrapper = mountFunction({\n      maxErrors,\n      errorMessages: ['foo', 'bar', 'fizz', 'buzz'],\n    })\n\n    await wrapper.vm.validate()\n\n    expect(wrapper.vm.errorMessages).toHaveLength(expected)\n  })\n\n  it.each([\n    [undefined, ['foo']],\n    [0, []],\n    [1, ['foo']],\n    [2, ['foo']],\n  ])('should not trim error message if passed as text', async (maxErrors, expected) => {\n    const wrapper = mountFunction({\n      maxErrors,\n      errorMessages: 'foo',\n    })\n\n    await wrapper.vm.validate()\n\n    expect(wrapper.vm.errorMessages).toStrictEqual(expected)\n  })\n\n  it('should warn the user when using an improper rule fn', async () => {\n    const rule = (v: any) => !!v || 1234\n    const wrapper = mountFunction({\n      rules: [rule as any],\n    })\n\n    await wrapper.vm.validate()\n\n    expect(`${1234} is not a valid value. Rule functions must return boolean true or a string.`).toHaveBeenTipped()\n  })\n\n  it('should update isPristine when using the validate and reset methods', async () => {\n    const wrapper = mountFunction({\n      rules: [(v: any) => v === 'foo' || 'bar'],\n      modelValue: '',\n    })\n\n    await nextTick()\n\n    expect(wrapper.vm.isPristine).toBe(true)\n    expect(wrapper.vm.isValid).toBeNull()\n\n    await wrapper.vm.validate()\n\n    expect(wrapper.vm.isPristine).toBe(false)\n    expect(wrapper.vm.isValid).toBe(false)\n\n    await wrapper.setProps({ modelValue: 'fizz' })\n\n    await nextTick()\n    await wrapper.vm.validate()\n\n    expect(wrapper.vm.isPristine).toBe(false)\n    expect(wrapper.vm.isValid).toBe(false)\n\n    await wrapper.setProps({ modelValue: 'foo' })\n\n    await nextTick()\n    await wrapper.vm.validate()\n\n    expect(wrapper.vm.isPristine).toBe(false)\n    expect(wrapper.vm.isValid).toBe(true)\n\n    wrapper.vm.reset()\n    await nextTick() // model update\n    await nextTick() // await rules\n\n    expect(wrapper.vm.isPristine).toBe(true)\n    expect(wrapper.vm.isValid).toBeNull()\n  })\n\n  it('should return valid if no rules are set', async () => {\n    const wrapper = mountFunction()\n\n    expect(wrapper.vm.isValid).toBe(true)\n\n    await wrapper.setProps({ rules: [] })\n\n    expect(wrapper.vm.isValid).toBe(true)\n\n    await wrapper.setProps({ error: true })\n\n    expect(wrapper.vm.isValid).toBe(false)\n  })\n\n  it('should return invalid if error is manually set', async () => {\n    const wrapper = mountFunction({\n      error: true,\n    })\n\n    expect(wrapper.vm.isValid).toBe(false)\n\n    await wrapper.setProps({ error: false, errorMessages: ['error'] })\n\n    expect(wrapper.vm.isValid).toBe(false)\n\n    await wrapper.setProps({ errorMessages: [] })\n\n    expect(wrapper.vm.isValid).toBe(true)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/__tests__/variant.spec.ts",
    "content": "// Composables\nimport { allowedVariants, makeVariantProps, useVariant } from '../variant'\n\n// Utilities\n\n// Utilities\n\ndescribe('variant', () => {\n  it.each([\n    [{ variant: 'default' }, 'test--variant-default'],\n    [{ variant: 'contained' }, 'test--variant-contained'],\n    [{ variant: 'outlined' }, 'test--variant-outlined'],\n    [{ variant: 'text' }, 'test--variant-text'],\n  ] as const)('should return the correct class given value %p', (...args) => {\n    const [input, expected] = args\n    // @ts-expect-error invalid variant\n    const { variantClasses } = useVariant(input, 'test')\n\n    expect(variantClasses.value).toStrictEqual(expected)\n  })\n\n  it('should only allow values from allowedVariants', () => {\n    const { variant: { validator } } = makeVariantProps()\n    const invalidValues = [-1, '25', false, true, null]\n\n    for (const value of allowedVariants) {\n      expect(validator(value)).toBe(true)\n    }\n\n    for (const value of invalidValues) {\n      expect(validator(value)).toBe(false)\n    }\n  })\n\n  it.each([\n    [{ color: 'primary' }, 'text-primary'],\n    [{ variant: 'default', color: 'primary' }, 'text-primary'],\n    [{ variant: 'elevated', color: 'primary' }, 'bg-primary'],\n    [{ variant: 'outlined', color: 'primary' }, 'text-primary'],\n    [{ variant: 'text', color: 'primary' }, 'text-primary'],\n  ] as const)('should return correct classes for %s props', (...args) => {\n    const [props, expected] = args\n    // @ts-expect-error invalid variant\n    const { colorClasses } = useVariant(props, 'test')\n\n    expect(colorClasses.value).toContain(expected)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/autocomplete.ts",
    "content": "// Utilities\nimport { shallowRef, toRef, useId } from 'vue'\nimport { propsFactory } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\n// Types\nexport interface InputAutocompleteProps {\n  autocomplete: 'suppress' | string | undefined\n  name?: string\n}\n\n// Composables\nexport const makeAutocompleteProps = propsFactory({\n  autocomplete: String as PropType<'suppress' | string>,\n}, 'autocomplete')\n\nexport function useAutocomplete (props: InputAutocompleteProps) {\n  const uniqueId = useId()\n  const reloadTrigger = shallowRef(0)\n\n  const isSuppressing = toRef(() => props.autocomplete === 'suppress')\n\n  const fieldName = toRef(() => {\n    if (!props.name) return undefined\n\n    return isSuppressing.value\n      ? `${props.name}-${uniqueId}-${reloadTrigger.value}`\n      : props.name\n  })\n\n  const fieldAutocomplete = toRef(() => {\n    return isSuppressing.value\n      ? 'off'\n      : props.autocomplete\n  })\n\n  return {\n    isSuppressing,\n    fieldAutocomplete,\n    fieldName,\n    update: () => reloadTrigger.value = new Date().getTime(),\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/autofocus.ts",
    "content": "interface AutofocusProps {\n  autofocus: boolean\n}\n\nexport function useAutofocus (props: AutofocusProps) {\n  function onIntersect (\n    isIntersecting: boolean,\n    entries: IntersectionObserverEntry[]\n  ) {\n    if (!props.autofocus || !isIntersecting) return\n\n    const el = entries[0].target\n    const target = (el.matches('input,textarea') ? el : el.querySelector('input,textarea')) as HTMLElement | null\n    target?.focus()\n  }\n\n  return {\n    onIntersect,\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/border.ts",
    "content": "// Utilities\nimport { computed } from 'vue'\nimport { getCurrentInstanceName, propsFactory } from '@/util'\n\n// Types\nexport interface BorderProps {\n  border?: boolean | number | string\n}\n\n// Composables\nexport const makeBorderProps = propsFactory({\n  border: [Boolean, Number, String],\n}, 'border')\n\nexport function useBorder (\n  props: BorderProps,\n  name = getCurrentInstanceName(),\n) {\n  const borderClasses = computed(() => {\n    const border = props.border\n\n    if (border === true || border === '') {\n      return `${name}--border`\n    } else if (\n      typeof border === 'string' ||\n      border === 0\n    ) {\n      return String(border).split(' ').map(v => `border-${v}`)\n    }\n\n    return []\n  })\n\n  return { borderClasses }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/calendar.ts",
    "content": "// Composables\nimport { useDate } from '@/composables/date/date'\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { computed } from 'vue'\nimport { propsFactory, wrapInArray } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\n// Types\nexport interface CalendarProps {\n  allowedDates: unknown[] | ((date: unknown) => boolean) | undefined\n  disabled: boolean\n  displayValue?: unknown\n  modelValue: unknown[] | undefined\n  max: unknown\n  min: unknown\n  showAdjacentMonths: boolean\n  month: number | string | undefined\n  weekdays: number[]\n  year: number | string | undefined\n  weeksInMonth: 'dynamic' | 'static'\n  firstDayOfWeek: number | string | undefined\n  firstDayOfYear: number | string | undefined\n  weekdayFormat: 'long' | 'short' | 'narrow' | undefined\n\n  'onUpdate:modelValue': ((value: unknown[]) => void) | undefined\n  'onUpdate:month': ((value: number) => void) | undefined\n  'onUpdate:year': ((value: number) => void) | undefined\n}\n\nexport type CalendarDay = {\n  date: Date\n  formatted: string\n  isAdjacent: boolean\n  isDisabled: boolean\n  isEnd: boolean\n  isHidden: boolean\n  isSame: boolean\n  isSelected: boolean\n  isStart: boolean\n  isToday: boolean\n  isWeekEnd: boolean\n  isWeekStart: boolean\n  isoDate: string\n  localized: string\n  month: number\n  year: number\n}\n\nexport type CalendarWeekdays = 0 | 1 | 2 | 3 | 4 | 5 | 6\n\n// Composables\nexport const makeCalendarProps = propsFactory({\n  allowedDates: [Array, Function] as PropType<unknown[] | ((date: unknown) => boolean)>,\n  disabled: {\n    type: Boolean,\n    default: null,\n  },\n  displayValue: null as any as PropType<unknown>,\n  modelValue: Array as PropType<unknown[]>,\n  month: [Number, String],\n  max: null as any as PropType<unknown>,\n  min: null as any as PropType<unknown>,\n  showAdjacentMonths: Boolean,\n  year: [Number, String],\n  weekdays: {\n    type: Array as PropType<CalendarWeekdays[]>,\n    default: () => [0, 1, 2, 3, 4, 5, 6],\n  },\n  weeksInMonth: {\n    type: String as PropType<'dynamic' | 'static'>,\n    default: 'dynamic',\n  },\n  firstDayOfWeek: {\n    type: [Number, String],\n    default: undefined,\n  },\n  firstDayOfYear: {\n    type: [Number, String],\n    default: undefined,\n  },\n  weekdayFormat: String as PropType<'long' | 'short' | 'narrow' | undefined>,\n}, 'calendar')\n\nexport function useCalendar (props: CalendarProps) {\n  const adapter = useDate()\n  const model = useProxiedModel(\n    props,\n    'modelValue',\n    [],\n    v => wrapInArray(v).map(i => adapter.date(i)),\n  )\n  const displayValue = computed(() => {\n    if (props.displayValue) return adapter.date(props.displayValue)\n    if (model.value.length > 0) return adapter.date(model.value[0])\n    if (props.min) return adapter.date(props.min)\n    if (Array.isArray(props.allowedDates)) return adapter.date(props.allowedDates[0])\n\n    return adapter.date()\n  })\n\n  const year = useProxiedModel(\n    props,\n    'year',\n    undefined,\n    v => {\n      const value = v != null ? Number(v) : adapter.getYear(displayValue.value)\n\n      return adapter.startOfYear(adapter.setYear(adapter.date(), value))\n    },\n    v => adapter.getYear(v)\n  )\n\n  const month = useProxiedModel(\n    props,\n    'month',\n    undefined,\n    v => {\n      const value = v != null ? Number(v) : adapter.getMonth(displayValue.value)\n      const date = adapter.setYear(adapter.startOfMonth(adapter.date()), adapter.getYear(year.value))\n\n      return adapter.setMonth(date, value)\n    },\n    v => adapter.getMonth(v)\n  )\n\n  const weekdayLabels = computed(() => {\n    const firstDayOfWeek = adapter.toJsDate(adapter.startOfWeek(adapter.date(), props.firstDayOfWeek)).getDay()\n    return adapter.getWeekdays(props.firstDayOfWeek, props.weekdayFormat)\n      .filter((_, i) => props.weekdays.includes((i + firstDayOfWeek) % 7))\n  })\n\n  const weeksInMonth = computed(() => {\n    const weeks = adapter.getWeekArray(month.value, props.firstDayOfWeek)\n\n    const days = weeks.flat()\n\n    // Make sure there's always 6 weeks in month (6 * 7 days)\n    // if weeksInMonth is 'static'\n    const daysInMonth = 6 * 7\n    if (props.weeksInMonth === 'static' && days.length < daysInMonth) {\n      const lastDay = days[days.length - 1]\n\n      let week = []\n      for (let day = 1; day <= daysInMonth - days.length; day++) {\n        week.push(adapter.addDays(lastDay, day))\n\n        if (day % 7 === 0) {\n          weeks.push(week)\n          week = []\n        }\n      }\n    }\n\n    return weeks\n  })\n\n  function genDays (days: Date[], today: Date): CalendarDay[] {\n    return days.filter(date => {\n      return props.weekdays.includes(adapter.toJsDate(date).getDay())\n    }).map((date, index) => {\n      const isoDate = adapter.toISO(date)\n      const isAdjacent = !adapter.isSameMonth(date, month.value)\n      const isStart = adapter.isSameDay(date, adapter.startOfMonth(month.value))\n      const isEnd = adapter.isSameDay(date, adapter.endOfMonth(month.value))\n      const isSame = adapter.isSameDay(date, month.value)\n      const weekdaysCount = props.weekdays.length\n\n      return {\n        date,\n        formatted: adapter.format(date, 'keyboardDate'),\n        isAdjacent,\n        isDisabled: isDisabled(date),\n        isEnd,\n        isHidden: isAdjacent && !props.showAdjacentMonths,\n        isSame,\n        isSelected: model.value.some(value => adapter.isSameDay(date, value)),\n        isStart,\n        isToday: adapter.isSameDay(date, today),\n        isWeekEnd: index % weekdaysCount === weekdaysCount - 1,\n        isWeekStart: index % weekdaysCount === 0,\n        isoDate,\n        localized: adapter.format(date, 'dayOfMonth'),\n        month: adapter.getMonth(date),\n        year: adapter.getYear(date),\n      }\n    })\n  }\n\n  const daysInWeek = computed(() => {\n    const lastDay = adapter.startOfWeek(displayValue.value, props.firstDayOfWeek)\n    const week: Date[] = []\n    for (let day = 0; day <= 6; day++) {\n      week.push(adapter.addDays(lastDay, day) as Date)\n    }\n\n    const today = adapter.date() as Date\n\n    return genDays(week as Date[], today as Date)\n  })\n\n  const daysInMonth = computed(() => {\n    const days = weeksInMonth.value.flat() as Date[]\n    const today = adapter.date() as Date\n\n    return genDays(days as Date[], today)\n  })\n\n  const weekNumbers = computed(() => {\n    return weeksInMonth.value.map(week => {\n      return week.length ? adapter.getWeek(week[0], props.firstDayOfWeek, props.firstDayOfYear) : null\n    })\n  })\n\n  const { minDate, maxDate } = useCalendarRange(props)\n\n  function isDisabled (value: unknown) {\n    if (props.disabled) return true\n\n    const date = adapter.date(value)\n\n    if (minDate.value && adapter.isBefore(adapter.endOfDay(date), minDate.value)) return true\n    if (maxDate.value && adapter.isAfter(date, maxDate.value)) return true\n\n    if (Array.isArray(props.allowedDates) && props.allowedDates.length > 0) {\n      return !props.allowedDates.some(d => adapter.isSameDay(adapter.date(d), date))\n    }\n\n    if (typeof props.allowedDates === 'function') {\n      return !props.allowedDates(date)\n    }\n\n    return false\n  }\n\n  return {\n    displayValue,\n    daysInMonth,\n    daysInWeek,\n    genDays,\n    model,\n    weeksInMonth,\n    weekdayLabels,\n    weekNumbers,\n  }\n}\n\nexport function useCalendarRange (props: Pick<CalendarProps, 'min' | 'max'>) {\n  const adapter = useDate()\n\n  const minDate = computed(() => {\n    if (!props.min) return null\n    const date = adapter.date(props.min)\n    return adapter.isValid(date) ? date : null\n  })\n\n  const maxDate = computed(() => {\n    if (!props.max) return null\n    const date = adapter.date(props.max)\n    return adapter.isValid(date) ? date : null\n  })\n\n  function clampDate (date: unknown) {\n    if (minDate.value && adapter.isBefore(date, minDate.value)) {\n      return minDate.value\n    }\n    if (maxDate.value && adapter.isAfter(date, maxDate.value)) {\n      return maxDate.value\n    }\n    return date\n  }\n\n  function isInAllowedRange (date: unknown) {\n    return (!minDate.value || adapter.isAfter(date, minDate.value)) &&\n      (!maxDate.value || adapter.isBefore(date, maxDate.value))\n  }\n\n  return {\n    minDate,\n    maxDate,\n    clampDate,\n    isInAllowedRange,\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/color.ts",
    "content": "// Utilities\nimport { toValue } from 'vue'\nimport { destructComputed, hasLightForeground, isCssColor, isParsableColor, parseColor } from '@/util'\n\n// Types\nimport type { CSSProperties, MaybeRefOrGetter, Ref } from 'vue'\n\nexport type ColorValue = string | false | null | undefined\n\nexport interface TextColorData {\n  textColorClasses: Ref<string[]>\n  textColorStyles: Ref<CSSProperties>\n}\n\nexport interface BackgroundColorData {\n  backgroundColorClasses: Ref<string[]>\n  backgroundColorStyles: Ref<CSSProperties>\n}\n\n// Composables\nexport function useColor (colors: MaybeRefOrGetter<{ background?: ColorValue, text?: ColorValue }>) {\n  return destructComputed(() => {\n    const {\n      class: colorClasses,\n      style: colorStyles,\n    } = computeColor(colors)\n\n    return { colorClasses, colorStyles }\n  })\n}\n\nexport function useTextColor (color: MaybeRefOrGetter<ColorValue>): TextColorData {\n  const {\n    colorClasses: textColorClasses,\n    colorStyles: textColorStyles,\n  } = useColor(() => ({\n    text: toValue(color),\n  }))\n\n  return { textColorClasses, textColorStyles }\n}\n\nexport function useBackgroundColor (color: MaybeRefOrGetter<ColorValue>): BackgroundColorData {\n  const {\n    colorClasses: backgroundColorClasses,\n    colorStyles: backgroundColorStyles,\n  } = useColor(() => ({\n    background: toValue(color),\n  }))\n\n  return { backgroundColorClasses, backgroundColorStyles }\n}\n\nfunction normalizeColors (colors: { background?: ColorValue, text?: ColorValue }) {\n  return {\n    text: typeof colors.text === 'string'\n      ? colors.text.replace(/^text-/, '')\n      : colors.text,\n    background: typeof colors.background === 'string'\n      ? colors.background.replace(/^bg-/, '')\n      : colors.background,\n  }\n}\n\nexport function computeColor (colors: MaybeRefOrGetter<{ background?: ColorValue, text?: ColorValue }>) {\n  const _colors = normalizeColors(toValue(colors))\n\n  const classes: string[] = []\n  const styles: CSSProperties = {}\n\n  if (_colors.background) {\n    if (isCssColor(_colors.background)) {\n      styles.backgroundColor = _colors.background\n\n      if (!_colors.text && isParsableColor(_colors.background)) {\n        const backgroundColor = parseColor(_colors.background)\n        if (backgroundColor.a == null || backgroundColor.a === 1) {\n          classes.push(hasLightForeground(backgroundColor)\n            ? 'v-theme-on-dark'\n            : 'v-theme-on-light'\n          )\n        }\n      }\n    } else {\n      classes.push(`bg-${_colors.background}`)\n    }\n  }\n\n  if (_colors.text) {\n    if (isCssColor(_colors.text)) {\n      styles.color = _colors.text\n      styles.caretColor = _colors.text\n    } else {\n      classes.push(`text-${_colors.text}`)\n    }\n  }\n\n  return { class: classes, style: styles }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/component.ts",
    "content": "// Utilities\nimport { propsFactory } from '@/util/propsFactory'\n\n// Types\nimport type { PropType, StyleValue } from 'vue'\n\n// TODO: import from vue once upstream PR is merged\n// https://github.com/vuejs/core/pull/14441\nexport type ClassValue = any\n\nexport interface ComponentProps {\n  class: ClassValue\n  style: StyleValue | undefined\n}\n\n// Composables\nexport const makeComponentProps = propsFactory({\n  class: [String, Array, Object] as PropType<ClassValue>,\n  style: {\n    type: [String, Array, Object] as PropType<StyleValue>,\n    default: null,\n  },\n}, 'component')\n"
  },
  {
    "path": "packages/vuetify/src/composables/date/DateAdapter.ts",
    "content": "export interface DateAdapter<T = unknown> {\n  date (value?: any): T | null\n  format (date: T, formatString: string): string\n  toJsDate (value: T): Date\n  parseISO (date: string): T\n  toISO (date: T): string\n\n  startOfDay (date: T): T\n  endOfDay (date: T): T\n  startOfWeek (date: T, firstDayOfWeek?: number | string): T\n  endOfWeek (date: T): T\n  startOfMonth (date: T): T\n  endOfMonth (date: T): T\n  startOfYear (date: T): T\n  endOfYear (date: T): T\n\n  isAfter (date: T, comparing: T): boolean\n  isAfterDay(date: T, comparing: T): boolean\n\n  isSameDay (date: T, comparing: T): boolean\n  isSameMonth (date: T, comparing: T): boolean\n  isSameYear(date: T, comparing: T): boolean\n\n  isBefore (date: T, comparing: T): boolean\n  isEqual (date: T, comparing: T): boolean\n  isValid (date: any): boolean\n  isWithinRange (date: T, range: [T, T]): boolean\n\n  addMinutes (date: T, amount: number): T\n  addHours (date: T, amount: number): T\n  addDays (date: T, amount: number): T\n  addWeeks (date: T, amount: number): T\n  addMonths (date: T, amount: number): T\n\n  getYear (date: T): number\n  setYear (date: T, year: number): T\n  getDiff (date: T, comparing: T | string, unit?: string): number\n  getWeekArray (date: T, firstDayOfWeek?: number | string): T[][]\n  getWeekdays (firstDayOfWeek?: number | string, weekdayFormat?: 'long' | 'short' | 'narrow'): string[]\n  getWeek (date: T, firstDayOfWeek?: number | string, firstDayOfYear?: number | string): number\n  getMonth (date: T): number\n  setMonth (date: T, month: number): T\n  getDate (date: T): number\n  setDate (date: T, day: number): T\n  getNextMonth (date: T): T\n  getPreviousMonth(date: T): T\n\n  getHours (date: T): number\n  setHours (date: T, hours: number): T\n  getMinutes (date: T): number\n  setMinutes (date: T, minutes: number): T\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/date/__tests__/date.spec.ts",
    "content": "// Utilities\nimport { StringDateAdapter } from '../adapters/string'\nimport { VuetifyDateAdapter } from '../adapters/vuetify'\nimport { createDateRange } from '../date'\n\n// Types\nimport type { IUtils } from '@date-io/core/IUtils'\nimport type { DateAdapter } from '../DateAdapter'\n\nfunction expectAssignable<T, T2 extends T = T> (value: T2): void {}\n\ndescribe('date', () => {\n  it('types', () => {\n    // Cannot define properties that don't exist in date-io\n    expectAssignable<DateAdapter>({} as IUtils<Date, string>)\n    // @ts-expect-error Can implement a subset of date-io\n    expectAssignable<IUtils<Date>>({} as DateAdapter)\n  })\n})\n\ndescribe('VuetifyDateAdapter', () => {\n  it('should have the correct days in a month', () => {\n    const adapter = new VuetifyDateAdapter({ locale: 'en-US' })\n\n    expect(adapter.getWeek(new Date('2023-10-10'))).toBe(41)\n  })\n\n  it('should correctly calculate weeks between years', () => {\n    const adapter = new VuetifyDateAdapter({ locale: 'en-US' })\n\n    expect(adapter.getWeek(new Date('2024-12-28'))).toBe(52)\n    expect(adapter.getWeek(new Date('2024-12-29'))).toBe(1)\n    expect(adapter.getWeek(new Date('2024-12-30'))).toBe(1)\n    expect(adapter.getWeek(new Date('2024-12-31'))).toBe(1)\n    expect(adapter.getWeek(new Date('2025-01-01'))).toBe(1)\n    expect(adapter.getWeek(new Date('2025-01-02'))).toBe(1)\n    expect(adapter.getWeek(new Date('2025-01-03'))).toBe(1)\n    expect(adapter.getWeek(new Date('2025-01-04'))).toBe(1)\n    expect(adapter.getWeek(new Date('2025-01-05'))).toBe(2)\n  })\n\n  it('should correctly calculate when year starts with a full week', () => {\n    const adapter1 = new VuetifyDateAdapter({ locale: 'en-US' }) // first day = 7 | minimal days = 1\n\n    expect(adapter1.getWeek(new Date('2022-12-25'))).toBe(53)\n    expect(adapter1.getWeek(new Date('2022-12-31'))).toBe(53)\n    expect(adapter1.getWeek(new Date('2023-01-01'))).toBe(1)\n    expect(adapter1.getWeek(new Date('2023-01-07'))).toBe(1)\n\n    const adapter2 = new VuetifyDateAdapter({ locale: 'pt' }) // first day = 7 | minimal days = 4\n\n    expect(adapter2.getWeek(new Date('2022-12-25'))).toBe(52)\n    expect(adapter2.getWeek(new Date('2022-12-31'))).toBe(52)\n    expect(adapter2.getWeek(new Date('2023-01-01'))).toBe(1)\n    expect(adapter2.getWeek(new Date('2023-01-07'))).toBe(1)\n  })\n\n  it('should adjust for start of a week', () => {\n    const adapter = new VuetifyDateAdapter({ locale: 'en-US' }) // first day = 7 | minimal days = 1\n\n    expect(adapter.getWeek(new Date('2028-12-25'), 1)).toBe(53)\n    expect(adapter.getWeek(new Date('2028-12-31'), 1)).toBe(53)\n    expect(adapter.getWeek(new Date('2029-01-01'), 1)).toBe(1)\n    expect(adapter.getWeek(new Date('2029-01-07'), 1)).toBe(1)\n\n    const adapter2 = new VuetifyDateAdapter({ locale: 'pt-PT' }) // first day = 7 | minimal days = 4\n\n    expect(adapter2.getWeek(new Date('2024-12-28'), 1)).toBe(52)\n    expect(adapter2.getWeek(new Date('2024-12-29'), 1)).toBe(52)\n    expect(adapter2.getWeek(new Date('2024-12-30'), 1)).toBe(1)\n    expect(adapter2.getWeek(new Date('2024-12-31'), 1)).toBe(1)\n    expect(adapter2.getWeek(new Date('2025-01-01'), 1)).toBe(1)\n    expect(adapter2.getWeek(new Date('2025-01-02'), 1)).toBe(1)\n    expect(adapter2.getWeek(new Date('2025-01-03'), 1)).toBe(1)\n    expect(adapter2.getWeek(new Date('2025-01-04'), 1)).toBe(1)\n    expect(adapter2.getWeek(new Date('2025-01-05'), 1)).toBe(1)\n    expect(adapter2.getWeek(new Date('2025-01-06'), 1)).toBe(2)\n    expect(adapter2.getWeek(new Date('2025-01-07'), 1)).toBe(2)\n\n    expect(adapter2.getWeek(new Date('2028-12-25'), 1)).toBe(52)\n    expect(adapter2.getWeek(new Date('2028-12-31'), 1)).toBe(52)\n    expect(adapter2.getWeek(new Date('2029-01-01'), 1)).toBe(1)\n    expect(adapter2.getWeek(new Date('2029-01-07'), 1)).toBe(1)\n\n    const adapter3 = new VuetifyDateAdapter({ locale: 'pl-PL' })\n    expect(adapter3.getWeek(new Date('2024-12-29'), 1)).toBe(52)\n  })\n\n  it('should adjust fallback to week start from locale', () => {\n    const adapter1 = new VuetifyDateAdapter({ locale: 'en-US' })\n    expect(adapter1.getWeek(new Date('2025-01-04'))).toBe(1) // saturday\n    expect(adapter1.getWeek(new Date('2025-01-05'))).toBe(2) // sunday\n\n    const adapter2 = new VuetifyDateAdapter({ locale: 'fr' })\n    expect(adapter2.getWeek(new Date('2025-01-05'))).toBe(1) // sunday\n    expect(adapter2.getWeek(new Date('2025-01-06'))).toBe(2) // monday\n  })\n\n  describe('createDateRange', () => {\n    const adapter = new VuetifyDateAdapter({ locale: 'en-US' })\n\n    it('should create a single date array when only start date is provided', () => {\n      const start = new Date('2024-01-01')\n      const result = createDateRange(adapter, start)\n\n      expect(result).toHaveLength(1)\n      expect(result[0]).toEqual(start)\n    })\n\n    it('should handle same start and stop date', () => {\n      const date = new Date('2024-01-01')\n      const result = createDateRange(adapter, date, date)\n\n      expect(result[0]).toEqual(date)\n      expect(result[1]).toEqual(adapter.endOfDay(date))\n    })\n\n    it('should create a range of dates between start and stop', () => {\n      const start = new Date('2024-01-01')\n      const stop = new Date('2024-01-03')\n      const result = createDateRange(adapter, start, stop)\n\n      expect(result).toHaveLength(3)\n      expect(result[0]).toEqual(start)\n      expect(result[1]).toEqual(new Date('2024-01-02'))\n      expect(result[2]).toEqual(adapter.endOfDay(stop))\n    })\n\n    it('should handle dates in different months', () => {\n      const start = new Date('2024-01-30')\n      const stop = new Date('2024-02-02')\n      const result = createDateRange(adapter, start, stop)\n\n      expect(result).toHaveLength(4)\n      expect(result[0]).toEqual(start)\n      expect(result[1]).toEqual(new Date('2024-01-31'))\n      expect(result[2]).toEqual(new Date('2024-02-01'))\n      expect(result[3]).toEqual(adapter.endOfDay(stop))\n    })\n\n    it('should handle dates in different years', () => {\n      const start = new Date('2024-12-30')\n      const stop = new Date('2025-01-02')\n      const result = createDateRange(adapter, start, stop)\n\n      expect(result).toHaveLength(4)\n      expect(result[0]).toEqual(start)\n      expect(result[1]).toEqual(new Date('2024-12-31'))\n      expect(result[2]).toEqual(new Date('2025-01-01'))\n      expect(result[3]).toEqual(adapter.endOfDay(stop))\n    })\n\n    it('should not miss any days near ST/DST transition', () => {\n      // values passed to createDateRange on VDateInput blur when TZ=Europe/Warsaw\n      const start = new Date('2025-03-28T23:00:00.000Z')\n      const stop = new Date('2025-03-30T22:00:00.000Z')\n      const result = createDateRange(adapter, start, stop)\n\n      expect(result).toHaveLength(3)\n    })\n  })\n\n  describe('week numbers with time zone', () => {\n    beforeAll(() => vi.stubEnv('TZ', 'America/Los_Angeles'))\n    afterAll(() => vi.unstubAllEnvs())\n\n    it('should calculate weeks correctly near ST/DST transition', () => {\n      const adapter = new VuetifyDateAdapter({ locale: 'en-US' })\n      expect(adapter.getWeek(adapter.parseISO('2025-03-15'))).toBe(11)\n      expect(adapter.getWeek(adapter.parseISO('2025-03-16'))).toBe(12)\n      expect(adapter.getWeek(adapter.parseISO('2025-03-17'))).toBe(12)\n    })\n\n    it('should calculate weeks correctly near DST/ST transition', () => {\n      const adapter = new VuetifyDateAdapter({ locale: 'en-US' })\n      expect(adapter.getWeek(adapter.parseISO('2025-11-01'))).toBe(44)\n      expect(adapter.getWeek(adapter.parseISO('2025-11-02'))).toBe(45)\n      expect(adapter.getWeek(adapter.parseISO('2025-11-03'))).toBe(45)\n    })\n  })\n\n  describe('week numbers with first-day-of-week', () => {\n    it('should calculate weeks correctly when adapting for UK', () => {\n      const adapterUS = new VuetifyDateAdapter({ locale: 'en-US' })\n      const adapterGB = new VuetifyDateAdapter({ locale: 'en-GB' })\n      expect(adapterUS.getWeek(adapterUS.parseISO('2025-03-16'))).toBe(12)\n      expect(adapterGB.getWeek(adapterGB.parseISO('2025-03-16'))).toBe(11)\n      expect(adapterUS.getWeek(adapterUS.parseISO('2025-03-16'), 1, 4)).toBe(11)\n    })\n  })\n})\n\ndescribe('StringDateAdapter', () => {\n  it('should have the correct days in a month', () => {\n    const adapter = new StringDateAdapter({ locale: 'en-US' })\n\n    expect(adapter.getWeek('2023-10-10')).toBe(41)\n  })\n\n  it('should correctly calculate weeks between years', () => {\n    const adapter = new StringDateAdapter({ locale: 'en-US' })\n\n    expect(adapter.getWeek('2024-12-28')).toBe(52)\n    expect(adapter.getWeek('2024-12-29')).toBe(1)\n    expect(adapter.getWeek('2024-12-30')).toBe(1)\n    expect(adapter.getWeek('2024-12-31')).toBe(1)\n    expect(adapter.getWeek('2025-01-01')).toBe(1)\n    expect(adapter.getWeek('2025-01-02')).toBe(1)\n    expect(adapter.getWeek('2025-01-03')).toBe(1)\n    expect(adapter.getWeek('2025-01-04')).toBe(1)\n    expect(adapter.getWeek('2025-01-05')).toBe(2)\n  })\n\n  it('should correctly calculate when year starts with a full week', () => {\n    const adapter1 = new StringDateAdapter({ locale: 'en-US' }) // first day = 7 | minimal days = 1\n\n    expect(adapter1.getWeek('2022-12-25')).toBe(53)\n    expect(adapter1.getWeek('2022-12-31')).toBe(53)\n    expect(adapter1.getWeek('2023-01-01')).toBe(1)\n    expect(adapter1.getWeek('2023-01-07')).toBe(1)\n\n    const adapter2 = new StringDateAdapter({ locale: 'pt' }) // first day = 7 | minimal days = 4\n\n    expect(adapter2.getWeek('2022-12-25')).toBe(52)\n    expect(adapter2.getWeek('2022-12-31')).toBe(52)\n    expect(adapter2.getWeek('2023-01-01')).toBe(1)\n    expect(adapter2.getWeek('2023-01-07')).toBe(1)\n  })\n\n  it('should adjust for start of a week', () => {\n    const adapter = new StringDateAdapter({ locale: 'en-US' }) // first day = 7 | minimal days = 1\n\n    expect(adapter.getWeek('2028-12-25', 1)).toBe(53)\n    expect(adapter.getWeek('2028-12-31', 1)).toBe(53)\n    expect(adapter.getWeek('2029-01-01', 1)).toBe(1)\n    expect(adapter.getWeek('2029-01-07', 1)).toBe(1)\n\n    const adapter2 = new StringDateAdapter({ locale: 'pt-PT' }) // first day = 7 | minimal days = 4\n\n    expect(adapter2.getWeek('2024-12-28', 1)).toBe(52)\n    expect(adapter2.getWeek('2024-12-29', 1)).toBe(52)\n    expect(adapter2.getWeek('2024-12-30', 1)).toBe(1)\n    expect(adapter2.getWeek('2024-12-31', 1)).toBe(1)\n    expect(adapter2.getWeek('2025-01-01', 1)).toBe(1)\n    expect(adapter2.getWeek('2025-01-02', 1)).toBe(1)\n    expect(adapter2.getWeek('2025-01-03', 1)).toBe(1)\n    expect(adapter2.getWeek('2025-01-04', 1)).toBe(1)\n    expect(adapter2.getWeek('2025-01-05', 1)).toBe(1)\n    expect(adapter2.getWeek('2025-01-06', 1)).toBe(2)\n    expect(adapter2.getWeek('2025-01-07', 1)).toBe(2)\n\n    expect(adapter2.getWeek('2028-12-25', 1)).toBe(52)\n    expect(adapter2.getWeek('2028-12-31', 1)).toBe(52)\n    expect(adapter2.getWeek('2029-01-01', 1)).toBe(1)\n    expect(adapter2.getWeek('2029-01-07', 1)).toBe(1)\n\n    const adapter3 = new StringDateAdapter({ locale: 'pl-PL' })\n    expect(adapter3.getWeek('2024-12-29', 1)).toBe(52)\n  })\n\n  it('should adjust fallback to week start from locale', () => {\n    const adapter1 = new StringDateAdapter({ locale: 'en-US' })\n    expect(adapter1.getWeek('2025-01-04')).toBe(1) // saturday\n    expect(adapter1.getWeek('2025-01-05')).toBe(2) // sunday\n\n    const adapter2 = new StringDateAdapter({ locale: 'fr' })\n    expect(adapter2.getWeek('2025-01-05')).toBe(1) // sunday\n    expect(adapter2.getWeek('2025-01-06')).toBe(2) // monday\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/date/adapters/__tests__/vuetify.spec.ts",
    "content": "// Utilities\nimport timezoneMock from 'timezone-mock'\nimport { VuetifyDateAdapter } from '../vuetify'\n\n// Types\nimport type { TimeZone } from 'timezone-mock'\n\ndescribe('vuetify date adapter', () => {\n  it('returns weekdays based on locale', () => {\n    let instance = new VuetifyDateAdapter({ locale: 'en-us' })\n\n    expect(instance.getWeekdays()).toStrictEqual(['S', 'M', 'T', 'W', 'T', 'F', 'S'])\n\n    instance = new VuetifyDateAdapter({ locale: 'sv-se' })\n\n    expect(instance.getWeekdays()).toStrictEqual(['M', 'T', 'O', 'T', 'F', 'L', 'S'])\n  })\n\n  it('formats dates', () => {\n    let instance = new VuetifyDateAdapter({ locale: 'en-gb' })\n    expect(instance.format(new Date(2000, 0, 1, 13), 'fullTime')).toBe('13:00')\n\n    instance = new VuetifyDateAdapter({ locale: 'en-us' })\n    expect(instance.format(new Date(2000, 0, 1, 13), 'fullTime')).toBe('1:00 PM')\n    expect(instance.format(new Date(2000, 0, 1, 13), 'fullTime12h')).toBe('1:00 PM')\n    expect(instance.format(new Date(2000, 0, 1, 13), 'fullTime24h')).toBe('13:00')\n\n    // These don't match the date-io spec\n    expect(instance.format(new Date(2000, 0, 1, 13), 'fullDateTime')).toBe('Jan 1, 2000, 1:00 PM')\n    expect(instance.format(new Date(2000, 0, 1, 13), 'fullDateTime12h')).toBe('Jan 1, 2000, 1:00 PM')\n    expect(instance.format(new Date(2000, 0, 1, 13), 'fullDateTime24h')).toBe('Jan 1, 2000, 13:00')\n\n    const keyboardDateTime12hFormat = '01/01/2000 1:00 PM'\n    expect(instance.format(new Date(2000, 0, 1, 13), 'keyboardDateTime')).toBe(keyboardDateTime12hFormat)\n    expect(instance.format(new Date(2000, 0, 1, 13), 'keyboardDateTime12h')).toBe(keyboardDateTime12hFormat)\n    expect(instance.format(new Date(2000, 0, 1, 13), 'keyboardDateTime24h')).toBe('01/01/2000 13:00')\n\n    expect(instance.format(new Date(2000, 0, 1), 'fullDateWithWeekday')).toBe('Saturday, January 1, 2000')\n\n    instance = new VuetifyDateAdapter({ locale: 'sv-SE' })\n\n    expect(instance.format(new Date(2000, 0, 1), 'fullDateWithWeekday')).toBe('lördag 1 januari 2000')\n  })\n\n  it.each([\n    'UTC',\n    'US/Pacific',\n    'Europe/London',\n    'Brazil/East',\n    'Australia/Adelaide',\n    'Etc/GMT-2',\n    'Etc/GMT-4',\n    'Etc/GMT+4',\n  ])('handles timezone %s when parsing date without time', timezone => {\n    // locale option here has no impact on timezone\n    const instance = new VuetifyDateAdapter({ locale: 'en-us' })\n\n    const str = '2001-01-01'\n\n    timezoneMock.register(timezone as TimeZone)\n\n    const date = instance.date(str)\n\n    expect(date?.getFullYear()).toBe(2001)\n    expect(date?.getDate()).toBe(1)\n    expect(date?.getMonth()).toBe(0)\n\n    timezoneMock.unregister()\n  })\n\n  describe('isAfterDay', () => {\n    const dateUtils = new VuetifyDateAdapter({ locale: 'en-us' })\n\n    it.each([\n      [new Date('2024-01-02'), new Date('2024-01-01'), true],\n      [new Date('2024-02-29'), new Date('2024-02-28'), true],\n      [new Date('2024-01-01'), new Date('2024-01-01'), false],\n      [new Date('2024-01-01'), new Date('2024-01-02'), false],\n    ])('returns %s when comparing %s and %s', (date, comparing, expected) => {\n      expect(dateUtils.isAfterDay(date, comparing)).toBe(expected)\n    })\n  })\n\n  // TODO: why do these only fail locally\n  describe.todo('getPreviousMonth', () => {\n    const dateUtils = new VuetifyDateAdapter({ locale: 'en-us' })\n\n    it.each([\n      [new Date('2024-03-15'), new Date('2024-02-01'), '2024-03-15 -> 2024-02-01'],\n      [new Date('2024-01-01'), new Date('2023-12-01'), '2024-01-01 -> 2023-12-01'],\n      [new Date('2025-01-31'), new Date('2024-12-01'), '2025-01-31 -> 2024-12-01'],\n      [new Date('2024-02-29'), new Date('2024-01-01'), '2024-02-29 -> 2024-01-01 (Leap Year)'],\n      [new Date('2023-03-01'), new Date('2023-02-01'), '2023-03-01 -> 2023-02-01'],\n    ])('correctly calculates the first day of the previous month: %s', (date, expected) => {\n      const result = dateUtils.getPreviousMonth(date)\n      expect(result.getFullYear()).toBe(expected.getFullYear())\n      expect(result.getMonth()).toBe(expected.getMonth())\n      expect(result.getDate()).toBe(expected.getDate())\n    })\n  })\n\n  // TODO: why do these only fail locally\n  describe.todo('isSameYear', () => {\n    const dateUtils = new VuetifyDateAdapter({ locale: 'en-us' })\n\n    it.each([\n      [new Date('2024-01-01'), new Date('2024-12-31'), true],\n      [new Date('2024-06-15'), new Date('2024-11-20'), true],\n      [new Date('2023-01-01'), new Date('2024-01-01'), false],\n      [new Date('2024-12-31'), new Date('2025-01-01'), false],\n      [new Date('2024-07-07'), new Date('2023-07-07'), false],\n    ])('returns %s when comparing %s and %s', (date1, date2, expected) => {\n      expect(dateUtils.isSameYear(date1, date2)).toBe(expected)\n    })\n  })\n\n  it('returns correct start of week', () => {\n    let instance = new VuetifyDateAdapter({ locale: 'en-US' })\n\n    let date = instance.startOfWeek(new Date(2024, 3, 10, 12, 0, 0))\n\n    expect(date?.getFullYear()).toBe(2024)\n    expect(date?.getMonth()).toBe(3)\n    expect(date?.getDate()).toBe(7)\n    expect(date?.getDay()).toBe(0)\n\n    instance = new VuetifyDateAdapter({ locale: 'sv-SE' })\n\n    date = instance.startOfWeek(new Date(2024, 3, 10, 12, 0, 0))\n\n    expect(date?.getFullYear()).toBe(2024)\n    expect(date?.getMonth()).toBe(3)\n    expect(date?.getDate()).toBe(8)\n    expect(date?.getDay()).toBe(1)\n  })\n\n  it('returns correct end of week', () => {\n    let instance = new VuetifyDateAdapter({ locale: 'en-US' })\n\n    let date = instance.endOfWeek(new Date(2024, 3, 10, 12, 0, 0))\n\n    expect(date?.getFullYear()).toBe(2024)\n    expect(date?.getMonth()).toBe(3)\n    expect(date?.getDate()).toBe(13)\n    expect(date?.getDay()).toBe(6)\n\n    instance = new VuetifyDateAdapter({ locale: 'sv-SE' })\n\n    date = instance.endOfWeek(new Date(2024, 3, 10, 12, 0, 0))\n\n    expect(date?.getFullYear()).toBe(2024)\n    expect(date?.getMonth()).toBe(3)\n    expect(date?.getDate()).toBe(14)\n    expect(date?.getDay()).toBe(0)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/date/adapters/string.ts",
    "content": "// Composables\nimport { VuetifyDateAdapter } from '@/composables/date/adapters/vuetify'\n\n// Types\nimport type { DateAdapter } from '@/composables/date'\n\ntype CustomDateFormat = Intl.DateTimeFormatOptions | ((date: string, formatString: string, locale: string) => string)\n\nexport class StringDateAdapter implements DateAdapter<string> {\n  base: VuetifyDateAdapter\n\n  constructor (options: { locale: string, formats?: Record<string, CustomDateFormat> }) {\n    this.base = new VuetifyDateAdapter({\n      locale: options.locale,\n      formats: options.formats && Object.fromEntries(\n        Object.entries(options.formats).map(([k, v]) => {\n          return [\n            k,\n            typeof v === 'function'\n              ? (date, ...args) => v(this.base.toISO(date), ...args)\n              : v,\n          ]\n        })\n      ),\n    })\n  }\n\n  addDays (date: string, amount: number): string {\n    return this.base.toISO(\n      this.base.addDays(this.base.date(date)!, amount)\n    )\n  }\n\n  addHours (date: string, amount: number): string {\n    return this.base.toISO(\n      this.base.addHours(this.base.date(date)!, amount)\n    )\n  }\n\n  addMinutes (date: string, amount: number): string {\n    return this.base.toISO(\n      this.base.addMinutes(this.base.date(date)!, amount)\n    )\n  }\n\n  addMonths (date: string, amount: number): string {\n    return this.base.toISO(\n      this.base.addMonths(this.base.date(date)!, amount)\n    )\n  }\n\n  addWeeks (date: string, amount: number): string {\n    return this.base.toISO(\n      this.base.addWeeks(this.base.date(date)!, amount)\n    )\n  }\n\n  date (value?: any): string | null {\n    return this.base.toISO(\n      this.base.date(value)!\n    )\n  }\n\n  endOfDay (date: string): string {\n    return this.base.toISO(\n      this.base.endOfDay(this.base.date(date)!)\n    )\n  }\n\n  endOfMonth (date: string): string {\n    return this.base.toISO(\n      this.base.endOfMonth(this.base.date(date)!)\n    )\n  }\n\n  endOfWeek (date: string): string {\n    return this.base.toISO(\n      this.base.endOfWeek(this.base.date(date)!)\n    )\n  }\n\n  endOfYear (date: string): string {\n    return this.base.toISO(\n      this.base.endOfYear(this.base.date(date)!)\n    )\n  }\n\n  format (date: string, formatString: string): string {\n    return this.base.format(\n      this.base.date(date)!,\n      formatString\n    )\n  }\n\n  getDate (date: string): number {\n    return this.base.getDate(this.base.date(date)!)\n  }\n\n  getDiff (date: string, comparing: string, unit?: string): number {\n    return this.base.getDiff(this.base.date(date)!, comparing, unit)\n  }\n\n  getHours (date: string): number {\n    return this.base.getHours(this.base.date(date)!)\n  }\n\n  getMinutes (date: string): number {\n    return this.base.getMinutes(this.base.date(date)!)\n  }\n\n  getMonth (date: string): number {\n    return this.base.getMonth(this.base.date(date)!)\n  }\n\n  getWeek (date: string, firstDayOfWeek?: number | string, firstDayOfYear?: number | string): number {\n    return this.base.getWeek(this.base.date(date)!, firstDayOfWeek, firstDayOfYear)\n  }\n\n  getNextMonth (date: string): string {\n    return this.base.toISO(\n      this.base.getNextMonth(this.base.date(date)!)\n    )\n  }\n\n  getPreviousMonth (date: string): string {\n    return this.base.toISO(\n      this.base.getPreviousMonth(this.base.date(date)!)\n    )\n  }\n\n  getWeekArray (date: string, firstDayOfWeek?: number | string): string[][] {\n    return this.base.getWeekArray(\n      this.base.date(date)!,\n      firstDayOfWeek,\n    ).map(week => {\n      return week.map(day => {\n        return this.base.toISO(day)\n      })\n    })\n  }\n\n  getWeekdays (firstDayOfWeek?: number | string, weekdayFormat?: 'long' | 'short' | 'narrow'): string[] {\n    return this.base.getWeekdays(firstDayOfWeek, weekdayFormat)\n  }\n\n  getYear (date: string): number {\n    return this.base.getYear(this.base.date(date)!)\n  }\n\n  isAfter (date: string, comparing: string): boolean {\n    return this.base.isAfter(\n      this.base.date(date)!,\n      this.base.date(comparing)!,\n    )\n  }\n\n  isAfterDay (date: string, comparing: string): boolean {\n    return this.base.isAfterDay(\n      this.base.date(date)!,\n      this.base.date(comparing)!,\n    )\n  }\n\n  isBefore (date: string, comparing: string): boolean {\n    return this.base.isBefore(\n      this.base.date(date)!,\n      this.base.date(comparing)!,\n    )\n  }\n\n  isEqual (date: string, comparing: string): boolean {\n    return this.base.isEqual(\n      this.base.date(date)!,\n      this.base.date(comparing)!,\n    )\n  }\n\n  isSameDay (date: string, comparing: string): boolean {\n    return this.base.isSameDay(\n      this.base.date(date)!,\n      this.base.date(comparing)!,\n    )\n  }\n\n  isSameMonth (date: string, comparing: string): boolean {\n    return this.base.isSameMonth(\n      this.base.date(date)!,\n      this.base.date(comparing)!,\n    )\n  }\n\n  isSameYear (date: string, comparing: string): boolean {\n    return this.base.isSameYear(\n      this.base.date(date)!,\n      this.base.date(comparing)!,\n    )\n  }\n\n  isValid (date: any): boolean {\n    return this.base.isValid(date)\n  }\n\n  isWithinRange (date: string, range: [string, string]): boolean {\n    return this.base.isWithinRange(\n      this.base.date(date)!,\n      [this.base.date(range[0])!, this.base.date(range[1])!],\n    )\n  }\n\n  parseISO (date: string): string {\n    return this.base.toISO(this.base.parseISO(date))\n  }\n\n  setDate (date: string, day: number): string {\n    return this.base.toISO(\n      this.base.setDate(this.base.date(date)!, day)\n    )\n  }\n\n  setHours (date: string, hours: number): string {\n    return this.base.toISO(\n      this.base.setHours(this.base.date(date)!, hours)\n    )\n  }\n\n  setMinutes (date: string, minutes: number): string {\n    return this.base.toISO(\n      this.base.setMinutes(this.base.date(date)!, minutes)\n    )\n  }\n\n  setMonth (date: string, month: number): string {\n    return this.base.toISO(\n      this.base.setMonth(this.base.date(date)!, month)\n    )\n  }\n\n  setYear (date: string, year: number): string {\n    return this.base.toISO(\n      this.base.setYear(this.base.date(date)!, year)\n    )\n  }\n\n  startOfDay (date: string): string {\n    return this.base.toISO(\n      this.base.startOfDay(this.base.date(date)!)\n    )\n  }\n\n  startOfMonth (date: string): string {\n    return this.base.toISO(\n      this.base.startOfMonth(this.base.date(date)!)\n    )\n  }\n\n  startOfWeek (date: string, firstDayOfWeek?: number | string): string {\n    return this.base.toISO(\n      this.base.startOfWeek(this.base.date(date)!, firstDayOfWeek)\n    )\n  }\n\n  startOfYear (date: string): string {\n    return this.base.toISO(\n      this.base.startOfYear(this.base.date(date)!)\n    )\n  }\n\n  toISO (date: string): string {\n    return this.base.toISO(\n      this.base.date(date)!\n    )\n  }\n\n  toJsDate (value: string): Date {\n    return this.base.date(value)!\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/date/adapters/vuetify.ts",
    "content": "// Utilities\nimport { consoleWarn, createRange, padStart } from '@/util'\n\n// Types\nimport type { DateAdapter } from '../DateAdapter'\n\ntype CustomDateFormat = Intl.DateTimeFormatOptions | ((date: Date, formatString: string, locale: string) => string)\n\nfunction weekInfo (locale: string): { firstDay: number, firstWeekSize: number } | null {\n  // https://simplelocalize.io/data/locales/\n  // then `new Intl.Locale(...).getWeekInfo()`\n  const code = locale.slice(-2).toUpperCase()\n  switch (true) {\n    case locale === 'GB-alt-variant': {\n      return { firstDay: 0, firstWeekSize: 4 }\n    }\n    case locale === '001': {\n      return { firstDay: 1, firstWeekSize: 1 }\n    }\n    case `AG AS BD BR BS BT BW BZ CA CO DM DO ET GT GU HK HN ID IL IN JM JP KE\n    KH KR LA MH MM MO MT MX MZ NI NP PA PE PH PK PR PY SA SG SV TH TT TW UM US\n    VE VI WS YE ZA ZW`.includes(code): {\n      return { firstDay: 0, firstWeekSize: 1 }\n    }\n    case `AI AL AM AR AU AZ BA BM BN BY CL CM CN CR CY EC GE HR KG KZ LB LK LV\n    MD ME MK MN MY NZ RO RS SI TJ TM TR UA UY UZ VN XK`.includes(code): {\n      return { firstDay: 1, firstWeekSize: 1 }\n    }\n    case `AD AN AT AX BE BG CH CZ DE DK EE ES FI FJ FO FR GB GF GP GR HU IE IS\n    IT LI LT LU MC MQ NL NO PL RE RU SE SK SM VA`.includes(code): {\n      return { firstDay: 1, firstWeekSize: 4 }\n    }\n    case `AE AF BH DJ DZ EG IQ IR JO KW LY OM QA SD SY`.includes(code): {\n      return { firstDay: 6, firstWeekSize: 1 }\n    }\n    case code === 'MV': {\n      return { firstDay: 5, firstWeekSize: 1 }\n    }\n    case code === 'PT': {\n      return { firstDay: 0, firstWeekSize: 4 }\n    }\n    default: return null\n  }\n}\n\nfunction getWeekArray (date: Date, locale: string, firstDayOfWeek?: number) {\n  const weeks = []\n  let currentWeek = []\n  const firstDayOfMonth = startOfMonth(date)\n  const lastDayOfMonth = endOfMonth(date)\n  const first = firstDayOfWeek ?? weekInfo(locale)?.firstDay ?? 0\n  const firstDayWeekIndex = (firstDayOfMonth.getDay() - first + 7) % 7\n  const lastDayWeekIndex = (lastDayOfMonth.getDay() - first + 7) % 7\n\n  for (let i = 0; i < firstDayWeekIndex; i++) {\n    const adjacentDay = new Date(firstDayOfMonth)\n    adjacentDay.setDate(adjacentDay.getDate() - (firstDayWeekIndex - i))\n    currentWeek.push(adjacentDay)\n  }\n\n  for (let i = 1; i <= lastDayOfMonth.getDate(); i++) {\n    const day = new Date(date.getFullYear(), date.getMonth(), i)\n\n    // Add the day to the current week\n    currentWeek.push(day)\n\n    // If the current week has 7 days, add it to the weeks array and start a new week\n    if (currentWeek.length === 7) {\n      weeks.push(currentWeek)\n      currentWeek = []\n    }\n  }\n\n  for (let i = 1; i < 7 - lastDayWeekIndex; i++) {\n    const adjacentDay = new Date(lastDayOfMonth)\n    adjacentDay.setDate(adjacentDay.getDate() + i)\n    currentWeek.push(adjacentDay)\n  }\n\n  if (currentWeek.length > 0) {\n    weeks.push(currentWeek)\n  }\n\n  return weeks\n}\n\nfunction startOfWeek (date: Date, locale: string, firstDayOfWeek?: number) {\n  let day = (firstDayOfWeek ?? weekInfo(locale)?.firstDay ?? 0) % 7\n\n  // prevent infinite loop\n  if (![0, 1, 2, 3, 4, 5, 6].includes(day)) {\n    consoleWarn('Invalid firstDayOfWeek, expected discrete number in range [0-6]')\n    day = 0\n  }\n\n  const d = new Date(date)\n  while (d.getDay() !== day) {\n    d.setDate(d.getDate() - 1)\n  }\n  return d\n}\n\nfunction endOfWeek (date: Date, locale: string) {\n  const d = new Date(date)\n  const lastDay = ((weekInfo(locale)?.firstDay ?? 0) + 6) % 7\n  while (d.getDay() !== lastDay) {\n    d.setDate(d.getDate() + 1)\n  }\n  return d\n}\n\nfunction startOfMonth (date: Date) {\n  return new Date(date.getFullYear(), date.getMonth(), 1)\n}\n\nfunction endOfMonth (date: Date) {\n  return new Date(date.getFullYear(), date.getMonth() + 1, 0)\n}\n\nfunction parseLocalDate (value: string): Date {\n  const parts = value.split('-').map(Number)\n\n  // new Date() uses local time zone when passing individual date component values\n  return new Date(parts[0], parts[1] - 1, parts[2])\n}\n\nconst _YYYMMDD = /^([12]\\d{3}-([1-9]|0[1-9]|1[0-2])-([1-9]|0[1-9]|[12]\\d|3[01]))$/\n\nfunction date (value?: any): Date | null {\n  if (value == null) return new Date()\n\n  if (value instanceof Date) return value\n\n  if (typeof value === 'string') {\n    let parsed\n\n    if (_YYYMMDD.test(value)) {\n      return parseLocalDate(value)\n    } else {\n      parsed = Date.parse(value)\n    }\n\n    if (!isNaN(parsed)) return new Date(parsed)\n  }\n\n  return null\n}\n\nconst sundayJanuarySecond2000 = new Date(2000, 0, 2)\n\nfunction getWeekdays (locale: string, firstDayOfWeek?: number, weekdayFormat?: 'long' | 'short' | 'narrow') {\n  const daysFromSunday = firstDayOfWeek ?? weekInfo(locale)?.firstDay ?? 0\n\n  return createRange(7).map(i => {\n    const weekday = new Date(sundayJanuarySecond2000)\n    weekday.setDate(sundayJanuarySecond2000.getDate() + daysFromSunday + i)\n    return new Intl.DateTimeFormat(locale, { weekday: weekdayFormat ?? 'narrow' }).format(weekday)\n  })\n}\n\nfunction format (\n  value: Date,\n  formatString: string,\n  locale: string,\n  formats?: Record<string, CustomDateFormat>\n): string {\n  const newDate = date(value) ?? new Date()\n  const customFormat = formats?.[formatString]\n\n  if (typeof customFormat === 'function') {\n    return customFormat(newDate, formatString, locale)\n  }\n\n  let options: Intl.DateTimeFormatOptions = {}\n  switch (formatString) {\n    case 'fullDate':\n      options = { year: 'numeric', month: 'short', day: 'numeric' }\n      break\n    case 'fullDateWithWeekday':\n      options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }\n      break\n    case 'normalDate':\n      const day = newDate.getDate()\n      const month = new Intl.DateTimeFormat(locale, { month: 'long' }).format(newDate)\n      return `${day} ${month}`\n    case 'normalDateWithWeekday':\n      options = { weekday: 'short', day: 'numeric', month: 'short' }\n      break\n    case 'shortDate':\n      options = { month: 'short', day: 'numeric' }\n      break\n    case 'year':\n      options = { year: 'numeric' }\n      break\n    case 'month':\n      options = { month: 'long' }\n      break\n    case 'monthShort':\n      options = { month: 'short' }\n      break\n    case 'monthAndYear':\n      options = { month: 'long', year: 'numeric' }\n      break\n    case 'monthAndDate':\n      options = { month: 'long', day: 'numeric' }\n      break\n    case 'weekday':\n      options = { weekday: 'long' }\n      break\n    case 'weekdayShort':\n      options = { weekday: 'short' }\n      break\n    case 'dayOfMonth':\n      return new Intl.NumberFormat(locale).format(newDate.getDate())\n    case 'hours12h':\n      options = { hour: 'numeric', hour12: true }\n      break\n    case 'hours24h':\n      options = { hour: 'numeric', hour12: false }\n      break\n    case 'minutes':\n      options = { minute: 'numeric' }\n      break\n    case 'seconds':\n      options = { second: 'numeric' }\n      break\n    case 'fullTime':\n      options = { hour: 'numeric', minute: 'numeric' }\n      break\n    case 'fullTime12h':\n      options = { hour: 'numeric', minute: 'numeric', hour12: true }\n      break\n    case 'fullTime24h':\n      options = { hour: 'numeric', minute: 'numeric', hour12: false }\n      break\n    case 'fullDateTime':\n      options = { year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute: 'numeric' }\n      break\n    case 'fullDateTime12h':\n      options = { year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute: 'numeric', hour12: true }\n      break\n    case 'fullDateTime24h':\n      options = { year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute: 'numeric', hour12: false }\n      break\n    case 'keyboardDate':\n      options = { year: 'numeric', month: '2-digit', day: '2-digit' }\n      break\n    case 'keyboardDateTime':\n      options = { year: 'numeric', month: '2-digit', day: '2-digit', hour: 'numeric', minute: 'numeric' }\n      return new Intl.DateTimeFormat(locale, options).format(newDate).replace(/, /g, ' ')\n    case 'keyboardDateTime12h':\n      options = { year: 'numeric', month: '2-digit', day: '2-digit', hour: 'numeric', minute: 'numeric', hour12: true }\n      return new Intl.DateTimeFormat(locale, options).format(newDate).replace(/, /g, ' ')\n    case 'keyboardDateTime24h':\n      options = { year: 'numeric', month: '2-digit', day: '2-digit', hour: 'numeric', minute: 'numeric', hour12: false }\n      return new Intl.DateTimeFormat(locale, options).format(newDate).replace(/, /g, ' ')\n    default:\n      options = customFormat ?? { timeZone: 'UTC', timeZoneName: 'short' }\n  }\n\n  return new Intl.DateTimeFormat(locale, options).format(newDate)\n}\n\nfunction toISO (adapter: DateAdapter<any>, value: Date) {\n  const date = adapter.toJsDate(value)\n  const year = date.getFullYear()\n  const month = padStart(String(date.getMonth() + 1), 2, '0')\n  const day = padStart(String(date.getDate()), 2, '0')\n\n  return `${year}-${month}-${day}`\n}\n\nfunction parseISO (value: string) {\n  const [year, month, day] = value.split('-').map(Number)\n\n  return new Date(year, month - 1, day)\n}\n\nfunction addMinutes (date: Date, amount: number) {\n  const d = new Date(date)\n  d.setMinutes(d.getMinutes() + amount)\n  return d\n}\n\nfunction addHours (date: Date, amount: number) {\n  const d = new Date(date)\n  d.setHours(d.getHours() + amount)\n  return d\n}\n\nfunction addDays (date: Date, amount: number) {\n  const d = new Date(date)\n  d.setDate(d.getDate() + amount)\n  return d\n}\n\nfunction addWeeks (date: Date, amount: number) {\n  const d = new Date(date)\n  d.setDate(d.getDate() + (amount * 7))\n  return d\n}\n\nfunction addMonths (date: Date, amount: number) {\n  const d = new Date(date)\n  d.setDate(1)\n  d.setMonth(d.getMonth() + amount)\n  return d\n}\n\nfunction getYear (date: Date) {\n  return date.getFullYear()\n}\n\nfunction getMonth (date: Date) {\n  return date.getMonth()\n}\n\nfunction getWeek (date: Date, locale: string, firstDayOfWeek?: number, firstDayOfYear?: number) {\n  const weekInfoFromLocale = weekInfo(locale)\n  const weekStart = firstDayOfWeek ?? weekInfoFromLocale?.firstDay ?? 0\n  const minWeekSize = weekInfoFromLocale?.firstWeekSize ?? 1\n\n  return firstDayOfYear !== undefined\n    ? calculateWeekWithFirstDayOfYear(date, locale, weekStart, firstDayOfYear)\n    : calculateWeekWithMinWeekSize(date, locale, weekStart, minWeekSize)\n}\n\nfunction calculateWeekWithFirstDayOfYear (date: Date, locale: string, weekStart: number, firstDayOfYear: number) {\n  const firstDayOfYearOffset = (7 + firstDayOfYear - weekStart) % 7\n  const currentWeekStart = startOfWeek(date, locale, weekStart)\n  const currentWeekEnd = addDays(currentWeekStart, 6)\n\n  function yearStartWeekdayOffset (year: number) {\n    return (7 + new Date(year, 0, 1).getDay() - weekStart) % 7\n  }\n\n  let year = getYear(currentWeekStart)\n  if (year < getYear(currentWeekEnd) && yearStartWeekdayOffset(year + 1) <= firstDayOfYearOffset) {\n    year++\n  }\n\n  const yearStart = new Date(year, 0, 1)\n  const offset = yearStartWeekdayOffset(year)\n  const d1w1 = offset <= firstDayOfYearOffset\n    ? addDays(yearStart, -offset)\n    : addDays(yearStart, 7 - offset)\n\n  return 1 + getDiff(endOfDay(currentWeekStart), startOfDay(d1w1), 'weeks')\n}\n\nfunction calculateWeekWithMinWeekSize (date: Date, locale: string, weekStart: number, minWeekSize: number) {\n  const currentWeekStart = startOfWeek(date, locale, weekStart)\n  const currentWeekEnd = addDays(startOfWeek(date, locale, weekStart), 6)\n\n  function firstWeekSize (year: number) {\n    const yearStart = new Date(year, 0, 1)\n    return 7 - getDiff(yearStart, startOfWeek(yearStart, locale, weekStart), 'days')\n  }\n\n  let year = getYear(currentWeekStart)\n  if (year < getYear(currentWeekEnd) && firstWeekSize(year + 1) >= minWeekSize) {\n    year++\n  }\n\n  const yearStart = new Date(year, 0, 1)\n  const size = firstWeekSize(year)\n  const d1w1 = size >= minWeekSize\n    ? addDays(yearStart, size - 7)\n    : addDays(yearStart, size)\n  return 1 + getDiff(endOfDay(currentWeekStart), startOfDay(d1w1), 'weeks')\n}\n\nfunction getDate (date: Date) {\n  return date.getDate()\n}\n\nfunction getNextMonth (date: Date) {\n  return new Date(date.getFullYear(), date.getMonth() + 1, 1)\n}\n\nfunction getPreviousMonth (date: Date) {\n  return new Date(date.getFullYear(), date.getMonth() - 1, 1)\n}\n\nfunction getHours (date: Date) {\n  return date.getHours()\n}\n\nfunction getMinutes (date: Date) {\n  return date.getMinutes()\n}\n\nfunction startOfYear (date: Date) {\n  return new Date(date.getFullYear(), 0, 1)\n}\nfunction endOfYear (date: Date) {\n  return new Date(date.getFullYear(), 11, 31)\n}\n\nfunction isWithinRange (date: Date, range: [Date, Date]) {\n  return (\n    isEqual(date, range[0]) || isEqual(date, range[1]) ||\n    (isAfter(date, range[0]) && isBefore(date, range[1]))\n  )\n}\n\nfunction isValid (date: any) {\n  const d = new Date(date)\n\n  return d instanceof Date && !isNaN(d.getTime())\n}\n\nfunction isAfter (date: Date, comparing: Date) {\n  return date.getTime() > comparing.getTime()\n}\n\nfunction isAfterDay (date: Date, comparing: Date): boolean {\n  return isAfter(startOfDay(date), startOfDay(comparing))\n}\n\nfunction isBefore (date: Date, comparing: Date) {\n  return date.getTime() < comparing.getTime()\n}\n\nfunction isEqual (date: Date, comparing: Date) {\n  return date.getTime() === comparing.getTime()\n}\n\nfunction isSameDay (date: Date, comparing: Date) {\n  return date.getDate() === comparing.getDate() &&\n    date.getMonth() === comparing.getMonth() &&\n    date.getFullYear() === comparing.getFullYear()\n}\n\nfunction isSameMonth (date: Date, comparing: Date) {\n  return date.getMonth() === comparing.getMonth() &&\n    date.getFullYear() === comparing.getFullYear()\n}\n\nfunction isSameYear (date: Date, comparing: Date) {\n  return date.getFullYear() === comparing.getFullYear()\n}\n\nfunction getDiff (date: Date, comparing: Date | string, unit?: string) {\n  const d = new Date(date)\n  const c = new Date(comparing)\n\n  switch (unit) {\n    case 'years':\n      return d.getFullYear() - c.getFullYear()\n    case 'quarters':\n      return Math.floor((d.getMonth() - c.getMonth() + (d.getFullYear() - c.getFullYear()) * 12) / 4)\n    case 'months':\n      return d.getMonth() - c.getMonth() + (d.getFullYear() - c.getFullYear()) * 12\n    case 'weeks':\n      return Math.floor((d.getTime() - c.getTime()) / (1000 * 60 * 60 * 24 * 7))\n    case 'days':\n      return Math.floor((d.getTime() - c.getTime()) / (1000 * 60 * 60 * 24))\n    case 'hours':\n      return Math.floor((d.getTime() - c.getTime()) / (1000 * 60 * 60))\n    case 'minutes':\n      return Math.floor((d.getTime() - c.getTime()) / (1000 * 60))\n    case 'seconds':\n      return Math.floor((d.getTime() - c.getTime()) / 1000)\n    default: {\n      return d.getTime() - c.getTime()\n    }\n  }\n}\n\nfunction setHours (date: Date, count: number) {\n  const d = new Date(date)\n  d.setHours(count)\n  return d\n}\n\nfunction setMinutes (date: Date, count: number) {\n  const d = new Date(date)\n  d.setMinutes(count)\n  return d\n}\n\nfunction setMonth (date: Date, count: number) {\n  const d = new Date(date)\n  d.setMonth(count)\n  return d\n}\n\nfunction setDate (date: Date, day: number) {\n  const d = new Date(date)\n  d.setDate(day)\n  return d\n}\n\nfunction setYear (date: Date, year: number) {\n  const d = new Date(date)\n  d.setFullYear(year)\n  return d\n}\n\nfunction startOfDay (date: Date) {\n  return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0, 0)\n}\n\nfunction endOfDay (date: Date) {\n  return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59, 999)\n}\n\nexport class VuetifyDateAdapter implements DateAdapter<Date> {\n  locale: string\n  formats?: Record<string, CustomDateFormat>\n\n  constructor (options: { locale: string, formats?: Record<string, CustomDateFormat> }) {\n    this.locale = options.locale\n    this.formats = options.formats\n  }\n\n  date (value?: any) {\n    return date(value)\n  }\n\n  toJsDate (date: Date) {\n    return date\n  }\n\n  toISO (date: Date): string {\n    return toISO(this, date)\n  }\n\n  parseISO (date: string) {\n    return parseISO(date)\n  }\n\n  addMinutes (date: Date, amount: number) {\n    return addMinutes(date, amount)\n  }\n\n  addHours (date: Date, amount: number) {\n    return addHours(date, amount)\n  }\n\n  addDays (date: Date, amount: number) {\n    return addDays(date, amount)\n  }\n\n  addWeeks (date: Date, amount: number) {\n    return addWeeks(date, amount)\n  }\n\n  addMonths (date: Date, amount: number) {\n    return addMonths(date, amount)\n  }\n\n  getWeekArray (date: Date, firstDayOfWeek?: number | string) {\n    const firstDay = firstDayOfWeek !== undefined ? Number(firstDayOfWeek) : undefined\n    return getWeekArray(date, this.locale, firstDay)\n  }\n\n  startOfWeek (date: Date, firstDayOfWeek?: number | string): Date {\n    const firstDay = firstDayOfWeek !== undefined ? Number(firstDayOfWeek) : undefined\n    return startOfWeek(date, this.locale, firstDay)\n  }\n\n  endOfWeek (date: Date): Date {\n    return endOfWeek(date, this.locale)\n  }\n\n  startOfMonth (date: Date) {\n    return startOfMonth(date)\n  }\n\n  endOfMonth (date: Date) {\n    return endOfMonth(date)\n  }\n\n  format (date: Date, formatString: string) {\n    return format(date, formatString, this.locale, this.formats)\n  }\n\n  isEqual (date: Date, comparing: Date) {\n    return isEqual(date, comparing)\n  }\n\n  isValid (date: any) {\n    return isValid(date)\n  }\n\n  isWithinRange (date: Date, range: [Date, Date]) {\n    return isWithinRange(date, range)\n  }\n\n  isAfter (date: Date, comparing: Date) {\n    return isAfter(date, comparing)\n  }\n\n  isAfterDay (date: Date, comparing: Date) {\n    return isAfterDay(date, comparing)\n  }\n\n  isBefore (date: Date, comparing: Date) {\n    return !isAfter(date, comparing) && !isEqual(date, comparing)\n  }\n\n  isSameDay (date: Date, comparing: Date) {\n    return isSameDay(date, comparing)\n  }\n\n  isSameMonth (date: Date, comparing: Date) {\n    return isSameMonth(date, comparing)\n  }\n\n  isSameYear (date: Date, comparing: Date) {\n    return isSameYear(date, comparing)\n  }\n\n  setMinutes (date: Date, count: number) {\n    return setMinutes(date, count)\n  }\n\n  setHours (date: Date, count: number) {\n    return setHours(date, count)\n  }\n\n  setMonth (date: Date, count: number) {\n    return setMonth(date, count)\n  }\n\n  setDate (date: Date, day: number): Date {\n    return setDate(date, day)\n  }\n\n  setYear (date: Date, year: number) {\n    return setYear(date, year)\n  }\n\n  getDiff (date: Date, comparing: Date | string, unit?: string) {\n    return getDiff(date, comparing, unit)\n  }\n\n  getWeekdays (firstDayOfWeek?: number | string, weekdayFormat?: 'long' | 'short' | 'narrow') {\n    const firstDay = firstDayOfWeek !== undefined ? Number(firstDayOfWeek) : undefined\n    return getWeekdays(this.locale, firstDay, weekdayFormat)\n  }\n\n  getYear (date: Date) {\n    return getYear(date)\n  }\n\n  getMonth (date: Date) {\n    return getMonth(date)\n  }\n\n  getWeek (date: Date, firstDayOfWeek?: number | string, firstDayOfYear?: number | string) {\n    const firstDay = firstDayOfWeek !== undefined ? Number(firstDayOfWeek) : undefined\n    const firstWeekStart = firstDayOfYear !== undefined ? Number(firstDayOfYear) : undefined\n    return getWeek(date, this.locale, firstDay, firstWeekStart)\n  }\n\n  getDate (date: Date) {\n    return getDate(date)\n  }\n\n  getNextMonth (date: Date) {\n    return getNextMonth(date)\n  }\n\n  getPreviousMonth (date: Date) {\n    return getPreviousMonth(date)\n  }\n\n  getHours (date: Date) {\n    return getHours(date)\n  }\n\n  getMinutes (date: Date) {\n    return getMinutes(date)\n  }\n\n  startOfDay (date: Date) {\n    return startOfDay(date)\n  }\n\n  endOfDay (date: Date) {\n    return endOfDay(date)\n  }\n\n  startOfYear (date: Date) {\n    return startOfYear(date)\n  }\n\n  endOfYear (date: Date) {\n    return endOfYear(date)\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/date/date.ts",
    "content": "// Composables\nimport { useLocale } from '@/composables/locale'\n\n// Utilities\nimport { inject, reactive, watch } from 'vue'\nimport { mergeDeep } from '@/util'\n\n// Types\nimport type { InjectionKey } from 'vue'\nimport type { DateAdapter } from './DateAdapter'\nimport type { LocaleInstance } from '@/composables/locale'\n\n// Adapters\nimport { VuetifyDateAdapter } from './adapters/vuetify'\n\nexport interface DateInstance extends DateModule.InternalAdapter {\n  locale?: any\n}\n\n/** Supports module augmentation to specify date adapter types */\nexport namespace DateModule {\n  interface Adapter {}\n\n  export type InternalAdapter = {} extends Adapter ? DateAdapter : Adapter\n}\n\nexport type InternalDateOptions = {\n  adapter: (new (options: { locale: any, formats?: any }) => DateInstance) | DateInstance\n  formats?: Record<string, any>\n  locale: Record<string, any>\n}\n\nexport type DateOptions = Partial<InternalDateOptions>\n\nexport const DateOptionsSymbol: InjectionKey<InternalDateOptions> = Symbol.for('vuetify:date-options')\nexport const DateAdapterSymbol: InjectionKey<DateInstance> = Symbol.for('vuetify:date-adapter')\n\nexport function createDate (options: DateOptions | undefined, locale: LocaleInstance) {\n  const _options = mergeDeep({\n    adapter: VuetifyDateAdapter,\n    locale: {\n      af: 'af-ZA',\n      // ar: '', # not the same value for all variants\n      bg: 'bg-BG',\n      ca: 'ca-ES',\n      ckb: '',\n      cs: 'cs-CZ',\n      de: 'de-DE',\n      el: 'el-GR',\n      en: 'en-US',\n      // es: '', # not the same value for all variants\n      et: 'et-EE',\n      fa: 'fa-IR',\n      fi: 'fi-FI',\n      // fr: '', #not the same value for all variants\n      hr: 'hr-HR',\n      hu: 'hu-HU',\n      he: 'he-IL',\n      id: 'id-ID',\n      it: 'it-IT',\n      ja: 'ja-JP',\n      ko: 'ko-KR',\n      lv: 'lv-LV',\n      lt: 'lt-LT',\n      nl: 'nl-NL',\n      no: 'no-NO',\n      pl: 'pl-PL',\n      pt: 'pt-PT',\n      ro: 'ro-RO',\n      ru: 'ru-RU',\n      sk: 'sk-SK',\n      sl: 'sl-SI',\n      srCyrl: 'sr-SP',\n      srLatn: 'sr-SP',\n      sv: 'sv-SE',\n      th: 'th-TH',\n      tr: 'tr-TR',\n      az: 'az-AZ',\n      uk: 'uk-UA',\n      vi: 'vi-VN',\n      zhHans: 'zh-CN',\n      zhHant: 'zh-TW',\n    },\n  }, options) as InternalDateOptions\n\n  return {\n    options: _options,\n    instance: createInstance(_options, locale),\n  }\n}\n\nexport function createDateRange (adapter: DateInstance, start: unknown, stop?: unknown) {\n  const diff = daysDiff(adapter, start, stop)\n  const datesInRange = [start]\n\n  for (let i = 1; i < diff; i++) {\n    const nextDate = adapter.addDays(start, i)\n    datesInRange.push(nextDate)\n  }\n\n  if (stop) {\n    datesInRange.push(adapter.endOfDay(stop))\n  }\n\n  return datesInRange\n}\n\nexport function daysDiff (adapter: DateInstance, start: unknown, stop?: unknown): number {\n  const iso = [\n    `${adapter.toISO(stop ?? start).split('T')[0]}T00:00:00Z`,\n    `${adapter.toISO(start).split('T')[0]}T00:00:00Z`,\n  ]\n  return typeof adapter.date() === 'string'\n    ? adapter.getDiff(iso[0], iso[1], 'days') // for StringDateAdapter\n    : adapter.getDiff(adapter.date(iso[0]), adapter.date(iso[1]), 'days')\n}\n\nfunction createInstance (options: InternalDateOptions, locale: LocaleInstance) {\n  const instance = reactive(\n    typeof options.adapter === 'function'\n      // eslint-disable-next-line new-cap\n      ? new options.adapter({\n        locale: options.locale[locale.current.value] ?? locale.current.value,\n        formats: options.formats,\n      })\n      : options.adapter\n  )\n\n  watch(locale.current, value => {\n    instance.locale = options.locale[value] ?? value ?? instance.locale\n  })\n\n  return instance\n}\n\nexport function useDate (): DateInstance {\n  const options = inject(DateOptionsSymbol)\n\n  if (!options) throw new Error('[Vuetify] Could not find injected date options')\n\n  const locale = useLocale()\n\n  return createInstance(options, locale)\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/date/index.ts",
    "content": "export { createDate, useDate, DateAdapterSymbol } from './date'\nexport type { DateAdapter } from './DateAdapter'\nexport type { DateOptions, DateInstance, DateModule } from './date'\nexport { VuetifyDateAdapter } from './adapters/vuetify'\n"
  },
  {
    "path": "packages/vuetify/src/composables/dateFormat.ts",
    "content": "// Composables\nimport { useDate } from '@/composables/date/date'\n\n// Utilities\nimport { toRef } from 'vue'\nimport { consoleWarn, propsFactory } from '@/util'\n\n// Types\nimport type { Ref } from 'vue'\n\n// Types\nexport interface DateFormatProps {\n  inputFormat?: string\n}\n\nclass DateFormatSpec {\n  constructor (\n    public readonly order: string, // mdy | dmy | ymd\n    public readonly separator: string // / | - | .\n  ) { }\n\n  get format () {\n    return this.order.split('')\n      .map(sign => `${sign}${sign}`)\n      .join(this.separator)\n      .replace('yy', 'yyyy')\n  }\n\n  static canBeParsed (v: any) {\n    if (typeof v !== 'string') return false\n    const lowercase = v.toLowerCase()\n    return ['y', 'm', 'd'].every(sign => lowercase.includes(sign)) &&\n      ['/', '-', '.'].some(sign => v.includes(sign))\n  }\n\n  static parse (v: string) {\n    if (!DateFormatSpec.canBeParsed(v)) {\n      throw new Error(`[${v}] cannot be parsed into date format specification`)\n    }\n    const order = v.toLowerCase().split('')\n      .filter((c, i, all) => 'dmy'.includes(c) && all.indexOf(c) === i)\n      .join('')\n    const separator = ['/', '-', '.'].find(sign => v.includes(sign))!\n    return new DateFormatSpec(order, separator)\n  }\n}\n\nexport const makeDateFormatProps = propsFactory({\n  inputFormat: {\n    type: String,\n    validator: (v: string) => !v || DateFormatSpec.canBeParsed(v),\n  },\n}, 'date-format')\n\nexport function useDateFormat (props: DateFormatProps, locale: Ref<string>) {\n  const adapter = useDate()\n\n  function inferFromLocale () {\n    const localeForDateFormat = locale.value ?? 'en-US'\n    const formatFromLocale = Intl.DateTimeFormat(localeForDateFormat, { year: 'numeric', month: '2-digit', day: '2-digit' })\n      .format(adapter.toJsDate(adapter.parseISO('1999-12-07')))\n      .replace(/(07)|(٠٧)|(٢٩)|(۱۶)|(০৭)/, 'dd')\n      .replace(/(12)|(١٢)|(٠٨)|(۰۹)|(১২)/, 'mm')\n      .replace(/(1999)|(2542)|(١٩٩٩)|(١٤٢٠)|(۱۳۷۸)|(১৯৯৯)/, 'yyyy')\n      .replace(/[^ymd\\-/.]/g, '')\n      .replace(/\\.$/, '')\n\n    if (!DateFormatSpec.canBeParsed(formatFromLocale)) {\n      consoleWarn(`Date format inferred from locale [${localeForDateFormat}] is invalid: [${formatFromLocale}]`)\n      return 'mm/dd/yyyy'\n    }\n\n    return formatFromLocale\n  }\n\n  const currentFormat = toRef(() => {\n    return DateFormatSpec.canBeParsed(props.inputFormat)\n      ? DateFormatSpec.parse(props.inputFormat!)\n      : DateFormatSpec.parse(inferFromLocale())\n  })\n\n  function parseDate (dateString: string) {\n    function parseDateParts (text: string): Record<'y' |'m' | 'd', number> {\n      const parts = text.trim().split(currentFormat.value.separator)\n\n      return {\n        y: Number(parts[currentFormat.value.order.indexOf('y')]),\n        m: Number(parts[currentFormat.value.order.indexOf('m')]),\n        d: Number(parts[currentFormat.value.order.indexOf('d')]),\n      }\n    }\n\n    function validateDateParts (dateParts: Record<string, number>) {\n      const { y: year, m: month, d: day } = dateParts\n      if (!year || !month || !day) return null\n      if (month < 1 || month > 12) return null\n      if (day < 1 || day > 31) return null\n\n      return { year: autoFixYear(year), month, day }\n    }\n\n    function autoFixYear (year: number) {\n      const currentYear = adapter.getYear(adapter.date())\n      if (year > 100 || currentYear % 100 >= 50) {\n        return year\n      }\n\n      const currentCentury = ~~(currentYear / 100) * 100\n\n      return year < 50\n        ? currentCentury + year\n        : (currentCentury - 100) + year\n    }\n\n    const dateParts = parseDateParts(dateString)\n    const validatedParts = validateDateParts(dateParts)\n\n    if (!validatedParts) return null\n\n    const { year, month, day } = validatedParts\n\n    const pad = (v: number) => String(v).padStart(2, '0')\n\n    return adapter.parseISO(`${year}-${pad(month)}-${pad(day)}`)\n  }\n\n  function isValid (text: string) {\n    return !!parseDate(text)\n  }\n\n  function formatDate (value: unknown) {\n    const parts = adapter.toISO(value).split('T')[0].split('-')\n\n    return currentFormat.value.order.split('')\n      .map(sign => parts['ymd'.indexOf(sign)])\n      .join(currentFormat.value.separator)\n  }\n\n  return {\n    isValid,\n    parseDate,\n    formatDate,\n    parserFormat: toRef(() => currentFormat.value.format),\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/defaults.ts",
    "content": "// Utilities\nimport { computed, inject, provide, ref, shallowRef, unref, watchEffect } from 'vue'\nimport { getCurrentInstance } from '@/util/getCurrentInstance'\nimport { mergeDeep, toKebabCase } from '@/util/helpers'\nimport { injectSelf } from '@/util/injectSelf'\n\n// Types\nimport type { ComputedRef, InjectionKey, Ref, VNode } from 'vue'\nimport type { MaybeRef } from '@/util'\n\nexport type DefaultsInstance = undefined | {\n  [key: string]: undefined | Record<string, unknown>\n  global?: Record<string, unknown>\n}\n\nexport type DefaultsOptions = Partial<DefaultsInstance>\n\nexport const DefaultsSymbol: InjectionKey<Ref<DefaultsInstance>> = Symbol.for('vuetify:defaults')\n\nexport function createDefaults (options?: DefaultsInstance): Ref<DefaultsInstance> {\n  return ref(options)\n}\n\nexport function injectDefaults () {\n  const defaults = inject(DefaultsSymbol)\n\n  if (!defaults) throw new Error('[Vuetify] Could not find defaults instance')\n\n  return defaults\n}\n\nexport function provideDefaults (\n  defaults?: MaybeRef<DefaultsInstance | undefined>,\n  options?: {\n    disabled?: MaybeRef<boolean | undefined>\n    reset?: MaybeRef<number | string | undefined>\n    root?: MaybeRef<boolean | string | undefined>\n    scoped?: MaybeRef<boolean | undefined>\n  }\n) {\n  const injectedDefaults = injectDefaults()\n  const providedDefaults = ref(defaults)\n\n  const newDefaults = computed(() => {\n    const disabled = unref(options?.disabled)\n\n    if (disabled) return injectedDefaults.value\n\n    const scoped = unref(options?.scoped)\n    const reset = unref(options?.reset)\n    const root = unref(options?.root)\n\n    if (providedDefaults.value == null && !(scoped || reset || root)) return injectedDefaults.value\n\n    let properties = mergeDeep(providedDefaults.value, { prev: injectedDefaults.value })\n\n    if (scoped) return properties\n\n    if (reset || root) {\n      const len = Number(reset || Infinity)\n\n      for (let i = 0; i <= len; i++) {\n        if (!properties || !('prev' in properties)) {\n          break\n        }\n\n        properties = properties.prev\n      }\n\n      if (properties && typeof root === 'string' && root in properties) {\n        properties = mergeDeep(mergeDeep(properties, { prev: properties }), properties[root])\n      }\n\n      return properties\n    }\n\n    return properties.prev\n      ? mergeDeep(properties.prev, properties, undefined, (_, v) => v !== undefined)\n      : properties\n  }) as ComputedRef<DefaultsInstance>\n\n  provide(DefaultsSymbol, newDefaults)\n\n  return newDefaults\n}\n\nfunction propIsDefined (vnode: VNode, prop: string) {\n  return vnode.props && (typeof vnode.props[prop] !== 'undefined' ||\n    typeof vnode.props[toKebabCase(prop)] !== 'undefined')\n}\n\nexport function internalUseDefaults (\n  props: Record<string, any> = {},\n  name?: string,\n  defaults = injectDefaults()\n) {\n  const vm = getCurrentInstance('useDefaults')\n\n  name = name ?? vm.type.name ?? vm.type.__name\n  if (!name) {\n    throw new Error('[Vuetify] Could not determine component name')\n  }\n\n  const componentDefaults = computed(() => defaults.value?.[props._as ?? name])\n  const _props = new Proxy(props, {\n    get (target, prop: string) {\n      const propValue = Reflect.get(target, prop)\n      if (prop === 'class' || prop === 'style') {\n        return [componentDefaults.value?.[prop], propValue].filter(v => v != null)\n      }\n      if (propIsDefined(vm.vnode, prop)) return propValue\n      const _componentDefault = componentDefaults.value?.[prop]\n      if (_componentDefault !== undefined) return _componentDefault\n      const _globalDefault = defaults.value?.global?.[prop]\n      if (_globalDefault !== undefined) return _globalDefault\n      return propValue\n    },\n  })\n\n  const _subcomponentDefaults = shallowRef()\n  watchEffect(() => {\n    if (componentDefaults.value) {\n      const subComponents = Object.entries(componentDefaults.value)\n        .filter(([key]) => key.startsWith(key[0].toUpperCase()))\n      _subcomponentDefaults.value = subComponents.length ? Object.fromEntries(subComponents) : undefined\n    } else {\n      _subcomponentDefaults.value = undefined\n    }\n  })\n\n  function provideSubDefaults () {\n    const injected = injectSelf(DefaultsSymbol, vm)\n    provide(DefaultsSymbol, computed(() => {\n      return _subcomponentDefaults.value ? mergeDeep(\n        injected?.value ?? {},\n        _subcomponentDefaults.value\n      ) : injected?.value\n    }))\n  }\n\n  return { props: _props, provideSubDefaults }\n}\n\nexport function useDefaults<T extends Record<string, any>> (props: T, name?: string): T\nexport function useDefaults (props?: undefined, name?: string): Record<string, any>\nexport function useDefaults (\n  props: Record<string, any> = {},\n  name?: string,\n) {\n  const { props: _props, provideSubDefaults } = internalUseDefaults(props, name)\n  provideSubDefaults()\n  return _props\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/delay.ts",
    "content": "// Utilities\nimport { defer, propsFactory } from '@/util'\n\n// Types\nexport interface DelayProps {\n  closeDelay?: number | string\n  openDelay?: number | string\n}\n\n// Composables\nexport const makeDelayProps = propsFactory({\n  closeDelay: [Number, String],\n  openDelay: [Number, String],\n}, 'delay')\n\nexport function useDelay (props: DelayProps, cb?: (value: boolean) => void) {\n  let clearDelay: (() => void) = () => {}\n\n  function runDelay (isOpening: boolean, options?: { minDelay: number }) {\n    clearDelay?.()\n\n    const delay = isOpening ? props.openDelay : props.closeDelay\n\n    const normalizedDelay = Math.max(\n      options?.minDelay ?? 0,\n      Number(delay ?? 0)\n    )\n\n    return new Promise(resolve => {\n      clearDelay = defer(normalizedDelay, () => {\n        cb?.(isOpening)\n        resolve(isOpening)\n      })\n    })\n  }\n\n  function runOpenDelay () {\n    return runDelay(true)\n  }\n\n  function runCloseDelay (options?: { minDelay: number }) {\n    return runDelay(false, options)\n  }\n\n  return {\n    clearDelay,\n    runOpenDelay,\n    runCloseDelay,\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/density.ts",
    "content": "// Utilities\nimport { toRef } from 'vue'\nimport { getCurrentInstanceName, propsFactory } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\nconst allowedDensities = [null, 'default', 'comfortable', 'compact'] as const\n\n// typeof allowedDensities[number] evaluates to any\n// when generating api types for whatever reason.\nexport type Density = null | 'default' | 'comfortable' | 'compact'\n\nexport interface DensityProps {\n  density?: Density\n}\n\n// Composables\nexport const makeDensityProps = propsFactory({\n  density: {\n    type: String as PropType<Density>,\n    default: 'default',\n    validator: (v: any) => allowedDensities.includes(v),\n  },\n}, 'density')\n\nexport function useDensity (\n  props: DensityProps,\n  name = getCurrentInstanceName(),\n) {\n  const densityClasses = toRef(() => {\n    return `${name}--density-${props.density}`\n  })\n\n  return { densityClasses }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/dimensions.ts",
    "content": "// Utilities\nimport { computed } from 'vue'\nimport { convertToUnit, propsFactory } from '@/util'\n\n// Types\nexport interface DimensionProps {\n  height?: number | string\n  maxHeight?: number | string\n  maxWidth?: number | string\n  minHeight?: number | string\n  minWidth?: number | string\n  width?: number | string\n}\n\n// Composables\nexport const makeDimensionProps = propsFactory({\n  height: [Number, String],\n  maxHeight: [Number, String],\n  maxWidth: [Number, String],\n  minHeight: [Number, String],\n  minWidth: [Number, String],\n  width: [Number, String],\n}, 'dimension')\n\nexport function useDimension (props: DimensionProps) {\n  const dimensionStyles = computed(() => {\n    const styles: Record<string, any> = {}\n\n    const height = convertToUnit(props.height)\n    const maxHeight = convertToUnit(props.maxHeight)\n    const maxWidth = convertToUnit(props.maxWidth)\n    const minHeight = convertToUnit(props.minHeight)\n    const minWidth = convertToUnit(props.minWidth)\n    const width = convertToUnit(props.width)\n\n    if (height != null) styles.height = height\n    if (maxHeight != null) styles.maxHeight = maxHeight\n    if (maxWidth != null) styles.maxWidth = maxWidth\n    if (minHeight != null) styles.minHeight = minHeight\n    if (minWidth != null) styles.minWidth = minWidth\n    if (width != null) styles.width = width\n\n    return styles\n  })\n\n  return { dimensionStyles }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/directiveComponent.ts",
    "content": "// Utilities\nimport { h, mergeProps, render, resolveComponent } from 'vue'\nimport { consoleError, isObject } from '@/util'\n\n// Types\nimport type {\n  Component,\n  ComponentInternalInstance,\n  ComponentPublicInstance,\n  ConcreteComponent,\n  DirectiveBinding,\n  ObjectDirective,\n  VNode,\n} from 'vue'\nimport type { ComponentInstance } from '@/util'\n\ntype ExcludeProps =\n  | 'v-slots'\n  | `v-slot:${string}`\n  | `on${Uppercase<string>}${string}`\n  | 'key'\n  | 'ref'\n  | 'ref_for'\n  | 'ref_key'\n  | '$children'\n\ndeclare const CustomDirectiveSymbol: unique symbol\ntype DirectiveHook<B extends DirectiveBinding> = (el: any, binding: B, vnode: VNode<any, any>, prevVNode: VNode<any, any>) => void\nexport interface CustomDirective<B extends DirectiveBinding = DirectiveBinding> {\n  created?: DirectiveHook<B>\n  beforeMount?: DirectiveHook<B>\n  mounted?: DirectiveHook<B>\n  beforeUpdate?: DirectiveHook<B>\n  updated?: DirectiveHook<B>\n  beforeUnmount?: DirectiveHook<B>\n  unmounted?: DirectiveHook<B>\n  [CustomDirectiveSymbol]: true\n}\n\nexport function useDirectiveComponent <\n  Binding extends DirectiveBinding,\n> (component: string | Component, props?: (binding: Binding) => Record<string, any>): CustomDirective<Binding>\nexport function useDirectiveComponent <\n  C extends Component,\n  Props = Omit<ComponentInstance<C>['$props'], ExcludeProps>\n> (component: string | C, props?: Record<string, any>): ObjectDirective<any, Props>\nexport function useDirectiveComponent (\n  component: string | Component,\n  props?: Record<string, any> | ((binding: DirectiveBinding) => Record<string, any>)\n): ObjectDirective | CustomDirective {\n  const concreteComponent = (typeof component === 'string'\n    ? resolveComponent(component)\n    : component) as ConcreteComponent\n\n  const hook = mountComponent(concreteComponent, props)\n\n  return {\n    mounted: hook,\n    updated: hook,\n    unmounted (el: HTMLElement) {\n      render(null, el)\n    },\n  }\n}\n\nfunction mountComponent (component: ConcreteComponent, props?: Record<string, any> | ((binding: DirectiveBinding) => Record<string, any>)) {\n  return function (el: HTMLElement, binding: DirectiveBinding, vnode: VNode) {\n    const _props = typeof props === 'function' ? props(binding) : props\n    const text = binding.value?.text ?? binding.value ?? _props?.text\n    const value = isObject(binding.value) ? binding.value : {}\n\n    // Get the children from the props or directive value, or the element's children\n    const children = () => text ?? el.textContent\n\n    // If vnode.ctx is the same as the instance, then we're bound to a plain element\n    // and need to find the nearest parent component instance to inherit provides from\n    const provides = (vnode.ctx === binding.instance!.$\n      ? findComponentParent(vnode, binding.instance!.$)?.provides\n      : vnode.ctx?.provides) ?? binding.instance!.$.provides\n\n    const node = h(component, mergeProps(_props, value), children)\n    node.appContext = Object.assign(\n      Object.create(null),\n      (binding.instance as ComponentPublicInstance).$.appContext,\n      { provides }\n    )\n\n    render(node, el)\n  }\n}\n\nfunction findComponentParent (vnode: VNode, root: ComponentInternalInstance): ComponentInternalInstance | null {\n  // Walk the tree from root until we find the child vnode\n  const stack = new Set<VNode>()\n  const walk = (children: VNode[]): boolean => {\n    for (const child of children) {\n      if (!child) continue\n\n      if (child === vnode || (child.el && vnode.el && child.el === vnode.el)) {\n        return true\n      }\n\n      stack.add(child)\n      let result\n      if (child.suspense) {\n        result = walk([child.ssContent!])\n      } else if (Array.isArray(child.children)) {\n        result = walk(child.children as VNode[])\n      } else if (child.component?.vnode) {\n        result = walk([child.component?.subTree])\n      }\n      if (result) {\n        return result\n      }\n      stack.delete(child)\n    }\n\n    return false\n  }\n  if (!walk([root.subTree])) {\n    consoleError('Could not find original vnode, component will not inherit provides')\n    return root\n  }\n\n  // Return the first component parent\n  const result = Array.from(stack).reverse()\n  for (const child of result) {\n    if (child.component) {\n      return child.component\n    }\n  }\n  return root\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/display.ts",
    "content": "// Utilities\nimport { computed, inject, onScopeDispose, reactive, shallowRef, toRef, toRefs, watchEffect } from 'vue'\nimport { getCurrentInstanceName, mergeDeep, propsFactory } from '@/util'\nimport { IN_BROWSER, SUPPORTS_TOUCH } from '@/util/globals'\n\n// Types\nimport type { InjectionKey, PropType, Ref } from 'vue'\n\nexport const breakpoints = ['sm', 'md', 'lg', 'xl', 'xxl'] as const // no xs\n\nexport type Breakpoint = typeof breakpoints[number]\n\nexport type DisplayBreakpoint = 'xs' | Breakpoint\n\nexport type DisplayThresholds = {\n  [key in DisplayBreakpoint]: number\n}\n\nexport interface DisplayProps {\n  mobile?: boolean | null\n  mobileBreakpoint?: number | DisplayBreakpoint\n}\n\nexport interface DisplayOptions {\n  mobileBreakpoint?: number | DisplayBreakpoint\n  thresholds?: Partial<DisplayThresholds>\n}\n\nexport interface InternalDisplayOptions {\n  mobileBreakpoint: number | DisplayBreakpoint\n  thresholds: DisplayThresholds\n}\n\nexport type SSROptions = boolean | {\n  clientWidth: number\n  clientHeight?: number\n}\n\nexport interface DisplayPlatform {\n  android: boolean\n  ios: boolean\n  cordova: boolean\n  electron: boolean\n  chrome: boolean\n  edge: boolean\n  firefox: boolean\n  opera: boolean\n  win: boolean\n  mac: boolean\n  linux: boolean\n  touch: boolean\n  ssr: boolean\n}\n\nexport interface DisplayInstance {\n  xs: Ref<boolean>\n  sm: Ref<boolean>\n  md: Ref<boolean>\n  lg: Ref<boolean>\n  xl: Ref<boolean>\n  xxl: Ref<boolean>\n  smAndUp: Ref<boolean>\n  mdAndUp: Ref<boolean>\n  lgAndUp: Ref<boolean>\n  xlAndUp: Ref<boolean>\n  smAndDown: Ref<boolean>\n  mdAndDown: Ref<boolean>\n  lgAndDown: Ref<boolean>\n  xlAndDown: Ref<boolean>\n  name: Ref<DisplayBreakpoint>\n  height: Ref<number>\n  width: Ref<number>\n  mobile: Ref<boolean>\n  mobileBreakpoint: Ref<number | DisplayBreakpoint>\n  platform: Ref<DisplayPlatform>\n  thresholds: Ref<DisplayThresholds>\n\n  /** @internal */\n  ssr: boolean\n\n  update (): void\n}\n\nexport const DisplaySymbol: InjectionKey<DisplayInstance> = Symbol.for('vuetify:display')\n\nconst defaultDisplayOptions: DisplayOptions = {\n  mobileBreakpoint: 'lg',\n  thresholds: {\n    xs: 0,\n    sm: 600,\n    md: 840,\n    lg: 1145,\n    xl: 1545,\n    xxl: 2138,\n  },\n}\n\nconst parseDisplayOptions = (options: DisplayOptions = defaultDisplayOptions) => {\n  return mergeDeep(defaultDisplayOptions, options) as InternalDisplayOptions\n}\n\nfunction getClientWidth (ssr?: SSROptions) {\n  return IN_BROWSER && !ssr\n    ? window.innerWidth\n    : (typeof ssr === 'object' && ssr.clientWidth) || 0\n}\n\nfunction getClientHeight (ssr?: SSROptions) {\n  return IN_BROWSER && !ssr\n    ? window.innerHeight\n    : (typeof ssr === 'object' && ssr.clientHeight) || 0\n}\n\nfunction getPlatform (ssr?: SSROptions): DisplayPlatform {\n  const userAgent = IN_BROWSER && !ssr\n    ? window.navigator.userAgent\n    : 'ssr'\n\n  function match (regexp: RegExp) {\n    return Boolean(userAgent.match(regexp))\n  }\n\n  const android = match(/android/i)\n  const ios = match(/iphone|ipad|ipod/i)\n  const cordova = match(/cordova/i)\n  const electron = match(/electron/i)\n  const chrome = match(/chrome/i)\n  const edge = match(/edge/i)\n  const firefox = match(/firefox/i)\n  const opera = match(/opera/i)\n  const win = match(/win/i)\n  const mac = match(/mac/i)\n  const linux = match(/linux/i)\n\n  return {\n    android,\n    ios,\n    cordova,\n    electron,\n    chrome,\n    edge,\n    firefox,\n    opera,\n    win,\n    mac,\n    linux,\n    touch: SUPPORTS_TOUCH,\n    ssr: userAgent === 'ssr',\n  }\n}\n\nexport function createDisplay (options?: DisplayOptions, ssr?: SSROptions): DisplayInstance {\n  const { thresholds, mobileBreakpoint } = parseDisplayOptions(options)\n\n  const height = shallowRef(getClientHeight(ssr))\n  const platform = shallowRef(getPlatform(ssr))\n  const state = reactive({} as DisplayInstance)\n  const width = shallowRef(getClientWidth(ssr))\n\n  function updateSize () {\n    height.value = getClientHeight()\n    width.value = getClientWidth()\n  }\n  function update () {\n    updateSize()\n    platform.value = getPlatform()\n  }\n\n  // eslint-disable-next-line max-statements\n  watchEffect(() => {\n    const xs = width.value < thresholds.sm\n    const sm = width.value < thresholds.md && !xs\n    const md = width.value < thresholds.lg && !(sm || xs)\n    const lg = width.value < thresholds.xl && !(md || sm || xs)\n    const xl = width.value < thresholds.xxl && !(lg || md || sm || xs)\n    const xxl = width.value >= thresholds.xxl\n    const name =\n      xs ? 'xs'\n      : sm ? 'sm'\n      : md ? 'md'\n      : lg ? 'lg'\n      : xl ? 'xl'\n      : 'xxl'\n    const breakpointValue = typeof mobileBreakpoint === 'number' ? mobileBreakpoint : thresholds[mobileBreakpoint]\n    const mobile = width.value < breakpointValue\n\n    state.xs = xs\n    state.sm = sm\n    state.md = md\n    state.lg = lg\n    state.xl = xl\n    state.xxl = xxl\n    state.smAndUp = !xs\n    state.mdAndUp = !(xs || sm)\n    state.lgAndUp = !(xs || sm || md)\n    state.xlAndUp = !(xs || sm || md || lg)\n    state.smAndDown = !(md || lg || xl || xxl)\n    state.mdAndDown = !(lg || xl || xxl)\n    state.lgAndDown = !(xl || xxl)\n    state.xlAndDown = !xxl\n    state.name = name\n    state.height = height.value\n    state.width = width.value\n    state.mobile = mobile\n    state.mobileBreakpoint = mobileBreakpoint\n    state.platform = platform.value\n    state.thresholds = thresholds\n  })\n\n  if (IN_BROWSER) {\n    window.addEventListener('resize', updateSize, { passive: true })\n\n    onScopeDispose(() => {\n      window.removeEventListener('resize', updateSize)\n    }, true)\n  }\n\n  return { ...toRefs(state), update, ssr: !!ssr }\n}\n\nexport const makeDisplayProps = propsFactory({\n  mobile: {\n    type: Boolean as PropType<boolean | null>,\n    default: false,\n  },\n  mobileBreakpoint: [Number, String] as PropType<number | DisplayBreakpoint>,\n}, 'display')\n\nexport function useDisplay (\n  props: DisplayProps = { mobile: null },\n  name = getCurrentInstanceName(),\n) {\n  const display = inject(DisplaySymbol)\n\n  if (!display) throw new Error('Could not find Vuetify display injection')\n\n  const mobile = computed(() => {\n    if (props.mobile) {\n      return true\n    } else if (typeof props.mobileBreakpoint === 'number') {\n      return display.width.value < props.mobileBreakpoint\n    } else if (props.mobileBreakpoint) {\n      return display.width.value < display.thresholds.value[props.mobileBreakpoint]\n    } else if (props.mobile === null) {\n      return display.mobile.value\n    } else {\n      return false\n    }\n  })\n\n  const displayClasses = toRef(() => {\n    if (!name) return {}\n\n    return { [`${name}--mobile`]: mobile.value }\n  })\n\n  return { ...display, displayClasses, mobile }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/documentVisibility.ts",
    "content": "// Utilities\nimport { onBeforeUnmount, shallowRef } from 'vue'\nimport { IN_BROWSER } from '@/util/globals'\n\nexport function useDocumentVisibility () {\n  const visibility = shallowRef(IN_BROWSER ? document.visibilityState : 'visible')\n\n  if (IN_BROWSER) {\n    const onVisibilityChange = () => {\n      visibility.value = document.visibilityState\n    }\n    document.addEventListener('visibilitychange', onVisibilityChange, { passive: true })\n    onBeforeUnmount(() => {\n      document.removeEventListener('visibilitychange', onVisibilityChange)\n    })\n  }\n\n  return visibility\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/elevation.ts",
    "content": "// Utilities\nimport { isRef, toRef } from 'vue'\nimport { propsFactory } from '@/util'\n\n// Types\nimport type { Ref } from 'vue'\nexport interface ElevationProps {\n  elevation?: number | string | null\n}\n\n// Composables\nexport const makeElevationProps = propsFactory({\n  elevation: {\n    type: [Number, String],\n    // no limit to allow both 0-6 (MD3) and legacy 0-24 (MD2)\n    validator: (value: string | number) => parseInt(value) >= 0,\n  },\n}, 'elevation')\n\ntype ElevationData = {\n  elevationClasses: Ref<string[]>\n}\n\nexport function useElevation (props: ElevationProps | Ref<number | string | undefined>): ElevationData {\n  const elevationClasses = toRef(() => {\n    const elevation = isRef(props) ? props.value : props.elevation\n    if (elevation == null) return []\n    return [`elevation-${parseInt(elevation)}`]\n  })\n\n  return { elevationClasses }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/fileDrop.ts",
    "content": "// Types\ntype FileSelection = { file: File, path: string }\n\nexport function useFileDrop () {\n  function hasFilesOrFolders (e: DragEvent): boolean {\n    const entries = [...e.dataTransfer?.items ?? []]\n      .filter(x => x.kind === 'file')\n      .map(x => x.webkitGetAsEntry())\n      .filter(Boolean)\n\n    return entries.length > 0 || [...e.dataTransfer?.files ?? []].length > 0\n  }\n\n  async function handleDrop (e: DragEvent) {\n    const result: File[] = []\n\n    const entries = [...e.dataTransfer?.items ?? []]\n      .filter(x => x.kind === 'file')\n      .map(x => x.webkitGetAsEntry())\n      .filter(Boolean)\n\n    if (entries.length) {\n      for (const entry of entries) {\n        const files = await traverseFileTree(entry!, appendIfDirectory('.', entry!))\n        result.push(...files.map(x => x.file))\n      }\n    } else {\n      result.push(...[...e.dataTransfer?.files ?? []])\n    }\n\n    return result\n  }\n\n  return {\n    handleDrop,\n    hasFilesOrFolders,\n  }\n}\n\nfunction traverseFileTree (item: FileSystemEntry, path = ''): Promise<FileSelection[]> {\n  return new Promise<FileSelection[]>((resolve, reject) => {\n    if (item.isFile) {\n      const fileEntry = item as FileSystemFileEntry\n      fileEntry.file((file: File) => resolve([{ file, path }]), reject)\n    } else if (item.isDirectory) {\n      const directoryReader = (item as FileSystemDirectoryEntry).createReader()\n      directoryReader.readEntries(async entries => {\n        const files = [] as FileSelection[]\n        for (const entry of entries) {\n          files.push(...(await traverseFileTree(entry, appendIfDirectory(path, entry))))\n        }\n        resolve(files)\n      })\n    }\n  })\n}\n\nfunction appendIfDirectory (path: string, item: FileSystemEntry) {\n  return item.isDirectory\n    ? `${path}/${item.name}`\n    : path\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/fileFilter.ts",
    "content": "// Utilities\nimport { computed } from 'vue'\nimport { propsFactory } from '@/util'\n\nexport interface FileFilterProps {\n  filterByType?: string\n}\n\nexport type FileFilterResult = {\n  accepted: File[]\n  rejected: File[]\n}\n\n// Composables\nexport const makeFileFilterProps = propsFactory({\n  filterByType: String,\n}, 'file-accept')\n\nexport function useFileFilter (props: FileFilterProps) {\n  const fileFilter = computed(() => props.filterByType ? createFilter(props.filterByType) : null)\n\n  function filterAccepted (files: File[]): FileFilterResult {\n    if (fileFilter.value) {\n      const accepted = files.filter(fileFilter.value)\n      return {\n        accepted,\n        rejected: files.filter(f => !accepted.includes(f)),\n      }\n    }\n    return {\n      accepted: files,\n      rejected: [],\n    }\n  }\n\n  return {\n    filterAccepted,\n  }\n}\n\nfunction createFilter (v: string): ((v: File) => boolean) {\n  const types = v.split(',').map(x => x.trim().toLowerCase())\n  const extensionsToMatch = types.filter(x => x.startsWith('.'))\n  const wildcards = types.filter(x => x.endsWith('/*'))\n  const typesToMatch = types.filter(x => !extensionsToMatch.includes(x) && !wildcards.includes(x))\n\n  return (file: File): boolean => {\n    const extension = file.name.split('.').at(-1)?.toLowerCase() ?? ''\n    const typeGroup = file.type.split('/').at(0)?.toLowerCase() ?? ''\n    return typesToMatch.includes(file.type) ||\n      extensionsToMatch.includes(`.${extension}`) ||\n      wildcards.includes(`${typeGroup}/*`)\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/filter.tsx",
    "content": "/* eslint-disable max-statements */\n/* eslint-disable no-labels */\n\n// Utilities\nimport { computed, shallowRef, unref, watchEffect } from 'vue'\nimport { getPropertyFromItem, propsFactory, wrapInArray } from '@/util'\n\n// Types\nimport type { PropType, Ref } from 'vue'\nimport type { MaybeRef } from '@/util'\n\n/**\n * - boolean: match without highlight\n * - number: single match (index), length already known\n * - []: single match (start, end)\n * - [][]: multiple matches (start, end), shouldn't overlap\n */\nexport type FilterMatchArraySingle = readonly [number, number]\nexport type FilterMatchArrayMultiple = readonly FilterMatchArraySingle[]\nexport type FilterMatchArray = FilterMatchArraySingle | FilterMatchArrayMultiple\nexport type FilterMatch = boolean | number | FilterMatchArray\nexport type FilterFunction = (value: string, query: string, item?: InternalItem) => FilterMatch\nexport type FilterKeyFunctions = Record<string, FilterFunction>\nexport type FilterKeys = string | string[]\nexport type FilterMode = 'some' | 'every' | 'union' | 'intersection'\n\nexport interface FilterProps {\n  customFilter?: FilterFunction\n  customKeyFilter?: FilterKeyFunctions\n  filterKeys?: FilterKeys\n  filterMode?: FilterMode\n  noFilter?: boolean\n}\n\nexport interface InternalItem<T = any> {\n  value: any\n  raw: T\n  type?: string\n}\n\ntype FilterResult = {\n  index: number\n  matches: Record<string, FilterMatchArrayMultiple | undefined>\n  type?: 'divider' | 'subheader'\n}\n\n// Composables\nexport const defaultFilter: FilterFunction = (value, query, item) => {\n  if (value == null || query == null) return -1\n  if (!query.length) return 0\n\n  value = value.toString().toLocaleLowerCase()\n  query = query.toString().toLocaleLowerCase()\n\n  const result = []\n  let idx = value.indexOf(query)\n  while (~idx) {\n    result.push([idx, idx + query.length] as const)\n\n    idx = value.indexOf(query, idx + query.length)\n  }\n\n  return result.length ? result : -1\n}\n\nfunction normaliseMatch (match: FilterMatch, query: string): FilterMatchArrayMultiple | undefined {\n  if (match == null || typeof match === 'boolean' || match === -1) return\n  if (typeof match === 'number') return [[match, match + query.length]]\n  if (Array.isArray(match[0])) return match as FilterMatchArrayMultiple\n  return [match] as FilterMatchArrayMultiple\n}\n\nexport const makeFilterProps = propsFactory({\n  customFilter: Function as PropType<FilterFunction>,\n  customKeyFilter: Object as PropType<FilterKeyFunctions>,\n  filterKeys: [Array, String] as PropType<FilterKeys>,\n  filterMode: {\n    type: String as PropType<FilterMode>,\n    default: 'intersection',\n  },\n  noFilter: Boolean,\n}, 'filter')\n\n// eslint-disable-next-line complexity\nexport function filterItems (\n  items: readonly (readonly [item: InternalItem, transformed: {}])[] | readonly InternalItem[],\n  query: string,\n  options?: {\n    customKeyFilter?: FilterKeyFunctions\n    default?: FilterFunction\n    filterKeys?: FilterKeys\n    filterMode?: FilterMode\n    noFilter?: boolean\n  },\n) {\n  const array: FilterResult[] = []\n  // always ensure we fall back to a functioning filter\n  const filter = options?.default ?? defaultFilter\n  const keys = options?.filterKeys ? wrapInArray(options.filterKeys) : false\n  const customFiltersLength = Object.keys(options?.customKeyFilter ?? {}).length\n\n  if (!items?.length) return array\n\n  let lookAheadItems: FilterResult[] = []\n\n  loop:\n  for (let i = 0; i < items.length; i++) {\n    const [item, transformed = item] = wrapInArray(items[i]) as readonly [InternalItem, {}]\n    const customMatches: Record<string, FilterMatchArrayMultiple | undefined> = {}\n    const defaultMatches: Record<string, FilterMatchArrayMultiple | undefined> = {}\n    let match: FilterMatch = -1\n\n    if ((query || customFiltersLength > 0) && !options?.noFilter) {\n      let hasOnlyCustomFilters = false\n\n      if (typeof item === 'object') {\n        if (item.type === 'divider' || item.type === 'subheader') {\n          if (lookAheadItems.at(-1)?.type !== 'divider' || item.type !== 'subheader') {\n            // clear unless, divider appears before subheader\n            lookAheadItems = []\n          }\n\n          lookAheadItems.push({ index: i, matches: { }, type: item.type })\n          continue\n        }\n\n        const filterKeys = keys || Object.keys(transformed)\n        hasOnlyCustomFilters = filterKeys.length === customFiltersLength\n\n        for (const key of filterKeys) {\n          const value = getPropertyFromItem(transformed, key)\n          const keyFilter = options?.customKeyFilter?.[key]\n\n          match = keyFilter\n            ? keyFilter(value, query, item)\n            : filter(value, query, item)\n\n          if (match !== -1 && match !== false) {\n            if (keyFilter) customMatches[key] = normaliseMatch(match, query)\n            else defaultMatches[key] = normaliseMatch(match, query)\n          } else if (options?.filterMode === 'every') {\n            continue loop\n          }\n        }\n      } else {\n        match = filter(item, query, item)\n        if (match !== -1 && match !== false) {\n          defaultMatches.title = normaliseMatch(match, query)\n        }\n      }\n\n      const defaultMatchesLength = Object.keys(defaultMatches).length\n      const customMatchesLength = Object.keys(customMatches).length\n\n      if (!defaultMatchesLength && !customMatchesLength) continue\n\n      if (\n        options?.filterMode === 'union' &&\n        customMatchesLength !== customFiltersLength &&\n        !defaultMatchesLength\n      ) continue\n\n      if (\n        options?.filterMode === 'intersection' &&\n        (\n          customMatchesLength !== customFiltersLength ||\n          (!defaultMatchesLength && customFiltersLength > 0 && !hasOnlyCustomFilters)\n        )\n      ) continue\n    }\n\n    if (lookAheadItems.length) {\n      array.push(...lookAheadItems)\n      lookAheadItems = []\n    }\n\n    array.push({ index: i, matches: { ...defaultMatches, ...customMatches } })\n  }\n\n  return array\n}\n\nexport function useFilter <T extends InternalItem> (\n  props: FilterProps,\n  items: MaybeRef<T[]>,\n  query: Ref<string | undefined> | (() => string | undefined),\n  options?: {\n    transform?: (item: T) => {}\n    customKeyFilter?: MaybeRef<FilterKeyFunctions | undefined>\n  }\n) {\n  const filteredItems = shallowRef<T[]>([])\n  const filteredMatches = shallowRef(new Map<unknown, Record<string, FilterMatchArrayMultiple | undefined>>())\n  const transformedItems = computed(() => (\n    options?.transform\n      ? unref(items).map(item => ([item, options.transform!(item)] as const))\n      : unref(items)\n  ))\n\n  watchEffect(() => {\n    const _query = typeof query === 'function' ? query() : unref(query)\n    const strQuery = (\n      typeof _query !== 'string' &&\n      typeof _query !== 'number'\n    ) ? '' : String(_query)\n\n    const results = filterItems(\n      transformedItems.value,\n      strQuery,\n      {\n        customKeyFilter: {\n          ...props.customKeyFilter,\n          ...unref(options?.customKeyFilter),\n        },\n        default: props.customFilter,\n        filterKeys: props.filterKeys,\n        filterMode: props.filterMode,\n        noFilter: props.noFilter,\n      },\n    )\n\n    const originalItems = unref(items)\n\n    const _filteredItems: typeof filteredItems['value'] = []\n    const _filteredMatches: typeof filteredMatches['value'] = new Map()\n    results.forEach(({ index, matches }) => {\n      const item = originalItems[index]\n      _filteredItems.push(item)\n      _filteredMatches.set(item.value, matches)\n    })\n    filteredItems.value = _filteredItems\n    filteredMatches.value = _filteredMatches\n  })\n\n  function getMatches (item: T) {\n    return filteredMatches.value.get(item.value)\n  }\n\n  return { filteredItems, filteredMatches, getMatches }\n}\n\nexport function highlightResult (name: string, text: string, matches: FilterMatchArrayMultiple | undefined) {\n  if (matches == null || !matches.length) return text\n\n  return matches.map((match, i) => {\n    const start = i === 0 ? 0 : matches[i - 1][1]\n    const result = [\n      <span class={ `${name}__unmask` }>{ text.slice(start, match[0]) }</span>,\n      <span class={ `${name}__mask` }>{ text.slice(match[0], match[1]) }</span>,\n    ]\n    if (i === matches.length - 1) {\n      result.push(<span class={ `${name}__unmask` }>{ text.slice(match[1]) }</span>)\n    }\n    return <>{ result }</>\n  })\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/focus.ts",
    "content": "// Composables\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { toRef } from 'vue'\nimport { EventProp, getCurrentInstanceName, propsFactory } from '@/util'\n\n// Types\nexport interface FocusProps {\n  focused: boolean\n  'onUpdate:focused': ((focused: boolean) => any) | undefined\n}\n\n// Composables\nexport const makeFocusProps = propsFactory({\n  focused: Boolean,\n  'onUpdate:focused': EventProp<[boolean]>(),\n}, 'focus')\n\nexport function useFocus (\n  props: FocusProps,\n  name = getCurrentInstanceName()\n) {\n  const isFocused = useProxiedModel(props, 'focused')\n  const focusClasses = toRef(() => {\n    return ({\n      [`${name}--focused`]: isFocused.value,\n    })\n  })\n\n  function focus () {\n    isFocused.value = true\n  }\n\n  function blur () {\n    isFocused.value = false\n  }\n\n  return { focusClasses, isFocused, focus, blur }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/focusGroups.ts",
    "content": "// Utilities\nimport { toValue } from 'vue'\nimport { focusableChildren } from '@/util'\n\n// Types\nimport type { MaybeRefOrGetter, Ref } from 'vue'\nimport type { VList } from '@/components/VList'\n\ntype FocusGroup =\n  | { type: 'list', contentRef: Ref<VList | undefined>, displayItemsCount: MaybeRefOrGetter<number> }\n  | { type: 'element', contentRef: Ref<HTMLElement | undefined> }\n\nexport function useFocusGroups ({ groups, onLeave }: {\n  groups: FocusGroup[]\n  onLeave: () => void\n}) {\n  function getContentRef (group: FocusGroup): HTMLElement | undefined {\n    return group.type === 'list'\n      ? group.contentRef.value?.$el as HTMLElement | undefined\n      : group.contentRef.value\n  }\n\n  function getChildren (group: FocusGroup): HTMLElement[] {\n    const contentRef = getContentRef(group)\n    return contentRef ? focusableChildren(contentRef) : []\n  }\n\n  function onTabKeydown (e: KeyboardEvent) {\n    const target = e.target as Element\n    const direction = e.shiftKey ? 'backward' : 'forward'\n    const children = groups.map(getChildren)\n\n    const currentGroupIndex = groups\n      .map(g => g.type === 'list' ? g.contentRef.value?.$el as HTMLElement : g.contentRef.value)\n      .findIndex(el => el?.contains(target))\n\n    const nextIndex = nextFocusGroup(children, currentGroupIndex, direction, target)\n\n    if (nextIndex === null) {\n      const originGroup = groups[currentGroupIndex]\n      const origin = children[currentGroupIndex]\n      const isListGroup = originGroup.type === 'list'\n\n      const atEdge = isListGroup || (\n        direction === 'forward'\n          ? origin.at(-1) === e.target\n          : origin.at(0) === e.target\n      )\n\n      if (atEdge) {\n        onLeave()\n      }\n    } else {\n      e.preventDefault()\n      e.stopImmediatePropagation()\n\n      const nextGroup = groups[nextIndex]\n      if (nextGroup.type === 'list' && toValue(nextGroup.displayItemsCount) > 0) {\n        nextGroup.contentRef.value?.focus(0)\n      } else {\n        const fromBefore = direction === 'forward'\n        children[nextIndex].at(fromBefore ? 0 : -1)!.focus()\n      }\n    }\n  }\n\n  function nextFocusGroup (\n    children: HTMLElement[][],\n    currentIndex: number,\n    direction: 'forward' | 'backward',\n    target: Element\n  ): number | null {\n    const originGroup = groups[currentIndex]\n    const origin = children[currentIndex]\n\n    // List groups always allow leaving (VList manages internal focus)\n    // Element groups require being at the edge focusable child\n    if (originGroup.type !== 'list') {\n      const isAtEdge = direction === 'forward'\n        ? origin.at(-1) === target\n        : origin.at(0) === target\n\n      if (!isAtEdge) return null\n    }\n\n    const step = direction === 'forward' ? 1 : -1\n    for (let i = currentIndex + step; i >= 0 && i < groups.length; i += step) {\n      const group = groups[i]\n      if (children[i].length > 0 || (group.type === 'list' && toValue(group.displayItemsCount) > 0)) {\n        return i\n      }\n    }\n\n    return null\n  }\n\n  return { onTabKeydown }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/focusTrap.ts",
    "content": "// Utilities\nimport { nextTick, onScopeDispose, toRef, toValue, watch } from 'vue'\nimport { focusableChildren, IN_BROWSER, propsFactory } from '@/util'\n\n// Types\nimport type { Ref } from 'vue'\n\n// Types\nexport interface FocusTrapProps {\n  retainFocus: boolean\n  captureFocus: boolean\n  disableInitialFocus?: boolean\n}\n\n// Composables\nexport const makeFocusTrapProps = propsFactory({\n  retainFocus: Boolean,\n  captureFocus: Boolean,\n  /** @deprecated */\n  disableInitialFocus: Boolean,\n}, 'focusTrap')\n\nconst registry = new Map<symbol, {\n  isActive: Ref<boolean>\n  contentEl: Ref<HTMLElement | undefined>\n}>()\nlet subscribers = 0\n\nfunction onKeydown (e: KeyboardEvent) {\n  const activeElement = document.activeElement as HTMLElement | null\n  if (e.key !== 'Tab' || !activeElement) return\n\n  const parentTraps = Array.from(registry.values())\n    .filter(({ isActive, contentEl }) => isActive.value && contentEl.value?.contains(activeElement))\n    .map(x => x.contentEl.value)\n\n  let closestTrap\n  let currentParent = activeElement.parentElement\n  while (currentParent) {\n    if (parentTraps.includes(currentParent)) {\n      closestTrap = currentParent\n      break\n    }\n    currentParent = currentParent.parentElement\n  }\n\n  if (!closestTrap) return\n\n  const focusable = focusableChildren(closestTrap)\n    // excluding VListItems with tabindex=\"-2\"\n    .filter(x => x.tabIndex >= 0)\n\n  if (!focusable.length) return\n\n  const active = document.activeElement as HTMLElement | null\n  if (\n    focusable.length === 1 &&\n    focusable[0].classList.contains('v-list') &&\n    focusable[0].contains(active)\n  ) {\n    e.preventDefault()\n    return\n  }\n\n  const firstElement = focusable[0]\n  const lastElement = focusable[focusable.length - 1]\n\n  if (\n    e.shiftKey &&\n    (\n      active === firstElement ||\n      (firstElement.classList.contains('v-list') && firstElement.contains(active))\n    )\n  ) {\n    e.preventDefault()\n    lastElement.focus()\n  }\n\n  if (\n    !e.shiftKey &&\n    (\n      active === lastElement ||\n      (lastElement.classList.contains('v-list') && lastElement.contains(active))\n    )\n  ) {\n    e.preventDefault()\n    firstElement.focus()\n  }\n}\n\nexport function useFocusTrap (\n  props: FocusTrapProps,\n  { isActive, localTop, activatorEl, contentEl }: {\n    isActive: Ref<boolean>\n    localTop: Readonly<Ref<boolean>>\n    activatorEl?: Readonly<Ref<HTMLElement | undefined>>\n    contentEl: Readonly<Ref<HTMLElement | undefined>>\n  }\n) {\n  const trapId = Symbol('trap')\n\n  let focusTrapSuppressed = false\n  let focusTrapSuppressionTimeout = -1\n\n  async function onPointerdown () {\n    focusTrapSuppressed = true\n    focusTrapSuppressionTimeout = window.setTimeout(() => {\n      focusTrapSuppressed = false\n    }, 100)\n  }\n\n  async function captureOnFocus (e: FocusEvent) {\n    const before = e.relatedTarget as HTMLElement | null\n    const after = e.target as HTMLElement | null\n\n    document.removeEventListener('pointerdown', onPointerdown)\n    document.removeEventListener('keydown', captureOnKeydown)\n\n    await nextTick()\n\n    if (\n      isActive.value &&\n      !focusTrapSuppressed &&\n      before !== after &&\n      contentEl.value &&\n      // We're the menu without open submenus or overlays\n      toValue(localTop) &&\n      // It isn't the document or the container body\n      ![document, contentEl.value].includes(after!) &&\n      // It isn't inside the container body\n      !contentEl.value.contains(after)\n    ) {\n      const focusable = focusableChildren(contentEl.value)\n      focusable[0]?.focus()\n    }\n  }\n\n  function captureOnKeydown (e: KeyboardEvent) {\n    if (e.key !== 'Tab') return\n    document.removeEventListener('keydown', captureOnKeydown)\n\n    if (\n      isActive.value &&\n      contentEl.value &&\n      e.target &&\n      !contentEl.value.contains(e.target as Element)\n    ) {\n      const allFocusableElements = focusableChildren(document.documentElement)\n\n      if (\n        (e.shiftKey && e.target === allFocusableElements.at(0)) ||\n        (!e.shiftKey && e.target === allFocusableElements.at(-1))\n      ) {\n        const focusable = focusableChildren(contentEl.value)\n        if (focusable.length > 0) {\n          e.preventDefault()\n          focusable[0].focus()\n        }\n      }\n    }\n  }\n\n  const shouldCapture = toRef(() => isActive.value && props.captureFocus && !props.disableInitialFocus)\n\n  if (IN_BROWSER) {\n    watch(() => props.retainFocus, val => {\n      if (val) {\n        registry.set(trapId, { isActive, contentEl })\n      } else {\n        registry.delete(trapId)\n      }\n    }, { immediate: true })\n\n    watch(shouldCapture, val => {\n      if (val) {\n        document.addEventListener('pointerdown', onPointerdown)\n        document.addEventListener('focusin', captureOnFocus, { once: true })\n        document.addEventListener('keydown', captureOnKeydown)\n      } else {\n        document.removeEventListener('pointerdown', onPointerdown)\n        document.removeEventListener('focusin', captureOnFocus)\n        document.removeEventListener('keydown', captureOnKeydown)\n      }\n    }, { immediate: true })\n\n    if (subscribers++ < 1) {\n      document.addEventListener('keydown', onKeydown)\n    }\n  }\n\n  onScopeDispose(() => {\n    registry.delete(trapId)\n    clearTimeout(focusTrapSuppressionTimeout)\n    document.removeEventListener('pointerdown', onPointerdown)\n    document.removeEventListener('focusin', captureOnFocus)\n    document.removeEventListener('keydown', captureOnKeydown)\n\n    if (--subscribers < 1) {\n      document.removeEventListener('keydown', onKeydown)\n    }\n  })\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/form.ts",
    "content": "// Composables\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { computed, inject, markRaw, provide, ref, shallowRef, toRef, watch } from 'vue'\nimport { consoleWarn, propsFactory } from '@/util'\n\n// Types\nimport type { ComponentInternalInstance, InjectionKey, PropType, Raw, Ref } from 'vue'\nimport type { ValidationProps } from './validation'\nimport type { EventProp } from '@/util'\n\nexport interface FormProvide {\n  register: (item: {\n    id: number | string\n    vm: ComponentInternalInstance\n    validate: () => Promise<string[]>\n    reset: () => Promise<void>\n    resetValidation: () => Promise<void>\n  }) => void\n  unregister: (id: number | string) => void\n  update: (id: number | string, isValid: boolean | null, errorMessages: string[]) => void\n  items: Ref<FormField[]>\n  isDisabled: Readonly<Ref<boolean>>\n  isReadonly: Readonly<Ref<boolean>>\n  isValidating: Ref<boolean>\n  isValid: Ref<boolean | null>\n  validateOn: Ref<FormProps['validateOn']>\n}\n\nexport interface FormField {\n  id: number | string\n  validate: () => Promise<string[]>\n  reset: () => Promise<void>\n  resetValidation: () => Promise<void>\n  vm: Raw<ComponentInternalInstance>\n  isValid: boolean | null\n  errorMessages: string[]\n}\n\nexport interface FieldValidationResult {\n  id: number | string\n  errorMessages: string[]\n}\n\nexport interface FormValidationResult {\n  valid: boolean\n  errors: FieldValidationResult[]\n}\n\nexport interface SubmitEventPromise extends SubmitEvent, Promise<FormValidationResult> {}\n\nexport const FormKey: InjectionKey<FormProvide> = Symbol.for('vuetify:form')\n\nexport interface FormProps {\n  disabled: boolean\n  fastFail: boolean\n  readonly: boolean\n  modelValue: boolean | null\n  'onUpdate:modelValue': EventProp<[boolean | null]> | undefined\n  validateOn: ValidationProps['validateOn']\n}\n\nexport const makeFormProps = propsFactory({\n  disabled: Boolean,\n  fastFail: Boolean,\n  readonly: Boolean,\n  modelValue: {\n    type: Boolean as PropType<boolean | null>,\n    default: null,\n  },\n  validateOn: {\n    type: String as PropType<FormProps['validateOn']>,\n    default: 'input',\n  },\n}, 'form')\n\nexport function createForm (props: FormProps) {\n  const model = useProxiedModel(props, 'modelValue')\n\n  const isDisabled = toRef(() => props.disabled)\n  const isReadonly = toRef(() => props.readonly)\n  const isValidating = shallowRef(false)\n  const items = ref<FormField[]>([])\n  const errors = ref<FieldValidationResult[]>([])\n\n  async function validate () {\n    const results = []\n    let valid = true\n\n    errors.value = []\n    isValidating.value = true\n\n    for (const item of items.value) {\n      const itemErrorMessages = await item.validate()\n\n      if (itemErrorMessages.length > 0) {\n        valid = false\n\n        results.push({\n          id: item.id,\n          errorMessages: itemErrorMessages,\n        })\n      }\n\n      if (!valid && props.fastFail) break\n    }\n\n    errors.value = results\n    isValidating.value = false\n\n    return { valid, errors: errors.value }\n  }\n\n  function reset () {\n    items.value.forEach(item => item.reset())\n  }\n\n  function resetValidation () {\n    items.value.forEach(item => item.resetValidation())\n  }\n\n  watch(items, () => {\n    let valid = 0\n    let invalid = 0\n    const results = []\n\n    for (const item of items.value) {\n      if (item.isValid === false) {\n        invalid++\n        results.push({\n          id: item.id,\n          errorMessages: item.errorMessages,\n        })\n      } else if (item.isValid === true) valid++\n    }\n\n    errors.value = results\n    model.value =\n      invalid > 0 ? false\n      : valid === items.value.length ? true\n      : null\n  }, { deep: true, flush: 'post' })\n\n  provide(FormKey, {\n    register: ({ id, vm, validate, reset, resetValidation }) => {\n      if (items.value.some(item => item.id === id)) {\n        consoleWarn(`Duplicate input name \"${id}\"`)\n      }\n\n      items.value.push({\n        id,\n        validate,\n        reset,\n        resetValidation,\n        vm: markRaw(vm),\n        isValid: null,\n        errorMessages: [],\n      })\n    },\n    unregister: id => {\n      items.value = items.value.filter(item => {\n        return item.id !== id\n      })\n    },\n    update: (id, isValid, errorMessages) => {\n      const found = items.value.find(item => item.id === id)\n\n      if (!found) return\n\n      found.isValid = isValid\n      found.errorMessages = errorMessages\n    },\n    isDisabled,\n    isReadonly,\n    isValidating,\n    isValid: model,\n    items,\n    validateOn: toRef(() => props.validateOn),\n  })\n\n  return {\n    errors,\n    isDisabled,\n    isReadonly,\n    isValidating,\n    isValid: model,\n    items,\n    validate,\n    reset,\n    resetValidation,\n  }\n}\n\nexport function useForm (props?: { readonly: boolean | null, disabled: boolean | null }) {\n  const form = inject(FormKey, null)\n  return {\n    ...form,\n    isReadonly: computed(() => !!(props?.readonly ?? form?.isReadonly.value)),\n    isDisabled: computed(() => !!(props?.disabled ?? form?.isDisabled.value)),\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/forwardRefs.ts",
    "content": "// Types\nimport type { ComponentOptionsBase, ComponentPublicInstance, Ref, UnwrapRef } from 'vue'\nimport type { NonEmptyArray, UnionToIntersection } from '@/util'\n\nconst Refs = Symbol('Forwarded refs')\n\n/** Omit properties starting with P */\ntype OmitPrefix<\n  T,\n  P extends string,\n  E = Extract<keyof T, `${P}${any}`>,\n> = [E] extends [never] ? T : Omit<T, `${P}${any}`>\ntype OmitPrivate<T> = OmitPrefix<T, '$'>\n\n/** Omit keyof $props from T */\ntype OmitProps<T> = T extends { $props: any } ? Omit<T, keyof T['$props']> : T\n\nfunction getDescriptor (obj: any, key: PropertyKey) {\n  let currentObj = obj\n  while (currentObj) {\n    const descriptor = Reflect.getOwnPropertyDescriptor(currentObj, key)\n    if (descriptor) return descriptor\n    currentObj = Object.getPrototypeOf(currentObj)\n  }\n  return undefined\n}\n\nexport function forwardRefs<\n  T extends {},\n  U extends NonEmptyArray<Ref<HTMLElement | Omit<ComponentPublicInstance, '$emit' | '$slots'> | undefined>>,\n  UU = { [K in keyof U]: NonNullable<UnwrapRef<U[K]>> }[number],\n  UC = { [K in keyof U]: OmitPrivate<OmitProps<NonNullable<UnwrapRef<U[K]>>>> }[number],\n  R = T & UnionToIntersection<UC> & {\n    _allExposed: T | (\n      UU extends { $options: infer O }\n        ? O extends ComponentOptionsBase<any, infer E, any, any, any, any, any, any>\n          ? E\n          : never\n        : never\n    )\n  }\n> (target: T, ...refs: U): R {\n  (target as any)[Refs] = refs\n\n  return new Proxy(target, {\n    get (target, key) {\n      if (Reflect.has(target, key)) {\n        return Reflect.get(target, key)\n      }\n\n      // Skip internal properties\n      if (typeof key === 'symbol' || key.startsWith('$') || key.startsWith('__')) return\n\n      for (const ref of refs) {\n        if (ref.value && Reflect.has(ref.value, key)) {\n          const val = Reflect.get(ref.value, key)\n          return typeof val === 'function'\n            ? val.bind(ref.value)\n            : val\n        }\n      }\n    },\n    has (target, key) {\n      if (Reflect.has(target, key)) {\n        return true\n      }\n\n      // Skip internal properties\n      if (typeof key === 'symbol' || key.startsWith('$') || key.startsWith('__')) return false\n\n      for (const ref of refs) {\n        if (ref.value && Reflect.has(ref.value, key)) {\n          return true\n        }\n      }\n      return false\n    },\n    set (target, key, value) {\n      if (Reflect.has(target, key)) {\n        return Reflect.set(target, key, value)\n      }\n\n      // Skip internal properties\n      if (typeof key === 'symbol' || key.startsWith('$') || key.startsWith('__')) return false\n\n      for (const ref of refs) {\n        if (ref.value && Reflect.has(ref.value, key)) {\n          return Reflect.set(ref.value, key, value)\n        }\n      }\n\n      return false\n    },\n    getOwnPropertyDescriptor (target, key) {\n      const descriptor = Reflect.getOwnPropertyDescriptor(target, key)\n      if (descriptor) return descriptor\n\n      // Skip internal properties\n      if (typeof key === 'symbol' || key.startsWith('$') || key.startsWith('__')) return\n\n      // Check each ref's own properties\n      for (const ref of refs) {\n        if (!ref.value) continue\n        const descriptor = getDescriptor(ref.value, key) ?? ('_' in ref.value ? getDescriptor(ref.value._?.setupState, key) : undefined)\n        if (descriptor) return descriptor\n      }\n\n      // Recursive search up each ref's prototype\n      for (const ref of refs) {\n        const childRefs = ref.value && (ref.value as any)[Refs]\n        if (!childRefs) continue\n        const queue = childRefs.slice()\n        while (queue.length) {\n          const ref = queue.shift()\n          const descriptor = getDescriptor(ref.value, key)\n          if (descriptor) return descriptor\n          const childRefs = ref.value && (ref.value as any)[Refs]\n          if (childRefs) queue.push(...childRefs)\n        }\n      }\n\n      return undefined\n    },\n  }) as any\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/goto.ts",
    "content": "// Utilities\nimport { inject, toRef } from 'vue'\nimport { useRtl } from './locale'\nimport { clamp, consoleWarn, easingPatterns, mergeDeep, PREFERS_REDUCED_MOTION, refElement } from '@/util'\n\n// Types\nimport type { ComponentPublicInstance, InjectionKey, Ref } from 'vue'\nimport type { LocaleInstance, RtlInstance } from './locale'\nimport type { EasingFunction } from '@/util'\n\nexport interface GoToInstance {\n  rtl: Ref<boolean>\n  options: InternalGoToOptions\n}\n\nexport interface InternalGoToOptions {\n  container: ComponentPublicInstance | HTMLElement | string\n  duration: number\n  layout: boolean\n  offset: number\n  easing: string | EasingFunction\n  patterns: Record<string, EasingFunction>\n}\n\nexport type GoToOptions = Partial<InternalGoToOptions>\n\nexport const GoToSymbol: InjectionKey<GoToInstance> = Symbol.for('vuetify:goto')\n\nfunction genDefaults () {\n  return {\n    container: undefined,\n    duration: 300,\n    layout: false,\n    offset: 0,\n    easing: 'easeInOutCubic' satisfies keyof typeof easingPatterns,\n    patterns: easingPatterns,\n  }\n}\n\nfunction getContainer (el?: ComponentPublicInstance | HTMLElement | string) {\n  return getTarget(el) ?? (document.scrollingElement || document.body) as HTMLElement\n}\n\nfunction getTarget (el: ComponentPublicInstance | HTMLElement | string | undefined) {\n  return (typeof el === 'string') ? document.querySelector<HTMLElement>(el) : refElement(el)\n}\n\nfunction getOffset (target: any, horizontal?: boolean, rtl?: boolean): number {\n  if (typeof target === 'number') return horizontal && rtl ? -target : target\n\n  let el = getTarget(target)\n  let totalOffset = 0\n  while (el) {\n    totalOffset += horizontal ? el.offsetLeft : el.offsetTop\n    el = el.offsetParent as HTMLElement\n  }\n\n  return totalOffset\n}\n\nexport function createGoTo (\n  options: GoToOptions| undefined,\n  locale: LocaleInstance & RtlInstance\n): GoToInstance {\n  return {\n    rtl: locale.isRtl,\n    options: mergeDeep(genDefaults(), options) as InternalGoToOptions,\n  }\n}\n\nexport async function scrollTo (\n  _target: ComponentPublicInstance | HTMLElement | number | string,\n  _options: GoToOptions,\n  horizontal?: boolean,\n  goTo?: GoToInstance,\n) {\n  const property = horizontal ? 'scrollLeft' : 'scrollTop'\n  const options = mergeDeep(goTo?.options ?? genDefaults(), _options)\n  const rtl = goTo?.rtl.value\n  const target = (typeof _target === 'number' ? _target : getTarget(_target)) ?? 0\n  const container = options.container === 'parent' && target instanceof HTMLElement\n    ? target.parentElement!\n    : getContainer(options.container)\n  const ease = PREFERS_REDUCED_MOTION() ? options.patterns.instant\n    : typeof options.easing === 'function' ? options.easing\n    : options.patterns[options.easing]\n\n  if (!ease) throw new TypeError(`Easing function \"${options.easing}\" not found.`)\n\n  let targetLocation: number\n  if (typeof target === 'number') {\n    targetLocation = getOffset(target, horizontal, rtl)\n  } else {\n    targetLocation = getOffset(target, horizontal, rtl) - getOffset(container, horizontal, rtl)\n\n    if (options.layout) {\n      const styles = window.getComputedStyle(target)\n      const layoutOffset = styles.getPropertyValue('--v-layout-top')\n\n      if (layoutOffset) targetLocation -= parseInt(layoutOffset, 10)\n    }\n  }\n\n  targetLocation += options.offset\n  targetLocation = clampTarget(container, targetLocation, !!rtl, !!horizontal)\n\n  const startLocation = container[property] ?? 0\n\n  if (targetLocation === startLocation) return Promise.resolve(targetLocation)\n\n  const startTime = performance.now()\n\n  return new Promise(resolve => requestAnimationFrame(function step (currentTime: number) {\n    const timeElapsed = currentTime - startTime\n    const progress = timeElapsed / options.duration\n    const location = Math.floor(\n      startLocation +\n      (targetLocation - startLocation) *\n      ease(clamp(progress, 0, 1))\n    )\n\n    container[property] = location\n\n    // Allow for some jitter if target time has elapsed\n    if (progress >= 1 && Math.abs(location - container[property]) < 10) {\n      return resolve(targetLocation)\n    } else if (progress > 2) {\n      // The target might not be reachable\n      consoleWarn('Scroll target is not reachable')\n      return resolve(container[property])\n    }\n\n    requestAnimationFrame(step)\n  }))\n}\n\nexport function useGoTo (_options: GoToOptions = {}) {\n  const goToInstance = inject(GoToSymbol)\n  const { isRtl } = useRtl()\n\n  if (!goToInstance) throw new Error('[Vuetify] Could not find injected goto instance')\n\n  const goTo = {\n    ...goToInstance,\n    // can be set via VLocaleProvider\n    rtl: toRef(() => goToInstance.rtl.value || isRtl.value),\n  }\n\n  async function go (\n    target: ComponentPublicInstance | HTMLElement | string | number,\n    options?: Partial<GoToOptions>,\n  ) {\n    return scrollTo(target, mergeDeep(_options, options), false, goTo)\n  }\n\n  go.horizontal = async (\n    target: ComponentPublicInstance | HTMLElement | string | number,\n    options?: Partial<GoToOptions>,\n  ) => {\n    return scrollTo(target, mergeDeep(_options, options), true, goTo)\n  }\n\n  return go\n}\n\n/**\n * Clamp target value to achieve a smooth scroll animation\n * when the value goes outside the scroll container size\n */\nfunction clampTarget (\n  container: HTMLElement,\n  value: number,\n  rtl: boolean,\n  horizontal: boolean,\n) {\n  const { scrollWidth, scrollHeight } = container\n  const [containerWidth, containerHeight] = container === document.scrollingElement\n    ? [window.innerWidth, window.innerHeight]\n    : [container.offsetWidth, container.offsetHeight]\n\n  let min: number\n  let max: number\n\n  if (horizontal) {\n    if (rtl) {\n      min = -(scrollWidth - containerWidth)\n      max = 0\n    } else {\n      min = 0\n      max = scrollWidth - containerWidth\n    }\n  } else {\n    min = 0\n    max = scrollHeight + -containerHeight\n  }\n\n  return clamp(value, min, max)\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/group.ts",
    "content": "// Composables\nimport { useProxiedModel } from './proxiedModel'\n\n// Utilities\nimport { computed, inject, onBeforeUnmount, onMounted, onUpdated, provide, reactive, toRef, unref, useId, watch } from 'vue'\nimport { consoleWarn, deepEqual, findChildrenWithProvide, getCurrentInstance, propsFactory, wrapInArray } from '@/util'\n\n// Types\nimport type { ComponentInternalInstance, ExtractPropTypes, InjectionKey, PropType, Ref, UnwrapRef } from 'vue'\nimport type { EventProp } from '@/util'\n\nexport interface GroupItem {\n  id: string\n  value: Ref<unknown>\n  disabled: Ref<boolean | undefined>\n  useIndexAsValue?: boolean\n}\n\nexport interface GroupProps {\n  disabled: boolean\n  modelValue: unknown\n  multiple?: boolean\n  mandatory?: boolean | 'force' | undefined\n  max?: number | undefined\n  selectedClass: string | undefined\n  'onUpdate:modelValue': EventProp<[unknown]> | undefined\n}\n\nexport interface GroupProvide {\n  register: (item: GroupItem, cmp: ComponentInternalInstance) => void\n  unregister: (id: string) => void\n  select: (id: string, value: boolean) => void\n  selected: Ref<Readonly<string[]>>\n  isSelected: (id: string) => boolean\n  prev: () => void\n  next: () => void\n  selectedClass: Ref<string | undefined>\n  items: Readonly<Ref<{\n    id: string\n    value: unknown\n    disabled: boolean | undefined\n  }[]>>\n  disabled: Ref<boolean | undefined>\n  getItemIndex: (value: unknown) => number\n}\n\nexport interface GroupItemProvide {\n  id: string\n  isSelected: Ref<boolean>\n  isFirst: Ref<boolean>\n  isLast: Ref<boolean>\n  toggle: () => void\n  select: (value: boolean) => void\n  selectedClass: Ref<(string | undefined)[] | false>\n  value: Ref<unknown>\n  disabled: Ref<boolean | undefined>\n  group: GroupProvide\n  register: () => void\n  unregister: () => void\n}\n\nexport const makeGroupProps = propsFactory({\n  modelValue: {\n    type: null,\n    default: undefined,\n  },\n  multiple: Boolean,\n  mandatory: [Boolean, String] as PropType<boolean | 'force'>,\n  max: Number,\n  selectedClass: String,\n  disabled: Boolean,\n}, 'group')\n\nexport const makeGroupItemProps = propsFactory({\n  value: null,\n  disabled: Boolean,\n  selectedClass: String,\n}, 'group-item')\n\nexport interface GroupItemProps extends ExtractPropTypes<ReturnType<typeof makeGroupItemProps>> {\n  'onGroup:selected': EventProp<[{ value: boolean }]> | undefined\n}\n\n// Composables\nexport function useGroupItem (\n  props: GroupItemProps,\n  injectKey: InjectionKey<GroupProvide>,\n  required?: true,\n): GroupItemProvide\nexport function useGroupItem (\n  props: GroupItemProps,\n  injectKey: InjectionKey<GroupProvide>,\n  required: false,\n): GroupItemProvide | null\nexport function useGroupItem (\n  props: GroupItemProps,\n  injectKey: InjectionKey<GroupProvide>,\n  required = true,\n): GroupItemProvide | null {\n  const vm = getCurrentInstance('useGroupItem')\n\n  if (!vm) {\n    throw new Error(\n      '[Vuetify] useGroupItem composable must be used inside a component setup function'\n    )\n  }\n\n  const id = useId()\n\n  provide(Symbol.for(`${injectKey.description}:id`), id)\n\n  const group = inject(injectKey, null)\n\n  if (!group) {\n    if (!required) return group\n\n    throw new Error(`[Vuetify] Could not find useGroup injection with symbol ${injectKey.description}`)\n  }\n\n  const value = toRef(() => props.value)\n  const disabled = computed(() => !!(group.disabled.value || props.disabled))\n\n  function register () {\n    group?.register({ id, value, disabled }, vm)\n  }\n\n  function unregister () {\n    group?.unregister(id)\n  }\n\n  register()\n  onBeforeUnmount(() => unregister())\n\n  const isSelected = computed(() => {\n    return group.isSelected(id)\n  })\n  const isFirst = computed(() => {\n    return group.items.value[0].id === id\n  })\n  const isLast = computed(() => {\n    return group.items.value[group.items.value.length - 1].id === id\n  })\n\n  const selectedClass = computed(() => isSelected.value && [group.selectedClass.value, props.selectedClass])\n\n  watch(isSelected, value => {\n    vm.emit('group:selected', { value })\n  }, { flush: 'sync' })\n\n  return {\n    id,\n    isSelected,\n    isFirst,\n    isLast,\n    toggle: () => group.select(id, !isSelected.value),\n    select: (value: boolean) => group.select(id, value),\n    selectedClass,\n    value,\n    disabled,\n    group,\n    register,\n    unregister,\n  }\n}\n\nexport function useGroup (\n  props: GroupProps,\n  injectKey: InjectionKey<GroupProvide>\n) {\n  let isUnmounted = false\n  const items = reactive<GroupItem[]>([])\n  const selected = useProxiedModel(\n    props,\n    'modelValue',\n    [],\n    v => {\n      if (v === undefined) return []\n\n      return getIds(items, v === null ? [null] : wrapInArray(v))\n    },\n    v => {\n      const arr = getValues(items, v)\n\n      return props.multiple ? arr : arr[0]\n    }\n  )\n\n  const groupVm = getCurrentInstance('useGroup')\n\n  function register (item: GroupItem, vm: ComponentInternalInstance) {\n    // Is there a better way to fix this typing?\n    const unwrapped = item as unknown as UnwrapRef<GroupItem>\n\n    const key = Symbol.for(`${injectKey.description}:id`)\n    const children = findChildrenWithProvide(key, groupVm?.vnode)\n    const index = children.indexOf(vm)\n\n    if (unref(unwrapped.value) === undefined) {\n      unwrapped.value = index\n      unwrapped.useIndexAsValue = true\n    }\n\n    if (index > -1) {\n      items.splice(index, 0, unwrapped)\n    } else {\n      items.push(unwrapped)\n    }\n  }\n\n  function unregister (id: string) {\n    if (isUnmounted) return\n\n    // TODO: re-evaluate this line's importance in the future\n    // should we only modify the model if mandatory is set.\n    // selected.value = selected.value.filter(v => v !== id)\n\n    forceMandatoryValue()\n\n    const index = items.findIndex(item => item.id === id)\n    items.splice(index, 1)\n  }\n\n  // If mandatory and nothing is selected, then select first non-disabled item\n  function forceMandatoryValue () {\n    const item = items.find(item => !item.disabled)\n    if (item && props.mandatory === 'force' && !selected.value.length) {\n      selected.value = [item.id]\n    }\n  }\n\n  onMounted(() => {\n    forceMandatoryValue()\n  })\n\n  onBeforeUnmount(() => {\n    isUnmounted = true\n  })\n\n  onUpdated(() => {\n    // #19655 update the items that use the index as the value.\n    for (let i = 0; i < items.length; i++) {\n      if (items[i].useIndexAsValue) {\n        items[i].value = i\n      }\n    }\n  })\n\n  function select (id: string, value?: boolean) {\n    const item = items.find(item => item.id === id)\n    if (value && item?.disabled) return\n\n    if (props.multiple) {\n      const internalValue = selected.value.slice()\n      const index = internalValue.findIndex(v => v === id)\n      const isSelected = ~index\n      value = value ?? !isSelected\n\n      // We can't remove value if group is\n      // mandatory, value already exists,\n      // and it is the only value\n      if (\n        isSelected &&\n        props.mandatory &&\n        internalValue.length <= 1\n      ) return\n\n      // We can't add value if it would\n      // cause max limit to be exceeded\n      if (\n        !isSelected &&\n        props.max != null &&\n        internalValue.length + 1 > props.max\n      ) return\n\n      if (index < 0 && value) internalValue.push(id)\n      else if (index >= 0 && !value) internalValue.splice(index, 1)\n\n      selected.value = internalValue\n    } else {\n      const isSelected = selected.value.includes(id)\n      if (props.mandatory && isSelected) return\n      if (!isSelected && !value) return\n\n      selected.value = (value ?? !isSelected) ? [id] : []\n    }\n  }\n\n  function step (offset: number) {\n    // getting an offset from selected value obviously won't work with multiple values\n    if (props.multiple) consoleWarn('This method is not supported when using \"multiple\" prop')\n\n    if (!selected.value.length) {\n      const item = items.find(item => !item.disabled)\n      item && (selected.value = [item.id])\n    } else {\n      const currentId = selected.value[0]\n      const currentIndex = items.findIndex(i => i.id === currentId)\n\n      let newIndex = (currentIndex + offset) % items.length\n      let newItem = items[newIndex]\n\n      while (newItem.disabled && newIndex !== currentIndex) {\n        newIndex = (newIndex + offset) % items.length\n        newItem = items[newIndex]\n      }\n\n      if (newItem.disabled) return\n\n      selected.value = [items[newIndex].id]\n    }\n  }\n\n  const state: GroupProvide = {\n    register,\n    unregister,\n    selected,\n    select,\n    disabled: toRef(() => props.disabled),\n    prev: () => step(items.length - 1),\n    next: () => step(1),\n    isSelected: (id: string) => selected.value.includes(id),\n    selectedClass: toRef(() => props.selectedClass),\n    items: toRef(() => items),\n    getItemIndex: (value: unknown) => getItemIndex(items, value),\n  }\n\n  provide(injectKey, state)\n\n  return state\n}\n\nfunction getItemIndex (items: UnwrapRef<GroupItem[]>, value: unknown) {\n  const ids = getIds(items, [value])\n\n  if (!ids.length) return -1\n\n  return items.findIndex(item => item.id === ids[0])\n}\n\nfunction getIds (items: UnwrapRef<GroupItem[]>, modelValue: any[]) {\n  const ids: string[] = []\n\n  modelValue.forEach(value => {\n    const item = items.find(item => deepEqual(value, item.value))\n    const itemByIndex = items[value]\n\n    if (item?.value !== undefined) {\n      ids.push(item.id)\n    } else if (itemByIndex?.useIndexAsValue) {\n      ids.push(itemByIndex.id)\n    }\n  })\n\n  return ids\n}\n\nfunction getValues (items: UnwrapRef<GroupItem[]>, ids: any[]) {\n  const values: unknown[] = []\n\n  ids.forEach(id => {\n    const itemIndex = items.findIndex(item => item.id === id)\n    if (~itemIndex) {\n      const item = items[itemIndex]\n      values.push(item.value !== undefined ? item.value : itemIndex)\n    }\n  })\n\n  return values\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/hotkey/__tests__/hotkey-parsing.spec.ts",
    "content": "// Utilities\nimport { parseKeyCombination } from '../hotkey-parsing'\n\ndescribe('hotkey-parsing', () => {\n  describe('combinations', () => {\n    // Basic combinations\n    it('should split simple combinations with +', () => {\n      const result = parseKeyCombination('ctrl+k')\n      expect(result).toEqual({\n        type: 'combo',\n        parts: ['ctrl', 'k'],\n      })\n    })\n\n    it('should split simple combinations with _', () => {\n      const result = parseKeyCombination('shift_tab')\n      expect(result).toEqual({\n        type: 'combo',\n        parts: ['shift', 'tab'],\n      })\n    })\n\n    it('should split simple combinations with /', () => {\n      const result = parseKeyCombination('up/down')\n      expect(result).toEqual({\n        type: 'alternate',\n        parts: ['arrowup', 'arrowdown'],\n      })\n    })\n\n    // Multiple modifiers and keys\n    it('should handle multiple modifiers', () => {\n      const result = parseKeyCombination('ctrl+shift+k')\n      expect(result).toEqual({\n        type: 'combo',\n        parts: ['ctrl', 'shift', 'k'],\n      })\n    })\n\n    it('should handle multiple primary keys', () => {\n      const result = parseKeyCombination('k+j')\n      expect(result).toEqual({\n        type: 'combo',\n        parts: ['k', 'j'],\n      })\n    })\n\n    it('should handle mixed separators', () => {\n      const result = parseKeyCombination('alt_shift+t')\n      expect(result).toEqual({\n        type: 'combo',\n        parts: ['alt', 'shift', 't'],\n      })\n    })\n\n    // Literal keys\n    it('should handle single literal keys', () => {\n      expect(parseKeyCombination('-')).toBe('-')\n      expect(parseKeyCombination('+')).toBe('+')\n      expect(parseKeyCombination('/')).toBe('/')\n      expect(parseKeyCombination('_')).toBe('_')\n      expect(parseKeyCombination(' ')).toBe(' ')\n    })\n\n    // Combinations with doubled literals\n    it('should handle doubled literal +', () => {\n      expect(parseKeyCombination('ctrl++')).toEqual({\n        type: 'combo',\n        parts: ['ctrl', '+'],\n      })\n    })\n\n    it('should handle doubled literal _', () => {\n      expect(parseKeyCombination('ctrl__')).toEqual({\n        type: 'combo',\n        parts: ['ctrl', '_'],\n      })\n    })\n\n    it('should handle doubled literal /', () => {\n      expect(parseKeyCombination('ctrl//')).toEqual({\n        type: 'alternate',\n        parts: ['ctrl', '/'],\n      })\n    })\n\n    it('should handle doubled literal -', () => {\n      const result = parseKeyCombination('shift--')\n      expect(result).toEqual({\n        type: 'sequence',\n        parts: ['shift', '-'],\n      })\n    })\n\n    it('should handle combination with literal minus', () => {\n      const result = parseKeyCombination('ctrl+-')\n      expect(result).toEqual({\n        type: 'combo',\n        parts: ['ctrl', '-'],\n      })\n    })\n\n    it('should handle combination with literal space', () => {\n      const result = parseKeyCombination('ctrl+ ')\n      expect(result).toEqual({\n        type: 'combo',\n        parts: ['ctrl', ' '],\n      })\n    })\n\n    // Invalid combinations\n    it('should return empty string for empty string', () => {\n      expect(parseKeyCombination('')).toBe('')\n      expect('Unexpected end of input').toHaveBeenTipped()\n    })\n\n    it('should return empty string for leading separators', () => {\n      expect(parseKeyCombination('+a')).toBe('')\n      expect('Unexpected separator \\'+\\' at position 0').toHaveBeenTipped()\n\n      expect(parseKeyCombination('/a')).toBe('')\n      expect('Unexpected separator \\'/\\' at position 0').toHaveBeenTipped()\n\n      expect(parseKeyCombination('_a')).toBe('')\n      expect('Unexpected separator \\'_\\' at position 0').toHaveBeenTipped()\n    })\n\n    it('should return empty string for trailing separators', () => {\n      expect(parseKeyCombination('a+')).toBe('')\n      expect('Unexpected end of input').toHaveBeenTipped()\n\n      expect(parseKeyCombination('a/')).toBe('')\n      expect('Unexpected end of input').toHaveBeenTipped()\n\n      expect(parseKeyCombination('a_')).toBe('')\n      expect('Unexpected end of input').toHaveBeenTipped()\n    })\n\n    it('should return empty string for extraneous spaces', () => {\n      expect(parseKeyCombination('shift + ')).toBe('')\n      expect('Unexpected character \\' \\' at position 5').toHaveBeenTipped()\n    })\n\n    it('should return empty string for standalone doubled separators', () => {\n      expect(parseKeyCombination('++')).toBe('')\n      expect('Unexpected end of input').toHaveBeenTipped()\n\n      expect(parseKeyCombination('//')).toBe('')\n      expect('Unexpected end of input').toHaveBeenTipped()\n\n      expect(parseKeyCombination('--')).toBe('')\n      expect('Unexpected end of input').toHaveBeenTipped()\n\n      expect(parseKeyCombination('__')).toBe('')\n      expect('Unexpected end of input').toHaveBeenTipped()\n    })\n\n    // Combinations starting with doubled literal separators\n    it('should parse combinations starting with doubled + literal', () => {\n      expect(parseKeyCombination('++k')).toEqual({\n        type: 'combo',\n        parts: ['+', 'k'],\n      })\n    })\n\n    // Key aliases from centralized key-aliases.ts\n    it('should handle all key aliases consistently', () => {\n      // Modifier aliases\n      expect(parseKeyCombination('control')).toBe('ctrl')\n      expect(parseKeyCombination('command')).toBe('cmd')\n      expect(parseKeyCombination('option')).toBe('alt')\n\n      // Arrow key aliases\n      expect(parseKeyCombination('up')).toBe('arrowup')\n      expect(parseKeyCombination('down')).toBe('arrowdown')\n      expect(parseKeyCombination('left')).toBe('arrowleft')\n      expect(parseKeyCombination('right')).toBe('arrowright')\n\n      // Common key aliases\n      expect(parseKeyCombination('esc')).toBe('escape')\n      expect(parseKeyCombination('return')).toBe('enter')\n      expect(parseKeyCombination('del')).toBe('delete')\n      expect(parseKeyCombination('space')).toBe(' ')\n      expect(parseKeyCombination('spacebar')).toBe(' ')\n\n      // Symbol aliases\n      expect(parseKeyCombination('plus')).toBe('+')\n      expect(parseKeyCombination('slash')).toBe('/')\n      expect(parseKeyCombination('underscore')).toBe('_')\n      expect(parseKeyCombination('minus')).toBe('-')\n      expect(parseKeyCombination('hyphen')).toBe('-')\n    })\n\n    it('should handle key aliases in complex combinations', () => {\n      const result1 = parseKeyCombination('control+option+up')\n      expect(typeof result1 === 'object' && result1.type === 'combo' && result1.parts).toEqual(['ctrl', 'alt', 'arrowup'])\n\n      const result2 = parseKeyCombination('command+shift+esc')\n      expect(typeof result2 === 'object' && result2.type === 'combo' && result2.parts).toEqual(['cmd', 'shift', 'escape'])\n\n      const result3 = parseKeyCombination('control+return')\n      expect(typeof result3 === 'object' && result3.type === 'combo' && result3.parts).toEqual(['ctrl', 'enter'])\n\n      const result4 = parseKeyCombination('alt+del')\n      expect(typeof result4 === 'object' && result4.type === 'combo' && result4.parts).toEqual(['alt', 'delete'])\n\n      const result5 = parseKeyCombination('shift+plus')\n      expect(typeof result5 === 'object' && result5.type === 'combo' && result5.parts).toEqual(['shift', '+'])\n\n      const result6 = parseKeyCombination('shift+slash')\n      expect(typeof result6 === 'object' && result6.type === 'combo' && result6.parts).toEqual(['shift', '/'])\n\n      const result7 = parseKeyCombination('shift+underscore')\n      expect(typeof result7 === 'object' && result7.type === 'combo' && result7.parts).toEqual(['shift', '_'])\n\n      const result8 = parseKeyCombination('shift+minus')\n      expect(typeof result8 === 'object' && result8.type === 'combo' && result8.parts).toEqual(['shift', '-'])\n    })\n\n    it('should handle case insensitive key aliases', () => {\n      const result1 = parseKeyCombination('CONTROL+K')\n      expect(typeof result1 === 'object' && result1.type === 'combo' && result1.parts).toEqual(['ctrl', 'k'])\n\n      const result2 = parseKeyCombination('Command+S')\n      expect(typeof result2 === 'object' && result2.type === 'combo' && result2.parts).toEqual(['cmd', 's'])\n\n      const result3 = parseKeyCombination('OPTION+TAB')\n      expect(typeof result3 === 'object' && result3.type === 'combo' && result3.parts).toEqual(['alt', 'tab'])\n\n      expect(parseKeyCombination('UP')).toBe('arrowup')\n      expect(parseKeyCombination('ESC')).toBe('escape')\n      expect(parseKeyCombination('PLUS')).toBe('+')\n      expect(parseKeyCombination('SLASH')).toBe('/')\n      expect(parseKeyCombination('UNDERSCORE')).toBe('_')\n      expect(parseKeyCombination('MINUS')).toBe('-')\n    })\n\n    it('should handle mixed case aliases in combinations', () => {\n      const result1 = parseKeyCombination('Control+Option+Up')\n      expect(typeof result1 === 'object' && result1.type === 'combo' && result1.parts).toEqual(['ctrl', 'alt', 'arrowup'])\n\n      const result2 = parseKeyCombination('COMMAND+shift+ESC')\n      expect(typeof result2 === 'object' && result2.type === 'combo' && result2.parts).toEqual(['cmd', 'shift', 'escape'])\n    })\n\n    it('should handle meta key correctly for cross-platform use', () => {\n      const result1 = parseKeyCombination('meta+s')\n      expect(typeof result1 === 'object' && result1.type === 'combo' && result1.parts).toEqual(['meta', 's'])\n\n      const result2 = parseKeyCombination('meta+shift+z')\n      expect(typeof result2 === 'object' && result2.type === 'combo' && result2.parts).toEqual(['meta', 'shift', 'z'])\n\n      const result3 = parseKeyCombination('meta+alt+p')\n      expect(typeof result3 === 'object' && result3.type === 'combo' && result3.parts).toEqual(['meta', 'alt', 'p'])\n    })\n  })\n\n  describe('sequences', () => {\n    // Basic sequences\n    it('should split simple sequences', () => {\n      const result1 = parseKeyCombination('a-b')\n      expect(result1).toEqual({\n        type: 'sequence',\n        parts: ['a', 'b'],\n      })\n\n      const result2 = parseKeyCombination('g-g')\n      expect(result2).toEqual({\n        type: 'sequence',\n        parts: ['g', 'g'],\n      })\n    })\n\n    it('should handle ctrl-b as a valid sequence', () => {\n      const result = parseKeyCombination('ctrl-b')\n      expect(result).toEqual({\n        type: 'sequence',\n        parts: ['ctrl', 'b'],\n      })\n    })\n\n    it('should handle long sequences', () => {\n      const result = parseKeyCombination('a-b-c-d')\n      expect(result).toEqual({\n        type: 'sequence',\n        parts: ['a', 'b', 'c', 'd'],\n      })\n    })\n\n    // Sequences with combinations\n    it('should split sequences with combinations', () => {\n      const result = parseKeyCombination('ctrl+k-p')\n      expect(result).toEqual({\n        type: 'sequence',\n        parts: [\n          {\n            type: 'combo',\n            parts: ['ctrl', 'k'],\n          },\n          'p',\n        ],\n      })\n    })\n\n    // Single combinations (no sequence)\n    it('should handle single combinations', () => {\n      const result = parseKeyCombination('ctrl+k')\n      expect(result).toEqual({\n        type: 'combo',\n        parts: ['ctrl', 'k'],\n      })\n    })\n\n    // Edge cases and literals\n    it('should handle literal minus in a sequence', () => {\n      const result = parseKeyCombination('ctrl+a-shift+-')\n      expect(result).toEqual({\n        type: 'sequence',\n        parts: [\n          {\n            type: 'combo',\n            parts: ['ctrl', 'a'],\n          },\n          {\n            type: 'combo',\n            parts: ['shift', '-'],\n          },\n        ],\n      })\n    })\n\n    it('should handle standalone literal minus in a sequence', () => {\n      expect(parseKeyCombination('-')).toBe('-')\n    })\n\n    it('should correctly parse meta+--k', () => {\n      const result = parseKeyCombination('meta+--k')\n      expect(result).toEqual({\n        type: 'sequence',\n        parts: [\n          {\n            type: 'combo',\n            parts: ['meta', '-'],\n          },\n          'k',\n        ],\n      })\n    })\n\n    it('should correctly parse --+', () => {\n      expect(parseKeyCombination('--+')).toEqual({\n        type: 'sequence',\n        parts: ['-', '+'],\n      })\n    })\n\n    it('should correctly parse ---', () => {\n      const result = parseKeyCombination('---')\n      expect(result).toEqual({\n        type: 'sequence',\n        parts: ['-', '-'],\n      })\n    })\n\n    it('should handle shift---alt++', () => {\n      const result = parseKeyCombination('shift---alt++')\n      expect(result).toEqual({\n        type: 'sequence',\n        parts: [\n          'shift',\n          '-',\n          {\n            type: 'combo',\n            parts: ['alt', '+'],\n          },\n        ],\n      })\n    })\n\n    it('should handle alt+++b+h', () => {\n      const result = parseKeyCombination('alt+++b+h')\n      expect(result).toEqual({\n        type: 'combo',\n        parts: ['alt', '+', 'b', 'h'],\n      })\n    })\n\n    // Invalid sequences\n    it('should return empty string for empty string', () => {\n      expect(parseKeyCombination('')).toBe('')\n      expect('Unexpected end of input').toHaveBeenTipped()\n    })\n\n    it('should return empty string for leading sequence separator', () => {\n      expect(parseKeyCombination('-a')).toBe('')\n      expect('Unexpected separator \\'-\\' at position 0').toHaveBeenTipped()\n    })\n\n    it('should return empty string for trailing sequence separator', () => {\n      expect(parseKeyCombination('a-')).toBe('')\n      expect('Unexpected end of input').toHaveBeenTipped()\n    })\n\n    it('should return empty string for invalid parts', () => {\n      expect(parseKeyCombination('a-ctrl+-b')).toBe('')\n      expect(`Unexpected separator '-' at position 7`).toHaveBeenTipped()\n    })\n\n    // Sequences with combinations that start with doubled literal\n    it('should handle cmd+shift-++k', () => {\n      const result = parseKeyCombination('cmd+shift-++k')\n      expect(result).toEqual({\n        type: 'sequence',\n        parts: [\n          {\n            type: 'combo',\n            parts: ['cmd', 'shift'],\n          },\n          {\n            type: 'combo',\n            parts: ['+', 'k'],\n          },\n        ],\n      })\n    })\n\n    it('should handle cmd+shift++-k', () => {\n      const result = parseKeyCombination('cmd+shift++-k')\n      expect(result).toEqual({\n        type: 'sequence',\n        parts: [\n          {\n            type: 'combo',\n            parts: ['cmd', 'shift', '+'],\n          },\n          'k',\n        ],\n      })\n    })\n  })\n\n  it('should correctly parse a complex sequence', () => {\n    const sequence = 'ctrl+shift+a-alt+--k'\n    const result = parseKeyCombination(sequence)\n    expect(result).toEqual({\n      type: 'sequence',\n      parts: [\n        {\n          type: 'combo',\n          parts: ['ctrl', 'shift', 'a'],\n        },\n        {\n          type: 'combo',\n          parts: ['alt', '-'],\n        },\n        'k',\n      ],\n    })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/hotkey/__tests__/hotkey.spec.ts",
    "content": "// Composables\nimport { useHotkey } from '../hotkey'\n\n// Utilities\nimport { wait } from '@test'\nimport { nextTick, ref } from 'vue'\n\ndescribe('hotkey.ts', () => {\n  const originalNavigator = window.navigator\n  afterEach(() => {\n    Object.defineProperty(window, 'navigator', { value: originalNavigator, writable: true })\n  })\n\n  it.each([\n    ['ctrl+a', { ctrlKey: true, key: 'a' }],\n    ['ctrl_a', { ctrlKey: true, key: 'a' }],\n    ['ctrl+shift+b', { ctrlKey: true, shiftKey: true, key: 'b' }],\n    ['ctrl_shift_b', { ctrlKey: true, shiftKey: true, key: 'b' }],\n    ['alt+f4', { altKey: true, key: 'f4' }],\n    ['shift+tab', { shiftKey: true, key: 'tab' }],\n    ['ctrl+alt+delete', { ctrlKey: true, altKey: true, key: 'delete' }],\n    ['escape', { key: 'escape' }],\n    ['f1', { key: 'f1' }],\n    ['enter', { key: 'enter' }],\n    ['space', { key: ' ' }],\n    ['plus', { key: '+' }],\n    ['slash', { key: '/' }],\n    ['underscore', { key: '_' }],\n    ['shift+plus', { shiftKey: true, key: '+' }],\n    ['shift+slash', { shiftKey: true, key: '/' }],\n    ['shift+underscore', { shiftKey: true, key: '_' }],\n    ['ctrl+plus', { ctrlKey: true, key: '+' }],\n    ['alt+-', { altKey: true, key: '-' }],\n  ])('fires on %s', (combo, props) => {\n    const cb = vi.fn()\n    const stop = useHotkey(combo, cb)\n\n    window.dispatchEvent(new KeyboardEvent('keydown', { ...{ ctrlKey: false, shiftKey: false, altKey: false, metaKey: false }, ...props }))\n\n    expect(cb).toHaveBeenCalledTimes(1)\n\n    stop()\n  })\n\n  describe.each([\n    ['complete', 0, ['g', 'g'], 1],\n    ['incomplete', 0, ['g'], 0],\n    ['timeout', 1100, ['g', 'g'], 0],\n  ])('%s g‑g sequence', (_, gap, seq, expected) => {\n    it('callback count matches', async () => {\n      vi.useFakeTimers()\n      const cb = vi.fn()\n      const stop = useHotkey('g-g', cb)\n\n      window.dispatchEvent(new KeyboardEvent('keydown', { key: seq[0] }))\n      vi.advanceTimersByTime(gap)\n      // eslint-disable-next-line vitest/no-conditional-in-test\n      if (seq[1]) window.dispatchEvent(new KeyboardEvent('keydown', { key: seq[1] }))\n      expect(cb).toHaveBeenCalledTimes(expected)\n\n      stop()\n\n      vi.useRealTimers()\n    })\n  })\n\n  it.each([\n    ['extra modifiers', 'ctrl+a', { ctrlKey: true, shiftKey: true, key: 'a' }],\n    ['modifiers only', 'ctrl+shift+b', { ctrlKey: true, shiftKey: true, key: 'Control' }],\n  ])('%s ignored', (_, combo, evtProps) => {\n    const cb = vi.fn()\n    const stop = useHotkey(combo, cb)\n\n    window.dispatchEvent(new KeyboardEvent('keydown', evtProps))\n\n    expect(cb).not.toHaveBeenCalled()\n\n    stop()\n  })\n\n  describe.each([\n    [false, 'input', () => document.createElement('input')],\n    [false, 'contentEditable', () => Object.assign(document.createElement('div'), { contentEditable: 'true', tabIndex: 0 })],\n    [true, 'input allowed', () => document.createElement('input')],\n  ])('inputs=%s (%s)', (flag, _label, factory) => {\n    it('honours inputs flag', () => {\n      const cb = vi.fn()\n      const stop = useHotkey('ctrl+a', cb, { inputs: flag })\n      const el = factory(); document.body.appendChild(el); el.focus()\n\n      window.dispatchEvent(new KeyboardEvent('keydown', { ctrlKey: true, key: 'a' }))\n\n      expect(cb).toHaveBeenCalledTimes(flag ? 1 : 0)\n\n      stop(); document.body.removeChild(el)\n    })\n  })\n\n  it.each([[true, true], [false, false]])('preventDefault=%s', (setting, shouldCall) => {\n    const cb = vi.fn()\n    const stop = useHotkey('ctrl+a', cb, { preventDefault: setting })\n    const evt = new KeyboardEvent('keydown', { ctrlKey: true, key: 'a' })\n    const spy = vi.spyOn(evt, 'preventDefault')\n\n    window.dispatchEvent(evt)\n\n    expect(cb).toHaveBeenCalledTimes(1)\n\n    expect(spy).toHaveBeenCalledTimes(shouldCall ? 1 : 0)\n\n    stop()\n  })\n\n  it.each([\n    ['Mac ctrl', 'ctrl+s', { ctrlKey: true, key: 's' }, 'Macintosh'],\n    ['Mac cmd', 'cmd+s', { metaKey: true, key: 's' }, 'Macintosh'],\n  ])('%s platform handling', (_, combo, evtProps, ua) => {\n    const cb = vi.fn()\n    Object.defineProperty(window, 'navigator', { value: { userAgent: `Mozilla/5.0 (${ua})` }, writable: true })\n    const stop = useHotkey(combo, cb)\n\n    window.dispatchEvent(new KeyboardEvent('keydown', evtProps))\n\n    expect(cb).toHaveBeenCalledTimes(1)\n\n    stop()\n  })\n\n  it('reactive ref & disabled', async () => {\n    const cb = vi.fn()\n    const keyRef = ref<string>('ctrl+a')\n    const stop = useHotkey(keyRef, cb)\n\n    window.dispatchEvent(new KeyboardEvent('keydown', { ctrlKey: true, key: 'a' }))\n    expect(cb).toHaveBeenCalledTimes(1)\n\n    keyRef.value = 'ctrl+b'\n    await wait(10)\n    window.dispatchEvent(new KeyboardEvent('keydown', { ctrlKey: true, key: 'a' }))\n    expect(cb).toHaveBeenCalledTimes(1)\n\n    window.dispatchEvent(new KeyboardEvent('keydown', { ctrlKey: true, key: 'b' }))\n    expect(cb).toHaveBeenCalledTimes(2)\n\n    keyRef.value = undefined as any\n    await wait(10)\n    window.dispatchEvent(new KeyboardEvent('keydown', { ctrlKey: true, key: 'b' }))\n    expect(cb).toHaveBeenCalledTimes(2)\n\n    stop()\n  })\n\n  it('case insensitive matching', () => {\n    const cb = vi.fn()\n    const stop = useHotkey('CTRL+A', cb)\n\n    window.dispatchEvent(new KeyboardEvent('keydown', { ctrlKey: true, key: 'A' }))\n\n    expect(cb).toHaveBeenCalledTimes(1)\n\n    stop()\n  })\n\n  it('long sequence ctrl+k-p-s', () => {\n    const cb = vi.fn()\n    const stop = useHotkey('ctrl+k-p-s', cb)\n\n    window.dispatchEvent(new KeyboardEvent('keydown', { ctrlKey: true, key: 'k' }))\n    window.dispatchEvent(new KeyboardEvent('keydown', { key: 'p' }))\n    window.dispatchEvent(new KeyboardEvent('keydown', { key: 's' }))\n\n    expect(cb).toHaveBeenCalledTimes(1)\n\n    stop()\n  })\n\n  it('multiple g-g completions', () => {\n    const cb = vi.fn()\n    const stop = useHotkey('g-g', cb)\n    for (let i = 0; i < 2; i++) {\n      window.dispatchEvent(new KeyboardEvent('keydown', { key: 'g' }))\n      window.dispatchEvent(new KeyboardEvent('keydown', { key: 'g' }))\n    }\n\n    expect(cb).toHaveBeenCalledTimes(2)\n\n    stop()\n  })\n\n  it('handles undefined navigator gracefully', () => {\n    const orig = window.navigator\n    Object.defineProperty(window, 'navigator', { value: undefined, writable: true })\n    try {\n      const cb = vi.fn()\n      const stop = useHotkey('ctrl+s', cb)\n\n      window.dispatchEvent(new KeyboardEvent('keydown', { ctrlKey: true, key: 's' }))\n\n      expect(cb).toHaveBeenCalledTimes(1)\n\n      stop()\n    } finally {\n      Object.defineProperty(window, 'navigator', { value: orig, writable: true })\n    }\n  })\n\n  it('handles sequence with literal symbols', () => {\n    const cb = vi.fn()\n    const stop = useHotkey('ctrl+a-shift+-', cb)\n\n    // First part of sequence\n    window.dispatchEvent(new KeyboardEvent('keydown', { ctrlKey: true, key: 'a' }))\n    expect(cb).toHaveBeenCalledTimes(0) // Should not trigger yet\n\n    // Second part of sequence\n    window.dispatchEvent(new KeyboardEvent('keydown', { shiftKey: true, key: '-' }))\n    expect(cb).toHaveBeenCalledTimes(1) // Should trigger after complete sequence\n\n    stop()\n  })\n\n  it('handles sequence timeout correctly', () => {\n    vi.useFakeTimers()\n    const cb = vi.fn()\n    const stop = useHotkey('a-b', cb, { sequenceTimeout: 500 })\n\n    // Start sequence\n    window.dispatchEvent(new KeyboardEvent('keydown', { key: 'a' }))\n    expect(cb).toHaveBeenCalledTimes(0)\n\n    // Wait past timeout\n    vi.advanceTimersByTime(600)\n\n    // Try to complete sequence - should not work\n    window.dispatchEvent(new KeyboardEvent('keydown', { key: 'b' }))\n    expect(cb).toHaveBeenCalledTimes(0)\n\n    // Start fresh sequence\n    window.dispatchEvent(new KeyboardEvent('keydown', { key: 'a' }))\n    window.dispatchEvent(new KeyboardEvent('keydown', { key: 'b' }))\n    expect(cb).toHaveBeenCalledTimes(1)\n\n    stop()\n    vi.useRealTimers()\n  })\n\n  it('handles custom event type', () => {\n    const cb = vi.fn()\n    const stop = useHotkey('ctrl+a', cb, { event: 'keyup' })\n\n    // Should not trigger on keydown\n    window.dispatchEvent(new KeyboardEvent('keydown', { ctrlKey: true, key: 'a' }))\n    expect(cb).toHaveBeenCalledTimes(0)\n\n    // Should trigger on keyup\n    window.dispatchEvent(new KeyboardEvent('keyup', { ctrlKey: true, key: 'a' }))\n    expect(cb).toHaveBeenCalledTimes(1)\n\n    stop()\n  })\n\n  it('cleans up event listeners on stop', () => {\n    const cb = vi.fn()\n    const stop = useHotkey('ctrl+a', cb)\n\n    // Should work initially\n    window.dispatchEvent(new KeyboardEvent('keydown', { ctrlKey: true, key: 'a' }))\n    expect(cb).toHaveBeenCalledTimes(1)\n\n    // Stop the hotkey\n    stop()\n\n    // Should not work after stop\n    window.dispatchEvent(new KeyboardEvent('keydown', { ctrlKey: true, key: 'a' }))\n    expect(cb).toHaveBeenCalledTimes(1)\n  })\n\n  it('resets sequence on non-matching key', () => {\n    const cb = vi.fn()\n    const stop = useHotkey('a-b-c', cb)\n\n    // Start sequence\n    window.dispatchEvent(new KeyboardEvent('keydown', { key: 'a' }))\n    window.dispatchEvent(new KeyboardEvent('keydown', { key: 'b' }))\n    expect(cb).toHaveBeenCalledTimes(0)\n\n    // Press wrong key - should reset sequence\n    window.dispatchEvent(new KeyboardEvent('keydown', { key: 'x' }))\n    expect(cb).toHaveBeenCalledTimes(0)\n\n    // Now complete sequence from beginning\n    window.dispatchEvent(new KeyboardEvent('keydown', { key: 'a' }))\n    window.dispatchEvent(new KeyboardEvent('keydown', { key: 'b' }))\n    window.dispatchEvent(new KeyboardEvent('keydown', { key: 'c' }))\n    expect(cb).toHaveBeenCalledTimes(1)\n\n    stop()\n  })\n\n  it('handles centralized key aliases', () => {\n    const cb = vi.fn()\n    const stop = useHotkey('control+k', cb)\n\n    window.dispatchEvent(new KeyboardEvent('keydown', { ctrlKey: true, key: 'k' }))\n\n    expect(cb).toHaveBeenCalledTimes(1)\n\n    stop()\n  })\n\n  it('handles arrow key aliases', () => {\n    const cb = vi.fn()\n    const stop = useHotkey('up', cb)\n\n    window.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowUp' }))\n\n    expect(cb).toHaveBeenCalledTimes(1)\n\n    stop()\n  })\n\n  describe('Cross-platform meta key behavior (Nuxt UI style)', () => {\n    const originalNavigator = window.navigator\n\n    afterEach(() => {\n      Object.defineProperty(window, 'navigator', { value: originalNavigator, writable: true })\n    })\n\n    it('should handle meta+s as cmd+s on Mac (metaKey)', () => {\n      Object.defineProperty(window, 'navigator', { value: { userAgent: 'Mozilla/5.0 (Macintosh)' }, writable: true })\n      const cb = vi.fn()\n      const stop = useHotkey('meta+s', cb)\n\n      // On Mac, meta+s should trigger with metaKey (Command key)\n      window.dispatchEvent(new KeyboardEvent('keydown', { metaKey: true, key: 's' }))\n      expect(cb).toHaveBeenCalledTimes(1)\n\n      // Should NOT trigger with ctrlKey on Mac\n      window.dispatchEvent(new KeyboardEvent('keydown', { ctrlKey: true, key: 's' }))\n      expect(cb).toHaveBeenCalledTimes(1) // Still 1, not 2\n\n      stop()\n    })\n\n    it('should handle meta+s as ctrl+s on PC (ctrlKey)', () => {\n      Object.defineProperty(window, 'navigator', { value: { userAgent: 'Windows NT 10.0' }, writable: true })\n      const cb = vi.fn()\n      const stop = useHotkey('meta+s', cb)\n\n      // On PC, meta+s should trigger with ctrlKey\n      window.dispatchEvent(new KeyboardEvent('keydown', { ctrlKey: true, key: 's' }))\n      expect(cb).toHaveBeenCalledTimes(1)\n\n      // Should NOT trigger with metaKey on PC\n      window.dispatchEvent(new KeyboardEvent('keydown', { metaKey: true, key: 's' }))\n      expect(cb).toHaveBeenCalledTimes(1) // Still 1, not 2\n\n      stop()\n    })\n\n    it('should handle cmd+s consistently across platforms', () => {\n      // Test on Mac\n      Object.defineProperty(window, 'navigator', { value: { userAgent: 'Mozilla/5.0 (Macintosh)' }, writable: true })\n      const cbMac = vi.fn()\n      const stopMac = useHotkey('cmd+s', cbMac)\n\n      window.dispatchEvent(new KeyboardEvent('keydown', { metaKey: true, key: 's' }))\n      expect(cbMac).toHaveBeenCalledTimes(1)\n      stopMac()\n\n      // Test on PC\n      Object.defineProperty(window, 'navigator', { value: { userAgent: 'Windows NT 10.0' }, writable: true })\n      const cbPc = vi.fn()\n      const stopPc = useHotkey('cmd+s', cbPc)\n\n      window.dispatchEvent(new KeyboardEvent('keydown', { ctrlKey: true, key: 's' }))\n      expect(cbPc).toHaveBeenCalledTimes(1)\n      stopPc()\n    })\n\n    it('should handle explicit ctrl+s as ctrl on all platforms', () => {\n      // Test on Mac - ctrl should always be ctrl, never cmd\n      Object.defineProperty(window, 'navigator', { value: { userAgent: 'Mozilla/5.0 (Macintosh)' }, writable: true })\n      const cbMac = vi.fn()\n      const stopMac = useHotkey('ctrl+s', cbMac)\n\n      // Should trigger with ctrlKey even on Mac\n      window.dispatchEvent(new KeyboardEvent('keydown', { ctrlKey: true, key: 's' }))\n      expect(cbMac).toHaveBeenCalledTimes(1)\n\n      // Should NOT trigger with metaKey on Mac when using explicit ctrl\n      window.dispatchEvent(new KeyboardEvent('keydown', { metaKey: true, key: 's' }))\n      expect(cbMac).toHaveBeenCalledTimes(1) // Still 1, not 2\n      stopMac()\n\n      // Test on PC\n      Object.defineProperty(window, 'navigator', { value: { userAgent: 'Windows NT 10.0' }, writable: true })\n      const cbPc = vi.fn()\n      const stopPc = useHotkey('ctrl+s', cbPc)\n\n      window.dispatchEvent(new KeyboardEvent('keydown', { ctrlKey: true, key: 's' }))\n      expect(cbPc).toHaveBeenCalledTimes(1)\n      stopPc()\n    })\n\n    it('should handle complex combinations with meta key', () => {\n      // Test meta+shift+z on Mac\n      Object.defineProperty(window, 'navigator', { value: { userAgent: 'Mozilla/5.0 (Macintosh)' }, writable: true })\n      const cbMac = vi.fn()\n      const stopMac = useHotkey('meta+shift+z', cbMac)\n\n      window.dispatchEvent(new KeyboardEvent('keydown', { metaKey: true, shiftKey: true, key: 'z' }))\n      expect(cbMac).toHaveBeenCalledTimes(1)\n      stopMac()\n\n      // Test meta+shift+z on PC\n      Object.defineProperty(window, 'navigator', { value: { userAgent: 'Windows NT 10.0' }, writable: true })\n      const cbPc = vi.fn()\n      const stopPc = useHotkey('meta+shift+z', cbPc)\n\n      window.dispatchEvent(new KeyboardEvent('keydown', { ctrlKey: true, shiftKey: true, key: 'z' }))\n      expect(cbPc).toHaveBeenCalledTimes(1)\n      stopPc()\n    })\n  })\n\n  describe('Key aliases cross-platform behavior', () => {\n    const originalNavigator = window.navigator\n\n    afterEach(() => {\n      Object.defineProperty(window, 'navigator', { value: originalNavigator, writable: true })\n    })\n\n    it('should handle command alias on Mac', () => {\n      Object.defineProperty(window, 'navigator', { value: { userAgent: 'Mozilla/5.0 (Macintosh)' }, writable: true })\n      const cb = vi.fn()\n      const stop = useHotkey('command+k', cb)\n\n      window.dispatchEvent(new KeyboardEvent('keydown', { metaKey: true, key: 'k' }))\n      expect(cb).toHaveBeenCalledTimes(1)\n\n      stop()\n    })\n\n    it('should handle command alias on PC', () => {\n      Object.defineProperty(window, 'navigator', { value: { userAgent: 'Windows NT 10.0' }, writable: true })\n      const cb = vi.fn()\n      const stop = useHotkey('command+k', cb)\n\n      window.dispatchEvent(new KeyboardEvent('keydown', { ctrlKey: true, key: 'k' }))\n      expect(cb).toHaveBeenCalledTimes(1)\n\n      stop()\n    })\n\n    it('should handle option alias on Mac', () => {\n      Object.defineProperty(window, 'navigator', { value: { userAgent: 'Mozilla/5.0 (Macintosh)' }, writable: true })\n      const cb = vi.fn()\n      const stop = useHotkey('option+tab', cb)\n\n      window.dispatchEvent(new KeyboardEvent('keydown', { altKey: true, key: 'tab' }))\n      expect(cb).toHaveBeenCalledTimes(1)\n\n      stop()\n    })\n\n    it('should handle control alias consistently', () => {\n      // Test on Mac\n      Object.defineProperty(window, 'navigator', { value: { userAgent: 'Mozilla/5.0 (Macintosh)' }, writable: true })\n      const cbMac = vi.fn()\n      const stopMac = useHotkey('control+r', cbMac)\n\n      window.dispatchEvent(new KeyboardEvent('keydown', { ctrlKey: true, key: 'r' }))\n      expect(cbMac).toHaveBeenCalledTimes(1)\n      stopMac()\n\n      // Test on PC\n      Object.defineProperty(window, 'navigator', { value: { userAgent: 'Windows NT 10.0' }, writable: true })\n      const cbPc = vi.fn()\n      const stopPc = useHotkey('control+r', cbPc)\n\n      window.dispatchEvent(new KeyboardEvent('keydown', { ctrlKey: true, key: 'r' }))\n      expect(cbPc).toHaveBeenCalledTimes(1)\n      stopPc()\n    })\n\n    it('should handle arrow key aliases', () => {\n      const testCases = [\n        ['up', 'ArrowUp'],\n        ['down', 'ArrowDown'],\n        ['left', 'ArrowLeft'],\n        ['right', 'ArrowRight'],\n      ]\n\n      testCases.forEach(([alias, key]) => {\n        const cb = vi.fn()\n        const stop = useHotkey(alias, cb)\n\n        window.dispatchEvent(new KeyboardEvent('keydown', { key }))\n        expect(cb).toHaveBeenCalledTimes(1)\n\n        stop()\n      })\n    })\n\n    it('should handle common key aliases', () => {\n      const testCases = [\n        ['esc', 'Escape'],\n        ['return', 'Enter'],\n        ['del', 'Delete'],\n      ]\n\n      testCases.forEach(([alias, key]) => {\n        const cb = vi.fn()\n        const stop = useHotkey(alias, cb)\n\n        window.dispatchEvent(new KeyboardEvent('keydown', { key }))\n        expect(cb).toHaveBeenCalledTimes(1)\n\n        stop()\n      })\n    })\n\n    it('should handle symbol aliases', () => {\n      const testCases = [\n        ['minus', '-'],\n        ['hyphen', '-'],\n      ]\n\n      testCases.forEach(([alias, key]) => {\n        const cb = vi.fn()\n        const stop = useHotkey(alias, cb)\n\n        window.dispatchEvent(new KeyboardEvent('keydown', { key }))\n        expect(cb).toHaveBeenCalledTimes(1)\n\n        stop()\n      })\n    })\n\n    it('should handle mixed aliases and modifiers', () => {\n      const cb = vi.fn()\n      const stop = useHotkey('control+up', cb)\n\n      window.dispatchEvent(new KeyboardEvent('keydown', { ctrlKey: true, key: 'ArrowUp' }))\n      expect(cb).toHaveBeenCalledTimes(1)\n\n      stop()\n    })\n\n    it('should handle case insensitive aliases', () => {\n      const cb = vi.fn()\n      const stop = useHotkey('CONTROL+ESC', cb)\n\n      window.dispatchEvent(new KeyboardEvent('keydown', { ctrlKey: true, key: 'Escape' }))\n      expect(cb).toHaveBeenCalledTimes(1)\n\n      stop()\n    })\n\n    it('should handle undefined navigator with aliases', () => {\n      Object.defineProperty(window, 'navigator', { value: undefined, writable: true })\n      const cb = vi.fn()\n      const stop = useHotkey('command+s', cb)\n\n      // Should default to PC behavior (ctrlKey) when navigator is undefined\n      window.dispatchEvent(new KeyboardEvent('keydown', { ctrlKey: true, key: 's' }))\n      expect(cb).toHaveBeenCalledTimes(1)\n\n      stop()\n    })\n  })\n\n  describe('Platform detection edge cases', () => {\n    const originalNavigator = window.navigator\n\n    afterEach(() => {\n      Object.defineProperty(window, 'navigator', { value: originalNavigator, writable: true })\n    })\n\n    it('should handle null navigator', () => {\n      Object.defineProperty(window, 'navigator', { value: null, writable: true })\n      const cb = vi.fn()\n      const stop = useHotkey('meta+s', cb)\n\n      // Should default to PC behavior when navigator is null\n      window.dispatchEvent(new KeyboardEvent('keydown', { ctrlKey: true, key: 's' }))\n      expect(cb).toHaveBeenCalledTimes(1)\n\n      stop()\n    })\n\n    it('should handle navigator without userAgent', () => {\n      Object.defineProperty(window, 'navigator', { value: {}, writable: true })\n      const cb = vi.fn()\n      const stop = useHotkey('meta+s', cb)\n\n      // Should default to PC behavior when userAgent is missing\n      window.dispatchEvent(new KeyboardEvent('keydown', { ctrlKey: true, key: 's' }))\n      expect(cb).toHaveBeenCalledTimes(1)\n\n      stop()\n    })\n\n    it('should handle different Mac user agent strings', () => {\n      const macUserAgents = [\n        'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)',\n        'Mozilla/5.0 (Macintosh; Apple Silicon Mac OS X 12_0_0)',\n        'Mozilla/5.0 (Macintosh)',\n      ]\n\n      macUserAgents.forEach(userAgent => {\n        Object.defineProperty(window, 'navigator', { value: { userAgent }, writable: true })\n        const cb = vi.fn()\n        const stop = useHotkey('meta+s', cb)\n\n        window.dispatchEvent(new KeyboardEvent('keydown', { metaKey: true, key: 's' }))\n        expect(cb).toHaveBeenCalledTimes(1)\n\n        stop()\n      })\n    })\n\n    it('should handle non-Mac user agent strings', () => {\n      const nonMacUserAgents = [\n        'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',\n        'Mozilla/5.0 (X11; Linux x86_64)',\n        'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1)',\n        '',\n      ]\n\n      nonMacUserAgents.forEach(userAgent => {\n        Object.defineProperty(window, 'navigator', { value: { userAgent }, writable: true })\n        const cb = vi.fn()\n        const stop = useHotkey('meta+s', cb)\n\n        window.dispatchEvent(new KeyboardEvent('keydown', { ctrlKey: true, key: 's' }))\n        expect(cb).toHaveBeenCalledTimes(1)\n\n        stop()\n      })\n    })\n  })\n\n  it('reactive options', async () => {\n    const preventDefault = ref(false)\n    const inputs = ref(false)\n    const cb = vi.fn()\n\n    const stop = useHotkey('ctrl+a', cb, { preventDefault, inputs })\n\n    // Test with initial values\n    const event1 = new KeyboardEvent('keydown', { ctrlKey: true, key: 'a' })\n    Object.defineProperty(event1, 'preventDefault', { value: vi.fn() })\n\n    window.dispatchEvent(event1)\n    expect(cb).toHaveBeenCalledTimes(1)\n    expect(event1.preventDefault).not.toHaveBeenCalled()\n\n    // Change preventDefault to true\n    preventDefault.value = true\n    await nextTick()\n\n    const event2 = new KeyboardEvent('keydown', { ctrlKey: true, key: 'a' })\n    Object.defineProperty(event2, 'preventDefault', { value: vi.fn() })\n\n    window.dispatchEvent(event2)\n    expect(cb).toHaveBeenCalledTimes(2)\n    expect(event2.preventDefault).toHaveBeenCalled()\n\n    // Test inputs reactivity\n    const input = document.createElement('input')\n    document.body.appendChild(input)\n    input.focus()\n\n    const event3 = new KeyboardEvent('keydown', { ctrlKey: true, key: 'a' })\n    window.dispatchEvent(event3)\n    expect(cb).toHaveBeenCalledTimes(2) // Should not fire because inputs=false\n\n    // Enable inputs\n    inputs.value = true\n    await nextTick()\n\n    const event4 = new KeyboardEvent('keydown', { ctrlKey: true, key: 'a' })\n    window.dispatchEvent(event4)\n    expect(cb).toHaveBeenCalledTimes(3) // Should fire because inputs=true\n\n    document.body.removeChild(input)\n    stop()\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/hotkey/hotkey-parsing.ts",
    "content": "// Utilities\nimport { normalizeKey } from './key-aliases'\nimport { consoleWarn, includes } from '@/util'\n\n// Types\nexport type KeyCombination = Sequence | Alternate | Combo | Key\n\nexport interface Sequence {\n  type: 'sequence'\n  parts: (Alternate | Combo | Key)[]\n}\n\nexport interface Alternate {\n  type: 'alternate'\n  parts: (Combo | Key)[]\n}\n\nexport interface Combo {\n  type: 'combo'\n  parts: Key[]\n}\n\nexport type Key = string\n\nclass ParseError extends Error {}\n\n/**\n * Splits a single combination string into individual key parts.\n * Grammar:\n *\n * sequence   = alternate *('-' alternate)\n * alternate  = combo *('/' combo)\n * combo      = key *(('+' | '_') key)\n * key        = /./ *(/[^-/+_ ]/)\n *\n */\nexport function parseKeyCombination (input: string) {\n  let pos = 0\n\n  try {\n    const result = parseSequence()\n    if (!atEnd()) {\n      throw new ParseError(`Unexpected character '${peek()}' at position ${pos}`)\n    }\n    return result\n  } catch (err) {\n    if (err instanceof ParseError) {\n      consoleWarn(`Invalid hotkey combination: ${err.message}\\n  ${input}\\n  ${' '.repeat(pos)}^`)\n      return ''\n    } else {\n      throw err\n    }\n  }\n\n  function peek (ahead = 0): string | null {\n    return pos + ahead < input.length\n      ? input[pos + ahead]\n      : null\n  }\n\n  function consume (): string {\n    if (pos >= input.length) {\n      throw new ParseError('Unexpected end of input')\n    }\n    return input[pos++]\n  }\n\n  function atEnd (): boolean {\n    return pos >= input.length\n  }\n\n  // sequence = alternate *('-' alternate)\n  function parseSequence (): KeyCombination {\n    const parts: (Alternate | Combo | Key)[] = [parseAlternate()]\n    while (peek() === '-') {\n      consume()\n      parts.push(parseAlternate())\n    }\n    if (parts.length === 1) return parts[0]\n    return { type: 'sequence', parts }\n  }\n\n  // alternate = combo *('/' combo)\n  function parseAlternate (): Alternate | Combo | Key {\n    const parts: (Combo | Key)[] = [parseCombo()]\n    while (peek() === '/') {\n      consume()\n      parts.push(parseCombo())\n    }\n    if (parts.length === 1) return parts[0]\n    return { type: 'alternate', parts }\n  }\n\n  // combo = key *(('+' | '_') key)\n  function parseCombo (): Combo | Key {\n    const keys: Key[] = [parseKey()]\n    while (includes(['+', '_'], peek())) {\n      consume()\n      keys.push(parseKey())\n    }\n    if (keys.length === 1) return keys[0]\n    return {\n      type: 'combo',\n      parts: keys,\n    }\n  }\n\n  // key = /./ *(/[^-/+_ ]/)\n  function parseKey (): Key {\n    const ch = peek()\n    if (ch == null) {\n      throw new ParseError('Unexpected end of input')\n    }\n    const next = peek(1)\n    if (isSep(ch) && next != null && !isSep(next)) {\n      throw new ParseError(`Unexpected separator '${ch}' at position ${pos}`)\n    }\n    const first = consume()\n    // separator keys are always a single character\n    if (isSep(first)) return first\n    const chars: Key[] = [first]\n    while (!atEnd() && !isSep(peek()) && peek() !== ' ') {\n      chars.push(consume())\n    }\n    return normalizeKey(chars.join(''))\n  }\n}\n\nfunction isSep (char: string | null) {\n  return includes(['-', '/', '+', '_'], char)\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/hotkey/hotkey.ts",
    "content": "// Composables\nimport { parseKeyCombination } from '@/composables/hotkey/hotkey-parsing'\n\n// Utilities\nimport { onScopeDispose, toValue, watch } from 'vue'\nimport { IN_BROWSER } from '@/util'\n\n// Types\nimport type { Combo, Key, KeyCombination, Sequence } from '@/composables/hotkey/hotkey-parsing'\nimport type { MaybeRef } from '@/util'\n\nconst MODIFIERS = ['ctrl', 'shift', 'alt', 'meta', 'cmd'] as const\nconst modifiersSet = new Set(MODIFIERS)\ntype Modifier = typeof MODIFIERS[number]\nfunction isModifier (key: string): key is Modifier {\n  return modifiersSet.has(key as Modifier)\n}\nconst emptyModifiers = Object.fromEntries(MODIFIERS.map(m => [m, false])) as Record<Modifier, boolean>\n\ninterface HotkeyOptions {\n  event?: MaybeRef<'keydown' | 'keyup'>\n  inputs?: MaybeRef<boolean>\n  preventDefault?: MaybeRef<boolean>\n  sequenceTimeout?: MaybeRef<number>\n}\n\nexport function useHotkey (\n  keys: MaybeRef<string | undefined>,\n  callback: (e: KeyboardEvent) => void,\n  options: HotkeyOptions = {}\n) {\n  if (!IN_BROWSER) return function () {}\n\n  const {\n    event = 'keydown',\n    inputs = false,\n    preventDefault = true,\n    sequenceTimeout = 1000,\n  } = options\n\n  const isMac = navigator?.userAgent?.includes('Macintosh') ?? false\n  let timeout = 0\n  let keyGroups: (Exclude<KeyCombination, Sequence>)[]\n  let isSequence = false\n  let groupIndex = 0\n\n  function isInputFocused () {\n    if (toValue(inputs)) return false\n\n    const activeElement = document.activeElement as HTMLElement\n\n    return activeElement && (\n      activeElement.tagName === 'INPUT' ||\n      activeElement.tagName === 'TEXTAREA' ||\n      activeElement.isContentEditable ||\n      activeElement.contentEditable === 'true'\n    )\n  }\n\n  function resetSequence () {\n    groupIndex = 0\n    clearTimeout(timeout)\n  }\n\n  function handler (e: KeyboardEvent) {\n    const group = keyGroups[groupIndex]\n\n    if (!group || isInputFocused()) return\n\n    if (!matchesKeyGroup(e, group, isMac)) {\n      if (isSequence) resetSequence()\n      return\n    }\n\n    if (toValue(preventDefault)) e.preventDefault()\n\n    if (!isSequence) {\n      callback(e)\n      return\n    }\n\n    clearTimeout(timeout)\n    groupIndex++\n\n    if (groupIndex === keyGroups.length) {\n      callback(e)\n      resetSequence()\n      return\n    }\n\n    timeout = window.setTimeout(resetSequence, toValue(sequenceTimeout))\n  }\n\n  function cleanup () {\n    window.removeEventListener(toValue(event), handler)\n    clearTimeout(timeout)\n  }\n\n  watch(() => toValue(keys), newKeys => {\n    cleanup()\n\n    if (newKeys) {\n      const parsed = parseKeyCombination(newKeys.toLowerCase())\n      if (parsed) {\n        const parts = typeof parsed !== 'string' && parsed.type === 'sequence'\n          ? parsed.parts\n          : [parsed]\n        isSequence = parts.length > 1\n        keyGroups = parts\n        resetSequence()\n        window.addEventListener(toValue(event), handler)\n      }\n    }\n  }, { immediate: true })\n\n  // Watch for changes in the event type to re-register the listener\n  watch(() => toValue(event), (newEvent, oldEvent) => {\n    if (oldEvent && keyGroups && keyGroups.length > 0) {\n      window.removeEventListener(oldEvent, handler)\n      window.addEventListener(newEvent, handler)\n    }\n  })\n\n  onScopeDispose(cleanup, true)\n\n  return cleanup\n}\n\nfunction matchesKeyGroup (e: KeyboardEvent, group: Exclude<KeyCombination, Sequence>, isMac: boolean): boolean {\n  if (typeof group !== 'string' && group.type === 'alternate') {\n    return group.parts.some(part => matchesKeyGroup(e, part, isMac))\n  }\n\n  const { modifiers, actualKey } = parseKeyGroup(group)\n\n  const expectCtrl = modifiers.ctrl || (!isMac && (modifiers.cmd || modifiers.meta))\n  const expectMeta = isMac && (modifiers.cmd || modifiers.meta)\n\n  return (\n    e.ctrlKey === expectCtrl &&\n    e.metaKey === expectMeta &&\n    e.shiftKey === modifiers.shift &&\n    e.altKey === modifiers.alt &&\n    e.key.toLowerCase() === actualKey?.toLowerCase()\n  )\n}\n\nfunction parseKeyGroup (group: Combo | Key): {\n  modifiers: Record<Modifier, boolean>\n  actualKey: string | undefined\n} {\n  const parts = typeof group === 'string' ? [group] : group.parts\n  const modifiers = { ...emptyModifiers }\n  let actualKey: string | undefined\n\n  for (const part of parts) {\n    if (isModifier(part)) {\n      modifiers[part] = true\n    } else {\n      // TODO: handle multiple keys\n      actualKey = part\n    }\n  }\n\n  return { modifiers, actualKey }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/hotkey/index.ts",
    "content": "export { useHotkey } from './hotkey'\n"
  },
  {
    "path": "packages/vuetify/src/composables/hotkey/key-aliases.ts",
    "content": "/**\n * Centralized key alias mapping for consistent key normalization across the hotkey system.\n *\n * This maps various user-friendly aliases to canonical key names that match\n * KeyboardEvent.key values (in lowercase) where possible.\n */\nexport const keyAliasMap: Record<string, string> = {\n  // Modifier aliases (from vue-use, other libraries, and current implementation)\n  control: 'ctrl',\n  command: 'cmd',\n  option: 'alt',\n\n  // Arrow key aliases (common abbreviations)\n  up: 'arrowup',\n  down: 'arrowdown',\n  left: 'arrowleft',\n  right: 'arrowright',\n\n  // Other common key aliases\n  esc: 'escape',\n  spacebar: ' ',\n  space: ' ',\n  return: 'enter',\n  del: 'delete',\n\n  // Symbol aliases (existing from hotkey-parsing.ts)\n  plus: '+',\n  slash: '/',\n  underscore: '_',\n  minus: '-',\n  hyphen: '-',\n}\n\n/**\n * Normalizes a key string to its canonical form using the alias map.\n *\n * @param key - The key string to normalize\n * @returns The canonical key name in lowercase\n */\nexport function normalizeKey (key: string): string {\n  const lowerKey = key.toLowerCase()\n  return keyAliasMap[lowerKey] || lowerKey\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/hydration.ts",
    "content": "// Composables\nimport { useDisplay } from '@/composables/display'\n\n// Utilities\nimport { onMounted, shallowRef } from 'vue'\nimport { IN_BROWSER } from '@/util'\n\nexport function useHydration () {\n  if (!IN_BROWSER) return shallowRef(false)\n\n  const { ssr } = useDisplay()\n\n  if (ssr) {\n    const isMounted = shallowRef(false)\n    onMounted(() => {\n      isMounted.value = true\n    })\n    return isMounted\n  } else {\n    return shallowRef(true)\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/iconSizes.ts",
    "content": "// Utilities\nimport { computed } from 'vue'\nimport { propsFactory } from '@/util'\n\n// Types\nimport type { ComputedGetter, PropType } from 'vue'\nimport type { VIconBtnSizes } from '@/labs/VIconBtn/VIconBtn'\n\n// Types\nexport interface IconSizeProps {\n  iconSize?: VIconBtnSizes | number | string\n  iconSizes: [VIconBtnSizes, number][]\n}\n\n// Composables\nexport const makeIconSizeProps = propsFactory({\n  iconSize: [Number, String] as PropType<VIconBtnSizes | number | string>,\n  iconSizes: {\n    type: Array as PropType<[VIconBtnSizes, number][]>,\n    default: () => ([\n      ['x-small', 10],\n      ['small', 16],\n      ['default', 24],\n      ['large', 28],\n      ['x-large', 32],\n    ]),\n  },\n}, 'iconSize')\n\nexport function useIconSizes (props: IconSizeProps, fallback: ComputedGetter<VIconBtnSizes | number | string | undefined>) {\n  const iconSize = computed(() => {\n    const iconSizeMap = new Map(props.iconSizes)\n    const _iconSize = props.iconSize as VIconBtnSizes ?? fallback() ?? 'default'\n    return iconSizeMap.has(_iconSize)\n      ? iconSizeMap.get(_iconSize)\n      : _iconSize\n  })\n\n  return { iconSize }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/icons.tsx",
    "content": "// Utilities\nimport { computed, inject, toValue } from 'vue'\nimport { consoleWarn, defineComponent, genericComponent, propsFactory } from '@/util'\n\n// Types\nimport type { InjectionKey, MaybeRefOrGetter, PropType } from 'vue'\nimport type { JSXComponent } from '@/util'\n\nexport type IconValue =\n  | string\n  | (string | [path: string, opacity: number])[]\n  | JSXComponent\nexport const IconValue = [String, Function, Object, Array] as PropType<IconValue>\n\nexport interface IconAliases {\n  [name: string]: IconValue\n  collapse: IconValue\n  complete: IconValue\n  cancel: IconValue\n  close: IconValue\n  delete: IconValue\n  clear: IconValue\n  success: IconValue\n  info: IconValue\n  warning: IconValue\n  error: IconValue\n  prev: IconValue\n  next: IconValue\n  checkboxOn: IconValue\n  checkboxOff: IconValue\n  checkboxIndeterminate: IconValue\n  delimiter: IconValue\n  sortAsc: IconValue\n  sortDesc: IconValue\n  expand: IconValue\n  menu: IconValue\n  subgroup: IconValue\n  dropdown: IconValue\n  radioOn: IconValue\n  radioOff: IconValue\n  edit: IconValue\n  ratingEmpty: IconValue\n  ratingFull: IconValue\n  ratingHalf: IconValue\n  loading: IconValue\n  first: IconValue\n  last: IconValue\n  unfold: IconValue\n  file: IconValue\n  plus: IconValue\n  minus: IconValue\n  calendar: IconValue\n  treeviewCollapse: IconValue\n  treeviewExpand: IconValue\n  eyeDropper: IconValue\n  upload: IconValue\n  color: IconValue\n  // Font Awesome does not have most of these icons!\n  command: IconValue\n  ctrl: IconValue\n  space: IconValue\n  shift: IconValue\n  alt: IconValue\n  enter: IconValue\n  arrowup: IconValue\n  arrowdown: IconValue\n  arrowleft: IconValue\n  arrowright: IconValue\n  backspace: IconValue\n}\n\nexport interface IconProps {\n  tag: string | JSXComponent\n  icon?: IconValue\n  disabled?: boolean\n}\n\ntype IconComponent = JSXComponent<IconProps>\n\nexport interface IconSet {\n  component: IconComponent\n}\n\nexport type InternalIconOptions = {\n  defaultSet: string\n  aliases: Partial<IconAliases>\n  sets: Record<string, IconSet>\n}\n\nexport type IconOptions = Partial<InternalIconOptions>\n\ntype IconInstance = {\n  component: IconComponent\n  icon?: IconValue\n}\n\nexport const IconSymbol: InjectionKey<InternalIconOptions> = Symbol.for('vuetify:icons')\n\nexport const makeIconProps = propsFactory({\n  icon: {\n    type: IconValue,\n  },\n  // Could not remove this and use makeTagProps, types complained because it is not required\n  tag: {\n    type: [String, Object, Function] as PropType<string | JSXComponent>,\n    required: true,\n  },\n}, 'icon')\n\nexport const VComponentIcon = genericComponent()({\n  name: 'VComponentIcon',\n\n  props: makeIconProps(),\n\n  setup (props, { slots }) {\n    return () => {\n      const Icon = props.icon as JSXComponent\n      return (\n        <props.tag>\n          { props.icon ? <Icon /> : slots.default?.() }\n        </props.tag>\n      )\n    }\n  },\n})\nexport type VComponentIcon = InstanceType<typeof VComponentIcon>\n\nexport const VSvgIcon = defineComponent({\n  name: 'VSvgIcon',\n\n  inheritAttrs: false,\n\n  props: makeIconProps(),\n\n  setup (props, { attrs }) {\n    return () => {\n      return (\n        <props.tag { ...attrs } style={ null }>\n          <svg\n            class=\"v-icon__svg\"\n            xmlns=\"http://www.w3.org/2000/svg\"\n            viewBox=\"0 0 24 24\"\n            role=\"img\"\n            aria-hidden=\"true\"\n          >\n            { Array.isArray(props.icon)\n              ? props.icon.map(path => (\n                Array.isArray(path)\n                  ? <path d={ path[0] as string } fill-opacity={ path[1] }></path>\n                  : <path d={ path as string }></path>\n              ))\n              : <path d={ props.icon as string }></path>\n            }\n          </svg>\n        </props.tag>\n      )\n    }\n  },\n})\nexport type VSvgIcon = InstanceType<typeof VSvgIcon>\n\nexport const VLigatureIcon = defineComponent({\n  name: 'VLigatureIcon',\n\n  props: makeIconProps(),\n\n  setup (props) {\n    return () => {\n      return <props.tag>{ props.icon }</props.tag>\n    }\n  },\n})\nexport type VLigatureIcon = InstanceType<typeof VLigatureIcon>\n\nexport const VClassIcon = defineComponent({\n  name: 'VClassIcon',\n\n  props: makeIconProps(),\n\n  setup (props) {\n    return () => {\n      return <props.tag class={ props.icon }></props.tag>\n    }\n  },\n})\nexport type VClassIcon = InstanceType<typeof VClassIcon>\n\nexport const useIcon = (props: MaybeRefOrGetter<IconValue | undefined>) => {\n  const icons = inject(IconSymbol)\n\n  if (!icons) throw new Error('Missing Vuetify Icons provide!')\n\n  const iconData = computed<IconInstance>(() => {\n    const iconAlias = toValue(props)\n\n    if (!iconAlias) return { component: VComponentIcon }\n\n    let icon: IconValue | undefined = iconAlias\n\n    if (typeof icon === 'string') {\n      icon = icon.trim()\n      if (icon.startsWith('$')) {\n        icon = icons.aliases?.[icon.slice(1)]\n      }\n    }\n\n    if (!icon) consoleWarn(`Could not find aliased icon \"${iconAlias}\"`)\n\n    if (Array.isArray(icon)) {\n      return {\n        component: VSvgIcon,\n        icon,\n      }\n    } else if (typeof icon !== 'string') {\n      return {\n        component: VComponentIcon,\n        icon,\n      }\n    }\n\n    const iconSetName = Object.keys(icons.sets).find(\n      setName => typeof icon === 'string' && icon.startsWith(`${setName}:`)\n    )\n\n    const iconName = iconSetName ? icon.slice(iconSetName.length + 1) : icon\n    const iconSet = icons.sets[iconSetName ?? icons.defaultSet]\n\n    return {\n      component: iconSet.component,\n      icon: iconName,\n    }\n  })\n\n  return { iconData }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/index.ts",
    "content": "/*\n * PUBLIC INTERFACES ONLY\n * Imports in our code should be to the composable directly, not this file\n */\n\nexport { useDate } from './date'\nexport { useDefaults } from './defaults'\nexport { useDisplay } from './display'\nexport { useGoTo } from './goto'\nexport { useLayout } from './layout'\nexport { useLocale, useRtl } from './locale'\nexport { useTheme } from './theme'\nexport { useHotkey } from './hotkey'\nexport { useMask } from './mask'\n"
  },
  {
    "path": "packages/vuetify/src/composables/intersectionObserver.ts",
    "content": "// Utilities\nimport { onScopeDispose, ref, shallowRef, watch } from 'vue'\nimport { SUPPORTS_INTERSECTION } from '@/util'\n\nexport function useIntersectionObserver (callback?: IntersectionObserverCallback, options?: IntersectionObserverInit) {\n  const intersectionRef = ref<HTMLElement>()\n  const isIntersecting = shallowRef(false)\n\n  if (SUPPORTS_INTERSECTION) {\n    const observer = new IntersectionObserver((entries: IntersectionObserverEntry[]) => {\n      callback?.(entries, observer)\n\n      isIntersecting.value = !!entries.find(entry => entry.isIntersecting)\n    }, options)\n\n    onScopeDispose(() => {\n      observer.disconnect()\n    })\n\n    watch(intersectionRef, (newValue, oldValue) => {\n      if (oldValue) {\n        observer.unobserve(oldValue)\n        isIntersecting.value = false\n      }\n\n      if (newValue) observer.observe(newValue)\n    }, {\n      flush: 'post',\n    })\n  }\n\n  return { intersectionRef, isIntersecting }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/layout.ts",
    "content": "// Composables\nimport { useResizeObserver } from '@/composables/resizeObserver'\n\n// Utilities\nimport {\n  computed,\n  inject,\n  onActivated,\n  onBeforeUnmount,\n  onDeactivated,\n  onMounted,\n  provide,\n  reactive,\n  ref,\n  shallowRef, toRef,\n  useId,\n} from 'vue'\nimport { consoleWarn, convertToUnit, findChildrenWithProvide, getCurrentInstance, propsFactory } from '@/util'\n\n// Types\nimport type { ComponentInternalInstance, CSSProperties, InjectionKey, Prop, Ref } from 'vue'\n\nexport type Position = 'top' | 'left' | 'right' | 'bottom'\n\ninterface Layer {\n  top: number\n  bottom: number\n  left: number\n  right: number\n}\n\ninterface LayoutItem extends Layer {\n  id: string\n  size: number\n  position: Position\n}\n\ninterface LayoutProvide {\n  register: (\n    vm: ComponentInternalInstance,\n    options: {\n      id: string\n      order: Ref<number>\n      position: Ref<Position>\n      layoutSize: Ref<number | string>\n      elementSize: Ref<number | string | undefined>\n      active: Ref<boolean>\n      disableTransitions?: Ref<boolean>\n      absolute: Ref<boolean | undefined>\n    }\n  ) => {\n    layoutItemStyles: Ref<CSSProperties>\n    layoutItemScrimStyles: Ref<CSSProperties>\n    zIndex: Ref<number>\n  }\n  unregister: (id: string) => void\n  mainRect: Ref<Layer>\n  mainStyles: Ref<CSSProperties>\n  getLayoutItem: (id: string) => LayoutItem | undefined\n  items: Ref<LayoutItem[]>\n  layoutRect: Ref<DOMRectReadOnly | undefined>\n  rootZIndex: Ref<number>\n}\n\nexport const VuetifyLayoutKey: InjectionKey<LayoutProvide> = Symbol.for('vuetify:layout')\nexport const VuetifyLayoutItemKey: InjectionKey<{ id: string }> = Symbol.for('vuetify:layout-item')\n\nconst ROOT_ZINDEX = 1000\n\nexport const makeLayoutProps = propsFactory({\n  overlaps: {\n    type: Array,\n    default: () => ([]),\n  } as Prop<string[]>,\n  fullHeight: Boolean,\n}, 'layout')\n\n// Composables\nexport const makeLayoutItemProps = propsFactory({\n  name: {\n    type: String,\n  },\n  order: {\n    type: [Number, String],\n    default: 0,\n  },\n  absolute: Boolean,\n}, 'layout-item')\n\nexport function useLayout () {\n  const layout = inject(VuetifyLayoutKey)\n\n  if (!layout) throw new Error('[Vuetify] Could not find injected layout')\n\n  return {\n    getLayoutItem: layout.getLayoutItem,\n    mainRect: layout.mainRect,\n    mainStyles: layout.mainStyles,\n  }\n}\n\nexport function useLayoutItem (options: {\n  id: string | undefined\n  order: Ref<number>\n  position: Ref<Position>\n  layoutSize: Ref<number | string>\n  elementSize: Ref<number | string | undefined>\n  active: Ref<boolean>\n  disableTransitions?: Ref<boolean>\n  absolute: Ref<boolean | undefined>\n}) {\n  const layout = inject(VuetifyLayoutKey)\n\n  if (!layout) throw new Error('[Vuetify] Could not find injected layout')\n\n  const id = options.id ?? `layout-item-${useId()}`\n\n  const vm = getCurrentInstance('useLayoutItem')\n\n  provide(VuetifyLayoutItemKey, { id })\n\n  const isKeptAlive = shallowRef(false)\n  onDeactivated(() => isKeptAlive.value = true)\n  onActivated(() => isKeptAlive.value = false)\n\n  const {\n    layoutItemStyles,\n    layoutItemScrimStyles,\n  } = layout.register(vm, {\n    ...options,\n    active: computed(() => isKeptAlive.value ? false : options.active.value),\n    id,\n  })\n\n  onBeforeUnmount(() => layout.unregister(id))\n\n  return { layoutItemStyles, layoutRect: layout.layoutRect, layoutItemScrimStyles }\n}\n\nconst generateLayers = (\n  layout: string[],\n  positions: Map<string, Ref<Position>>,\n  layoutSizes: Map<string, Ref<number | string>>,\n  activeItems: Map<string, Ref<boolean>>,\n): { id: string, layer: Layer }[] => {\n  let previousLayer: Layer = { top: 0, left: 0, right: 0, bottom: 0 }\n  const layers = [{ id: '', layer: { ...previousLayer } }]\n  for (const id of layout) {\n    const position = positions.get(id)\n    const amount = layoutSizes.get(id)\n    const active = activeItems.get(id)\n    if (!position || !amount || !active) continue\n\n    const layer = {\n      ...previousLayer,\n      [position.value]: parseInt(previousLayer[position.value], 10) + (active.value ? parseInt(amount.value, 10) : 0),\n    }\n\n    layers.push({\n      id,\n      layer,\n    })\n\n    previousLayer = layer\n  }\n\n  return layers\n}\n\nexport function createLayout (props: { overlaps?: string[], fullHeight?: boolean }) {\n  const parentLayout = inject(VuetifyLayoutKey, null)\n  const rootZIndex = computed(() => parentLayout ? parentLayout.rootZIndex.value - 100 : ROOT_ZINDEX)\n  const registered = ref<string[]>([])\n  const positions = reactive(new Map<string, Ref<Position>>())\n  const layoutSizes = reactive(new Map<string, Ref<number | string>>())\n  const priorities = reactive(new Map<string, Ref<number>>())\n  const activeItems = reactive(new Map<string, Ref<boolean>>())\n  const disabledTransitions = reactive(new Map<string, Ref<boolean>>())\n  const { resizeRef, contentRect: layoutRect } = useResizeObserver()\n\n  const computedOverlaps = computed(() => {\n    const map = new Map<string, { position: Position, amount: number }>()\n    const overlaps = props.overlaps ?? []\n    for (const overlap of overlaps.filter(item => item.includes(':'))) {\n      const [top, bottom] = overlap.split(':')\n      if (!registered.value.includes(top) || !registered.value.includes(bottom)) continue\n\n      const topPosition = positions.get(top)\n      const bottomPosition = positions.get(bottom)\n      const topAmount = layoutSizes.get(top)\n      const bottomAmount = layoutSizes.get(bottom)\n\n      if (!topPosition || !bottomPosition || !topAmount || !bottomAmount) continue\n\n      map.set(bottom, { position: topPosition.value, amount: parseInt(topAmount.value, 10) })\n      map.set(top, { position: bottomPosition.value, amount: -parseInt(bottomAmount.value, 10) })\n    }\n\n    return map\n  })\n\n  const layers = computed(() => {\n    const uniquePriorities = [...new Set([...priorities.values()].map(p => p.value))].sort((a, b) => a - b)\n    const layout = []\n    for (const p of uniquePriorities) {\n      const items = registered.value.filter(id => priorities.get(id)?.value === p)\n      layout.push(...items)\n    }\n    return generateLayers(layout, positions, layoutSizes, activeItems)\n  })\n\n  const transitionsEnabled = computed(() => {\n    return !Array.from(disabledTransitions.values()).some(ref => ref.value)\n  })\n\n  const mainRect = computed(() => {\n    return layers.value[layers.value.length - 1].layer\n  })\n\n  const mainStyles = toRef(() => {\n    return {\n      '--v-layout-left': convertToUnit(mainRect.value.left),\n      '--v-layout-right': convertToUnit(mainRect.value.right),\n      '--v-layout-top': convertToUnit(mainRect.value.top),\n      '--v-layout-bottom': convertToUnit(mainRect.value.bottom),\n      ...(transitionsEnabled.value ? undefined : { transition: 'none' }),\n    } satisfies CSSProperties\n  })\n\n  const items = computed(() => {\n    return layers.value.slice(1).map(({ id }, index) => {\n      const { layer } = layers.value[index]\n      const size = layoutSizes.get(id)\n      const position = positions.get(id)\n\n      return {\n        id,\n        ...layer,\n        size: Number(size!.value),\n        position: position!.value,\n      }\n    })\n  })\n\n  const getLayoutItem = (id: string) => {\n    return items.value.find(item => item.id === id)\n  }\n\n  const rootVm = getCurrentInstance('createLayout')\n\n  const isMounted = shallowRef(false)\n  onMounted(() => {\n    isMounted.value = true\n  })\n\n  provide(VuetifyLayoutKey, {\n    register: (\n      vm: ComponentInternalInstance,\n      {\n        id,\n        order,\n        position,\n        layoutSize,\n        elementSize,\n        active,\n        disableTransitions,\n        absolute,\n      }\n    ) => {\n      priorities.set(id, order)\n      positions.set(id, position)\n      layoutSizes.set(id, layoutSize)\n      activeItems.set(id, active)\n      disableTransitions && disabledTransitions.set(id, disableTransitions)\n\n      const instances = findChildrenWithProvide(VuetifyLayoutItemKey, rootVm?.vnode)\n      const instanceIndex = instances.indexOf(vm)\n\n      if (instanceIndex > -1) registered.value.splice(instanceIndex, 0, id)\n      else registered.value.push(id)\n\n      const index = computed(() => items.value.findIndex(i => i.id === id))\n      const zIndex = computed(() => rootZIndex.value + (layers.value.length * 2) - (index.value * 2))\n\n      const layoutItemStyles = computed<CSSProperties>(() => {\n        const isHorizontal = position.value === 'left' || position.value === 'right'\n        const isOppositeHorizontal = position.value === 'right'\n        const isOppositeVertical = position.value === 'bottom'\n        const size = elementSize.value ?? layoutSize.value\n        const unit = size === 0 ? '%' : 'px'\n\n        const styles = {\n          [position.value]: 0,\n          zIndex: zIndex.value,\n          transform: `translate${isHorizontal ? 'X' : 'Y'}(${(active.value ? 0 : -(size === 0 ? 100 : size)) * (isOppositeHorizontal || isOppositeVertical ? -1 : 1)}${unit})`,\n          position: absolute.value || rootZIndex.value !== ROOT_ZINDEX ? 'absolute' : 'fixed',\n          ...(transitionsEnabled.value ? undefined : { transition: 'none' }),\n        } as const\n\n        if (!isMounted.value) return styles\n\n        const item = items.value[index.value]\n\n        if (!item) consoleWarn(`[Vuetify] Could not find layout item \"${id}\"`)\n\n        const overlap = computedOverlaps.value.get(id)\n        if (overlap) {\n          item[overlap.position] += overlap.amount\n        }\n\n        return {\n          ...styles,\n          height:\n            isHorizontal ? `calc(100% - ${item.top}px - ${item.bottom}px)`\n            : elementSize.value ? `${elementSize.value}px`\n            : undefined,\n          left: isOppositeHorizontal ? undefined : `${item.left}px`,\n          right: isOppositeHorizontal ? `${item.right}px` : undefined,\n          top: position.value !== 'bottom' ? `${item.top}px` : undefined,\n          bottom: position.value !== 'top' ? `${item.bottom}px` : undefined,\n          width:\n            !isHorizontal ? `calc(100% - ${item.left}px - ${item.right}px)`\n            : elementSize.value ? `${elementSize.value}px`\n            : undefined,\n        }\n      })\n      const layoutItemScrimStyles = computed<CSSProperties>(() => ({\n        zIndex: zIndex.value - 1,\n      }))\n\n      return { layoutItemStyles, layoutItemScrimStyles, zIndex }\n    },\n    unregister: (id: string) => {\n      priorities.delete(id)\n      positions.delete(id)\n      layoutSizes.delete(id)\n      activeItems.delete(id)\n      disabledTransitions.delete(id)\n      registered.value = registered.value.filter(v => v !== id)\n    },\n    mainRect,\n    mainStyles,\n    getLayoutItem,\n    items,\n    layoutRect,\n    rootZIndex,\n  })\n\n  const layoutClasses = toRef(() => [\n    'v-layout',\n    { 'v-layout--full-height': props.fullHeight },\n  ])\n\n  const layoutStyles = toRef(() => ({\n    zIndex: parentLayout ? rootZIndex.value : undefined,\n    position: parentLayout ? 'relative' as const : undefined,\n    overflow: parentLayout ? 'hidden' : undefined,\n  }))\n\n  return {\n    layoutClasses,\n    layoutStyles,\n    getLayoutItem,\n    items,\n    layoutRect,\n    layoutRef: resizeRef,\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/lazy.ts",
    "content": "// Utilities\nimport { shallowRef, toRef, watch } from 'vue'\nimport { propsFactory } from '@/util'\n\n// Types\nimport type { Ref } from 'vue'\n\nexport const makeLazyProps = propsFactory({\n  eager: Boolean,\n}, 'lazy')\n\nexport function useLazy (props: { eager: boolean }, active: Ref<boolean>) {\n  const isBooted = shallowRef(false)\n  const hasContent = toRef(() => isBooted.value || props.eager || active.value)\n\n  watch(active, () => isBooted.value = true)\n\n  function onAfterLeave () {\n    if (!props.eager) isBooted.value = false\n  }\n\n  return { isBooted, hasContent, onAfterLeave }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/list-items.ts",
    "content": "// Utilities\nimport { computed, shallowRef, watchEffect } from 'vue'\nimport { deepEqual, getPropertyFromItem, isPrimitive, omit, pick, propsFactory } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { InternalItem } from '@/composables/filter'\nimport type { Primitive, SelectItemKey, ValueComparator } from '@/util'\n\nexport interface ListItem<T = any> extends InternalItem<T> {\n  title: string\n  props: {\n    [key: string]: any\n    title: string\n    value: any\n  }\n  children: ListItem<T>[] | undefined\n  type: string\n}\n\nexport interface ItemProps {\n  items: any[]\n  itemTitle: SelectItemKey\n  itemValue: SelectItemKey\n  itemChildren: SelectItemKey\n  itemProps: SelectItemKey\n  itemType: SelectItemKey\n  returnObject: boolean\n  valueComparator: ValueComparator | undefined\n}\n\n// Composables\nexport const makeItemsProps = propsFactory({\n  items: {\n    type: Array as PropType<ItemProps['items']>,\n    default: () => ([]),\n  },\n  itemTitle: {\n    type: [String, Array, Function] as PropType<SelectItemKey>,\n    default: 'title',\n  },\n  itemValue: {\n    type: [String, Array, Function] as PropType<SelectItemKey>,\n    default: 'value',\n  },\n  itemChildren: {\n    type: [Boolean, String, Array, Function] as PropType<SelectItemKey>,\n    default: 'children',\n  },\n  itemProps: {\n    type: [Boolean, String, Array, Function] as PropType<SelectItemKey>,\n    default: 'props',\n  },\n  itemType: {\n    type: [Boolean, String, Array, Function] as PropType<SelectItemKey>,\n    default: 'type',\n  },\n  returnObject: Boolean,\n  valueComparator: Function as PropType<ValueComparator>,\n}, 'list-items')\n\nconst itemTypes = new Set(['item', 'divider', 'subheader'])\n\nexport function transformItem (\n  props: Pick<ItemProps, typeof transformItem.neededProps[number]>,\n  item: any\n): ListItem {\n  const title = getPropertyFromItem(item, props.itemTitle, item)\n  const value = getPropertyFromItem(item, props.itemValue, title)\n  const children = getPropertyFromItem(item, props.itemChildren)\n  const itemProps = props.itemProps === true\n    ? typeof item === 'object' && item != null && !Array.isArray(item)\n      ? 'children' in item\n        ? omit(item, ['children'])\n        : item\n      : undefined\n    : getPropertyFromItem(item, props.itemProps)\n\n  let type = getPropertyFromItem(item, props.itemType, 'item')\n  if (!itemTypes.has(type)) {\n    type = 'item'\n  }\n\n  const _props = {\n    title,\n    value,\n    ...itemProps,\n  }\n\n  return {\n    type,\n    title: String(_props.title ?? ''),\n    value: _props.value,\n    props: _props,\n    children: type === 'item' && Array.isArray(children) ? transformItems(props, children) : undefined,\n    raw: item,\n  }\n}\n\ntransformItem.neededProps = [\n  'itemTitle',\n  'itemValue',\n  'itemChildren',\n  'itemProps',\n  'itemType',\n] as const\n\nexport function transformItems (\n  props: Pick<ItemProps, typeof transformItem.neededProps[number]>,\n  items: ItemProps['items']\n) {\n  // avoid reactive access in the loop\n  const _props = pick(props, transformItem.neededProps)\n\n  const array: ListItem[] = []\n  for (const item of items) {\n    array.push(transformItem(_props, item))\n  }\n\n  return array\n}\n\nexport function useItems (props: ItemProps) {\n  const items = computed(() => transformItems(props, props.items))\n  const hasNullItem = computed(() => items.value.some(item => item.value === null))\n\n  const itemsMap = shallowRef<Map<Primitive, ListItem[]>>(new Map())\n  const keylessItems = shallowRef<ListItem[]>([])\n  watchEffect(() => {\n    const _items = items.value\n    const map = new Map()\n    const keyless = []\n    for (let i = 0; i < _items.length; i++) {\n      const item = _items[i]\n      if (isPrimitive(item.value) || item.value === null) {\n        let values = map.get(item.value)\n        if (!values) {\n          values = []\n          map.set(item.value, values)\n        }\n        values.push(item)\n      } else {\n        keyless.push(item)\n      }\n    }\n    itemsMap.value = map\n    keylessItems.value = keyless\n  })\n\n  function transformIn (value: any[]): ListItem[] {\n    // Cache unrefed values outside the loop,\n    // proxy getters can be slow when you call them a billion times\n    const _items = itemsMap.value\n    const _allItems = items.value\n    const _keylessItems = keylessItems.value\n    const _hasNullItem = hasNullItem.value\n    const _returnObject = props.returnObject\n    const hasValueComparator = !!props.valueComparator\n    const valueComparator = props.valueComparator || deepEqual\n    const _props = pick(props, transformItem.neededProps)\n\n    const returnValue: ListItem[] = []\n    main: for (const v of value) {\n      // When the model value is null, return an InternalItem\n      // based on null only if null is one of the items\n      if (!_hasNullItem && v === null) continue\n\n      // String model value means value is a custom input value from combobox\n      // Don't look up existing items if the model value is a string\n      if (_returnObject && typeof v === 'string') {\n        returnValue.push(transformItem(_props, v))\n        continue\n      }\n\n      // Fast path, items with primitive values and no\n      // custom valueComparator can use a constant-time\n      // map lookup instead of searching the items array\n      const fastItems = _items.get(v)\n\n      // Slow path, always use valueComparator.\n      // This is O(n^2) so we really don't want to\n      // do it for more than a couple hundred items.\n      if (hasValueComparator || !fastItems) {\n        for (const item of (hasValueComparator ? _allItems : _keylessItems)) {\n          if (valueComparator(v, item.value)) {\n            returnValue.push(item)\n            continue main\n          }\n        }\n        // Not an existing item, construct it from the model (#4000)\n        returnValue.push(transformItem(_props, v))\n        continue\n      }\n\n      returnValue.push(...fastItems)\n    }\n\n    return returnValue\n  }\n\n  function transformOut (value: ListItem[]): any[] {\n    return props.returnObject\n      ? value.map(({ raw }) => raw)\n      : value.map(({ value }) => value)\n  }\n\n  return { items, transformIn, transformOut }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/loader.tsx",
    "content": "// Components\nimport { VProgressLinear } from '@/components/VProgressLinear'\n\n// Utilities\nimport { toRef } from 'vue'\nimport { getCurrentInstanceName, propsFactory } from '@/util'\n\n// Types\nimport type { ExtractPropTypes, SetupContext } from 'vue'\nimport type { SlotsToProps } from '@/util'\n\nexport interface LoaderSlotProps {\n  color: string | undefined\n  isActive: boolean\n}\n\nexport interface LoaderProps {\n  loading?: boolean | string\n}\n\n// Composables\nexport const makeLoaderProps = propsFactory({\n  loading: [Boolean, String],\n}, 'loader')\n\nexport function useLoader (\n  props: LoaderProps,\n  name = getCurrentInstanceName(),\n) {\n  const loaderClasses = toRef(() => ({\n    [`${name}--loading`]: props.loading,\n  }))\n\n  return { loaderClasses }\n}\n\nexport function LoaderSlot (\n  props: {\n    absolute?: boolean\n    active: boolean\n    name: string\n    color?: string\n  } & ExtractPropTypes<SlotsToProps<{\n    default: LoaderSlotProps\n  }>>,\n  { slots }: SetupContext,\n) {\n  return (\n    <div class={ `${props.name}__loader` }>\n      { slots.default?.({\n        color: props.color,\n        isActive: props.active,\n      } satisfies LoaderSlotProps) || (\n        <VProgressLinear\n          absolute={ props.absolute }\n          active={ props.active }\n          color={ props.color }\n          height=\"2\"\n          indeterminate\n        />\n      )}\n    </div>\n  )\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/locale.ts",
    "content": "// Utilities\nimport { computed, inject, provide, ref, toRef } from 'vue'\nimport { createVuetifyAdapter } from '@/locale/adapters/vuetify'\n\n// Types\nimport type { InjectionKey, Ref, ShallowRef } from 'vue'\n\nexport interface LocaleMessages {\n  [key: string]: LocaleMessages | string\n}\n\nexport interface LocaleOptions {\n  decimalSeparator?: string\n  messages?: LocaleMessages\n  locale?: string\n  fallback?: string\n  adapter?: LocaleInstance\n}\n\nexport interface LocaleInstance {\n  name: string\n  decimalSeparator: ShallowRef<string>\n  messages: Ref<LocaleMessages>\n  current: Ref<string>\n  fallback: Ref<string>\n  t: (key: string, ...params: unknown[]) => string\n  n: (value: number) => string\n  provide: (props: LocaleOptions) => LocaleInstance\n}\n\nexport const LocaleSymbol: InjectionKey<LocaleInstance & RtlInstance> = Symbol.for('vuetify:locale')\n\nfunction isLocaleInstance (obj: any): obj is LocaleInstance {\n  return obj.name != null\n}\n\nexport function createLocale (options?: LocaleOptions & RtlOptions) {\n  const i18n = options?.adapter && isLocaleInstance(options?.adapter) ? options?.adapter : createVuetifyAdapter(options)\n  const rtl = createRtl(i18n, options)\n\n  return { ...i18n, ...rtl }\n}\n\nexport function useLocale () {\n  const locale = inject(LocaleSymbol)\n\n  if (!locale) throw new Error('[Vuetify] Could not find injected locale instance')\n\n  return locale\n}\n\nexport function provideLocale (props: LocaleOptions & RtlProps) {\n  const locale = inject(LocaleSymbol)\n\n  if (!locale) throw new Error('[Vuetify] Could not find injected locale instance')\n\n  const i18n = locale.provide(props)\n  const rtl = provideRtl(i18n, locale.rtl, props)\n\n  const data = { ...i18n, ...rtl }\n\n  provide(LocaleSymbol, data)\n\n  return data\n}\n\n// RTL\n\nexport interface RtlOptions {\n  rtl?: Record<string, boolean>\n}\n\nexport interface RtlProps {\n  rtl?: boolean\n}\n\nexport interface RtlInstance {\n  isRtl: Ref<boolean>\n  rtl: Ref<Record<string, boolean>>\n  rtlClasses: Ref<string>\n}\n\nexport const RtlSymbol: InjectionKey<RtlInstance> = Symbol.for('vuetify:rtl')\n\nfunction genDefaults () {\n  return {\n    af: false,\n    ar: true,\n    bg: false,\n    ca: false,\n    ckb: false,\n    cs: false,\n    de: false,\n    el: false,\n    en: false,\n    es: false,\n    et: false,\n    fa: true,\n    fi: false,\n    fr: false,\n    hr: false,\n    hu: false,\n    he: true,\n    id: false,\n    it: false,\n    ja: false,\n    km: false,\n    ko: false,\n    lv: false,\n    lt: false,\n    nl: false,\n    no: false,\n    pl: false,\n    pt: false,\n    ro: false,\n    ru: false,\n    sk: false,\n    sl: false,\n    srCyrl: false,\n    srLatn: false,\n    sv: false,\n    th: false,\n    tr: false,\n    az: false,\n    uk: false,\n    vi: false,\n    zhHans: false,\n    zhHant: false,\n  }\n}\n\nexport function createRtl (i18n: LocaleInstance, options?: RtlOptions): RtlInstance {\n  const rtl = ref<Record<string, boolean>>(options?.rtl ?? genDefaults())\n  const isRtl = computed(() => rtl.value[i18n.current.value] ?? false)\n\n  return {\n    isRtl,\n    rtl,\n    rtlClasses: toRef(() => `v-locale--is-${isRtl.value ? 'rtl' : 'ltr'}`),\n  }\n}\n\nexport function provideRtl (locale: LocaleInstance, rtl: RtlInstance['rtl'], props: RtlProps): RtlInstance {\n  const isRtl = computed(() => props.rtl ?? rtl.value[locale.current.value] ?? false)\n\n  return {\n    isRtl,\n    rtl,\n    rtlClasses: toRef(() => `v-locale--is-${isRtl.value ? 'rtl' : 'ltr'}`),\n  }\n}\n\nexport function useRtl () {\n  const locale = inject(LocaleSymbol)\n\n  if (!locale) throw new Error('[Vuetify] Could not find injected rtl instance')\n\n  return { isRtl: locale.isRtl, rtlClasses: locale.rtlClasses }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/location.ts",
    "content": "// Composables\nimport { useRtl } from '@/composables/locale'\n\n// Utilities\nimport { computed } from 'vue'\nimport { parseAnchor, propsFactory } from '@/util'\n\n// Types\nimport type { CSSProperties, PropType } from 'vue'\nimport type { Anchor } from '@/util'\n\nconst oppositeMap = {\n  center: 'center',\n  top: 'bottom',\n  bottom: 'top',\n  left: 'right',\n  right: 'left',\n} as const\n\nexport interface LocationProps {\n  location: Anchor | null | undefined\n}\n\nexport const makeLocationProps = propsFactory({\n  location: String as PropType<Anchor | null>,\n}, 'location')\n\nexport function useLocation (props: LocationProps, opposite = false, offset?: (side: string) => number) {\n  const { isRtl } = useRtl()\n\n  const locationStyles = computed(() => {\n    if (!props.location) return {}\n\n    const { side, align } = parseAnchor(\n      props.location.split(' ').length > 1\n        ? props.location\n        : `${props.location} center` as Anchor,\n      isRtl.value\n    )\n\n    function getOffset (side: string) {\n      return offset\n        ? offset(side)\n        : 0\n    }\n\n    const styles = {} as CSSProperties\n\n    if (side !== 'center') {\n      if (opposite) styles[oppositeMap[side]] = `calc(100% - ${getOffset(side)}px)`\n      else styles[side] = 0\n    }\n    if (align !== 'center') {\n      if (opposite) styles[oppositeMap[align]] = `calc(100% - ${getOffset(align)}px)`\n      else styles[align] = 0\n    } else {\n      if (side === 'center') styles.top = styles.left = '50%'\n      else {\n        styles[({\n          top: 'left',\n          bottom: 'left',\n          left: 'top',\n          right: 'top',\n        } as const)[side]] = '50%'\n      }\n      styles.transform = {\n        top: 'translateX(-50%)',\n        bottom: 'translateX(-50%)',\n        left: 'translateY(-50%)',\n        right: 'translateY(-50%)',\n        center: 'translate(-50%, -50%)',\n      }[side]\n    }\n\n    return styles\n  })\n\n  return { locationStyles }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/mask/__tests__/mask.spec.ts",
    "content": "// Composables\nimport { useMask } from '../mask'\n\n// Types\nimport type { MaskProps } from '../mask'\n\ndescribe('mask', () => {\n  it.each([\n    [{ mask: '(#', modelValue: '5' }, '(5'],\n    [{ mask: '(#', modelValue: '(' }, '('],\n    [{ mask: '(###) #', modelValue: '4567' }, '(456) 7'],\n    [{ mask: '#### - #### - #### - ####', modelValue: '444444444' }, '4444 - 4444 - 4'],\n    [{ mask: 'A## - ####', modelValue: 'A314444' }, 'A31 - 4444'],\n    [{ mask: '## - ##', modelValue: '55' }, '55 - '],\n    [{ mask: '## - ##', modelValue: '' }, ''],\n    [{ mask: 'Aa', modelValue: 'aa' }, 'Aa'],\n    [{ mask: 'aa', modelValue: 'AA' }, 'aa'],\n    [{ mask: 'Aa', modelValue: 'A1' }, 'A'],\n    [{ mask: 'NnNnNn', modelValue: '12abAB' }, '12AbAb'],\n    [{ mask: '#a', modelValue: 'a' }, ''],\n    [{ mask: '#)', modelValue: '1' }, '1)'],\n    [{ mask: '(###)!!', modelValue: '123' }, '(123)!!'],\n    [{ mask: '##.##', modelValue: '1234' }, '12.34'],\n    [{ mask: '#', modelValue: null }, ''],\n    [{ mask: '\\\\#(###)', modelValue: '123' }, '#(123)'],\n    [{ mask: '\\\\####', modelValue: '1' }, '#1'],\n    [{ mask: '+38(###)', modelValue: '43' }, '+38(43'],\n  ])('mask %#', (props, expected) => {\n    const { mask } = useMask(props as MaskProps)\n    expect(mask(props.modelValue)).toEqual(expected)\n  })\n\n  it.each([\n    [{ mask: '(#) (#)', modelValue: ' 5   6 ' }, '(5) (6)'],\n  ])('should trim spaces', (props, expected) => {\n    const { mask } = useMask(props as MaskProps)\n    expect(mask(props.modelValue)).toEqual(expected)\n  })\n\n  it.each([\n    [{ mask: '(#', modelValue: '(5' }, '5'],\n    [{ mask: '####', modelValue: '1111' }, '1111'],\n    [{ mask: '(###)#', modelValue: '(123)4' }, '1234'],\n    [{ mask: '(###) #)', modelValue: '(456) 7)' }, '4567'],\n    [{ mask: '#### - #### - #', modelValue: '4444 - 4444 - 4' }, '444444444'],\n    [{ mask: 'NNN - ####', modelValue: 'A31 - 4444' }, 'A314444'],\n    [{ mask: '\\\\#(###)', modelValue: '#(123)' }, '123'],\n    [{ mask: '\\\\#(###)', modelValue: '123' }, '123'],\n    [{ mask: '\\\\####', modelValue: '#(123)' }, '(123)'],\n    [{ mask: '\\\\####', modelValue: '#1' }, '1'],\n    [{ mask: '#-#', modelValue: '2-23' }, '223'],\n    [{ mask: '+38(###)', modelValue: '+38(43' }, '43'],\n    [{ mask: '+38(###)', modelValue: '43' }, '43'],\n    [{ mask: '', modelValue: null }, null],\n  ])('unmask %#', (props, expected) => {\n    const { unmask } = useMask(props as MaskProps)\n    expect(unmask(props.modelValue)).toEqual(expected)\n  })\n\n  describe('The test method', () => {\n    it.each([\n      [{ mask: '####', text: '1234' }, true],\n      [{ mask: '####', text: '123' }, true],\n      [{ mask: '####', text: '12345' }, false],\n      [{ mask: '##/##/####', text: '12/34/5678' }, true],\n      [{ mask: '##/##/####', text: '12345678' }, true],\n      [{ mask: '##/##/####', text: '12/34/567' }, true],\n      [{ mask: '##/##/####', text: '123456789' }, false],\n      [{ mask: '(###) ###-####', text: '(123) 456-7890' }, true],\n      [{ mask: '(###) ###-####', text: '1234567890' }, true],\n      [{ mask: '(###) ###-####', text: '(123) 456-789' }, true],\n      [{ mask: 'A##', text: 'A12' }, true],\n      [{ mask: 'A##', text: 'a12' }, false],\n      [{ mask: 'A##', text: 'A1' }, true],\n      [{ mask: '', text: '' }, false],\n      [{ mask: '', text: 'abc' }, true],\n    ])('should check if the text is valid for the mask', (props, expected) => {\n      const { isValid } = useMask(props as MaskProps)\n      expect(isValid(props.text)).toEqual(expected)\n    })\n\n    it.each([\n      [{ mask: '####', text: '1234' }, true],\n      [{ mask: '####', text: '123' }, false],\n      [{ mask: '####', text: '12345' }, false],\n      [{ mask: '##/##/####', text: '12/34/5678' }, true],\n      [{ mask: '##/##/####', text: '12345678' }, true],\n      [{ mask: '##/##/####', text: '12/34/567' }, false],\n      [{ mask: '##/##/####', text: '123456789' }, false],\n      [{ mask: '(###) ###-####', text: '(123) 456-7890' }, true],\n      [{ mask: '(###) ###-####', text: '1234567890' }, true],\n      [{ mask: '(###) ###-####', text: '(123) 456-789' }, false],\n      [{ mask: 'A##', text: 'A12' }, true],\n      [{ mask: 'A##', text: 'a12' }, false],\n      [{ mask: 'A##', text: 'A1' }, false],\n      [{ mask: '', text: '' }, false],\n      [{ mask: '', text: 'abc' }, false],\n    ])('should check if the text is complete for the mask', (props, expected) => {\n      const { isComplete } = useMask(props as MaskProps)\n      expect(isComplete(props.text)).toEqual(expected)\n    })\n\n    it('should handle null and undefined text', () => {\n      const { isValid } = useMask({ mask: '####' })\n      expect(isValid('')).toBe(false)\n      expect(isValid(null as any)).toBe(false)\n      expect(isValid(undefined as any)).toBe(false)\n    })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/mask/index.ts",
    "content": "export * from './mask'\n"
  },
  {
    "path": "packages/vuetify/src/composables/mask/mask.ts",
    "content": "// Utilities\nimport { computed } from 'vue'\nimport { isObject, propsFactory } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\nexport interface MaskProps {\n  mask: string | MaskOptions | undefined\n}\n\nexport interface MaskOptions {\n  mask: string\n  tokens: Record<string, MaskItem>\n}\n\nexport const makeMaskProps = propsFactory({\n  mask: [String, Object] as PropType<string | MaskOptions>,\n}, 'mask')\n\nexport type MaskItem = {\n  convert?: (char: string) => string\n} & ({\n  pattern?: never\n  test: (char: string) => boolean\n} | {\n  pattern: RegExp\n  test?: never\n})\n\nexport const defaultDelimiters = /[-!$%^&*()_+|~=`{}[\\]:\";'<>?,./\\\\ ]/\n\nconst presets: Record<string, string> = {\n  'credit-card': '#### - #### - #### - ####',\n  date: '##/##/####',\n  'date-time': '##/##/#### ##:##',\n  'iso-date': '####-##-##',\n  'iso-date-time': '####-##-## ##:##',\n  phone: '(###) ### - ####',\n  social: '###-##-####',\n  time: '##:##',\n  'time-with-seconds': '##:##:##',\n}\n\nconst defaultTokens: Record<string, MaskItem> = {\n  '#': {\n    pattern: /[0-9]/,\n  },\n  A: {\n    pattern: /[A-Z]/i,\n    convert: v => v.toUpperCase(),\n  },\n  a: {\n    pattern: /[a-z]/i,\n    convert: v => v.toLowerCase(),\n  },\n  N: {\n    pattern: /[0-9A-Z]/i,\n    convert: v => v.toUpperCase(),\n  },\n  n: {\n    pattern: /[0-9a-z]/i,\n    convert: v => v.toLowerCase(),\n  },\n  X: {\n    pattern: defaultDelimiters,\n  },\n}\n\nexport function useMask (props: MaskProps) {\n  const mask = computed(() => {\n    if (typeof props.mask === 'string') {\n      if (props.mask in presets) return presets[props.mask]\n      return props.mask\n    }\n    return props.mask?.mask ?? ''\n  })\n  const tokens = computed(() => {\n    return {\n      ...defaultTokens,\n      ...(isObject(props.mask) ? props.mask.tokens : null),\n    }\n  })\n\n  function isMask (char: string): boolean {\n    return char in tokens.value\n  }\n\n  function maskValidates (mask: string, char: string): boolean {\n    if (char == null || !isMask(mask)) return false\n    const item = tokens.value[mask]\n    if (item.pattern) return item.pattern.test(char)\n    return item.test(char)\n  }\n\n  function convert (mask: string, char: string): string {\n    const item = tokens.value[mask]\n    return item.convert ? item.convert(char) : char\n  }\n\n  function maskText (text: string | null | undefined): string {\n    const trimmedText = text?.trim().replace(/\\s+/g, ' ')\n\n    if (trimmedText == null) return ''\n\n    if (!mask.value.length || !trimmedText.length) return trimmedText\n\n    let textIndex = 0\n    let maskIndex = 0\n    let newText = ''\n\n    while (maskIndex < mask.value.length) {\n      const mchar = mask.value[maskIndex]\n      const tchar = trimmedText[textIndex]\n\n      // Escaped character in mask, the next mask character is inserted\n      if (mchar === '\\\\') {\n        newText += mask.value[maskIndex + 1]\n        maskIndex += 2\n        continue\n      }\n\n      if (!isMask(mchar)) {\n        newText += mchar\n        if (tchar === mchar) {\n          textIndex++\n        }\n      } else if (maskValidates(mchar, tchar)) {\n        newText += convert(mchar, tchar)\n        textIndex++\n      } else if (textIndex < trimmedText.length) {\n        // No match, try the next input character\n        textIndex++\n        continue\n      } else {\n        break\n      }\n\n      maskIndex++\n    }\n    return newText\n  }\n\n  function unmaskText (text: string | null): string | null {\n    if (text == null) return null\n\n    if (!mask.value.length || !text.length) return text\n\n    let result = ''\n    const unmaskMap = getUnmaskMap(text)\n    for (let i = 0; i < text.length; i++) {\n      if (!unmaskMap[i]) result += text[i]\n    }\n    return result\n  }\n\n  function isDelimiter (text: string, index: number): boolean {\n    if (!mask.value.length || !text.length) return false\n    return !!getUnmaskMap(text)[index]\n  }\n\n  function getUnmaskMap (text: string | null): boolean[] {\n    if (text == null || !mask.value.length || !text.length) return []\n\n    let textIndex = 0\n    let maskIndex = 0\n    const result = Array.from({ length: text.length }, () => true)\n\n    while (true) {\n      const mchar = mask.value[maskIndex]\n      const tchar = text[textIndex]\n\n      if (tchar == null) break\n\n      if (mchar == null) {\n        result[textIndex] = false\n        textIndex++\n        continue\n      }\n\n      // Escaped character in mask, skip the next input character\n      if (mchar === '\\\\') {\n        if (tchar === mask.value[maskIndex + 1]) {\n          textIndex++\n        }\n        maskIndex += 2\n        continue\n      }\n\n      if (maskValidates(mchar, tchar)) {\n        // masked char\n        result[textIndex] = false\n        textIndex++\n        maskIndex++\n        continue\n      } else if (mchar !== tchar) {\n        // input doesn't match mask, skip forward until it does\n        while (true) {\n          const mchar = mask.value[maskIndex++]\n          if (mchar == null || maskValidates(mchar, tchar)) break\n        }\n        continue\n      }\n\n      textIndex++\n      maskIndex++\n    }\n\n    return result\n  }\n\n  function isValid (text: string): boolean {\n    if (!text) return false\n\n    return unmaskText(text) === unmaskText(maskText(text))\n  }\n\n  function isComplete (text: string): boolean {\n    if (!text) return false\n\n    const maskedText = maskText(text)\n    return maskedText.length === mask.value.length && isValid(text)\n  }\n\n  return {\n    isDelimiter,\n    isValid,\n    isComplete,\n    mask: maskText,\n    unmask: unmaskText,\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/menuActivator.ts",
    "content": "// Utilities\nimport { computed, toRef, toValue, useId } from 'vue'\nimport { propsFactory } from '@/util'\n\n// Types\nimport type { MaybeRefOrGetter } from 'vue'\n\n// Types\nexport interface MenuActivatorProps {\n  closeText: string\n  openText: string\n}\n\n// Composables\nexport const makeMenuActivatorProps = propsFactory({\n  closeText: {\n    type: String,\n    default: '$vuetify.close',\n  },\n  openText: {\n    type: String,\n    default: '$vuetify.open',\n  },\n}, 'autocomplete')\n\nexport function useMenuActivator (props: MenuActivatorProps, isOpen: MaybeRefOrGetter<boolean>) {\n  const uid = useId()\n  const menuId = computed(() => `menu-${uid}`)\n\n  const ariaExpanded = toRef(() => toValue(isOpen))\n  const ariaControls = toRef(() => menuId.value)\n\n  return {\n    menuId,\n    ariaExpanded,\n    ariaControls,\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/mutationObserver.ts",
    "content": "// Utilities\nimport { onBeforeUnmount, onMounted, ref, watch } from 'vue'\nimport { refElement } from '@/util'\n\n// Types\nimport type { ComponentPublicInstance } from 'vue'\n\nexport interface MutationOptions {\n  attr?: boolean\n  char?: boolean\n  child?: boolean\n  sub?: boolean\n  once?: boolean\n  immediate?: boolean\n}\n\nexport function useMutationObserver (\n  handler?: MutationCallback,\n  options?: MutationOptions,\n) {\n  const mutationRef = ref<ComponentPublicInstance | HTMLElement>()\n  const { once, immediate, ...optionKeys } = options || {}\n  const defaultValue = !Object.keys(optionKeys).length\n\n  const observer = new MutationObserver((\n    mutations: MutationRecord[],\n    observer: MutationObserver\n  ) => {\n    handler?.(mutations, observer)\n\n    if (options?.once) observer.disconnect()\n  })\n\n  onMounted(() => {\n    if (!options?.immediate) return\n\n    handler?.([], observer)\n  })\n\n  onBeforeUnmount(() => {\n    observer.disconnect()\n  })\n\n  watch(mutationRef, (newValue, oldValue) => {\n    if (oldValue) observer.disconnect()\n\n    const el = refElement(newValue)\n\n    if (!el) return\n\n    observer.observe(el, {\n      attributes: options?.attr ?? defaultValue,\n      characterData: options?.char ?? defaultValue,\n      childList: options?.child ?? defaultValue,\n      subtree: options?.sub ?? defaultValue,\n    })\n  }, {\n    flush: 'post',\n  })\n\n  return { mutationRef }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/nested/__tests__/selectStrategies.spec.ts",
    "content": "/* eslint-disable max-len */\n/* eslint-disable sonarjs/no-identical-functions */\n// Utilities\nimport {\n  branchSelectStrategy,\n  classicSelectStrategy,\n  independentSelectStrategy,\n  independentSingleSelectStrategy,\n  leafSelectStrategy,\n  leafSingleSelectStrategy,\n  trunkSelectStrategy,\n} from '../selectStrategies'\n\ndescribe('selectStrategies', () => {\n  describe('independent', () => {\n    it('should allow selection of multiple items', () => {\n      const strategy = independentSelectStrategy(false)\n\n      const children = new Map([\n        ['1', ['2', '3']],\n      ])\n\n      const parents = new Map([\n        ['2', '1'],\n        ['3', '1'],\n      ])\n      let selected = new Map()\n\n      selected = strategy.select({\n        id: '2',\n        value: true,\n        children,\n        parents,\n        disabled: new Set(),\n        selected,\n      })\n\n      selected = strategy.select({\n        id: '3',\n        value: true,\n        children,\n        parents,\n        disabled: new Set(),\n        selected,\n      })\n\n      expect(selected).toEqual(new Map([\n        ['2', 'on'],\n        ['3', 'on'],\n      ]))\n    })\n\n    it('should allow selection of both branch and leaf nodes', () => {\n      const strategy = independentSelectStrategy(false)\n\n      const children = new Map([\n        ['1', ['2', '3']],\n      ])\n\n      const parents = new Map([\n        ['2', '1'],\n        ['3', '1'],\n      ])\n\n      expect(strategy.select({\n        id: '1',\n        value: true,\n        children,\n        parents,\n        disabled: new Set(),\n        selected: new Map(),\n      })).toEqual(new Map([\n        ['1', 'on'],\n      ]))\n\n      expect(strategy.select({\n        id: '2',\n        value: true,\n        children,\n        parents,\n        disabled: new Set(),\n        selected: new Map(),\n      })).toEqual(new Map([\n        ['2', 'on'],\n      ]))\n    })\n\n    it('should allow deselection of both branch and leaf nodes', () => {\n      const strategy = independentSelectStrategy(false)\n\n      const children = new Map([\n        ['1', ['2', '3']],\n      ])\n\n      const parents = new Map([\n        ['2', '1'],\n        ['3', '1'],\n      ])\n\n      expect(strategy.select({\n        id: '1',\n        value: false,\n        children,\n        parents,\n        disabled: new Set(),\n        selected: new Map([\n          ['1', 'on'],\n        ]),\n      })).toEqual(new Map([\n        ['1', 'off'],\n      ]))\n\n      expect(strategy.select({\n        id: '2',\n        value: false,\n        children,\n        parents,\n        disabled: new Set(),\n        selected: new Map([\n          ['2', 'on'],\n        ]),\n      })).toEqual(new Map([\n        ['2', 'off'],\n      ]))\n    })\n\n    it('should not allow deselection of last item when using mandatory', () => {\n      const strategy = independentSelectStrategy(true)\n\n      const children = new Map([\n        ['1', ['2', '3']],\n      ])\n\n      const parents = new Map([\n        ['2', '1'],\n        ['3', '1'],\n      ])\n\n      expect(strategy.select({\n        id: '2',\n        value: false,\n        children,\n        parents,\n        disabled: new Set(),\n        selected: new Map([\n          ['2', 'on'],\n        ]),\n      })).toEqual(new Map([\n        ['2', 'on'],\n      ]))\n    })\n  })\n\n  describe('single-independent', () => {\n    it('should not allow selection of multiple items', () => {\n      const strategy = independentSingleSelectStrategy(false)\n\n      const children = new Map([\n        ['1', ['2', '3']],\n      ])\n\n      const parents = new Map([\n        ['2', '1'],\n        ['3', '1'],\n      ])\n\n      let selected = new Map()\n\n      selected = strategy.select({\n        id: '2',\n        value: true,\n        children,\n        parents,\n        disabled: new Set(),\n        selected,\n      })\n\n      selected = strategy.select({\n        id: '3',\n        value: true,\n        children,\n        parents,\n        disabled: new Set(),\n        selected,\n      })\n\n      expect(selected).toEqual(new Map([\n        ['3', 'on'],\n      ]))\n    })\n\n    it('should allow selection of both branch and leaf nodes', () => {\n      const strategy = independentSingleSelectStrategy(false)\n\n      const children = new Map([\n        ['1', ['2', '3']],\n      ])\n\n      const parents = new Map([\n        ['2', '1'],\n        ['3', '1'],\n      ])\n\n      expect(strategy.select({\n        id: '1',\n        value: true,\n        children,\n        parents,\n        disabled: new Set(),\n        selected: new Map(),\n      })).toEqual(new Map([\n        ['1', 'on'],\n      ]))\n\n      expect(strategy.select({\n        id: '2',\n        value: true,\n        children,\n        parents,\n        disabled: new Set(),\n        selected: new Map(),\n      })).toEqual(new Map([\n        ['2', 'on'],\n      ]))\n    })\n\n    it('should allow deselection of both branch and leaf nodes', () => {\n      const strategy = independentSingleSelectStrategy(false)\n\n      const children = new Map([\n        ['1', ['2', '3']],\n      ])\n\n      const parents = new Map([\n        ['2', '1'],\n        ['3', '1'],\n      ])\n\n      expect(strategy.select({\n        id: '1',\n        value: false,\n        children,\n        parents,\n        disabled: new Set(),\n        selected: new Map([\n          ['1', 'on'],\n        ]),\n      })).toEqual(new Map([\n        ['1', 'off'],\n      ]))\n\n      expect(strategy.select({\n        id: '2',\n        value: false,\n        children,\n        parents,\n        disabled: new Set(),\n        selected: new Map([\n          ['2', 'on'],\n        ]),\n      })).toEqual(new Map([\n        ['2', 'off'],\n      ]))\n    })\n\n    it('should not allow deselection of last item when using mandatory', () => {\n      const strategy = independentSingleSelectStrategy(true)\n\n      const children = new Map([\n        ['1', ['2', '3']],\n      ])\n\n      const parents = new Map([\n        ['2', '1'],\n        ['3', '1'],\n      ])\n\n      expect(strategy.select({\n        id: '2',\n        value: false,\n        children,\n        parents,\n        disabled: new Set(),\n        selected: new Map([\n          ['2', 'on'],\n        ]),\n      })).toEqual(new Map([\n        ['2', 'on'],\n      ]))\n    })\n  })\n\n  describe('single-leaf', () => {\n    it('should not allow selection of multiple items', () => {\n      const strategy = leafSingleSelectStrategy(false)\n\n      const children = new Map([\n        ['1', ['2', '3']],\n      ])\n\n      const parents = new Map([\n        ['2', '1'],\n        ['3', '1'],\n      ])\n\n      let selected = new Map()\n\n      selected = strategy.select({\n        id: '2',\n        value: true,\n        children,\n        parents,\n        disabled: new Set(),\n        selected,\n      })\n\n      selected = strategy.select({\n        id: '3',\n        value: true,\n        children,\n        parents,\n        disabled: new Set(),\n        selected,\n      })\n\n      expect(selected).toEqual(new Map([\n        ['3', 'on'],\n      ]))\n    })\n\n    it('should allow selection of only leaf nodes', () => {\n      const strategy = leafSingleSelectStrategy(false)\n\n      const children = new Map([\n        ['1', ['2', '3']],\n      ])\n\n      const parents = new Map([\n        ['2', '1'],\n        ['3', '1'],\n      ])\n\n      expect(strategy.select({\n        id: '1',\n        value: true,\n        children,\n        parents,\n        disabled: new Set(),\n        selected: new Map(),\n      })).toEqual(new Map())\n\n      expect(strategy.select({\n        id: '2',\n        value: true,\n        children,\n        parents,\n        disabled: new Set(),\n        selected: new Map(),\n      })).toEqual(new Map([\n        ['2', 'on'],\n      ]))\n    })\n\n    it('should allow deselection of only leaf nodes', () => {\n      const strategy = leafSingleSelectStrategy(false)\n\n      const children = new Map([\n        ['1', ['2', '3']],\n      ])\n\n      const parents = new Map([\n        ['2', '1'],\n        ['3', '1'],\n      ])\n\n      expect(strategy.select({\n        id: '1',\n        value: false,\n        children,\n        parents,\n        disabled: new Set(),\n        selected: new Map([\n          ['1', 'on'],\n        ]),\n      })).toEqual(new Map([\n        ['1', 'on'],\n      ]))\n\n      expect(strategy.select({\n        id: '2',\n        value: false,\n        children,\n        parents,\n        disabled: new Set(),\n        selected: new Map([\n          ['2', 'on'],\n        ]),\n      })).toEqual(new Map([\n        ['2', 'off'],\n      ]))\n    })\n\n    it('should not allow deselection of last item when using mandatory', () => {\n      const strategy = leafSingleSelectStrategy(true)\n\n      const children = new Map([\n        ['1', ['2', '3']],\n      ])\n\n      const parents = new Map([\n        ['2', '1'],\n        ['3', '1'],\n      ])\n\n      expect(strategy.select({\n        id: '2',\n        value: false,\n        children,\n        parents,\n        disabled: new Set(),\n        selected: new Map([\n          ['2', 'on'],\n        ]),\n      })).toEqual(new Map([\n        ['2', 'on'],\n      ]))\n    })\n  })\n\n  describe('leaf', () => {\n    it('should allow selection of multiple items', () => {\n      const strategy = leafSelectStrategy(false)\n\n      const children = new Map([\n        ['1', ['2', '3']],\n      ])\n\n      const parents = new Map([\n        ['2', '1'],\n        ['3', '1'],\n      ])\n\n      let selected = new Map()\n\n      selected = strategy.select({\n        id: '2',\n        value: true,\n        children,\n        parents,\n        disabled: new Set(),\n        selected,\n      })\n\n      selected = strategy.select({\n        id: '3',\n        value: true,\n        children,\n        parents,\n        disabled: new Set(),\n        selected,\n      })\n\n      expect(selected).toEqual(new Map([\n        ['2', 'on'],\n        ['3', 'on'],\n      ]))\n    })\n\n    it('should allow selection of only leaf nodes', () => {\n      const strategy = leafSelectStrategy(false)\n\n      const children = new Map([\n        ['1', ['2', '3']],\n      ])\n\n      const parents = new Map([\n        ['2', '1'],\n        ['3', '1'],\n      ])\n\n      expect(strategy.select({\n        id: '1',\n        value: true,\n        children,\n        parents,\n        disabled: new Set(),\n        selected: new Map(),\n      })).toEqual(new Map())\n\n      expect(strategy.select({\n        id: '2',\n        value: true,\n        children,\n        parents,\n        disabled: new Set(),\n        selected: new Map(),\n      })).toEqual(new Map([\n        ['2', 'on'],\n      ]))\n    })\n\n    it('should allow deselection of only leaf nodes', () => {\n      const strategy = leafSelectStrategy(false)\n\n      const children = new Map([\n        ['1', ['2', '3']],\n      ])\n\n      const parents = new Map([\n        ['2', '1'],\n        ['3', '1'],\n      ])\n\n      expect(strategy.select({\n        id: '1',\n        value: false,\n        children,\n        parents,\n        disabled: new Set(),\n        selected: new Map([\n          ['1', 'on'],\n        ]),\n      })).toEqual(new Map([\n        ['1', 'on'],\n      ]))\n\n      expect(strategy.select({\n        id: '2',\n        value: false,\n        children,\n        parents,\n        disabled: new Set(),\n        selected: new Map([\n          ['2', 'on'],\n        ]),\n      })).toEqual(new Map([\n        ['2', 'off'],\n      ]))\n    })\n\n    it('should not allow deselection of last item when using mandatory', () => {\n      const strategy = leafSelectStrategy(true)\n\n      const children = new Map([\n        ['1', ['2', '3']],\n      ])\n\n      const parents = new Map([\n        ['2', '1'],\n        ['3', '1'],\n      ])\n\n      expect(strategy.select({\n        id: '2',\n        value: false,\n        children,\n        parents,\n        disabled: new Set(),\n        selected: new Map([\n          ['2', 'on'],\n        ]),\n      })).toEqual(new Map([\n        ['2', 'on'],\n      ]))\n    })\n  })\n\n  describe('classic', () => {\n    it('should update parents of selected leaf', () => {\n      const strategy = classicSelectStrategy(false)\n\n      const children = new Map([\n        ['1', ['2', '3']],\n        ['3', ['4', '5']],\n        ['5', ['6']],\n      ])\n\n      const parents = new Map([\n        ['2', '1'],\n        ['3', '1'],\n        ['4', '3'],\n        ['5', '3'],\n        ['6', '5'],\n      ])\n\n      expect(strategy.select({\n        id: '6',\n        value: true,\n        children,\n        parents,\n        disabled: new Set(),\n        selected: new Map(),\n      })).toEqual(new Map([\n        ['1', 'indeterminate'],\n        ['3', 'indeterminate'],\n        ['5', 'on'],\n        ['6', 'on'],\n      ]))\n    })\n\n    it('should select children of a branch node', () => {\n      const strategy = classicSelectStrategy(false)\n\n      const children = new Map([\n        ['1', ['2', '3']],\n        ['3', ['4', '5']],\n        ['5', ['6']],\n      ])\n\n      const parents = new Map([\n        ['2', '1'],\n        ['3', '1'],\n        ['4', '3'],\n        ['5', '3'],\n        ['6', '5'],\n      ])\n\n      expect(strategy.select({\n        id: '3',\n        value: true,\n        children,\n        parents,\n        disabled: new Set(),\n        selected: new Map(),\n      })).toEqual(new Map([\n        ['1', 'indeterminate'],\n        ['3', 'on'],\n        ['4', 'on'],\n        ['5', 'on'],\n        ['6', 'on'],\n      ]))\n    })\n\n    it('should deselect children of branch node', () => {\n      const strategy = classicSelectStrategy(false)\n\n      const children = new Map([\n        ['1', ['2', '3']],\n        ['3', ['4', '5']],\n        ['5', ['6']],\n      ])\n\n      const parents = new Map([\n        ['2', '1'],\n        ['3', '1'],\n        ['4', '3'],\n        ['5', '3'],\n        ['6', '5'],\n      ])\n\n      expect(strategy.select({\n        id: '3',\n        value: false,\n        children,\n        parents,\n        disabled: new Set(),\n        selected: new Map([\n          ['1', 'indeterminate'],\n          ['3', 'on'],\n          ['4', 'on'],\n          ['5', 'on'],\n          ['6', 'on'],\n        ]),\n      })).toEqual(new Map([\n        ['1', 'off'],\n        ['3', 'off'],\n        ['4', 'off'],\n        ['5', 'off'],\n        ['6', 'off'],\n      ]))\n    })\n\n    it('should allow selection of multiple items', () => {\n      const strategy = classicSelectStrategy(false)\n\n      const children = new Map([\n        ['1', ['2', '3']],\n      ])\n\n      const parents = new Map([\n        ['2', '1'],\n        ['3', '1'],\n      ])\n\n      let selected = new Map()\n\n      selected = strategy.select({\n        id: '2',\n        value: true,\n        children,\n        parents,\n        disabled: new Set(),\n        selected,\n      })\n\n      expect(selected).toEqual(new Map([\n        ['1', 'indeterminate'],\n        ['2', 'on'],\n      ]))\n\n      selected = strategy.select({\n        id: '3',\n        value: true,\n        children,\n        parents,\n        disabled: new Set(),\n        selected,\n      })\n\n      expect(selected).toEqual(new Map([\n        ['1', 'on'],\n        ['2', 'on'],\n        ['3', 'on'],\n      ]))\n    })\n\n    it('should not allow deselection of last item when using mandatory', () => {\n      const strategy = classicSelectStrategy(true)\n\n      const children = new Map([\n        ['1', ['2', '3']],\n        ['3', ['4', '5']],\n        ['5', ['6']],\n      ])\n\n      const parents = new Map([\n        ['2', '1'],\n        ['3', '1'],\n        ['4', '3'],\n        ['5', '3'],\n        ['6', '5'],\n      ])\n\n      expect(strategy.select({\n        id: '6',\n        value: false,\n        children,\n        parents,\n        disabled: new Set(),\n        selected: new Map([\n          ['1', 'indeterminate'],\n          ['3', 'indeterminate'],\n          ['5', 'on'],\n          ['6', 'on'],\n        ]),\n      })).toEqual(new Map([\n        ['1', 'indeterminate'],\n        ['3', 'indeterminate'],\n        ['5', 'on'],\n        ['6', 'on'],\n      ]))\n\n      expect(strategy.select({\n        id: '1',\n        value: false,\n        children,\n        parents,\n        disabled: new Set(),\n        selected: new Map([\n          ['1', 'on'],\n          ['2', 'on'],\n          ['3', 'on'],\n          ['4', 'on'],\n          ['5', 'on'],\n          ['6', 'on'],\n        ]),\n      })).toEqual(new Map([\n        ['1', 'on'],\n        ['2', 'on'],\n        ['3', 'on'],\n        ['4', 'on'],\n        ['5', 'on'],\n        ['6', 'on'],\n      ]))\n    })\n\n    it('should not select disabled children when parent is selected', () => {\n      const strategy = classicSelectStrategy(false)\n\n      const children = new Map([\n        ['1', ['2', '3']],\n        ['3', ['4', '5']],\n      ])\n\n      const parents = new Map([\n        ['2', '1'],\n        ['3', '1'],\n        ['4', '3'],\n        ['5', '3'],\n      ])\n\n      const disabled = new Set(['3'])\n\n      let selected = new Map()\n\n      selected = strategy.select({\n        id: '1',\n        value: true,\n        children,\n        parents,\n        disabled,\n        selected,\n      })\n\n      expect(selected.has('3')).toBe(false)\n\n      disabled.delete('3')\n      disabled.add('2')\n\n      selected = strategy.select({\n        id: '1',\n        value: true,\n        children,\n        parents,\n        disabled,\n        selected: new Map(),\n      })\n\n      expect(selected.has('2')).toBe(false)\n      expect(selected.has('3')).toBe(true)\n    })\n  })\n\n  describe('trunk', () => {\n    it('selects individual leaves', () => {\n      const strategy = trunkSelectStrategy(false)\n\n      const value = new Map([\n        ['1', 'indeterminate'],\n        ['2', 'on'],\n        ['3', 'indeterminate'],\n        ['4', 'on'],\n      ] as const)\n\n      const children = new Map([\n        ['1', ['2', '3']],\n        ['3', ['4', '5']],\n      ])\n\n      const parents = new Map([\n        ['2', '1'],\n        ['3', '1'],\n        ['4', '3'],\n        ['5', '3'],\n      ])\n\n      expect(strategy.out(value, children, parents)).toEqual(['2', '4'])\n    })\n\n    it('selects a parent node', () => {\n      const strategy = trunkSelectStrategy(false)\n\n      const value = new Map([\n        ['1', 'indeterminate'],\n        ['3', 'on'],\n        ['4', 'on'],\n        ['5', 'on'],\n      ] as const)\n\n      const children = new Map([\n        ['1', ['2', '3']],\n        ['3', ['4', '5']],\n      ])\n\n      const parents = new Map([\n        ['2', '1'],\n        ['3', '1'],\n        ['4', '3'],\n        ['5', '3'],\n      ])\n\n      expect(strategy.out(value, children, parents)).toEqual(['3'])\n    })\n  })\n\n  describe('branch', () => {\n    it('selects individual leaves', () => {\n      const strategy = branchSelectStrategy(false)\n\n      const value = new Map([\n        ['1', 'indeterminate'],\n        ['2', 'on'],\n        ['3', 'indeterminate'],\n        ['4', 'on'],\n      ] as const)\n\n      const children = new Map([\n        ['1', ['2', '3']],\n        ['3', ['4', '5']],\n      ])\n\n      const parents = new Map([\n        ['2', '1'],\n        ['3', '1'],\n        ['4', '3'],\n        ['5', '3'],\n      ])\n\n      expect(strategy.out(value, children, parents)).toEqual(['1', '2', '3', '4'])\n    })\n\n    it('selects a parent node', () => {\n      const strategy = branchSelectStrategy(false)\n\n      const value = new Map([\n        ['1', 'indeterminate'],\n        ['3', 'on'],\n        ['4', 'on'],\n        ['5', 'on'],\n      ] as const)\n\n      const children = new Map([\n        ['1', ['2', '3']],\n        ['3', ['4', '5']],\n      ])\n\n      const parents = new Map([\n        ['2', '1'],\n        ['3', '1'],\n        ['4', '3'],\n        ['5', '3'],\n      ])\n\n      expect(strategy.out(value, children, parents)).toEqual(['1', '3', '4', '5'])\n    })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/composables/nested/activeStrategies.ts",
    "content": "/* eslint-disable sonarjs/no-identical-functions */\n// Utilities\nimport { toRaw } from 'vue'\nimport { wrapInArray } from '@/util'\n\ntype ActiveStrategyFunction = (data: {\n  id: unknown\n  value: boolean\n  activated: Set<unknown>\n  children: Map<unknown, unknown[]>\n  parents: Map<unknown, unknown>\n  event?: Event\n}) => Set<unknown>\n\ntype ActiveStrategyTransformInFunction = (\n  v: unknown | undefined,\n  children: Map<unknown, unknown[]>,\n  parents: Map<unknown, unknown>,\n) => Set<unknown>\n\ntype ActiveStrategyTransformOutFunction = (\n  v: Set<unknown>,\n  children: Map<unknown, unknown[]>,\n  parents: Map<unknown, unknown>,\n) => unknown\n\nexport type ActiveStrategy = {\n  activate: ActiveStrategyFunction\n  in: ActiveStrategyTransformInFunction\n  out: ActiveStrategyTransformOutFunction\n}\n\nexport const independentActiveStrategy = (mandatory?: boolean): ActiveStrategy => {\n  const strategy: ActiveStrategy = {\n    activate: ({ id, value, activated }) => {\n      id = toRaw(id)\n\n      // When mandatory and we're trying to deselect when id\n      // is the only currently selected item then do nothing\n      if (mandatory && !value && activated.size === 1 && activated.has(id)) return activated\n\n      if (value) {\n        activated.add(id)\n      } else {\n        activated.delete(id)\n      }\n\n      return activated\n    },\n    in: (v, children, parents) => {\n      let set = new Set()\n\n      if (v != null) {\n        for (const id of wrapInArray(v)) {\n          set = strategy.activate({\n            id,\n            value: true,\n            activated: new Set(set),\n            children,\n            parents,\n          })\n        }\n      }\n\n      return set\n    },\n    out: v => {\n      return Array.from(v)\n    },\n  }\n\n  return strategy\n}\n\nexport const independentSingleActiveStrategy = (mandatory?: boolean): ActiveStrategy => {\n  const parentStrategy = independentActiveStrategy(mandatory)\n\n  const strategy: ActiveStrategy = {\n    activate: ({ activated, id, ...rest }) => {\n      id = toRaw(id)\n      const singleSelected = activated.has(id) ? new Set([id]) : new Set()\n      return parentStrategy.activate({ ...rest, id, activated: singleSelected })\n    },\n    in: (v, children, parents) => {\n      let set = new Set()\n\n      if (v != null) {\n        const arr = wrapInArray(v)\n        if (arr.length) {\n          set = parentStrategy.in(arr.slice(0, 1), children, parents)\n        }\n      }\n\n      return set\n    },\n    out: (v, children, parents) => {\n      return parentStrategy.out(v, children, parents)\n    },\n  }\n\n  return strategy\n}\n\nexport const leafActiveStrategy = (mandatory?: boolean): ActiveStrategy => {\n  const parentStrategy = independentActiveStrategy(mandatory)\n\n  const strategy: ActiveStrategy = {\n    activate: ({ id, activated, children, ...rest }) => {\n      id = toRaw(id)\n      if (children.has(id)) return activated\n\n      return parentStrategy.activate({ id, activated, children, ...rest })\n    },\n    in: parentStrategy.in,\n    out: parentStrategy.out,\n  }\n\n  return strategy\n}\n\nexport const leafSingleActiveStrategy = (mandatory?: boolean): ActiveStrategy => {\n  const parentStrategy = independentSingleActiveStrategy(mandatory)\n\n  const strategy: ActiveStrategy = {\n    activate: ({ id, activated, children, ...rest }) => {\n      id = toRaw(id)\n      if (children.has(id)) return activated\n\n      return parentStrategy.activate({ id, activated, children, ...rest })\n    },\n    in: parentStrategy.in,\n    out: parentStrategy.out,\n  }\n\n  return strategy\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/nested/nested.ts",
    "content": "// Composables\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport {\n  computed,\n  inject,\n  nextTick,\n  onBeforeMount,\n  onBeforeUnmount,\n  provide,\n  ref,\n  shallowRef,\n  toRaw,\n  toRef,\n  toValue,\n  watch,\n} from 'vue'\nimport {\n  independentActiveStrategy,\n  independentSingleActiveStrategy,\n  leafActiveStrategy,\n  leafSingleActiveStrategy,\n} from './activeStrategies'\nimport { listOpenStrategy, multipleOpenStrategy, singleOpenStrategy } from './openStrategies'\nimport {\n  branchSelectStrategy,\n  classicSelectStrategy,\n  independentSelectStrategy,\n  independentSingleSelectStrategy,\n  leafSelectStrategy,\n  leafSingleSelectStrategy,\n  trunkSelectStrategy,\n} from './selectStrategies'\nimport { consoleError, getCurrentInstance, propsFactory, throttle } from '@/util'\n\n// Types\nimport type { InjectionKey, MaybeRefOrGetter, PropType, Ref } from 'vue'\nimport type { ActiveStrategy } from './activeStrategies'\nimport type { OpenStrategy } from './openStrategies'\nimport type { SelectStrategy } from './selectStrategies'\nimport type { ListItem } from '@/composables/list-items'\nimport type { EventProp } from '@/util'\n\nexport type ActiveStrategyProp =\n  | 'single-leaf'\n  | 'leaf'\n  | 'independent'\n  | 'single-independent'\n  | ActiveStrategy\n  | ((mandatory: boolean) => ActiveStrategy)\nexport type SelectStrategyProp =\n  | 'single-leaf'\n  | 'leaf'\n  | 'independent'\n  | 'single-independent'\n  | 'classic'\n  | 'trunk'\n  | 'branch'\n  | SelectStrategy\n  | ((mandatory: boolean) => SelectStrategy)\nexport type OpenStrategyProp = 'single' | 'multiple' | 'list' | OpenStrategy\nexport type ItemsRegistrationType = 'props' | 'render'\n\nexport interface NestedProps {\n  activatable: boolean\n  selectable: boolean\n  activeStrategy: ActiveStrategyProp | undefined\n  selectStrategy: SelectStrategyProp | undefined\n  openStrategy: OpenStrategyProp | undefined\n  activated: any\n  selected: any\n  opened: any\n  mandatory: boolean\n  itemsRegistration: ItemsRegistrationType\n  'onUpdate:activated': EventProp<[any]> | undefined\n  'onUpdate:selected': EventProp<[any]> | undefined\n  'onUpdate:opened': EventProp<[any]> | undefined\n}\n\ntype NestedProvide = {\n  id: Ref<unknown>\n  isGroupActivator?: boolean\n  root: {\n    children: Ref<Map<unknown, unknown[]>>\n    parents: Ref<Map<unknown, unknown>>\n    disabled: Ref<Set<unknown>>\n    activatable: Ref<boolean>\n    selectable: Ref<boolean>\n    opened: Ref<Set<unknown>>\n    activated: Ref<Set<unknown>>\n    scrollToActive: Ref<boolean>\n    selected: Ref<Map<unknown, 'on' | 'off' | 'indeterminate'>>\n    selectedValues: Ref<unknown[]>\n    itemsRegistration: Ref<ItemsRegistrationType>\n    register: (id: unknown, parentId: unknown, isDisabled: boolean, isGroup?: boolean) => void\n    unregister: (id: unknown) => void\n    updateDisabled: (id: unknown, isDisabled: boolean) => void\n    open: (id: unknown, value: boolean, event?: Event) => void\n    activate: (id: unknown, value: boolean, event?: Event) => void\n    select: (id: unknown, value: boolean, event?: Event) => void\n    openOnSelect: (id: unknown, value: boolean, event?: Event) => void\n    getPath: (id: unknown) => unknown[]\n  }\n}\n\nexport const VNestedSymbol: InjectionKey<NestedProvide> = Symbol.for('vuetify:nested')\n\nexport const emptyNested: NestedProvide = {\n  id: shallowRef(),\n  root: {\n    itemsRegistration: ref('render'),\n    register: () => null,\n    unregister: () => null,\n    updateDisabled: () => null,\n    children: ref(new Map()),\n    parents: ref(new Map()),\n    disabled: ref(new Set()),\n    open: () => null,\n    openOnSelect: () => null,\n    activate: () => null,\n    select: () => null,\n    activatable: ref(false),\n    scrollToActive: ref(false),\n    selectable: ref(false),\n    opened: ref(new Set()),\n    activated: ref(new Set()),\n    selected: ref(new Map()),\n    selectedValues: ref([]),\n    getPath: () => [],\n  },\n}\n\nexport const makeNestedProps = propsFactory({\n  activatable: Boolean,\n  selectable: Boolean,\n  activeStrategy: [String, Function, Object] as PropType<ActiveStrategyProp>,\n  selectStrategy: [String, Function, Object] as PropType<SelectStrategyProp>,\n  openStrategy: [String, Object] as PropType<OpenStrategyProp>,\n  opened: null,\n  activated: null,\n  selected: null,\n  mandatory: Boolean,\n  itemsRegistration: {\n    type: String as PropType<ItemsRegistrationType>,\n    default: 'render',\n  },\n}, 'nested')\n\nexport const useNested = (\n  props: NestedProps,\n  {\n    items,\n    returnObject,\n    scrollToActive,\n  }: {\n    items: Ref<ListItem[]>\n    returnObject: MaybeRefOrGetter<boolean>\n    scrollToActive: MaybeRefOrGetter<boolean>\n  },\n) => {\n  let isUnmounted = false\n  const children = shallowRef(new Map<unknown, unknown[]>())\n  const parents = shallowRef(new Map<unknown, unknown>())\n  const disabled = shallowRef(new Set<unknown>())\n\n  const opened = useProxiedModel(\n    props,\n    'opened',\n    props.opened,\n    v => new Set(Array.isArray(v) ? v.map(i => toRaw(i)) : v),\n    v => [...v.values()],\n  )\n\n  const activeStrategy = computed(() => {\n    if (typeof props.activeStrategy === 'object') return props.activeStrategy\n    if (typeof props.activeStrategy === 'function') return props.activeStrategy(props.mandatory)\n\n    switch (props.activeStrategy) {\n      case 'leaf': return leafActiveStrategy(props.mandatory)\n      case 'single-leaf': return leafSingleActiveStrategy(props.mandatory)\n      case 'independent': return independentActiveStrategy(props.mandatory)\n      case 'single-independent':\n      default: return independentSingleActiveStrategy(props.mandatory)\n    }\n  })\n\n  const selectStrategy = computed(() => {\n    if (typeof props.selectStrategy === 'object') return props.selectStrategy\n    if (typeof props.selectStrategy === 'function') return props.selectStrategy(props.mandatory)\n\n    switch (props.selectStrategy) {\n      case 'single-leaf': return leafSingleSelectStrategy(props.mandatory)\n      case 'leaf': return leafSelectStrategy(props.mandatory)\n      case 'independent': return independentSelectStrategy(props.mandatory)\n      case 'single-independent': return independentSingleSelectStrategy(props.mandatory)\n      case 'trunk': return trunkSelectStrategy(props.mandatory)\n      case 'branch': return branchSelectStrategy(props.mandatory)\n      case 'classic':\n      default: return classicSelectStrategy(props.mandatory)\n    }\n  })\n\n  const openStrategy = computed(() => {\n    if (typeof props.openStrategy === 'object') return props.openStrategy\n\n    switch (props.openStrategy) {\n      case 'list': return listOpenStrategy\n      case 'single': return singleOpenStrategy\n      case 'multiple':\n      default: return multipleOpenStrategy\n    }\n  })\n\n  const activated = useProxiedModel(\n    props,\n    'activated',\n    props.activated,\n    v => activeStrategy.value.in(v, children.value, parents.value),\n    v => activeStrategy.value.out(v, children.value, parents.value),\n  )\n  const selected = useProxiedModel(\n    props,\n    'selected',\n    props.selected,\n    v => selectStrategy.value.in(v, children.value, parents.value, disabled.value),\n    v => selectStrategy.value.out(v, children.value, parents.value),\n  )\n\n  onBeforeUnmount(() => {\n    isUnmounted = true\n  })\n\n  function getPath (id: unknown) {\n    const path: unknown[] = []\n    let parent: unknown = toRaw(id)\n\n    while (parent !== undefined) {\n      path.unshift(parent)\n      parent = parents.value.get(parent)\n    }\n\n    return path\n  }\n\n  const vm = getCurrentInstance('nested')\n\n  const nodeIds = new Set<unknown>()\n\n  const itemsUpdatePropagation = throttle(() => {\n    nextTick(() => {\n      children.value = new Map(children.value)\n      parents.value = new Map(parents.value)\n    })\n  }, 100)\n\n  watch(() => [items.value, toValue(returnObject)], () => {\n    if (props.itemsRegistration === 'props') {\n      updateInternalMaps()\n    }\n  }, { immediate: true })\n\n  function updateInternalMaps () {\n    const _parents = new Map()\n    const _children = new Map()\n    const _disabled = new Set()\n\n    const getValue = toValue(returnObject)\n      ? (item: ListItem) => toRaw(item.raw)\n      : (item: ListItem) => item.value\n\n    const stack = [...items.value]\n    let i = 0\n    while (i < stack.length) {\n      const item = stack[i++]\n      const itemValue = getValue(item)\n\n      if (item.children) {\n        const childValues = []\n        for (const child of item.children) {\n          const childValue = getValue(child)\n          _parents.set(childValue, itemValue)\n          childValues.push(childValue)\n          stack.push(child)\n        }\n        _children.set(itemValue, childValues)\n      }\n\n      if (item.props.disabled) {\n        _disabled.add(itemValue)\n      }\n    }\n\n    children.value = _children\n    parents.value = _parents\n    disabled.value = _disabled\n  }\n\n  const nested: NestedProvide = {\n    id: shallowRef(),\n    root: {\n      opened,\n      activatable: toRef(() => props.activatable),\n      scrollToActive: toRef(() => toValue(scrollToActive)),\n      selectable: toRef(() => props.selectable),\n      activated,\n      selected,\n      selectedValues: computed(() => {\n        const arr = []\n\n        for (const [key, value] of selected.value.entries()) {\n          if (value === 'on') arr.push(key)\n        }\n\n        return arr\n      }),\n      itemsRegistration: toRef(() => props.itemsRegistration),\n      register: (id, parentId, isDisabled, isGroup) => {\n        if (nodeIds.has(id)) {\n          const path = getPath(id).map(String).join(' -> ')\n          const newPath = getPath(parentId).concat(id).map(String).join(' -> ')\n          consoleError(`Multiple nodes with the same ID\\n\\t${path}\\n\\t${newPath}`)\n          return\n        } else {\n          nodeIds.add(id)\n        }\n\n        parentId && id !== parentId && parents.value.set(id, parentId)\n\n        isDisabled && disabled.value.add(id)\n        isGroup && children.value.set(id, [])\n\n        if (parentId != null) {\n          children.value.set(parentId, [...children.value.get(parentId) || [], id])\n        }\n        itemsUpdatePropagation()\n      },\n      unregister: id => {\n        if (isUnmounted) return\n\n        nodeIds.delete(id)\n        children.value.delete(id)\n        disabled.value.delete(id)\n        const parent = parents.value.get(id)\n        if (parent) {\n          const list = children.value.get(parent) ?? []\n          children.value.set(parent, list.filter(child => child !== id))\n        }\n        parents.value.delete(id)\n        itemsUpdatePropagation()\n      },\n      updateDisabled: (id, isDisabled) => {\n        if (isDisabled) {\n          disabled.value.add(id)\n        } else {\n          disabled.value.delete(id)\n        }\n        // classic selection requires refresh to re-evaluate on/off/indeterminate but\n        // currently it is only run for selection interactions, so it will set new disabled\n        // to \"off\" and the visual state becomes out of sync\n        // -- selected.value = new Map(selected.value)\n        // it is not clear if the framework should un-select when disabled changed to true\n        // more discussion is needed\n      },\n      open: (id, value, event) => {\n        vm.emit('click:open', { id, value, path: getPath(id), event })\n\n        const newOpened = openStrategy.value.open({\n          id,\n          value,\n          opened: new Set(opened.value),\n          children: children.value,\n          parents: parents.value,\n          event,\n        })\n\n        newOpened && (opened.value = newOpened)\n      },\n      openOnSelect: (id, value, event) => {\n        const newOpened = openStrategy.value.select({\n          id,\n          value,\n          selected: new Map(selected.value),\n          opened: new Set(opened.value),\n          children: children.value,\n          parents: parents.value,\n          event,\n        })\n        newOpened && (opened.value = newOpened)\n      },\n      select: (id, value, event) => {\n        vm.emit('click:select', { id, value, path: getPath(id), event })\n\n        const newSelected = selectStrategy.value.select({\n          id,\n          value,\n          selected: new Map(selected.value),\n          children: children.value,\n          parents: parents.value,\n          disabled: disabled.value,\n          event,\n        })\n        newSelected && (selected.value = newSelected)\n\n        nested.root.openOnSelect(id, value, event)\n      },\n      activate: (id, value, event) => {\n        if (!props.activatable) {\n          return nested.root.select(id, true, event)\n        }\n\n        vm.emit('click:activate', { id, value, path: getPath(id), event })\n\n        const newActivated = activeStrategy.value.activate({\n          id,\n          value,\n          activated: new Set(activated.value),\n          children: children.value,\n          parents: parents.value,\n          event,\n        })\n\n        if (newActivated.size !== activated.value.size) {\n          activated.value = newActivated\n        } else {\n          for (const value of newActivated) {\n            if (!activated.value.has(value)) {\n              activated.value = newActivated\n              return\n            }\n          }\n          for (const value of activated.value) {\n            if (!newActivated.has(value)) {\n              activated.value = newActivated\n              return\n            }\n          }\n        }\n      },\n      children,\n      parents,\n      disabled,\n      getPath,\n    },\n  }\n\n  provide(VNestedSymbol, nested)\n\n  return nested.root\n}\n\nexport const useNestedItem = (id: MaybeRefOrGetter<unknown>, isDisabled: MaybeRefOrGetter<boolean>, isGroup: boolean) => {\n  const parent = inject(VNestedSymbol, emptyNested)\n\n  const uidSymbol = Symbol('nested item')\n  const computedId = computed(() => {\n    const idValue = toRaw(toValue(id))\n    return idValue !== undefined ? idValue : uidSymbol\n  })\n\n  const item = {\n    ...parent,\n    id: computedId,\n    open: (open: boolean, e: Event) => parent.root.open(computedId.value, open, e),\n    openOnSelect: (open: boolean, e?: Event) => parent.root.openOnSelect(computedId.value, open, e),\n    isOpen: computed(() => parent.root.opened.value.has(computedId.value)),\n    parent: computed(() => parent.root.parents.value.get(computedId.value)),\n    activate: (activated: boolean, e?: Event) => parent.root.activate(computedId.value, activated, e),\n    isActivated: computed(() => parent.root.activated.value.has(computedId.value)),\n    scrollToActive: parent.root.scrollToActive,\n    select: (selected: boolean, e?: Event) => parent.root.select(computedId.value, selected, e),\n    isSelected: computed(() => parent.root.selected.value.get(computedId.value) === 'on'),\n    isIndeterminate: computed(() => parent.root.selected.value.get(computedId.value) === 'indeterminate'),\n    isLeaf: computed(() => !parent.root.children.value.get(computedId.value)),\n    isGroupActivator: parent.isGroupActivator,\n  }\n\n  onBeforeMount(() => {\n    if (parent.isGroupActivator || parent.root.itemsRegistration.value === 'props') return\n    nextTick(() => {\n      parent.root.register(computedId.value, parent.id.value, toValue(isDisabled), isGroup)\n    })\n  })\n\n  onBeforeUnmount(() => {\n    if (parent.isGroupActivator || parent.root.itemsRegistration.value === 'props') return\n    parent.root.unregister(computedId.value)\n  })\n\n  watch(computedId, (val, oldVal) => {\n    if (parent.isGroupActivator || parent.root.itemsRegistration.value === 'props') return\n    parent.root.unregister(oldVal)\n    nextTick(() => {\n      parent.root.register(val, parent.id.value, toValue(isDisabled), isGroup)\n    })\n  })\n\n  watch(() => toValue(isDisabled), val => {\n    parent.root.updateDisabled(computedId.value, val)\n  })\n\n  isGroup && provide(VNestedSymbol, item)\n\n  return item\n}\n\nexport const useNestedGroupActivator = () => {\n  const parent = inject(VNestedSymbol, emptyNested)\n\n  provide(VNestedSymbol, { ...parent, isGroupActivator: true })\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/nested/openStrategies.ts",
    "content": "type OpenStrategyFunction = (data: {\n  id: unknown\n  value: boolean\n  opened: Set<unknown>\n  children: Map<unknown, unknown[]>\n  parents: Map<unknown, unknown>\n  event?: Event\n}) => Set<unknown>\n\ntype OpenSelectStrategyFunction = (data: {\n  id: unknown\n  value: boolean\n  opened: Set<unknown>\n  selected: Map<unknown, 'on' | 'off' | 'indeterminate'>\n  children: Map<unknown, unknown[]>\n  parents: Map<unknown, unknown>\n  event?: Event\n}) => Set<unknown> | null\n\nexport type OpenStrategy = {\n  open: OpenStrategyFunction\n  select: OpenSelectStrategyFunction\n}\n\nexport const singleOpenStrategy: OpenStrategy = {\n  open: ({ id, value, opened, parents }) => {\n    if (value) {\n      const newOpened = new Set<unknown>()\n      newOpened.add(id)\n\n      let parent = parents.get(id)\n\n      while (parent != null) {\n        newOpened.add(parent)\n        parent = parents.get(parent)\n      }\n\n      return newOpened\n    } else {\n      opened.delete(id)\n      return opened\n    }\n  },\n  select: () => null,\n}\n\nexport const multipleOpenStrategy: OpenStrategy = {\n  open: ({ id, value, opened, parents }) => {\n    if (value) {\n      let parent = parents.get(id)\n      opened.add(id)\n\n      while (parent != null && parent !== id) {\n        opened.add(parent)\n        parent = parents.get(parent)\n      }\n\n      return opened\n    } else {\n      opened.delete(id)\n    }\n    return opened\n  },\n  select: () => null,\n}\n\nexport const listOpenStrategy: OpenStrategy = {\n  open: multipleOpenStrategy.open,\n  select: ({ id, value, opened, parents }) => {\n    if (!value) return opened\n\n    const path: unknown[] = []\n\n    let parent = parents.get(id)\n\n    while (parent != null) {\n      path.push(parent)\n      parent = parents.get(parent)\n    }\n\n    return new Set(path)\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/nested/selectStrategies.ts",
    "content": "/* eslint-disable sonarjs/no-identical-functions */\n// Utilities\nimport { toRaw } from 'vue'\n\ntype SelectStrategyFunction = (data: {\n  id: unknown\n  value: boolean\n  selected: Map<unknown, 'on' | 'off' | 'indeterminate'>\n  children: Map<unknown, unknown[]>\n  parents: Map<unknown, unknown>\n  disabled: Set<unknown>\n  event?: Event\n}) => Map<unknown, 'on' | 'off' | 'indeterminate'>\n\ntype SelectStrategyTransformInFunction = (\n  v: readonly unknown[] | undefined,\n  children: Map<unknown, unknown[]>,\n  parents: Map<unknown, unknown>,\n  disabled: Set<unknown>,\n) => Map<unknown, 'on' | 'off' | 'indeterminate'>\n\ntype SelectStrategyTransformOutFunction = (\n  v: Map<unknown, 'on' | 'off' | 'indeterminate'>,\n  children: Map<unknown, unknown[]>,\n  parents: Map<unknown, unknown>,\n) => unknown[]\n\nexport type SelectStrategy = {\n  select: SelectStrategyFunction\n  in: SelectStrategyTransformInFunction\n  out: SelectStrategyTransformOutFunction\n}\n\nexport const independentSelectStrategy = (mandatory?: boolean): SelectStrategy => {\n  const strategy: SelectStrategy = {\n    select: ({ id, value, selected }) => {\n      id = toRaw(id)\n\n      // When mandatory and we're trying to deselect when id\n      // is the only currently selected item then do nothing\n      if (mandatory && !value) {\n        const on = Array.from(selected.entries())\n          .reduce((arr, [key, value]) => {\n            if (value === 'on') arr.push(key)\n            return arr\n          }, [] as unknown[])\n        if (on.length === 1 && on[0] === id) return selected\n      }\n\n      selected.set(id, value ? 'on' : 'off')\n\n      return selected\n    },\n    in: (v, children, parents, disabled) => {\n      const map = new Map()\n\n      for (const id of (v || [])) {\n        strategy.select({\n          id,\n          value: true,\n          selected: map,\n          children,\n          parents,\n          disabled,\n        })\n      }\n\n      return map\n    },\n    out: v => {\n      const arr = []\n\n      for (const [key, value] of v.entries()) {\n        if (value === 'on') arr.push(key)\n      }\n\n      return arr\n    },\n  }\n\n  return strategy\n}\n\nexport const independentSingleSelectStrategy = (mandatory?: boolean): SelectStrategy => {\n  const parentStrategy = independentSelectStrategy(mandatory)\n\n  const strategy: SelectStrategy = {\n    select: ({ selected, id, ...rest }) => {\n      id = toRaw(id)\n      const singleSelected = selected.has(id) ? new Map([[id, selected.get(id)!]]) : new Map()\n      return parentStrategy.select({ ...rest, id, selected: singleSelected })\n    },\n    in: (v, children, parents, disabled) => {\n      if (v?.length) {\n        return parentStrategy.in(v.slice(0, 1), children, parents, disabled)\n      }\n\n      return new Map()\n    },\n    out: (v, children, parents) => {\n      return parentStrategy.out(v, children, parents)\n    },\n  }\n\n  return strategy\n}\n\nexport const leafSelectStrategy = (mandatory?: boolean): SelectStrategy => {\n  const parentStrategy = independentSelectStrategy(mandatory)\n\n  const strategy: SelectStrategy = {\n    select: ({ id, selected, children, ...rest }) => {\n      id = toRaw(id)\n      if (children.has(id)) return selected\n\n      return parentStrategy.select({ id, selected, children, ...rest })\n    },\n    in: parentStrategy.in,\n    out: parentStrategy.out,\n  }\n\n  return strategy\n}\n\nexport const leafSingleSelectStrategy = (mandatory?: boolean): SelectStrategy => {\n  const parentStrategy = independentSingleSelectStrategy(mandatory)\n\n  const strategy: SelectStrategy = {\n    select: ({ id, selected, children, ...rest }) => {\n      id = toRaw(id)\n      if (children.has(id)) return selected\n\n      return parentStrategy.select({ id, selected, children, ...rest })\n    },\n    in: parentStrategy.in,\n    out: parentStrategy.out,\n  }\n\n  return strategy\n}\n\nexport const classicSelectStrategy = (mandatory?: boolean): SelectStrategy => {\n  const strategy: SelectStrategy = {\n    select: ({ id, value, selected, children, parents, disabled }) => {\n      id = toRaw(id)\n      const original = new Map(selected)\n\n      const items = [id]\n\n      while (items.length) {\n        const item = items.shift()!\n\n        if (!disabled.has(item)) {\n          selected.set(toRaw(item), value ? 'on' : 'off')\n        }\n\n        if (children.has(item)) {\n          items.push(...children.get(item)!)\n        }\n      }\n\n      let parent = toRaw(parents.get(id))\n\n      while (parent) {\n        let everySelected = true\n        let noneSelected = true\n\n        for (const child of children.get(parent)!) {\n          const cid = toRaw(child)\n\n          if (disabled.has(cid)) continue\n          if (selected.get(cid) !== 'on') everySelected = false\n          if (selected.has(cid) && selected.get(cid) !== 'off') noneSelected = false\n          if (!everySelected && !noneSelected) break\n        }\n\n        selected.set(parent, everySelected ? 'on' : noneSelected ? 'off' : 'indeterminate')\n\n        parent = toRaw(parents.get(parent))\n      }\n\n      // If mandatory and planned deselect results in no selected\n      // items then we can't do it, so return original state\n      if (mandatory && !value) {\n        const on = Array.from(selected.entries())\n          .reduce((arr, [key, value]) => {\n            if (value === 'on') arr.push(key)\n            return arr\n          }, [] as unknown[])\n        if (on.length === 0) return original\n      }\n\n      return selected\n    },\n    in: (v, children, parents) => {\n      let map = new Map()\n\n      for (const id of (v || [])) {\n        map = strategy.select({\n          id,\n          value: true,\n          selected: map,\n          children,\n          parents,\n          disabled: new Set<unknown>(),\n        })\n      }\n\n      return map\n    },\n    out: (v, children) => {\n      const arr = []\n\n      for (const [key, value] of v.entries()) {\n        if (value === 'on' && !children.has(key)) arr.push(key)\n      }\n\n      return arr\n    },\n  }\n\n  return strategy\n}\n\nexport const trunkSelectStrategy = (mandatory?: boolean): SelectStrategy => {\n  const parentStrategy = classicSelectStrategy(mandatory)\n\n  const strategy: SelectStrategy = {\n    select: parentStrategy.select,\n    in: parentStrategy.in,\n    out: (v, children, parents) => {\n      const arr = []\n\n      for (const [key, value] of v.entries()) {\n        if (value === 'on') {\n          if (parents.has(key)) {\n            const parent = parents.get(key)\n            if (v.get(parent) === 'on') continue\n          }\n          arr.push(key)\n        }\n      }\n\n      return arr\n    },\n  }\n\n  return strategy\n}\n\nexport const branchSelectStrategy = (mandatory?: boolean): SelectStrategy => {\n  const parentStrategy = classicSelectStrategy(mandatory)\n\n  const strategy: SelectStrategy = {\n    select: parentStrategy.select,\n    in: (v, children, parents, disabled) => {\n      let map = new Map()\n\n      for (const id of (v || [])) {\n        if (children.has(id)) continue\n        map = strategy.select({\n          id,\n          value: true,\n          selected: map,\n          children,\n          parents,\n          disabled,\n        })\n      }\n\n      return map\n    },\n    out: v => {\n      const arr = []\n\n      for (const [key, value] of v.entries()) {\n        if (value === 'on' || value === 'indeterminate') {\n          arr.push(key)\n        }\n      }\n\n      return arr\n    },\n  }\n\n  return strategy\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/position.ts",
    "content": "// Utilities\nimport { toRef } from 'vue'\nimport { getCurrentInstanceName, propsFactory } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\nconst positionValues = ['static', 'relative', 'fixed', 'absolute', 'sticky'] as const\n\ntype Position = typeof positionValues[number]\n\nexport interface PositionProps {\n  position: Position | undefined\n}\n\n// Composables\nexport const makePositionProps = propsFactory({\n  position: {\n    type: String as PropType<Position>,\n    validator: /* istanbul ignore next */ (v: any) => positionValues.includes(v),\n  },\n}, 'position')\n\nexport function usePosition (\n  props: PositionProps,\n  name = getCurrentInstanceName(),\n) {\n  const positionClasses = toRef(() => {\n    return props.position ? `${name}--${props.position}` : undefined\n  })\n\n  return { positionClasses }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/proxiedModel.ts",
    "content": "// Composables\nimport { useToggleScope } from '@/composables/toggleScope'\n\n// Utilities\nimport { computed, ref, toRaw, watch } from 'vue'\nimport { getCurrentInstance, toKebabCase } from '@/util'\n\n// Types\nimport type { Ref } from 'vue'\nimport type { EventProp } from '@/util'\n\ntype InnerVal<T> = T extends any[] ? Readonly<T> : T\n\n// Composables\nexport function useProxiedModel<\n  Props extends object & { [key in Prop as `onUpdate:${Prop}`]: EventProp | undefined },\n  Prop extends Extract<keyof Props, string>,\n  Inner = Props[Prop],\n> (\n  props: Props,\n  prop: Prop,\n  defaultValue?: Props[Prop],\n  transformIn: (value?: Props[Prop]) => Inner = (v: any) => v,\n  transformOut: (value: Inner) => Props[Prop] = (v: any) => v,\n) {\n  const vm = getCurrentInstance('useProxiedModel')\n  const internal = ref(props[prop] !== undefined ? props[prop] : defaultValue) as Ref<Props[Prop]>\n  const kebabProp = toKebabCase(prop)\n  const checkKebab = kebabProp !== prop\n\n  const isControlled = checkKebab\n    ? computed(() => {\n      void props[prop]\n      return !!(\n        (vm.vnode.props?.hasOwnProperty(prop) || vm.vnode.props?.hasOwnProperty(kebabProp)) &&\n        (vm.vnode.props?.hasOwnProperty(`onUpdate:${prop}`) || vm.vnode.props?.hasOwnProperty(`onUpdate:${kebabProp}`))\n      )\n    })\n    : computed(() => {\n      void props[prop]\n      return !!(vm.vnode.props?.hasOwnProperty(prop) && vm.vnode.props?.hasOwnProperty(`onUpdate:${prop}`))\n    })\n\n  useToggleScope(() => !isControlled.value, () => {\n    watch(() => props[prop], val => {\n      internal.value = val\n    })\n  })\n\n  const model = computed({\n    get (): any {\n      const externalValue = props[prop]\n      return transformIn(isControlled.value ? externalValue : internal.value)\n    },\n    set (internalValue) {\n      const newValue = transformOut(internalValue)\n      const value = toRaw(isControlled.value ? props[prop] : internal.value)\n      if (value === newValue || transformIn(value) === internalValue) {\n        return\n      }\n      internal.value = newValue\n      vm?.emit(`update:${prop}`, newValue)\n    },\n  }) as any as Ref<InnerVal<Inner>> & { readonly externalValue: Props[Prop] }\n\n  Object.defineProperty(model, 'externalValue', {\n    get: () => isControlled.value ? props[prop] : internal.value,\n  })\n\n  return model\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/refs.ts",
    "content": "// Utilities\nimport { onBeforeUpdate, ref } from 'vue'\n\n// Types\nimport type { Ref } from 'vue'\n\nexport function useRefs <T extends {}> () {\n  const refs = ref<(T | undefined)[]>([]) as Ref<(T | undefined)[]>\n\n  onBeforeUpdate(() => (refs.value = []))\n\n  function updateRef (e: any, i: number) {\n    refs.value[i] = e\n  }\n\n  return { refs, updateRef }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/resizeObserver.ts",
    "content": "// Utilities\nimport { onBeforeUnmount, readonly, ref, watch } from 'vue'\nimport { templateRef } from '@/util'\nimport { IN_BROWSER } from '@/util/globals'\n\n// Types\nimport type { DeepReadonly, Ref } from 'vue'\nimport type { TemplateRef } from '@/util'\n\ninterface ResizeState {\n  resizeRef: TemplateRef\n  contentRect: DeepReadonly<Ref<DOMRectReadOnly | undefined>>\n}\n\nexport function useResizeObserver (callback?: ResizeObserverCallback, box: 'content' | 'border' = 'content'): ResizeState {\n  const resizeRef = templateRef()\n  const contentRect = ref<DOMRectReadOnly>()\n\n  if (IN_BROWSER) {\n    const observer = new ResizeObserver((entries: ResizeObserverEntry[]) => {\n      callback?.(entries, observer)\n\n      if (!entries.length) return\n\n      if (box === 'content') {\n        contentRect.value = entries[0].contentRect\n      } else {\n        contentRect.value = entries[0].target.getBoundingClientRect()\n      }\n    })\n\n    onBeforeUnmount(() => {\n      observer.disconnect()\n    })\n\n    watch(() => resizeRef.el, (newValue, oldValue) => {\n      if (oldValue) {\n        observer.unobserve(oldValue)\n        contentRect.value = undefined\n      }\n\n      if (newValue) observer.observe(newValue)\n    }, {\n      flush: 'post',\n    })\n  }\n\n  return {\n    resizeRef,\n    contentRect: readonly(contentRect),\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/reveal.ts",
    "content": "// Utilities\nimport { onMounted, shallowRef, toRef } from 'vue'\nimport { propsFactory } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\n// Types\nexport interface RevealProps {\n  reveal: boolean | { duration?: number }\n}\n\n// Composables\nexport const makeRevealProps = propsFactory({\n  reveal: {\n    type: [Boolean, Object] as PropType<boolean | {\n      duration?: number\n    }>,\n    default: false,\n  },\n}, 'reveal')\n\nexport function useReveal (props: RevealProps) {\n  const defaultDuration = 900\n  const duration = toRef(() => typeof props.reveal === 'object'\n    ? Math.max(0, Number(props.reveal.duration ?? defaultDuration))\n    : defaultDuration\n  )\n\n  const state = shallowRef(props.reveal ? 'initial' : 'disabled')\n\n  onMounted(async () => {\n    if (props.reveal) {\n      state.value = 'initial'\n      await new Promise(resolve => requestAnimationFrame(resolve))\n      state.value = 'pending'\n      await new Promise(resolve => setTimeout(resolve, duration.value))\n      state.value = 'done'\n    }\n  })\n\n  return {\n    duration,\n    state,\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/rounded.ts",
    "content": "// Utilities\nimport { computed, isRef } from 'vue'\nimport { getCurrentInstanceName, propsFactory } from '@/util'\n\n// Types\nimport type { Ref } from 'vue'\n\ntype RoundedValue = boolean | string | number | null | undefined\n\nexport interface RoundedProps {\n  rounded?: RoundedValue\n  tile?: boolean\n}\n\ntype RoundedData = {\n  roundedClasses: Ref<string[]>\n}\n\n// Composables\nexport const makeRoundedProps = propsFactory({\n  rounded: {\n    type: [Boolean, Number, String],\n    default: undefined,\n  },\n  tile: Boolean,\n}, 'rounded')\n\nexport function useRounded (\n  props: RoundedProps | Ref<RoundedValue>,\n  name = getCurrentInstanceName(),\n): RoundedData {\n  const roundedClasses = computed(() => {\n    const rounded = isRef(props) ? props.value : props.rounded\n    const tile = isRef(props) ? false : props.tile\n    const classes: string[] = []\n\n    if (tile || rounded === false) {\n      classes.push('rounded-0')\n    } else if (rounded === true || rounded === '') {\n      classes.push(`${name}--rounded`)\n    } else if (typeof rounded === 'string' || rounded === 0) {\n      for (const value of String(rounded).split(' ')) {\n        classes.push(`rounded-${value}`)\n      }\n    }\n\n    return classes\n  })\n\n  return { roundedClasses }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/router.tsx",
    "content": "// Utilities\nimport {\n  computed,\n  nextTick,\n  onScopeDispose, reactive,\n  resolveDynamicComponent,\n  toRef,\n} from 'vue'\nimport { deepEqual, getCurrentInstance, hasEvent, IN_BROWSER, propsFactory } from '@/util'\n\n// Types\nimport type { PropType, Ref, SetupContext } from 'vue'\nimport type {\n  RouterLink as _RouterLink,\n  useLink as _useLink,\n  NavigationGuardReturn,\n  RouteLocation,\n  RouteLocationNormalizedLoaded,\n  RouteLocationRaw,\n  Router,\n} from 'vue-router'\nimport type { EventProp } from '@/util'\n\nexport function useRoute (): Ref<RouteLocationNormalizedLoaded | undefined> {\n  const vm = getCurrentInstance('useRoute')\n\n  return computed(() => vm?.proxy?.$route)\n}\n\nexport function useRouter (): Router | undefined {\n  return getCurrentInstance('useRouter')?.proxy?.$router\n}\n\nexport interface LinkProps {\n  href: string | undefined\n  replace: boolean | undefined\n  to: RouteLocationRaw | undefined\n  exact: boolean | undefined\n  disabled: boolean | undefined\n}\n\nexport interface LinkListeners {\n  onClick?: EventProp | undefined\n  onClickOnce?: EventProp | undefined\n}\n\nexport interface UseLink extends Omit<Partial<ReturnType<typeof _useLink>>, 'href'|'route'|'navigate'> {\n  isLink: Readonly<Ref<boolean>>\n  isRouterLink: Readonly<Ref<boolean>>\n  isClickable: Readonly<Ref<boolean>>\n  href: Ref<string | undefined>\n  linkProps: Record<string, string | undefined>\n  route: Readonly<Ref<RouteLocation & { href: string} | undefined>>\n  navigate: Readonly<Ref<ReturnType<typeof _useLink>['navigate'] | undefined>>\n}\n\nexport function useLink (props: LinkProps & LinkListeners, attrs: SetupContext['attrs']): UseLink {\n  const RouterLink = resolveDynamicComponent('RouterLink') as typeof _RouterLink | string\n\n  const isLink = toRef(() => !!(props.href || props.to))\n  const isClickable = computed(() => {\n    return isLink?.value || hasEvent(attrs, 'click') || hasEvent(props, 'click')\n  })\n\n  if (typeof RouterLink === 'string' || !('useLink' in RouterLink)) {\n    const href = toRef(() => props.href)\n    return {\n      isLink,\n      isRouterLink: toRef(() => false),\n      isClickable,\n      href,\n      linkProps: reactive({ href }),\n      route: toRef(() => undefined),\n      navigate: toRef(() => undefined),\n    }\n  }\n\n  // vue-router useLink `to` prop needs to be reactive and useLink will crash if undefined\n  const routerLink = RouterLink.useLink({\n    to: toRef(() => props.to || ''),\n    replace: toRef(() => props.replace),\n  })\n  // Actual link needs to be undefined when to prop is not used\n  const link = computed(() => props.to ? routerLink : undefined)\n  const route = useRoute()\n  const isActive = computed(() => {\n    if (!link.value) return false\n    if (!props.exact) return link.value.isActive?.value ?? false\n    if (!route.value) return link.value.isExactActive?.value ?? false\n\n    return link.value.isExactActive?.value && deepEqual(link.value.route.value.query, route.value.query)\n  })\n  const href = computed(() => props.to ? link.value?.route.value.href : props.href)\n  const isRouterLink = toRef(() => !!props.to)\n\n  return {\n    isLink,\n    isRouterLink,\n    isClickable,\n    isActive,\n    route: toRef(() => link.value?.route.value),\n    navigate: toRef(() => link.value?.navigate),\n    href,\n    linkProps: reactive({\n      href,\n      'aria-current': toRef(() => isActive.value ? 'page' : undefined),\n      'aria-disabled': toRef(() => props.disabled && isLink.value ? 'true' : undefined),\n      tabindex: toRef(() => props.disabled && isLink.value ? '-1' : undefined),\n    }),\n  }\n}\n\nexport const makeRouterProps = propsFactory({\n  href: String,\n  replace: Boolean,\n  to: [String, Object] as PropType<RouteLocationRaw>,\n  exact: Boolean,\n}, 'router')\n\nlet inTransition = false\nexport function useBackButton (router: Router | undefined, cb: () => NavigationGuardReturn) {\n  let popped = false\n  let removeBefore: (() => void) | undefined\n  let removeAfter: (() => void) | undefined\n\n  if (IN_BROWSER && router?.beforeEach) {\n    nextTick(() => {\n      window.addEventListener('popstate', onPopstate)\n      removeBefore = router.beforeEach(() => {\n        if (!inTransition) {\n          inTransition = true\n          return new Promise<NavigationGuardReturn>(resolve => {\n            setTimeout(() => resolve(popped ? cb() : undefined))\n          })\n        }\n        return popped ? cb() : undefined\n      })\n      removeAfter = router?.afterEach(() => {\n        inTransition = false\n      })\n    })\n    onScopeDispose(() => {\n      window.removeEventListener('popstate', onPopstate)\n      removeBefore?.()\n      removeAfter?.()\n    })\n  }\n\n  function onPopstate (e: PopStateEvent) {\n    if (e.state?.replaced) return\n\n    popped = true\n    setTimeout(() => (popped = false))\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/scopeId.ts",
    "content": "// Utilities\nimport { getCurrentInstance } from '@/util'\n\nexport function useScopeId () {\n  const vm = getCurrentInstance('useScopeId')\n\n  const scopeId = vm!.vnode.scopeId\n\n  return { scopeId: scopeId ? { [scopeId]: '' } : undefined }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/scroll.ts",
    "content": "// Utilities\nimport {\n  computed,\n  onBeforeUnmount,\n  onMounted,\n  ref,\n  shallowRef,\n  watch,\n} from 'vue'\nimport { clamp, consoleWarn, propsFactory } from '@/util'\n\n// Types\nimport type { Ref } from 'vue'\n\nexport interface ScrollProps {\n  scrollTarget?: string\n  scrollThreshold?: string | number\n}\n\nexport interface ThresholdMetCallbackData {\n  isScrollingUp: boolean\n  currentThreshold: number\n  savedScroll: Ref<number>\n}\n\n// Composables\nexport const makeScrollProps = propsFactory({\n  scrollTarget: {\n    type: String,\n  },\n  scrollThreshold: {\n    type: [String, Number],\n    default: 300,\n  },\n}, 'scroll')\n\nexport interface ScrollArguments {\n  canScroll?: Readonly<Ref<boolean>>\n  layoutSize?: Readonly<Ref<number>>\n}\n\nexport function useScroll (\n  props: ScrollProps,\n  args: ScrollArguments = {},\n) {\n  const { canScroll, layoutSize } = args\n  let previousScroll = 0\n  let previousScrollHeight = 0\n  const target = ref<Element | Window | null>(null)\n  const currentScroll = shallowRef(0)\n  const savedScroll = shallowRef(0)\n  const currentThreshold = shallowRef(0)\n  const isScrollActive = shallowRef(false)\n  const isScrollingUp = shallowRef(false)\n  const isAtBottom = shallowRef(false)\n  const reachedBottomWhileScrollingDown = shallowRef(false)\n  const hasEnoughScrollableSpace = shallowRef(true)\n\n  const scrollThreshold = computed(() => {\n    return Number(props.scrollThreshold)\n  })\n\n  /**\n   * 1: at top\n   * 0: at threshold\n   */\n  const scrollRatio = computed(() => {\n    return clamp(((scrollThreshold.value - currentScroll.value) / scrollThreshold.value) || 0)\n  })\n\n  function getScrollMetrics (targetEl: Element | Window) {\n    const clientHeight = ('window' in targetEl) ? window.innerHeight : targetEl.clientHeight\n    const scrollHeight = ('window' in targetEl) ? document.documentElement.scrollHeight : targetEl.scrollHeight\n    return { clientHeight, scrollHeight }\n  }\n\n  function checkScrollableSpace () {\n    const targetEl = target.value\n    if (!targetEl) return\n\n    const { clientHeight, scrollHeight } = getScrollMetrics(targetEl)\n    const maxScrollableDistance = scrollHeight - clientHeight\n\n    // When the scroll-hide element (like AppBar) hides, it causes the page to grow\n    // We need extra scrollable space beyond the threshold to prevent bouncing\n    // Add the element's height to the required minimum distance\n    const elementHeight = layoutSize?.value || 0\n    const minRequiredDistance = scrollThreshold.value + elementHeight\n\n    // Only enable scroll-hide if there's enough scrollable space\n    hasEnoughScrollableSpace.value = maxScrollableDistance > minRequiredDistance\n  }\n\n  function onResize () {\n    checkScrollableSpace()\n  }\n\n  function onScroll () {\n    const targetEl = target.value\n\n    if (!targetEl || (canScroll && !canScroll.value)) return\n\n    previousScroll = currentScroll.value\n    currentScroll.value = ('window' in targetEl) ? targetEl.pageYOffset : targetEl.scrollTop\n\n    const currentScrollHeight = targetEl instanceof Window ? document.documentElement.scrollHeight : targetEl.scrollHeight\n    if (previousScrollHeight !== currentScrollHeight) {\n      // If page is growing (content loading), recalculate scrollable space\n      // If page is shrinking (likely due to navbar animation), don't recalculate\n      if (currentScrollHeight > previousScrollHeight) {\n        checkScrollableSpace()\n      }\n      previousScrollHeight = currentScrollHeight\n    }\n\n    isScrollingUp.value = currentScroll.value < previousScroll\n    currentThreshold.value = Math.abs(currentScroll.value - scrollThreshold.value)\n\n    // Detect if at bottom of page\n    const { clientHeight, scrollHeight } = getScrollMetrics(targetEl)\n    const atBottom = currentScroll.value + clientHeight >= scrollHeight - 5\n\n    // Track when bottom is reached during downward scroll\n    // Only set flag if ALL conditions are met:\n    // 1. Scrolled past threshold (navbar is hiding)\n    // 2. Page has enough scrollable space for scroll-hide\n    // This prevents activation on short pages or edge cases\n    if (!isScrollingUp.value && atBottom &&\n        currentScroll.value >= scrollThreshold.value &&\n        hasEnoughScrollableSpace.value) {\n      reachedBottomWhileScrollingDown.value = true\n    }\n\n    // Reset the flag when:\n    // 1. Scrolling up away from bottom (with small tolerance for touchpad/momentum scrolling)\n    // 2. Scroll position jumped significantly (e.g., navigation, scroll restoration)\n    // 3. Scroll is at the very top (page navigation resets to top)\n    const scrollJumped = Math.abs(currentScroll.value - previousScroll) > 100\n    const atTop = currentScroll.value <= 5\n    const scrolledUpSignificantly = isScrollingUp.value && (previousScroll - currentScroll.value) > 1\n    if ((scrolledUpSignificantly && !atBottom) || (scrollJumped && currentScroll.value < scrollThreshold.value) || atTop) {\n      reachedBottomWhileScrollingDown.value = false\n    }\n\n    // Update state\n    isAtBottom.value = atBottom\n  }\n\n  watch(isScrollingUp, () => {\n    savedScroll.value = savedScroll.value || currentScroll.value\n  })\n\n  watch(isScrollActive, () => {\n    savedScroll.value = 0\n  })\n\n  onMounted(() => {\n    watch(() => props.scrollTarget, scrollTarget => {\n      const newTarget = scrollTarget ? document.querySelector(scrollTarget) : window\n\n      if (!newTarget) {\n        consoleWarn(`Unable to locate element with identifier ${scrollTarget}`)\n        return\n      }\n\n      if (newTarget === target.value) return\n\n      target.value?.removeEventListener('scroll', onScroll)\n      target.value = newTarget\n      target.value.addEventListener('scroll', onScroll, { passive: true })\n\n      // Check scrollable space when target is set\n      Promise.resolve().then(() => {\n        checkScrollableSpace()\n      })\n    }, { immediate: true })\n\n    // Listen to window resize to recalculate scrollable space\n    window.addEventListener('resize', onResize, { passive: true })\n  })\n\n  onBeforeUnmount(() => {\n    target.value?.removeEventListener('scroll', onScroll)\n    window.removeEventListener('resize', onResize)\n  })\n\n  // Do we need this? If yes - seems that\n  // there's no need to expose onScroll\n  canScroll && watch(canScroll, onScroll, { immediate: true })\n\n  return {\n    scrollThreshold,\n    currentScroll,\n    currentThreshold,\n    isScrollActive,\n    scrollRatio,\n\n    // required only for testing\n    // probably can be removed\n    // later (2 chars chlng)\n    isScrollingUp,\n    savedScroll,\n    isAtBottom,\n    reachedBottomWhileScrollingDown,\n    hasEnoughScrollableSpace,\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/selectLink.ts",
    "content": "// Utilities\nimport { nextTick, watch } from 'vue'\n\n// Types\nimport type { UseLink } from './router'\n\nexport function useSelectLink (link: UseLink, select?: (value: boolean, e?: Event) => void) {\n  watch(() => link.isActive?.value, isActive => {\n    if (link.isLink.value && isActive != null && select) {\n      nextTick(() => {\n        select(isActive)\n      })\n    }\n  }, {\n    immediate: true,\n  })\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/size.ts",
    "content": "// Utilities\nimport { convertToUnit, destructComputed, getCurrentInstanceName, includes, propsFactory } from '@/util'\n\n// Types\nconst predefinedSizes = ['x-small', 'small', 'default', 'large', 'x-large']\n\nexport interface SizeProps {\n  size?: string | number\n}\n\n// Composables\nexport const makeSizeProps = propsFactory({\n  size: {\n    type: [String, Number],\n    default: 'default',\n  },\n}, 'size')\n\nexport function useSize (\n  props: SizeProps,\n  name = getCurrentInstanceName(),\n) {\n  return destructComputed(() => {\n    const size = props.size\n    let sizeClasses\n    let sizeStyles\n    if (includes(predefinedSizes, size)) {\n      sizeClasses = `${name}--size-${size}`\n    } else if (size) {\n      sizeStyles = {\n        width: convertToUnit(size),\n        height: convertToUnit(size),\n      }\n    }\n    return { sizeClasses, sizeStyles }\n  })\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/ssrBoot.ts",
    "content": "// Utilities\nimport { onMounted, readonly, shallowRef, toRef } from 'vue'\n\n// Composables\nexport function useSsrBoot () {\n  const isBooted = shallowRef(false)\n\n  onMounted(() => {\n    window.requestAnimationFrame(() => {\n      isBooted.value = true\n    })\n  })\n\n  const ssrBootStyles = toRef(() => !isBooted.value ? ({\n    transition: 'none !important',\n  }) : undefined)\n\n  return { ssrBootStyles, isBooted: readonly(isBooted) }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/stack.ts",
    "content": "// Composables\nimport { useToggleScope } from '@/composables/toggleScope'\n\n// Utilities\nimport {\n  inject,\n  onScopeDispose,\n  provide,\n  reactive,\n  readonly,\n  shallowRef,\n  toRaw,\n  toRef,\n  toValue,\n  watchEffect,\n} from 'vue'\nimport { getCurrentInstance } from '@/util'\n\n// Types\nimport type { InjectionKey, MaybeRefOrGetter, Ref } from 'vue'\n\nconst StackSymbol: InjectionKey<StackProvide> = Symbol.for('vuetify:stack')\n\ninterface StackProvide {\n  activeChildren: Set<number>\n}\n\nconst globalStack = reactive<[uid: number, zIndex: number][]>([])\n\nexport function useStack (\n  isActive: Readonly<Ref<boolean>>,\n  zIndex: MaybeRefOrGetter<string | number>,\n  disableGlobalStack: boolean\n) {\n  const vm = getCurrentInstance('useStack')\n  const createStackEntry = !disableGlobalStack\n\n  const parent = inject(StackSymbol, undefined)\n  const stack: StackProvide = reactive({\n    activeChildren: new Set<number>(),\n  })\n  provide(StackSymbol, stack)\n\n  const _zIndex = shallowRef(Number(toValue(zIndex)))\n  useToggleScope(isActive, () => {\n    const lastZIndex = globalStack.at(-1)?.[1]\n    _zIndex.value = lastZIndex ? lastZIndex + 10 : Number(toValue(zIndex))\n\n    if (createStackEntry) {\n      globalStack.push([vm.uid, _zIndex.value])\n    }\n\n    parent?.activeChildren.add(vm.uid)\n\n    onScopeDispose(() => {\n      if (createStackEntry) {\n        const idx = toRaw(globalStack).findIndex(v => v[0] === vm.uid)\n        globalStack.splice(idx, 1)\n      }\n\n      parent?.activeChildren.delete(vm.uid)\n    })\n  })\n\n  const globalTop = shallowRef(true)\n  if (createStackEntry) {\n    watchEffect(() => {\n      const _isTop = globalStack.at(-1)?.[0] === vm.uid\n      setTimeout(() => globalTop.value = _isTop)\n    })\n  }\n\n  const localTop = toRef(() => !stack.activeChildren.size)\n\n  return {\n    globalTop: readonly(globalTop),\n    localTop,\n    stackStyles: toRef(() => ({ zIndex: _zIndex.value })),\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/tag.ts",
    "content": "// Utilities\nimport { propsFactory } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { JSXComponent } from '@/util'\n\n// Types\nexport interface TagProps {\n  tag: string | JSXComponent\n}\n\n// Composables\nexport const makeTagProps = propsFactory({\n  tag: {\n    type: [String, Object, Function] as PropType<string | JSXComponent>,\n    default: 'div',\n  },\n}, 'tag')\n"
  },
  {
    "path": "packages/vuetify/src/composables/teleport.ts",
    "content": "// Utilities\nimport { computed, warn } from 'vue'\nimport { IN_BROWSER } from '@/util'\n\nexport function useTeleport (target: () => (boolean | string | ParentNode)) {\n  const teleportTarget = computed(() => {\n    const _target = target()\n\n    if (_target === true || !IN_BROWSER) return undefined\n\n    const targetElement =\n      _target === false ? document.body\n      : typeof _target === 'string' ? document.querySelector(_target)\n      : _target\n\n    if (targetElement == null) {\n      warn(`Unable to locate target ${_target}`)\n      return undefined\n    }\n\n    let container = [...targetElement.children].find(el => el.matches('.v-overlay-container'))\n\n    if (!container) {\n      container = document.createElement('div')\n      container.className = 'v-overlay-container'\n      targetElement.appendChild(container)\n    }\n\n    return container\n  })\n\n  return { teleportTarget }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/theme.ts",
    "content": "// Utilities\nimport {\n  computed,\n  getCurrentScope,\n  inject,\n  onScopeDispose,\n  provide,\n  ref,\n  shallowRef,\n  toRef,\n  watch,\n  watchEffect,\n} from 'vue'\nimport {\n  consoleWarn,\n  createRange,\n  darken,\n  deprecate,\n  getCurrentInstance,\n  getLuma,\n  hasLightForeground,\n  IN_BROWSER,\n  lighten,\n  mergeDeep,\n  parseColor,\n  propsFactory,\n  RGBtoHex,\n  SUPPORTS_MATCH_MEDIA,\n} from '@/util'\n\n// Types\nimport type { VueHeadClient } from '@unhead/vue/client'\nimport type { HeadClient } from '@vueuse/head'\nimport type { App, DeepReadonly, InjectionKey, Ref } from 'vue'\nimport type { Color } from '@/util'\n\ntype DeepPartial<T> = T extends object ? { [P in keyof T]?: DeepPartial<T[P]> } : T\n\nexport type ThemeOptions = false | {\n  cspNonce?: string\n  defaultTheme?: 'light' | 'dark' | 'system' | string & {}\n  variations?: false | VariationsOptions\n  themes?: Record<string, ThemeDefinition>\n  stylesheetId?: string\n  scope?: string\n  utilities?: boolean\n}\nexport type ThemeDefinition = DeepPartial<InternalThemeDefinition>\n\ninterface InternalThemeOptions {\n  cspNonce?: string\n  isDisabled: boolean\n  defaultTheme: 'light' | 'dark' | 'system' | string & {}\n  prefix: string\n  variations: false | VariationsOptions\n  themes: Record<string, InternalThemeDefinition>\n  stylesheetId: string\n  scope?: string\n  scoped: boolean\n  utilities: boolean\n}\n\ninterface VariationsOptions {\n  colors: string[]\n  lighten: number\n  darken: number\n}\n\ninterface InternalThemeDefinition {\n  dark: boolean\n  colors: Colors\n  variables: Record<string, string | number>\n}\n\nexport interface Colors extends BaseColors, OnColors {\n  [key: string]: Color\n}\n\ninterface BaseColors {\n  background: Color\n  surface: Color\n  primary: Color\n  secondary: Color\n  success: Color\n  warning: Color\n  error: Color\n  info: Color\n}\n\ninterface OnColors {\n  'on-background': Color\n  'on-surface': Color\n  'on-primary': Color\n  'on-secondary': Color\n  'on-success': Color\n  'on-warning': Color\n  'on-error': Color\n  'on-info': Color\n}\n\nexport interface ThemeInstance {\n  change: (themeName: string) => void\n  cycle: (themeArray?: string[]) => void\n  toggle: (themeArray?: [string, string]) => void\n\n  readonly isDisabled: boolean\n  readonly isSystem: Readonly<Ref<boolean>>\n  readonly themes: Ref<Record<string, InternalThemeDefinition>>\n\n  readonly name: Readonly<Ref<string>>\n  readonly current: DeepReadonly<Ref<InternalThemeDefinition>>\n  readonly computedThemes: DeepReadonly<Ref<Record<string, InternalThemeDefinition>>>\n  readonly prefix: string\n\n  readonly themeClasses: Readonly<Ref<string | undefined>>\n  readonly styles: Readonly<Ref<string>>\n\n  readonly global: {\n    readonly name: Ref<string>\n    readonly current: DeepReadonly<Ref<InternalThemeDefinition>>\n  }\n}\n\nexport const ThemeSymbol: InjectionKey<ThemeInstance> = Symbol.for('vuetify:theme')\n\nexport const makeThemeProps = propsFactory({\n  theme: String,\n}, 'theme')\n\nfunction genDefaults () {\n  return {\n    defaultTheme: 'system',\n    prefix: 'v-',\n    variations: { colors: [], lighten: 0, darken: 0 },\n    themes: {\n      light: {\n        dark: false,\n        colors: {\n          background: '#FFFFFF',\n          surface: '#FFFFFF',\n          'surface-bright': '#FFFFFF',\n          'surface-light': '#EEEEEE',\n          'surface-variant': '#424242',\n          'on-surface-variant': '#EEEEEE',\n          primary: '#1867C0',\n          'primary-darken-1': '#1F5592',\n          secondary: '#48A9A6',\n          'secondary-darken-1': '#018786',\n          error: '#B00020',\n          info: '#2196F3',\n          success: '#4CAF50',\n          warning: '#FB8C00',\n        },\n        variables: {\n          'border-color': '#000000',\n          'border-opacity': 0.12,\n          'shadow-color': '#000000',\n          'high-emphasis-opacity': 0.87,\n          'medium-emphasis-opacity': 0.60,\n          'disabled-opacity': 0.38,\n          'idle-opacity': 0.04,\n          'hover-opacity': 0.04,\n          'focus-opacity': 0.12,\n          'selected-opacity': 0.08,\n          'activated-opacity': 0.12,\n          'pressed-opacity': 0.12,\n          'dragged-opacity': 0.08,\n          'theme-kbd': '#EEEEEE',\n          'theme-on-kbd': '#000000',\n          'theme-code': '#F5F5F5',\n          'theme-on-code': '#000000',\n          'theme-on-dark': '#FFF',\n          'theme-on-light': '#000',\n          'elevation-overlay-color': 'black',\n          'elevation-overlay-opacity-step': '2%',\n        },\n      },\n      dark: {\n        dark: true,\n        colors: {\n          background: '#121212',\n          surface: '#212121',\n          'surface-bright': '#ccbfd6',\n          'surface-light': '#424242',\n          'surface-variant': '#c8c8c8',\n          'on-surface-variant': '#000000',\n          primary: '#2196F3',\n          'primary-darken-1': '#277CC1',\n          secondary: '#54B6B2',\n          'secondary-darken-1': '#48A9A6',\n          error: '#CF6679',\n          info: '#2196F3',\n          success: '#4CAF50',\n          warning: '#FB8C00',\n        },\n        variables: {\n          'border-color': '#FFFFFF',\n          'border-opacity': 0.12,\n          'shadow-color': '#000000',\n          'high-emphasis-opacity': 1,\n          'medium-emphasis-opacity': 0.70,\n          'disabled-opacity': 0.50,\n          'idle-opacity': 0.10,\n          'hover-opacity': 0.04,\n          'focus-opacity': 0.12,\n          'selected-opacity': 0.08,\n          'activated-opacity': 0.12,\n          'pressed-opacity': 0.16,\n          'dragged-opacity': 0.08,\n          'theme-kbd': '#424242',\n          'theme-on-kbd': '#FFFFFF',\n          'theme-code': '#343434',\n          'theme-on-code': '#CCCCCC',\n          'theme-on-dark': '#FFF',\n          'theme-on-light': '#000',\n          'elevation-overlay-color': 'white',\n          'elevation-overlay-opacity-step': '2%',\n        },\n      },\n    },\n    stylesheetId: 'vuetify-theme-stylesheet',\n    scoped: false,\n    utilities: true,\n  }\n}\n\nfunction parseThemeOptions (options: ThemeOptions = genDefaults()): InternalThemeOptions {\n  const defaults = genDefaults()\n\n  if (!options) return { ...defaults, isDisabled: true } as any\n\n  return mergeDeep(defaults, options) as InternalThemeOptions\n}\n\nfunction createCssClass (lines: string[], selector: string, content: string[], scope?: string) {\n  lines.push(\n    `${getScopedSelector(selector, scope)} {\\n`,\n    ...content.map(line => `  ${line};\\n`),\n    '}\\n',\n  )\n}\n\nfunction genCssVariables (theme: InternalThemeDefinition, prefix: string) {\n  const lightOverlay = theme.dark ? 2 : 1\n  const darkOverlay = theme.dark ? 1 : 2\n\n  const variables: string[] = []\n  for (const [key, value] of Object.entries(theme.colors)) {\n    const rgb = parseColor(value)\n    variables.push(`--${prefix}theme-${key}: ${rgb.r},${rgb.g},${rgb.b}` + (rgb.a == null ? '' : `,${rgb.a}`))\n    if (!key.startsWith('on-')) {\n      variables.push(`--${prefix}theme-${key}-overlay-multiplier: ${getLuma(value) > 0.18 ? lightOverlay : darkOverlay}`)\n    }\n  }\n\n  for (const [key, value] of Object.entries(theme.variables)) {\n    const color = typeof value === 'string' && value.startsWith('#') ? parseColor(value) : undefined\n    const rgb = color ? `${color.r}, ${color.g}, ${color.b}` : undefined\n    variables.push(`--${prefix}${key}: ${rgb ?? value}`)\n  }\n\n  return variables\n}\n\nfunction genVariation (name: string, color: Color, variations: VariationsOptions | false) {\n  const object: Record<string, string> = {}\n  if (variations) {\n    for (const variation of (['lighten', 'darken'] as const)) {\n      const fn = variation === 'lighten' ? lighten : darken\n      for (const amount of createRange(variations[variation], 1)) {\n        object[`${name}-${variation}-${amount}`] = RGBtoHex(fn(parseColor(color), amount))\n      }\n    }\n  }\n  return object\n}\n\nfunction genVariations (colors: InternalThemeDefinition['colors'], variations: VariationsOptions | false) {\n  if (!variations) return {}\n\n  let variationColors = {}\n  for (const name of variations.colors) {\n    const color = colors[name]\n\n    if (!color) continue\n\n    variationColors = {\n      ...variationColors,\n      ...genVariation(name, color, variations),\n    }\n  }\n  return variationColors\n}\n\nfunction genOnColors (colors: InternalThemeDefinition['colors'], variables: InternalThemeDefinition['variables']) {\n  const onColors = {} as InternalThemeDefinition['colors']\n\n  for (const color of Object.keys(colors)) {\n    if (color.startsWith('on-') || colors[`on-${color}`]) continue\n\n    const onColor = `on-${color}` as keyof OnColors\n    const colorVal = parseColor(colors[color])\n\n    onColors[onColor] = hasLightForeground(colorVal)\n      ? variables['theme-on-dark']\n      : variables['theme-on-light']\n  }\n\n  return onColors\n}\n\nfunction getScopedSelector (selector: string, scope?: string) {\n  if (!scope) return selector\n\n  const scopeSelector = `:where(${scope})`\n\n  return selector === ':root' ? scopeSelector : `${scopeSelector} ${selector}`\n}\n\nfunction upsertStyles (id: string, cspNonce: string | undefined, styles: string) {\n  const styleEl = getOrCreateStyleElement(id, cspNonce)\n\n  if (!styleEl) return\n\n  styleEl.innerHTML = styles\n}\n\nfunction getOrCreateStyleElement (id: string, cspNonce?: string) {\n  if (!IN_BROWSER) return null\n\n  let style = document.getElementById(id) as HTMLStyleElement | null\n\n  if (!style) {\n    style = document.createElement('style')\n    style.id = id\n    style.type = 'text/css'\n\n    if (cspNonce) style.setAttribute('nonce', cspNonce)\n\n    document.head.appendChild(style)\n  }\n\n  return style\n}\n\n// Composables\nexport function createTheme (options?: ThemeOptions): ThemeInstance & { install: (app: App) => void } {\n  const parsedOptions = parseThemeOptions(options)\n  const _name = shallowRef(parsedOptions.defaultTheme)\n  const themes = ref(parsedOptions.themes)\n  const systemName = shallowRef('light')\n\n  const name = computed({\n    get () {\n      return _name.value === 'system' ? systemName.value : _name.value\n    },\n    set (val: string) {\n      _name.value = val\n    },\n  })\n\n  const computedThemes = computed(() => {\n    const acc: Record<string, InternalThemeDefinition> = {}\n    for (const [name, original] of Object.entries(themes.value)) {\n      const defaultTheme = original.dark || name === 'dark'\n        ? themes.value.dark\n        : themes.value.light\n\n      const merged = mergeDeep(defaultTheme, original) as InternalThemeDefinition\n\n      const colors = {\n        ...merged.colors,\n        ...genVariations(merged.colors, parsedOptions.variations),\n      }\n\n      acc[name] = {\n        ...merged,\n        colors: {\n          ...colors,\n          ...genOnColors(colors, merged.variables),\n        },\n      }\n    }\n    return acc\n  })\n\n  const current = toRef(() => computedThemes.value[name.value])\n\n  const isSystem = toRef(() => _name.value === 'system')\n\n  const styles = computed(() => {\n    const lines: string[] = []\n    const scoped = parsedOptions.scoped ? parsedOptions.prefix : ''\n\n    lines.push('@layer theme-base {\\n')\n\n    if (current.value?.dark) {\n      createCssClass(lines, ':root', ['color-scheme: dark'], parsedOptions.scope)\n    }\n\n    createCssClass(lines, ':root', genCssVariables(current.value, parsedOptions.prefix), parsedOptions.scope)\n\n    for (const [themeName, theme] of Object.entries(computedThemes.value)) {\n      createCssClass(lines, `.${parsedOptions.prefix}theme--${themeName}`, [\n        `color-scheme: ${theme.dark ? 'dark' : 'normal'}`,\n        ...genCssVariables(theme, parsedOptions.prefix),\n      ], parsedOptions.scope)\n    }\n\n    lines.push('}\\n')\n\n    if (parsedOptions.utilities) {\n      const bgLines: string[] = []\n      const fgLines: string[] = []\n\n      const colors = new Set(Object.values(computedThemes.value).flatMap(theme => Object.keys(theme.colors)))\n      for (const key of colors) {\n        if (key.startsWith('on-')) {\n          createCssClass(fgLines, `.${key}`, [`color: rgb(var(--${parsedOptions.prefix}theme-${key}))`], parsedOptions.scope)\n        } else {\n          createCssClass(bgLines, `.${scoped}bg-${key}`, [\n            `--${parsedOptions.prefix}theme-overlay-multiplier: var(--${parsedOptions.prefix}theme-${key}-overlay-multiplier)`,\n            `background-color: rgb(var(--${parsedOptions.prefix}theme-${key}))`,\n            `color: rgb(var(--${parsedOptions.prefix}theme-on-${key}))`,\n          ], parsedOptions.scope)\n          createCssClass(fgLines, `.${scoped}text-${key}`, [`color: rgb(var(--${parsedOptions.prefix}theme-${key}))`], parsedOptions.scope)\n          createCssClass(fgLines, `.${scoped}border-${key}`, [`--${parsedOptions.prefix}border-color: var(--${parsedOptions.prefix}theme-${key})`], parsedOptions.scope)\n        }\n      }\n\n      lines.push(\n        '@layer theme-background {\\n',\n        ...bgLines.map(v => `  ${v}`),\n        '}\\n',\n        '@layer theme-foreground {\\n',\n        ...fgLines.map(v => `  ${v}`),\n        '}\\n',\n      )\n    }\n\n    return '@layer vuetify-utilities {\\n' + lines.map(v => `  ${v}`).join('') + '\\n}'\n  })\n\n  const themeClasses = toRef(() => parsedOptions.isDisabled ? undefined : `${parsedOptions.prefix}theme--${name.value}`)\n  const themeNames = toRef(() => Object.keys(computedThemes.value))\n\n  if (SUPPORTS_MATCH_MEDIA) {\n    const media = window.matchMedia('(prefers-color-scheme: dark)')\n\n    function updateSystemName () {\n      systemName.value = media.matches ? 'dark' : 'light'\n    }\n\n    updateSystemName()\n\n    media.addEventListener('change', updateSystemName, { passive: true })\n\n    if (getCurrentScope()) {\n      onScopeDispose(() => {\n        media.removeEventListener('change', updateSystemName)\n      })\n    }\n  }\n\n  function install (app: App) {\n    if (parsedOptions.isDisabled) return\n\n    const head = app._context.provides.usehead as HeadClient & VueHeadClient<any> | undefined\n    if (head) {\n      function getHead () {\n        return {\n          style: [{\n            textContent: styles.value,\n            id: parsedOptions.stylesheetId,\n            nonce: parsedOptions.cspNonce || false as never,\n            tagPosition: 'bodyOpen' as const,\n          }],\n        }\n      }\n\n      if (head.push) {\n        const entry = head.push(getHead)\n        if (IN_BROWSER) {\n          watch(styles, () => { entry.patch(getHead) })\n        }\n      } else {\n        if (IN_BROWSER) {\n          head.addHeadObjs(toRef(getHead))\n          watchEffect(() => head.updateDOM())\n        } else {\n          head.addHeadObjs(getHead())\n        }\n      }\n    } else {\n      if (IN_BROWSER) {\n        watch(styles, updateStyles, { immediate: true })\n      } else {\n        updateStyles()\n      }\n\n      function updateStyles () {\n        upsertStyles(parsedOptions.stylesheetId, parsedOptions.cspNonce, styles.value)\n      }\n    }\n  }\n\n  function change (themeName: string) {\n    if (themeName !== 'system' && !themeNames.value.includes(themeName)) {\n      consoleWarn(`Theme \"${themeName}\" not found on the Vuetify theme instance`)\n      return\n    }\n\n    name.value = themeName\n  }\n\n  function cycle (themeArray: string[] = themeNames.value) {\n    const currentIndex = themeArray.indexOf(name.value)\n    const nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % themeArray.length\n\n    change(themeArray[nextIndex])\n  }\n\n  function toggle (themeArray: [string, string] = ['light', 'dark']) {\n    cycle(themeArray)\n  }\n\n  const globalName = new Proxy(name, {\n    get (target, prop) {\n      return Reflect.get(target, prop)\n    },\n    set (target, prop, val) {\n      if (prop === 'value') {\n        deprecate(`theme.global.name.value = ${val}`, `theme.change('${val}')`)\n      }\n      return Reflect.set(target, prop, val)\n    },\n  })\n\n  return {\n    install,\n    change,\n    cycle,\n    toggle,\n    isDisabled: parsedOptions.isDisabled,\n    isSystem,\n    name,\n    themes,\n    current,\n    computedThemes,\n    prefix: parsedOptions.prefix,\n    themeClasses,\n    styles,\n    global: {\n      name: globalName,\n      current,\n    },\n  }\n}\n\nexport function provideTheme (props: { theme?: string }) {\n  getCurrentInstance('provideTheme')\n\n  const theme = inject(ThemeSymbol, null)\n\n  if (!theme) throw new Error('Could not find Vuetify theme injection')\n\n  const name = toRef(() => props.theme ?? theme.name.value)\n  const current = toRef(() => theme.themes.value[name.value])\n\n  const themeClasses = toRef(() => theme.isDisabled ? undefined : `${theme.prefix}theme--${name.value}`)\n\n  const newTheme: ThemeInstance = {\n    ...theme,\n    name,\n    current,\n    themeClasses,\n  }\n\n  provide(ThemeSymbol, newTheme)\n\n  return newTheme\n}\n\nexport function useTheme () {\n  getCurrentInstance('useTheme')\n\n  const theme = inject(ThemeSymbol, null)\n\n  if (!theme) throw new Error('Could not find Vuetify theme injection')\n\n  return theme\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/toggleScope.ts",
    "content": "// Utilities\nimport { effectScope, onScopeDispose, watch } from 'vue'\n\n// Types\nimport type { EffectScope, WatchSource } from 'vue'\n\nexport function useToggleScope (source: WatchSource<boolean>, fn: (reset: () => void) => void) {\n  let scope: EffectScope | undefined\n  function start () {\n    scope = effectScope()\n    scope.run(() => fn.length\n      ? fn(() => { scope?.stop(); start() })\n      : (fn as any)()\n    )\n  }\n\n  watch(source, active => {\n    if (active && !scope) {\n      start()\n    } else if (!active) {\n      scope?.stop()\n      scope = undefined\n    }\n  }, { immediate: true })\n\n  onScopeDispose(() => {\n    scope?.stop()\n  })\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/touch.ts",
    "content": "// Utilities\nimport { CircularBuffer } from '@/util'\n\nconst HORIZON = 100 // ms\nconst HISTORY = 20 // number of samples to keep\n\nexport interface Sample {\n  t: number\n  d: number\n}\n\n/** @see https://android.googlesource.com/platform/frameworks/native/+/master/libs/input/VelocityTracker.cpp */\nfunction kineticEnergyToVelocity (work: number) {\n  const sqrt2 = 1.41421356237\n  return (work < 0 ? -1.0 : 1.0) * Math.sqrt(Math.abs(work)) * sqrt2\n}\n\n/**\n * Returns pointer velocity in px/s\n */\nexport function calculateImpulseVelocity (samples: Sample[]) {\n  // The input should be in reversed time order (most recent sample at index i=0)\n  if (samples.length < 2) {\n    // if 0 or 1 points, velocity is zero\n    return 0\n  }\n  // if (samples[1].t > samples[0].t) {\n  //   // Algorithm will still work, but not perfectly\n  //   consoleWarn('Samples provided to calculateImpulseVelocity in the wrong order')\n  // }\n  if (samples.length === 2) {\n    // if 2 points, basic linear calculation\n    if (samples[1].t === samples[0].t) {\n      // consoleWarn(`Events have identical time stamps t=${samples[0].t}, setting velocity = 0`)\n      return 0\n    }\n    return (samples[1].d - samples[0].d) / (samples[1].t - samples[0].t)\n  }\n  // Guaranteed to have at least 3 points here\n  // start with the oldest sample and go forward in time\n  let work = 0\n  for (let i = samples.length - 1; i > 0; i--) {\n    if (samples[i].t === samples[i - 1].t) {\n      // consoleWarn(`Events have identical time stamps t=${samples[i].t}, skipping sample`)\n      continue\n    }\n    const vprev = kineticEnergyToVelocity(work) // v[i-1]\n    const vcurr = (samples[i].d - samples[i - 1].d) / (samples[i].t - samples[i - 1].t) // v[i]\n    work += (vcurr - vprev) * Math.abs(vcurr)\n    if (i === samples.length - 1) {\n      work *= 0.5\n    }\n  }\n  return kineticEnergyToVelocity(work) * 1000\n}\n\nexport function useVelocity () {\n  const touches: Record<number, CircularBuffer<[number, Touch]> | undefined> = {}\n\n  function addMovement (e: TouchEvent) {\n    Array.from(e.changedTouches).forEach(touch => {\n      const samples = touches[touch.identifier] ?? (touches[touch.identifier] = new CircularBuffer(HISTORY))\n      samples.push([e.timeStamp, touch])\n    })\n  }\n\n  function endTouch (e: TouchEvent) {\n    Array.from(e.changedTouches).forEach(touch => {\n      delete touches[touch.identifier]\n    })\n  }\n\n  function getVelocity (id: number) {\n    const samples = touches[id]?.values().reverse()\n\n    if (!samples) {\n      throw new Error(`No samples for touch id ${id}`)\n    }\n\n    const newest = samples[0]\n    const x: Sample[] = []\n    const y: Sample[] = []\n    for (const val of samples) {\n      if (newest[0] - val[0] > HORIZON) break\n\n      x.push({ t: val[0], d: val[1].clientX })\n      y.push({ t: val[0], d: val[1].clientY })\n    }\n\n    return {\n      x: calculateImpulseVelocity(x),\n      y: calculateImpulseVelocity(y),\n      get direction () {\n        const { x, y } = this\n        const [absX, absY] = [Math.abs(x), Math.abs(y)]\n\n        return absX > absY && x >= 0 ? 'right'\n          : absX > absY && x <= 0 ? 'left'\n          : absY > absX && y >= 0 ? 'down'\n          : absY > absX && y <= 0 ? 'up'\n          : oops()\n      },\n    }\n  }\n\n  return { addMovement, endTouch, getVelocity }\n}\n\nfunction oops (): never {\n  throw new Error()\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/transition.ts",
    "content": "// Utilities\nimport { h, mergeProps, Transition, TransitionGroup } from 'vue'\nimport { isObject, onlyDefinedProps, propsFactory } from '@/util'\n\n// Types\nimport type { Component, FunctionalComponent, Prop, TransitionProps } from 'vue'\n\nexport const makeTransitionProps = propsFactory({\n  transition: {\n    type: null,\n    default: 'fade-transition',\n    validator: val => val !== true,\n  } as Prop<null | string | boolean | TransitionProps & { component?: Component }>,\n}, 'transition')\n\ninterface MaybeTransitionProps extends TransitionProps {\n  transition?: null | string | boolean | TransitionProps & { component?: any }\n  disabled?: boolean\n  group?: boolean\n}\n\nexport const MaybeTransition: FunctionalComponent<MaybeTransitionProps> = (props, { slots }) => {\n  const { transition, disabled, group, ...rest } = props\n\n  const {\n    component = group ? TransitionGroup : Transition,\n    ...customProps\n  } = isObject(transition) ? transition : {}\n\n  let transitionProps\n  if (isObject(transition)) {\n    transitionProps = mergeProps(\n      customProps,\n      onlyDefinedProps({ disabled, group }),\n      rest,\n    )\n  } else {\n    transitionProps = mergeProps(\n      { name: disabled || !transition ? '' : transition },\n      rest,\n    )\n  }\n\n  return h(\n    component,\n    transitionProps,\n    slots\n  )\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/validation.ts",
    "content": "// Composables\nimport { makeFocusProps } from '@/composables/focus'\nimport { useForm } from '@/composables/form'\nimport { useProxiedModel } from '@/composables/proxiedModel'\nimport { useToggleScope } from '@/composables/toggleScope'\nimport { useRules } from '@/labs/rules'\n\n// Utilities\nimport { computed, nextTick, onBeforeMount, onBeforeUnmount, onMounted, ref, shallowRef, unref, useId, watch } from 'vue'\nimport { getCurrentInstance, getCurrentInstanceName, propsFactory, wrapInArray } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { ValidationAlias } from '@/labs/rules'\nimport type { EventProp, MaybeRef } from '@/util'\n\nexport type ValidationResult = string | boolean\nexport type ValidationRule =\n  | ValidationResult\n  | PromiseLike<ValidationResult>\n  | ((value: any) => ValidationResult)\n  | ((value: any) => PromiseLike<ValidationResult>)\n\ntype ValidateOnValue = 'blur' | 'input' | 'submit' | 'invalid-input'\ntype ValidateOn =\n  | ValidateOnValue\n  | `${ValidateOnValue} lazy`\n  | `${ValidateOnValue} eager`\n  | `lazy ${ValidateOnValue}`\n  | `eager ${ValidateOnValue}`\n  | 'lazy'\n  | 'eager'\n\nexport interface ValidationProps {\n  disabled: boolean | null\n  error: boolean\n  errorMessages: string | readonly string[] | null\n  focused: boolean\n  maxErrors: string | number\n  name: string | undefined\n  label: string | undefined\n  readonly: boolean | null\n  rules: readonly (ValidationRule | ValidationAlias)[]\n  modelValue: any\n  'onUpdate:modelValue': EventProp | undefined\n  validateOn?: ValidateOn\n  validationValue: any\n}\n\nexport const makeValidationProps = propsFactory({\n  disabled: {\n    type: Boolean as PropType<boolean | null>,\n    default: null,\n  },\n  error: Boolean,\n  errorMessages: {\n    type: [Array, String] as PropType<string | readonly string[] | null>,\n    default: () => ([]),\n  },\n  maxErrors: {\n    type: [Number, String],\n    default: 1,\n  },\n  name: String,\n  label: String,\n  readonly: {\n    type: Boolean as PropType<boolean | null>,\n    default: null,\n  },\n  rules: {\n    type: Array as PropType<readonly (ValidationRule | ValidationAlias)[]>,\n    default: () => ([]),\n  },\n  modelValue: null,\n  validateOn: String as PropType<ValidationProps['validateOn']>,\n  validationValue: null,\n\n  ...makeFocusProps(),\n}, 'validation')\n\nexport function useValidation (\n  props: ValidationProps,\n  name = getCurrentInstanceName(),\n  id: MaybeRef<string | number> = useId(),\n) {\n  const model = useProxiedModel(props, 'modelValue')\n  const validationModel = computed(() => props.validationValue === undefined ? model.value : props.validationValue)\n  const form = useForm(props)\n  const rules = useRules(() => props.rules)\n  const internalErrorMessages = ref<string[]>([])\n  const isPristine = shallowRef(true)\n  const isDirty = computed(() => !!(\n    wrapInArray(model.value === '' ? null : model.value).length ||\n    wrapInArray(validationModel.value === '' ? null : validationModel.value).length\n  ))\n  const errorMessages = computed(() => {\n    return props.errorMessages?.length\n      ? wrapInArray(props.errorMessages).concat(internalErrorMessages.value).slice(0, Math.max(0, Number(props.maxErrors)))\n      : internalErrorMessages.value\n  })\n  const validateOn = computed(() => {\n    let value = (props.validateOn ?? form.validateOn?.value) || 'input'\n    if (value === 'lazy') value = 'input lazy'\n    if (value === 'eager') value = 'input eager'\n    const set = new Set(value?.split(' ') ?? [])\n\n    return {\n      input: set.has('input'),\n      blur: set.has('blur') || set.has('input') || set.has('invalid-input'),\n      invalidInput: set.has('invalid-input'),\n      lazy: set.has('lazy'),\n      eager: set.has('eager'),\n    }\n  })\n  const isValid = computed(() => {\n    if (props.error || props.errorMessages?.length) return false\n    if (!props.rules.length) return true\n    if (isPristine.value) {\n      return internalErrorMessages.value.length || validateOn.value.lazy ? null : true\n    } else {\n      return !internalErrorMessages.value.length\n    }\n  })\n  const isValidating = shallowRef(false)\n  const validationClasses = computed(() => {\n    return {\n      [`${name}--error`]: isValid.value === false,\n      [`${name}--dirty`]: isDirty.value,\n      [`${name}--disabled`]: form.isDisabled.value,\n      [`${name}--readonly`]: form.isReadonly.value,\n    }\n  })\n\n  const vm = getCurrentInstance('validation')\n  const uid = computed(() => props.name ?? unref(id))\n\n  onBeforeMount(() => {\n    form.register?.({\n      id: uid.value,\n      vm,\n      validate,\n      reset,\n      resetValidation,\n    })\n  })\n\n  onBeforeUnmount(() => {\n    form.unregister?.(uid.value)\n  })\n\n  onMounted(async () => {\n    if (!validateOn.value.lazy) {\n      await validate(!validateOn.value.eager)\n    }\n    form.update?.(uid.value, isValid.value, errorMessages.value)\n  })\n\n  useToggleScope(() => validateOn.value.input || (validateOn.value.invalidInput && isValid.value === false), () => {\n    watch(validationModel, () => {\n      if (validationModel.value != null) {\n        validate()\n      } else if (props.focused) {\n        const unwatch = watch(() => props.focused, val => {\n          if (!val) validate()\n\n          unwatch()\n        })\n      }\n    })\n  })\n\n  useToggleScope(() => validateOn.value.blur, () => {\n    watch(() => props.focused, val => {\n      if (!val) validate()\n    })\n  })\n\n  watch([isValid, errorMessages], () => {\n    form.update?.(uid.value, isValid.value, errorMessages.value)\n  })\n\n  async function reset () {\n    model.value = null\n    await nextTick()\n    await resetValidation()\n  }\n\n  async function resetValidation () {\n    isPristine.value = true\n    if (!validateOn.value.lazy) {\n      await validate(!validateOn.value.eager)\n    } else {\n      internalErrorMessages.value = []\n    }\n  }\n\n  async function validate (silent = false) {\n    const results = []\n\n    isValidating.value = true\n\n    for (const rule of rules.value) {\n      if (results.length >= Number(props.maxErrors ?? 1)) {\n        break\n      }\n\n      const handler = typeof rule === 'function' ? rule : () => rule\n      const result = await handler(validationModel.value)\n\n      if (result === true) continue\n\n      if (result !== false && typeof result !== 'string') {\n        // eslint-disable-next-line no-console\n        console.warn(`${result} is not a valid value. Rule functions must return boolean true or a string.`)\n\n        continue\n      }\n\n      results.push(result || '')\n    }\n\n    internalErrorMessages.value = results\n    isValidating.value = false\n    isPristine.value = silent\n\n    return internalErrorMessages.value\n  }\n\n  return {\n    errorMessages,\n    isDirty,\n    isDisabled: form.isDisabled,\n    isReadonly: form.isReadonly,\n    isPristine,\n    isValid,\n    isValidating,\n    reset,\n    resetValidation,\n    validate,\n    validationClasses,\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/variant.tsx",
    "content": "// Composables\nimport { useColor } from '@/composables/color'\n\n// Utilities\nimport { toRef, toValue } from 'vue'\nimport { getCurrentInstanceName, propsFactory } from '@/util'\n\n// Types\nimport type { MaybeRefOrGetter, PropType } from 'vue'\n\nexport const allowedVariants = [\n  'elevated',\n  'flat',\n  'tonal',\n  'outlined',\n  'text',\n  'plain',\n] as const\n\nexport type Variant = typeof allowedVariants[number]\n\nexport interface VariantProps {\n  color?: string\n  variant: Variant\n}\n\nexport function genOverlays (isClickable: boolean, name: string) {\n  return (\n    <>\n      { isClickable && <span key=\"overlay\" class={ `${name}__overlay` } /> }\n\n      <span key=\"underlay\" class={ `${name}__underlay` } />\n    </>\n  )\n}\n\nexport const makeVariantProps = propsFactory({\n  color: String,\n  variant: {\n    type: String as PropType<Variant>,\n    default: 'elevated',\n    validator: (v: any) => allowedVariants.includes(v),\n  },\n}, 'variant')\n\nexport function useVariant (\n  props: MaybeRefOrGetter<VariantProps>,\n  name = getCurrentInstanceName(),\n) {\n  const variantClasses = toRef(() => {\n    const { variant } = toValue(props)\n    return `${name}--variant-${variant}`\n  })\n\n  const { colorClasses, colorStyles } = useColor(() => {\n    const { variant, color } = toValue(props)\n    return {\n      [['elevated', 'flat'].includes(variant) ? 'background' : 'text']: color,\n    }\n  })\n\n  return { colorClasses, colorStyles, variantClasses }\n}\n"
  },
  {
    "path": "packages/vuetify/src/composables/virtual.ts",
    "content": "// Composables\nimport { useDisplay } from '@/composables/display'\nimport { useResizeObserver } from '@/composables/resizeObserver'\n\n// Utilities\nimport { computed, nextTick, onScopeDispose, ref, shallowRef, watch, watchEffect } from 'vue'\nimport { clamp, debounce, getPropertyFromItem, IN_BROWSER, propsFactory } from '@/util'\n\n// Types\nimport type { PropType, Ref } from 'vue'\nimport type { SelectItemKey } from '@/util'\n\nconst UP = -1\nconst DOWN = 1\n\n/** Determines how large each batch of items should be */\nconst BUFFER_PX = 100\n\ntype VirtualProps = {\n  itemHeight: number | string | null | undefined\n  itemKey: SelectItemKey\n  height: number | string | undefined\n}\n\nexport const makeVirtualProps = propsFactory({\n  itemHeight: {\n    type: [Number, String],\n    default: null,\n  },\n  itemKey: {\n    type: [String, Array, Function] as PropType<SelectItemKey>,\n    default: null,\n  },\n  height: [Number, String],\n}, 'virtual')\n\nexport function useVirtual <T> (props: VirtualProps, items: Ref<readonly T[]>) {\n  const display = useDisplay()\n\n  const itemHeight = shallowRef(0)\n  watchEffect(() => {\n    itemHeight.value = parseFloat(props.itemHeight || 0)\n  })\n\n  const first = shallowRef(0)\n  const last = shallowRef(Math.ceil(\n    // Assume 16px items filling the entire screen height if\n    // not provided. This is probably incorrect but it minimises\n    // the chance of ending up with empty space at the bottom.\n    // The default value is set here to avoid poisoning getSize()\n    (parseInt(props.height!) || display.height.value) / (itemHeight.value || 16)\n  ) || 1)\n  const paddingTop = shallowRef(0)\n  const paddingBottom = shallowRef(0)\n\n  /** The scrollable element */\n  const containerRef = ref<HTMLElement>()\n  /** An element marking the top of the scrollable area,\n   * used to add an offset if there's padding or other elements above the virtual list */\n  const markerRef = ref<HTMLElement>()\n  /** markerRef's offsetTop, lazily evaluated */\n  let markerOffset = 0\n\n  const { resizeRef, contentRect } = useResizeObserver()\n  watchEffect(() => {\n    resizeRef.value = containerRef.value\n  })\n  const viewportHeight = computed(() => {\n    return containerRef.value === document.documentElement\n      ? display.height.value\n      : contentRect.value?.height || parseInt(props.height!) || 0\n  })\n  /** All static elements have been rendered and we have an assumed item height */\n  const hasInitialRender = computed(() => {\n    return !!(containerRef.value && markerRef.value && viewportHeight.value && itemHeight.value)\n  })\n\n  let sizes = Array.from<number | null>({ length: items.value.length })\n  let offsets = Array.from<number>({ length: items.value.length })\n  const updateTime = shallowRef(0)\n  let targetScrollIndex = -1\n\n  function getSize (index: number) {\n    return sizes[index] || itemHeight.value\n  }\n\n  const updateOffsets = debounce(() => {\n    const start = performance.now()\n    offsets[0] = 0\n    const length = items.value.length\n    for (let i = 1; i <= length; i++) {\n      offsets[i] = (offsets[i - 1] || 0) + getSize(i - 1)\n    }\n    updateTime.value = Math.max(updateTime.value, performance.now() - start)\n  }, updateTime)\n\n  const unwatch = watch(hasInitialRender, v => {\n    if (!v) return\n    // First render is complete, update offsets and visible\n    // items in case our assumed item height was incorrect\n\n    unwatch()\n    markerOffset = markerRef.value!.offsetTop\n    updateOffsets.immediate()\n    calculateVisibleItems()\n\n    if (!~targetScrollIndex) return\n\n    nextTick(() => {\n      IN_BROWSER && window.requestAnimationFrame(() => {\n        scrollToIndex(targetScrollIndex)\n        targetScrollIndex = -1\n      })\n    })\n  })\n\n  onScopeDispose(() => {\n    updateOffsets.clear()\n  })\n\n  function handleItemResize (index: number, height: number) {\n    const prevHeight = sizes[index]\n    const prevMinHeight = itemHeight.value\n\n    itemHeight.value = prevMinHeight ? Math.min(itemHeight.value, height) : height\n\n    if (prevHeight !== height || prevMinHeight !== itemHeight.value) {\n      sizes[index] = height\n      updateOffsets()\n    }\n  }\n\n  function calculateOffset (index: number) {\n    index = clamp(index, 0, items.value.length)\n    const whole = Math.floor(index)\n    const fraction = index % 1\n    const next = whole + 1\n    const wholeOffset = offsets[whole] || 0\n    const nextOffset = offsets[next] || wholeOffset\n    return wholeOffset + (nextOffset - wholeOffset) * fraction\n  }\n\n  function calculateIndex (scrollTop: number) {\n    return binaryClosest(offsets, scrollTop)\n  }\n\n  let lastScrollTop = 0\n  let scrollVelocity = 0\n  let lastScrollTime = 0\n\n  watch(viewportHeight, (val, oldVal) => {\n    calculateVisibleItems()\n    if (val < oldVal) {\n      requestAnimationFrame(() => {\n        scrollVelocity = 0\n        calculateVisibleItems()\n      })\n    }\n  })\n\n  let scrollTimeout = -1\n  function handleScroll () {\n    if (!containerRef.value || !markerRef.value) return\n\n    const scrollTop = containerRef.value.scrollTop\n    const scrollTime = performance.now()\n    const scrollDeltaT = scrollTime - lastScrollTime\n\n    if (scrollDeltaT > 500) {\n      scrollVelocity = Math.sign(scrollTop - lastScrollTop)\n\n      // Not super important, only update at the\n      // start of a scroll sequence to avoid reflows\n      markerOffset = markerRef.value.offsetTop\n    } else {\n      scrollVelocity = scrollTop - lastScrollTop\n    }\n\n    lastScrollTop = scrollTop\n    lastScrollTime = scrollTime\n\n    window.clearTimeout(scrollTimeout)\n    scrollTimeout = window.setTimeout(handleScrollend, 500)\n\n    calculateVisibleItems()\n  }\n  function handleScrollend () {\n    if (!containerRef.value || !markerRef.value) return\n\n    scrollVelocity = 0\n    lastScrollTime = 0\n\n    window.clearTimeout(scrollTimeout)\n    calculateVisibleItems()\n  }\n\n  let raf = -1\n  function calculateVisibleItems () {\n    cancelAnimationFrame(raf)\n    raf = requestAnimationFrame(_calculateVisibleItems)\n  }\n  function _calculateVisibleItems () {\n    if (!containerRef.value || !viewportHeight.value || !itemHeight.value) return\n    const scrollTop = lastScrollTop - markerOffset\n    const direction = Math.sign(scrollVelocity)\n\n    const startPx = Math.max(0, scrollTop - BUFFER_PX)\n    const start = clamp(calculateIndex(startPx), 0, items.value.length)\n\n    const endPx = scrollTop + viewportHeight.value + BUFFER_PX\n    const end = clamp(calculateIndex(endPx) + 1, start + 1, items.value.length)\n\n    if (\n      // Only update the side we're scrolling towards,\n      // the other side will be updated incidentally\n      (direction !== UP || start < first.value) &&\n      (direction !== DOWN || end > last.value)\n    ) {\n      const topOverflow = calculateOffset(first.value) - calculateOffset(start)\n      const bottomOverflow = calculateOffset(end) - calculateOffset(last.value)\n      const bufferOverflow = Math.max(topOverflow, bottomOverflow)\n\n      if (bufferOverflow > BUFFER_PX) {\n        first.value = start\n        last.value = end\n      } else {\n        // Only update the side that's reached its limit if there's still buffer left\n        if (start <= 0) first.value = start\n        if (end >= items.value.length) last.value = end\n      }\n    }\n\n    paddingTop.value = calculateOffset(first.value)\n    paddingBottom.value = calculateOffset(items.value.length) - calculateOffset(last.value)\n  }\n\n  function scrollToIndex (index: number) {\n    const offset = calculateOffset(index)\n    if (!containerRef.value || (index && !offset)) {\n      targetScrollIndex = index\n    } else {\n      containerRef.value.scrollTop = offset\n    }\n  }\n\n  const computedItems = computed(() => {\n    return items.value.slice(first.value, last.value).map((item, index) => {\n      const _index = index + first.value\n      return {\n        raw: item,\n        index: _index,\n        key: getPropertyFromItem(item, props.itemKey, _index),\n      }\n    })\n  })\n\n  watch(items, () => {\n    sizes = Array.from({ length: items.value.length })\n    offsets = Array.from({ length: items.value.length })\n    updateOffsets.immediate()\n    calculateVisibleItems()\n  }, { deep: 1 })\n\n  return {\n    calculateVisibleItems,\n    containerRef,\n    markerRef,\n    computedItems,\n    paddingTop,\n    paddingBottom,\n    scrollToIndex,\n    handleScroll,\n    handleScrollend,\n    handleItemResize,\n  }\n}\n\n// https://gist.github.com/robertleeplummerjr/1cc657191d34ecd0a324\nfunction binaryClosest (arr: ArrayLike<number>, val: number) {\n  let high = arr.length - 1\n  let low = 0\n  let mid = 0\n  let item = null\n  let target = -1\n\n  if (arr[high]! < val) {\n    return high\n  }\n\n  while (low <= high) {\n    mid = (low + high) >> 1\n    item = arr[mid]!\n\n    if (item > val) {\n      high = mid - 1\n    } else if (item < val) {\n      target = mid\n      low = mid + 1\n    } else if (item === val) {\n      return mid\n    } else {\n      return low\n    }\n  }\n\n  return target\n}\n"
  },
  {
    "path": "packages/vuetify/src/directives/click-outside/__tests__/click-outside-shadow-dom.spec.ts",
    "content": "// Directives\nimport ClickOutside from '../'\n\n// Utilities\nimport { wait } from '@test'\n\nfunction bootstrap (args?: object) {\n  const outsideEl = document.createElement('div')\n  const shadowHost = document.createElement('div')\n  const shadowRoot = shadowHost.attachShadow({ mode: 'open' })\n  const shadowEl = document.createElement('div')\n\n  const binding = {\n    value: {\n      handler: vi.fn(),\n      ...args,\n    },\n    instance: {\n      $: { uid: 1 },\n    },\n  } as any\n\n  let shadowClickHandler: any\n  let outsideClickHandler: any\n\n  let shadowMousedownHandler: any\n  let outsideMousedownHandler: any\n\n  document.body.appendChild(shadowHost)\n  shadowRoot.appendChild(shadowEl)\n\n  vi.spyOn(window.document, 'addEventListener').mockImplementation((eventName, eventHandler, options) => {\n    if (eventName === 'click') outsideClickHandler = eventHandler\n    if (eventName === 'mousedown') outsideMousedownHandler = eventHandler\n  })\n\n  vi.spyOn(shadowRoot, 'addEventListener').mockImplementation((eventName, eventHandler, options) => {\n    if (eventName === 'click') shadowClickHandler = eventHandler\n    if (eventName === 'mousedown') shadowMousedownHandler = eventHandler\n  })\n\n  vi.spyOn(window.document, 'removeEventListener')\n  vi.spyOn(shadowRoot, 'removeEventListener')\n\n  ClickOutside.mounted(shadowEl as HTMLElement, binding)\n\n  return {\n    binding,\n    callback: binding.value.handler,\n    shadowEl: shadowEl as HTMLElement,\n    outsideEl: outsideEl as HTMLElement,\n    shadowRoot: shadowRoot as Node,\n    shadowClickHandler,\n    outsideClickHandler,\n    shadowMousedownHandler,\n    outsideMousedownHandler,\n  }\n}\n\ndescribe('click-outside.js within the Shadow DOM', () => {\n  it('should register and unregister handler outside of the shadow DOM', () => {\n    const { outsideClickHandler, shadowEl, binding } = bootstrap()\n    expect(window.document.addEventListener).toHaveBeenCalledWith('click', outsideClickHandler, true)\n\n    ClickOutside.beforeUnmount(shadowEl, binding)\n    expect(window.document.removeEventListener).toHaveBeenCalledWith('click', outsideClickHandler, true)\n  })\n\n  it('should register and unregister handler within the shadow DOM', () => {\n    const { shadowClickHandler, shadowRoot, shadowEl, binding } = bootstrap()\n    expect(shadowRoot.addEventListener).toHaveBeenCalledWith('click', shadowClickHandler, true)\n\n    ClickOutside.beforeUnmount(shadowEl, binding)\n    expect(shadowRoot.removeEventListener).toHaveBeenCalledWith('click', shadowClickHandler, true)\n  })\n\n  it('should call the callback when closeConditional returns true and event target is outside the shadow DOM', async () => {\n    const { outsideClickHandler, outsideMousedownHandler, callback, outsideEl } = bootstrap({ closeConditional: () => true })\n    const event = { target: outsideEl }\n\n    outsideMousedownHandler({ target: document.body })\n    outsideClickHandler(event)\n    await wait()\n    expect(callback).toHaveBeenCalledWith(event)\n  })\n\n  it('should call the callback when closeConditional returns true and event target is within the shadow DOM', async () => {\n    const { shadowClickHandler, outsideMousedownHandler, callback, shadowRoot } = bootstrap({ closeConditional: () => true })\n    const event = { target: shadowRoot }\n\n    outsideMousedownHandler({ target: document.body })\n    shadowClickHandler(event)\n    await wait()\n    expect(callback).toHaveBeenCalledWith(event)\n  })\n\n  it('should not call the callback when closeConditional is not provided', async () => {\n    const { shadowClickHandler, outsideMousedownHandler, callback, shadowEl } = bootstrap()\n\n    outsideMousedownHandler({ target: document.body })\n    shadowClickHandler({ target: shadowEl })\n    await wait()\n    expect(callback).not.toHaveBeenCalled()\n  })\n\n  it('should not call the callback when clicked in element within the shadow DOM', async () => {\n    const { shadowClickHandler, outsideMousedownHandler, callback, shadowEl } = bootstrap({ closeConditional: () => true })\n\n    outsideMousedownHandler({ target: document.body })\n    shadowClickHandler({ target: shadowEl })\n    await wait()\n    expect(callback).not.toHaveBeenCalled()\n  })\n\n  it('should not call the callback when mousedown was on the element within the shadow DOM', async () => {\n    const { shadowClickHandler, shadowMousedownHandler, callback, shadowEl } = bootstrap({ closeConditional: () => true })\n    const mousedownEvent = { target: shadowEl }\n    const clickEvent = { target: document.createElement('div') }\n\n    shadowMousedownHandler(mousedownEvent)\n    shadowClickHandler(clickEvent)\n    await wait()\n    expect(callback).not.toHaveBeenCalledWith(clickEvent)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/directives/click-outside/__tests__/click-outside.spec.ts",
    "content": "// Directives\nimport ClickOutside from '../'\n\n// Utilities\nimport { wait } from '@test'\n\nfunction bootstrap (args?: object) {\n  const el = document.createElement('div')\n  const el2 = document.createElement('div')\n\n  const binding = {\n    value: {\n      handler: vi.fn(),\n      ...args,\n    },\n    instance: {\n      $: { uid: 1 },\n    },\n  } as any\n\n  let clickHandler: any\n  let mousedownHandler: any\n  vi.spyOn(window.document, 'addEventListener').mockImplementation((eventName, eventHandler, options) => {\n    if (eventName === 'click') clickHandler = eventHandler\n    if (eventName === 'mousedown') mousedownHandler = eventHandler\n  })\n  vi.spyOn(window.document, 'removeEventListener')\n\n  ClickOutside.mounted(el as HTMLElement, binding)\n\n  return {\n    binding,\n    callback: binding.value.handler,\n    el: el as HTMLElement,\n    el2: el2 as HTMLElement,\n    clickHandler,\n    mousedownHandler,\n  }\n}\n\ndescribe('v-click-outside', () => {\n  it('should register and unregister handler', () => {\n    const { clickHandler, el, binding } = bootstrap()\n    expect(window.document.addEventListener).toHaveBeenCalledWith('click', clickHandler, true)\n\n    ClickOutside.beforeUnmount(el, binding)\n    expect(window.document.removeEventListener).toHaveBeenCalledWith('click', clickHandler, true)\n  })\n\n  it('should call the callback when closeConditional returns true', async () => {\n    const { clickHandler, mousedownHandler, callback } = bootstrap({ closeConditional: () => true })\n    const event = { target: document.createElement('div') }\n\n    mousedownHandler({ target: document.body })\n    clickHandler(event)\n    await wait()\n    expect(callback).toHaveBeenCalledWith(event)\n  })\n\n  it('should not call the callback when closeConditional returns false', async () => {\n    const { clickHandler, mousedownHandler, callback, el } = bootstrap({ closeConditional: () => false })\n\n    mousedownHandler({ target: document.body })\n    clickHandler({ target: el })\n    await wait()\n    expect(callback).not.toHaveBeenCalled()\n  })\n\n  it('should not call the callback when closeConditional is not provided', async () => {\n    const { clickHandler, mousedownHandler, callback, el } = bootstrap()\n\n    mousedownHandler({ target: document.body })\n    clickHandler({ target: el })\n    await wait()\n    expect(callback).not.toHaveBeenCalled()\n  })\n\n  it('should not call the callback when clicked in element', async () => {\n    const { clickHandler, mousedownHandler, callback, el } = bootstrap({ closeConditional: () => true })\n\n    mousedownHandler({ target: document.body })\n    clickHandler({ target: el })\n    await wait()\n    expect(callback).not.toHaveBeenCalled()\n  })\n\n  it('should not call the callback when clicked in included element', async () => {\n    const { clickHandler, mousedownHandler, callback, el2 } = bootstrap({\n      closeConditional: () => true,\n      include: () => [el2],\n    })\n\n    mousedownHandler({ target: document.body })\n    clickHandler({ target: el2 })\n    await wait()\n    expect(callback).not.toHaveBeenCalled()\n  })\n\n  it('should not call the callback when mousedown was on the element', async () => {\n    const { clickHandler, mousedownHandler, callback, el } = bootstrap({ closeConditional: () => true })\n    const mousedownEvent = { target: el }\n    const clickEvent = { target: document.createElement('div') }\n\n    mousedownHandler(mousedownEvent)\n    clickHandler(clickEvent)\n    await wait()\n    expect(callback).not.toHaveBeenCalledWith(clickEvent)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/directives/click-outside/index.ts",
    "content": "// Utilities\nimport { attachedRoot } from '@/util'\n\n// Types\nimport type { DirectiveBinding } from 'vue'\n\ninterface ClickOutsideBindingArgs {\n  handler: (e: MouseEvent) => void\n  closeConditional?: (e: Event) => boolean\n  include?: () => HTMLElement[]\n}\n\ninterface ClickOutsideDirectiveBinding extends DirectiveBinding {\n  value: ((e: MouseEvent) => void) | ClickOutsideBindingArgs\n}\n\nfunction defaultConditional () {\n  return true\n}\n\nfunction checkEvent (e: MouseEvent, el: HTMLElement, binding: ClickOutsideDirectiveBinding): boolean {\n  // The include element callbacks below can be expensive\n  // so we should avoid calling them when we're not active.\n  // Explicitly check for false to allow fallback compatibility\n  // with non-toggleable components\n  if (!e || checkIsActive(e, binding) === false) return false\n\n  // If we're clicking inside the shadowroot, then the app root doesn't get the same\n  // level of introspection as to _what_ we're clicking. We want to check to see if\n  // our target is the shadowroot parent container, and if it is, ignore.\n  const root = attachedRoot(el)\n  if (\n    typeof ShadowRoot !== 'undefined' &&\n    root instanceof ShadowRoot &&\n    root.host === e.target\n  ) return false\n\n  // Check if additional elements were passed to be included in check\n  // (click must be outside all included elements, if any)\n  const elements = ((typeof binding.value === 'object' && binding.value.include) || (() => []))()\n  // Add the root element for the component this directive was defined on\n  elements.push(el)\n\n  // Check if it's a click outside our elements, and then if our callback returns true.\n  // Non-toggleable components should take action in their callback and return falsy.\n  // Toggleable can return true if it wants to deactivate.\n  // Note that, because we're in the capture phase, this callback will occur before\n  // the bubbling click event on any outside elements.\n  return !elements.some(el => el?.contains(e.target as Node))\n}\n\nfunction checkIsActive (e: MouseEvent, binding: ClickOutsideDirectiveBinding): boolean | void {\n  const isActive = (typeof binding.value === 'object' && binding.value.closeConditional) || defaultConditional\n\n  return isActive(e)\n}\n\nfunction directive (e: MouseEvent, el: HTMLElement, binding: ClickOutsideDirectiveBinding) {\n  const handler = typeof binding.value === 'function' ? binding.value : binding.value.handler\n\n  // Clicks in the Shadow DOM change their target while using setTimeout, so the original target is saved here\n  e.shadowTarget = e.target\n\n  el._clickOutside!.lastMousedownWasOutside && checkEvent(e, el, binding) && setTimeout(() => {\n    checkIsActive(e, binding) && handler && handler(e)\n  }, 0)\n}\n\nfunction handleShadow (el: HTMLElement, callback: Function): void {\n  const root = attachedRoot(el)\n\n  callback(document)\n\n  if (typeof ShadowRoot !== 'undefined' && root instanceof ShadowRoot) {\n    callback(root)\n  }\n}\n\nexport const ClickOutside = {\n  // [data-app] may not be found\n  // if using bind, inserted makes\n  // sure that the root element is\n  // available, iOS does not support\n  // clicks on body\n  mounted (el: HTMLElement, binding: ClickOutsideDirectiveBinding) {\n    const onClick = (e: Event) => directive(e as MouseEvent, el, binding)\n    const onMousedown = (e: Event) => {\n      el._clickOutside!.lastMousedownWasOutside = checkEvent(e as MouseEvent, el, binding)\n    }\n\n    handleShadow(el, (app: HTMLElement) => {\n      app.addEventListener('click', onClick, true)\n      app.addEventListener('mousedown', onMousedown, true)\n    })\n    if (!el._clickOutside) {\n      el._clickOutside = {\n        lastMousedownWasOutside: false,\n      }\n    }\n\n    el._clickOutside[binding.instance!.$.uid] = {\n      onClick,\n      onMousedown,\n    }\n  },\n\n  beforeUnmount (el: HTMLElement, binding: ClickOutsideDirectiveBinding) {\n    if (!el._clickOutside) return\n\n    handleShadow(el, (app: HTMLElement) => {\n      if (!app || !el._clickOutside?.[binding.instance!.$.uid]) return\n\n      const { onClick, onMousedown } = el._clickOutside[binding.instance!.$.uid]!\n\n      app.removeEventListener('click', onClick, true)\n      app.removeEventListener('mousedown', onMousedown, true)\n    })\n\n    delete el._clickOutside[binding.instance!.$.uid]\n  },\n}\n\nexport default ClickOutside\n"
  },
  {
    "path": "packages/vuetify/src/directives/color/__tests__/color.spec.ts",
    "content": "// @ts-nocheck\n/* eslint-disable */\n\n// Vue\n// import Vue from 'vue'\n\n// Directives\n// import Color from '../'\n\n// Utilities\nimport {\n  mount,\n  Wrapper,\n} from '@vue/test-utils'\n\ndescribe.skip('color.ts', () => {\n  let mountFunction: () => Wrapper<Vue>\n\n  beforeEach(() => {\n    mountFunction = (directive = {}) => {\n      return mount(Vue.component('test', {\n        directives: { Color },\n        data: () => ({\n          color: '',\n        }),\n        render (h) {\n          return h('div', {\n            directives: [{\n              ...directive,\n              value: this.color,\n            }],\n          })\n        },\n      }), {\n        mocks: {\n          $vuetify: {\n            theme: {\n              currentTheme: {\n                primary: '#1976d2',\n              },\n            },\n          },\n        },\n      })\n    }\n  })\n\n  it('should set background color', async () => {\n    const wrapper = mountFunction({\n      name: 'color',\n    })\n\n    wrapper.setData({ color: '#01f' })\n    expect(wrapper.element.style.backgroundColor).toEqual('rgb(0, 17, 255)')\n    expect(wrapper.element.style.borderColor).toEqual('#01f')\n\n    wrapper.setData({ color: 'rgb(255, 255, 0)' })\n    expect(wrapper.element.style.backgroundColor).toEqual('rgb(255, 255, 0)')\n    expect(wrapper.element.style.borderColor).toEqual('rgb(255, 255, 0)')\n\n    wrapper.setData({ color: 'red' })\n    expect(wrapper.element.style.backgroundColor).toEqual('rgb(244, 67, 54)')\n    expect(wrapper.element.style.borderColor).toEqual('#f44336')\n\n    wrapper.setData({ color: 'red lighten-1' })\n    expect(wrapper.element.style.backgroundColor).toEqual('rgb(239, 83, 80)')\n    expect(wrapper.element.style.borderColor).toEqual('#ef5350')\n\n    wrapper.setData({ color: 'primary' })\n    expect(wrapper.element.style.backgroundColor).toEqual('rgb(25, 118, 210)')\n    expect(wrapper.element.style.borderColor).toEqual('#1976d2')\n  })\n\n  it('should set text color', async () => {\n    const wrapper = mountFunction({\n      name: 'color',\n      arg: 'text',\n    })\n\n    wrapper.setData({ color: '#01f' })\n    expect(wrapper.element.style.color).toEqual('rgb(0, 17, 255)')\n    expect(wrapper.element.style.caretColor).toEqual('#01f')\n\n    wrapper.setData({ color: 'rgba(0, 1, 2, 0.5)' })\n    expect(wrapper.element.style.color).toEqual('rgba(0, 1, 2, 0.5)')\n    expect(wrapper.element.style.caretColor).toEqual('rgba(0, 1, 2, 0.5)')\n\n    wrapper.setData({ color: 'red' })\n    expect(wrapper.element.style.color).toEqual('rgb(244, 67, 54)')\n    expect(wrapper.element.style.caretColor).toEqual('#f44336')\n\n    wrapper.setData({ color: 'red lighten-1' })\n    expect(wrapper.element.style.color).toEqual('rgb(239, 83, 80)')\n    expect(wrapper.element.style.caretColor).toEqual('#ef5350')\n\n    wrapper.setData({ color: 'primary' })\n    expect(wrapper.element.style.color).toEqual('rgb(25, 118, 210)')\n    expect(wrapper.element.style.caretColor).toEqual('#1976d2')\n  })\n\n  it('should set border color', async () => {\n    const wrapper = mountFunction({\n      name: 'color',\n      arg: 'border',\n    })\n\n    wrapper.setData({ color: '#01f' })\n    expect(wrapper.element.style.borderColor).toEqual('#01f')\n\n    wrapper.setData({ color: 'rgb(255, 255, 0)' })\n    expect(wrapper.element.style.borderColor).toEqual('rgb(255, 255, 0)')\n\n    wrapper.setData({ color: 'red' })\n    expect(wrapper.element.style.borderColor).toEqual('#f44336')\n\n    wrapper.setData({ color: 'red lighten-1' })\n    expect(wrapper.element.style.borderColor).toEqual('#ef5350')\n\n    wrapper.setData({ color: 'primary' })\n    expect(wrapper.element.style.borderColor).toEqual('#1976d2')\n  })\n\n  it('should respect border sides modifiers', async () => {\n    const wrapper = mountFunction({\n      name: 'color',\n      arg: 'border',\n      modifiers: { top: true, right: true, left: true },\n    })\n\n    wrapper.setData({ color: '#fff' })\n    expect(wrapper.element.style.borderTopColor).toEqual('#fff')\n    expect(wrapper.element.style.borderRightColor).toEqual('#fff')\n    expect(wrapper.element.style.borderLeftColor).toEqual('#fff')\n    expect(wrapper.element.style.borderBottomColor).toEqual('')\n    expect(wrapper.element.style.borderColor).toEqual('')\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/directives/color/index.ts",
    "content": "// @ts-nocheck\n/* eslint-disable */\n\n// Utilities\nimport {\n  classToHex,\n  isCssColor,\n  parseGradient,\n} from '../../util/colorUtils'\nimport colors from '../../util/colors'\n\n// Types\nimport { VuetifyThemeVariant } from 'types/services/theme'\nimport { VNode, VNodeDirective } from 'vue'\n\ninterface BorderModifiers {\n  top?: Boolean\n  right?: Boolean\n  bottom?: Boolean\n  left?: Boolean\n}\n\nfunction setTextColor (\n  el: HTMLElement,\n  color: string,\n  currentTheme: Partial<VuetifyThemeVariant>,\n) {\n  const cssColor = !isCssColor(color) ? classToHex(color, colors, currentTheme) : color\n\n  el.style.color = cssColor\n  el.style.caretColor = cssColor\n}\n\nfunction setBackgroundColor (\n  el: HTMLElement,\n  color: string,\n  currentTheme: Partial<VuetifyThemeVariant>,\n) {\n  const cssColor = !isCssColor(color) ? classToHex(color, colors, currentTheme) : color\n\n  el.style.backgroundColor = cssColor\n  el.style.borderColor = cssColor\n}\n\nfunction setBorderColor (\n  el: HTMLElement,\n  color: string,\n  currentTheme: Partial<VuetifyThemeVariant>,\n  modifiers?: BorderModifiers,\n) {\n  const cssColor = !isCssColor(color) ? classToHex(color, colors, currentTheme) : color\n\n  if (!modifiers || !Object.keys(modifiers).length) {\n    el.style.borderColor = cssColor\n    return\n  }\n\n  if (modifiers.top) el.style.borderTopColor = cssColor\n  if (modifiers.right) el.style.borderRightColor = cssColor\n  if (modifiers.bottom) el.style.borderBottomColor = cssColor\n  if (modifiers.left) el.style.borderLeftColor = cssColor\n}\n\nfunction setGradientColor (\n  el: HTMLElement,\n  gradient: string,\n  currentTheme: Partial<VuetifyThemeVariant>,\n) {\n  el.style.backgroundImage = `linear-gradient(${\n    parseGradient(gradient, colors, currentTheme)\n  })`\n}\n\nfunction updateColor (\n  el: HTMLElement,\n  binding: VNodeDirective,\n  node: VNode\n) {\n  const currentTheme = node.context!.$vuetify.theme.currentTheme\n\n  if (binding.arg === undefined) {\n    setBackgroundColor(el, binding.value, currentTheme)\n  } else if (binding.arg === 'text') {\n    setTextColor(el, binding.value, currentTheme)\n  } else if (binding.arg === 'border') {\n    setBorderColor(el, binding.value, currentTheme, binding.modifiers)\n  } else if (binding.arg === 'gradient') {\n    setGradientColor(el, binding.value, currentTheme)\n  }\n}\n\nfunction update (\n  el: HTMLElement,\n  binding: VNodeDirective,\n  node: VNode\n) {\n  if (binding.value === binding.oldValue) return\n\n  updateColor(el, binding, node)\n}\n\nexport const Color = {\n  bind: updateColor,\n  update,\n}\n\nexport default Color\n"
  },
  {
    "path": "packages/vuetify/src/directives/index.ts",
    "content": "export { ClickOutside } from './click-outside'\n// export { Color } from './color'\nexport { Intersect } from './intersect'\nexport { Mutate } from './mutate'\nexport { Resize } from './resize'\nexport { Ripple } from './ripple'\nexport { Scroll } from './scroll'\nexport { Touch } from './touch'\nexport { Tooltip } from './tooltip'\n"
  },
  {
    "path": "packages/vuetify/src/directives/intersect/__tests__/intersect.spec.browser.tsx",
    "content": "// Directives\nimport vIntersect from '../'\n\n// Utilities\nimport { scroll, waitIdle } from '@test'\nimport { render, screen } from '@testing-library/vue'\n\ndescribe('v-intersect', () => {\n  it('binds event on mounted', async () => {\n    const callback = vi.fn()\n\n    render({\n      directives: { vIntersect },\n      setup () {\n        return () => <div v-intersect={ callback } style=\"height: 10px\" />\n      },\n    })\n\n    await waitIdle()\n\n    expect(callback).toHaveBeenCalled()\n  })\n\n  // TODO: flaky, sometimes triggers with isIntersecting=false\n  it.todo('does not callback on mount when quiet', async () => {\n    const callback = vi.fn()\n\n    render({\n      directives: { vIntersect },\n      setup () {\n        return () => <div v-intersect={[callback, null, ['quiet']]} style=\"height: 10px\" />\n      },\n    })\n\n    await waitIdle()\n\n    expect(callback).not.toHaveBeenCalled()\n  })\n\n  describe('once', () => {\n    async function setup (height: string, quiet: boolean) {\n      const callback = vi.fn()\n\n      render({\n        directives: { vIntersect },\n        setup () {\n          return () => (\n            <>\n              <div style={{ height }} />\n              { quiet // directive modifiers are static\n                ? <div v-intersect={[callback, null, ['once', 'quiet']]} style=\"height: 10px\">el</div>\n                : <div v-intersect={[callback, null, ['once']]} style=\"height: 10px\">el</div>\n              }\n              <div style=\"height: 1000px\" />\n            </>\n          )\n        },\n      })\n\n      const el = screen.getByText('el')\n      expect(Object.keys(el._observe!)).toHaveLength(1)\n\n      await waitIdle()\n      return { callback, el }\n    }\n\n    it.each([\n      ['initially in', '100px', false, 1, 0, 1],\n      ['initially out', '120vh', false, 0, 1, 1],\n      // ['initially in - quiet', '100px', true, 0, 1, 1], // TODO: flaky\n      // ['initially out - quiet', '120vh', true, 0, 1, 1],\n    ])('%s', async (name, height, quiet, ...v) => {\n      const { callback, el } = await setup(height, quiet)\n\n      expect(callback).toHaveBeenCalledTimes(v[0])\n      expect(Object.keys(el._observe!)).toHaveLength(v[1])\n\n      el.scrollIntoView()\n      await waitIdle()\n      expect(callback).toHaveBeenCalledTimes(v[2])\n      expect(Object.keys(el._observe!)).toHaveLength(0)\n      callback.mockClear()\n\n      await scroll({ top: 1000 })\n      expect(callback).not.toHaveBeenCalled()\n\n      el.scrollIntoView()\n      await waitIdle()\n      expect(callback).not.toHaveBeenCalled()\n    })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/directives/intersect/index.ts",
    "content": "// Utilities\nimport { SUPPORTS_INTERSECTION } from '@/util'\n\n// Types\nimport type {\n  DirectiveBinding,\n} from 'vue'\n\ntype ObserveHandler = (\n  isIntersecting: boolean,\n  entries: IntersectionObserverEntry[],\n  observer: IntersectionObserver,\n) => void\n\nexport interface ObserveDirectiveBinding extends Omit<DirectiveBinding, 'modifiers' | 'value'> {\n  value?: ObserveHandler | { handler: ObserveHandler, options?: IntersectionObserverInit }\n  modifiers: {\n    once?: boolean\n    quiet?: boolean\n  }\n}\n\nfunction mounted (el: HTMLElement, binding: ObserveDirectiveBinding) {\n  if (!SUPPORTS_INTERSECTION) return\n\n  const modifiers = binding.modifiers || {}\n  const value = binding.value\n  const { handler, options } = typeof value === 'object'\n    ? value\n    : { handler: value, options: {} }\n\n  const observer = new IntersectionObserver((\n    entries: IntersectionObserverEntry[] = [],\n    observer: IntersectionObserver\n  ) => {\n    const _observe = el._observe?.[binding.instance!.$.uid]\n    if (!_observe) return // Just in case, should never fire\n\n    const isIntersecting = entries.some(entry => entry.isIntersecting)\n\n    // If is not quiet or has already been\n    // initted, invoke the user callback\n    if (\n      handler && (\n        !modifiers.quiet ||\n        _observe.init\n      ) && (\n        !modifiers.once ||\n        isIntersecting ||\n        _observe.init\n      )\n    ) {\n      handler(isIntersecting, entries, observer)\n    }\n\n    if (isIntersecting && modifiers.once) unmounted(el, binding)\n    else _observe.init = true\n  }, options)\n\n  el._observe = Object(el._observe)\n  el._observe![binding.instance!.$.uid] = { init: false, observer }\n\n  observer.observe(el)\n}\n\nfunction unmounted (el: HTMLElement, binding: ObserveDirectiveBinding) {\n  const observe = el._observe?.[binding.instance!.$.uid]\n  if (!observe) return\n\n  observe.observer.unobserve(el)\n  delete el._observe![binding.instance!.$.uid]\n}\n\nexport const Intersect = {\n  mounted,\n  unmounted,\n  updated: (el: HTMLElement, binding: ObserveDirectiveBinding) => {\n    if (el._observe?.[binding.instance!.$.uid]) {\n      unmounted(el, binding)\n      mounted(el, binding)\n    }\n  },\n}\n\nexport default Intersect\n"
  },
  {
    "path": "packages/vuetify/src/directives/mutate/__tests__/mutate.spec.ts",
    "content": "// Directives\nimport Mutate from '..'\n\n// Utilities\n\n// Utilities\n\n(global as any).MutationObserver = class { // Mock MutationObserver\n  _callback: Function\n\n  _observe = vi.fn()\n\n  constructor (callback: () => {}) {\n    this._callback = callback\n  }\n\n  disconnect () {}\n\n  observe (_: any, options = {}) {\n    this._observe(options)\n  }\n\n  trigger (evts: MutationRecord[]) { // Trigger this manually in tests\n    this._callback(evts, this)\n  }\n}\n\nconst instance = {\n  $: { uid: 1 },\n}\n\ndescribe('v-mutate', () => {\n  it('should bind event on mounted', () => {\n    const callback = vi.fn()\n    const el = document.createElement('div')\n    document.body.appendChild(el)\n\n    Mutate.mounted(el, {\n      value: callback,\n      modifiers: {},\n      instance,\n    } as any)\n\n    expect(el._mutate).toBeTruthy()\n    expect(callback).not.toHaveBeenCalled()\n\n    document.body.removeChild(el)\n\n    Mutate.unmounted(el, { instance } as any)\n\n    expect(el._mutate![1]).toBeUndefined()\n  })\n\n  it('should invoke callback once and then unmount', async () => {\n    const callback = vi.fn()\n    const el = document.createElement('div')\n    document.body.appendChild(el)\n\n    Mutate.mounted(el, {\n      value: callback,\n      modifiers: { once: true },\n      instance,\n    } as any)\n\n    expect(callback).not.toHaveBeenCalled()\n    expect(el._mutate).toBeTruthy()\n\n    ;(el._mutate![1]!.observer as any)?.trigger([])\n\n    expect(callback).toHaveBeenCalledTimes(1)\n    expect(el._mutate![1]).toBeUndefined()\n  })\n\n  it('should invoke callback on mount, on mutation and then unmount', async () => {\n    const callback = vi.fn()\n    const el = document.createElement('div')\n    document.body.appendChild(el)\n\n    Mutate.mounted(el, {\n      value: callback,\n      modifiers: { immediate: true, once: true },\n      instance,\n    } as any)\n\n    expect(callback).toHaveBeenCalledTimes(1)\n    expect(el._mutate).toBeTruthy()\n\n    ;(el._mutate![1]!.observer as any)?.trigger([])\n\n    expect(callback).toHaveBeenCalledTimes(2)\n    expect(el._mutate![1]).toBeUndefined()\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/directives/mutate/index.ts",
    "content": "// Types\nimport type { DirectiveBinding } from 'vue'\nimport type { MutationOptions } from '@/composables/mutationObserver'\n\nexport interface MutationDirectiveBinding extends Omit<DirectiveBinding, 'modifiers' | 'value'> {\n  value: MutationCallback | { handler: MutationCallback, options?: MutationObserverInit }\n  modifiers: MutationOptions\n}\n\nfunction mounted (el: HTMLElement, binding: MutationDirectiveBinding) {\n  const modifiers = binding.modifiers || {}\n  const value = binding.value\n  const { once, immediate, ...modifierKeys } = modifiers\n  const defaultValue = !Object.keys(modifierKeys).length\n\n  const { handler, options } = typeof value === 'object'\n    ? value\n    : {\n      handler: value,\n      options: {\n        attributes: modifierKeys?.attr ?? defaultValue,\n        characterData: modifierKeys?.char ?? defaultValue,\n        childList: modifierKeys?.child ?? defaultValue,\n        subtree: modifierKeys?.sub ?? defaultValue,\n      },\n    }\n\n  const observer = new MutationObserver((\n    mutations: MutationRecord[] = [],\n    observer: MutationObserver\n  ) => {\n    handler?.(mutations, observer)\n\n    if (once) unmounted(el, binding)\n  })\n\n  if (immediate) handler?.([], observer)\n\n  el._mutate = Object(el._mutate)\n  el._mutate![binding.instance!.$.uid] = { observer }\n\n  observer.observe(el, options)\n}\n\nfunction unmounted (el: HTMLElement, binding: MutationDirectiveBinding) {\n  if (!el._mutate?.[binding.instance!.$.uid]) return\n\n  el._mutate[binding.instance!.$.uid]!.observer.disconnect()\n  delete el._mutate[binding.instance!.$.uid]\n}\n\nexport const Mutate = {\n  mounted,\n  unmounted,\n}\n\nexport default Mutate\n"
  },
  {
    "path": "packages/vuetify/src/directives/resize/__tests__/resize.spec.ts",
    "content": "// Directives\nimport Resize from '../'\n\n// Utilities\n\n// Types\nimport type { Mock } from 'vitest'\n\nconst instance = {\n  $: { uid: 1 },\n}\n\ndescribe('v-resize', () => {\n  it('should bind event on inserted', () => {\n    const callback = vi.fn()\n\n    vi.spyOn(window, 'addEventListener')\n    vi.spyOn(window, 'removeEventListener')\n\n    const el = {}\n\n    Resize.mounted!(el as HTMLElement, { value: callback, instance } as any)\n    expect(callback).toHaveBeenCalledWith()\n    expect(window.addEventListener).toHaveBeenCalledWith('resize', callback, { passive: true })\n\n    Resize.unmounted!(el as HTMLElement, { value: callback, instance } as any)\n    expect(window.removeEventListener).toHaveBeenCalledWith('resize', callback, { passive: true })\n\n    ;(window.addEventListener as Mock).mockClear()\n    ;(window.removeEventListener as Mock).mockClear()\n  })\n\n  it('should not run the callback in quiet mode', () => {\n    const callback = vi.fn()\n\n    vi.spyOn(window, 'addEventListener')\n    vi.spyOn(window, 'removeEventListener')\n\n    const el = {}\n\n    Resize.mounted!(el as HTMLElement, { value: callback, modifiers: { quiet: true }, instance } as any)\n    expect(callback).not.toHaveBeenCalled()\n    expect(window.addEventListener).toHaveBeenCalledWith('resize', callback, { passive: true })\n\n    Resize.unmounted!(el as HTMLElement, { value: callback, modifiers: { quiet: true }, instance } as any)\n    expect(window.removeEventListener).toHaveBeenCalledWith('resize', callback, { passive: true })\n\n    ;(window.addEventListener as Mock).mockClear()\n    ;(window.removeEventListener as Mock).mockClear()\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/directives/resize/index.ts",
    "content": "// Types\nimport type { DirectiveBinding } from 'vue'\n\ninterface ResizeDirectiveBinding extends Omit<DirectiveBinding, 'modifiers'> {\n  value: () => void\n  modifiers?: {\n    active?: boolean\n    quiet?: boolean\n  }\n}\n\nfunction mounted (el: HTMLElement, binding: ResizeDirectiveBinding) {\n  const handler = binding.value\n  const options: AddEventListenerOptions = {\n    passive: !binding.modifiers?.active,\n  }\n\n  window.addEventListener('resize', handler, options)\n\n  el._onResize = Object(el._onResize)\n  el._onResize![binding.instance!.$.uid] = {\n    handler,\n    options,\n  }\n\n  if (!binding.modifiers?.quiet) {\n    handler()\n  }\n}\n\nfunction unmounted (el: HTMLElement, binding: ResizeDirectiveBinding) {\n  if (!el._onResize?.[binding.instance!.$.uid]) return\n\n  const { handler, options } = el._onResize[binding.instance!.$.uid]!\n\n  window.removeEventListener('resize', handler, options)\n\n  delete el._onResize[binding.instance!.$.uid]\n}\n\nexport const Resize = {\n  mounted,\n  unmounted,\n}\n\nexport default Resize\n"
  },
  {
    "path": "packages/vuetify/src/directives/ripple/VRipple.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-ripple\n    &__container\n      color: inherit\n      border-radius: inherit\n      position: absolute\n      width: 100%\n      height: 100%\n      left: 0\n      top: 0\n      overflow: hidden\n      z-index: 0\n      pointer-events: none\n      contain: strict\n\n    &__animation\n      color: inherit\n      position: absolute\n      top: 0\n      left: 0\n      border-radius: 50%\n      background: currentColor\n      opacity: 0\n      pointer-events: none\n      overflow: hidden\n      will-change: transform, opacity\n\n      &--enter\n        transition: none\n        opacity: 0\n\n      &--in\n        transition: $ripple-animation-transition-in\n        opacity: $ripple-animation-visible-opacity\n\n        @media (prefers-reduced-motion: reduce)\n          transition-property: opacity\n          transition-duration: 0.1s\n\n      &--out\n        transition: $ripple-animation-transition-out\n        opacity: 0\n"
  },
  {
    "path": "packages/vuetify/src/directives/ripple/__tests__/ripple.spec.ts",
    "content": "// Directives\nimport Ripple from '../'\n\n// Utilities\nimport { mount } from '@vue/test-utils'\nimport { defineComponent } from 'vue'\n\nconst testComponent = defineComponent({\n  directives: { Ripple },\n  template: '<div class=\"a\" v-ripple />',\n})\n\ndescribe('v-ripple', () => {\n  it('with no value should be enabled', () => {\n    const wrapper = mount(testComponent)\n\n    expect(wrapper.element._ripple?.enabled).toBe(true)\n  })\n\n  it('should update element property reactively', async () => {\n    const wrapper = mount({\n      directives: { Ripple },\n      props: {\n        ripple: {\n          type: Boolean,\n          default: true,\n        },\n      },\n      template: '<div class=\"a\" v-ripple=\"ripple\" />',\n    })\n    const el = wrapper.element\n\n    expect(el._ripple?.enabled).toBe(true)\n\n    await wrapper.setProps({ ripple: false })\n    expect(el._ripple?.enabled).toBe(false)\n\n    await wrapper.setProps({ ripple: true })\n    expect(el._ripple?.enabled).toBe(true)\n  })\n\n  it('should trigger ripple on mousedown', () => {\n    vi.useFakeTimers()\n    const wrapper = mount(testComponent)\n\n    const mousedownEvent = new MouseEvent('mousedown')\n    wrapper.element.dispatchEvent(mousedownEvent)\n\n    expect(wrapper.find('.v-ripple__container').exists()).toBe(true)\n\n    const mouseupEvent = new MouseEvent('mouseup')\n    wrapper.element.dispatchEvent(mouseupEvent)\n\n    vi.runAllTimers()\n    expect(wrapper.find('.v-ripple__container').exists()).toBe(false)\n  })\n\n  it.each(['Enter', 'Space'] as const)('should trigger ripple on %s key press', key => {\n    vi.useFakeTimers()\n    const wrapper = mount(testComponent)\n\n    const keydownEvent = new KeyboardEvent('keydown', { key })\n    wrapper.element.dispatchEvent(keydownEvent)\n\n    expect(wrapper.find('.v-ripple__container').exists()).toBe(true)\n\n    const keyupEvent = new KeyboardEvent('keyup')\n    wrapper.element.dispatchEvent(keyupEvent)\n\n    vi.runAllTimers()\n    expect(wrapper.find('.v-ripple__container').exists()).toBe(false)\n  })\n\n  it('should only ripple on one element', () => {\n    vi.useFakeTimers()\n\n    const wrapper = mount({\n      directives: { Ripple },\n      template: '<div v-ripple><div class=\"child\" v-ripple></div></div>',\n    })\n\n    const child = wrapper.find('.child').element\n\n    const mousedownEvent = new MouseEvent('mousedown', { detail: 1, bubbles: true })\n    child.dispatchEvent(mousedownEvent)\n\n    expect(wrapper.findAll('.v-ripple__container')).toHaveLength(1)\n\n    const mouseupEvent = new MouseEvent('mouseup', { detail: 1, bubbles: true })\n    child.dispatchEvent(mouseupEvent)\n\n    vi.runAllTimers()\n    expect(wrapper.findAll('.v-ripple__container')).toHaveLength(0)\n  })\n\n  it('should hide ripple on blur if keyboardRipple is true', () => {\n    vi.useFakeTimers()\n    const wrapper = mount(testComponent)\n    const keydownEvent = new KeyboardEvent('keydown', { key: 'Enter' })\n    wrapper.element.dispatchEvent(keydownEvent)\n\n    expect(wrapper.find('.v-ripple__container').exists()).toBe(true)\n\n    const blurEvent = new FocusEvent('blur')\n    wrapper.element.dispatchEvent(blurEvent)\n\n    vi.runAllTimers()\n    expect(wrapper.find('.v-ripple__container').exists()).toBe(false)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/directives/ripple/_variables.scss",
    "content": "@use '../../styles/settings';\n\n$ripple-animation-transition-in: transform .25s settings.$decelerated-easing,\n                                 opacity .1s settings.$decelerated-easing !default;\n$ripple-animation-transition-out: opacity .3s settings.$decelerated-easing !default;\n$ripple-animation-visible-opacity: calc(.25 * var(--v-theme-overlay-multiplier)) !default;\n"
  },
  {
    "path": "packages/vuetify/src/directives/ripple/index.ts",
    "content": "// Styles\nimport './VRipple.sass'\n\n// Utilities\nimport { isObject } from '@/util'\n\n// Types\nimport type { DirectiveBinding } from 'vue'\n\nconst stopSymbol = Symbol('rippleStop')\n\ntype VuetifyRippleEvent = (MouseEvent | TouchEvent | KeyboardEvent) & { [stopSymbol]?: boolean }\n\nconst DELAY_RIPPLE = 80\n\nfunction transform (el: HTMLElement, value: string) {\n  el.style.transform = value\n  el.style.webkitTransform = value\n}\n\ninterface RippleOptions {\n  class?: string\n  center?: boolean\n  circle?: boolean\n}\n\nexport interface RippleDirectiveBinding extends Omit<DirectiveBinding, 'modifiers' | 'value'> {\n  value?: boolean | {\n    class?: string\n    keys?: string[]\n  }\n  modifiers: {\n    center?: boolean\n    circle?: boolean\n    stop?: boolean\n  }\n}\n\nfunction isTouchEvent (e: VuetifyRippleEvent): e is TouchEvent {\n  return e.constructor.name === 'TouchEvent'\n}\n\nfunction isKeyboardEvent (e: VuetifyRippleEvent): e is KeyboardEvent {\n  return e.constructor.name === 'KeyboardEvent'\n}\n\nconst calculate = (\n  e: VuetifyRippleEvent,\n  el: HTMLElement,\n  value: RippleOptions = {}\n) => {\n  let localX = 0\n  let localY = 0\n\n  if (!isKeyboardEvent(e)) {\n    const offset = el.getBoundingClientRect()\n    const target = isTouchEvent(e) ? e.touches[e.touches.length - 1] : e\n\n    localX = target.clientX - offset.left\n    localY = target.clientY - offset.top\n  }\n\n  let radius = 0\n  let scale = 0.3\n  if (el._ripple?.circle) {\n    scale = 0.15\n    radius = el.clientWidth / 2\n    radius = value.center ? radius : radius + Math.sqrt((localX - radius) ** 2 + (localY - radius) ** 2) / 4\n  } else {\n    radius = Math.sqrt(el.clientWidth ** 2 + el.clientHeight ** 2) / 2\n  }\n\n  const centerX = `${(el.clientWidth - (radius * 2)) / 2}px`\n  const centerY = `${(el.clientHeight - (radius * 2)) / 2}px`\n\n  const x = value.center ? centerX : `${localX - radius}px`\n  const y = value.center ? centerY : `${localY - radius}px`\n\n  return { radius, scale, x, y, centerX, centerY }\n}\n\nconst ripples = {\n  /* eslint-disable max-statements */\n  show (\n    e: VuetifyRippleEvent,\n    el: HTMLElement,\n    value: RippleOptions = {}\n  ) {\n    if (!el?._ripple?.enabled) {\n      return\n    }\n\n    const container = document.createElement('span')\n    const animation = document.createElement('span')\n\n    container.appendChild(animation)\n    container.className = 'v-ripple__container'\n\n    if (value.class) {\n      container.className += ` ${value.class}`\n    }\n\n    const { radius, scale, x, y, centerX, centerY } = calculate(e, el, value)\n\n    const size = `${radius * 2}px`\n    animation.className = 'v-ripple__animation'\n    animation.style.width = size\n    animation.style.height = size\n\n    el.appendChild(container)\n\n    const computed = window.getComputedStyle(el)\n    if (computed && computed.position === 'static') {\n      el.style.position = 'relative'\n      el.dataset.previousPosition = 'static'\n    }\n\n    animation.classList.add('v-ripple__animation--enter')\n    animation.classList.add('v-ripple__animation--visible')\n    transform(animation, `translate(${x}, ${y}) scale3d(${scale},${scale},${scale})`)\n    animation.dataset.activated = String(performance.now())\n\n    requestAnimationFrame(() => {\n      requestAnimationFrame(() => {\n        animation.classList.remove('v-ripple__animation--enter')\n        animation.classList.add('v-ripple__animation--in')\n        transform(animation, `translate(${centerX}, ${centerY}) scale3d(1,1,1)`)\n      })\n    })\n  },\n\n  hide (el: HTMLElement | null) {\n    if (!el?._ripple?.enabled) return\n\n    const ripples = el.getElementsByClassName('v-ripple__animation')\n\n    if (ripples.length === 0) return\n    const animation = Array.from(ripples).findLast(ripple => !ripple.dataset.isHiding)\n\n    if (!animation) return\n    else animation.dataset.isHiding = 'true'\n\n    const diff = performance.now() - Number(animation.dataset.activated)\n    const delay = Math.max(250 - diff, 0)\n\n    setTimeout(() => {\n      animation.classList.remove('v-ripple__animation--in')\n      animation.classList.add('v-ripple__animation--out')\n\n      setTimeout(() => {\n        const ripples = el.getElementsByClassName('v-ripple__animation')\n        if (ripples.length === 1 && el.dataset.previousPosition) {\n          el.style.position = el.dataset.previousPosition\n          delete el.dataset.previousPosition\n        }\n\n        if (animation.parentNode?.parentNode === el) el.removeChild(animation.parentNode)\n      }, 300)\n    }, delay)\n  },\n}\n\nfunction isRippleEnabled (value: any) {\n  return typeof value === 'undefined' || !!value\n}\n\nfunction rippleShow (e: VuetifyRippleEvent) {\n  const value: RippleOptions = {}\n  const element = e.currentTarget as HTMLElement | undefined\n\n  if (!element?._ripple || element._ripple.touched || e[stopSymbol]) return\n\n  // Don't allow the event to trigger ripples on any other elements\n  e[stopSymbol] = true\n\n  if (isTouchEvent(e)) {\n    element._ripple.touched = true\n    element._ripple.isTouch = true\n  } else {\n    // It's possible for touch events to fire\n    // as mouse events on Android/iOS, this\n    // will skip the event call if it has\n    // already been registered as touch\n    if (element._ripple.isTouch) return\n  }\n\n  value.center = element._ripple.centered || isKeyboardEvent(e)\n  if (element._ripple.class) {\n    value.class = element._ripple.class\n  }\n\n  if (isTouchEvent(e)) {\n    // already queued that shows or hides the ripple\n    if (element._ripple.showTimerCommit) return\n\n    element._ripple.showTimerCommit = () => {\n      ripples.show(e, element, value)\n    }\n    element._ripple.showTimer = window.setTimeout(() => {\n      if (element?._ripple?.showTimerCommit) {\n        element._ripple.showTimerCommit()\n        element._ripple.showTimerCommit = null\n      }\n    }, DELAY_RIPPLE)\n  } else {\n    ripples.show(e, element, value)\n  }\n}\n\nfunction rippleStop (e: VuetifyRippleEvent) {\n  e[stopSymbol] = true\n}\n\nfunction rippleHide (e: Event) {\n  const element = e.currentTarget as HTMLElement | null\n  if (!element?._ripple) return\n\n  window.clearTimeout(element._ripple.showTimer)\n\n  // The touch interaction occurs before the show timer is triggered.\n  // We still want to show ripple effect.\n  if (e.type === 'touchend' && element._ripple.showTimerCommit) {\n    element._ripple.showTimerCommit()\n    element._ripple.showTimerCommit = null\n\n    // re-queue ripple hiding\n    element._ripple.showTimer = window.setTimeout(() => {\n      rippleHide(e)\n    })\n    return\n  }\n\n  window.setTimeout(() => {\n    if (element._ripple) {\n      element._ripple.touched = false\n    }\n  })\n  ripples.hide(element)\n}\n\nfunction rippleCancelShow (e: MouseEvent | TouchEvent) {\n  const element = e.currentTarget as HTMLElement | undefined\n\n  if (!element?._ripple) return\n\n  if (element._ripple.showTimerCommit) {\n    element._ripple.showTimerCommit = null\n  }\n\n  window.clearTimeout(element._ripple.showTimer)\n}\n\nlet keyboardRipple = false\n\nfunction keyboardRippleShow (e: KeyboardEvent, keys: string[]) {\n  if (!keyboardRipple && keys.includes(e.key)) {\n    keyboardRipple = true\n    rippleShow(e)\n  }\n}\n\nfunction keyboardRippleHide (e: KeyboardEvent) {\n  keyboardRipple = false\n  rippleHide(e)\n}\n\nfunction focusRippleHide (e: FocusEvent) {\n  if (keyboardRipple) {\n    keyboardRipple = false\n    rippleHide(e)\n  }\n}\n\nfunction updateRipple (el: HTMLElement, binding: RippleDirectiveBinding, wasEnabled: boolean) {\n  const { value, modifiers } = binding\n\n  const enabled = isRippleEnabled(value)\n  if (!enabled) {\n    ripples.hide(el)\n  }\n\n  el._ripple = el._ripple ?? {}\n  el._ripple.enabled = enabled\n  el._ripple.centered = modifiers.center\n  el._ripple.circle = modifiers.circle\n\n  const bindingValue = isObject(value) ? value : {}\n  if (bindingValue.class) {\n    el._ripple.class = bindingValue.class\n  }\n\n  const allowedKeys = bindingValue.keys ?? ['Enter', 'Space']\n  el._ripple.keyDownHandler = (e: KeyboardEvent) => keyboardRippleShow(e, allowedKeys)\n\n  if (enabled && !wasEnabled) {\n    if (modifiers.stop) {\n      el.addEventListener('touchstart', rippleStop, { passive: true })\n      el.addEventListener('mousedown', rippleStop)\n      return\n    }\n\n    el.addEventListener('touchstart', rippleShow, { passive: true })\n    el.addEventListener('touchend', rippleHide, { passive: true })\n    el.addEventListener('touchmove', rippleCancelShow, { passive: true })\n    el.addEventListener('touchcancel', rippleHide)\n\n    el.addEventListener('mousedown', rippleShow)\n    el.addEventListener('mouseup', rippleHide)\n    el.addEventListener('mouseleave', rippleHide)\n\n    el.addEventListener('keydown', el._ripple.keyDownHandler)\n    el.addEventListener('keyup', keyboardRippleHide)\n\n    el.addEventListener('blur', focusRippleHide)\n\n    // Anchor tags can be dragged, causes other hides to fail - #1537\n    el.addEventListener('dragstart', rippleHide, { passive: true })\n  } else if (!enabled && wasEnabled) {\n    removeListeners(el)\n  }\n}\n\nfunction removeListeners (el: HTMLElement) {\n  el.removeEventListener('touchstart', rippleStop)\n  el.removeEventListener('mousedown', rippleStop)\n\n  el.removeEventListener('touchstart', rippleShow)\n  el.removeEventListener('touchend', rippleHide)\n  el.removeEventListener('touchmove', rippleCancelShow)\n  el.removeEventListener('touchcancel', rippleHide)\n\n  el.removeEventListener('mousedown', rippleShow)\n  el.removeEventListener('mouseup', rippleHide)\n  el.removeEventListener('mouseleave', rippleHide)\n\n  if (el._ripple?.keyDownHandler) {\n    el.removeEventListener('keydown', el._ripple.keyDownHandler)\n  }\n  el.removeEventListener('keyup', keyboardRippleHide)\n\n  el.removeEventListener('blur', focusRippleHide)\n\n  el.removeEventListener('dragstart', rippleHide)\n}\n\nfunction mounted (el: HTMLElement, binding: RippleDirectiveBinding) {\n  updateRipple(el, binding, false)\n}\n\nfunction unmounted (el: HTMLElement) {\n  removeListeners(el)\n  delete el._ripple\n}\n\nfunction updated (el: HTMLElement, binding: RippleDirectiveBinding) {\n  if (binding.value === binding.oldValue) {\n    return\n  }\n\n  const wasEnabled = isRippleEnabled(binding.oldValue)\n  updateRipple(el, binding, wasEnabled)\n}\n\nexport const Ripple = {\n  mounted,\n  unmounted,\n  updated,\n}\n\nexport default Ripple\n"
  },
  {
    "path": "packages/vuetify/src/directives/scroll/__tests__/scroll.spec.browser.tsx",
    "content": "// Directives\nimport vScroll from '../'\n\n// Utilities\nimport { render, scroll } from '@test'\nimport { defineComponent } from 'vue'\n\ndescribe('v-scroll', () => {\n  function setup (selector = '') {\n    const callback = vi.fn()\n    const result = render(defineComponent({\n      directives: { vScroll },\n      setup () {\n        return () => (\n          <div data-testid=\"root\" style=\"overflow: auto; height: 500px; margin-block: 500px\">\n            <div style=\"margin-block: 500px\" v-scroll={[callback, selector]}>el</div>\n          </div>\n        )\n      },\n    }))\n\n    const el = result.getByText('el')\n    const root = result.getByTestId('root')\n\n    return { callback, result, el, root }\n  }\n\n  it('listens to scroll on window', async () => {\n    const { callback, root } = setup()\n\n    await scroll({ top: 100 })\n    expect(callback).toHaveBeenCalledTimes(1)\n\n    callback.mockClear()\n    await scroll({ top: 100 }, root)\n    expect(callback).not.toHaveBeenCalled()\n  })\n\n  it('listens to scroll on selector', async () => {\n    const { callback, root } = setup('[data-testid=\"root\"]')\n\n    await scroll({ top: 100 }, root)\n    expect(callback).toHaveBeenCalledTimes(1)\n\n    callback.mockClear()\n    await scroll({ top: 100 })\n    expect(callback).not.toHaveBeenCalled()\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/directives/scroll/index.ts",
    "content": "// Types\nimport type { DirectiveBinding } from 'vue'\n\ninterface ScrollDirectiveBinding extends Omit<DirectiveBinding, 'modifiers'> {\n  value: EventListener | {\n    handler: EventListener\n    options?: AddEventListenerOptions\n  } | EventListenerObject & { options?: AddEventListenerOptions }\n  modifiers?: {\n    self?: boolean\n  }\n}\n\nfunction mounted (el: HTMLElement, binding: ScrollDirectiveBinding) {\n  const { self = false } = binding.modifiers ?? {}\n  const value = binding.value\n  const options = (typeof value === 'object' && value.options) || { passive: true }\n  const handler = typeof value === 'function' || 'handleEvent' in value ? value : value.handler\n\n  const target = self\n    ? el\n    : binding.arg\n      ? document.querySelector(binding.arg)\n      : window\n\n  if (!target) return\n\n  target.addEventListener('scroll', handler, options)\n\n  el._onScroll = Object(el._onScroll)\n  el._onScroll![binding.instance!.$.uid] = {\n    handler,\n    options,\n    // Don't reference self\n    target: self ? undefined : target,\n  }\n}\n\nfunction unmounted (el: HTMLElement, binding: ScrollDirectiveBinding) {\n  if (!el._onScroll?.[binding.instance!.$.uid]) return\n\n  const { handler, options, target = el } = el._onScroll[binding.instance!.$.uid]!\n\n  target.removeEventListener('scroll', handler, options)\n  delete el._onScroll[binding.instance!.$.uid]\n}\n\nfunction updated (el: HTMLElement, binding: ScrollDirectiveBinding) {\n  if (binding.value === binding.oldValue) return\n\n  unmounted(el, binding)\n  mounted(el, binding)\n}\n\nexport const Scroll = {\n  mounted,\n  unmounted,\n  updated,\n}\n\nexport default Scroll\n"
  },
  {
    "path": "packages/vuetify/src/directives/tooltip/index.ts",
    "content": "// Components\nimport { VTooltip } from '@/components/VTooltip'\n\n// Composables\nimport { useDirectiveComponent } from '@/composables/directiveComponent'\n\n// Utilities\nimport { isObject } from '@/util'\n\n// Types\nimport type { DirectiveBinding } from 'vue'\nimport type { Anchor } from '@/util'\n\nexport interface TooltipDirectiveBinding extends Omit<DirectiveBinding<string>, 'arg' | 'value'> {\n  arg?: { [T in Anchor]: T extends `${infer A} ${infer B}` ? `${A}-${B}` : T }[Anchor]\n  value: boolean | string | Record<string, any>\n}\n\nexport const Tooltip = useDirectiveComponent<TooltipDirectiveBinding>(VTooltip, binding => {\n  const disabled = isObject(binding.value)\n    ? !binding.value.text\n    : ['', false, null].includes(binding.value) // undefined means true\n\n  return {\n    activator: disabled ? null : 'parent',\n    location: binding.arg?.replace('-', ' '),\n    text: typeof binding.value === 'boolean' ? undefined : binding.value,\n  }\n})\n\nexport default Tooltip\n"
  },
  {
    "path": "packages/vuetify/src/directives/touch/__tests__/touch.spec.browser.tsx",
    "content": "// Directives\nimport vTouch from '../'\n\n// Utilities\nimport { commands, render } from '@test'\nimport { defineComponent } from 'vue'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { TouchValue } from '../'\n\nconst TestComponent = defineComponent({\n  directives: { vTouch },\n  props: {\n    value: Object as PropType<TouchValue>,\n  },\n  setup (props) {\n    return () => (\n      <div v-touch={ props.value } style=\"width: 200px; height: 200px; background: red;\" />\n    )\n  },\n})\n\ndescribe('v-touch', () => {\n  describe('calls directive handler', () => {\n    it.each([\n      ['down', [100, 140]],\n      ['up', [100, 60]],\n      ['left', [60, 100]],\n      ['right', [140, 100]],\n    ])('%s', async (name, to) => {\n      const fn = vi.fn()\n      const start = vi.fn()\n      const move = vi.fn()\n      const end = vi.fn()\n\n      render(<TestComponent value={{ [name]: fn, start, move, end }} />)\n\n      await commands.drag([100, 100], to)\n\n      expect(fn).toHaveBeenCalledTimes(1)\n      expect(start).toHaveBeenCalledTimes(1)\n      expect(move).toHaveBeenCalledTimes(1)\n      expect(end).toHaveBeenCalledTimes(1)\n    })\n  })\n\n  describe('calls directive handler if not straight', () => {\n    it.each([\n      ['down', 'right', [115, 140]],\n      ['up', 'left', [85, 60]],\n      ['left', 'down', [60, 115]],\n      ['right', 'up', [140, 85]],\n    ])('%s', async (name, not, to) => {\n      const fn = vi.fn()\n      const nope = vi.fn()\n      const start = vi.fn()\n      const move = vi.fn()\n      const end = vi.fn()\n\n      render(<TestComponent value={{ [name]: fn, [not]: nope, start, move, end }} />)\n\n      await commands.drag([100, 100], to)\n\n      expect(fn).toHaveBeenCalledTimes(1)\n      expect(nope).not.toHaveBeenCalled()\n      expect(start).toHaveBeenCalledTimes(1)\n      expect(move).toHaveBeenCalledTimes(1)\n      expect(end).toHaveBeenCalledTimes(1)\n    })\n  })\n\n  describe('does not call directive handlers if distance is too small', () => {\n    it.each([\n      ['down', [100, 115]],\n      ['up', [100, 85]],\n      ['left', [85, 100]],\n      ['right', [115, 100]],\n    ])('%s', async (name, to) => {\n      const fn = vi.fn()\n      const start = vi.fn()\n      const move = vi.fn()\n      const end = vi.fn()\n\n      render(<TestComponent value={{ [name]: fn, start, move, end }} />)\n\n      await commands.drag([100, 100], to)\n\n      expect(fn).not.toHaveBeenCalled()\n      expect(start).toHaveBeenCalledTimes(1)\n      expect(move).not.toHaveBeenCalled()\n      expect(end).toHaveBeenCalledTimes(1)\n    })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/directives/touch/index.ts",
    "content": "// Utilities\nimport { keys } from '@/util'\n\n// Types\nimport type {\n  DirectiveBinding,\n} from 'vue'\n\nexport interface TouchHandlers {\n  start?: (wrapperEvent: { originalEvent: TouchEvent } & TouchData) => void\n  end?: (wrapperEvent: { originalEvent: TouchEvent } & TouchData) => void\n  move?: (wrapperEvent: { originalEvent: TouchEvent } & TouchData) => void\n  left?: (wrapper: TouchData) => void\n  right?: (wrapper: TouchData) => void\n  up?: (wrapper: TouchData) => void\n  down?: (wrapper: TouchData) => void\n}\n\nexport interface TouchData {\n  touchstartX: number\n  touchstartY: number\n  touchmoveX: number\n  touchmoveY: number\n  touchendX: number\n  touchendY: number\n  offsetX: number\n  offsetY: number\n}\n\nexport type TouchWrapper = TouchHandlers & TouchData\n\nexport interface TouchValue extends TouchHandlers {\n  parent?: boolean\n  options?: AddEventListenerOptions\n}\n\nexport interface TouchStoredHandlers {\n  touchstart: (e: TouchEvent) => void\n  touchend: (e: TouchEvent) => void\n  touchmove: (e: TouchEvent) => void\n}\n\nexport interface TouchDirectiveBinding extends Omit<DirectiveBinding, 'value'> {\n  value?: TouchValue\n}\n\nconst handleGesture = (wrapper: TouchWrapper) => {\n  const { touchstartX, touchendX, touchstartY, touchendY } = wrapper\n  const dirRatio = 0.5\n  const minDistance = 16\n  wrapper.offsetX = touchendX - touchstartX\n  wrapper.offsetY = touchendY - touchstartY\n\n  if (Math.abs(wrapper.offsetY) < dirRatio * Math.abs(wrapper.offsetX)) {\n    wrapper.left && (touchendX < touchstartX - minDistance) && wrapper.left(wrapper)\n    wrapper.right && (touchendX > touchstartX + minDistance) && wrapper.right(wrapper)\n  }\n\n  if (Math.abs(wrapper.offsetX) < dirRatio * Math.abs(wrapper.offsetY)) {\n    wrapper.up && (touchendY < touchstartY - minDistance) && wrapper.up(wrapper)\n    wrapper.down && (touchendY > touchstartY + minDistance) && wrapper.down(wrapper)\n  }\n}\n\nfunction touchstart (event: TouchEvent, wrapper: TouchWrapper) {\n  const touch = event.changedTouches[0]\n  wrapper.touchstartX = touch.clientX\n  wrapper.touchstartY = touch.clientY\n\n  wrapper.start?.({ originalEvent: event, ...wrapper })\n}\n\nfunction touchend (event: TouchEvent, wrapper: TouchWrapper) {\n  const touch = event.changedTouches[0]\n  wrapper.touchendX = touch.clientX\n  wrapper.touchendY = touch.clientY\n\n  wrapper.end?.({ originalEvent: event, ...wrapper })\n\n  handleGesture(wrapper)\n}\n\nfunction touchmove (event: TouchEvent, wrapper: TouchWrapper) {\n  const touch = event.changedTouches[0]\n  wrapper.touchmoveX = touch.clientX\n  wrapper.touchmoveY = touch.clientY\n\n  wrapper.move?.({ originalEvent: event, ...wrapper })\n}\n\nfunction createHandlers (value: TouchHandlers = {}): TouchStoredHandlers {\n  const wrapper = {\n    touchstartX: 0,\n    touchstartY: 0,\n    touchendX: 0,\n    touchendY: 0,\n    touchmoveX: 0,\n    touchmoveY: 0,\n    offsetX: 0,\n    offsetY: 0,\n    left: value.left,\n    right: value.right,\n    up: value.up,\n    down: value.down,\n    start: value.start,\n    move: value.move,\n    end: value.end,\n  }\n\n  return {\n    touchstart: (e: TouchEvent) => touchstart(e, wrapper),\n    touchend: (e: TouchEvent) => touchend(e, wrapper),\n    touchmove: (e: TouchEvent) => touchmove(e, wrapper),\n  }\n}\n\nfunction mounted (el: HTMLElement, binding: TouchDirectiveBinding) {\n  const value = binding.value\n  const target = value?.parent ? el.parentElement : el\n  const options = value?.options ?? { passive: true }\n  const uid = binding.instance?.$.uid // TODO: use custom uid generator\n\n  if (!target || uid === undefined) return\n\n  const handlers = createHandlers(binding.value)\n\n  target._touchHandlers = target._touchHandlers ?? Object.create(null)\n  target._touchHandlers![uid] = handlers\n\n  keys(handlers).forEach(eventName => {\n    target.addEventListener(eventName, handlers[eventName], options)\n  })\n}\n\nfunction unmounted (el: HTMLElement, binding: TouchDirectiveBinding) {\n  const target = binding.value?.parent ? el.parentElement : el\n  const uid = binding.instance?.$.uid\n\n  if (!target?._touchHandlers || uid === undefined) return\n\n  const handlers = target._touchHandlers[uid]\n\n  keys(handlers).forEach(eventName => {\n    target.removeEventListener(eventName, handlers[eventName])\n  })\n\n  delete target._touchHandlers[uid]\n}\n\nexport const Touch = {\n  mounted,\n  unmounted,\n}\n\nexport default Touch\n"
  },
  {
    "path": "packages/vuetify/src/entry-bundler.ts",
    "content": "/* eslint-disable local-rules/sort-imports */\n\n// Styles\nimport './styles/main.sass'\n\n// Components\nimport * as blueprints from './blueprints'\nimport * as components from './components'\nimport * as directives from './directives'\nimport { createVuetify as _createVuetify } from './framework'\n\n// Types\nimport type { VuetifyOptions } from './framework'\n\nexport const createVuetify = (options: VuetifyOptions = {}) => {\n  return _createVuetify({ components, directives, ...options })\n}\n\nexport const version = __VUETIFY_VERSION__\ncreateVuetify.version = version\n\nexport {\n  blueprints,\n  components,\n  directives,\n}\nexport * from './composables'\n"
  },
  {
    "path": "packages/vuetify/src/entry-styles.ts",
    "content": "// Styles\nimport './styles/colors.scss'\nimport './styles/core.scss'\nimport './styles/utilities.scss'\n"
  },
  {
    "path": "packages/vuetify/src/framework.ts",
    "content": "// Composables\nimport { createIcons } from './icons'\nimport { createDate, DateAdapterSymbol, DateOptionsSymbol } from '@/composables/date/date'\nimport { createDefaults, DefaultsSymbol } from '@/composables/defaults'\nimport { createDisplay, DisplaySymbol } from '@/composables/display'\nimport { createGoTo, GoToSymbol } from '@/composables/goto'\nimport { IconSymbol } from '@/composables/icons'\nimport { createLocale, LocaleSymbol } from '@/composables/locale'\nimport { createTheme, ThemeSymbol } from '@/composables/theme'\n\n// Utilities\nimport { effectScope, nextTick, reactive } from 'vue'\nimport { defineComponent, IN_BROWSER, mergeDeep } from '@/util'\n\n// Types\nimport type { App, ComponentPublicInstance, InjectionKey } from 'vue'\nimport type { DateOptions } from '@/composables/date'\nimport type { DefaultsOptions } from '@/composables/defaults'\nimport type { DisplayOptions, SSROptions } from '@/composables/display'\nimport type { GoToOptions } from '@/composables/goto'\nimport type { IconOptions } from '@/composables/icons'\nimport type { LocaleOptions, RtlOptions } from '@/composables/locale'\nimport type { ThemeOptions } from '@/composables/theme'\n\n// Exports\nexport * from './composables'\nexport * from './types'\n\nexport interface VuetifyOptions {\n  aliases?: Record<string, any>\n  blueprint?: Blueprint\n  components?: Record<string, any>\n  date?: DateOptions\n  directives?: Record<string, any>\n  defaults?: DefaultsOptions\n  display?: DisplayOptions\n  goTo?: GoToOptions\n  theme?: ThemeOptions\n  icons?: IconOptions\n  locale?: LocaleOptions & RtlOptions\n  ssr?: SSROptions\n}\n\nexport interface Blueprint extends Omit<VuetifyOptions, 'blueprint'> {}\n\nexport function createVuetify (vuetify: VuetifyOptions = {}) {\n  const { blueprint, ...rest } = vuetify\n  const options: VuetifyOptions = mergeDeep(blueprint, rest)\n  const {\n    aliases = {},\n    components = {},\n    directives = {},\n  } = options\n\n  const scope = effectScope()\n  return scope.run(() => {\n    const defaults = createDefaults(options.defaults)\n    const display = createDisplay(options.display, options.ssr)\n    const theme = createTheme(options.theme)\n    const icons = createIcons(options.icons)\n    const locale = createLocale(options.locale)\n    const date = createDate(options.date, locale)\n    const goTo = createGoTo(options.goTo, locale)\n\n    function install (app: App) {\n      for (const key in directives) {\n        app.directive(key, directives[key])\n      }\n\n      for (const key in components) {\n        app.component(key, components[key])\n      }\n\n      for (const key in aliases) {\n        app.component(key, defineComponent({\n          ...aliases[key],\n          name: key,\n          aliasName: aliases[key].name,\n        }))\n      }\n\n      const appScope = effectScope()\n      appScope.run(() => {\n        theme.install(app)\n      })\n      app.onUnmount(() => appScope.stop())\n\n      app.provide(DefaultsSymbol, defaults)\n      app.provide(DisplaySymbol, display)\n      app.provide(ThemeSymbol, theme)\n      app.provide(IconSymbol, icons)\n      app.provide(LocaleSymbol, locale)\n      app.provide(DateOptionsSymbol, date.options)\n      app.provide(DateAdapterSymbol, date.instance)\n      app.provide(GoToSymbol, goTo)\n\n      if (IN_BROWSER && options.ssr) {\n        if (app.$nuxt) {\n          app.$nuxt.hook('app:suspense:resolve', () => {\n            display.update()\n          })\n        } else {\n          const { mount } = app\n          app.mount = (...args) => {\n            const vm = mount(...args)\n            nextTick(() => display.update())\n            app.mount = mount\n            return vm\n          }\n        }\n      }\n\n      if (typeof __VUE_OPTIONS_API__ !== 'boolean' || __VUE_OPTIONS_API__) {\n        app.mixin({\n          computed: {\n            $vuetify () {\n              return reactive({\n                defaults: inject.call(this, DefaultsSymbol),\n                display: inject.call(this, DisplaySymbol),\n                theme: inject.call(this, ThemeSymbol),\n                icons: inject.call(this, IconSymbol),\n                locale: inject.call(this, LocaleSymbol),\n                date: inject.call(this, DateAdapterSymbol),\n              })\n            },\n          },\n        })\n      }\n    }\n\n    function unmount () {\n      scope.stop()\n    }\n\n    return {\n      install,\n      unmount,\n      defaults,\n      display,\n      theme,\n      icons,\n      locale,\n      date,\n      goTo,\n    }\n  })!\n}\n\nexport const version = __VUETIFY_VERSION__\ncreateVuetify.version = version\n\n// Vue's inject() can only be used in setup\nfunction inject (this: ComponentPublicInstance, key: InjectionKey<any> | string) {\n  const vm = this.$\n\n  const provides = vm.parent?.provides ?? vm.vnode.appContext?.provides\n\n  if (provides && (key as any) in provides) {\n    return provides[(key as string)]\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/globals.d.ts",
    "content": "import 'vue/jsx'\n\n// Types\nimport type { ComponentInjectOptions, ComponentOptionsMixin, EmitsOptions, SlotsType } from 'vue'\nimport type { ComputedOptions, Events, MethodOptions, VNode } from 'vue'\nimport type { TouchStoredHandlers } from './directives/touch'\n\ndeclare global {\n  interface Element {\n    _clickOutside?: Record<number, {\n      onClick: EventListener\n      onMousedown: EventListener\n    } | undefined> & { lastMousedownWasOutside: boolean }\n    _onResize?: Record<number, {\n      handler: () => void\n      options: AddEventListenerOptions\n    } | undefined>\n    _ripple?: {\n      enabled?: boolean\n      centered?: boolean\n      class?: string\n      circle?: boolean\n      touched?: boolean\n      isTouch?: boolean\n      showTimer?: number\n      showTimerCommit?: (() => void) | null\n      keyDownHandler?: ((e: KeyboardEvent) => void) | null\n    }\n    _observe?: Record<number, {\n      init: boolean\n      observer: IntersectionObserver\n    } | undefined>\n    _mutate?: Record<number, {\n      observer: MutationObserver\n    } | undefined>\n    _onScroll?: Record<number, {\n      handler: EventListenerOrEventListenerObject\n      options: AddEventListenerOptions\n      target?: EventTarget\n    } | undefined>\n    _touchHandlers?: {\n      [_uid: number]: TouchStoredHandlers\n    }\n    _transitionInitialStyles?: {\n      position: string\n      top: string\n      left: string\n      width: string\n      height: string\n    }\n\n    getElementsByClassName(classNames: string): NodeListOf<HTMLElement>\n  }\n\n  interface WheelEvent {\n    path?: EventTarget[]\n  }\n\n  interface MouseEvent {\n    sourceCapabilities?: { firesTouchEvents: boolean }\n    shadowTarget?: EventTarget | null\n  }\n\n  interface ColorSelectionOptions {\n    signal?: AbortSignal\n  }\n\n  interface ColorSelectionResult {\n    sRGBHex: string\n  }\n\n  interface EyeDropper {\n    open: (options?: ColorSelectionOptions) => Promise<ColorSelectionResult>\n  }\n\n  interface EyeDropperConstructor {\n    new (): EyeDropper\n  }\n\n  interface Window {\n    EyeDropper: EyeDropperConstructor\n  }\n\n  function parseInt(s: string | number, radix?: number): number\n  function parseFloat(string: string | number): number\n\n  export const __VUETIFY_VERSION__: string\n  export const __REQUIRED_VUE__: string\n  export const __VUE_OPTIONS_API__: boolean | undefined\n\n  namespace JSX {\n    interface Element extends VNode {}\n    interface IntrinsicAttributes {\n      [name: string]: any\n    }\n  }\n}\n\ndeclare module 'vue' {\n  export interface ComponentCustomProperties {\n    _: ComponentInternalInstance\n  }\n\n  export interface ComponentInternalInstance {\n    provides: Record<string, unknown>\n    setupState: any\n  }\n\n  export interface FunctionalComponent {\n    aliasName?: string\n  }\n\n  export interface ComponentOptionsBase<\n    Props,\n    RawBindings,\n    D,\n    C extends ComputedOptions,\n    M extends MethodOptions,\n    Mixin extends ComponentOptionsMixin,\n    Extends extends ComponentOptionsMixin,\n    E extends EmitsOptions,\n    EE extends string = string,\n    Defaults = {},\n    I extends ComponentInjectOptions = {},\n    II extends string = string,\n    S extends SlotsType = {}\n  > {\n    aliasName?: string\n  }\n\n  export interface App {\n    $nuxt?: { hook: (name: string, fn: () => void) => void }\n  }\n\n  export interface VNode {\n    ctx: ComponentInternalInstance | null\n    ssContent: VNode | null\n  }\n\n  type UnionToIntersection<U> =\n    (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never\n\n  type Combine<T extends string> = T | {\n    [K in T]: {\n      [L in Exclude<T, K>]: `${K}${Exclude<T, K>}` | `${K}${L}${Exclude<T, K | L>}`\n    }[Exclude<T, K>]\n  }[T]\n\n  type Modifiers = Combine<'Passive' | 'Capture' | 'Once'>\n\n  type ModifiedEvents = UnionToIntersection<{\n    [K in keyof Events]: { [L in `${K}${Modifiers}`]: Events[K] }\n  }[keyof Events]>\n\n  type EventHandlers<E> = {\n    [K in keyof E]?: E[K] extends Function ? E[K] : (payload: E[K]) => void\n  }\n\n  export interface HTMLAttributes extends EventHandlers<ModifiedEvents> {\n    onScrollend?: (e: Event) => void\n  }\n\n  type CustomProperties = {\n    [k in `--${string}`]: any\n  }\n\n  export interface CSSProperties extends CustomProperties {}\n}\n"
  },
  {
    "path": "packages/vuetify/src/icons.ts",
    "content": "// Composables\nimport { VClassIcon, VSvgIcon } from '@/composables/icons'\nimport { aliases, mdi } from '@/iconsets/mdi'\n\n// Utilities\nimport { mergeDeep } from '@/util'\n\n// Types\nimport type { IconOptions, IconSet, InternalIconOptions } from '@/composables/icons'\n\nfunction genDefaults (): Record<string, IconSet> {\n  return {\n    svg: {\n      component: VSvgIcon,\n    },\n    class: {\n      component: VClassIcon,\n    },\n  }\n}\n\nexport function createIcons (options?: IconOptions) {\n  const sets = genDefaults()\n  const defaultSet = options?.defaultSet ?? 'mdi'\n\n  if (defaultSet === 'mdi' && !sets.mdi) {\n    sets.mdi = mdi\n  }\n\n  return mergeDeep({\n    defaultSet,\n    sets,\n    aliases: {\n      ...aliases,\n      /* eslint-disable max-len */\n      vuetify: [\n        'M8.2241 14.2009L12 21L22 3H14.4459L8.2241 14.2009Z',\n        ['M7.26303 12.4733L7.00113 12L2 3H12.5261C12.5261 3 12.5261 3 12.5261 3L7.26303 12.4733Z', 0.6],\n      ],\n      'vuetify-outline': 'svg:M7.26 12.47 12.53 3H2L7.26 12.47ZM14.45 3 8.22 14.2 12 21 22 3H14.45ZM18.6 5 12 16.88 10.51 14.2 15.62 5ZM7.26 8.35 5.4 5H9.13L7.26 8.35Z',\n      'vuetify-play': [\n        'm6.376 13.184-4.11-7.192C1.505 4.66 2.467 3 4.003 3h8.532l-.953 1.576-.006.01-.396.677c-.429.732-.214 1.507.194 2.015.404.503 1.092.878 1.869.806a3.72 3.72 0 0 1 1.005.022c.276.053.434.143.523.237.138.146.38.635-.25 2.09-.893 1.63-1.553 1.722-1.847 1.677-.213-.033-.468-.158-.756-.406a4.95 4.95 0 0 1-.8-.927c-.39-.564-1.04-.84-1.66-.846-.625-.006-1.316.27-1.693.921l-.478.826-.911 1.506Z',\n        ['M9.093 11.552c.046-.079.144-.15.32-.148a.53.53 0 0 1 .43.207c.285.414.636.847 1.046 1.2.405.35.914.662 1.516.754 1.334.205 2.502-.698 3.48-2.495l.014-.028.013-.03c.687-1.574.774-2.852-.005-3.675-.37-.391-.861-.586-1.333-.676a5.243 5.243 0 0 0-1.447-.044c-.173.016-.393-.073-.54-.257-.145-.18-.127-.316-.082-.392l.393-.672L14.287 3h5.71c1.536 0 2.499 1.659 1.737 2.992l-7.997 13.996c-.768 1.344-2.706 1.344-3.473 0l-3.037-5.314 1.377-2.278.004-.006.004-.007.481-.831Z', 0.6],\n      ],\n      /* eslint-enable max-len */\n    },\n  }, options) as InternalIconOptions\n}\n"
  },
  {
    "path": "packages/vuetify/src/iconsets/bx.ts",
    "content": "// @unocss-include\n// Composables\nimport { VClassIcon } from '@/composables/icons'\n\n// Utilities\nimport { h } from 'vue'\n\nimport { aliases as mdiAliases } from './mdi-svg'\n\n// Types\nimport type { IconAliases, IconSet } from '@/composables/icons'\n\nconst aliases: IconAliases = {\n  collapse: 'i-bx:chevron-up',\n  complete: 'i-bx:check',\n  cancel: 'i-bx:x-circle',\n  close: 'i-bx:x',\n  delete: 'i-bx:x-circle', // delete (e.g. v-chip close)\n  clear: 'i-bx:x-circle',\n  success: 'i-bx:check-circle',\n  info: 'i-bx:info-circle',\n  warning: 'i-bx:error-circle',\n  error: 'i-bx:x-circle',\n  prev: 'i-bx:chevron-left',\n  next: 'i-bx:chevron-right',\n  checkboxOn: 'i-bx:checkbox-checked',\n  checkboxOff: 'i-bx:checkbox',\n  checkboxIndeterminate: 'i-bx:checkbox-minus',\n  delimiter: 'i-bx:bxs-circle', // for carousel\n  sortAsc: 'i-bx:sort-up',\n  sortDesc: 'i-bx:sort-down',\n  expand: 'i-bx:chevron-down',\n  menu: 'i-bx:menu',\n  subgroup: 'i-bx:caret-down',\n  dropdown: 'i-bx:caret-down',\n  radioOn: 'i-bx:radio-circle-marked',\n  radioOff: 'i-bx:radio-circle',\n  edit: 'i-bx:pencil',\n  ratingEmpty: 'i-bx:star',\n  ratingFull: 'i-bx:bxs-star',\n  ratingHalf: 'i-bx:bxs-star-half',\n  loading: 'i-bx:refresh',\n  first: 'i-bx:first-page',\n  last: 'i-bx:last-page',\n  unfold: 'i-bx:expand-vertical',\n  file: 'i-bx:paperclip',\n  plus: 'i-bx:plus',\n  minus: 'i-bx:minus',\n  calendar: 'i-bx:calendar',\n  treeviewCollapse: 'i-bx:chevron-down',\n  treeviewExpand: 'i-bx:chevron-right',\n  tableGroupExpand: 'i-bx:chevron-right',\n  tableGroupCollapse: 'i-bx:chevron-down',\n  eyeDropper: 'i-bx:bxs-eyedropper',\n  upload: 'i-bx:cloud-upload',\n  color: 'i-bx:palette',\n  command: 'i-bx:command',\n  ctrl: 'i-bx:chevron-up',\n  space: 'i-bx:space-bar',\n  shift: 'i-bx:up-arrow-alt',\n  alt: mdiAliases.alt,\n  enter: mdiAliases.enter,\n  arrowup: 'i-bx:up-arrow-alt',\n  arrowdown: 'i-bx:down-arrow-alt',\n  arrowleft: 'i-bx:left-arrow-alt',\n  arrowright: 'i-bx:right-arrow-alt',\n  backspace: 'i-bx:undo',\n  play: 'i-bx:play',\n  pause: 'i-bx:pause',\n  fullscreen: 'i-bx:fullscreen',\n  fullscreenExit: 'i-bx:exit-fullscreen',\n  volumeHigh: 'i-bx:volume-full',\n  volumeMedium: 'i-bx:volume',\n  volumeLow: 'i-bx:volume-low',\n  volumeOff: 'i-bx:volume-mute',\n  search: 'i-bx:search',\n}\n\nconst bx: IconSet = {\n  component: (props: any) => h(VClassIcon, { ...props, class: 'bx' }),\n}\n\nexport { aliases, bx }\n"
  },
  {
    "path": "packages/vuetify/src/iconsets/carbon.ts",
    "content": "// @unocss-include\n// Composables\nimport { VClassIcon } from '@/composables/icons'\n\n// Utilities\nimport { h } from 'vue'\n\nimport { aliases as mdiAliases } from './mdi-svg'\n\n// Types\nimport type { IconAliases, IconSet } from '@/composables/icons'\n\nconst aliases: IconAliases = {\n  collapse: 'i-carbon:chevron-up',\n  complete: 'i-carbon:checkmark',\n  cancel: 'i-carbon:close-filled',\n  close: 'i-carbon:close',\n  delete: 'i-carbon:close-filled', // delete (e.g. v-chip close)\n  clear: 'i-carbon:close-filled',\n  success: 'i-carbon:checkmark-filled',\n  info: 'i-carbon:information',\n  warning: 'i-carbon:warning',\n  error: 'i-carbon:misuse',\n  prev: 'i-carbon:chevron-left',\n  next: 'i-carbon:chevron-right',\n  checkboxOn: 'i-carbon:checkbox-checked',\n  checkboxOff: 'i-carbon:checkbox',\n  checkboxIndeterminate: 'i-carbon:checkbox-indeterminate',\n  delimiter: 'i-carbon:circle-filled', // for carousel\n  sortAsc: 'i-carbon:arrow-up',\n  sortDesc: 'i-carbon:arrow-down',\n  expand: 'i-carbon:chevron-down',\n  menu: 'i-carbon:menu',\n  subgroup: 'i-carbon:caret-down',\n  dropdown: 'i-carbon:caret-down',\n  radioOn: 'i-carbon:radio-button-checked',\n  radioOff: 'i-carbon:radio-button',\n  edit: 'i-carbon:edit',\n  ratingEmpty: 'i-carbon:star',\n  ratingFull: 'i-carbon:star-filled',\n  ratingHalf: 'i-carbon:star-half',\n  loading: 'i-carbon:renew',\n  first: 'i-carbon:page-first',\n  last: 'i-carbon:page-last',\n  unfold: mdiAliases.unfold,\n  file: 'i-carbon:attachment',\n  plus: 'i-carbon:add',\n  minus: 'i-carbon:subtract',\n  calendar: 'i-carbon:calendar',\n  treeviewCollapse: 'i-carbon:chevron-down',\n  treeviewExpand: 'i-carbon:chevron-right',\n  tableGroupExpand: 'i-carbon:chevron-right',\n  tableGroupCollapse: 'i-carbon:chevron-down',\n  eyeDropper: mdiAliases.eyeDropper,\n  upload: 'i-carbon:cloud-upload',\n  color: 'i-carbon:color-palette',\n  command: 'i-carbon:mac-command',\n  ctrl: mdiAliases.ctrl,\n  space: mdiAliases.space,\n  shift: 'i-carbon:mac-shift',\n  alt: 'i-carbon:mac-option',\n  enter: 'i-carbon:return',\n  arrowup: 'i-carbon:arrow-up',\n  arrowdown: 'i-carbon:arrow-down',\n  arrowleft: 'i-carbon:arrow-left',\n  arrowright: 'i-carbon:arrow-right',\n  backspace: 'i-carbon:undo',\n  play: 'i-carbon:play',\n  pause: 'i-carbon:pause',\n  fullscreen: 'i-carbon:maximize',\n  fullscreenExit: 'i-carbon:minimize',\n  volumeHigh: 'i-carbon:volume-up',\n  volumeMedium: 'i-carbon:volume-down',\n  volumeLow: 'i-carbon:volume-down',\n  volumeOff: 'i-carbon:volume-mute',\n  search: 'i-carbon:search',\n}\n\nconst carbon: IconSet = {\n  component: (props: any) => h(VClassIcon, { ...props, class: 'carbon' }),\n}\n\nexport { aliases, carbon }\n"
  },
  {
    "path": "packages/vuetify/src/iconsets/fa-svg.ts",
    "content": "// Utilities\nimport { h, resolveComponent } from 'vue'\nimport { aliases as faAliases } from './fa'\n\n// Types\nimport type { IconSet } from '@/composables/icons'\n\nconst aliases = faAliases\n\nconst fa: IconSet = {\n  component: props => {\n    const { icon, tag, ...rest } = props\n    const stringIcon = icon as string\n    return h(tag, rest, [\n      h(resolveComponent('font-awesome-icon'), {\n        key: stringIcon, // TODO: https://github.com/FortAwesome/vue-fontawesome/issues/250\n        icon: stringIcon.includes(' fa-') ? stringIcon.split(' fa-') : stringIcon,\n      }),\n    ])\n  },\n}\n\nexport { aliases, fa }\n"
  },
  {
    "path": "packages/vuetify/src/iconsets/fa.ts",
    "content": "// Composables\nimport { VClassIcon } from '@/composables/icons'\n\n// Types\nimport type { IconAliases, IconSet } from '@/composables/icons'\n\nconst aliases: IconAliases = {\n  collapse: 'fas fa-chevron-up',\n  complete: 'fas fa-check',\n  cancel: 'fas fa-times-circle',\n  close: 'fas fa-times',\n  delete: 'fas fa-times-circle', // delete (e.g. v-chip close)\n  clear: 'fas fa-times-circle', // delete (e.g. v-chip close)\n  success: 'fas fa-check-circle',\n  info: 'fas fa-info-circle',\n  warning: 'fas fa-exclamation',\n  error: 'fas fa-exclamation-triangle',\n  prev: 'fas fa-chevron-left',\n  next: 'fas fa-chevron-right',\n  checkboxOn: 'fas fa-check-square',\n  checkboxOff: 'far fa-square', // note 'far'\n  checkboxIndeterminate: 'fas fa-minus-square',\n  delimiter: 'fas fa-circle', // for carousel\n  sortAsc: 'fas fa-arrow-up',\n  sortDesc: 'fas fa-arrow-down',\n  expand: 'fas fa-chevron-down',\n  menu: 'fas fa-bars',\n  subgroup: 'fas fa-caret-down',\n  dropdown: 'fas fa-caret-down',\n  radioOn: 'far fa-dot-circle',\n  radioOff: 'far fa-circle',\n  edit: 'fas fa-edit',\n  ratingEmpty: 'far fa-star',\n  ratingFull: 'fas fa-star',\n  ratingHalf: 'fas fa-star-half',\n  loading: 'fas fa-sync',\n  first: 'fas fa-step-backward',\n  last: 'fas fa-step-forward',\n  unfold: 'fas fa-arrows-alt-v',\n  file: 'fas fa-paperclip',\n  plus: 'fas fa-plus',\n  minus: 'fas fa-minus',\n  calendar: 'fas fa-calendar',\n  treeviewCollapse: 'fas fa-caret-down',\n  treeviewExpand: 'fas fa-caret-right',\n  tableGroupExpand: 'fas fa-chevron-right',\n  tableGroupCollapse: 'fas fa-chevron-down',\n  eyeDropper: 'fas fa-eye-dropper',\n  upload: 'fas fa-cloud-upload-alt',\n  color: 'fas fa-palette',\n  command: 'fas fa-keyboard',\n  ctrl: 'fas fa-keyboard',\n  shift: 'fas fa-arrow-up',\n  alt: 'fas fa-keyboard',\n  space: 'fas fa-square',\n  enter: 'fas fa-reply',\n  arrowup: 'fas fa-arrow-up',\n  arrowdown: 'fas fa-arrow-down',\n  arrowleft: 'fas fa-arrow-left',\n  arrowright: 'fas fa-arrow-right',\n  backspace: 'fas fa-backspace',\n  play: 'fas fa-play',\n  pause: 'fas fa-pause',\n  fullscreen: 'fas fa-fullscreen',\n  fullscreenExit: 'fas fa-compress',\n  volumeHigh: 'fas fa-volume-high',\n  volumeMedium: 'fas fa-volume-low',\n  volumeLow: 'fas fa-volume-off',\n  volumeOff: 'fas fa-volume-off',\n  search: 'fas fa-magnifying-glass',\n}\n\nconst fa: IconSet = {\n  component: VClassIcon,\n}\n\nexport { aliases, fa }\n"
  },
  {
    "path": "packages/vuetify/src/iconsets/fa4.ts",
    "content": "// Composables\nimport { VClassIcon } from '@/composables/icons'\n\n// Utilities\nimport { h } from 'vue'\n\n// Types\nimport type { IconAliases, IconSet } from '@/composables/icons'\n\nconst aliases: IconAliases = {\n  collapse: 'fa-chevron-up',\n  complete: 'fa-check',\n  cancel: 'fa-times-circle',\n  close: 'fa-times',\n  delete: 'fa-times-circle', // delete (e.g. v-chip close)\n  clear: 'fa-check-circle', // delete (e.g. v-chip close)\n  success: 'fa-check-circle',\n  info: 'fa-info-circle',\n  warning: 'fa-exclamation',\n  error: 'fa-exclamation-triangle',\n  prev: 'fa-chevron-left',\n  next: 'fa-chevron-right',\n  checkboxOn: 'fa-check-square',\n  checkboxOff: 'fa-square-o',\n  checkboxIndeterminate: 'fa-minus-square',\n  delimiter: 'fa-circle', // for carousel\n  sortAsc: 'fa-arrow-up',\n  sortDesc: 'fa-arrow-down',\n  expand: 'fa-chevron-down',\n  menu: 'fa-bars',\n  subgroup: 'fa-caret-down',\n  dropdown: 'fa-caret-down',\n  radioOn: 'fa-dot-circle-o',\n  radioOff: 'fa-circle-o',\n  edit: 'fa-pencil',\n  ratingEmpty: 'fa-star-o',\n  ratingFull: 'fa-star',\n  ratingHalf: 'fa-star-half-o',\n  loading: 'fa-refresh',\n  first: 'fa-step-backward',\n  last: 'fa-step-forward',\n  unfold: 'fa-angle-double-down',\n  file: 'fa-paperclip',\n  plus: 'fa-plus',\n  minus: 'fa-minus',\n  calendar: 'fa-calendar',\n  treeviewCollapse: 'fa-caret-down',\n  treeviewExpand: 'fa-caret-right',\n  tableGroupExpand: 'fa-chevron-right',\n  tableGroupCollapse: 'fa-chevron-down',\n  eyeDropper: 'fa-eye-dropper',\n  upload: 'fa-cloud-upload',\n  color: 'fa-paint-brush',\n  command: 'fa-keyboard-o',\n  ctrl: 'fa-keyboard-o',\n  shift: 'fa-arrow-up',\n  alt: 'fa-keyboard-o',\n  space: 'fa-square-o',\n  enter: 'fa-reply',\n  arrowup: 'fa-arrow-up',\n  arrowdown: 'fa-arrow-down',\n  arrowleft: 'fa-arrow-left',\n  arrowright: 'fa-arrow-right',\n  backspace: 'fa-undo',\n  play: 'fa-play',\n  pause: 'fa-pause',\n  fullscreen: 'fa-fullscreen',\n  fullscreenExit: 'fa-compress',\n  volumeHigh: 'fa-volume-high',\n  volumeMedium: 'fa-volume-low',\n  volumeLow: 'fa-volume-off',\n  volumeOff: 'fa-volume-off',\n  search: 'fa-magnifying-glass',\n}\n\nconst fa: IconSet = {\n  // Not using mergeProps here, functional components merge props by default (?)\n  component: props => h(VClassIcon, { ...props, class: 'fa' }),\n}\n\nexport { aliases, fa }\n"
  },
  {
    "path": "packages/vuetify/src/iconsets/fa6.ts",
    "content": "// @unocss-include\n// Composables\nimport { VClassIcon } from '@/composables/icons'\n\n// Utilities\nimport { h } from 'vue'\n\nimport { aliases as mdiAliases } from './mdi-svg'\n\n// Types\nimport type { IconAliases, IconSet } from '@/composables/icons'\n\nconst aliases: IconAliases = {\n  collapse: 'i-fa6-solid:chevron-up',\n  complete: 'i-fa6-solid:check',\n  cancel: 'i-fa6-solid:circle-xmark',\n  close: 'i-fa6-solid:xmark',\n  delete: 'i-fa6-solid:circle-xmark', // delete (e.g. v-chip close)\n  clear: 'i-fa6-solid:circle-xmark',\n  success: 'i-fa6-solid:circle-check',\n  info: 'i-fa6-solid:circle-info',\n  warning: 'i-fa6-solid:triangle-exclamation',\n  error: 'i-fa6-solid:circle-xmark',\n  prev: 'i-fa6-solid:chevron-left',\n  next: 'i-fa6-solid:chevron-right',\n  checkboxOn: 'i-fa6-solid:square-check',\n  checkboxOff: 'i-fa6-regular:square',\n  checkboxIndeterminate: 'i-fa6-solid:square-minus',\n  delimiter: 'i-fa6-solid:circle', // for carousel\n  sortAsc: 'i-fa6-solid:arrow-up',\n  sortDesc: 'i-fa6-solid:arrow-down',\n  expand: 'i-fa6-solid:chevron-down',\n  menu: 'i-fa6-solid:bars',\n  subgroup: 'i-fa6-solid:caret-down',\n  dropdown: 'i-fa6-solid:caret-down',\n  radioOn: 'i-fa6-regular:circle-dot',\n  radioOff: 'i-fa6-regular:circle',\n  edit: 'i-fa6-solid:pencil',\n  ratingEmpty: 'i-fa6-regular:star',\n  ratingFull: 'i-fa6-solid:star',\n  ratingHalf: 'i-fa6-solid:star-half-stroke',\n  loading: 'i-fa6-solid:arrows-rotate',\n  first: 'i-fa6-solid:angles-left',\n  last: 'i-fa6-solid:angles-right',\n  unfold: 'i-fa6-solid:up-down',\n  file: 'i-fa6-solid:paperclip',\n  plus: 'i-fa6-solid:plus',\n  minus: 'i-fa6-solid:minus',\n  calendar: 'i-fa6-regular:calendar',\n  treeviewCollapse: 'i-fa6-solid:caret-down',\n  treeviewExpand: 'i-fa6-solid:caret-right',\n  tableGroupExpand: 'i-fa6-solid:chevron-right',\n  tableGroupCollapse: 'i-fa6-solid:chevron-down',\n  eyeDropper: 'i-fa6-solid:eye-dropper',\n  upload: 'i-fa6-solid:cloud-arrow-up',\n  color: 'i-fa6-solid:palette',\n  command: mdiAliases.command,\n  ctrl: mdiAliases.ctrl,\n  space: mdiAliases.space,\n  shift: 'i-fa6-solid:up-long',\n  alt: mdiAliases.alt,\n  enter: mdiAliases.enter,\n  arrowup: 'i-fa6-solid:arrow-up',\n  arrowdown: 'i-fa6-solid:arrow-down',\n  arrowleft: 'i-fa6-solid:arrow-left',\n  arrowright: 'i-fa6-solid:arrow-right',\n  backspace: 'i-fa6-solid:delete-left',\n  play: 'i-fa6-solid:play',\n  pause: 'i-fa6-solid:pause',\n  fullscreen: 'i-fa6-solid:maximize',\n  fullscreenExit: 'i-fa6-solid:minimize',\n  volumeHigh: 'i-fa6-solid:volume-high',\n  volumeMedium: 'i-fa6-solid:volume-low',\n  volumeLow: 'i-fa6-solid:volume-off',\n  volumeOff: 'i-fa6-solid:volume-xmark',\n  search: 'i-fa6-solid:magnifying-glass',\n}\n\nconst fa6: IconSet = {\n  component: (props: any) => h(VClassIcon, { ...props, class: 'fa6' }),\n}\n\nexport { aliases, fa6 }\n"
  },
  {
    "path": "packages/vuetify/src/iconsets/lucide.ts",
    "content": "// @unocss-include\n// Composables\nimport { VClassIcon } from '@/composables/icons'\n\n// Utilities\nimport { h } from 'vue'\n\nimport { aliases as mdiAliases } from './mdi-svg'\n\n// Types\nimport type { IconAliases, IconSet } from '@/composables/icons'\n\nconst aliases: IconAliases = {\n  collapse: 'i-lucide:chevron-up',\n  complete: 'i-lucide:check',\n  cancel: 'i-lucide:circle-x',\n  close: 'i-lucide:x',\n  delete: 'i-lucide:circle-x', // delete (e.g. v-chip close)\n  clear: 'i-lucide:circle-x',\n  success: 'i-lucide:circle-check-big',\n  info: 'i-lucide:info',\n  warning: 'i-lucide:triangle-alert',\n  error: 'i-lucide:circle-x',\n  prev: 'i-lucide:chevron-left',\n  next: 'i-lucide:chevron-right',\n  checkboxOn: 'i-lucide:square-check',\n  checkboxOff: 'i-lucide:square',\n  checkboxIndeterminate: 'i-lucide:square-minus',\n  delimiter: mdiAliases.delimiter, // for carousel\n  sortAsc: 'i-lucide:arrow-up',\n  sortDesc: 'i-lucide:arrow-down',\n  expand: 'i-lucide:chevron-down',\n  menu: 'i-lucide:menu',\n  subgroup: 'i-lucide:chevron-down',\n  dropdown: 'i-lucide:chevron-down',\n  radioOn: 'i-lucide:circle-check',\n  radioOff: 'i-lucide:circle',\n  edit: 'i-lucide:pencil',\n  ratingEmpty: 'i-lucide:star',\n  ratingFull: 'i-lucide:star',\n  ratingHalf: 'i-lucide:star-half',\n  loading: 'i-lucide:refresh-cw',\n  first: 'i-lucide:chevrons-left',\n  last: 'i-lucide:chevrons-right',\n  unfold: 'i-lucide:unfold-vertical',\n  file: 'i-lucide:paperclip',\n  plus: 'i-lucide:plus',\n  minus: 'i-lucide:minus',\n  calendar: 'i-lucide:calendar',\n  treeviewCollapse: 'i-lucide:chevron-down',\n  treeviewExpand: 'i-lucide:chevron-right',\n  tableGroupExpand: 'i-lucide:chevron-right',\n  tableGroupCollapse: 'i-lucide:chevron-down',\n  eyeDropper: 'i-lucide:pipette',\n  upload: 'i-lucide:cloud-upload',\n  color: 'i-lucide:palette',\n  command: 'i-lucide:command',\n  ctrl: 'i-lucide:chevron-up',\n  space: 'i-lucide:space',\n  shift: 'i-lucide:arrow-big-up',\n  alt: 'i-lucide:option',\n  enter: 'i-lucide:corner-down-left',\n  arrowup: 'i-lucide:arrow-up',\n  arrowdown: 'i-lucide:arrow-down',\n  arrowleft: 'i-lucide:arrow-left',\n  arrowright: 'i-lucide:arrow-right',\n  backspace: 'i-lucide:delete',\n  play: 'i-lucide:play',\n  pause: 'i-lucide:pause',\n  fullscreen: 'i-lucide:maximize',\n  fullscreenExit: 'i-lucide:minimize',\n  volumeHigh: 'i-lucide:volume-2',\n  volumeMedium: 'i-lucide:volume-1',\n  volumeLow: 'i-lucide:volume',\n  volumeOff: 'i-lucide:volume-x',\n  search: 'i-lucide:search',\n}\n\nconst lucide: IconSet = {\n  component: (props: any) => h(VClassIcon, { ...props, class: 'lucide' }),\n}\n\nexport { aliases, lucide }\n"
  },
  {
    "path": "packages/vuetify/src/iconsets/md.ts",
    "content": "// Composables\nimport { VLigatureIcon } from '@/composables/icons'\n\n// Utilities\nimport { h } from 'vue'\n\n// Types\nimport type { IconAliases, IconSet } from '@/composables/icons'\n\nconst aliases: IconAliases = {\n  collapse: 'keyboard_arrow_up',\n  complete: 'check',\n  cancel: 'cancel',\n  close: 'close',\n  delete: 'cancel', // delete (e.g. v-chip close)\n  clear: 'cancel',\n  success: 'check_circle',\n  info: 'info',\n  warning: 'priority_high',\n  error: 'warning',\n  prev: 'chevron_left',\n  next: 'chevron_right',\n  checkboxOn: 'check_box',\n  checkboxOff: 'check_box_outline_blank',\n  checkboxIndeterminate: 'indeterminate_check_box',\n  delimiter: 'fiber_manual_record', // for carousel\n  sortAsc: 'arrow_upward',\n  sortDesc: 'arrow_downward',\n  expand: 'keyboard_arrow_down',\n  menu: 'menu',\n  subgroup: 'arrow_drop_down',\n  dropdown: 'arrow_drop_down',\n  radioOn: 'radio_button_checked',\n  radioOff: 'radio_button_unchecked',\n  edit: 'edit',\n  ratingEmpty: 'star_border',\n  ratingFull: 'star',\n  ratingHalf: 'star_half',\n  loading: 'cached',\n  first: 'first_page',\n  last: 'last_page',\n  unfold: 'unfold_more',\n  file: 'attach_file',\n  plus: 'add',\n  minus: 'remove',\n  calendar: 'event',\n  treeviewCollapse: 'arrow_drop_down',\n  treeviewExpand: 'arrow_right',\n  tableGroupCollapse: 'chevron_down',\n  tableGroupExpand: 'chevron_right',\n  eyeDropper: 'colorize',\n  upload: 'cloud_upload',\n  color: 'palette',\n  command: 'keyboard_command_key',\n  ctrl: 'keyboard_control_key',\n  shift: 'shift',\n  alt: 'keyboard_option_key',\n  space: 'keyboard_space',\n  enter: 'keyboard_return',\n  arrowup: 'keyboard_arrow_up',\n  arrowdown: 'keyboard_arrow_down',\n  arrowleft: 'keyboard_arrow_left',\n  arrowright: 'keyboard_arrow_right',\n  backspace: 'backspace',\n  play: 'play',\n  pause: 'pause',\n  fullscreen: 'fullscreen',\n  fullscreenExit: 'fullscreen_exit',\n  volumeHigh: 'volume_high',\n  volumeMedium: 'volume_medium',\n  volumeLow: 'volume_low',\n  volumeOff: 'volume_variant_off',\n  search: 'search',\n}\n\nconst md: IconSet = {\n  // Not using mergeProps here, functional components merge props by default (?)\n  component: props => h(VLigatureIcon, { ...props, class: 'material-icons' }),\n}\n\nexport { aliases, md }\n"
  },
  {
    "path": "packages/vuetify/src/iconsets/mdi-svg.ts",
    "content": "/* eslint-disable max-len */\n\n// Composables\nimport { VSvgIcon } from '@/composables/icons'\n\n// Types\nimport type { IconAliases, IconSet } from '@/composables/icons'\n\nconst aliases: IconAliases = {\n  collapse: 'svg:M7.41,15.41L12,10.83L16.59,15.41L18,14L12,8L6,14L7.41,15.41Z',\n  complete: 'svg:M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z',\n  cancel: 'svg:M12,2C17.53,2 22,6.47 22,12C22,17.53 17.53,22 12,22C6.47,22 2,17.53 2,12C2,6.47 6.47,2 12,2M15.59,7L12,10.59L8.41,7L7,8.41L10.59,12L7,15.59L8.41,17L12,13.41L15.59,17L17,15.59L13.41,12L17,8.41L15.59,7Z',\n  close: 'svg:M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z',\n  delete: 'svg:M12,2C17.53,2 22,6.47 22,12C22,17.53 17.53,22 12,22C6.47,22 2,17.53 2,12C2,6.47 6.47,2 12,2M15.59,7L12,10.59L8.41,7L7,8.41L10.59,12L7,15.59L8.41,17L12,13.41L15.59,17L17,15.59L13.41,12L17,8.41L15.59,7Z', // delete (e.g. v-chip close)\n  clear: 'svg:M12,2C17.53,2 22,6.47 22,12C22,17.53 17.53,22 12,22C6.47,22 2,17.53 2,12C2,6.47 6.47,2 12,2M15.59,7L12,10.59L8.41,7L7,8.41L10.59,12L7,15.59L8.41,17L12,13.41L15.59,17L17,15.59L13.41,12L17,8.41L15.59,7Z',\n  success: 'svg:M12,2C17.52,2 22,6.48 22,12C22,17.52 17.52,22 12,22C6.48,22 2,17.52 2,12C2,6.48 6.48,2 12,2M11,16.5L18,9.5L16.59,8.09L11,13.67L7.91,10.59L6.5,12L11,16.5Z',\n  info: 'svg:M13,9H11V7H13M13,17H11V11H13M12,2C6.48,2 2,6.48 2,12C2,17.52 6.48,22 12,22C17.52,22 22,17.52 22,12C22,6.48 17.52,2 12,2Z',\n  warning: 'svg:M13,13H11V7H13M13,17H11V15H13M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z',\n  error: 'svg:M12,2C17.53,2 22,6.47 22,12C22,17.53 17.53,22 12,22C6.47,22 2,17.53 2,12C2,6.47 6.47,2 12,2M15.59,7L12,10.59L8.41,7L7,8.41L10.59,12L7,15.59L8.41,17L12,13.41L15.59,17L17,15.59L13.41,12L17,8.41L15.59,7Z',\n  prev: 'svg:M15.41,16.58L10.83,12L15.41,7.41L14,6L8,12L14,18L15.41,16.58Z',\n  next: 'svg:M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z',\n  checkboxOn: 'svg:M10,17L5,12L6.41,10.58L10,14.17L17.59,6.58L19,8M19,3H5C3.89,3 3,3.89 3,5V19C3,20.1 3.9,21 5,21H19C20.1,21 21,20.1 21,19V5C21,3.89 20.1,3 19,3Z',\n  checkboxOff: 'svg:M19,3H5C3.89,3 3,3.89 3,5V19C3,20.1 3.9,21 5,21H19C20.1,21 21,20.1 21,19V5C21,3.89 20.1,3 19,3M19,5V19H5V5H19Z',\n  checkboxIndeterminate: 'svg:M17,13H7V11H17M19,3H5C3.89,3 3,3.89 3,5V19C3,20.1 3.9,21 5,21H19C20.1,21 21,20.1 21,19V5C21,3.89 20.1,3 19,3Z',\n  delimiter: 'svg:M12,2C6.48,2 2,6.48 2,12C2,17.52 6.48,22 12,22C17.52,22 22,17.52 22,12C22,6.48 17.52,2 12,2Z', // for carousel\n  sortAsc: 'svg:M13,20H11V8L5.5,13.5L4.08,12.08L12,4.16L19.92,12.08L18.5,13.5L13,8V20Z',\n  sortDesc: 'svg:M11,4H13V16L18.5,10.5L19.92,11.92L12,19.84L4.08,11.92L5.5,10.5L11,16V4Z',\n  expand: 'svg:M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z',\n  menu: 'svg:M3,6H21V8H3V6M3,11H21V13H3V11M3,16H21V18H3V16Z',\n  subgroup: 'svg:M7,10L12,15L17,10H7Z',\n  dropdown: 'svg:M7,10L12,15L17,10H7Z',\n  radioOn: 'svg:M12,20C7.58,20 4,16.42 4,12C4,7.58 7.58,4 12,4C16.42,4 20,7.58 20,12C20,16.42 16.42,20 12,20M12,2C6.48,2 2,6.48 2,12C2,17.52 6.48,22 12,22C17.52,22 22,17.52 22,12C22,6.48 17.52,2 12,2M12,7C9.24,7 7,9.24 7,12C7,14.76 9.24,17 12,17C14.76,17 17,14.76 17,12C17,9.24 14.76,7 12,7Z',\n  radioOff: 'svg:M12,20C7.58,20 4,16.42 4,12C4,7.58 7.58,4 12,4C16.42,4 20,7.58 20,12C20,16.42 16.42,20 12,20M12,2C6.48,2 2,6.48 2,12C2,17.52 6.48,22 12,22C17.52,22 22,17.52 22,12C22,6.48 17.52,2 12,2Z',\n  edit: 'svg:M20.71,7.04C21.1,6.65 21.1,6 20.71,5.63L18.37,3.29C18,2.9 17.35,2.9 16.96,3.29L15.12,5.12L18.87,8.87M3,17.25V21H6.75L17.81,9.93L14.06,6.18L3,17.25Z',\n  ratingEmpty: 'svg:M12,15.39L8.24,17.66L9.23,13.38L5.91,10.5L10.29,10.13L12,6.09L13.71,10.13L18.09,10.5L14.77,13.38L15.76,17.66M22,9.24L14.81,8.63L12,2L9.19,8.63L2,9.24L7.45,13.97L5.82,21L12,17.27L18.18,21L16.54,13.97L22,9.24Z',\n  ratingFull: 'svg:M12,17.27L18.18,21L16.54,13.97L22,9.24L14.81,8.62L12,2L9.19,8.62L2,9.24L7.45,13.97L5.82,21L12,17.27Z',\n  ratingHalf: 'svg:M12,15.4V6.1L13.71,10.13L18.09,10.5L14.77,13.39L15.76,17.67M22,9.24L14.81,8.63L12,2L9.19,8.63L2,9.24L7.45,13.97L5.82,21L12,17.27L18.18,21L16.54,13.97L22,9.24Z',\n  loading: 'svg:M19,8L15,12H18C18,15.31 15.31,18 12,18C11,18 10.03,17.75 9.2,17.3L7.74,18.76C8.97,19.54 10.43,20 12,20C16.42,20 20,16.42 20,12H23M6,12C6,8.69 8.69,6 12,6C13,6 13.97,6.25 14.8,6.7L16.26,5.24C15.03,4.46 13.57,4 12,4C7.58,4 4,7.58 4,12H1L5,16L9,12',\n  first: 'svg:M18.41,16.59L13.82,12L18.41,7.41L17,6L11,12L17,18L18.41,16.59M6,6H8V18H6V6Z',\n  last: 'svg:M5.59,7.41L10.18,12L5.59,16.59L7,18L13,12L7,6L5.59,7.41M16,6H18V18H16V6Z',\n  unfold: 'svg:M12,18.17L8.83,15L7.42,16.41L12,21L16.59,16.41L15.17,15M12,5.83L15.17,9L16.58,7.59L12,3L7.41,7.59L8.83,9L12,5.83Z',\n  file: 'svg:M16.5,6V17.5C16.5,19.71 14.71,21.5 12.5,21.5C10.29,21.5 8.5,19.71 8.5,17.5V5C8.5,3.62 9.62,2.5 11,2.5C12.38,2.5 13.5,3.62 13.5,5V15.5C13.5,16.05 13.05,16.5 12.5,16.5C11.95,16.5 11.5,16.05 11.5,15.5V6H10V15.5C10,16.88 11.12,18 12.5,18C13.88,18 15,16.88 15,15.5V5C15,2.79 13.21,1 11,1C8.79,1 7,2.79 7,5V17.5C7,20.54 9.46,23 12.5,23C15.54,23 18,20.54 18,17.5V6H16.5Z',\n  plus: 'svg:M19,13H13V19H11V13H5V11H11V5H13V11H19V13Z',\n  minus: 'svg:M19,13H5V11H19V13Z',\n  calendar: 'svg:M19,19H5V8H19M16,1V3H8V1H6V3H5C3.89,3 3,3.89 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5C21,3.89 20.1,3 19,3H18V1M17,12H12V17H17V12Z',\n  treeviewCollapse: 'svg:M7,10L12,15L17,10H7Z',\n  treeviewExpand: 'svg:M10,17L15,12L10,7V17Z',\n  tableGroupExpand: 'svg:M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z',\n  tableGroupCollapse: 'svg:M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z',\n  eyeDropper: 'svg:M19.35,11.72L17.22,13.85L15.81,12.43L8.1,20.14L3.5,22L2,20.5L3.86,15.9L11.57,8.19L10.15,6.78L12.28,4.65L19.35,11.72M16.76,3C17.93,1.83 19.83,1.83 21,3C22.17,4.17 22.17,6.07 21,7.24L19.08,9.16L14.84,4.92L16.76,3M5.56,17.03L4.5,19.5L6.97,18.44L14.4,11L13,9.6L5.56,17.03Z',\n  upload: 'svg:M11 20H6.5q-2.28 0-3.89-1.57Q1 16.85 1 14.58q0-1.95 1.17-3.48q1.18-1.53 3.08-1.95q.63-2.3 2.5-3.72Q9.63 4 12 4q2.93 0 4.96 2.04Q19 8.07 19 11q1.73.2 2.86 1.5q1.14 1.28 1.14 3q0 1.88-1.31 3.19T18.5 20H13v-7.15l1.6 1.55L16 13l-4-4l-4 4l1.4 1.4l1.6-1.55Z',\n  color: 'svg:M17.5 12a1.5 1.5 0 0 1-1.5-1.5A1.5 1.5 0 0 1 17.5 9a1.5 1.5 0 0 1 1.5 1.5a1.5 1.5 0 0 1-1.5 1.5m-3-4A1.5 1.5 0 0 1 13 6.5A1.5 1.5 0 0 1 14.5 5A1.5 1.5 0 0 1 16 6.5A1.5 1.5 0 0 1 14.5 8m-5 0A1.5 1.5 0 0 1 8 6.5A1.5 1.5 0 0 1 9.5 5A1.5 1.5 0 0 1 11 6.5A1.5 1.5 0 0 1 9.5 8m-3 4A1.5 1.5 0 0 1 5 10.5A1.5 1.5 0 0 1 6.5 9A1.5 1.5 0 0 1 8 10.5A1.5 1.5 0 0 1 6.5 12M12 3a9 9 0 0 0-9 9a9 9 0 0 0 9 9a1.5 1.5 0 0 0 1.5-1.5c0-.39-.15-.74-.39-1c-.23-.27-.38-.62-.38-1a1.5 1.5 0 0 1 1.5-1.5H16a5 5 0 0 0 5-5c0-4.42-4.03-8-9-8',\n  command: 'svg:M6,2A4,4 0 0,1 10,6V8H14V6A4,4 0 0,1 18,2A4,4 0 0,1 22,6A4,4 0 0,1 18,10H16V14H18A4,4 0 0,1 22,18A4,4 0 0,1 18,22A4,4 0 0,1 14,18V16H10V18A4,4 0 0,1 6,22A4,4 0 0,1 2,18A4,4 0 0,1 6,14H8V10H6A4,4 0 0,1 2,6A4,4 0 0,1 6,2M16,18A2,2 0 0,0 18,20A2,2 0 0,0 20,18A2,2 0 0,0 18,16H16V18M14,10H10V14H14V10M6,16A2,2 0 0,0 4,18A2,2 0 0,0 6,20A2,2 0 0,0 8,18V16H6M8,6A2,2 0 0,0 6,4A2,2 0 0,0 4,6A2,2 0 0,0 6,8H8V6M18,8A2,2 0 0,0 20,6A2,2 0 0,0 18,4A2,2 0 0,0 16,6V8H18Z',\n  ctrl: 'svg:M19.78,11.78L18.36,13.19L12,6.83L5.64,13.19L4.22,11.78L12,4L19.78,11.78Z',\n  space: 'svg:M3 15H5V19H19V15H21V19C21 20.1 20.1 21 19 21H5C3.9 21 3 20.1 3 19V15Z',\n  shift: 'svg:M15 18v-6h2.17L12 6.83L6.83 12H9v6zM12 4l10 10h-5v6H7v-6H2z',\n  alt: 'svg:M3 4h6.11l7.04 14H21v2h-6.12L7.84 6H3zm11 0h7v2h-7z',\n  enter: 'svg:M19 7v4H5.83l3.58-3.59L8 6l-6 6l6 6l1.41-1.42L5.83 13H21V7z',\n  arrowup: 'svg:M13 20h-2V8l-5.5 5.5l-1.42-1.42L12 4.16l7.92 7.92l-1.42 1.42L13 8z',\n  arrowdown: 'svg:M11 4h2v12l5.5-5.5l1.42 1.42L12 19.84l-7.92-7.92L5.5 10.5L11 16z',\n  arrowleft: 'svg:M20 11v2H8l5.5 5.5l-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5L8 11z',\n  arrowright: 'svg:M4 11v2h12l-5.5 5.5l1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5L16 11z',\n  backspace: 'svg:M19 15.59L17.59 17L14 13.41L10.41 17L9 15.59L12.59 12L9 8.41L10.41 7L14 10.59L17.59 7L19 8.41L15.41 12zM22 3a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H7c-.69 0-1.23-.36-1.59-.89L0 12l5.41-8.12C5.77 3.35 6.31 3 7 3zm0 2H7l-4.72 7L7 19h15z',\n  play: 'svg:M8,5.14V19.14L19,12.14L8,5.14Z',\n  pause: 'svg:M14,19H18V5H14M6,19H10V5H6V19Z',\n  fullscreen: 'svg:M5,5H10V7H7V10H5V5M14,5H19V10H17V7H14V5M17,14H19V19H14V17H17V14M10,17V19H5V14H7V17H10Z',\n  fullscreenExit: 'svg:M14,14H19V16H16V19H14V14M5,14H10V19H8V16H5V14M8,5H10V10H5V8H8V5M19,8V10H14V5H16V8H19Z',\n  volumeHigh: 'svg:M14,3.23V5.29C16.89,6.15 19,8.83 19,12C19,15.17 16.89,17.84 14,18.7V20.77C18,19.86 21,16.28 21,12C21,7.72 18,4.14 14,3.23M16.5,12C16.5,10.23 15.5,8.71 14,7.97V16C15.5,15.29 16.5,13.76 16.5,12M3,9V15H7L12,20V4L7,9H3Z',\n  volumeMedium: 'svg:M5,9V15H9L14,20V4L9,9M18.5,12C18.5,10.23 17.5,8.71 16,7.97V16C17.5,15.29 18.5,13.76 18.5,12Z',\n  volumeLow: 'svg:M7,9V15H11L16,20V4L11,9H7Z',\n  volumeOff: 'svg:M5.64,3.64L21.36,19.36L19.95,20.78L16,16.83V20L11,15H7V9H8.17L4.22,5.05L5.64,3.64M16,4V11.17L12.41,7.58L16,4Z',\n  search: 'svg:M9.5,3A6.5,6.5 0 0,1 16,9.5C16,11.11 15.41,12.59 14.44,13.73L14.71,14H15.5L20.5,19L19,20.5L14,15.5V14.71L13.73,14.44C12.59,15.41 11.11,16 9.5,16A6.5,6.5 0 0,1 3,9.5A6.5,6.5 0 0,1 9.5,3M9.5,5C7,5 5,7 5,9.5C5,12 7,14 9.5,14C12,14 14,12 14,9.5C14,7 12,5 9.5,5Z',\n}\n\nconst mdi: IconSet = {\n  component: VSvgIcon,\n}\n\nexport { aliases, mdi }\n"
  },
  {
    "path": "packages/vuetify/src/iconsets/mdi-unocss.ts",
    "content": "// @unocss-include\n// Composables\nimport { VClassIcon } from '@/composables/icons'\n\n// Utilities\nimport { h } from 'vue'\n\n// Types\nimport type { IconAliases, IconSet } from '@/composables/icons'\n\nconst aliases: IconAliases = {\n  collapse: 'i-mdi:chevron-up',\n  complete: 'i-mdi:check',\n  cancel: 'i-mdi:close-circle',\n  close: 'i-mdi:close',\n  // delete (e.g. v-chip close)\n  delete: 'i-mdi:close-circle',\n  clear: 'i-mdi:close-circle',\n  success: 'i-mdi:check-circle',\n  info: 'i-mdi:information',\n  warning: 'i-mdi:alert-circle',\n  error: 'i-mdi:close-circle',\n  prev: 'i-mdi:chevron-left',\n  next: 'i-mdi:chevron-right',\n  checkboxOn: 'i-mdi:checkbox-marked',\n  checkboxOff: 'i-mdi:checkbox-blank-outline',\n  checkboxIndeterminate: 'i-mdi:minus-box',\n  delimiter: 'i-mdi:circle',\n  // for carousel\n  sortAsc: 'i-mdi:arrow-up',\n  sortDesc: 'i-mdi:arrow-down',\n  expand: 'i-mdi:chevron-down',\n  menu: 'i-mdi:menu',\n  subgroup: 'i-mdi:menu-down',\n  dropdown: 'i-mdi:menu-down',\n  radioOn: 'i-mdi:radiobox-marked',\n  radioOff: 'i-mdi:radiobox-blank',\n  edit: 'i-mdi:pencil',\n  ratingEmpty: 'i-mdi:star-outline',\n  ratingFull: 'i-mdi:star',\n  ratingHalf: 'i-mdi:star-half-full',\n  loading: 'i-mdi:cached',\n  first: 'i-mdi:page-first',\n  last: 'i-mdi:page-last',\n  unfold: 'i-mdi:unfold-more-horizontal',\n  file: 'i-mdi:paperclip',\n  plus: 'i-mdi:plus',\n  minus: 'i-mdi:minus',\n  calendar: 'i-mdi:calendar',\n  treeviewCollapse: 'i-mdi:menu-down',\n  treeviewExpand: 'i-mdi:menu-right',\n  tableGroupCollapse: 'i-mdi:chevron-down',\n  tableGroupExpand: 'i-mdi:chevron-right',\n  eyeDropper: 'i-mdi:eyedropper',\n  upload: 'i-mdi:cloud-upload',\n  color: 'i-mdi:palette',\n  command: 'i-mdi:apple-keyboard-command',\n  ctrl: 'i-mdi:apple-keyboard-control',\n  space: 'i-mdi:keyboard-space',\n  shift: 'i-mdi:apple-keyboard-shift',\n  alt: 'i-mdi:apple-keyboard-option',\n  enter: 'i-mdi:keyboard-return',\n  arrowup: 'i-mdi:arrow-up',\n  arrowdown: 'i-mdi:arrow-down',\n  arrowleft: 'i-mdi:arrow-left',\n  arrowright: 'i-mdi:arrow-right',\n  backspace: 'i-mdi:backspace',\n  play: 'i-mdi:play',\n  pause: 'i-mdi:pause',\n  fullscreen: 'i-mdi:fullscreen',\n  fullscreenExit: 'i-mdi:fullscreen-exit',\n  volumeHigh: 'i-mdi:volume-high',\n  volumeMedium: 'i-mdi:volume-medium',\n  volumeLow: 'i-mdi:volume-low',\n  volumeOff: 'i-mdi:volume-variant-off',\n  search: 'i-mdi:magnify',\n}\n\nconst mdi: IconSet = {\n  // Not using mergeProps here, functional components merge props by default (?)\n  component: (props: any) => h(VClassIcon, { ...props, class: 'mdi' }),\n}\n\nexport { aliases, mdi }\n"
  },
  {
    "path": "packages/vuetify/src/iconsets/mdi.ts",
    "content": "// Composables\nimport { VClassIcon } from '@/composables/icons'\n\n// Utilities\nimport { h } from 'vue'\n\n// Types\nimport type { IconAliases, IconSet } from '@/composables/icons'\n\nconst aliases: IconAliases = {\n  collapse: 'mdi-chevron-up',\n  complete: 'mdi-check',\n  cancel: 'mdi-close-circle',\n  close: 'mdi-close',\n  delete: 'mdi-close-circle', // delete (e.g. v-chip close)\n  clear: 'mdi-close-circle',\n  success: 'mdi-check-circle',\n  info: 'mdi-information',\n  warning: 'mdi-alert-circle',\n  error: 'mdi-close-circle',\n  prev: 'mdi-chevron-left',\n  next: 'mdi-chevron-right',\n  checkboxOn: 'mdi-checkbox-marked',\n  checkboxOff: 'mdi-checkbox-blank-outline',\n  checkboxIndeterminate: 'mdi-minus-box',\n  delimiter: 'mdi-circle', // for carousel\n  sortAsc: 'mdi-arrow-up',\n  sortDesc: 'mdi-arrow-down',\n  expand: 'mdi-chevron-down',\n  menu: 'mdi-menu',\n  subgroup: 'mdi-menu-down',\n  dropdown: 'mdi-menu-down',\n  radioOn: 'mdi-radiobox-marked',\n  radioOff: 'mdi-radiobox-blank',\n  edit: 'mdi-pencil',\n  ratingEmpty: 'mdi-star-outline',\n  ratingFull: 'mdi-star',\n  ratingHalf: 'mdi-star-half-full',\n  loading: 'mdi-cached',\n  first: 'mdi-page-first',\n  last: 'mdi-page-last',\n  unfold: 'mdi-unfold-more-horizontal',\n  file: 'mdi-paperclip',\n  plus: 'mdi-plus',\n  minus: 'mdi-minus',\n  calendar: 'mdi-calendar',\n  treeviewCollapse: 'mdi-menu-down',\n  treeviewExpand: 'mdi-menu-right',\n  tableGroupCollapse: 'mdi-chevron-down',\n  tableGroupExpand: 'mdi-chevron-right',\n  eyeDropper: 'mdi-eyedropper',\n  upload: 'mdi-cloud-upload',\n  color: 'mdi-palette',\n  command: 'mdi-apple-keyboard-command',\n  ctrl: 'mdi-apple-keyboard-control',\n  space: 'mdi-keyboard-space',\n  shift: 'mdi-apple-keyboard-shift',\n  alt: 'mdi-apple-keyboard-option',\n  enter: 'mdi-keyboard-return',\n  arrowup: 'mdi-arrow-up',\n  arrowdown: 'mdi-arrow-down',\n  arrowleft: 'mdi-arrow-left',\n  arrowright: 'mdi-arrow-right',\n  backspace: 'mdi-backspace',\n  play: 'mdi-play',\n  pause: 'mdi-pause',\n  fullscreen: 'mdi-fullscreen',\n  fullscreenExit: 'mdi-fullscreen-exit',\n  volumeHigh: 'mdi-volume-high',\n  volumeMedium: 'mdi-volume-medium',\n  volumeLow: 'mdi-volume-low',\n  volumeOff: 'mdi-volume-variant-off',\n  search: 'mdi-magnify',\n}\n\nconst mdi: IconSet = {\n  // Not using mergeProps here, functional components merge props by default (?)\n  component: (props: any) => h(VClassIcon, { ...props, class: 'mdi' }),\n}\n\nexport { aliases, mdi }\n"
  },
  {
    "path": "packages/vuetify/src/iconsets/ms.ts",
    "content": "// @unocss-include\n// Composables\nimport { VClassIcon } from '@/composables/icons'\n\n// Utilities\nimport { h } from 'vue'\n\n// Types\nimport type { IconAliases, IconSet } from '@/composables/icons'\n\nconst aliases: IconAliases = {\n  collapse: 'i-material-symbols:keyboard-arrow-up',\n  complete: 'i-material-symbols:check',\n  cancel: 'i-material-symbols:cancel',\n  close: 'i-material-symbols:close',\n  delete: 'i-material-symbols:cancel', // delete (e.g. v-chip close)\n  clear: 'i-material-symbols:cancel',\n  success: 'i-material-symbols:check-circle',\n  info: 'i-material-symbols:info',\n  warning: 'i-material-symbols:warning',\n  error: 'i-material-symbols:error',\n  prev: 'i-material-symbols:chevron-left',\n  next: 'i-material-symbols:chevron-right',\n  checkboxOn: 'i-material-symbols:check-box',\n  checkboxOff: 'i-material-symbols:check-box-outline-blank',\n  checkboxIndeterminate: 'i-material-symbols:indeterminate-check-box',\n  delimiter: 'i-material-symbols:circle', // for carousel\n  sortAsc: 'i-material-symbols:arrow-upward',\n  sortDesc: 'i-material-symbols:arrow-downward',\n  expand: 'i-material-symbols:keyboard-arrow-down',\n  menu: 'i-material-symbols:menu',\n  subgroup: 'i-material-symbols:arrow-drop-down',\n  dropdown: 'i-material-symbols:arrow-drop-down',\n  radioOn: 'i-material-symbols:radio-button-checked',\n  radioOff: 'i-material-symbols:radio-button-unchecked',\n  edit: 'i-material-symbols:edit',\n  ratingEmpty: 'i-material-symbols:star-outline',\n  ratingFull: 'i-material-symbols:star',\n  ratingHalf: 'i-material-symbols:star-half',\n  loading: 'i-material-symbols:cached',\n  first: 'i-material-symbols:first-page',\n  last: 'i-material-symbols:last-page',\n  unfold: 'i-material-symbols:unfold-more',\n  file: 'i-material-symbols:attach-file',\n  plus: 'i-material-symbols:add',\n  minus: 'i-material-symbols:remove',\n  calendar: 'i-material-symbols:calendar-today',\n  treeviewCollapse: 'i-material-symbols:arrow-drop-down',\n  treeviewExpand: 'i-material-symbols:arrow-right',\n  tableGroupExpand: 'i-material-symbols:chevron-right',\n  tableGroupCollapse: 'i-material-symbols:keyboard-arrow-down',\n  eyeDropper: 'i-material-symbols:colorize',\n  upload: 'i-material-symbols:upload',\n  color: 'i-material-symbols:palette',\n  command: 'i-material-symbols:keyboard-command-key',\n  ctrl: 'i-material-symbols:keyboard-control-key',\n  space: 'i-material-symbols:space-bar',\n  shift: 'i-material-symbols:shift',\n  alt: 'i-material-symbols:keyboard-option-key',\n  enter: 'i-material-symbols:keyboard-return',\n  arrowup: 'i-material-symbols:arrow-upward',\n  arrowdown: 'i-material-symbols:arrow-downward',\n  arrowleft: 'i-material-symbols:arrow-back',\n  arrowright: 'i-material-symbols:arrow-forward',\n  backspace: 'i-material-symbols:backspace-outline',\n  play: 'i-material-symbols:play-arrow',\n  pause: 'i-material-symbols:pause',\n  fullscreen: 'i-material-symbols:fullscreen',\n  fullscreenExit: 'i-material-symbols:fullscreen-exit',\n  volumeHigh: 'i-material-symbols:volume-up',\n  volumeMedium: 'i-material-symbols:volume-down',\n  volumeLow: 'i-material-symbols:volume-mute',\n  volumeOff: 'i-material-symbols:volume-off',\n  search: 'i-material-symbols:search',\n}\n\nconst ms: IconSet = {\n  component: (props: any) => h(VClassIcon, { ...props, class: 'ms' }),\n}\n\nexport { aliases, ms }\n"
  },
  {
    "path": "packages/vuetify/src/iconsets/ph.ts",
    "content": "// @unocss-include\n// Composables\nimport { VClassIcon } from '@/composables/icons'\n\n// Utilities\nimport { h } from 'vue'\n\nimport { aliases as mdiAliases } from './mdi-svg'\n\n// Types\nimport type { IconAliases, IconSet } from '@/composables/icons'\n\nconst aliases: IconAliases = {\n  collapse: 'i-ph:caret-up',\n  complete: 'i-ph:check',\n  cancel: 'i-ph:x-circle',\n  close: 'i-ph:x',\n  delete: 'i-ph:x-circle', // delete (e.g. v-chip close)\n  clear: 'i-ph:x-circle',\n  success: 'i-ph:check-circle',\n  info: 'i-ph:info',\n  warning: 'i-ph:warning',\n  error: 'i-ph:x-circle',\n  prev: 'i-ph:caret-left',\n  next: 'i-ph:caret-right',\n  checkboxOn: 'i-ph:check-square',\n  checkboxOff: 'i-ph:square',\n  checkboxIndeterminate: 'i-ph:minus-square',\n  delimiter: 'i-ph:circle-fill', // for carousel\n  sortAsc: 'i-ph:arrow-up',\n  sortDesc: 'i-ph:arrow-down',\n  expand: 'i-ph:caret-down',\n  menu: 'i-ph:list',\n  subgroup: 'i-ph:caret-down',\n  dropdown: 'i-ph:caret-down',\n  radioOn: 'i-ph:radio-button-fill',\n  radioOff: 'i-ph:circle',\n  edit: 'i-ph:pencil',\n  ratingEmpty: 'i-ph:star',\n  ratingFull: 'i-ph:star-fill',\n  ratingHalf: 'i-ph:star-half-fill',\n  loading: 'i-ph:arrows-clockwise',\n  first: 'i-ph:caret-double-left',\n  last: 'i-ph:caret-double-right',\n  unfold: 'i-ph:arrows-out-line-vertical',\n  file: 'i-ph:paperclip',\n  plus: 'i-ph:plus',\n  minus: 'i-ph:minus',\n  calendar: 'i-ph:calendar',\n  treeviewCollapse: 'i-ph:caret-down',\n  treeviewExpand: 'i-ph:caret-right',\n  tableGroupExpand: 'i-ph:caret-right',\n  tableGroupCollapse: 'i-ph:caret-down',\n  eyeDropper: 'i-ph:eyedropper',\n  upload: 'i-ph:cloud-arrow-up',\n  color: 'i-ph:palette',\n  command: 'i-ph:command',\n  ctrl: 'i-ph:control',\n  space: mdiAliases.space,\n  shift: 'i-ph:arrow-fat-up',\n  alt: 'i-ph:option',\n  enter: 'i-ph:key-return',\n  arrowup: 'i-ph:arrow-up',\n  arrowdown: 'i-ph:arrow-down',\n  arrowleft: 'i-ph:arrow-left',\n  arrowright: 'i-ph:arrow-right',\n  backspace: 'i-ph:backspace',\n  play: 'i-ph:play',\n  pause: 'i-ph:pause',\n  fullscreen: 'i-ph:arrows-out-simple',\n  fullscreenExit: 'i-ph:arrows-in-simple',\n  volumeHigh: 'i-ph:speaker-high',\n  volumeMedium: 'i-ph:speaker-simple-high',\n  volumeLow: 'i-ph:speaker-low',\n  volumeOff: 'i-ph:speaker-x',\n  search: 'i-ph:magnifying-glass',\n}\n\nconst ph: IconSet = {\n  component: (props: any) => h(VClassIcon, { ...props, class: 'ph' }),\n}\n\nexport { aliases, ph }\n"
  },
  {
    "path": "packages/vuetify/src/iconsets/ri.ts",
    "content": "// @unocss-include\n// Composables\nimport { VClassIcon } from '@/composables/icons'\n\n// Utilities\nimport { h } from 'vue'\n\nimport { aliases as mdiAliases } from './mdi-svg'\n\n// Types\nimport type { IconAliases, IconSet } from '@/composables/icons'\n\nconst aliases: IconAliases = {\n  collapse: 'i-ri:arrow-up-s-line',\n  complete: 'i-ri:check-line',\n  cancel: 'i-ri:close-circle-line',\n  close: 'i-ri:close-line',\n  delete: 'i-ri:close-circle-line', // delete (e.g. v-chip close)\n  clear: 'i-ri:close-circle-line',\n  success: 'i-ri:checkbox-circle-line',\n  info: 'i-ri:information-line',\n  warning: 'i-ri:alert-line',\n  error: 'i-ri:error-warning-line',\n  prev: 'i-ri:arrow-left-s-line',\n  next: 'i-ri:arrow-right-s-line',\n  checkboxOn: 'i-ri:checkbox-fill',\n  checkboxOff: 'i-ri:checkbox-line',\n  checkboxIndeterminate: 'i-ri:checkbox-indeterminate-line',\n  delimiter: 'i-ri:checkbox-blank-circle-fill', // for carousel\n  sortAsc: 'i-ri:arrow-up-line',\n  sortDesc: 'i-ri:arrow-down-line',\n  expand: 'i-ri:arrow-down-s-line',\n  menu: 'i-ri:menu-line',\n  subgroup: 'i-ri:arrow-down-s-fill',\n  dropdown: 'i-ri:arrow-down-s-fill',\n  radioOn: 'i-ri:radio-button-fill',\n  radioOff: 'i-ri:radio-button-line',\n  edit: 'i-ri:pencil-line',\n  ratingEmpty: 'i-ri:star-line',\n  ratingFull: 'i-ri:star-fill',\n  ratingHalf: 'i-ri:star-half-line',\n  loading: 'i-ri:refresh-line',\n  first: 'i-ri:skip-back-line',\n  last: 'i-ri:skip-forward-line',\n  unfold: 'i-ri:expand-up-down-line',\n  file: 'i-ri:attachment-2',\n  plus: 'i-ri:add-line',\n  minus: 'i-ri:subtract-line',\n  calendar: 'i-ri:calendar-line',\n  treeviewCollapse: 'i-ri:arrow-down-s-line',\n  treeviewExpand: 'i-ri:arrow-right-s-line',\n  tableGroupExpand: 'i-ri:arrow-right-s-line',\n  tableGroupCollapse: 'i-ri:arrow-down-s-line',\n  eyeDropper: 'i-ri:dropper-line',\n  upload: 'i-ri:upload-cloud-line',\n  color: 'i-ri:palette-line',\n  command: 'i-ri:command-line',\n  ctrl: 'i-ri:arrow-up-s-line',\n  space: 'i-ri:space',\n  shift: 'i-ri:arrow-up-line',\n  alt: mdiAliases.alt,\n  enter: 'i-ri:corner-down-left-line',\n  arrowup: 'i-ri:arrow-up-line',\n  arrowdown: 'i-ri:arrow-down-line',\n  arrowleft: 'i-ri:arrow-left-line',\n  arrowright: 'i-ri:arrow-right-line',\n  backspace: 'i-ri:delete-back-2-line',\n  play: 'i-ri:play-line',\n  pause: 'i-ri:pause-line',\n  fullscreen: 'i-ri:fullscreen-line',\n  fullscreenExit: 'i-ri:fullscreen-exit-line',\n  volumeHigh: 'i-ri:volume-up-line',\n  volumeMedium: 'i-ri:volume-down-line',\n  volumeLow: 'i-ri:volume-down-line',\n  volumeOff: 'i-ri:volume-mute-line',\n  search: 'i-ri:search-line',\n}\n\nconst ri: IconSet = {\n  component: (props: any) => h(VClassIcon, { ...props, class: 'ri' }),\n}\n\nexport { aliases, ri }\n"
  },
  {
    "path": "packages/vuetify/src/iconsets/tabler.ts",
    "content": "// @unocss-include\n// Composables\nimport { VClassIcon } from '@/composables/icons'\n\n// Utilities\nimport { h } from 'vue'\n\n// Types\nimport type { IconAliases, IconSet } from '@/composables/icons'\n\nconst aliases: IconAliases = {\n  collapse: 'i-tabler:chevron-up',\n  complete: 'i-tabler:check',\n  cancel: 'i-tabler:circle-x',\n  close: 'i-tabler:x',\n  delete: 'i-tabler:circle-x', // delete (e.g. v-chip close)\n  clear: 'i-tabler:circle-x',\n  success: 'i-tabler:circle-check',\n  info: 'i-tabler:info-circle',\n  warning: 'i-tabler:alert-circle',\n  error: 'i-tabler:circle-x',\n  prev: 'i-tabler:chevron-left',\n  next: 'i-tabler:chevron-right',\n  checkboxOn: 'i-tabler:square-check',\n  checkboxOff: 'i-tabler:square',\n  checkboxIndeterminate: 'i-tabler:square-minus',\n  delimiter: 'i-tabler:circle-filled', // for carousel\n  sortAsc: 'i-tabler:arrow-up',\n  sortDesc: 'i-tabler:arrow-down',\n  expand: 'i-tabler:chevron-down',\n  menu: 'i-tabler:menu-2',\n  subgroup: 'i-tabler:caret-down',\n  dropdown: 'i-tabler:caret-down',\n  radioOn: 'i-tabler:circle-check',\n  radioOff: 'i-tabler:circle',\n  edit: 'i-tabler:pencil',\n  ratingEmpty: 'i-tabler:star',\n  ratingFull: 'i-tabler:star-filled',\n  ratingHalf: 'i-tabler:star-half-filled',\n  loading: 'i-tabler:refresh',\n  first: 'i-tabler:chevrons-left',\n  last: 'i-tabler:chevrons-right',\n  unfold: 'i-tabler:arrows-vertical',\n  file: 'i-tabler:paperclip',\n  plus: 'i-tabler:plus',\n  minus: 'i-tabler:minus',\n  calendar: 'i-tabler:calendar',\n  treeviewCollapse: 'i-tabler:chevron-down',\n  treeviewExpand: 'i-tabler:chevron-right',\n  tableGroupExpand: 'i-tabler:chevron-right',\n  tableGroupCollapse: 'i-tabler:chevron-down',\n  eyeDropper: 'i-tabler:color-picker',\n  upload: 'i-tabler:cloud-upload',\n  color: 'i-tabler:palette',\n  command: 'i-tabler:command',\n  ctrl: 'i-tabler:arrow-back',\n  space: 'i-tabler:space',\n  shift: 'i-tabler:arrow-big-up',\n  alt: 'i-tabler:alt',\n  enter: 'i-tabler:corner-down-left',\n  arrowup: 'i-tabler:arrow-up',\n  arrowdown: 'i-tabler:arrow-down',\n  arrowleft: 'i-tabler:arrow-left',\n  arrowright: 'i-tabler:arrow-right',\n  backspace: 'i-tabler:backspace',\n  play: 'i-tabler:player-play',\n  pause: 'i-tabler:player-pause',\n  fullscreen: 'i-tabler:arrows-maximize',\n  fullscreenExit: 'i-tabler:arrows-minimize',\n  volumeHigh: 'i-tabler:volume',\n  volumeMedium: 'i-tabler:volume-2',\n  volumeLow: 'i-tabler:volume-3',\n  volumeOff: 'i-tabler:volume-off',\n  search: 'i-tabler:search',\n}\n\nconst tabler: IconSet = {\n  component: (props: any) => h(VClassIcon, { ...props, class: 'tabler' }),\n}\n\nexport { aliases, tabler }\n"
  },
  {
    "path": "packages/vuetify/src/labs/VAvatarGroup/VAvatarGroup.scss",
    "content": "@use '../../styles/settings';\n@use '../../styles/tools';\n@use './variables' as *;\n\n@include tools.layer('components') {\n  .v-avatar-group {\n    display: inline-flex;\n    align-items: center;\n    gap: $avatar-group-container-gap;\n\n    &--hoverable {\n      .v-avatar {\n        cursor: pointer;\n        transition: transform 0.25s settings.$standard-easing;\n\n        &:hover {\n          transform: $avatar-group-hoverable-horizontal-transform;\n        }\n      }\n\n      &.v-avatar-group--vertical .v-avatar:hover {\n        transform: $avatar-group-hoverable-vertical-transform;\n      }\n    }\n\n    &__content {\n      display: flex;\n      align-items: center;\n    }\n\n    .v-avatar-group__overflow {\n      background: $avatar-group-overflow-background;\n      color: $avatar-group-overflow-color;\n    }\n\n    &--horizontal {\n      .v-avatar:not(:first-child) {\n        margin-inline-start: var(--v-avatar-group-gap, $avatar-group-gap);\n      }\n\n      &.v-avatar-group--reverse {\n        .v-avatar-group__content {\n          flex-direction: row-reverse;\n        }\n\n        /* upgrade someday: https://caniuse.com/wf-sibling-count */\n        // .v-avatar {\n        //   z-index: calc(99 - sibling-index());\n        // }\n\n        .v-avatar:not(:first-child) {\n          margin-inline-start: 0;\n          margin-inline-end: var(--v-avatar-group-gap, $avatar-group-gap);\n        }\n      }\n    }\n\n    &--vertical {\n      .v-avatar-group__content {\n        flex-direction: column;\n      }\n\n      .v-avatar:not(:first-child) {\n        margin-block-start: var(--v-avatar-group-gap, $avatar-group-gap);\n      }\n\n      &.v-avatar-group--reverse {\n        .v-avatar-group__content {\n          flex-direction: column-reverse;\n        }\n\n        .v-avatar:not(:first-child) {\n          margin-block-start: 0;\n          margin-block-end: var(--v-avatar-group-gap, $avatar-group-gap);\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/labs/VAvatarGroup/VAvatarGroup.tsx",
    "content": "// Styles\nimport './VAvatarGroup.scss'\n\n// Components\nimport { VAvatar } from '@/components/VAvatar'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { makeTagProps } from '@/composables/tag'\n\n// Utilities\nimport { computed } from 'vue'\nimport { convertToUnit, genericComponent, getPropertyFromItem, isObject, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { SelectItemKey } from '@/util'\n\nexport type AvatarGroupItem = string | Record<string, any>\n\nexport type VAvatarGroupSlots = {\n  default: never\n  prepend: never\n  append: never\n  item: { props: any, index: number }\n  overflow: { overflow: number }\n}\n\nexport const makeVAvatarGroupProps = propsFactory({\n  border: [Boolean, Number, String],\n  gap: [Number, String],\n  hoverable: Boolean,\n  items: {\n    type: Array as PropType<AvatarGroupItem[]>,\n    default: () => ([]),\n  },\n  itemProps: {\n    type: [Boolean, String, Array, Function] as PropType<SelectItemKey>,\n    default: null,\n  },\n  limit: [Number, String],\n  overflowText: String,\n  reverse: Boolean,\n  size: [Number, String],\n  vertical: Boolean,\n\n  ...makeComponentProps(),\n  ...makeTagProps(),\n}, 'VAvatarGroup')\n\nexport const VAvatarGroup = genericComponent<VAvatarGroupSlots>()({\n  name: 'VAvatarGroup',\n\n  props: makeVAvatarGroupProps(),\n\n  setup (props, { slots }) {\n    const limit = computed(() => props.limit !== null ? Number(props.limit) : null)\n    const overflow = computed(() => {\n      return limit.value && !isNaN(limit.value) && props.items.length > limit.value\n        ? Math.max(0, props.items.length - limit.value + 1)\n        : 0\n    })\n\n    const items = computed(() => {\n      const visibleItems = limit.value && overflow.value > 1\n        ? props.items.slice(0, limit.value - 1)\n        : props.items\n\n      const orderedItems = props.reverse\n        ? visibleItems.toReversed()\n        : visibleItems\n\n      return orderedItems.map(item => {\n        const avatarProps = props.itemProps === true\n          ? (isObject(item) ? item : { image: item })\n          : getPropertyFromItem(item, props.itemProps, item)\n\n        if (avatarProps != null) return avatarProps\n\n        if (!isObject(item)) return { image: item }\n\n        return item\n      })\n    })\n\n    const overflowText = computed(() => props.overflowText ?? (overflow.value ? `+${overflow.value}` : ''))\n\n    const overflowItem = () => (\n      slots.overflow?.({ overflow: overflow.value }) ?? (\n        <VAvatar class=\"v-avatar-group__overflow\" text={ overflowText.value } />\n      )\n    )\n\n    useRender(() => (\n      <props.tag\n        class={[\n          'v-avatar-group',\n          `v-avatar-group--${props.vertical ? 'vertical' : 'horizontal'}`,\n          {\n            'v-avatar-group--hoverable': props.hoverable,\n            'v-avatar-group--reverse': props.reverse,\n          },\n          props.class,\n        ]}\n        style={[\n          { '--v-avatar-group-gap': convertToUnit(props.gap) },\n          props.style,\n        ]}\n      >\n        { slots.prepend?.() }\n\n        <div class=\"v-avatar-group__content\">\n          <VDefaultsProvider\n            defaults={{\n              VAvatar: {\n                size: props.size,\n                border: props.border,\n              },\n            }}\n          >\n            { slots.default?.() ?? (\n              <>\n                { props.reverse && overflowText.value && overflowItem() }\n                { items.value.map((item, index) => (\n                  slots.item?.({ props: item, index }) ?? (\n                    <VAvatar\n                      key={ index }\n                      { ...item }\n                    />\n                  )\n                ))}\n                { !props.reverse && overflowText.value && overflowItem() }\n              </>\n            )}\n          </VDefaultsProvider>\n        </div>\n\n        { slots.append?.() }\n      </props.tag>\n    ))\n\n    return {}\n  },\n})\n\nexport type VAvatarGroup = InstanceType<typeof VAvatarGroup>\n"
  },
  {
    "path": "packages/vuetify/src/labs/VAvatarGroup/__tests__/VAvatarGroup.spec.browser.tsx",
    "content": "import { VAvatarGroup } from '../VAvatarGroup'\n\n// Utilities\nimport { render, screen } from '@test'\n\nconst items = [\n  { text: 'AB', color: 'primary' },\n  { text: 'CD', color: 'secondary' },\n  { text: 'EF', color: 'success' },\n  { text: 'GH', color: 'warning' },\n  { text: 'IJ', color: 'error' },\n]\n\ndescribe('VAvatarGroup', () => {\n  it('should apply border to avatars', () => {\n    render(() => <VAvatarGroup items={ items } border=\"md\" />)\n\n    const avatars = screen.getByCSS('.v-avatar-group').querySelectorAll('.v-avatar')\n    avatars.forEach(avatar => {\n      expect(avatar).toHaveClass('border-md')\n    })\n  })\n\n  it('should set gap css variable', () => {\n    render(() => <VAvatarGroup items={ items } gap={ -16 } />)\n\n    const group = screen.getByCSS('.v-avatar-group')\n    expect(group).toHaveStyle('--v-avatar-group-gap: -16px')\n  })\n\n  it('should show all items if they fit within limit', () => {\n    render(() => <VAvatarGroup items={ items } limit={ 5 } />)\n\n    const avatars = screen.getByCSS('.v-avatar-group__content').querySelectorAll('.v-avatar')\n    expect(avatars).toHaveLength(5)\n    expect(avatars[4]).toHaveTextContent('IJ')\n  })\n\n  it('should limit visible items and show overflow', () => {\n    render(() => <VAvatarGroup items={ items } limit={ 3 } />)\n\n    const avatars = screen.getByCSS('.v-avatar-group__content').querySelectorAll('.v-avatar')\n    expect(avatars).toHaveLength(3) // 2 items + overflow\n    expect(avatars[2]).toHaveTextContent('+3')\n  })\n\n  it('should use custom overflowText', () => {\n    render(() => <VAvatarGroup items={ items } limit={ 2 } overflowText=\"and 4 more\" />)\n\n    const overflow = screen.getByCSS('.v-avatar-group__overflow')\n    expect(overflow).toHaveTextContent('and 4 more')\n  })\n\n  it('should apply vertical class', () => {\n    render(() => <VAvatarGroup items={ items } vertical />)\n\n    const group = screen.getByCSS('.v-avatar-group')\n    expect(group).toHaveClass('v-avatar-group--vertical')\n    expect(group).not.toHaveClass('v-avatar-group--horizontal')\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/labs/VAvatarGroup/_variables.scss",
    "content": "$avatar-group-container-gap: 8px !default;\n$avatar-group-gap: -12px !default;\n$avatar-group-hoverable-horizontal-transform: translateY(-8px) !default;\n$avatar-group-hoverable-vertical-transform: translateX(8px) !default;\n$avatar-group-overflow-background: rgb(var(--v-theme-surface-light)) !default;\n$avatar-group-overflow-color: rgb(var(--v-theme-on-surface-light)) !default;\n"
  },
  {
    "path": "packages/vuetify/src/labs/VAvatarGroup/index.ts",
    "content": "export { VAvatarGroup } from './VAvatarGroup'\n"
  },
  {
    "path": "packages/vuetify/src/labs/VColorInput/VColorInput.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  /* region INPUT */\n  .v-color-input\n    padding: 0\n\n    @at-root\n      @include tools.density('v-color-input.v-input', $color-input-pip-density) using ($modifier)\n        .v-color-input__pip\n          --v-avatar-height: #{$color-input-pip-avatar-size + $modifier}\n\n    .v-color-input__pip.v-avatar--variant-text\n      --v-avatar-height: min-content\n"
  },
  {
    "path": "packages/vuetify/src/labs/VColorInput/VColorInput.tsx",
    "content": "// Styles\nimport './VColorInput.sass'\n\n// Components\nimport { VAvatar } from '@/components/VAvatar'\nimport { makeVColorPickerProps, VColorPicker } from '@/components/VColorPicker/VColorPicker'\nimport { makeVConfirmEditProps, VConfirmEdit } from '@/components/VConfirmEdit/VConfirmEdit'\nimport { VMenu } from '@/components/VMenu/VMenu'\nimport { makeVTextFieldProps, VTextField } from '@/components/VTextField/VTextField'\n\n// Composables\nimport { makeFocusProps } from '@/composables/focus'\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { computed, shallowRef } from 'vue'\nimport { genericComponent, omit, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { VTextFieldSlots } from '@/components/VTextField/VTextField'\n\nexport type VColorInputActionsSlot = {\n  save: () => void\n  cancel: () => void\n  isPristine: boolean\n}\n\nexport type VColorInputSlots = Omit<VTextFieldSlots, 'default'> & {\n  actions: VColorInputActionsSlot\n  default: never\n}\n\nconst availablePipLocations = ['prepend', 'prepend-inner', 'append', 'append-inner'] as const\nexport type PipLocation = typeof availablePipLocations[number]\n\nexport const makeVColorInputProps = propsFactory({\n  hidePip: Boolean,\n  colorPip: Boolean,\n  menuProps: Object as PropType<VMenu['$props']>,\n  pipIcon: {\n    type: String,\n    default: '$color',\n  },\n  pipLocation: {\n    type: String as PropType<PipLocation>,\n    default: 'prepend',\n    validator: (v: any) => availablePipLocations.includes(v),\n  },\n  pipVariant: {\n    type: String as PropType<VAvatar['$props']['variant']>,\n    default: 'text',\n  },\n  pickerProps: Object as PropType<VColorPicker['$props']>,\n\n  ...makeFocusProps(),\n  ...makeVConfirmEditProps(),\n  ...makeVTextFieldProps(),\n  ...omit(makeVColorPickerProps(), [\n    'location',\n    'height',\n    'minHeight',\n    'maxHeight',\n  ]),\n}, 'VColorInput')\n\nexport const VColorInput = genericComponent<VColorInputSlots>()({\n  name: 'VColorInput',\n\n  props: makeVColorInputProps(),\n\n  emits: {\n    'update:modelValue': (val: string) => true,\n  },\n\n  setup (props, { slots }) {\n    const model = useProxiedModel(props, 'modelValue')\n    const menu = shallowRef(false)\n    const isFocused = shallowRef(props.focused)\n\n    const isInteractive = computed(() => !props.disabled && !props.readonly)\n\n    const display = computed(() => model.value || null)\n\n    function onKeydown (e: KeyboardEvent) {\n      if (e.key !== 'Enter') return\n\n      if (!menu.value || !isFocused.value) {\n        menu.value = true\n\n        return\n      }\n\n      const target = e.target as HTMLInputElement\n\n      model.value = target.value\n    }\n\n    function onClick (e: MouseEvent) {\n      e.preventDefault()\n      e.stopPropagation()\n\n      menu.value = true\n    }\n\n    function onSave () {\n      menu.value = false\n    }\n\n    function onCancel () {\n      menu.value = false\n    }\n\n    useRender(() => {\n      const confirmEditProps = VConfirmEdit.filterProps(props)\n      const colorPickerProps = {\n        ...VColorPicker.filterProps(omit(props, [\n          'active',\n          'bgColor',\n          'color',\n          'rounded',\n          'maxWidth',\n          'minWidth',\n          'width',\n        ])),\n        ...props.pickerProps,\n      }\n      const textFieldProps = VTextField.filterProps(props)\n\n      const slotWithPip = props.hidePip\n        ? undefined\n        : {\n          [props.pipLocation]: (arg: any) => (\n            <>\n              <VAvatar\n                class=\"v-color-input__pip\"\n                color={ props.colorPip ? model.value as string : undefined }\n                variant={ props.pipVariant }\n                icon={ props.pipIcon }\n              />\n              { slots[props.pipLocation]?.(arg) }\n            </>\n          ),\n        }\n\n      return (\n        <VTextField\n          { ...textFieldProps }\n          class={[\n            'v-color-input',\n            props.class,\n          ]}\n          style={ props.style }\n          modelValue={ display.value }\n          onKeydown={ isInteractive.value ? onKeydown : undefined }\n          focused={ menu.value || isFocused.value }\n          onClick:control={ !props.disabled ? onClick : undefined }\n          onClick:prependInner={ !props.disabled ? onClick : undefined }\n          onUpdate:focused={ event => isFocused.value = event }\n          onClick:appendInner={ !props.disabled ? onClick : undefined }\n          onUpdate:modelValue={ val => {\n            model.value = val\n          }}\n        >\n          {{\n            ...slots,\n            ...slotWithPip,\n            default: () => (\n              <>\n                <VMenu\n                  v-model={ menu.value }\n                  activator=\"parent\"\n                  minWidth=\"0\"\n                  closeOnContentClick={ false }\n                  openOnClick={ false }\n                  { ...props.menuProps }\n                >\n                  <VConfirmEdit\n                    { ...confirmEditProps }\n                    v-model={ model.value }\n                    onSave={ onSave }\n                    onCancel={ onCancel }\n                  >\n                    {{\n                      default: ({ actions, model: proxyModel, save, cancel, isPristine }) => {\n                        function onUpdateModel (value: string) {\n                          if (!props.hideActions) {\n                            proxyModel.value = value\n                          } else {\n                            model.value = value\n                          }\n                        }\n\n                        return (\n                          <VColorPicker\n                            { ...colorPickerProps }\n                            modelValue={ props.hideActions ? model.value : proxyModel.value }\n                            onUpdate:modelValue={ value => onUpdateModel(value) }\n                          >\n                            {{\n                              actions: !props.hideActions ? () => slots.actions?.({ save, cancel, isPristine }) ?? actions() : undefined,\n                            }}\n                          </VColorPicker>\n                        )\n                      },\n                    }}\n                  </VConfirmEdit>\n                </VMenu>\n\n                { slots.default?.() }\n              </>\n            ),\n          }}\n        </VTextField>\n      )\n    })\n  },\n})\n\nexport type VColorInput = InstanceType<typeof VColorInput>\n"
  },
  {
    "path": "packages/vuetify/src/labs/VColorInput/__tests__/VColorInput.spec.browser.tsx",
    "content": "// Components\nimport { VColorInput } from '../VColorInput'\n\n// Utilities\nimport { render, userEvent } from '@test'\n\ndescribe('VColorInput', () => {\n  it('should not fire @update:focus twice when clicking bottom of input', async () => {\n    const onFocus = vi.fn()\n    const { element } = render(() => (\n      <VColorInput onUpdate:focused={ onFocus } />\n    ))\n\n    await userEvent.click(element, { position: { x: 92, y: 55 } })\n\n    expect(onFocus).toHaveBeenCalledTimes(1)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/labs/VColorInput/_variables.scss",
    "content": "@use '../../styles/tools';\n\n// Defaults\n$color-input-pip-default-color: tools.theme-color('on-surface', var(--v-medium-emphasis-opacity)) !default;\n$color-input-pip-avatar-size: 40px !default;\n$color-input-pip-density: ('default': 0, 'comfortable': -2, 'compact': -3) !default;\n"
  },
  {
    "path": "packages/vuetify/src/labs/VColorInput/index.ts",
    "content": "export { VColorInput } from './VColorInput'\n"
  },
  {
    "path": "packages/vuetify/src/labs/VCommandPalette/VCommandPalette.scss",
    "content": "@use '../../styles/tools';\n@use './variables' as *;\n\n@include tools.layer('components') {\n  .v-command-palette {\n    > .v-overlay__content > .v-sheet {\n      display: flex;\n      flex: 1 1 100%;\n      flex-direction: column;\n    }\n\n    @at-root {\n      @include tools.density('v-command-palette', $command-palette-density) using ($modifier) {\n        .v-command-palette__input-container {\n          padding-block: $command-palette-input-padding-block + $modifier;\n          padding-inline: $command-palette-input-padding-inline + $modifier;\n        }\n      }\n    }\n\n    &__content {\n      overflow-y: auto;\n    }\n\n    &__no-data {\n      opacity: $command-palette-no-data-opacity;\n      padding: $command-palette-no-data-padding;\n      text-align: center;\n    }\n\n    &__list {\n      .v-list-subheader {\n        opacity: $command-palette-subheader-opacity;\n        user-select: none;\n      }\n\n      .v-divider {\n        margin-block: $command-palette-divider-margin;\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/labs/VCommandPalette/VCommandPalette.tsx",
    "content": "// Styles\nimport './VCommandPalette.scss'\n\n// Components\nimport { VCommandPaletteSymbol } from './shared'\nimport { VCommandPaletteItem } from './VCommandPaletteItem'\nimport { VDialog } from '@/components/VDialog'\nimport { makeVDialogProps } from '@/components/VDialog/VDialog'\nimport { VList } from '@/components/VList'\nimport { VSheet } from '@/components/VSheet'\nimport { VTextField } from '@/components/VTextField'\n\n// Composables\nimport { useCommandPaletteNavigation } from './composables/useCommandPaletteNavigation'\nimport { makeDensityProps } from '@/composables/density'\nimport { makeFilterProps, useFilter } from '@/composables/filter'\nimport { useHotkey } from '@/composables/hotkey'\nimport { useLocale } from '@/composables/locale'\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { computed, nextTick, onUnmounted, provide, ref, shallowRef, toRef, watch, watchEffect } from 'vue'\nimport { isActionItem } from './types'\nimport { genericComponent, omit, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType, Ref } from 'vue'\nimport type { VCommandPaletteItem as VCommandPaletteItemType } from './types'\nimport type { VListChildrenSlots } from '@/components/VList/VListChildren'\nimport type { OverlaySlots } from '@/components/VOverlay/VOverlay'\n\nexport const makeVCommandPaletteProps = propsFactory({\n  modelValue: Boolean,\n  search: String,\n  items: {\n    type: Array as PropType<VCommandPaletteItemType[]>,\n    default: () => [],\n  },\n  placeholder: {\n    type: String,\n    default: '$vuetify.command.search',\n  },\n  inputIcon: {\n    type: String,\n    default: '$search',\n  },\n  hotkey: String,\n  closeOnSelect: {\n    type: Boolean,\n    default: true,\n  },\n  noDataText: {\n    type: String,\n    default: '$vuetify.noDataText',\n  },\n  listProps: Object as PropType<VList['$props']>,\n\n  ...makeFilterProps({ filterKeys: ['title', 'subtitle'] }),\n  ...makeDensityProps(),\n  ...omit(makeVDialogProps({ maxWidth: 500 }), ['modelValue']),\n}, 'VCommandPalette')\n\nexport type VCommandPaletteSlots = {\n  activator: OverlaySlots['activator']\n  default: never\n  prepend: never\n  append: never\n  input: never\n  'input.append-inner': never\n  'no-data': never\n  'list.prepend': never\n  'list.subheader': VListChildrenSlots<any>['subheader']\n  item: { item: VCommandPaletteItemType, index: number }\n  'item.prepend': { item: VCommandPaletteItemType, index: number }\n  'item.title': { item: VCommandPaletteItemType, index: number }\n  'item.append': { item: VCommandPaletteItemType, index: number }\n}\n\nexport const VCommandPalette = genericComponent<VCommandPaletteSlots>()({\n  name: 'VCommandPalette',\n\n  props: makeVCommandPaletteProps(),\n\n  emits: {\n    'update:modelValue': (value: boolean) => true,\n    'update:search': (value: string) => true,\n    'click:item': (item: VCommandPaletteItemType, event: MouseEvent | KeyboardEvent) => true,\n    'before-select': (payload: {\n      item: VCommandPaletteItemType\n      event: MouseEvent | KeyboardEvent\n      preventDefault: () => void\n    }) => true,\n  },\n\n  setup (props, { emit, slots }) {\n    const { t } = useLocale()\n    const isOpen = useProxiedModel(props, 'modelValue')\n    const searchQuery = useProxiedModel(props, 'search') as Ref<string>\n    const searchInputRef = ref<VTextField>()\n    const dialogRef = ref<VDialog>()\n    const previouslyFocusedElement = shallowRef<HTMLElement | null>(null)\n\n    const internalItems = computed(() =>\n      props.items.map((item, index) => ({\n        value: index,\n        type: item.type,\n        raw: item,\n        ...('title' in item && { title: item.title }),\n        ...('subtitle' in item && { subtitle: item.subtitle }),\n      }))\n    )\n\n    const { filteredItems: filterResult } = useFilter(props, internalItems, searchQuery)\n\n    const filteredItems = computed(() => filterResult.value.map(item => item.raw))\n\n    const itemsForList = computed(() => {\n      return filteredItems.value.map((item, idx) => ({\n        ...item,\n        value: idx,\n      }))\n    })\n\n    function executeItem (item: VCommandPaletteItemType, event: MouseEvent | KeyboardEvent) {\n      if ('onClick' in item && item.onClick) {\n        item.onClick(event, item.value)\n      }\n\n      emit('click:item', item, event)\n\n      if (!isActionItem(item) || !props.closeOnSelect) return\n\n      let shouldClose = true\n      emit('before-select', {\n        item,\n        event,\n        preventDefault: () => {\n          shouldClose = false\n        },\n      })\n\n      if (shouldClose) {\n        isOpen.value = false\n      }\n    }\n\n    const navigation = useCommandPaletteNavigation({\n      filteredItems,\n      onItemClick: (item, event) => {\n        executeItem(item, event)\n      },\n    })\n\n    provide(VCommandPaletteSymbol, {\n      items: computed(() => props.items),\n      filteredItems,\n      selectedIndex: navigation.selectedIndex,\n      search: searchQuery,\n      setSelectedIndex: navigation.setSelectedIndex,\n    })\n\n    // Register main hotkey with cleanup - using toRef for reactivity\n    const hotkeyUnsubscribe = useHotkey(toRef(props, 'hotkey'), () => {\n      isOpen.value = !isOpen.value\n    })\n\n    watchEffect(onCleanup => {\n      if (!isOpen.value) {\n        return\n      }\n\n      const hotkeyUnsubscribes: Array<() => void> = []\n\n      function registerItemHotkeys (items: VCommandPaletteItemType[]) {\n        items.forEach(item => {\n          if (isActionItem(item) && item.hotkey) {\n            const unsubscribe = useHotkey(item.hotkey, event => {\n              event.preventDefault()\n              executeItem(item, event as KeyboardEvent)\n            }, { inputs: true })\n            hotkeyUnsubscribes.push(unsubscribe)\n          }\n        })\n      }\n\n      registerItemHotkeys(props.items)\n\n      onCleanup(() => {\n        hotkeyUnsubscribes.forEach(unsubscribe => unsubscribe?.())\n      })\n    })\n\n    function findNextSelectableIndex (startIndex: number, direction: 1 | -1): number {\n      const items = filteredItems.value\n      if (items.length === 0) return -1\n\n      let index = startIndex\n      const maxIterations = items.length\n\n      for (let i = 0; i < maxIterations; i++) {\n        index += direction\n        if (index >= items.length) index = 0\n        if (index < 0) index = items.length - 1\n\n        if (isActionItem(items[index])) {\n          return index\n        }\n      }\n\n      return -1\n    }\n\n    function handleSearchKeydown (e: KeyboardEvent) {\n      switch (e.key) {\n        case 'ArrowDown': {\n          e.preventDefault()\n          const nextIndex = findNextSelectableIndex(navigation.selectedIndex.value, 1)\n          if (nextIndex !== -1) {\n            navigation.setSelectedIndex(nextIndex)\n          }\n          break\n        }\n        case 'ArrowUp': {\n          e.preventDefault()\n          const prevIndex = findNextSelectableIndex(navigation.selectedIndex.value, -1)\n          if (prevIndex !== -1) {\n            navigation.setSelectedIndex(prevIndex)\n          }\n          break\n        }\n        case 'Enter':\n          e.preventDefault()\n          navigation.executeSelected(e)\n          break\n        case 'Escape':\n          e.preventDefault()\n          isOpen.value = false\n          break\n      }\n    }\n\n    watch(isOpen, (newValue, oldValue) => {\n      if (newValue && !oldValue) {\n        previouslyFocusedElement.value = document.activeElement as HTMLElement | null\n        searchQuery.value = ''\n        navigation.reset()\n\n        // Use requestAnimationFrame to ensure DOM is fully rendered\n        nextTick(() => {\n          requestAnimationFrame(() => {\n            if (searchInputRef.value && typeof searchInputRef.value.focus === 'function') {\n              searchInputRef.value.focus()\n            }\n          })\n        })\n      } else if (!newValue && oldValue) {\n        nextTick(() => {\n          previouslyFocusedElement.value?.focus({ preventScroll: true })\n          previouslyFocusedElement.value = null\n        })\n      }\n    }, { immediate: true })\n\n    onUnmounted(() => {\n      hotkeyUnsubscribe()\n      previouslyFocusedElement.value = null\n    })\n\n    useRender(() => {\n      const dialogProps = VDialog.filterProps(omit(props, ['modelValue', 'class', 'style']))\n\n      return (\n        <VDialog\n          ref={ dialogRef }\n          class=\"v-command-palette\"\n          v-model={ isOpen.value }\n          scrollable\n          { ...dialogProps }\n        >\n          {{\n            activator: slots.activator,\n            default: () => (\n              <VSheet\n                class={ props.class }\n                style={ props.style }\n              >\n                { slots.prepend?.() }\n\n              <div class=\"v-command-palette__input-container\">\n                { slots.input?.() ?? (\n                  <VTextField\n                    ref={ searchInputRef }\n                    v-model={ searchQuery.value }\n                    density={ props.density }\n                    placeholder={ t(props.placeholder) }\n                    prependInnerIcon={ props.inputIcon }\n                    autocomplete=\"off\"\n                    autofocus\n                    singleLine\n                    hideDetails\n                    variant=\"solo\"\n                    flat\n                    bgColor=\"transparent\"\n                    onKeydown={ handleSearchKeydown }\n                    v-slots={{\n                      'append-inner': slots['input.append-inner'],\n                    }}\n                  />\n                )}\n              </div>\n\n                <div class=\"v-command-palette__content\">\n                  { filteredItems.value.length > 0 ? (\n                    <VList\n                      key=\"list\"\n                      class=\"v-command-palette__list\"\n                      density={ props.density }\n                      items={ itemsForList.value }\n                      itemType=\"type\"\n                      itemProps\n                      activatable\n                      { ...props.listProps }\n                      navigationStrategy=\"track\"\n                      navigationIndex={ navigation.selectedIndex.value }\n                      onUpdate:navigationIndex={ navigation.setSelectedIndex }\n                      v-slots={{\n                        prepend: slots['list.prepend'],\n                        subheader: slots['list.subheader'],\n                        item: ({ props: itemProps }: { props: any }) => (\n                          slots.item?.({ item: itemProps, index: itemProps.index }) ?? (\n                            <VCommandPaletteItem\n                              key={ `item-${itemProps.index}` }\n                              item={ itemProps }\n                              index={ itemProps.index }\n                              onExecute={ (event: MouseEvent | KeyboardEvent) => navigation.execute(itemProps.index, event) }\n                              v-slots={{\n                                prepend: slots['item.prepend']\n                                  ? () => slots['item.prepend']?.({ item: itemProps, index: itemProps.index })\n                                  : undefined,\n                                title: slots['item.title']\n                                  ? () => slots['item.title']?.({ item: itemProps, index: itemProps.index })\n                                  : undefined,\n                                append: slots['item.append']\n                                  ? () => slots['item.append']?.({ item: itemProps, index: itemProps.index })\n                                  : undefined,\n                              }}\n                            />\n                          )\n                        ),\n                      }}\n                    />\n                  ) : (\n                    <div key=\"no-data\" class=\"v-command-palette__no-data\">\n                      { slots['no-data']?.() || t(props.noDataText) }\n                    </div>\n                  )}\n                </div>\n\n                { slots.append?.() }\n              </VSheet>\n            ),\n          }}\n        </VDialog>\n      )\n    })\n  },\n})\n\nexport type VCommandPalette = InstanceType<typeof VCommandPalette>\n"
  },
  {
    "path": "packages/vuetify/src/labs/VCommandPalette/VCommandPaletteItem.tsx",
    "content": "// Components\nimport { VHotkey } from '@/components/VHotkey'\nimport { VListItem } from '@/components/VList'\n\n// Utilities\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { VCommandPaletteActionItem } from './types'\n\nexport const makeVCommandPaletteItemProps = propsFactory({\n  item: {\n    type: Object as PropType<VCommandPaletteActionItem>,\n    required: true,\n  },\n  index: {\n    type: Number,\n    required: true,\n  },\n  onExecute: Function as PropType<(event: MouseEvent | KeyboardEvent) => void>,\n}, 'VCommandPaletteItem')\n\nexport type VCommandPaletteItemSlots = {\n  prepend: never\n  title: never\n  append: never\n}\n\nexport const VCommandPaletteItem = genericComponent<VCommandPaletteItemSlots>()({\n  name: 'VCommandPaletteItem',\n\n  props: makeVCommandPaletteItemProps(),\n\n  setup (props, { slots }) {\n    useRender(() => (\n      <VListItem\n        index={ props.index }\n        value={ props.item.value }\n        title={ props.item.title }\n        subtitle={ props.item.subtitle }\n        prependIcon={ props.item.prependIcon }\n        prependAvatar={ props.item.prependAvatar }\n        appendIcon={ props.item.appendIcon }\n        appendAvatar={ props.item.appendAvatar }\n        onClick={ props.onExecute }\n        v-slots={{\n          prepend: slots.prepend,\n          title: slots.title,\n          append: slots.append ?? (props.item.hotkey ? () => <VHotkey keys={ props.item.hotkey } /> : undefined),\n        }}\n      />\n    ))\n  },\n})\n\nexport type VCommandPaletteItem = InstanceType<typeof VCommandPaletteItem>\n"
  },
  {
    "path": "packages/vuetify/src/labs/VCommandPalette/__tests__/VCommandPalette.spec.browser.tsx",
    "content": "// Components\nimport { VCommandPalette } from '../VCommandPalette'\n\n// Utilities\nimport { render, screen, userEvent, wait } from '@test'\nimport { ref } from 'vue'\n\n// Test data\nconst testItems = [\n  {\n    title: 'File',\n    subtitle: 'Create new file',\n    value: 'file',\n  },\n  {\n    title: 'Folder',\n    subtitle: 'Create new folder',\n    value: 'folder',\n  },\n  {\n    title: 'Project',\n    subtitle: 'Create new project',\n    value: 'project',\n  },\n  {\n    type: 'divider' as const,\n  },\n  {\n    type: 'subheader' as const,\n    title: 'Recent',\n  },\n  {\n    title: 'Open File',\n    subtitle: 'Recently opened file',\n    value: 'open-file',\n  },\n]\n\ndescribe('VCommandPalette', () => {\n  afterEach(() => {\n    const overlays = document.querySelectorAll('.v-overlay')\n    overlays.forEach(overlay => overlay.remove())\n  })\n\n  describe('Rendering', () => {\n    it('should render dialog closed by default', () => {\n      render(() => <VCommandPalette items={ testItems } />)\n      expect(document.querySelector('[role=\"dialog\"]')).not.toBeInTheDocument()\n    })\n\n    it('should render dialog when modelValue is true', async () => {\n      const model = ref(true)\n      render(() => (\n        <VCommandPalette v-model={ model.value } items={ testItems } />\n      ))\n\n      await screen.findByRole('dialog')\n      expect(screen.getByRole('dialog')).toBeInTheDocument()\n    })\n\n    it('should render items with titles, subtitles, subheaders, and dividers', async () => {\n      const model = ref(true)\n      render(() => (\n        <VCommandPalette v-model={ model.value } items={ testItems } />\n      ))\n\n      await screen.findByRole('dialog')\n\n      // Action items\n      expect(screen.getByText('File')).toBeInTheDocument()\n      expect(screen.getByText('Create new file')).toBeInTheDocument()\n\n      // Subheader\n      expect(screen.getByText('Recent')).toBeInTheDocument()\n\n      // Divider\n      expect(document.querySelectorAll('.v-divider').length).toBeGreaterThan(0)\n    })\n\n    it('should show no-data message when no items match search', async () => {\n      const model = ref(true)\n      render(() => (\n        <VCommandPalette v-model={ model.value } items={ testItems } />\n      ))\n\n      await screen.findByRole('dialog')\n      const input = screen.getByRole('textbox')\n\n      await userEvent.type(input, 'nonexistent')\n      await wait(50)\n\n      expect(screen.getByText('No data available')).toBeInTheDocument()\n    })\n  })\n\n  describe('Search & Filtering', () => {\n    it('should filter items by title (case insensitive)', async () => {\n      const model = ref(true)\n      render(() => (\n        <VCommandPalette v-model={ model.value } items={ testItems } />\n      ))\n\n      await screen.findByRole('dialog')\n      const input = screen.getByRole('textbox')\n\n      await userEvent.type(input, 'FILE')\n      await wait(50)\n\n      expect(screen.getByText('File')).toBeInTheDocument()\n      expect(screen.getByText('Open File')).toBeInTheDocument()\n      expect(screen.queryByText('Folder')).not.toBeInTheDocument()\n    })\n\n    it('should clear search when dialog closes and reopens', async () => {\n      const model = ref(true)\n      render(() => (\n        <VCommandPalette v-model={ model.value } items={ testItems } />\n      ))\n\n      await screen.findByRole('dialog')\n      const input = screen.getByRole('textbox') as HTMLInputElement\n\n      await userEvent.type(input, 'test')\n      await wait(50)\n      expect(input.value).toBe('test')\n\n      // Close and reopen\n      model.value = false\n      await wait(50)\n      model.value = true\n      await screen.findByRole('dialog')\n\n      const newInput = screen.getByRole('textbox') as HTMLInputElement\n      expect(newInput.value).toBe('')\n    })\n  })\n\n  describe('Keyboard Navigation', () => {\n    it('should navigate with arrow keys and skip dividers/subheaders', async () => {\n      const model = ref(true)\n      render(() => (\n        <VCommandPalette v-model={ model.value } items={ testItems } />\n      ))\n\n      await screen.findByRole('dialog')\n      await wait(100)\n      const listbox = screen.getByRole('listbox')\n\n      // Items: File(0), Folder(1), Project(2), Divider(3), Subheader(4), Open File(5)\n      // Selectable: 0, 1, 2, 5\n\n      // Start at first item\n      expect(listbox.getAttribute('aria-activedescendant')).toMatch(/^v-list-item-.*-0$/)\n\n      // Navigate through items\n      await userEvent.keyboard('{ArrowDown}')\n      await wait(50)\n      expect(listbox.getAttribute('aria-activedescendant')).toMatch(/^v-list-item-.*-1$/)\n\n      await userEvent.keyboard('{ArrowDown}')\n      await wait(50)\n      expect(listbox.getAttribute('aria-activedescendant')).toMatch(/^v-list-item-.*-2$/)\n\n      // Should skip divider(3) and subheader(4), land on Open File(5)\n      await userEvent.keyboard('{ArrowDown}')\n      await wait(50)\n      expect(listbox.getAttribute('aria-activedescendant')).toMatch(/^v-list-item-.*-5$/)\n\n      // Should wrap to first item\n      await userEvent.keyboard('{ArrowDown}')\n      await wait(50)\n      expect(listbox.getAttribute('aria-activedescendant')).toMatch(/^v-list-item-.*-0$/)\n\n      // Arrow up should go back to last selectable\n      await userEvent.keyboard('{ArrowUp}')\n      await wait(50)\n      expect(listbox.getAttribute('aria-activedescendant')).toMatch(/^v-list-item-.*-5$/)\n    })\n\n    it('should keep focus in search input while navigating', async () => {\n      const model = ref(true)\n      render(() => (\n        <VCommandPalette v-model={ model.value } items={ testItems } />\n      ))\n\n      await screen.findByRole('dialog')\n      const input = screen.getByRole('textbox')\n\n      await userEvent.click(input)\n      expect(input).toHaveFocus()\n\n      await userEvent.keyboard('{ArrowDown}')\n      await wait(50)\n\n      expect(input).toHaveFocus()\n    })\n  })\n\n  describe('Item Execution', () => {\n    it('should execute item with Enter key and close dialog', async () => {\n      const model = ref(true)\n      const onClickItem = vi.fn()\n      render(() => (\n        <VCommandPalette\n          v-model={ model.value }\n          items={ testItems }\n          onClick:item={ onClickItem }\n        />\n      ))\n\n      await screen.findByRole('dialog')\n      await wait(100)\n\n      // Navigate to second item and execute\n      await userEvent.keyboard('{ArrowDown}')\n      await wait(50)\n      await userEvent.keyboard('{Enter}')\n      await wait(100)\n\n      expect(onClickItem).toHaveBeenCalledWith(\n        expect.objectContaining({ title: 'Folder', value: 'folder' }),\n        expect.any(KeyboardEvent)\n      )\n      expect(model.value).toBe(false)\n    })\n\n    it('should execute item with mouse click', async () => {\n      const model = ref(true)\n      const onClickItem = vi.fn()\n      render(() => (\n        <VCommandPalette\n          v-model={ model.value }\n          items={ testItems }\n          onClick:item={ onClickItem }\n        />\n      ))\n\n      await screen.findByRole('dialog')\n      await wait(100)\n\n      const folderItem = screen.getByText('Folder')\n      await userEvent.click(folderItem)\n      await wait(100)\n\n      expect(onClickItem).toHaveBeenCalledWith(\n        expect.objectContaining({ title: 'Folder', value: 'folder' }),\n        expect.any(MouseEvent)\n      )\n      expect(model.value).toBe(false)\n    })\n\n    it('should call item onClick handler when executed', async () => {\n      const handleClick = vi.fn()\n      const model = ref(true)\n      const itemsWithHandler = [\n        {\n          title: 'Action Item',\n          value: 'action',\n          onClick: handleClick,\n        },\n      ]\n\n      render(() => (\n        <VCommandPalette v-model={ model.value } items={ itemsWithHandler } />\n      ))\n\n      await screen.findByRole('dialog')\n      await wait(100)\n\n      await userEvent.keyboard('{Enter}')\n      await wait(100)\n\n      expect(handleClick).toHaveBeenCalled()\n    })\n\n    it('should keep palette open when closeOnSelect is false', async () => {\n      const model = ref(true)\n      const onClickItem = vi.fn()\n\n      render(() => (\n        <VCommandPalette\n          v-model={ model.value }\n          closeOnSelect={ false }\n          items={ testItems }\n          onClick:item={ onClickItem }\n        />\n      ))\n\n      await screen.findByRole('dialog')\n      await wait(100)\n\n      await userEvent.keyboard('{Enter}')\n      await wait(100)\n\n      expect(onClickItem).toHaveBeenCalledWith(\n        expect.objectContaining({ title: 'File', value: 'file' }),\n        expect.any(KeyboardEvent)\n      )\n      expect(model.value).toBe(true)\n      expect(screen.getByRole('dialog')).toBeInTheDocument()\n    })\n\n    it('should support drill-in by preventing close in before-select', async () => {\n      const model = ref(true)\n      const onClickItem = vi.fn()\n      const items = ref([\n        { title: 'Files', value: 'files' },\n        { title: 'Settings', value: 'settings' },\n      ])\n\n      render(() => (\n        <VCommandPalette\n          v-model={ model.value }\n          items={ items.value }\n          onClick:item={ onClickItem }\n          onBeforeSelect={ (payload: any) => {\n            const { item, preventDefault } = payload\n            if ('value' in item && item.value === 'files') {\n              preventDefault()\n              items.value = [\n                { title: 'New File', value: 'new-file' },\n                { title: 'Open File', value: 'open-file' },\n              ]\n            }\n          }}\n        />\n      ))\n\n      await screen.findByRole('dialog')\n      await wait(100)\n\n      await userEvent.keyboard('{Enter}')\n      await wait(100)\n\n      expect(model.value).toBe(true)\n      expect(screen.getByText('New File')).toBeInTheDocument()\n      expect(onClickItem).toHaveBeenCalledWith(\n        expect.objectContaining({ title: 'Files', value: 'files' }),\n        expect.any(KeyboardEvent)\n      )\n\n      await userEvent.keyboard('{Enter}')\n      await wait(100)\n\n      expect(onClickItem).toHaveBeenCalledWith(\n        expect.objectContaining({ title: 'New File', value: 'new-file' }),\n        expect.any(KeyboardEvent)\n      )\n      expect(model.value).toBe(false)\n    })\n  })\n\n  describe('Hotkeys', () => {\n    it('should open palette with global hotkey', async () => {\n      const model = ref(false)\n      render(() => (\n        <VCommandPalette\n          v-model={ model.value }\n          items={ testItems }\n          hotkey=\"ctrl+shift+p\"\n        />\n      ))\n\n      expect(document.querySelector('[role=\"dialog\"]')).not.toBeInTheDocument()\n\n      await userEvent.keyboard('{Control>}{Shift>}p{/Shift}{/Control}')\n      await wait(100)\n\n      expect(document.querySelector('[role=\"dialog\"]')).toBeInTheDocument()\n    })\n\n    it('should trigger item hotkey when palette is open', async () => {\n      const model = ref(true)\n      const handleClick = vi.fn()\n      const itemsWithHotkeys = [\n        {\n          title: 'Save File',\n          value: 'save',\n          hotkey: 'ctrl+s',\n          onClick: handleClick,\n        },\n      ]\n\n      render(() => (\n        <VCommandPalette v-model={ model.value } items={ itemsWithHotkeys } />\n      ))\n\n      await screen.findByRole('dialog')\n      await wait(100)\n\n      await userEvent.keyboard('{Control>}s{/Control}')\n      await wait(100)\n\n      expect(handleClick).toHaveBeenCalledWith(expect.any(KeyboardEvent), 'save')\n      expect(document.querySelector('[role=\"dialog\"]')).not.toBeInTheDocument()\n    })\n  })\n\n  describe('Slots', () => {\n    it('should render prepend, append, and no-data slots', async () => {\n      const model = ref(true)\n      const search = ref('')\n      render(() => (\n        <VCommandPalette\n          v-model={ model.value }\n          v-model:search={ search.value }\n          items={ testItems }\n          v-slots={{\n            prepend: () => <div data-testid=\"prepend-slot\">Prepend</div>,\n            append: () => <div data-testid=\"append-slot\">Append</div>,\n            'no-data': () => <div data-testid=\"no-data-slot\">No results</div>,\n          } as any}\n        />\n      ))\n\n      await screen.findByRole('dialog')\n      await wait(100)\n\n      expect(screen.getByTestId('prepend-slot')).toBeInTheDocument()\n      expect(screen.getByTestId('append-slot')).toBeInTheDocument()\n\n      // Type a search that yields no results to trigger no-data slot\n      const input = screen.getByRole('textbox')\n      await userEvent.type(input, 'nonexistent')\n      await wait(100)\n\n      expect(screen.getByTestId('no-data-slot')).toBeInTheDocument()\n    })\n  })\n\n  describe('Accessibility', () => {\n    it('should have proper ARIA attributes on listbox and options', async () => {\n      const model = ref(true)\n      render(() => (\n        <VCommandPalette v-model={ model.value } items={ testItems } />\n      ))\n\n      await screen.findByRole('dialog')\n      await wait(100)\n\n      const listbox = screen.getByRole('listbox')\n      expect(listbox).toHaveAttribute('aria-activedescendant')\n\n      const options = screen.getAllByRole('option')\n      expect(options).toHaveLength(4) // 4 action items, not divider/subheader\n      options.forEach(option => {\n        expect(option).toHaveAttribute('aria-selected')\n      })\n    })\n\n    it('should update aria-activedescendant when navigating', async () => {\n      const model = ref(true)\n      render(() => (\n        <VCommandPalette v-model={ model.value } items={ testItems } />\n      ))\n\n      await screen.findByRole('dialog')\n      await wait(100)\n\n      const listbox = screen.getByRole('listbox')\n      const options = screen.getAllByRole('option')\n\n      // Initially focused on first item\n      const firstItemId = options[0].id\n      expect(listbox.getAttribute('aria-activedescendant')).toBe(firstItemId)\n\n      // Navigate to second item\n      await userEvent.keyboard('{ArrowDown}')\n      await wait(100)\n\n      const secondItemId = options[1].id\n      expect(listbox.getAttribute('aria-activedescendant')).toBe(secondItemId)\n    })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/labs/VCommandPalette/_variables.scss",
    "content": "$command-palette-density: ('default': 0, 'comfortable': -1, 'compact': -2) !default;\n$command-palette-input-padding-block: 8px !default;\n$command-palette-input-padding-inline: 16px !default;\n$command-palette-no-data-padding: 16px !default;\n$command-palette-no-data-opacity: 0.6 !default;\n$command-palette-subheader-opacity: 0.7 !default;\n$command-palette-divider-margin: 4px !default;\n"
  },
  {
    "path": "packages/vuetify/src/labs/VCommandPalette/composables/useCommandPaletteNavigation.ts",
    "content": "// Utilities\nimport { readonly, ref, shallowRef, watch } from 'vue'\n\n// Types\nimport type { ComputedRef, Ref } from 'vue'\nimport type { VCommandPaletteItem } from '../types'\nimport { isActionItem } from '../types'\n\nexport interface UseCommandPaletteNavigationOptions {\n  filteredItems: ComputedRef<VCommandPaletteItem[]>\n  onItemClick: (item: VCommandPaletteItem, event: KeyboardEvent | MouseEvent) => void\n}\n\nexport interface UseCommandPaletteNavigationReturn {\n  selectedIndex: Readonly<Ref<number>>\n  getSelectedItem: () => VCommandPaletteItem | undefined\n  execute: (index: number, event: KeyboardEvent | MouseEvent) => void\n  executeSelected: (event: KeyboardEvent | MouseEvent) => void\n  reset: () => void\n  setSelectedIndex: (index: number) => void\n}\n\nfunction getItemKey (item: VCommandPaletteItem): string | undefined {\n  if (!isActionItem(item)) return undefined\n  return item.value !== undefined ? String(item.value) : item.title\n}\n\nfunction findFirstSelectableIndex (items: VCommandPaletteItem[]): number {\n  return items.findIndex(item => isActionItem(item))\n}\n\nexport function useCommandPaletteNavigation (\n  options: UseCommandPaletteNavigationOptions\n): UseCommandPaletteNavigationReturn {\n  const selectedIndex = ref(0)\n  const selectedItemKey = shallowRef<string | undefined>(undefined)\n\n  watch(() => options.filteredItems.value, (newItems, oldItems) => {\n    if (newItems.length === 0) {\n      selectedIndex.value = -1\n      selectedItemKey.value = undefined\n      return\n    }\n\n    if (selectedItemKey.value !== undefined) {\n      const newIndex = newItems.findIndex(item =>\n        isActionItem(item) && getItemKey(item) === selectedItemKey.value\n      )\n      if (newIndex !== -1) {\n        selectedIndex.value = newIndex\n        return\n      }\n    }\n\n    const firstSelectableIndex = findFirstSelectableIndex(newItems)\n    if (firstSelectableIndex !== -1) {\n      selectedIndex.value = firstSelectableIndex\n      selectedItemKey.value = getItemKey(newItems[firstSelectableIndex])\n      return\n    }\n\n    selectedIndex.value = 0\n    selectedItemKey.value = undefined\n  }, { immediate: true })\n\n  function getSelectedItem (): VCommandPaletteItem | undefined {\n    return options.filteredItems.value[selectedIndex.value]\n  }\n\n  function execute (index: number, event: KeyboardEvent | MouseEvent) {\n    const item = options.filteredItems.value[index]\n    if (item) {\n      options.onItemClick(item, event)\n    }\n  }\n\n  function executeSelected (event: KeyboardEvent | MouseEvent) {\n    const item = getSelectedItem()\n    if (item) {\n      options.onItemClick(item, event)\n    }\n  }\n\n  function reset () {\n    const items = options.filteredItems.value\n\n    if (items.length === 0) {\n      selectedIndex.value = -1\n      selectedItemKey.value = undefined\n      return\n    }\n\n    const firstSelectableIndex = findFirstSelectableIndex(items)\n    if (firstSelectableIndex !== -1) {\n      selectedIndex.value = firstSelectableIndex\n      selectedItemKey.value = getItemKey(items[firstSelectableIndex])\n      return\n    }\n\n    selectedIndex.value = 0\n    selectedItemKey.value = undefined\n  }\n\n  function setSelectedIndex (index: number) {\n    // Ignore VList's reset to -1 when we have items - we manage selection on filter changes\n    if (index === -1 && options.filteredItems.value.length > 0) {\n      return\n    }\n    selectedIndex.value = index\n    const item = options.filteredItems.value[index]\n    selectedItemKey.value = item ? getItemKey(item) : undefined\n  }\n\n  return {\n    selectedIndex: readonly(selectedIndex),\n    getSelectedItem,\n    execute,\n    executeSelected,\n    reset,\n    setSelectedIndex,\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/labs/VCommandPalette/index.ts",
    "content": "export { VCommandPalette } from './VCommandPalette'\nexport { VCommandPaletteItem } from './VCommandPaletteItem'\n"
  },
  {
    "path": "packages/vuetify/src/labs/VCommandPalette/shared.ts",
    "content": "// Utilities\nimport { inject } from 'vue'\n\n// Types\nimport type { InjectionKey, Ref } from 'vue'\nimport type { VCommandPaletteItem } from './types'\n\nexport interface CommandPaletteProvide {\n  items: Ref<VCommandPaletteItem[]>\n  filteredItems: Ref<VCommandPaletteItem[]>\n  selectedIndex: Ref<number>\n  search: Ref<string>\n  setSelectedIndex: (index: number) => void\n}\n\nexport const VCommandPaletteSymbol: InjectionKey<CommandPaletteProvide> = Symbol.for('vuetify:command-palette')\n\nexport function useCommandPalette () {\n  const commandPalette = inject(VCommandPaletteSymbol)\n\n  if (!commandPalette) {\n    throw new Error('[Vuetify] useCommandPalette must be used within VCommandPalette')\n  }\n\n  return commandPalette\n}\n"
  },
  {
    "path": "packages/vuetify/src/labs/VCommandPalette/types.ts",
    "content": "// Types\nimport type { RouteLocationRaw } from 'vue-router'\n\nexport interface BaseVListItem {\n  title?: string\n  subtitle?: string\n  prependIcon?: string\n  appendIcon?: string\n  prependAvatar?: string\n  appendAvatar?: string\n}\n\ninterface NavigableItemProps {\n  to?: RouteLocationRaw\n  href?: string\n}\n\nexport interface VCommandPaletteActionItem extends BaseVListItem, NavigableItemProps {\n  type?: 'item'\n  onClick?: (event: MouseEvent | KeyboardEvent, value?: any) => void\n  value?: any\n  hotkey?: string\n}\n\nexport interface VCommandPaletteSubheader {\n  type: 'subheader'\n  title: string\n  inset?: boolean\n}\n\nexport interface VCommandPaletteDivider {\n  type: 'divider'\n  inset?: boolean\n}\n\nexport type VCommandPaletteItem =\n  | VCommandPaletteActionItem\n  | VCommandPaletteSubheader\n  | VCommandPaletteDivider\n\nexport function isActionItem (item: any): item is VCommandPaletteActionItem {\n  return !item.type || item.type === 'item'\n}\n"
  },
  {
    "path": "packages/vuetify/src/labs/VDateInput/VDateInput.tsx",
    "content": "// Components\nimport { makeVConfirmEditProps, VConfirmEdit } from '@/components/VConfirmEdit/VConfirmEdit'\nimport { makeVDatePickerProps, VDatePicker } from '@/components/VDatePicker/VDatePicker'\nimport { useInputIcon } from '@/components/VInput/InputIcon'\nimport { VMenu } from '@/components/VMenu/VMenu'\nimport { makeVTextFieldProps, VTextField } from '@/components/VTextField/VTextField'\n\n// Composables\nimport { useCalendarRange } from '@/composables/calendar'\nimport { useDate } from '@/composables/date'\nimport { createDateRange } from '@/composables/date/date'\nimport { makeDateFormatProps, useDateFormat } from '@/composables/dateFormat'\nimport { makeDisplayProps, useDisplay } from '@/composables/display'\nimport { makeFocusProps } from '@/composables/focus'\nimport { forwardRefs } from '@/composables/forwardRefs'\nimport { useLocale } from '@/composables/locale'\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { computed, ref, shallowRef, watch } from 'vue'\nimport { genericComponent, omit, pick, propsFactory, useRender, wrapInArray } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { VDatePickerSlots } from '@/components/VDatePicker/VDatePicker'\nimport type { StrategyProps } from '@/components/VOverlay/locationStrategies'\nimport type { VTextFieldSlots } from '@/components/VTextField/VTextField'\nimport type { GenericProps } from '@/util'\n\n// Types\nexport type VDateInputActionsSlot = {\n  save: () => void\n  cancel: () => void\n  isPristine: boolean\n}\n\nexport type VDateInputSlots = Omit<VTextFieldSlots, 'default'> &\n  Pick<VDatePickerSlots, 'title' | 'header' | 'day' | 'month' | 'year'> & {\n    actions: VDateInputActionsSlot\n    default: never\n  }\n\nexport const makeVDateInputProps = propsFactory({\n  displayFormat: {\n    type: [Function, String] as PropType<string | ((date: unknown) => any)>,\n    default: undefined,\n  },\n  location: {\n    type: String as PropType<StrategyProps['location']>,\n    default: 'bottom start',\n  },\n  menu: Boolean,\n  menuProps: Object as PropType<VMenu['$props']>,\n  updateOn: {\n    type: Array as PropType<('blur' | 'enter')[]>,\n    default: () => ['blur', 'enter'],\n  },\n  pickerProps: Object as PropType<VDatePicker['$props']>,\n\n  ...makeDateFormatProps(),\n  ...makeDisplayProps({\n    mobile: null,\n  }),\n  ...makeFocusProps(),\n  ...makeVConfirmEditProps({\n    hideActions: true,\n  }),\n  ...makeVTextFieldProps({\n    prependIcon: '$calendar',\n  }),\n  ...omit(makeVDatePickerProps({\n    hideHeader: true,\n    showAdjacentMonths: true,\n  }), [\n    'location',\n    'rounded',\n    'height',\n    'minHeight',\n    'maxHeight',\n  ]),\n}, 'VDateInput')\n\nexport const VDateInput = genericComponent<new <\n  T,\n  Multiple extends boolean | 'range' | number | (string & {}) = false,\n  TModel = Multiple extends true | number | string\n    ? T[]\n    : T,\n> (\n  props: {\n    modelValue?: TModel\n    onSave?: (value: TModel) => void\n    'onUpdate:modelValue'?: (value: TModel) => void\n    multiple?: Multiple\n  },\n  slots: VDateInputSlots\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VDateInput',\n\n  props: makeVDateInputProps(),\n\n  emits: {\n    save: (value: unknown) => true,\n    cancel: () => true,\n    'update:focused': (val: boolean) => true,\n    'update:modelValue': (val: unknown) => true,\n    'update:menu': (val: boolean) => true,\n  },\n\n  setup (props, { emit, slots }) {\n    const { t, current: currentLocale } = useLocale()\n    const adapter = useDate()\n    const { isValid, parseDate, formatDate, parserFormat } = useDateFormat(props, currentLocale)\n    const { mobile } = useDisplay(props)\n    const { InputIcon } = useInputIcon(props)\n\n    const { clampDate, isInAllowedRange } = useCalendarRange(props)\n\n    const emptyModelValue = () => props.multiple ? [] : null\n\n    const model = useProxiedModel(\n      props,\n      'modelValue',\n      emptyModelValue(),\n      val => Array.isArray(val) ? val.map(item => adapter.toJsDate(item)) : val ? adapter.toJsDate(val) : val,\n      val => Array.isArray(val) ? val.map(item => adapter.date(item)) : val ? adapter.date(val) : val\n    )\n\n    const menu = useProxiedModel(props, 'menu')\n    const isEditingInput = shallowRef(false)\n    const isFocused = shallowRef(props.focused)\n    const vTextFieldRef = ref<VTextField>()\n    const disabledActions = ref<typeof VConfirmEdit['props']['disabled']>(['save'])\n\n    function format (date: unknown) {\n      if (typeof props.displayFormat === 'function') {\n        return props.displayFormat(date)\n      }\n      if (props.displayFormat) {\n        return adapter.format(date, props.displayFormat ?? 'keyboardDate')\n      }\n      return formatDate(date)\n    }\n\n    const display = computed(() => {\n      const value = wrapInArray(model.value)\n\n      if (!value.length) return null\n\n      if (props.multiple === true) {\n        return t('$vuetify.datePicker.itemsSelected', value.length)\n      }\n\n      if (props.multiple === 'range') {\n        const start = value[0]\n        const end = value[value.length - 1]\n\n        if (!adapter.isValid(start) || !adapter.isValid(end)) return ''\n\n        return `${format(adapter.date(start))} - ${format(adapter.date(end))}`\n      }\n\n      return adapter.isValid(model.value) ? format(adapter.date(model.value)) : ''\n    })\n\n    const inputmode = computed(() => {\n      if (!mobile.value) return undefined\n      if (isEditingInput.value) return 'text'\n\n      return 'none'\n    })\n\n    const isInteractive = computed(() => !props.disabled && !props.readonly)\n\n    const isReadonly = computed(() => {\n      if (!props.updateOn.length) return true\n\n      return !(mobile.value && isEditingInput.value) && props.readonly\n    })\n\n    watch(menu, val => {\n      if (val) return\n\n      isEditingInput.value = false\n      disabledActions.value = ['save']\n    })\n\n    function onKeydown (e: KeyboardEvent) {\n      if (e.key !== 'Enter') return\n\n      if (!menu.value || !isFocused.value) {\n        menu.value = true\n      }\n\n      if (props.updateOn.includes('enter') && !props.readonly) {\n        onUserInput(e.target as HTMLInputElement)\n      }\n    }\n\n    function onClick (e: MouseEvent) {\n      if (props.disabled) return\n\n      e.preventDefault()\n      e.stopPropagation()\n\n      if (menu.value && mobile.value) {\n        isEditingInput.value = !props.readonly\n      } else {\n        menu.value = true\n      }\n    }\n\n    function onCancel () {\n      emit('cancel')\n      menu.value = false\n      isEditingInput.value = false\n    }\n\n    function onSave (value: string) {\n      emit('save', value)\n      menu.value = false\n    }\n\n    function onUpdateDisplayModel (value: unknown) {\n      if (value != null) return\n\n      model.value = emptyModelValue()\n    }\n\n    function onBlur (e: FocusEvent) {\n      if (props.updateOn.includes('blur') && !props.readonly) {\n        onUserInput(e.target as HTMLInputElement)\n      }\n\n      // When in mobile mode and editing is done (due to keyboard dismissal), close the menu\n      if (mobile.value && isEditingInput.value && !isFocused.value) {\n        menu.value = false\n        isEditingInput.value = false\n      }\n    }\n\n    function onUserInput ({ value }: HTMLInputElement) {\n      if (!value.trim()) {\n        model.value = emptyModelValue()\n      } else if (!props.multiple) {\n        if (isValid(value)) {\n          model.value = clampDate(parseDate(value))\n        }\n      } else {\n        const parts = value.trim().split(/\\D+-\\D+|[^\\d\\-/.]+/)\n        if (parts.every(isValid)) {\n          if (props.multiple === 'range') {\n            const [start, stop] = parts\n              .map(parseDate)\n              .map(clampDate)\n              .toSorted((a, b) => adapter.isAfter(a, b) ? 1 : -1)\n            model.value = createDateRange(adapter, start, stop)\n          } else {\n            model.value = parts\n              .map(parseDate)\n              .filter(isInAllowedRange)\n          }\n        }\n      }\n    }\n\n    useRender(() => {\n      const hasPrepend = !!(props.prependIcon || slots.prepend)\n      const confirmEditProps = VConfirmEdit.filterProps(props)\n      const datePickerProps = {\n        ...VDatePicker.filterProps(omit(props, [\n          'active',\n          'bgColor',\n          'color',\n          'location',\n          'rounded',\n          'maxWidth',\n          'minWidth',\n          'width',\n        ])),\n        ...props.pickerProps,\n      }\n      const datePickerSlots = pick(slots, ['title', 'header', 'day', 'month', 'year'])\n      const textFieldProps = VTextField.filterProps(omit(props, ['placeholder']))\n\n      return (\n        <VTextField\n          ref={ vTextFieldRef }\n          { ...textFieldProps }\n          class={['v-date-input', props.class]}\n          style={ props.style }\n          modelValue={ display.value }\n          inputmode={ inputmode.value }\n          placeholder={ props.placeholder ?? parserFormat.value }\n          readonly={ isReadonly.value }\n          onKeydown={ isInteractive.value ? onKeydown : undefined }\n          focused={ menu.value || isFocused.value }\n          onBlur={ onBlur }\n          validationValue={ model.value }\n          onClick:control={ onClick }\n          onUpdate:modelValue={ onUpdateDisplayModel }\n          onUpdate:focused={ event => isFocused.value = event }\n        >\n          {{\n            ...slots,\n            default: () => (\n              <>\n                <VMenu\n                  v-model={ menu.value }\n                  activator=\"parent\"\n                  minWidth=\"0\"\n                  eager={ isFocused.value }\n                  location={ props.location }\n                  closeOnContentClick={ false }\n                  openOnClick={ false }\n                  { ...props.menuProps }\n                >\n                  <VConfirmEdit\n                    { ...confirmEditProps }\n                    v-model={ model.value }\n                    disabled={ disabledActions.value }\n                    onSave={ onSave }\n                    onCancel={ onCancel }\n                  >\n                    {{\n                      default: ({ actions, model: proxyModel, save, cancel, isPristine }) => {\n                        function onUpdateModel (value: string) {\n                          if (!props.hideActions) {\n                            proxyModel.value = value\n                          } else {\n                            model.value = value\n\n                            if (!props.multiple) {\n                              menu.value = false\n                            }\n                          }\n\n                          emit('save', value)\n\n                          disabledActions.value = []\n                        }\n\n                        return (\n                          <VDatePicker\n                            { ...datePickerProps }\n                            modelValue={ props.hideActions ? model.value : proxyModel.value }\n                            onUpdate:modelValue={ value => onUpdateModel(value) }\n                            onMousedown={ (e: MouseEvent) => e.preventDefault() }\n                          >\n                            {{\n                              ...datePickerSlots,\n                              actions: !props.hideActions ? () => slots.actions?.({ save, cancel, isPristine }) ?? actions() : undefined,\n                            }}\n                          </VDatePicker>\n                        )\n                      },\n                    }}\n                  </VConfirmEdit>\n                </VMenu>\n\n                { slots.default?.() }\n              </>\n            ),\n            prepend: hasPrepend ? prependSlotProps => (\n              slots.prepend\n                ? slots.prepend(prependSlotProps)\n                : (props.prependIcon && (\n                  <InputIcon\n                    key=\"prepend-icon\"\n                    name=\"prepend\"\n                    tabindex={ props['onClick:prepend'] ? undefined : -1 }\n                    onClick={ isInteractive.value ? onClick : undefined }\n                  />\n                ))\n            ) : undefined,\n          }}\n        </VTextField>\n      )\n    })\n\n    return forwardRefs({}, vTextFieldRef)\n  },\n})\n\nexport type VDateInput = InstanceType<typeof VDateInput>\n"
  },
  {
    "path": "packages/vuetify/src/labs/VDateInput/__tests__/VDateInput.spec.browser.tsx",
    "content": "// Components\nimport { VDateInput } from '../VDateInput'\n\n// Utilities\nimport { render, screen, userEvent } from '@test'\nimport { ref } from 'vue'\n\ndescribe('VDateInput', () => {\n  it('should not fire @update:focus twice when clicking bottom of input', async () => {\n    const onFocus = vi.fn()\n    const { element } = render(() => (\n      <VDateInput onUpdate:focused={ onFocus } />\n    ))\n\n    await userEvent.click(element, { position: { x: 92, y: 55 } })\n\n    expect(onFocus).toHaveBeenCalledTimes(1)\n  })\n\n  it('accepts keyboard input even if the picker is hidden', async () => {\n    const model = ref<Date | null>(null)\n    const { element } = render(() => <VDateInput v-model={ model.value } />)\n\n    await userEvent.click(element)\n    await expect.poll(() => screen.getByCSS('.v-picker')).toBeVisible()\n\n    await userEvent.keyboard('{Escape}') // hide picker, but keep the focus\n\n    await expect.poll(() => screen.getByCSS('.v-picker')).not.toBeVisible()\n\n    const input = screen.getByCSS('input')\n    await userEvent.type(input, '02/20/2022{Enter}')\n\n    expect(model.value).toBeDefined()\n    const formatter = new Intl.DateTimeFormat('en-US', { dateStyle: 'medium' })\n    expect(formatter.format(model.value!)).toBe('Feb 20, 2022')\n  })\n\n  describe('parseDateString', () => {\n    const testCases = [\n      {\n        format: 'YYYY-MM-DD',\n        input: '2024-03-15',\n        expected: { year: 2024, month: 2, day: 15 },\n      },\n      {\n        format: 'MM/DD/YYYY',\n        input: '03/15/2024',\n        expected: { year: 2024, month: 2, day: 15 },\n      },\n      {\n        format: 'DD-MM-YYYY',\n        input: '15-03-2024',\n        expected: { year: 2024, month: 2, day: 15 },\n      },\n      {\n        format: 'YYYY-MM-DD',\n        input: '2023-02-29',\n        expected: { year: 2023, month: 2, day: 1 },\n      },\n      {\n        format: 'YYYY-MM-DD',\n        input: '2024-02-29',\n        expected: { year: 2024, month: 1, day: 29 },\n      },\n      {\n        format: 'YYYY-MM-DD',\n        input: '2024-12-31',\n        expected: { year: 2024, month: 11, day: 31 },\n      },\n      {\n        format: 'YYYY-MM-DD',\n        input: '2024-01-01',\n        expected: { year: 2024, month: 0, day: 1 },\n      },\n    ]\n\n    testCases.forEach(({ format, input, expected }) => {\n      it(`should select date with ${format} format`, async () => {\n        const { element, emitted } = render(\n          <VDateInput\n            inputFormat={ format }\n            modelValue={ null }\n          />\n        )\n\n        await userEvent.click(element)\n        await userEvent.keyboard(input)\n        await userEvent.keyboard('{Enter}')\n\n        const date = emitted<Date[]>('update:modelValue')![0][0]\n        expect(date.getFullYear()).toBe(expected.year)\n        expect(date.getMonth()).toBe(expected.month)\n        expect(date.getDate()).toBe(expected.day)\n      })\n    })\n\n    const invalidTestCases = [\n      {\n        format: 'YYYY-MM-DD',\n        input: 'invalid-date',\n        description: 'invalid date string',\n      },\n      {\n        format: 'YYYY-MM-DD',\n        input: '2024-13-45',\n        description: 'out of range date',\n      },\n      {\n        format: 'YYYY-MM-DD',\n        input: '2024-00-01',\n        description: 'zero month',\n      },\n      {\n        format: 'YYYY-MM-DD',\n        input: '2024-01-00',\n        description: 'zero day',\n      },\n      {\n        format: 'YYYY-MM-DD',\n        input: '2024-12-32',\n        description: 'day exceeds 31',\n      },\n      {\n        format: 'YYYY-MM-DD',\n        input: '2024-13-01',\n        description: 'month exceeds year length',\n      },\n    ]\n\n    invalidTestCases.forEach(({ format, input, description }) => {\n      it(`should handle ${description}`, async () => {\n        const { element, emitted } = render(<VDateInput\n          inputFormat={ format }\n          modelValue={ null }\n        />)\n\n        await userEvent.click(element)\n        await userEvent.keyboard(input)\n        await userEvent.keyboard('{Enter}')\n\n        expect(emitted('update:modelValue')).toBeFalsy()\n      })\n    })\n\n    it(`should reset if empty string is inputted`, async () => {\n      const { emitted, getByRole } = render(\n        <VDateInput\n          modelValue={ new Date() }\n        />\n      )\n\n      const input = getByRole('textbox')\n      await userEvent.clear(input)\n      await userEvent.keyboard('{Enter}')\n\n      const date = emitted<Date[]>('update:modelValue')![0][0]\n      expect(date).toBeNull()\n    })\n  })\n\n  describe('update-on prop', () => {\n    const TEST_DATE = '05/21/2025'\n\n    it('should update modelValue only on enter key press', async () => {\n      const { element, emitted } = render(\n        <VDateInput\n          updateOn={['enter']}\n          modelValue={ null }\n        />\n      )\n\n      await userEvent.click(element)\n      await userEvent.keyboard(TEST_DATE)\n\n      await userEvent.keyboard('{Enter}')\n      expect(emitted('update:modelValue')).toBeTruthy()\n\n      await userEvent.tab()\n      expect(emitted('update:modelValue')).toHaveLength(1)\n    })\n\n    it('should update modelValue only on blur event', async () => {\n      const { element, emitted } = render(\n        <VDateInput\n          updateOn={['blur']}\n          modelValue={ null }\n        />\n      )\n\n      await userEvent.click(element)\n      await userEvent.keyboard(TEST_DATE)\n\n      await userEvent.keyboard('{Enter}')\n      expect(emitted('update:modelValue')).toBeFalsy()\n\n      await userEvent.tab()\n      expect(emitted('update:modelValue')).toBeTruthy()\n    })\n\n    it('should update modelValue on both enter key press and blur event', async () => {\n      const { element, emitted } = render(\n        <VDateInput\n          updateOn={['enter', 'blur']}\n          modelValue={ null }\n        />\n      )\n\n      await userEvent.click(element)\n      await userEvent.keyboard(TEST_DATE)\n\n      await userEvent.keyboard('{Enter}')\n      expect(emitted('update:modelValue')).toBeTruthy()\n\n      await userEvent.tab()\n      expect(emitted('update:modelValue')).toHaveLength(2)\n    })\n\n    it('should make the input readonly and prevent value updates', async () => {\n      const { element, emitted, getByRole } = render(\n        <VDateInput\n          updateOn={[]}\n          modelValue={ null }\n        />\n      )\n\n      const input = getByRole<HTMLInputElement>('textbox')\n      expect(input).toHaveAttribute('readonly')\n      expect(input.readOnly).toBe(true)\n\n      await userEvent.click(element)\n      await userEvent.keyboard(TEST_DATE)\n      await userEvent.keyboard('{Enter}')\n      await userEvent.tab()\n\n      expect(emitted('update:modelValue')).toBeFalsy()\n    })\n  })\n\n  describe('typing values', () => {\n    it.each([\n      { multiple: false, typing: '07/01/2022', expected: '07/01/2022' },\n      { multiple: false, typing: '4/15/26', expected: '04/15/2026' },\n      { multiple: 'range', typing: '07/01/2022', expected: '07/01/2022 - 07/01/2022' },\n      { multiple: 'range', typing: '4/15/26', expected: '04/15/2026 - 04/15/2026' },\n      { multiple: 'range', typing: '05/02/2025 - 05/14/2025', expected: '05/02/2025 - 05/14/2025' },\n      { multiple: true, typing: '07/01/2022', expected: '1 selected' },\n      { multiple: true, typing: '05/02/2025 05/14/2025', expected: '2 selected' },\n      { multiple: true, typing: '4/15/25 04/22/25 04/15/25', expected: '3 selected' },\n    ])('should accept pasted and typed values', async ({ multiple, typing, expected }) => {\n      const { element } = render(() => <VDateInput multiple={ multiple } />)\n      const input = screen.getByCSS('input')\n      await userEvent.click(element)\n      await userEvent.keyboard(typing)\n      await userEvent.click(document.body)\n      expect(input).toHaveValue(expected)\n    })\n\n    it.each([\n      { format: 'yyyy-mm-dd', multiple: false, typing: '2022-01-07', expected: '2022-01-07' },\n      { format: 'yyyy-mm-dd', multiple: false, typing: '26-4-15', expected: '2026-04-15' },\n      { format: 'yyyy-mm-dd', multiple: 'range', typing: '2022-01-07', expected: '2022-01-07 - 2022-01-07' },\n      { format: 'yyyy-mm-dd', multiple: 'range', typing: '26-4-15', expected: '2026-04-15 - 2026-04-15' },\n      { format: 'dd.mm.yyyy', multiple: 'range', typing: '01.05.2025 - 22.05.2025', expected: '01.05.2025 - 22.05.2025' },\n      { format: 'yyyy-mm-dd', multiple: true, typing: '2022-01-07', expected: '1 selected' },\n      { format: 'dd.mm.yyyy', multiple: true, typing: '01.05.2025 22.05.2025', expected: '2 selected' },\n      { format: 'dd.mm.yyyy', multiple: true, typing: ' 03.05.25 05.05.25  07.05.25 ', expected: '3 selected' },\n    ])('should accept pasted and typed values with custom format', async ({ format, multiple, typing, expected }) => {\n      const { element } = render(() => <VDateInput multiple={ multiple } inputFormat={ format } />)\n      const input = screen.getByCSS('input')\n      await userEvent.click(element)\n      await userEvent.keyboard(typing)\n      await userEvent.click(document.body)\n      expect(input).toHaveValue(expected)\n    })\n\n    it.each([\n      { multiple: false, initial: '05/16/2025', typing: '←←←←←×2', expected: '05/12/2025' },\n      { multiple: 'range', initial: '05/16/2025 - 05/24/2025', typing: '←←←←←××3', expected: '05/03/2025 - 05/16/2025' },\n    ])('should accept changes typed from keyboard', async ({ multiple, initial, typing, expected }) => {\n      const { element } = render(() => <VDateInput multiple={ multiple } />)\n      const input = screen.getByCSS('input')\n      await userEvent.click(element)\n      await userEvent.keyboard(`${initial}{Enter}`)\n      expect(input).toHaveValue(initial)\n      const typingSequence = typing\n        .replaceAll('←', '{ArrowLeft}')\n        .replaceAll('×', '{Backspace}')\n      await userEvent.keyboard(typingSequence)\n      await userEvent.click(document.body)\n      expect(input).toHaveValue(expected)\n    })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/labs/VDateInput/index.ts",
    "content": "export { VDateInput } from './VDateInput'\n"
  },
  {
    "path": "packages/vuetify/src/labs/VFileUpload/VFileUpload.sass",
    "content": "@use '../../styles/tools'\n@use '../../styles/settings'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-file-upload\n    .v-input__control\n      flex-direction: column\n\n  .v-file-upload-dropzone\n    padding: $file-upload-padding\n    flex-direction: column\n    justify-content: center\n    align-items: center\n    position: relative\n\n    &.v-sheet\n      display: flex\n      border-radius: 4px\n      border-style: dashed\n      border-width: 2px\n\n    &.v-file-upload-dropzone--density-compact\n      padding: 32px 0\n      flex-direction: row\n      gap: 1rem\n\n    .v-overlay__scrim\n      pointer-events: none\n\n    &--disabled\n      pointer-events: none\n      opacity: var(--v-disabled-opacity)\n\n    &--dragging\n      > *\n        pointer-events: none\n\n    &--clickable\n      cursor: pointer\n\n    &--has-files:not(&--clickable)\n      cursor: default\n\n    &--error.v-sheet\n      border-color: rgb(var(--v-theme-error))\n\n    &--inset\n      padding: 16px\n\n    input[type=\"file\"]\n      left: 0\n      opacity: 0\n      position: absolute\n      cursor: pointer\n      top: 0\n      z-index: -1\n\n  .v-file-upload-title\n    font-size: $file-upload-title-font-size\n    font-weight: 600\n    text-align: center\n\n  .v-file-upload-icon\n    opacity: var(--v-medium-emphasis-opacity)\n    font-size: $file-upload-icon-font-size\n    margin-bottom: $file-upload-icon-margin-bottom\n\n    .v-file-upload-dropzone--density-comfortable &\n      font-size: $file-upload-icon-font-size - .5rem\n      margin-bottom: $file-upload-icon-margin-bottom - .5rem\n\n    .v-file-upload-dropzone--density-compact &\n      font-size: $file-upload-icon-font-size - 1rem\n      margin-bottom: $file-upload-icon-margin-bottom - 1rem\n\n  .v-file-upload-divider\n    align-items: center\n    display: flex\n    margin: $file-upload-divider-margin\n    justify-content: center\n    width: 100%\n\n    .v-divider__wrapper\n      max-width: 100%\n\n  .v-file-upload-inset\n    width: 100%\n\n  .v-file-upload-inset__action\n    display: flex\n    justify-content: center\n    width: 100%\n    padding: $file-upload-inset-action-padding\n\n  .v-file-upload-list\n    margin: $file-upload-items-margin\n\n  .v-file-upload-item\n    &:not(:first-child)\n      margin-top: 8px\n"
  },
  {
    "path": "packages/vuetify/src/labs/VFileUpload/VFileUpload.tsx",
    "content": "// Styles\nimport './VFileUpload.sass'\n\n// Components\nimport { VFileUploadDropzone, VFileUploadKey } from './VFileUploadDropzone'\nimport { VFileUploadList } from './VFileUploadList'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider/VDefaultsProvider'\nimport { makeVInputProps, VInput } from '@/components/VInput/VInput'\n\n// Composables\nimport { makeFileFilterProps, useFileFilter } from '@/composables/fileFilter'\nimport { useFocus } from '@/composables/focus'\nimport { useForm } from '@/composables/form'\nimport { forwardRefs } from '@/composables/forwardRefs'\nimport { IconValue } from '@/composables/icons'\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { provide, ref, toRef, watch } from 'vue'\nimport { filterInputAttrs, genericComponent, omit, propsFactory, useRender, wrapInArray } from '@/util'\n\n// Types\nimport type { PropType, VNode } from 'vue'\nimport type { VInputSlots } from '@/components/VInput/VInput'\n\nexport type VFileUploadSlots = Omit<VInputSlots, 'default'> & {\n  browse: {\n    props: { onClick: (e: MouseEvent) => void }\n  }\n  default: never\n  icon: never\n  input: {\n    inputNode: VNode\n  }\n  item: {\n    file: File\n    props: { 'onClick:remove': () => void }\n  }\n  single: {\n    file: File\n    props: { 'onClick:remove': () => void }\n  }\n  title: never\n  divider: never\n}\n\nexport const makeVFileUploadProps = propsFactory({\n  browseText: {\n    type: String,\n    default: '$vuetify.fileUpload.browse',\n  },\n  dividerText: {\n    type: String,\n    default: '$vuetify.fileUpload.divider',\n  },\n  title: {\n    type: String,\n    default: '$vuetify.fileUpload.title',\n  },\n  subtitle: String,\n  icon: {\n    type: IconValue,\n    default: '$upload',\n  },\n  clearable: Boolean,\n  insetFileList: Boolean,\n  hideBrowse: Boolean,\n  multiple: Boolean,\n  scrim: {\n    type: [Boolean, String],\n    default: true,\n  },\n  showSize: Boolean,\n\n  ...makeFileFilterProps(),\n  ...omit(makeVInputProps(), ['direction']),\n\n  modelValue: {\n    type: [Array, Object] as PropType<File[] | File>,\n    default: null,\n    validator: (val: any) => {\n      return wrapInArray(val).every(v => v != null && typeof v === 'object')\n    },\n  },\n}, 'VFileUpload')\n\nexport const VFileUpload = genericComponent<VFileUploadSlots>()({\n  name: 'VFileUpload',\n\n  inheritAttrs: false,\n\n  props: makeVFileUploadProps(),\n\n  emits: {\n    'update:modelValue': (files: File[]) => true,\n    'update:focused': (focused: boolean) => true,\n    rejected: (files: File[]) => true,\n  },\n\n  setup (props, { attrs, emit, slots }) {\n    const { filterAccepted } = useFileFilter(props)\n    const { isFocused } = useFocus(props)\n    const form = useForm(props)\n    const model = useProxiedModel(\n      props,\n      'modelValue',\n      props.modelValue,\n      val => wrapInArray(val),\n      val => (props.multiple || Array.isArray(props.modelValue)) ? val : val[0],\n    )\n\n    const vInputRef = ref<VInput>()\n    const vDropzoneRef = ref<VFileUploadDropzone>()\n    const inputRef = ref<HTMLInputElement | null>(null)\n    const isError = toRef(() => vInputRef.value?.isValid === false)\n\n    provide(VFileUploadKey, {\n      files: model,\n      disabled: form.isDisabled,\n      error: isError,\n      onDrop,\n      onClickBrowse: onClick,\n      onClickRemove,\n    })\n\n    watch(model, newValue => {\n      const hasModelReset = !Array.isArray(newValue) || !newValue.length\n      if (hasModelReset && inputRef.value) {\n        inputRef.value.value = ''\n      }\n    })\n\n    function onDrop (files: File[]) {\n      selectAccepted(files)\n    }\n\n    function onFileSelection (e: Event) {\n      if (!e.target || (e as any).repack) return // prevent loop\n\n      if (!props.filterByType) {\n        const target = e.target as HTMLInputElement\n        const newFiles = [...target.files ?? []]\n        model.value = props.multiple ? [...model.value, ...newFiles] : newFiles\n      } else {\n        selectAccepted([...(e as any).target.files])\n      }\n    }\n\n    function selectAccepted (files: File[]) {\n      const dataTransfer = new DataTransfer()\n      const { accepted, rejected } = filterAccepted(files)\n\n      if (rejected.length) {\n        emit('rejected', rejected)\n      }\n\n      for (const file of accepted) {\n        dataTransfer.items.add(file)\n      }\n\n      inputRef.value!.files = dataTransfer.files\n      const newFiles = [...dataTransfer.files]\n      model.value = props.multiple ? [...model.value, ...newFiles] : newFiles\n\n      const event = new Event('change', { bubbles: true }) as any\n      event.repack = true\n      inputRef.value!.dispatchEvent(event)\n    }\n\n    function onClick () {\n      inputRef.value?.click()\n    }\n\n    function onClickRemove (index: number) {\n      const newValue = model.value.filter((_, i) => i !== index)\n      model.value = newValue\n\n      if (newValue.length > 0 || !inputRef.value) return\n\n      inputRef.value.value = ''\n    }\n\n    useRender(() => {\n      const { modelValue: _, ...inputProps } = VInput.filterProps(props)\n      const { modelValue: __, ...dropzoneProps } = VFileUploadDropzone.filterProps(props as any)\n      const [rootAttrs, inputAttrs] = filterInputAttrs(attrs)\n\n      const expectsDirectory = attrs.webkitdirectory !== undefined && attrs.webkitdirectory !== false\n      const acceptFallback = attrs.accept ? String(attrs.accept) : undefined\n      const inputAccept = expectsDirectory ? undefined : (props.filterByType ?? acceptFallback)\n\n      const inputNode = (\n        <input\n          ref={ inputRef }\n          type=\"file\"\n          accept={ inputAccept }\n          disabled={ props.disabled ?? undefined }\n          multiple={ props.multiple }\n          name={ props.name }\n          onChange={ onFileSelection }\n          { ...inputAttrs }\n        />\n      )\n\n      return (\n        <VInput\n          ref={ vInputRef }\n          modelValue={ props.multiple ? model.value : model.value[0] }\n          onUpdate:modelValue={ val => {\n            if (val == null || (Array.isArray(val) && !val.length)) {\n              model.value = []\n            }\n          }}\n          class={[\n            'v-file-upload',\n            props.class,\n          ]}\n          style={ props.style }\n          focused={ isFocused.value }\n          { ...rootAttrs }\n          { ...inputProps }\n        >\n          {{\n            ...slots,\n            default: () => {\n              return (\n              <>\n                { slots.default ? (\n                  <>\n                    { slots.default() }\n                    <input\n                      ref={ inputRef }\n                      type=\"file\"\n                      accept={ inputAccept }\n                      disabled={ props.disabled ?? undefined }\n                      multiple={ props.multiple }\n                      name={ props.name }\n                      style=\"display: none;\"\n                      onChange={ onFileSelection }\n                      { ...inputAttrs }\n                    />\n                  </>\n                ) : (\n                  <VFileUploadDropzone\n                    ref={ vDropzoneRef }\n                    { ...dropzoneProps }\n                  >\n                    {{\n                      browse: slots.browse,\n                      icon: slots.icon,\n                      title: slots.title,\n                      divider: slots.divider,\n                      single: slots.single,\n                      item: slots.item,\n                      input: () => slots.input?.({ inputNode }) ?? inputNode,\n                    }}\n                  </VFileUploadDropzone>\n                )}\n\n                { !slots.default && !props.insetFileList && (\n                  <VDefaultsProvider\n                    defaults={{\n                      VFileUploadList: {\n                        clearable: props.clearable,\n                        showSize: props.showSize,\n                      },\n                    }}\n                  >\n                    <VFileUploadList>\n                      {{ item: slots.item }}\n                    </VFileUploadList>\n                  </VDefaultsProvider>\n                )}\n              </>\n              )\n            },\n          }}\n        </VInput>\n      )\n    })\n\n    return forwardRefs({\n      controlRef: inputRef,\n    }, vInputRef, vDropzoneRef)\n  },\n})\n\nexport type VFileUpload = InstanceType<typeof VFileUpload>\n"
  },
  {
    "path": "packages/vuetify/src/labs/VFileUpload/VFileUploadDropzone.tsx",
    "content": "// Components\nimport { VFileUploadItem } from './VFileUploadItem'\nimport { VBtn } from '@/components/VBtn/VBtn'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider/VDefaultsProvider'\nimport { makeVDividerProps, VDivider } from '@/components/VDivider/VDivider'\nimport { VIcon } from '@/components/VIcon/VIcon'\nimport { VOverlay } from '@/components/VOverlay/VOverlay'\nimport { makeVSheetProps, VSheet } from '@/components/VSheet/VSheet'\n\n// Composables\nimport { makeDelayProps } from '@/composables/delay'\nimport { makeDensityProps, useDensity } from '@/composables/density'\nimport { useFileDrop } from '@/composables/fileDrop'\nimport { forwardRefs } from '@/composables/forwardRefs'\nimport { IconValue } from '@/composables/icons'\nimport { useLocale } from '@/composables/locale'\n\n// Utilities\nimport { inject, ref, shallowRef } from 'vue'\nimport { genericComponent, pick, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { InjectionKey, PropType, Ref } from 'vue'\n\nexport interface VFileUploadContext {\n  files: Ref<readonly File[]>\n  disabled: Ref<boolean>\n  error: Ref<boolean>\n  onDrop: (files: File[]) => void\n  onClickBrowse: () => void\n  onClickRemove: (index: number) => void\n}\n\nexport const VFileUploadKey: InjectionKey<VFileUploadContext> = Symbol.for('vuetify:file-upload')\n\nexport type VFileUploadDropzoneSlots = {\n  default: {\n    isDragging: boolean\n    hasFiles: boolean\n    files: readonly File[]\n    props: { onClick: () => void }\n  }\n  browse: {\n    props: { onClick: (e: MouseEvent) => void }\n  }\n  icon: never\n  title: never\n  divider: never\n  single: {\n    file: File\n    props: { 'onClick:remove': () => void }\n  }\n  item: {\n    file: File\n    props: { 'onClick:remove': () => void }\n  }\n  input: never\n}\n\nexport const makeVFileUploadDropzoneProps = propsFactory({\n  browseText: {\n    type: String,\n    default: '$vuetify.fileUpload.browse',\n  },\n  dividerText: {\n    type: String,\n    default: '$vuetify.fileUpload.divider',\n  },\n  title: {\n    type: String,\n    default: '$vuetify.fileUpload.title',\n  },\n  subtitle: String,\n  icon: {\n    type: IconValue,\n    default: '$upload',\n  },\n  clearable: Boolean,\n  disabled: Boolean,\n  error: Boolean,\n  hideBrowse: Boolean,\n  insetFileList: Boolean,\n  multiple: Boolean,\n  scrim: {\n    type: [Boolean, String],\n    default: true,\n  },\n  showSize: Boolean,\n\n  ...makeDelayProps(),\n  ...makeDensityProps(),\n  ...pick(makeVDividerProps({\n    length: 150,\n  }), ['length', 'thickness', 'opacity']),\n  ...makeVSheetProps(),\n\n  modelValue: {\n    type: Array as PropType<File[]>,\n    default: () => [],\n  },\n}, 'VFileUploadDropzone')\n\nexport const VFileUploadDropzone = genericComponent<VFileUploadDropzoneSlots>()({\n  name: 'VFileUploadDropzone',\n\n  props: makeVFileUploadDropzoneProps(),\n\n  emits: {\n    'click:browse': () => true,\n    'click:remove': (index: number) => true,\n    drop: (files: File[]) => true,\n  },\n\n  setup (props, { emit, slots }) {\n    const { t } = useLocale()\n    const { densityClasses } = useDensity(props)\n    const { handleDrop } = useFileDrop()\n    const context = inject(VFileUploadKey, null)\n    const vSheetRef = ref<VSheet>()\n    const isDragging = shallowRef(false)\n\n    function onDragover (e: DragEvent) {\n      e.preventDefault()\n      e.stopImmediatePropagation()\n      isDragging.value = true\n    }\n\n    function onDragleave (e: DragEvent) {\n      e.preventDefault()\n      const container = e.currentTarget as HTMLElement\n      if (!container.contains(e.relatedTarget as Node)) {\n        isDragging.value = false\n      }\n    }\n\n    async function onDrop (e: DragEvent) {\n      e.preventDefault()\n      e.stopImmediatePropagation()\n      isDragging.value = false\n\n      const files = await handleDrop(e)\n      if (context) {\n        context.onDrop(files)\n      } else {\n        emit('drop', files)\n      }\n    }\n\n    function onClickBrowse () {\n      if (context) {\n        context.onClickBrowse()\n      } else {\n        emit('click:browse')\n      }\n    }\n\n    function onClickRemove (index: number) {\n      if (context) {\n        context.onClickRemove(index)\n      } else {\n        emit('click:remove', index)\n      }\n    }\n\n    useRender(() => {\n      const modelValue = context?.files.value ?? props.modelValue\n      const disabled = context?.disabled.value ?? props.disabled\n      const error = context?.error.value || props.error\n      const hasTitle = !!(slots.title || props.title)\n      const hasIcon = !!(slots.icon || props.icon)\n      const hasBrowse = !!(!props.hideBrowse && (slots.browse || props.density === 'default'))\n      const hasFiles = modelValue.length > 0\n      const isInset = props.insetFileList && hasFiles\n      const sheetProps = VSheet.filterProps(props)\n      const dividerProps = VDivider.filterProps(props)\n\n      return (\n        <VSheet\n          ref={ vSheetRef }\n          { ...sheetProps }\n          class={[\n            'v-file-upload-dropzone',\n            {\n              'v-file-upload-dropzone--clickable': !hasBrowse && !hasFiles,\n              'v-file-upload-dropzone--disabled': disabled,\n              'v-file-upload-dropzone--dragging': isDragging.value,\n              'v-file-upload-dropzone--has-files': hasFiles,\n              'v-file-upload-dropzone--inset': isInset,\n              'v-file-upload-dropzone--error': error,\n            },\n            densityClasses.value,\n            props.class,\n          ]}\n          style={ props.style }\n          onDragleave={ onDragleave }\n          onDragover={ onDragover }\n          onDrop={ onDrop }\n          onClick={ !hasBrowse && !hasFiles ? onClickBrowse : undefined }\n        >\n          { slots.default?.({\n            isDragging: isDragging.value,\n            hasFiles,\n            files: modelValue,\n            props: { onClick: onClickBrowse },\n          }) ?? (isInset ? (\n            <div key=\"inset\" class=\"v-file-upload-inset\">\n              { modelValue.length === 1 && !props.multiple ? (\n                slots.single?.({\n                  file: modelValue[0],\n                  props: { 'onClick:remove': () => onClickRemove(0) },\n                }) ?? (\n                  <VDefaultsProvider\n                    defaults={{\n                      VFileUploadItem: {\n                        file: modelValue[0],\n                        clearable: props.clearable,\n                        disabled,\n                        showSize: props.showSize,\n                        border: false,\n                      },\n                    }}\n                  >\n                    <VFileUploadItem\n                      onClick:remove={ () => onClickRemove(0) }\n                    />\n                  </VDefaultsProvider>\n                )\n              ) : (\n                modelValue.map((file, i) => {\n                  const slotProps = {\n                    file,\n                    props: {\n                      'onClick:remove': () => onClickRemove(i),\n                    },\n                  }\n\n                  return (\n                    <VDefaultsProvider\n                      key={ i }\n                      defaults={{\n                        VFileUploadItem: {\n                          file,\n                          clearable: props.clearable,\n                          disabled,\n                          showSize: props.showSize,\n                          border: false,\n                        },\n                      }}\n                    >\n                      { slots.item?.(slotProps) ?? (\n                        <VFileUploadItem\n                          key={ i }\n                          onClick:remove={ () => onClickRemove(i) }\n                        />\n                      )}\n                    </VDefaultsProvider>\n                  )\n                })\n              )}\n\n              <VDivider />\n\n              <div class=\"v-file-upload-inset__action\">\n                { !slots.browse ? (\n                  <VBtn\n                    readonly={ disabled }\n                    text={ t(props.browseText) }\n                    variant=\"text\"\n                    onClick={ onClickBrowse }\n                  />\n                ) : (\n                  <VDefaultsProvider\n                    defaults={{\n                      VBtn: {\n                        readonly: disabled,\n                        text: t(props.browseText),\n                        variant: 'text',\n                      },\n                    }}\n                  >\n                    { slots.browse({ props: { onClick: onClickBrowse } }) }\n                  </VDefaultsProvider>\n                )}\n              </div>\n            </div>\n          ) : (\n            <>\n              { hasIcon && (\n                <div key=\"icon\" class=\"v-file-upload-icon\">\n                  { !slots.icon ? (\n                    <VIcon\n                      key=\"icon-icon\"\n                      icon={ props.icon }\n                    />\n                  ) : (\n                    <VDefaultsProvider\n                      key=\"icon-defaults\"\n                      defaults={{\n                        VIcon: {\n                          icon: props.icon,\n                        },\n                      }}\n                    >\n                      { slots.icon() }\n                    </VDefaultsProvider>\n                  )}\n                </div>\n              )}\n\n              { hasTitle && (\n                <div key=\"title\" class=\"v-file-upload-title\">\n                  { slots.title?.() ?? t(props.title) }\n                </div>\n              )}\n\n              { props.density === 'default' && (\n                <>\n                  { hasBrowse && (\n                    <>\n                      <div key=\"upload-divider\" class=\"v-file-upload-divider\">\n                        { slots.divider?.() ?? (\n                          <VDivider { ...dividerProps }>\n                            { t(props.dividerText) }\n                          </VDivider>\n                        )}\n                      </div>\n                      { !slots.browse ? (\n                        <VBtn\n                          readonly={ disabled }\n                          size=\"large\"\n                          text={ t(props.browseText) }\n                          variant=\"tonal\"\n                          onClick={ onClickBrowse }\n                        />\n                      ) : (\n                        <VDefaultsProvider\n                          defaults={{\n                            VBtn: {\n                              readonly: disabled,\n                              size: 'large',\n                              text: t(props.browseText),\n                              variant: 'tonal',\n                            },\n                          }}\n                        >\n                          { slots.browse({ props: { onClick: onClickBrowse } }) }\n                        </VDefaultsProvider>\n                      )}\n                    </>\n                  )}\n\n                  { props.subtitle && (\n                    <div class=\"v-file-upload-subtitle\">\n                      { props.subtitle }\n                    </div>\n                  )}\n                </>\n              )}\n            </>\n          ))}\n\n          <VOverlay\n            modelValue={ isDragging.value }\n            contained\n            scrim={ props.scrim }\n          />\n\n          { slots.input?.() }\n        </VSheet>\n      )\n    })\n\n    return forwardRefs({}, vSheetRef)\n  },\n})\n\nexport type VFileUploadDropzone = InstanceType<typeof VFileUploadDropzone>\n"
  },
  {
    "path": "packages/vuetify/src/labs/VFileUpload/VFileUploadItem.tsx",
    "content": "// Components\nimport { VAvatar } from '@/components/VAvatar/VAvatar'\nimport { VBtn } from '@/components/VBtn/VBtn'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider/VDefaultsProvider'\nimport { makeVListItemProps, VListItem } from '@/components/VList/VListItem'\n\n// Utilities\nimport { computed, ref, watchEffect } from 'vue'\nimport { genericComponent, humanReadableFileSize, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { VListItemSlots } from '@/components/VList/VListItem'\n\nexport type VFileUploadItemSlots = {\n  clear: {\n    props: { onClick: () => void }\n  }\n} & VListItemSlots\n\nexport const makeVFileUploadItemProps = propsFactory({\n  clearable: Boolean,\n  file: {\n    type: Object as PropType<File>,\n    default: null,\n  },\n  fileIcon: {\n    type: String,\n    // TODO: setup up a proper aliased icon\n    default: 'mdi-file-document',\n  },\n  showSize: Boolean,\n\n  ...makeVListItemProps({\n    border: true,\n    rounded: true,\n    lines: 'two' as const,\n  }),\n}, 'VFileUploadItem')\n\nexport const VFileUploadItem = genericComponent<VFileUploadItemSlots>()({\n  name: 'VFileUploadItem',\n\n  props: makeVFileUploadItemProps(),\n\n  emits: {\n    'click:remove': () => true,\n    click: (e: MouseEvent | KeyboardEvent) => true,\n  },\n\n  setup (props, { emit, slots }) {\n    const preview = ref()\n    const base = computed(() => typeof props.showSize !== 'boolean' ? props.showSize : undefined)\n\n    function onClickRemove () {\n      emit('click:remove')\n    }\n\n    watchEffect(() => {\n      preview.value = props.file?.type.startsWith('image') ? URL.createObjectURL(props.file) : undefined\n    })\n\n    useRender(() => {\n      const listItemProps = VListItem.filterProps(props)\n\n      return (\n        <VListItem\n          { ...listItemProps }\n          class={[\n            'v-file-upload-item',\n            props.class,\n          ]}\n          title={ props.title ?? props.file?.name }\n          subtitle={ props.showSize ? humanReadableFileSize(props.file?.size, base.value) : props.file?.type }\n          style={ props.style }\n        >\n          {{\n            ...slots,\n            title: slots.title ?? (() => props?.title ?? props.file?.name),\n            prepend: slotProps => (\n              <>\n                { !slots.prepend ? (\n                  <VAvatar\n                    icon={ props.fileIcon }\n                    image={ preview.value }\n                    rounded\n                  />\n                ) : (\n                  <VDefaultsProvider\n                    defaults={{\n                      VAvatar: {\n                        image: preview.value,\n                        icon: !preview.value ? props.fileIcon : undefined,\n                        rounded: true,\n                      },\n                    }}\n                  >\n                    { slots.prepend?.(slotProps) ?? (\n                      <VAvatar />\n                    )}\n                  </VDefaultsProvider>\n                )}\n              </>\n            ),\n            append: slotProps => (\n              <>\n                { props.clearable && (\n                  <>\n                    { !slots.clear ? (\n                      <VBtn\n                        icon=\"$clear\"\n                        density=\"comfortable\"\n                        variant=\"text\"\n                        onClick={ onClickRemove }\n                      />\n                    ) : (\n                      <VDefaultsProvider\n                        defaults={{\n                          VBtn: {\n                            icon: '$clear',\n                            density: 'comfortable',\n                            variant: 'text',\n                          },\n                        }}\n                      >\n                        { slots.clear?.({\n                          ...slotProps,\n                          props: { onClick: onClickRemove },\n                        }) ?? (<VBtn />)}\n                      </VDefaultsProvider>\n                    )}\n                  </>\n                )}\n\n                { slots.append?.(slotProps) }\n              </>\n            ),\n          }}\n        </VListItem>\n      )\n    })\n  },\n})\n\nexport type VFileUploadItem = InstanceType<typeof VFileUploadItem>\n"
  },
  {
    "path": "packages/vuetify/src/labs/VFileUpload/VFileUploadList.tsx",
    "content": "// Components\nimport { VFileUploadKey } from './VFileUploadDropzone'\nimport { VFileUploadItem } from './VFileUploadItem'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider/VDefaultsProvider'\nimport { makeVListProps, VList } from '@/components/VList/VList'\n\n// Utilities\nimport { inject } from 'vue'\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\nexport type VFileUploadListSlots = {\n  default: {\n    files: readonly File[]\n    onClickRemove: (index: number) => void\n  }\n  item: {\n    file: File\n    props: { 'onClick:remove': () => void }\n  }\n}\n\nexport const makeVFileUploadListProps = propsFactory({\n  clearable: Boolean,\n  showSize: Boolean,\n  files: Array as PropType<File[]>,\n\n  ...makeVListProps({\n    border: false,\n    elevation: 0,\n    lines: false as const,\n  }),\n}, 'VFileUploadList')\n\nexport const VFileUploadList = genericComponent<VFileUploadListSlots>()({\n  name: 'VFileUploadList',\n\n  props: makeVFileUploadListProps(),\n\n  setup (props, { slots }) {\n    const context = inject(VFileUploadKey, null)\n\n    useRender(() => {\n      const files = props.files ?? context?.files.value ?? []\n      const disabled = context?.disabled.value ?? props.disabled\n      const listProps = VList.filterProps(props)\n\n      if (!slots.default && !files.length) return (<></>)\n\n      return (\n        <VList\n          { ...listProps }\n          disabled={ disabled }\n          class={[\n            'v-file-upload-list',\n            props.class,\n          ]}\n          style={ props.style }\n          bgColor=\"transparent\"\n        >\n          { slots.default?.({ files, onClickRemove: (i: number) => context?.onClickRemove(i) }) ?? files.map((file, index) => {\n            const slotProps = {\n              file,\n              props: {\n                'onClick:remove': () => context?.onClickRemove(index),\n              },\n            }\n\n            return (\n              <VDefaultsProvider\n                key={ index }\n                defaults={{\n                  VFileUploadItem: {\n                    file,\n                    clearable: props.clearable,\n                    disabled,\n                    showSize: props.showSize,\n                    variant: 'flat',\n                  },\n                }}\n              >\n                { slots.item?.(slotProps) ?? (\n                  <VFileUploadItem\n                    key={ index }\n                    onClick:remove={ () => context?.onClickRemove(index) }\n                  />\n                )}\n              </VDefaultsProvider>\n            )\n          })}\n        </VList>\n      )\n    })\n  },\n})\n\nexport type VFileUploadList = InstanceType<typeof VFileUploadList>\n"
  },
  {
    "path": "packages/vuetify/src/labs/VFileUpload/_variables.scss",
    "content": "@use '../../styles/tools';\n@use '../../styles/settings';\n\n$file-upload-title-font-size: 1.5rem !default;\n$file-upload-padding: 64px 16px !default;\n$file-upload-border-radius: 4px !default;\n$file-upload-border-width: 2px !default;\n$file-upload-title-font-weight: 600 !default;\n$file-upload-icon-font-size: 3rem !default;\n$file-upload-icon-margin-bottom: 1rem !default;\n$file-upload-divider-margin: 32px 0 !default;\n$file-upload-items-margin: 16px 0 !default;\n$file-upload-inset-action-padding: 8px 0 !default;\n$file-upload-inset-padding: 16px !default;\n"
  },
  {
    "path": "packages/vuetify/src/labs/VFileUpload/index.ts",
    "content": "export { VFileUpload } from './VFileUpload'\nexport { VFileUploadDropzone } from './VFileUploadDropzone'\nexport { VFileUploadItem } from './VFileUploadItem'\nexport { VFileUploadList } from './VFileUploadList'\n"
  },
  {
    "path": "packages/vuetify/src/labs/VIconBtn/VIconBtn.scss",
    "content": "@use '../../styles/settings';\n@use '../../styles/tools';\n@use './variables' as *;\n\n@include tools.layer('components') {\n  .v-icon-btn {\n    @include tools.border($icon-btn-border...);\n    @include tools.rounded($icon-btn-border-radius);\n    @include tools.states('.v-icon-btn__overlay');\n    @include tools.variant($icon-btn-variants...);\n\n    & {\n      align-items: center;\n      cursor: pointer;\n      display: inline-flex;\n      flex: none;\n      font-size: $icon-btn-font-size;\n      font-weight: $icon-btn-font-weight;\n      line-height: $icon-btn-line-height;\n      height: #{$icon-btn-height};\n      justify-content: center;\n      outline: none;\n      position: relative;\n      transition-property: width, height, transform;\n      transition: 0.2s settings.$standard-easing;\n      vertical-align: middle;\n      width: #{$icon-btn-width};\n\n      @supports selector(:focus-visible) {\n        &::after {\n          pointer-events: none;\n          border: 2px solid currentColor;\n          border-radius: inherit;\n          opacity: 0;\n          transition: opacity .2s ease-in-out;\n          @include tools.absolute(true);\n        }\n\n        &:focus-visible::after {\n          opacity: calc(.25 * var(--v-theme-overlay-multiplier));\n        }\n      }\n    }\n\n    &--disabled,\n    &--loading,\n    &--readonly {\n      pointer-events: none;\n    }\n\n    &--disabled {\n      opacity: $icon-btn-disabled-opacity;\n    }\n\n    &--start {\n      margin-inline-end: $icon-btn-margin-start;\n    }\n\n    &--end {\n      margin-inline-start: $icon-btn-margin-end;\n    }\n  }\n\n  .v-icon-btn__content {\n    align-items: center;\n    justify-content: center;\n    display: inline-flex;\n    transition: inherit;\n    transition-property: transform;\n    transform: rotate(var(--v-icon-btn-rotate, 0deg));\n\n    .v-icon-btn--loading & {\n      opacity: 0;\n    }\n\n    .v-icon {\n      transition: 0.2s settings.$standard-easing;\n      transition-property: opacity, font-size, width, height;\n      transform-origin: center;\n    }\n  }\n\n  .v-icon-btn__loader {\n    align-items: center;\n    display: flex;\n    height: 100%;\n    justify-content: center;\n    left: 0;\n    position: absolute;\n    top: 0;\n    width: 100%;\n  }\n\n  .v-icon-btn__overlay,\n  .v-icon-btn__underlay {\n    border-radius: inherit;\n    pointer-events: none;\n\n    @include tools.absolute();\n  }\n\n  .v-icon-btn__overlay {\n    background-color: currentColor;\n    opacity: 0;\n    transition: opacity .2s ease-in-out;\n\n    .v-icon-btn--active:not(:hover) & {\n      --v-activated-opacity: 0;\n    }\n  }\n}\n\n@include tools.layer('trumps') {\n  @media (forced-colors: active) {\n    .v-icon-btn {\n      &:focus-visible {\n        outline: 2px solid;\n        outline-offset: 2px;\n      }\n\n      &:not(&--active):hover,\n      &:not(&--active):focus {\n        color: highlight;\n      }\n\n      &--active:not(&--disabled),\n      &--active:not(&--disabled)[class*=\"bg-\"] {\n        outline-color: canvastext;\n        background: highlight;\n        color: highlighttext;\n      }\n\n      &--disabled {\n        color: graytext;\n      }\n\n      &__overlay,\n      &__underlay,\n      .v-icon {\n        forced-color-adjust: preserve-parent-color;\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/labs/VIconBtn/VIconBtn.tsx",
    "content": "// Styles\nimport './VIconBtn.scss'\n\n// Components\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\nimport { VIcon } from '@/components/VIcon'\nimport { VProgressCircular } from '@/components/VProgressCircular'\n\n// Composables\nimport { makeBorderProps, useBorder } from '@/composables/border'\nimport { makeComponentProps } from '@/composables/component'\nimport { makeElevationProps, useElevation } from '@/composables/elevation'\nimport { makeIconSizeProps, useIconSizes } from '@/composables/iconSizes'\nimport { useProxiedModel } from '@/composables/proxiedModel'\nimport { makeRoundedProps, useRounded } from '@/composables/rounded'\nimport { makeTagProps } from '@/composables/tag'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\nimport { genOverlays, makeVariantProps, useVariant } from '@/composables/variant'\n\n// Utilities\nimport { toDisplayString } from 'vue'\nimport { convertToUnit, genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { IconValue } from '@/composables/icons'\nimport type { Variant } from '@/composables/variant'\n\nexport type VIconBtnSlots = {\n  default: never\n  loader: never\n}\n\nexport type VIconBtnSizes = 'x-small' | 'small' | 'default' | 'large' | 'x-large'\n\nexport const makeVIconBtnProps = propsFactory({\n  active: {\n    type: Boolean,\n    default: undefined,\n  },\n  activeColor: String,\n  activeIcon: [String, Function, Object] as PropType<IconValue>,\n  activeVariant: String as PropType<Variant>,\n  baseVariant: {\n    type: String as PropType<Variant>,\n    default: 'tonal',\n  },\n  disabled: Boolean,\n  height: [Number, String],\n  width: [Number, String],\n  hideOverlay: Boolean,\n  icon: [String, Function, Object] as PropType<IconValue>,\n  iconColor: String,\n  loading: Boolean,\n  opacity: [Number, String],\n  readonly: Boolean,\n  rotate: [Number, String],\n  size: {\n    type: [Number, String] as PropType<VIconBtnSizes | number | string>,\n    default: 'default',\n  },\n  sizes: {\n    type: Array as PropType<[VIconBtnSizes, number][]>,\n    default: () => ([\n      ['x-small', 16],\n      ['small', 24],\n      ['default', 40],\n      ['large', 48],\n      ['x-large', 56],\n    ]),\n  },\n  text: {\n    type: [String, Number, Boolean],\n    default: undefined,\n  },\n\n  ...makeBorderProps(),\n  ...makeComponentProps(),\n  ...makeElevationProps(),\n  ...makeIconSizeProps(),\n  ...makeRoundedProps(),\n  ...makeTagProps({ tag: 'button' }),\n  ...makeThemeProps(),\n  ...makeVariantProps({ variant: 'flat' } as const),\n}, 'VIconBtn')\n\nexport const VIconBtn = genericComponent<VIconBtnSlots>()({\n  name: 'VIconBtn',\n\n  props: makeVIconBtnProps(),\n\n  emits: {\n    'update:active': (value: boolean) => true,\n  },\n\n  setup (props, { attrs, slots }) {\n    const isActive = useProxiedModel(props, 'active')\n\n    const { themeClasses } = provideTheme(props)\n    const { borderClasses } = useBorder(props)\n    const { elevationClasses } = useElevation(props)\n    const { roundedClasses } = useRounded(props)\n\n    const { colorClasses, colorStyles, variantClasses } = useVariant(() => ({\n      color: (() => {\n        if (props.disabled) return undefined\n        if (!isActive.value) return props.color\n        // Use an inline fallback as opposed to setting a default color\n        // because non-toggle buttons are default flat whereas toggle\n        // buttons are default tonal and active flat. The exact use\n        // case for this is a toggle button with no active color.\n        return props.activeColor ?? props.color ?? 'surface-variant'\n      })(),\n      variant: (() => {\n        if (isActive.value === undefined) return props.variant\n        if (isActive.value) return props.activeVariant ?? props.variant\n        return props.baseVariant ?? props.variant\n      })(),\n    }))\n\n    const btnSizeMap = new Map(props.sizes)\n\n    function onClick () {\n      if (\n        props.disabled ||\n        props.readonly ||\n        isActive.value === undefined ||\n        (props.tag === 'a' && attrs.href)\n      ) return\n\n      isActive.value = !isActive.value\n    }\n\n    useRender(() => {\n      const icon = isActive.value ? props.activeIcon ?? props.icon : props.icon\n\n      const _btnSize = props.size as VIconBtnSizes\n      const hasNamedSize = btnSizeMap.has(_btnSize)\n      const btnSize = hasNamedSize ? btnSizeMap.get(_btnSize) : _btnSize\n      const btnHeight = props.height ?? btnSize\n      const btnWidth = props.width ?? btnSize\n      const { iconSize } = useIconSizes(props, () => new Map(props.iconSizes).get(_btnSize))\n\n      const iconProps = {\n        icon,\n        size: iconSize.value,\n        color: props.iconColor,\n        opacity: props.opacity,\n      }\n\n      return (\n        <props.tag\n          type={ props.tag === 'button' ? 'button' : undefined }\n          class={[\n            {\n              'v-icon-btn': true,\n              'v-icon-btn--active': isActive.value,\n              'v-icon-btn--disabled': props.disabled,\n              'v-icon-btn--loading': props.loading,\n              'v-icon-btn--readonly': props.readonly,\n              [`v-icon-btn--${props.size}`]: true,\n            },\n            themeClasses.value,\n            colorClasses.value,\n            borderClasses.value,\n            elevationClasses.value,\n            roundedClasses.value,\n            variantClasses.value,\n            props.class,\n          ]}\n          style={[\n            {\n              '--v-icon-btn-rotate': convertToUnit(props.rotate, 'deg'),\n              '--v-icon-btn-height': convertToUnit(btnHeight),\n              '--v-icon-btn-width': convertToUnit(btnWidth),\n            },\n            colorStyles.value,\n            props.style,\n          ]}\n          tabindex={ props.disabled || props.readonly ? -1 : 0 }\n          onClick={ onClick }\n        >\n          { genOverlays(!props.hideOverlay, 'v-icon-btn') }\n\n          <div class=\"v-icon-btn__content\" data-no-activator=\"\">\n            { (!slots.default && icon) ? (\n              <VIcon\n                key=\"content-icon\"\n                { ...iconProps }\n              />\n            ) : (\n              <VDefaultsProvider\n                key=\"content-defaults\"\n                disabled={ !icon }\n                defaults={{ VIcon: { ...iconProps } }}\n                v-slots={{\n                  default: () => slots.default?.() ?? toDisplayString(props.text),\n                }}\n              />\n            )}\n          </div>\n\n          { !!props.loading && (\n            <span key=\"loader\" class=\"v-icon-btn__loader\">\n              { slots.loader?.() ?? (\n                <VProgressCircular\n                  color={ typeof props.loading === 'boolean' ? undefined : props.loading }\n                  indeterminate=\"disable-shrink\"\n                  width=\"2\"\n                  size={ iconSize.value }\n                />\n              )}\n            </span>\n          )}\n        </props.tag>\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VIconBtn = InstanceType<typeof VIconBtn>\n"
  },
  {
    "path": "packages/vuetify/src/labs/VIconBtn/__tests__/VIconBtn.spec.browser.tsx",
    "content": "import { VIconBtn } from '../VIconBtn'\n\n// Utilities\nimport { render, screen } from '@test'\n\ndescribe('VIconBtn', () => {\n  it.each([\n    [undefined, undefined, 40, 24],\n    [undefined, 'small', 40, 16],\n    [undefined, 22, 40, 22],\n    ['small', undefined, 24, 16],\n    ['small', 'x-small', 24, 10],\n    ['small', 12, 24, 12],\n    [64, undefined, 64, 24],\n    [64, 'small', 64, 16],\n    [64, 32, 64, 32],\n  ])('should work with %s button size and %s icon size', (btn, icon, btnSize, iconSize) => {\n    render(() => <VIconBtn size={ btn } iconSize={ icon } icon=\"$vuetify\" />)\n\n    const btnEl = screen.getByText('', { selector: '.v-icon-btn' })\n    expect(btnEl).toHaveStyle(`--v-icon-btn-height: ${btnSize}px`)\n    expect(btnEl).toHaveStyle(`--v-icon-btn-width: ${btnSize}px`)\n\n    const iconEl = screen.getByText('', { selector: '.v-icon' })\n    expect(iconEl).toHaveStyle(`font-size: ${iconSize}px`)\n    expect(iconEl).toHaveStyle(`height: ${iconSize}px`)\n    expect(iconEl).toHaveStyle(`width: ${iconSize}px`)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/labs/VIconBtn/_variables.scss",
    "content": "@use 'sass:map';\n@use '../../styles/settings';\n@use '../../styles/tools';\n\n// VIconBtn\n$icon-btn-background: rgb(var(--v-theme-surface)) !default;\n$icon-btn-color: inherit !default;\n$icon-btn-border-color: settings.$border-color-root !default;\n$icon-btn-border-radius: map.get(settings.$rounded, 'circle') !default;\n$icon-btn-border-style: settings.$border-style-root !default;\n$icon-btn-border-thin-width: thin !default;\n$icon-btn-border-width: 0 !default;\n$icon-btn-disabled-opacity: 0.26 !default;\n$icon-btn-elevation: 1 !default;\n$icon-btn-font-size: tools.map-deep-get(settings.$typography, 'label-large', 'size') !default;\n$icon-btn-font-weight: tools.map-deep-get(settings.$typography, 'label-large', 'weight') !default;\n$icon-btn-line-height: normal !default;\n$icon-btn-height: var(--v-icon-btn-height) !default;\n$icon-btn-width: var(--v-icon-btn-width) !default;\n$icon-btn-margin-start: 8px !default;\n$icon-btn-margin-end: 8px !default;\n$icon-btn-plain-opacity: .62 !default;\n\n$icon-btn-border: (\n  $icon-btn-border-color,\n  $icon-btn-border-style,\n  $icon-btn-border-width,\n  $icon-btn-border-thin-width\n) !default;\n\n$icon-btn-variants: (\n  $icon-btn-background,\n  $icon-btn-color,\n  $icon-btn-elevation,\n  $icon-btn-plain-opacity,\n  'v-icon-btn'\n) !default;\n"
  },
  {
    "path": "packages/vuetify/src/labs/VIconBtn/index.ts",
    "content": "export { VIconBtn } from './VIconBtn'\n"
  },
  {
    "path": "packages/vuetify/src/labs/VMaskInput/VMaskInput.tsx",
    "content": "// Components\nimport { makeVTextFieldProps, VTextField } from '@/components/VTextField/VTextField'\n\n// Composables\nimport { forwardRefs } from '@/composables/forwardRefs'\nimport { makeMaskProps, useMask } from '@/composables/mask'\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { computed, nextTick, onBeforeMount, ref, shallowRef, toRef } from 'vue'\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { VTextFieldSlots } from '@/components/VTextField/VTextField'\n\nexport type VMaskInputSlots = VTextFieldSlots\n\nexport const makeVMaskInputProps = propsFactory({\n  returnMaskedValue: Boolean,\n  ...makeVTextFieldProps(),\n  ...makeMaskProps(),\n}, 'VMaskInput')\n\nexport const VMaskInput = genericComponent<VMaskInputSlots>()({\n  name: 'VMaskInput',\n\n  props: makeVMaskInputProps(),\n\n  emits: {\n    'update:modelValue': (val: string) => true,\n  },\n\n  setup (props, { slots, emit }) {\n    const vTextFieldRef = ref<VTextField>()\n\n    const inputAction = shallowRef()\n    const caretPosition = shallowRef(0)\n\n    const mask = useMask(props)\n    const returnMaskedValue = computed(() => props.mask && props.returnMaskedValue)\n\n    const model = useProxiedModel(\n      props,\n      'modelValue',\n      undefined,\n      // Always display masked value in input when mask is applied\n      val => props.mask ? mask.mask(mask.unmask(val)) : val,\n      val => {\n        if (props.mask) {\n          // E.g. mask is #-# and the input value is '2-23'\n          // model-value should be enforced to '2-2'\n          const newMaskedValue = mask.mask(mask.unmask(val))\n          const newUnmaskedValue = mask.unmask(newMaskedValue)\n\n          const newCaretPosition = getNewCaretPosition({\n            oldValue: model.value,\n            newValue: newMaskedValue,\n            oldCaret: caretPosition.value,\n          })\n\n          vTextFieldRef.value!.value = newMaskedValue\n          vTextFieldRef.value!.setSelectionRange(newCaretPosition, newCaretPosition)\n\n          return returnMaskedValue.value ? mask.mask(newUnmaskedValue) : newUnmaskedValue\n        }\n        return val\n      },\n    )\n\n    const validationValue = toRef(() => returnMaskedValue.value ? model.value : mask.unmask(model.value))\n\n    function getNewCaretPosition ({\n      oldValue,\n      newValue,\n      oldCaret,\n    }: {\n      oldValue: string\n      newValue: string\n      oldCaret: number\n    }): number {\n      if (!newValue) return 0\n      if (!oldValue) return newValue.length\n\n      let newCaret: number\n\n      if (inputAction.value === 'Backspace') {\n        newCaret = oldCaret - 1\n        while (newCaret > 0 && mask.isDelimiter(newValue, newCaret - 1)) newCaret--\n      } else if (inputAction.value === 'Delete') {\n        newCaret = oldCaret\n      } else { // insertion\n        newCaret = oldCaret + 1\n        while (mask.isDelimiter(newValue, newCaret)) newCaret++\n        if (mask.isDelimiter(newValue, oldCaret)) newCaret++\n      }\n\n      return newCaret\n    }\n\n    onBeforeMount(() => {\n      if (props.returnMaskedValue) {\n        emit('update:modelValue', model.value)\n      }\n    })\n\n    function onKeyDown (e: KeyboardEvent) {\n      if (e.metaKey) return\n\n      const inputElement = e.target as HTMLInputElement\n\n      caretPosition.value = inputElement.selectionStart || 0\n      inputAction.value = e.key\n\n      const hasSelection = inputElement.selectionStart !== inputElement.selectionEnd\n      if (e.key === 'Backspace' && hasSelection) {\n        e.preventDefault()\n        deleteSelection(e)\n      }\n    }\n\n    async function onCut (e: Event) {\n      e.preventDefault()\n\n      await copySelectionToClipboard(e)\n      await deleteSelection(e)\n    }\n\n    async function onPaste (e: ClipboardEvent) {\n      e.preventDefault()\n\n      const inputElement = e.target as HTMLInputElement\n      const pastedString = e.clipboardData?.getData('text') || ''\n\n      if (!pastedString) return\n\n      const pastedCharacters = [...pastedString]\n\n      const hasSelection = inputElement.selectionStart !== inputElement.selectionEnd\n\n      if (hasSelection) {\n        replaceSelection(inputElement, pastedCharacters)\n      } else {\n        insertCharacters(inputElement, pastedCharacters)\n      }\n    }\n\n    async function copySelectionToClipboard (e: Event) {\n      const inputElement = e.target as HTMLInputElement\n      const start = inputElement.selectionStart || 0\n      const end = inputElement.selectionEnd || 0\n      const selectedText = inputElement.value.substring(start, end)\n      await navigator.clipboard.writeText(selectedText)\n    }\n\n    async function deleteSelection (e: Event) {\n      const inputElement = e.target as HTMLInputElement\n      const curStart = inputElement.selectionStart || 0\n      caretPosition.value = inputElement.selectionEnd || 0\n\n      while (caretPosition.value > curStart) {\n        const success = await simulateBackspace(inputElement)\n        if (!success) break\n      }\n    }\n\n    async function simulateBackspace (inputElement: HTMLInputElement) {\n      inputAction.value = 'Backspace'\n      model.value = inputElement.value.slice(0, caretPosition.value - 1) + inputElement.value.slice(caretPosition.value)\n      inputAction.value = ''\n      if (caretPosition.value === inputElement.selectionEnd) return false\n      caretPosition.value = inputElement.selectionEnd || 0\n      await nextTick()\n      return true\n    }\n\n    async function insertCharacters (inputElement: HTMLInputElement, pastedCharacters: string[]) {\n      for (let i = 0; i < pastedCharacters.length; i++) {\n        await insertCharacter(inputElement, pastedCharacters[i])\n      }\n    }\n\n    async function insertCharacter (inputElement: HTMLInputElement, character: string) {\n      caretPosition.value = inputElement.selectionEnd || 0\n      model.value = inputElement.value.slice(0, caretPosition.value) + character + inputElement.value.slice(caretPosition.value)\n      await nextTick()\n    }\n\n    async function replaceSelection (inputElement: HTMLInputElement, pastedCharacters: string[]) {\n      caretPosition.value = inputElement.selectionStart || 0\n      for (let i = 0; i < pastedCharacters.length; i++) {\n        if (await replaceCharacter(caretPosition.value, pastedCharacters[i])) {\n          caretPosition.value++\n        }\n      }\n    }\n\n    async function replaceCharacter (index: number, character: string) {\n      let targetIndex = index\n\n      // Find next non-delimiter position\n      while (targetIndex < model.value.length && mask.isDelimiter(model.value, targetIndex)) {\n        targetIndex++\n      }\n\n      const newValue = model.value.slice(0, targetIndex) + character + model.value.slice(targetIndex + 1)\n\n      if (mask.isValid(newValue)) {\n        model.value = newValue\n        await nextTick()\n        return true\n      }\n      return false\n    }\n\n    useRender(() => {\n      const textFieldProps = VTextField.filterProps(props)\n\n      return (\n        <VTextField\n          { ...textFieldProps }\n          v-model={ model.value }\n          ref={ vTextFieldRef }\n          class={['v-mask-input', props.class]}\n          style={ props.style }\n          validationValue={ validationValue.value }\n          onCut={ onCut }\n          onPaste={ onPaste }\n          onKeydown={ onKeyDown }\n        >\n          {{ ...slots }}\n        </VTextField>\n      )\n    })\n\n    return forwardRefs({}, vTextFieldRef)\n  },\n})\n\nexport type VMaskInput = InstanceType<typeof VMaskInput>\n"
  },
  {
    "path": "packages/vuetify/src/labs/VMaskInput/__tests__/VMaskInput.spec.browser.tsx",
    "content": "import { VMaskInput } from '../VMaskInput'\n\n// Utilities\nimport { commands, render, screen, userEvent } from '@test'\nimport { ref } from 'vue'\n\ndescribe('VMaskInput', () => {\n  it('should mask model-value but keep v-model intact', async () => {\n    const inputValue = ref('4567')\n    render(() => (\n      <VMaskInput\n        v-model={ inputValue.value }\n        mask=\"(###) #\"\n      />\n    ))\n\n    await expect.element(screen.getByCSS('input')).toHaveValue('(456) 7')\n    expect(inputValue.value).toBe('4567')\n  })\n\n  it('should mask model-value and also return v-model to be masked value', async () => {\n    const inputValue = ref('4567')\n    render(() => (\n      <VMaskInput\n        v-model={ inputValue.value }\n        mask=\"(###) #\"\n        returnMaskedValue\n      />\n    ))\n\n    await expect.element(screen.getByCSS('input')).toHaveValue('(456) 7')\n    expect(inputValue.value).toBe('(456) 7')\n  })\n\n  it('should clear the input when clear icon is clicked', async () => {\n    const inputValue = ref('(456) 7')\n\n    render(() => (\n      <VMaskInput\n        v-model={ inputValue.value }\n        mask=\"(###) #\"\n        clearable\n      />\n    ))\n\n    await userEvent.click(screen.getByLabelText('Clear'))\n    expect(inputValue.value).toBe('')\n  })\n\n  describe('Caret Position and Formatting', () => {\n    const renderComponent = ({\n      defaultModel = '(AS)-123-XYZ-45-67',\n      defaultMask = '(AA)-###-NNN-##-##',\n    }: {\n      defaultModel?: string\n      defaultMask?: string\n    } = {}) => {\n      const model = ref(defaultModel)\n\n      const wrapper = render(() => (\n        <VMaskInput\n          v-model={ model.value }\n          mask={ defaultMask }\n          returnMaskedValue\n        />\n      ))\n\n      const input = screen.getByCSS('input') as HTMLInputElement\n\n      const insertCaretAt = async (start: number, end?: number) => {\n        await userEvent.click(input)\n        input.setSelectionRange(start, end || start)\n        return input.selectionStart\n      }\n\n      return {\n        model,\n        input,\n        wrapper,\n        insertCaretAt,\n      }\n    }\n\n    describe('Insertion', () => {\n      it('should work as expected when typing', async () => {\n        const { input, model } = renderComponent({ defaultModel: '', defaultMask: '####' })\n        await userEvent.type(input, '123')\n        expect(model.value).toBe('123')\n        expect(input.selectionStart).toBe(input.value.length)\n      })\n\n      it('should handle escaped characters', async () => {\n        const { input, model } = renderComponent({ defaultModel: '', defaultMask: '\\\\####' })\n        await userEvent.type(input, '123')\n        expect(model.value).toBe('#123')\n        expect(input.selectionStart).toBe(input.value.length)\n      })\n\n      it.each([\n        // when cursor before delimiter\n        {\n          inputCaret: [12],\n          inputText: '1',\n          outputText: '(AS)-123-XYZ-14-56',\n          outputCaret: 14,\n        },\n        // when typing such that cursor lands before delimiter.\n        {\n          defaultModel: '(A',\n          inputCaret: [2],\n          inputText: 'S',\n          outputText: '(AS)-',\n          outputCaret: 5,\n        },\n        // when typing in the middle of input\n        {\n          inputCaret: [13],\n          inputText: '1',\n          outputText: '(AS)-123-XYZ-14-56',\n          outputCaret: 14,\n        },\n        // when selected in the middle\n        {\n          inputCaret: [9, 11],\n          inputText: 'A',\n          outputText: '(AS)-123-AZ4-56-7',\n          outputCaret: 10,\n        },\n        // when selected such that one character before, one at and one after delimiter\n        {\n          inputCaret: [11, 14],\n          inputText: '1',\n          outputText: '(AS)-123-XY1-56-7',\n          outputCaret: 13,\n        },\n      ])('should work as expected when typing', async ({ defaultModel, inputText, inputCaret, outputText, outputCaret }) => {\n        const { input, model, insertCaretAt } = renderComponent({ defaultModel })\n\n        await insertCaretAt(inputCaret[0], inputCaret[1])\n\n        await userEvent.type(input, inputText)\n\n        expect(model.value).toBe(outputText)\n        expect(input.selectionStart).toBe(outputCaret)\n      })\n    })\n\n    describe('Backward Delete / Backspace', () => {\n      it.each([\n        // when backspace is pressed\n        {\n          defaultMask: '####',\n          defaultModel: '1234',\n          inputCaret: [3],\n          outputText: '124',\n          outputCaret: 2,\n        },\n        // when backspace pressed when cursor is after delimiter\n        {\n          defaultMask: '##-##',\n          defaultModel: '12-34',\n          inputCaret: [3],\n          outputText: '12-34',\n          outputCaret: 2,\n        },\n        // backspace pressed such that cursor lands after delimiter\n        {\n          defaultMask: '##-##',\n          defaultModel: '12-34',\n          inputCaret: [4],\n          outputText: '12-4',\n          outputCaret: 2,\n        },\n        // backspace pressed in the middle of input\n        {\n          inputCaret: [15],\n          outputText: '(AS)-123-XYZ-46-7',\n          outputCaret: 14,\n        },\n        // backspace pressed with selection in middle\n        {\n          inputCaret: [10, 12],\n          outputText: '(AS)-123-X45-67-',\n          outputCaret: 10,\n        },\n        // backspace pressed with selection containing one character before, one at and one after delimiter\n        {\n          inputCaret: [11, 14],\n          outputText: '(AS)-123-XY5-67-',\n          outputCaret: 11,\n        },\n      ])('should work as expected when pressing backspace', async ({ defaultModel, defaultMask, inputCaret, outputText, outputCaret }) => {\n        const { input, model, insertCaretAt } = renderComponent({ defaultModel, defaultMask })\n\n        await insertCaretAt(inputCaret[0], inputCaret[1])\n\n        await userEvent.type(input, '{backspace}')\n        expect(model.value).toBe(outputText)\n        expect(input.selectionStart).toBe(outputCaret)\n      })\n    })\n\n    describe('Forward Delete', () => {\n      it.each([\n        // when forward delete is pressed\n        {\n          defaultMask: '####',\n          defaultModel: '1234',\n          inputCaret: [2],\n          outputText: '124',\n          outputCaret: 2,\n        },\n        // when forward delete pressed when cursor is after delimiter\n        {\n          defaultMask: '##-##',\n          defaultModel: '12-34',\n          inputCaret: [3],\n          outputText: '12-4',\n          outputCaret: 3,\n        },\n        // forward delete pressed in the middle of input\n        {\n          inputCaret: [14],\n          outputText: '(AS)-123-XYZ-46-7',\n          outputCaret: 14,\n        },\n        // forward delete pressed with selection in middle\n        {\n          inputCaret: [10, 12],\n          outputText: '(AS)-123-X45-67-',\n          outputCaret: 10,\n        },\n        // forward delete pressed with selection containing one character before, one at and one after delimiter\n        {\n          inputCaret: [11, 14],\n          outputText: '(AS)-123-XY5-67-',\n          outputCaret: 11,\n        },\n      ])('should work as expected when pressing delete', async ({ defaultModel, defaultMask, inputCaret, outputText, outputCaret }) => {\n        const { input, model, insertCaretAt } = renderComponent({ defaultModel, defaultMask })\n\n        await insertCaretAt(inputCaret[0], inputCaret[1])\n\n        await userEvent.type(input, '{delete}')\n        expect(model.value).toBe(outputText)\n        expect(input.selectionStart).toBe(outputCaret)\n      })\n    })\n\n    describe('Cut', () => {\n      it.each([\n        // when cut with selection in middle\n        {\n          inputCaret: [10, 12],\n          outputText: '(AS)-123-X45-67-',\n          outputCaret: 10,\n        },\n        // when cut with selection containing one character before, one at and one after delimiter\n        {\n          inputCaret: [11, 14],\n          outputText: '(AS)-123-XY5-67-',\n          outputCaret: 11,\n        },\n      ])('should work as expected when pressing cut', async ({ inputCaret, outputText, outputCaret }) => {\n        const { input, model, insertCaretAt } = renderComponent()\n\n        await insertCaretAt(inputCaret[0], inputCaret[1])\n\n        await userEvent.keyboard('{ControlOrMeta>}x{/ControlOrMeta}')\n        expect(model.value).toBe(outputText)\n        expect(input.selectionStart).toBe(outputCaret)\n      })\n    })\n\n    describe('Paste', () => {\n      it.each([\n        // pasted when cursor is at end\n        {\n          defaultMask: '####',\n          defaultModel: '12',\n          inputText: '34',\n          inputCaret: [2],\n          outputText: '1234',\n          outputCaret: 4,\n        },\n        // pasted when cursor is in middle\n        {\n          defaultMask: '#####',\n          defaultModel: '1245',\n          inputText: '3',\n          inputCaret: [2],\n          outputText: '12345',\n          outputCaret: 3,\n        },\n        // pasted when cursor is after delimiter\n        {\n          defaultModel: '(AS)-123-XYZ-',\n          inputText: '12',\n          inputCaret: [13],\n          outputText: '(AS)-123-XYZ-12-',\n          outputCaret: 16,\n        },\n        // pasted when cursor is before delimiter\n        {\n          defaultMask: '##-##',\n          defaultModel: '12-',\n          inputText: '34',\n          inputCaret: [2],\n          outputText: '12-34',\n          outputCaret: 5,\n        },\n        // pasted when selection is in middle\n        {\n          inputCaret: [10, 12],\n          inputText: 'CD',\n          outputText: '(AS)-123-XCD-45-67',\n          outputCaret: 13,\n        },\n        // pasted when selection is in middle\n        {\n          inputCaret: [1, 3],\n          inputText: 'CD',\n          outputText: '(CD)-123-XYZ-45-67',\n          outputCaret: 5,\n        },\n        // pasted with junk delimiters when selection is in middle\n        {\n          inputCaret: [1, 3],\n          inputText: '_CD',\n          outputText: '(CD)-123-XYZ-45-67',\n          outputCaret: 5,\n        },\n        // pasted when selection contains one character before, one at and one after delimiter\n        {\n          inputCaret: [11, 14],\n          inputText: 'A0',\n          outputText: '(AS)-123-XYA-05-67',\n          outputCaret: 14,\n        },\n      ])('should work as expected when pasting', async ({ defaultModel, defaultMask, inputText, inputCaret, outputText, outputCaret }) => {\n        const { input, model, insertCaretAt } = renderComponent({ defaultModel, defaultMask })\n\n        await insertCaretAt(inputCaret[0], inputCaret[1])\n        const lock = await commands.getLock()\n        await navigator.clipboard.writeText(inputText)\n        await userEvent.paste()\n        await commands.releaseLock(lock)\n\n        expect(model.value).toBe(outputText)\n        expect(input.selectionStart).toBe(outputCaret)\n      })\n    })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/labs/VMaskInput/index.ts",
    "content": "export { VMaskInput } from './VMaskInput'\n"
  },
  {
    "path": "packages/vuetify/src/labs/VPicker/VPicker.sass",
    "content": "@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-picker.v-sheet\n    display: grid\n    grid-auto-rows: min-content\n    grid-template-areas: \"header\" \"body\"\n    grid-template-columns: minmax(0, 1fr)\n    overflow: hidden\n    @include tools.elevation($picker-elevation)\n    @include tools.rounded($picker-border-radius)\n\n    &.v-picker--with-actions\n      grid-template-areas: \"header\" \"body\" \"actions\"\n\n    &.v-picker--landscape\n      grid-template-columns: auto 1fr\n      grid-template-areas: \"header body\" \"header body\"\n\n      &.v-picker--with-actions\n        grid-template-areas: \"header body\" \"header actions\"\n\n  .v-picker__body\n    grid-area: body\n    overflow: hidden\n    position: relative\n    display: flex\n    justify-content: center\n    flex-wrap: wrap\n\n  .v-picker__header-wrapper\n    grid-area: header\n\n  .v-picker__actions\n    grid-area: actions\n    padding: $picker-actions-padding\n    display: flex\n    align-items: center\n    justify-content: flex-end\n\n    .v-btn\n      min-width: 48px\n\n      &:not(:last-child)\n        margin-inline-end: 8px\n\n  .v-picker--divided\n    .v-picker__header\n      border-bottom-color: $picker-border-color\n      border-bottom-style: $picker-border-style\n      border-bottom-width: $picker-border-thin-width\n\n  .v-picker-title\n    text-transform: uppercase\n    font-size: .75rem\n    padding-inline: 24px 12px\n    padding-top: 16px\n    padding-bottom: 16px\n    font-weight: $picker-title-font-weight\n    letter-spacing: .1666666667em\n"
  },
  {
    "path": "packages/vuetify/src/labs/VPicker/VPicker.tsx",
    "content": "// Styles\nimport './VPicker.sass'\n\n// Components\nimport { VPickerTitle } from './VPickerTitle'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider/VDefaultsProvider'\nimport { makeVSheetProps, VSheet } from '@/components/VSheet/VSheet'\n\n// Composables\nimport { useBackgroundColor } from '@/composables/color'\n\n// Utilities\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nexport type VPickerSlots = {\n  header: never\n  default: never\n  actions: never\n  title: never\n}\n\nexport const makeVPickerProps = propsFactory({\n  bgColor: String,\n  divided: Boolean,\n  landscape: Boolean,\n  title: String,\n  hideHeader: Boolean,\n  hideTitle: Boolean,\n\n  ...makeVSheetProps(),\n}, 'VPicker')\n\nexport const VPicker = genericComponent<VPickerSlots>()({\n  name: 'VPicker',\n\n  props: makeVPickerProps(),\n\n  setup (props, { slots }) {\n    const { backgroundColorClasses, backgroundColorStyles } = useBackgroundColor(() => props.color)\n    useRender(() => {\n      const sheetProps = VSheet.filterProps(props)\n      const hasTitle = !props.hideTitle && !!(props.title || slots.title)\n\n      return (\n        <VSheet\n          { ...sheetProps }\n          color={ props.bgColor }\n          class={[\n            'v-picker',\n            {\n              'v-picker--divided': props.divided,\n              'v-picker--landscape': props.landscape,\n              'v-picker--with-actions': !!slots.actions,\n            },\n            props.class,\n          ]}\n          style={ props.style }\n        >\n          { !props.hideHeader && (\n            <div\n              key=\"header\"\n              class={[\n                'v-picker__header-wrapper',\n                backgroundColorClasses.value,\n              ]}\n              style={[\n                backgroundColorStyles.value,\n              ]}\n            >\n              { hasTitle && (\n                <VPickerTitle key=\"picker-title\">\n                  { slots.title?.() ?? props.title }\n                </VPickerTitle>\n              )}\n\n              { slots.header && (\n                <div class=\"v-picker__header\">\n                  { slots.header() }\n                </div>\n              )}\n            </div>\n          )}\n\n          <div class=\"v-picker__body\">\n            { slots.default?.() }\n          </div>\n\n          { slots.actions && (\n            <VDefaultsProvider\n              defaults={{\n                VBtn: {\n                  slim: true,\n                  variant: 'text',\n                },\n              }}\n            >\n              <div class=\"v-picker__actions\">\n                { slots.actions() }\n              </div>\n            </VDefaultsProvider>\n          )}\n        </VSheet>\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VPicker = InstanceType<typeof VPicker>\n"
  },
  {
    "path": "packages/vuetify/src/labs/VPicker/VPickerTitle.ts",
    "content": "// Utilities\nimport { createSimpleFunctional } from '@/util'\n\nexport const VPickerTitle = createSimpleFunctional('v-picker-title')\n\nexport type VPickerTitle = InstanceType<typeof VPickerTitle>\n"
  },
  {
    "path": "packages/vuetify/src/labs/VPicker/__tests__/VPicker.spec.ts",
    "content": "// @ts-nocheck\n/* eslint-disable */\n\n// Components\n// import VPicker from '../VPicker'\n\n// Utilities\nimport {\n  mount,\n  Wrapper,\n} from '@vue/test-utils'\n// import { compileToFunctions } from 'vue-template-compiler'\n\ndescribe.skip('VPicker.ts', () => {\n  type Instance = InstanceType<typeof VPicker>\n  let mountFunction: (options?: object) => Wrapper<Instance>\n\n  beforeEach(() => {\n    mountFunction = (options = {}) => {\n      return mount(VPicker, {\n        ...options,\n      })\n    }\n  })\n\n  it('should render component without title and match snapshot', () => {\n    const wrapper = mountFunction({\n      slots: {\n        default: [compileToFunctions('<span>default</span>')],\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render component with title and match snapshot', () => {\n    const wrapper = mountFunction({\n      slots: {\n        default: [compileToFunctions('<span>default</span>')],\n        title: [compileToFunctions('<span>title</span>')],\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render flat component and match snapshot', () => {\n    const wrapper = mountFunction({\n      slots: {\n        default: [compileToFunctions('<span>default</span>')],\n        title: [compileToFunctions('<span>title</span>')],\n      },\n      props: {\n        flat: true,\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render component with elevation and match snapshot', () => {\n    const wrapper = mountFunction({\n      slots: {\n        default: [compileToFunctions('<span>default</span>')],\n        title: [compileToFunctions('<span>title</span>')],\n      },\n      props: {\n        elevation: 4,\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render dark component and match snapshot', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        dark: true,\n      },\n      slots: {\n        default: [compileToFunctions('<span>default</span>')],\n        title: [compileToFunctions('<span>title</span>')],\n      },\n    })\n\n    expect(wrapper.html()).toMatchSnapshot()\n  })\n\n  it('should render colored component', () => {\n    const wrapper = mountFunction({\n      propsData: {\n        color: 'orange lighten-1',\n      },\n      slots: {\n        title: [compileToFunctions('<span>title</span>')],\n      },\n    })\n\n    const title = wrapper.find('.v-picker__title')\n    expect(title.classes('orange')).toBe(true)\n    expect(title.classes('lighten-1')).toBe(true)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/labs/VPicker/__tests__/__snapshots__/VPicker.spec.ts.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`VPicker.ts should render component with elevation and match snapshot 1`] = `\n<div class=\"v-picker v-card theme--light\">\n  <div class=\"v-picker__title primary\">\n    <span>\n      title\n    </span>\n  </div>\n  <div class=\"v-picker__body theme--light\"\n       style=\"width: 290px;\"\n  >\n    <span>\n      default\n    </span>\n  </div>\n</div>\n`;\n\nexports[`VPicker.ts should render component with title and match snapshot 1`] = `\n<div class=\"v-picker v-card theme--light\">\n  <div class=\"v-picker__title primary\">\n    <span>\n      title\n    </span>\n  </div>\n  <div class=\"v-picker__body theme--light\"\n       style=\"width: 290px;\"\n  >\n    <span>\n      default\n    </span>\n  </div>\n</div>\n`;\n\nexports[`VPicker.ts should render component without title and match snapshot 1`] = `\n<div class=\"v-picker v-card theme--light\">\n  <div class=\"v-picker__body theme--light\"\n       style=\"width: 290px;\"\n  >\n    <span>\n      default\n    </span>\n  </div>\n</div>\n`;\n\nexports[`VPicker.ts should render dark component and match snapshot 1`] = `\n<div class=\"v-picker v-card theme--dark\">\n  <div class=\"v-picker__title\">\n    <span>\n      title\n    </span>\n  </div>\n  <div class=\"v-picker__body theme--dark\"\n       style=\"width: 290px;\"\n  >\n    <span>\n      default\n    </span>\n  </div>\n</div>\n`;\n\nexports[`VPicker.ts should render flat component and match snapshot 1`] = `\n<div class=\"v-picker v-card theme--light\">\n  <div class=\"v-picker__title primary\">\n    <span>\n      title\n    </span>\n  </div>\n  <div class=\"v-picker__body theme--light\"\n       style=\"width: 290px;\"\n  >\n    <span>\n      default\n    </span>\n  </div>\n</div>\n`;\n"
  },
  {
    "path": "packages/vuetify/src/labs/VPicker/_variables.scss",
    "content": "@use '../../styles/settings';\n\n$picker-actions-padding: 0 12px 12px !default;\n$picker-border-color: settings.$border-color-root !default;\n$picker-border-radius: settings.$border-radius-root !default;\n$picker-border-radius: settings.$border-radius-root !default;\n$picker-border-style: settings.$border-style-root !default;\n$picker-border-thin-width: thin !default;\n$picker-elevation: 0 !default;\n$picker-inactive-btn-opacity: .6 !default;\n$picker-title-font-weight: 400 !default;\n"
  },
  {
    "path": "packages/vuetify/src/labs/VPicker/index.ts",
    "content": "export { VPicker } from './VPicker'\nexport { VPickerTitle } from './VPickerTitle'\n"
  },
  {
    "path": "packages/vuetify/src/labs/VPie/VPie.sass",
    "content": "@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-pie\n    display: grid\n    align-items: center\n    column-gap: 24px\n    --v-pie-size: 250px\n\n    &--legend\n      &-top\n        grid-template-areas: 'title' 'legend' 'content'\n        grid-template-columns: var(--v-pie-size)\n      &-bottom\n        grid-template-areas: 'title' 'content' 'legend'\n        grid-template-columns: var(--v-pie-size)\n      &-right\n        grid-template-areas: 'title .' 'content legend'\n      &-left\n        grid-template-areas: '. title' 'legend content'\n      &-hidden\n        grid-template-areas: 'title' 'content'\n\n    &__title\n      grid-area: title\n      text-align: center\n      padding-bottom: $pie-title-padding-bottom\n\n    &__content\n      grid-area: content\n      position: relative\n      width: var(--v-pie-size)\n      height: var(--v-pie-size)\n\n      @include tools.layer('overrides')\n        .v-overlay__scrim,\n        .v-overlay__content\n          pointer-events: none\n\n      @include tools.layer('trumps')\n        // expected to get bg-* class for text color\n        // actual background is applied to underlay\n        background: none\n\n    &__segments\n      border-radius: 50%\n\n    &__content-underlay\n      border-radius: 50%\n      position: absolute\n      inset: $pie-underlay-inset\n      pointer-events: none\n      z-index: -1\n\n    &__center-content\n      position: absolute\n      top: 50%\n      left: 50%\n      transform: translate(-50%, -50%)\n      pointer-events: none\n\n      > div\n        pointer-events: auto\n\n    &__legend\n      grid-area: legend\n      padding-block: $pie-legend-padding-block\n\n      .v-avatar\n        border: $pie-legend-avatar-border\n\n      .v-chip__content\n        width: 100%\n\n      .v-chip-group .v-chip:not(.v-chip--selected)\n        opacity: $pie-legend-chip-disabled-opacity\n\n      &__text\n        font-size: $pie-legend-chip-default-font-size\n        white-space: nowrap\n        width: 100%\n\n        .v-chip--density-compact &\n          font-size: $pie-legend-chip-compact-font-size\n\n    .v-chip.v-chip--density-comfortable .v-avatar--start\n      margin-inline-start: -6px\n\n    .v-chip.v-chip--density-default .v-avatar--start\n      margin-inline-start: -4px\n\n    &-segment\n      pointer-events: none\n      position: absolute\n      inset: 0\n\n      .v-pie-segment__overlay\n        pointer-events: auto\n        opacity: 0\n\n    &__tooltip-content\n      .v-list-item\n        padding-inline: 0\n        min-width: $pie-tooltip-min-width\n        zoom: 0.88\n\n      .v-list-item-subtitle\n        opacity: 1\n\n      .v-avatar\n        border: $pie-tooltip-avatar-border\n"
  },
  {
    "path": "packages/vuetify/src/labs/VPie/VPie.tsx",
    "content": "// Styles\nimport './VPie.sass'\n\n// Components\nimport { makeVPieSegmentProps, VPieSegment } from './VPieSegment'\nimport { VPieTooltip } from './VPieTooltip'\nimport { VAvatar } from '@/components/VAvatar'\nimport { VChip } from '@/components/VChip'\nimport { VChipGroup } from '@/components/VChipGroup'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\n\n// Composables\nimport { useColor } from '@/composables/color'\nimport { makeDensityProps } from '@/composables/density'\n\n// Directives\nimport vClickOutside from '@/directives/click-outside'\n\n// Utilities\nimport { computed, shallowRef, toRef, watch } from 'vue'\nimport { formatTextTemplate } from './utils'\nimport { convertToUnit, genericComponent, pick, propsFactory } from '@/util'\n\n// Types\nimport type { PropType, TransitionProps } from 'vue'\nimport type { PieItem, TextTemplate } from './types'\n\nexport type VPieSlots = {\n  center: { total: number }\n  legend: {\n    isActive: (item: PieItem) => boolean\n    toggle: (item: PieItem) => void\n    items: PieItem[]\n    total: number\n  }\n  'legend-text': {\n    item: PieItem\n    total: number\n  }\n  title: never\n  tooltip: {\n    item: PieItem\n    total: number\n  }\n}\n\nexport const makeVPieProps = propsFactory({\n  title: String,\n  bgColor: String,\n  items: {\n    type: Array as PropType<Record<string, any> | { color?: string, pattern?: string }[]>,\n    default: () => [],\n  },\n  palette: {\n    type: Array as PropType<({ color?: string, pattern?: string } | string)[]>,\n    default: () => [],\n  },\n  itemKey: {\n    type: String,\n    default: 'key',\n  },\n  itemValue: {\n    type: String,\n    default: 'value',\n  },\n  itemTitle: {\n    type: String,\n    default: 'title',\n  },\n  size: {\n    type: [Number, String],\n    default: 250,\n  },\n  rotate: [Number, String],\n  gaugeCut: [Number, String],\n  legend: {\n    type: [Boolean, Object] as PropType<boolean | {\n      position?: 'left' | 'top' | 'right' | 'bottom'\n      textFormat?: TextTemplate\n    }>,\n    default: false,\n  },\n  tooltip: {\n    type: [Boolean, Object] as PropType<boolean | {\n      titleFormat?: TextTemplate\n      subtitleFormat?: TextTemplate\n      avatarSize?: number\n      transition?: string | boolean | TransitionProps\n      offset?: number\n    }>,\n    default: false,\n  },\n\n  ...makeDensityProps(),\n  ...pick(makeVPieSegmentProps(), [\n    'animation',\n    'gap',\n    'rounded',\n    'innerCut',\n    'hoverScale',\n    'hideSlice',\n    'reveal',\n  ]),\n}, 'VPie')\n\nexport const VPie = genericComponent<VPieSlots>()({\n  name: 'VPie',\n\n  directives: { vClickOutside },\n\n  props: makeVPieProps(),\n\n  setup (props, { slots }) {\n    const legendConfig = computed(() => ({\n      visible: !!props.legend,\n      position: 'bottom',\n      textFormat: '[title]',\n      ...(typeof props.legend === 'object' ? props.legend : {}),\n    }))\n\n    const { colorClasses, colorStyles } = useColor(() => ({ background: props.bgColor }))\n    const textColorStyles = toRef(() => pick(colorStyles.value, ['color', 'caretColor']))\n\n    const legendAvatarSize = toRef(() => ({ default: 20, comfortable: 18, compact: 16 }[props.density ?? 'default']))\n    const legendDirection = toRef(() => ['left', 'right'].includes(legendConfig.value.position) ? 'vertical' : 'horizontal')\n\n    const legendMode = toRef(() => !legendConfig.value.visible ? 'hidden' : legendConfig.value.position)\n\n    const legendTextFormatFunction = toRef(() => (item: PieItem) => {\n      return typeof legendConfig.value.textFormat === 'function'\n        ? legendConfig.value.textFormat(item)\n        : formatTextTemplate(legendConfig.value.textFormat, item)\n    })\n\n    const arcs = computed<PieItem[]>(() => {\n      // hidden items get (value: 0) to trigger disappearing animation\n      return props.items\n        .filter(Boolean)\n        .map((item: any, index: number) => {\n          return {\n            key: item[props.itemKey],\n            color: item.color ?? colorFromPalette(index),\n            value: item[props.itemValue],\n            title: String(item[props.itemTitle]),\n            pattern: item.pattern ?? patternFromPalette(index),\n            raw: item,\n          } as PieItem\n        })\n    })\n\n    const visibleItemsKeys = shallowRef<PieItem['key'][]>([])\n\n    watch(() => arcs.value.length, () => {\n      // reset when number of items changes\n      visibleItemsKeys.value = arcs.value.map(a => a.key)\n    }, { immediate: true })\n\n    const visibleItems = computed(() => {\n      // hidden items get (value: 0) to trigger disappearing animation\n      return arcs.value.map(item => {\n        return isVisible(item)\n          ? item\n          : { ...item, value: 0 }\n      })\n    })\n\n    const total = computed(() => visibleItems.value.reduce((sum, item) => sum + item.value, 0))\n\n    const gaugeCut = toRef(() => Number(props.gaugeCut ?? 0))\n    const gaugeOffset = computed(() => (1 - Math.cos(Math.PI * Math.min(90, gaugeCut.value / 2) / 180)) / 2)\n    const rotateDeg = computed(() => `${gaugeCut.value ? (180 + gaugeCut.value / 2) : (props.rotate ?? 0)}deg`)\n\n    function arcOffset (index: number) {\n      return visibleItems.value\n        .slice(0, index)\n        .reduce((acc, s) => acc + (total.value > 0 ? s.value / total.value : 0) * (360 - gaugeCut.value), 0)\n    }\n\n    function arcSize (v: number) { return v / total.value * (100 - gaugeCut.value / 3.6) }\n\n    function colorFromPalette (index: number) {\n      if (props.palette.length === 0) return undefined\n      const paletteItem = props.palette[index % props.palette.length]\n      return typeof paletteItem === 'object' ? paletteItem.color : paletteItem\n    }\n\n    function patternFromPalette (index: number) {\n      if (props.palette.length === 0) return undefined\n      const paletteItem = props.palette[index % props.palette.length]\n      return typeof paletteItem === 'object' ? paletteItem.pattern : undefined\n    }\n\n    function isVisible (item: PieItem) {\n      return visibleItemsKeys.value.includes(item.key)\n    }\n\n    function toggle (item: PieItem) {\n      if (isVisible(item)) {\n        visibleItemsKeys.value = visibleItemsKeys.value.filter(x => x !== item.key)\n      } else {\n        visibleItemsKeys.value = [...visibleItemsKeys.value, item.key]\n      }\n    }\n\n    const tooltipItem = shallowRef<PieItem | null>(null)\n    const tooltipVisible = shallowRef(false)\n    const tooltipTarget = shallowRef<[x: number, y: number]>([0, 0])\n\n    let mouseLeaveTimeout = null! as ReturnType<typeof setTimeout>\n\n    function setItemActive (item: PieItem, active: boolean) {\n      arcs.value.forEach(a => a.isActive = a.key === item.key && active)\n\n      if (props.tooltip) {\n        setTooltip(item, active)\n      }\n    }\n\n    function setTooltip (item: PieItem, active: boolean) {\n      clearTimeout(mouseLeaveTimeout)\n\n      if (active) {\n        tooltipVisible.value = true\n        tooltipItem.value = item\n      } else {\n        mouseLeaveTimeout = setTimeout(() => {\n          tooltipVisible.value = false\n\n          // intentionally reusing timeout here\n          mouseLeaveTimeout = setTimeout(() => {\n            tooltipItem.value = null\n          }, 500)\n        }, 100)\n      }\n    }\n\n    let frame = -1\n    function onSvgMousemove ({ clientX, clientY }: MouseEvent) {\n      cancelAnimationFrame(frame)\n      frame = requestAnimationFrame(() => {\n        tooltipTarget.value = [clientX, clientY]\n      })\n    }\n\n    function onSvgTouchstart ({ touches }: TouchEvent) {\n      if (!touches) return\n      const { clientX, clientY } = touches[0]\n      tooltipTarget.value = [clientX, clientY]\n    }\n\n    function onSvgClickOutside () {\n      arcs.value.forEach(a => a.isActive = false)\n      tooltipVisible.value = false\n    }\n\n    return () => {\n      const segmentProps = pick(props, [\n        'animation',\n        'gap',\n        'rounded',\n        'hideSlice',\n        'reveal',\n        'innerCut',\n        'hoverScale',\n      ])\n\n      const defaultTooltipTransition = {\n        name: 'fade-transition',\n        duration: 150,\n      }\n\n      const tooltipProps = {\n        item: tooltipItem.value,\n        modelValue: tooltipVisible.value,\n        titleFormat: typeof props.tooltip === 'object' ? props.tooltip.titleFormat : '[title]',\n        subtitleFormat: typeof props.tooltip === 'object' ? props.tooltip.subtitleFormat : '[value]',\n        transition: typeof props.tooltip === 'object' ? props.tooltip.transition : defaultTooltipTransition,\n        offset: typeof props.tooltip === 'object' ? props.tooltip.offset : 16,\n        target: tooltipTarget.value,\n      }\n\n      const legendDefaults = {\n        VChipGroup: {\n          direction: legendDirection.value,\n        },\n        VChip: {\n          density: props.density,\n        },\n        VAvatar: {\n          size: legendAvatarSize.value,\n        },\n      }\n\n      const tooltipDefaults = {\n        VAvatar: {\n          size: typeof props.tooltip === 'object' ? (props.tooltip.avatarSize ?? 28) : 28,\n        },\n      }\n\n      const avatarSlot = ({ item }: { item: PieItem }) => (\n        <VAvatar color={ item.color } start>\n          { item.pattern && (\n            <svg height=\"40\" width=\"40\">\n              <rect width=\"40\" height=\"40\" fill={ item.pattern } />\n            </svg>\n          )}\n        </VAvatar>\n      )\n\n      return (\n        <div\n          class={[\n            'v-pie',\n            `v-pie--legend-${legendMode.value}`,\n          ]}\n          style={{\n            '--v-pie-size': convertToUnit(props.size),\n          }}\n        >\n          { slots.title?.() ?? (props.title && (<div class=\"v-pie__title\">{ props.title }</div>)) }\n          <div\n            class={[\n              'v-pie__content',\n              colorClasses.value,\n            ]}\n            style={[\n              {\n                transform: `rotate(${rotateDeg.value})`,\n                marginBottom: `calc(-1 * ${convertToUnit(props.size)} * ${gaugeOffset.value})`,\n              },\n              textColorStyles.value,\n            ]}\n          >\n            <div\n              class={[\n                'v-pie__content-underlay',\n                colorClasses.value,\n              ]}\n              style={ colorStyles.value }\n            />\n            <svg\n              xmlns=\"http://www.w3.org/2000/svg\"\n              viewBox=\"0 0 100 100\"\n              class=\"v-pie__segments\"\n              onMousemove={ onSvgMousemove }\n              onTouchstart={ onSvgTouchstart }\n              v-click-outside={{ handler: onSvgClickOutside }}\n            >\n              { arcs.value.map((item, index) => (\n                <VPieSegment\n                  { ...segmentProps }\n                  key={ item.key }\n                  active={ item.isActive }\n                  color={ item.color }\n                  value={ isVisible(item) ? arcSize(item.value) : 0 }\n                  rotate={ arcOffset(index) }\n                  pattern={ item.pattern }\n                  onUpdate:active={ val => setItemActive(item, val) }\n                  onTouchend={ () => setItemActive(item, true) }\n                />\n              ))}\n            </svg>\n\n            <div\n              class=\"v-pie__center-content\"\n              style={{\n                transform: `translate(-50%, -50%)\n                  rotate(-${rotateDeg.value})\n                  translateY(calc(-100% * ${gaugeOffset.value}))`,\n              }}\n            >\n              <div>\n                { slots.center?.({ total: total.value }) }\n              </div>\n            </div>\n          </div>\n\n          { legendConfig.value.visible && (\n            <VDefaultsProvider key=\"legend\" defaults={ legendDefaults }>\n              <div class=\"v-pie__legend\">\n                { slots.legend?.({ isActive: isVisible, toggle, items: arcs.value, total: total.value }) ?? (\n                  <VChipGroup\n                    column\n                    multiple\n                    v-model={ visibleItemsKeys.value }\n                  >\n                    { arcs.value.map(item => (\n                      <VChip\n                        value={ item.key }\n                        v-slots={{\n                          prepend: () => avatarSlot({ item }),\n                          default: () => (\n                            <div class=\"v-pie__legend__text\">\n                              { slots['legend-text']?.({ item, total: total.value }) ?? legendTextFormatFunction.value(item) }\n                            </div>\n                          ),\n                        }}\n                      />\n                    ))}\n                  </VChipGroup>\n                )}\n              </div>\n            </VDefaultsProvider>\n          )}\n          { !!props.tooltip && (\n            <VDefaultsProvider defaults={ tooltipDefaults }>\n              <VPieTooltip\n                { ...tooltipProps }\n                v-slots={{\n                  default: slots.tooltip ? slotProps => slots.tooltip?.({ ...slotProps, total: total.value }) : undefined,\n                  prepend: avatarSlot,\n                }}\n              />\n            </VDefaultsProvider>\n          )}\n        </div>\n      )\n    }\n  },\n})\n\nexport type VPie = InstanceType<typeof VPie>\n"
  },
  {
    "path": "packages/vuetify/src/labs/VPie/VPieSegment.tsx",
    "content": "// Composables\nimport { useProxiedModel } from '@/composables/proxiedModel'\nimport { makeRevealProps, useReveal } from '@/composables/reveal'\n\n// Utilities\nimport { computed, toRef } from 'vue'\nimport { useInnerSlicePath, useOuterSlicePath, usePieArc } from './utils'\nimport { easingPatterns, genericComponent, propsFactory, useTransition } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\nexport const makeVPieSegmentProps = propsFactory({\n  active: Boolean,\n  rotate: [Number, String],\n  value: {\n    type: Number,\n    default: 0,\n  },\n  color: String,\n  innerCut: [Number, String],\n  hoverScale: {\n    type: [Number, String],\n    default: 0.05,\n  },\n  gap: [Number, String],\n  rounded: [Number, String],\n  animation: {\n    type: [Boolean, Object] as PropType<boolean | {\n      duration?: number\n      easing?: keyof typeof easingPatterns\n    }>,\n    default: false,\n  },\n  pattern: String,\n  hideSlice: Boolean,\n  ...makeRevealProps(),\n}, 'VPieSegment')\n\nexport const VPieSegment = genericComponent()({\n  name: 'VPieSegment',\n\n  props: makeVPieSegmentProps(),\n\n  emits: {\n    'update:active': (val: boolean) => true,\n  },\n\n  setup (props) {\n    const isActive = useProxiedModel(props, 'active')\n\n    const { state: revealState, duration: revealDuration } = useReveal(props)\n\n    const transitionConfig = computed(() => {\n      const defaultEasing = 'easeInOutCubic'\n      const defaultDuration = 400\n\n      const easingName = typeof props.animation === 'object'\n        ? props.animation.easing ?? defaultEasing\n        : defaultEasing\n\n      return {\n        duration: ['initial', 'pending'].includes(revealState.value)\n          ? revealDuration.value\n          : typeof props.animation === 'object'\n            ? props.animation.duration\n            : (props.animation ? defaultDuration : 0),\n        transition: easingPatterns[easingName],\n      }\n    })\n\n    const {\n      hoverZoomRatio,\n      normalizedValue,\n      normalizedInnerCut,\n      outerX,\n      outerY,\n      arcWidth,\n    } = usePieArc(props, isActive)\n\n    const arcSize = toRef(() => revealState.value === 'initial' ? 0 : normalizedValue.value)\n    const currentArcSize = useTransition(arcSize, transitionConfig)\n\n    const angle = toRef(() => revealState.value === 'initial' ? 0 : (Number(props.rotate ?? 0) + Number(props.gap ?? 0) / 2))\n    const currentAngle = useTransition(angle, transitionConfig)\n\n    const arcRadius = toRef(() => 50 * (isActive.value ? 1 : (1 - hoverZoomRatio.value)))\n    const currentArcRadius = useTransition(arcRadius, transitionConfig)\n    const currentArcWidth = useTransition(arcWidth, transitionConfig)\n\n    const outerSlicePath = useOuterSlicePath({\n      angle: currentAngle,\n      radius: currentArcRadius,\n      size: currentArcSize,\n      width: currentArcWidth,\n      rounded: () => Number(props.rounded ?? 0),\n    })\n\n    const innerSlicePath = useInnerSlicePath({\n      angle: currentAngle,\n      radius: () => currentArcRadius.value - currentArcWidth.value,\n      size: currentArcSize,\n    })\n\n    const overlayPath = toRef(() => `M 50 0 A 50 50 0 ${normalizedValue.value > 50 ? 1 : 0} 1 ${outerX.value} ${outerY.value} L 50 50`)\n\n    return () => (\n      <g\n        class=\"v-pie-segment\"\n        style={{ color: props.color }}\n      >\n        <path\n          key=\"outer-slice\"\n          fill=\"currentColor\"\n          shape-rendering=\"geometricPrecision\"\n          d={ outerSlicePath.value }\n        />\n        { props.pattern && (\n          <path\n            key=\"pattern-overlay\"\n            shape-rendering=\"geometricPrecision\"\n            fill={ props.pattern }\n            d={ outerSlicePath.value }\n          />\n        )}\n        { !props.hideSlice && normalizedInnerCut.value > 0 && (\n          <path\n            key=\"inner-slice\"\n            fill=\"oklch(from currentColor l c h / calc(alpha / 2))\"\n            d={ innerSlicePath.value }\n          />\n        )}\n        {['disabled', 'done'].includes(revealState.value) && (\n          <path\n            transform={ `rotate(${currentAngle.value} 50 50)` }\n            class=\"v-pie-segment__overlay\"\n            d={ overlayPath.value }\n            onMouseenter={ () => isActive.value = true }\n            onMouseleave={ () => isActive.value = false }\n          />\n        )}\n      </g>\n    )\n  },\n})\n\nexport type VPieSegment = InstanceType<typeof VPieSegment>\n"
  },
  {
    "path": "packages/vuetify/src/labs/VPie/VPieTooltip.tsx",
    "content": "// Components\nimport { VListItem } from '@/components/VList/VListItem'\nimport { makeVTooltipProps, VTooltip } from '@/components/VTooltip/VTooltip'\n\n// Composables\nimport { makeTransitionProps, MaybeTransition } from '@/composables/transition'\n\n// Utilities\nimport { toRef } from 'vue'\nimport { formatTextTemplate } from './utils'\nimport { genericComponent, pick, propsFactory } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { PieItem, TextTemplate } from './types'\n\nexport type VPieTooltipSlots = {\n  default: { item: PieItem }\n  prepend: { item: PieItem }\n}\n\nexport const makeVPieTooltipProps = propsFactory({\n  modelValue: Boolean,\n  target: Object as PropType<[x: number, y: number]>,\n  item: {\n    type: Object as PropType<PieItem | null>,\n    default: null,\n  },\n  titleFormat: {\n    type: [String, Function] as PropType<TextTemplate>,\n    default: '[title]',\n  },\n  subtitleFormat: {\n    type: [String, Function] as PropType<TextTemplate>,\n    default: '[value]',\n  },\n  ...makeTransitionProps(),\n  ...pick(makeVTooltipProps(), ['offset']),\n}, 'VPieTooltip')\n\nexport const VPieTooltip = genericComponent<VPieTooltipSlots>()({\n  name: 'VPieTooltip',\n\n  props: makeVPieTooltipProps(),\n\n  setup (props, { slots }) {\n    const tooltipTitleFormatFunction = toRef(() => (segment: PieItem) => {\n      return typeof props.titleFormat === 'function'\n        ? props.titleFormat(segment)\n        : formatTextTemplate(props.titleFormat, segment)\n    })\n\n    const tooltipSubtitleFormatFunction = toRef(() => (segment: PieItem) => {\n      return typeof props.subtitleFormat === 'function'\n        ? props.subtitleFormat(segment)\n        : formatTextTemplate(props.subtitleFormat, segment)\n    })\n\n    return () => (\n      <VTooltip\n        offset={ props.offset }\n        modelValue={ props.modelValue }\n        target={ props.target }\n        contentClass=\"v-pie__tooltip-content\"\n      >\n        { !!props.item && (\n          slots.default?.({ item: props.item }) ?? (\n            <MaybeTransition transition={ props.transition } mode=\"out-in\">\n              <VListItem\n                key={ props.item.key }\n                density=\"compact\"\n                title={ tooltipTitleFormatFunction.value(props.item) }\n                subtitle={ tooltipSubtitleFormatFunction.value(props.item) }\n                v-slots={{\n                  prepend: slots.prepend\n                    ? () => slots.prepend!({ item: props.item! })\n                    : undefined,\n                }}\n              />\n            </MaybeTransition>\n          )\n        )}\n      </VTooltip>\n    )\n  },\n})\n\nexport type VPieTooltip = InstanceType<typeof VPieTooltip>\n"
  },
  {
    "path": "packages/vuetify/src/labs/VPie/__tests__/pie-arc.spec.ts",
    "content": "// Composables\nimport { usePieArc } from '../utils'\n\n// Utilities\nimport { ref } from 'vue'\n\ndescribe('usePieArc', () => {\n  it.each([\n    [{ innerCut: 0, value: 25, hoverScale: 0 }, { x: 100, y: 50, arcWidth: 50 }],\n    [{ innerCut: 25, value: 25, hoverScale: 0 }, { x: 100, y: 50, arcWidth: 37.5 }],\n    [{ innerCut: 75, value: 25, hoverScale: 0 }, { x: 100, y: 50, arcWidth: 12.5 }],\n    [{ innerCut: 0, value: 66, hoverScale: 0 }, { x: 7.78, y: 76.79, arcWidth: 50 }],\n    [{ innerCut: 70, value: 25, hoverScale: 0.2 }, { x: 100, y: 50, arcWidth: 12 }],\n    [{ innerCut: 50, value: 75, hoverScale: 0.2 }, { x: 0, y: 50, arcWidth: 20 }],\n  ])('should correctly calculate arc properties', (props, expected) => {\n    const isHovering = ref(false)\n    const { outerX, outerY, arcWidth } = usePieArc({\n      innerCut: props.innerCut ?? 0,\n      value: props.value!,\n      hoverScale: props.hoverScale ?? 0,\n      gap: 0,\n      rounded: 0,\n    }, isHovering)\n\n    expect(outerX.value).toBeCloseTo(expected.x, 2)\n    expect(outerY.value).toBeCloseTo(expected.y, 2)\n    expect(arcWidth.value).toBeCloseTo(expected.arcWidth, 2)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/labs/VPie/_variables.scss",
    "content": "@use '../../styles/settings';\n@use '../../styles/tools';\n\n$pie-underlay-inset: -8px !default;\n$pie-title-padding-bottom: 12px !default;\n$pie-legend-padding-block: 12px !default;\n$pie-legend-chip-default-font-size: 0.8125rem !default;\n$pie-legend-chip-compact-font-size: 0.66rem !default;\n$pie-legend-chip-disabled-opacity: .4 !default;\n$pie-legend-avatar-border: thin solid tools.theme-color('on-surface', .2) !default;\n$pie-tooltip-min-width: 100px !default;\n$pie-tooltip-avatar-border: thin solid tools.theme-color('on-surface-variant', .2) !default;\n"
  },
  {
    "path": "packages/vuetify/src/labs/VPie/index.ts",
    "content": "export { VPie } from './VPie'\nexport { VPieSegment } from './VPieSegment'\nexport { VPieTooltip } from './VPieTooltip'\n"
  },
  {
    "path": "packages/vuetify/src/labs/VPie/types.ts",
    "content": "export interface PieItem {\n  key: string | number | symbol\n  color: string\n  value: number\n  title: string\n  pattern?: string\n  isActive: boolean\n  raw?: Record<string, any>\n}\n\nexport interface PieSegmentProps {\n  gap?: number | string\n  hoverScale?: number | string\n  innerCut?: number | string\n  rounded?: number | string\n  value: number\n}\n\nexport type TextTemplate = string | ((v: PieItem) => string)\n"
  },
  {
    "path": "packages/vuetify/src/labs/VPie/utils.ts",
    "content": "// Utilities\nimport { computed, toRef, toValue } from 'vue'\nimport { clamp } from '@/util'\nimport { roundedArc, simpleArc } from '@/util/svg-arc-corners'\n\n// Types\nimport type { MaybeRefOrGetter, Ref } from 'vue'\nimport type { PieItem, PieSegmentProps } from './types'\n\nexport function formatTextTemplate (template: string, item?: PieItem) {\n  return item\n    ? template\n      .replaceAll('[title]', item.title)\n      .replaceAll('[value]', String(item.value))\n    : undefined\n}\n\nexport function usePieArc (props: PieSegmentProps, isHovering: Ref<boolean>) {\n  const hoverZoomRatio = toRef(() => clamp(Number(props.hoverScale ?? 0), 0, 0.25))\n  const normalizedValue = toRef(() => clamp(props.value - 100 * Number(props.gap ?? 0) / 360, 0.01, 99.99))\n  const normalizedInnerCut = toRef(() => {\n    const min = Number(props.rounded ?? 0) > 0 ? 0.2 : 0\n    return clamp(Number(props.innerCut ?? 0) / 100, min, 1)\n  })\n\n  const radians = computed(() => (360 * (-normalizedValue.value / 100) + 90) * (Math.PI / 180))\n  const arcWidth = computed(() => 50 * (1 - normalizedInnerCut.value) * (isHovering.value ? 1 : (1 - hoverZoomRatio.value)))\n\n  const outerX = toRef(() => 50 + 50 * Math.cos(radians.value))\n  const outerY = toRef(() => 50 - 50 * Math.sin(radians.value))\n\n  return {\n    hoverZoomRatio,\n    normalizedValue,\n    normalizedInnerCut,\n    outerX,\n    outerY,\n    arcWidth,\n  }\n}\n\nexport function useOuterSlicePath ({\n  angle,\n  radius,\n  size,\n  width,\n  rounded,\n}: {\n  angle: MaybeRefOrGetter<number>\n  radius: MaybeRefOrGetter<number>\n  size: MaybeRefOrGetter<number>\n  width: MaybeRefOrGetter<number>\n  rounded: MaybeRefOrGetter<number>\n}) {\n  return computed(() =>\n    roundedArc(\n      [50, 50],\n      toValue(radius),\n      toValue(angle),\n      toValue(angle) + 360 * toValue(size) / 100, // angle end,\n      toValue(width),\n      toValue(rounded),\n    )\n  )\n}\n\nexport function useInnerSlicePath ({\n  angle,\n  radius,\n  size,\n}: {\n  angle: MaybeRefOrGetter<number>\n  radius: MaybeRefOrGetter<number>\n  size: MaybeRefOrGetter<number>\n}) {\n  return computed(() =>\n    simpleArc(\n      [50, 50],\n      toValue(radius),\n      toValue(angle),\n      toValue(angle) + 360 * toValue(size) / 100, // angle end,\n    )\n  )\n}\n"
  },
  {
    "path": "packages/vuetify/src/labs/VProgress/VProgress.sass",
    "content": "@use '../../styles/tools'\n\n@include tools.layer('components')\n  .v-progress\n    display: flex\n    flex-direction: column\n    gap: 8px\n\n    > .v-progress-circular\n      align-self: center\n\n    &:has(> .v-progress-circular) > .v-progress__details > *:only-child\n      margin-inline: auto\n\n    &__label\n      overflow: hidden\n      text-overflow: ellipsis\n      white-space: nowrap\n\n      + .v-progress__value\n        margin-inline-start: auto\n\n    &__details\n      display: flex\n      align-items: flex-end\n      gap: 8px\n\n      &--location-bottom\n        align-items: flex-start\n        order: 1\n\n    &--absolute\n      position: absolute\n      inset: 0\n      align-items: center\n      justify-content: center\n\n      > .v-progress__details\n        height: 0\n        overflow: visible\n\n      > .v-progress__spacer\n        height: 0"
  },
  {
    "path": "packages/vuetify/src/labs/VProgress/VProgress.tsx",
    "content": "// Styles\nimport './VProgress.sass'\n\n// Components\nimport { VProgressCircular } from '@/components/VProgressCircular/VProgressCircular'\nimport { makeVProgressLinearProps, VProgressLinear } from '@/components/VProgressLinear/VProgressLinear'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\n\n// Utilities\nimport { computed, toRef } from 'vue'\nimport { clamp, genericComponent, omit, pick, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\nexport type ValueFormat = string | ((ctx: { value: number, max: number, percent: number }) => string)\n\ntype VProgressSlotsProps = {\n  max: number\n  percent: number\n  value: number\n  formattedValue: string\n}\n\ntype VProgressSlots = {\n  default: VProgressSlotsProps\n  label: VProgressSlotsProps\n  value: VProgressSlotsProps\n}\n\nexport const makeVProgressProps = propsFactory({\n  type: {\n    type: String as PropType<'linear' | 'circular'>,\n    default: 'linear',\n  },\n  label: String,\n  detailsPosition: {\n    type: String as PropType<'top' | 'bottom'>,\n    default: 'top',\n  },\n  valueFormat: {\n    type: [String, Function] as PropType<ValueFormat>,\n    default: '[percent]%',\n  },\n  max: {\n    type: [Number, String],\n    default: 100,\n  },\n  absolute: Boolean,\n  hideLabel: Boolean,\n  hideValue: Boolean,\n  indeterminate: Boolean,\n  rounded: Boolean,\n\n  ...pick(makeVProgressLinearProps(), [\n    // relevant props shared between linear and circular\n    'modelValue',\n    'color',\n    'bgColor',\n    'theme',\n  ]),\n  ...makeComponentProps(),\n}, 'VProgress')\n\nfunction formatValue (format: ValueFormat, value: number, max: number, percent: number): string {\n  if (typeof format === 'function') return format({ value, max, percent })\n  return format\n    .replaceAll('[value]', String(value))\n    .replaceAll('[max]', String(max))\n    .replaceAll('[percent]', String(Math.round(percent)))\n}\n\nexport const VProgress = genericComponent<VProgressSlots>()({\n  name: 'VProgress',\n\n  props: makeVProgressProps(),\n\n  setup (props, { slots }) {\n    const isLinear = toRef(() => props.type === 'linear')\n    const max = toRef(() => parseFloat(props.max as string) || 100)\n    const normalizedValue = computed(() => clamp(parseFloat(props.modelValue), 0, max.value))\n    const percent = computed(() => normalizedValue.value / max.value * 100)\n    const formattedValue = toRef(() => formatValue(props.valueFormat, normalizedValue.value, max.value, percent.value))\n\n    useRender(() => {\n      const hasDetails = !!(props.label || slots.label) && !(props.hideLabel && props.hideValue)\n      const scopeProps = {\n        max: max.value,\n        percent: percent.value,\n        value: normalizedValue.value,\n        formattedValue: formattedValue.value,\n      }\n\n      const progressProps = {\n        role: 'progressbar' as const,\n        'aria-label': props.label,\n        'aria-valuenow': props.indeterminate ? undefined : normalizedValue.value,\n        'aria-valuemin': 0,\n        'aria-valuemax': max.value,\n        'aria-valuetext': props.indeterminate ? undefined : formattedValue.value,\n      }\n\n      function progressComponent () {\n        if (isLinear.value) {\n          const linearProps = VProgressLinear.filterProps(props)\n          return (\n            <VProgressLinear\n              { ...linearProps }\n              modelValue={ props.modelValue }\n              aria-hidden=\"true\"\n            />\n          )\n        }\n\n        const circularProps = VProgressCircular.filterProps(omit(props, ['indeterminate']))\n        return (\n          <VProgressCircular\n            { ...circularProps }\n            modelValue={ percent.value }\n            aria-hidden=\"true\"\n            indeterminate={ props.indeterminate }\n          />\n        )\n      }\n\n      return (\n        <div\n          class={[\n            'v-progress',\n            {\n              'v-progress--absolute': props.absolute,\n            },\n            props.class,\n          ]}\n          style={ props.style }\n          { ...progressProps }\n        >\n          { hasDetails && (\n            <div\n              key=\"details\"\n              class={[\n                'v-progress__details',\n                `v-progress__details--location-${props.detailsPosition}`,\n              ]}\n              aria-hidden=\"true\"\n            >\n              { !props.hideLabel && (\n                <div key=\"label\" class=\"v-progress__label\">\n                  { slots.label?.(scopeProps) ?? props.label }\n                </div>\n              )}\n              { !props.hideValue && (\n                <div key=\"value\" class=\"v-progress__value\">\n                  { slots.value?.(scopeProps) ?? formattedValue.value }\n                </div>\n              )}\n            </div>\n          )}\n          { slots.default?.(scopeProps) ?? progressComponent() }\n          { props.absolute && hasDetails && (\n            <div\n              key=\"spacer\"\n              class=\"v-progress__spacer\"\n              style={{ order: props.detailsPosition === 'bottom' ? -1 : 2 }}\n            />\n          )}\n        </div>\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VProgress = InstanceType<typeof VProgress>\n"
  },
  {
    "path": "packages/vuetify/src/labs/VProgress/index.ts",
    "content": "export { VProgress } from './VProgress'\n"
  },
  {
    "path": "packages/vuetify/src/labs/VPullToRefresh/VPullToRefresh.sass",
    "content": ".v-pull-to-refresh\n  overflow: hidden\n  position: relative\n  &__pull-down\n    position: absolute\n    width: 100%\n    transition: top .3s ease-out\n    &--touching\n      transition: none\n\n  &__pull-down-default\n    display: flex\n    width: 100%\n    height: 100%\n    justify-content: center\n    align-items: flex-end\n    padding-bottom: 10px\n\n  &__scroll-container\n    position: relative\n    transition: top .3s ease-out\n    &--touching\n      transition: none\n"
  },
  {
    "path": "packages/vuetify/src/labs/VPullToRefresh/VPullToRefresh.tsx",
    "content": "// Styles\nimport './VPullToRefresh.sass'\n\n// Components\nimport { VIcon } from '@/components/VIcon'\nimport { VProgressCircular } from '@/components/VProgressCircular'\n\n// Utilities\nimport { computed, onMounted, ref, shallowRef, watch } from 'vue'\nimport { clamp, convertToUnit, genericComponent, getScrollParents, useRender } from '@/util'\n\nexport type VPullToRefreshSlots = {\n  default: never\n  pullDownPanel: {\n    canRefresh: boolean\n    goingUp: boolean\n    refreshing: boolean\n  }\n}\n\nexport const VPullToRefresh = genericComponent<VPullToRefreshSlots>()({\n  name: 'VPullToRefresh',\n\n  props: {\n    disabled: Boolean,\n    pullDownThreshold: {\n      type: Number,\n      default: 64,\n    },\n  },\n\n  emits: {\n    load: (options: { done: () => void }) => true,\n  },\n\n  setup (props, { slots, emit }) {\n    let touchstartY = 0\n    let scrollParents: HTMLElement[] = []\n\n    const touchDiff = shallowRef(0)\n    const containerRef = ref<HTMLElement>()\n\n    const refreshing = shallowRef(false)\n    const goingUp = shallowRef(false)\n    const touching = shallowRef(false)\n\n    const canRefresh = computed(() => touchDiff.value >= props.pullDownThreshold && !refreshing.value)\n    const topOffset = computed(() => clamp(touchDiff.value, 0, props.pullDownThreshold))\n\n    function onTouchstart (e: TouchEvent | MouseEvent) {\n      if (refreshing.value || props.disabled) return\n      touching.value = true\n      touchstartY = 'clientY' in e ? e.clientY : e.touches[0].clientY\n    }\n\n    function onTouchmove (e: TouchEvent | MouseEvent) {\n      if (refreshing.value || !touching.value || props.disabled) return\n\n      const touchY = 'clientY' in e ? e.clientY : e.touches[0].clientY\n\n      if (scrollParents.length && !scrollParents[0].scrollTop) {\n        touchDiff.value = touchY - touchstartY\n      }\n    }\n\n    function onTouchend (e: TouchEvent | MouseEvent) {\n      if (refreshing.value || props.disabled) return\n      touching.value = false\n      if (canRefresh.value) {\n        function done () {\n          if (!refreshing.value) return\n          touchDiff.value = 0\n          refreshing.value = false\n        }\n        emit('load', { done })\n        refreshing.value = true\n      } else {\n        touchDiff.value = 0\n      }\n    }\n\n    onMounted(() => {\n      scrollParents = getScrollParents(containerRef.value)\n    })\n\n    watch([topOffset, refreshing], () => {\n      if (scrollParents.length) {\n        const stopScrolling = topOffset.value && !refreshing.value\n        scrollParents.forEach(p => p.style.overflow = stopScrolling ? 'hidden' : 'auto')\n      }\n    })\n\n    watch(topOffset, (newVal, oldVal) => {\n      goingUp.value = newVal < oldVal\n    })\n\n    useRender(() => {\n      return (\n        <div\n          class={[\n            'v-pull-to-refresh',\n          ]}\n          onTouchstart={ onTouchstart }\n          onTouchmove={ onTouchmove }\n          onTouchend={ onTouchend }\n          onMousedown={ onTouchstart }\n          onMouseup={ onTouchend }\n          onMouseleave={ onTouchend }\n          onMousemove={ onTouchmove }\n          ref={ containerRef }\n        >\n          <div\n            class={[\n              'v-pull-to-refresh__pull-down',\n              {\n                'v-pull-to-refresh__pull-down--touching': touching.value,\n              },\n            ]}\n            style={{\n              top: convertToUnit(-1 * props.pullDownThreshold + topOffset.value),\n              height: convertToUnit(props.pullDownThreshold),\n            }}\n          >\n            { slots.pullDownPanel\n              ? slots.pullDownPanel({\n                canRefresh: canRefresh.value,\n                goingUp: goingUp.value,\n                refreshing: refreshing.value,\n              }) : (\n                <div\n                  class={[\n                    'v-pull-to-refresh__pull-down-default',\n                  ]}\n                >\n                  {\n                    refreshing.value ? (\n                      <VProgressCircular\n                        indeterminate\n                        active={ false }\n                      />\n                    ) : (\n                      <VIcon\n                        icon={ canRefresh.value || goingUp.value ? '$sortAsc' : '$sortDesc' }\n                      />\n                    )\n                  }\n                </div>\n              )\n            }\n          </div>\n          <div\n            class={[\n              'v-pull-to-refresh__scroll-container',\n              {\n                'v-pull-to-refresh__scroll-container--touching': touching.value,\n              },\n            ]}\n            style={{ top: convertToUnit(topOffset.value) }}\n          >\n            { slots.default?.() }\n          </div>\n        </div>\n      )\n    })\n  },\n})\n\nexport type VPullToRefresh = InstanceType<typeof VPullToRefresh>\n"
  },
  {
    "path": "packages/vuetify/src/labs/VPullToRefresh/index.ts",
    "content": "export { VPullToRefresh } from './VPullToRefresh'\n"
  },
  {
    "path": "packages/vuetify/src/labs/VStepperVertical/VStepperVertical.tsx",
    "content": "// Components\nimport { VStepperVerticalItem } from './VStepperVerticalItem'\nimport { makeVExpansionPanelsProps, VExpansionPanels } from '@/components/VExpansionPanel/VExpansionPanels'\nimport { makeStepperProps } from '@/components/VStepper/VStepper'\n\n// Composables\nimport { provideDefaults } from '@/composables/defaults'\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { computed, ref, toRefs } from 'vue'\nimport { genericComponent, getPropertyFromItem, omit, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { StepperVerticalItemActionSlot } from './VStepperVerticalItem'\nimport type { VStepperSlot } from '@/components/VStepper/VStepper'\nimport type { StepperItemSlot } from '@/components/VStepper/VStepperItem'\nimport type { GenericProps } from '@/util'\n\nexport type VStepperVerticalSlots<T> = {\n  actions: StepperVerticalItemActionSlot<T>\n  default: VStepperSlot & { step: T }\n  icon: StepperItemSlot<T>\n  title: StepperItemSlot<T>\n  subtitle: StepperItemSlot<T>\n  prev: StepperVerticalItemActionSlot<T>\n  next: StepperVerticalItemActionSlot<T>\n} & {\n  [key: `header-item.${string}`]: StepperItemSlot<T>\n  [key: `item.${string}`]: StepperItemSlot<T>\n}\n\nexport const makeVStepperVerticalProps = propsFactory({\n  prevText: {\n    type: String,\n    default: '$vuetify.stepper.prev',\n  },\n  nextText: {\n    type: String,\n    default: '$vuetify.stepper.next',\n  },\n\n  ...makeStepperProps(),\n  ...omit(makeVExpansionPanelsProps({\n    mandatory: 'force' as const,\n    variant: 'accordion' as const,\n  }), ['static']),\n}, 'VStepperVertical')\n\nexport const VStepperVertical = genericComponent<new <T = number>(\n  props: {\n    modelValue?: T\n    'onUpdate:modelValue'?: (value: T) => void\n  },\n  slots: VStepperVerticalSlots<T>,\n) => GenericProps<typeof props, typeof slots>>()({\n  name: 'VStepperVertical',\n\n  props: makeVStepperVerticalProps(),\n\n  emits: {\n    'update:modelValue': (val: any) => true,\n  },\n\n  setup (props, { slots }) {\n    const vExpansionPanelsRef = ref<typeof VExpansionPanels>()\n    const { color, eager, editable, prevText, nextText, hideActions } = toRefs(props)\n\n    const model = useProxiedModel(props, 'modelValue')\n    const items = computed(() => props.items.map((item, index) => {\n      const title = getPropertyFromItem(item, props.itemTitle, item)\n      const value = getPropertyFromItem(item, props.itemValue, index + 1)\n      const itemProps = props.itemProps === true\n        ? item\n        : getPropertyFromItem(item, props.itemProps)\n\n      const _props = {\n        title,\n        value,\n        ...itemProps,\n      }\n\n      return {\n        title: _props.title,\n        value: _props.value,\n        props: _props,\n        raw: item,\n      }\n    }))\n\n    provideDefaults({\n      VStepperVerticalItem: {\n        color,\n        eager,\n        editable,\n        hideActions,\n        static: true,\n      },\n      VStepperVerticalActions: {\n        color,\n        nextText,\n        prevText,\n      },\n    })\n\n    useRender(() => {\n      const expansionPanelProps = VExpansionPanels.filterProps(props)\n\n      return (\n        <VExpansionPanels\n          { ...expansionPanelProps }\n          v-model={ model.value }\n          ref={ vExpansionPanelsRef }\n          class={[\n            'v-stepper',\n            {\n              'v-stepper--alt-labels': props.altLabels,\n              'v-stepper--flat': props.flat,\n              'v-stepper--non-linear': props.nonLinear,\n              'v-stepper--mobile': props.mobile,\n            },\n            props.class,\n          ]}\n          style={ props.style }\n        >\n          {{\n            ...slots,\n            default: ({ prev, next }) => {\n              return (\n                <>\n                  { items.value.map(({ raw, ...item }) => (\n                    <VStepperVerticalItem { ...item.props }>\n                      {{\n                        ...slots,\n                        default: slots[`item.${item.value}`],\n                      }}\n                    </VStepperVerticalItem>\n                  ))}\n\n                  { slots.default?.({ prev, next, step: model.value }) }\n                </>\n              )\n            },\n          }}\n        </VExpansionPanels>\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VStepperVertical = InstanceType<typeof VStepperVertical>\n"
  },
  {
    "path": "packages/vuetify/src/labs/VStepperVertical/VStepperVerticalActions.tsx",
    "content": "// Components\nimport { makeVStepperActionsProps, VStepperActions } from '@/components/VStepper/VStepperActions'\n\n// Utilities\nimport { genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { VStepperActionsSlots } from '@/components/VStepper/VStepperActions'\n\nexport const makeVStepperVerticalActionsProps = propsFactory({\n  ...makeVStepperActionsProps(),\n}, 'VStepperActions')\n\nexport const VStepperVerticalActions = genericComponent<VStepperActionsSlots>()({\n  name: 'VStepperVerticalActions',\n\n  props: makeVStepperVerticalActionsProps(),\n\n  emits: {\n    'click:prev': () => true,\n    'click:next': () => true,\n  },\n\n  setup (props, { emit, slots }) {\n    function onClickPrev () {\n      emit('click:prev')\n    }\n\n    function onClickNext () {\n      emit('click:next')\n    }\n\n    useRender(() => {\n      const stepperActionsProps = VStepperActions.filterProps(props)\n\n      return (\n        <VStepperActions\n          class=\"v-stepper-vertical-actions\"\n          { ...stepperActionsProps }\n          onClick:prev={ onClickPrev }\n          onClick:next={ onClickNext }\n          v-slots={ slots }\n        />\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VStepperVerticalActions = InstanceType<typeof VStepperVerticalActions>\n"
  },
  {
    "path": "packages/vuetify/src/labs/VStepperVertical/VStepperVerticalItem.sass",
    "content": "@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-stepper-vertical-item\n    position: relative\n    transition-duration: $stepper-vertical-item-transition-duration\n    transition-property: $stepper-vertical-item-transition-property\n    transition-timing-function: $stepper-vertical-item-transition-timing-function\n\n    &--error\n      color: rgb(var(--v-theme-error))\n\n    &__title\n      font-size: 1rem\n\n    &__subtitle\n      font-size: .75rem\n\n    .v-expansion-panel-text\n      padding-inline-start: 32px\n\n    &:not(:last-child):before\n      content: ''\n      position: absolute\n      width: 2px\n      height: calc(100% - 30px)\n      background: rgba(var(--v-border-color), var(--v-border-opacity))\n      left: 35px\n      top: 44px\n      z-index: 1\n      transition-duration: 300ms\n      transition-property: height\n\n    &:after\n      display: none\n\n    &.v-expansion-panel--disabled,\n    &:not(.v-stepper-vertical-item--editable)\n      .v-expansion-panel-title\n        pointer-events: none\n\n        .v-expansion-panel-title__overlay\n          opacity: 0\n\n  .v-stepper-vertical-item__avatar.v-avatar\n    background: tools.theme-color('surface-variant', var(--v-medium-emphasis-opacity))\n    color: rgb(var(--v-theme-on-surface-variant))\n    transition-property: background\n    align-self: start\n\n    .v-icon\n      font-size: .875rem\n\n    .v-expansion-panel--active &\n      background: rgb(var(--v-theme-surface-variant))\n\n    .v-stepper-vertical-item--error &\n      background: rgb(var(--v-theme-error))\n      color: rgb(var(--v-theme-on-error))\n\n  .v-stepper-vertical-item__title\n    .v-stepper-vertical-item--error &\n      color: rgb(var(--v-theme-error))\n\n  .v-stepper-vertical-item__subtitle\n    .v-stepper-vertical-item--error &\n      color: rgb(var(--v-theme-error))\n\n  .v-stepper-vertical-actions\n    &.v-stepper-actions\n      .v-btn\n        margin-inline-end: 8px\n\n      .v-stepper &\n        justify-content: flex-end\n        padding: 24px 0 0\n        flex-direction: row-reverse\n"
  },
  {
    "path": "packages/vuetify/src/labs/VStepperVertical/VStepperVerticalItem.tsx",
    "content": "// Styles\nimport './VStepperVerticalItem.sass'\n\n// Components\nimport { VStepperVerticalActions } from './VStepperVerticalActions'\nimport { VAvatar } from '@/components/VAvatar/VAvatar'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider/VDefaultsProvider'\nimport { makeVExpansionPanelProps, VExpansionPanel } from '@/components/VExpansionPanel/VExpansionPanel'\nimport { VIcon } from '@/components/VIcon/VIcon'\nimport { makeStepperItemProps } from '@/components/VStepper/VStepperItem'\n\n// Utilities\nimport { computed, ref } from 'vue'\nimport { genericComponent, omit, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { StepperItemSlot } from '@/components/VStepper/VStepperItem'\n\nexport type StepperVerticalItemActionSlot<T = any> = StepperItemSlot<T> & {\n  next: () => void\n  prev: () => void\n}\n\nexport type VStepperVerticalItemSlots<T = any> = {\n  default: StepperItemSlot<T>\n  icon: StepperItemSlot<T>\n  subtitle: StepperItemSlot<T>\n  title: StepperItemSlot<T>\n  text: StepperItemSlot<T>\n  prev: StepperVerticalItemActionSlot<T>\n  next: StepperVerticalItemActionSlot<T>\n  actions: StepperVerticalItemActionSlot<T>\n}\n\nexport const makeVStepperVerticalItemProps = propsFactory({\n  hideActions: Boolean,\n\n  ...makeStepperItemProps(),\n  ...omit(makeVExpansionPanelProps({\n    expandIcon: '',\n    collapseIcon: '',\n  }), ['hideActions']),\n}, 'VStepperVerticalItem')\n\nexport const VStepperVerticalItem = genericComponent<VStepperVerticalItemSlots>()({\n  name: 'VStepperVerticalItem',\n\n  props: makeVStepperVerticalItemProps(),\n\n  emits: {\n    'click:next': () => true,\n    'click:prev': () => true,\n    'click:finish': () => true,\n  },\n\n  setup (props, { emit, slots }) {\n    const vExpansionPanelRef = ref<typeof VExpansionPanel>()\n    const step = computed(() => !isNaN(parseInt(props.value)) ? Number(props.value) : props.value)\n    const groupItem = computed(() => vExpansionPanelRef.value?.groupItem)\n    const isValid = computed(() => props.rules.every(handler => handler() === true))\n    const canEdit = computed(() => !props.disabled && props.editable)\n    const hasError = computed(() => props.error || !isValid.value)\n    const hasCompleted = computed(() => props.complete || (props.rules.length > 0 && isValid.value))\n\n    const disabled = computed(() => {\n      if (props.disabled) return props.disabled\n      if (groupItem.value?.isFirst.value) return 'prev'\n\n      return false\n    })\n    const icon = computed(() => {\n      if (hasError.value) return props.errorIcon\n      if (hasCompleted.value) return props.completeIcon\n      if (groupItem.value?.isSelected.value && props.editable) return props.editIcon\n\n      return props.icon\n    })\n\n    const slotProps = computed(() => ({\n      canEdit: canEdit.value,\n      hasError: hasError.value,\n      hasCompleted: hasCompleted.value,\n      title: props.title,\n      subtitle: props.subtitle,\n      step: step.value,\n    } satisfies StepperItemSlot))\n\n    const actionProps = computed(() => ({\n      ...slotProps.value,\n      prev: onClickPrev,\n      next: onClickNext,\n    } satisfies StepperVerticalItemActionSlot))\n\n    function onClickNext () {\n      emit('click:next')\n\n      if (groupItem.value?.isLast.value) return\n\n      groupItem.value.group.next()\n    }\n\n    function onClickPrev () {\n      emit('click:prev')\n\n      groupItem.value.group.prev()\n    }\n\n    useRender(() => {\n      const hasColor = (\n        !groupItem.value ||\n        groupItem.value?.isSelected.value ||\n        hasCompleted.value ||\n        canEdit.value\n      ) && (\n        !hasError.value &&\n        !props.disabled\n      )\n\n      const hasActions = !props.hideActions || !!slots.actions\n      const expansionPanelProps = VExpansionPanel.filterProps(props)\n\n      return (\n        <VExpansionPanel\n          _as=\"VStepperVerticalItem\"\n          ref={ vExpansionPanelRef }\n          { ...expansionPanelProps }\n          class={[\n            'v-stepper-vertical-item',\n            {\n              'v-stepper-vertical-item--complete': hasCompleted.value,\n              'v-stepper-vertical-item--disabled': props.disabled,\n              'v-stepper-vertical-item--editable': canEdit.value,\n              'v-stepper-vertical-item--error': hasError.value,\n            },\n            props.class,\n          ]}\n          readonly={ !props.editable }\n          style={ props.style }\n          color=\"\"\n          hideActions={ false }\n          value={ step.value }\n        >\n          {{\n            title: () => (\n              <>\n                <VAvatar\n                  key=\"stepper-avatar\"\n                  class=\"v-stepper-vertical-item__avatar\"\n                  color={ hasColor ? props.color : undefined }\n                  size={ 24 }\n                  start\n                >\n                  { slots.icon?.(slotProps.value) ?? (\n                    icon.value ? (\n                      <VIcon icon={ icon.value }></VIcon>\n                    ) : step.value\n                  )}\n                </VAvatar>\n\n                <div>\n                  <div class=\"v-stepper-vertical-item__title\">\n                    { slots.title?.(slotProps.value) ?? props.title }\n                  </div>\n\n                  <div class=\"v-stepper-vertical-item__subtitle\">\n                    { slots.subtitle?.(slotProps.value) ?? props.subtitle }\n                  </div>\n                </div>\n              </>\n            ),\n            text: () => (\n              <>\n                { slots.default?.(slotProps.value) ?? props.text }\n\n                { hasActions && (\n                  <VDefaultsProvider\n                    defaults={{\n                      VStepperVerticalActions: {\n                        disabled: disabled.value,\n                        finish: groupItem.value?.isLast.value,\n                      },\n                    }}\n                  >\n                    { slots.actions?.(actionProps.value) ?? (\n                      <VStepperVerticalActions\n                        onClick:next={ onClickNext }\n                        onClick:prev={ onClickPrev }\n                        v-slots={{\n                          prev: slots.prev ? () => slots.prev?.(actionProps.value) : undefined,\n                          next: slots.next ? () => slots.next?.(actionProps.value) : undefined,\n                        }}\n                      />\n                    )}\n                  </VDefaultsProvider>\n                )}\n              </>\n            ),\n          }}\n        </VExpansionPanel>\n      )\n    })\n\n    return {}\n  },\n})\n\nexport type VStepperVerticalItem = InstanceType<typeof VStepperVerticalItem>\n"
  },
  {
    "path": "packages/vuetify/src/labs/VStepperVertical/_variables.scss",
    "content": "$stepper-vertical-item-transition-duration: .2s !default;\n$stepper-vertical-item-transition-property: opacity !default;\n$stepper-vertical-item-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1) !default;\n"
  },
  {
    "path": "packages/vuetify/src/labs/VStepperVertical/index.ts",
    "content": "export { VStepperVertical } from './VStepperVertical'\nexport { VStepperVerticalItem } from './VStepperVerticalItem'\nexport { VStepperVerticalActions } from './VStepperVerticalActions'\n"
  },
  {
    "path": "packages/vuetify/src/labs/VVideo/VVideo.sass",
    "content": "@use '../../styles/settings'\n@use '../../styles/tools'\n@use './variables' as *\n\n@include tools.layer('components')\n  .v-video\n    display: flex\n    flex-direction: column\n    align-items: center\n    position: relative\n    --v-video-aspect-ratio: #{$video-aspect-ratio}\n    --v-video-controls-height: #{$video-controls-height}\n    --v-video-controls-pill-border-radius: #{$video-controls-pill-border-radius}\n\n    @at-root\n      @include tools.density('v-video', $video-density) using ($modifier)\n        --v-video-controls-height: #{$video-controls-height + $modifier * 2}\n\n    &__video\n      position: absolute\n      width: 100%\n      height: 100%\n      object-fit: cover\n      z-index: 0\n\n      &::-webkit-media-controls\n        display: none !important\n\n      & ~ *\n        z-index: 1\n\n    &__header\n      position: relative\n      opacity: 0\n      transition: opacity .6s ease-in-out\n      pointer-events: none\n      > *\n        pointer-events: auto\n\n    &__content\n      position: relative\n      border-radius: inherit\n      z-index: 0\n      @include tools.elevation($video-elevation)\n\n    &:not(.v-video--idle):not(.v-video--error)\n      .v-video__content .v-video__overlay-fill\n        &, > *\n          pointer-events: none\n\n    &:not(.v-video--error)\n      .v-video__content\n        cursor: pointer\n\n    &__overlay-fill\n      position: absolute\n      inset: 0\n      display: flex\n      align-items: center\n      justify-content: center\n      border-radius: inherit\n\n      > .v-img\n        position: absolute\n        border-radius: inherit\n        inset: 0\n\n    &:has(.v-video-controls:not(.v-video-controls--detached))\n      .v-video__content .v-video__overlay-fill\n        padding-bottom: var(--v-video-controls-height) // controls size\n\n    &__center-icon.v-icon-btn\n      border: $video-center-icon-border\n      transition-property: transform, opacity\n      transition-duration: 0.28s\n      transition-timing-function: settings.$standard-easing\n\n      &.v-video__center-icon--play\n        opacity: $video-center-icon-opacity\n\n    &__content:hover &__center-icon--play\n      transform: $video-center-icon-hover-transform\n      opacity: 1\n\n    &-volume--inline\n      display: flex\n      align-items: center\n\n    &-volume__menu\n      background: rgb(var(--v-theme-surface))\n      color: rgb(var(--v-theme-on-surface))\n      overflow: hidden\n      display: flex\n      align-items: center\n      justify-content: center\n\n      @include tools.border($video-volume-menu-border...)\n      @include tools.elevation($video-volume-menu-elevation)\n      @include tools.rounded($video-volume-menu-border-radius)\n\n      &:has(.v-input--horizontal)\n        height: $video-volume-horizontal-menu-height\n\n      &:has(.v-input--vertical)\n        width: $video-volume-vertical-menu-width\n\n      .v-slider.v-input--horizontal\n        margin: $video-volume-horizontal-margin\n        width: $video-volume-horizontal-menu-width\n        height: $video-volume-horizontal-menu-height\n\n      .v-slider.v-input--vertical\n        margin: $video-volume-vertical-margin\n        height: $video-volume-vertical-menu-height\n        width: $video-volume-vertical-menu-width\n\n        > .v-input__control\n          // just smaller than 300px default\n          min-height: 50px\n\n    &__track\n      position: relative\n      z-index: 1\n\n      &.v-slider.v-input--horizontal > .v-input__control\n        min-height: 4px\n\n      .v-slider-thumb:not(:hover)\n        .v-slider-thumb__label\n          opacity: 0\n          transition-delay: .2s\n\n      .v-slider-thumb__label\n        color: rgb(var(--v-theme-on-surface-variant)) !important\n\n    &__time\n      font-size: $video-time-font-size\n      line-height: $video-time-line-height\n      letter-spacing: $video-time-letter-spacing\n\n    &--variant-player\n      width: $video-player-width\n\n      > .v-video__content\n        width: 100%\n        aspect-ratio: var(--v-video-aspect-ratio)\n\n    &--variant-background\n      outline: none\n      position: absolute\n      inset: 0\n      pointer-events: none\n\n      > .v-video__content\n        width: 100%\n        height: 100%\n\n    &-controls\n      --v-background-opacity: #{$video-controls-default-background-opacity}\n      --v-video-controls-gap: #{$video-controls-gap}\n\n      // override by density logic\n      --v-video-controls-pill-height: 42px\n\n      flex: 1 0 100%\n      align-self: stretch\n      padding: $video-controls-padding\n      display: flex\n      align-items: center\n      position: relative\n      gap: var(--v-video-controls-gap)\n      min-height: var(--v-video-controls-height)\n      backdrop-filter: $video-controls-default-backdrop-filter\n      background-color: rgba($video-controls-default-background-color, var(--v-background-opacity))\n      color: $video-controls-default-color\n      width: 100%\n      opacity: 0\n\n      @at-root\n        @include tools.density('v-video-controls', $video-density) using ($modifier)\n          --v-video-controls-gap: #{$video-controls-gap + $modifier}\n\n      &, &--pills > .v-video-control__pill\n        transition: .6s ease-in-out\n        transition-property: opacity, background-color\n\n      &--pills > .v-video-control__pill\n        @include tools.elevation($video-elevation)\n\n      &:hover\n        --v-background-opacity: 1\n\n      .v-video__track\n        width: auto\n\n      .v-video-control__pill\n        display: flex\n        align-items: center\n        gap: $video-controls-pill-gap\n\n      &--pills\n        --v-background-opacity: 1\n        --v-video-controls-height: calc(var(--v-video-controls-pill-height) + 24px)\n        backdrop-filter: none\n        pointer-events: none\n\n        > *\n          pointer-events: auto\n\n        &:not(:empty)\n          background: transparent\n\n        > .v-video-control__pill\n          backdrop-filter: $video-controls-pill-backdrop-filter\n          background: rgba($video-controls-default-background-color, var(--v-background-opacity))\n          border-radius: var(--v-video-controls-pill-border-radius)\n          min-height: var(--v-video-controls-pill-height)\n          min-width: var(--v-video-controls-pill-height)\n          padding: $video-controls-pill-padding\n          z-index: 1\n\n          > .v-icon-btn\n            border-radius: inherit\n\n          &:empty\n            display: none\n\n          &:has(> *:only-child)\n            padding-inline: 0\n            justify-content: center\n            border-radius: var(--v-video-controls-pill-border-radius)\n\n        > .v-video__time\n          padding: $video-time-pill-padding\n\n      &--variant-tube\n        .v-slider.v-video__track\n          position: absolute\n          top: $video-tube-track-top\n          left: 0\n          right: 0\n\n          .v-slider-track\n            height: calc(var(--v-slider-track-size) + #{$video-tube-track-hover-offset})\n\n          .v-slider-track__fill\n            height: var(--v-slider-track-size)\n\n      &--split-time\n        padding-inline: $video-controls-split-time-padding-inline\n\n      &:not(.v-video-controls--detached)\n        margin-top: calc(-1 * var(--v-video-controls-height))\n\n      &:not(.v-video-controls--floating)\n        border-bottom-left-radius: inherit\n        border-bottom-right-radius: inherit\n\n      &:not(.v-video-controls--floating):not(.v-video-controls--pills)\n        border-top: thin solid tools.theme-color('surface-variant', .2)\n\n      &--floating\n        --v-background-opacity: 1\n        border-radius: inherit\n        margin-inline: $video-controls-floating-margin\n        width: calc(100% - 2 * #{$video-controls-floating-margin})\n\n      &--floating:not(.v-video-controls--detached)\n        margin-top: calc(-1 * var(--v-video-controls-height) - $video-controls-floating-margin)\n        margin-bottom: $video-controls-floating-margin\n\n      &--detached\n        --v-background-opacity: 1\n        position: relative\n        margin-block-start: $video-controls-detached-offset\n        padding-inline: $video-controls-detached-padding-inline\n        backdrop-filter: none\n        border-top: none\n        border-radius: inherit\n        opacity: 1\n\n        &:not(.v-video-controls--pills)\n          @include tools.elevation($video-elevation)\n\n    &:not(.v-video--playing),\n    &:hover\n      .v-video__header,\n      .v-video-controls\n        opacity: 1\n\n    &--rounded\n      border-radius: $video-rounded-border-radius\n\n    &:fullscreen\n      .v-video__content\n        min-height: 100% !important\n        min-width: 100% !important\n\n      .v-video-controls\n        position: absolute\n        bottom: 0\n        z-index: 2147483647\n\n        &--floating\n          bottom: $video-controls-floating-margin\n\n  .poster-fade-out\n    &-leave-active\n      transition: opacity 1s linear 0.3s\n    &-leave-to\n      opacity: 0\n"
  },
  {
    "path": "packages/vuetify/src/labs/VVideo/VVideo.tsx",
    "content": "// Styles\nimport './VVideo.sass'\n\n// Components\nimport { makeVVideoControlsProps, VVideoControls } from './VVideoControls'\nimport { VFadeTransition } from '@/components/transitions'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider'\nimport { VIcon } from '@/components/VIcon'\nimport { VImg } from '@/components/VImg/VImg'\nimport { VProgressCircular } from '@/components/VProgressCircular/VProgressCircular'\nimport { VIconBtn } from '@/labs/VIconBtn/VIconBtn'\n\n// Composables\nimport { useDisplay } from '@/composables'\nimport { makeComponentProps } from '@/composables/component'\nimport { makeDensityProps, useDensity } from '@/composables/density'\nimport { makeDimensionProps, useDimension } from '@/composables/dimensions'\nimport { useElevation } from '@/composables/elevation'\nimport { forwardRefs } from '@/composables/forwardRefs'\nimport { useProxiedModel } from '@/composables/proxiedModel'\nimport { useRounded } from '@/composables/rounded'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\nimport { MaybeTransition } from '@/composables/transition'\n\n// Utilities\nimport { nextTick, onBeforeUnmount, onMounted, ref, shallowRef, toRef, Transition, watch } from 'vue'\nimport { createRange, genericComponent, omit, pick, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { Component, PropType, TransitionProps } from 'vue'\nimport type { VVideoControlsActionsSlot, VVideoControlsVariant } from './VVideoControls'\nimport type { LoaderSlotProps } from '@/composables/loader'\n\nexport type VVideoSlots = {\n  header: never\n  controls: VVideoControlsActionsSlot\n  prepend: VVideoControlsActionsSlot\n  append: VVideoControlsActionsSlot\n  loader: LoaderSlotProps\n  sources: never\n  error: { error?: MediaError | boolean }\n}\n\nconst allowedVariants = ['background', 'player'] as const\ntype Variant = typeof allowedVariants[number]\n\nexport const makeVVideoProps = propsFactory({\n  aspectRatio: [String, Number],\n  autoplay: Boolean,\n  muted: Boolean,\n  eager: Boolean,\n  error: [Object, Boolean] as PropType<MediaError | boolean>,\n  src: String,\n  srcObject: Object as PropType<MediaStream | MediaSource | Blob>,\n  type: String, // e.g. video/mp4\n  image: String,\n  hideOverlay: Boolean,\n  noFullscreen: Boolean,\n  startAt: [Number, String],\n  variant: {\n    type: String as PropType<Variant>,\n    default: 'player',\n    validator: (v: any) => allowedVariants.includes(v),\n  },\n  controlsTransition: {\n    type: [Boolean, String, Object] as PropType<null | string | boolean | TransitionProps & { component?: any }>,\n    component: VFadeTransition as Component,\n  },\n  controlsVariant: {\n    type: String as PropType<VVideoControlsVariant>,\n    default: 'default',\n  },\n  controlsProps: {\n    type: Object as PropType<VVideoControls['$props']>,\n  },\n  rounded: [Boolean, Number, String, Array] as PropType<boolean | number | string | (boolean | number | string)[]>,\n\n  ...makeComponentProps(),\n  ...makeDensityProps(),\n  ...makeDimensionProps(),\n  ...makeThemeProps(),\n  ...omit(makeVVideoControlsProps(), [\n    'fullscreen',\n    'variant',\n  ]),\n}, 'VVideo')\n\nexport const VVideo = genericComponent<VVideoSlots>()({\n  name: 'VVideo',\n\n  inheritAttrs: false,\n\n  props: makeVVideoProps(),\n\n  emits: {\n    error: (val: MediaError | boolean) => true,\n    loaded: (element: HTMLVideoElement) => true,\n    'update:error': (val: boolean) => true,\n    'update:playing': (val: boolean) => true,\n    'update:progress': (val: number) => true,\n    'update:volume': (val: number) => true,\n  },\n\n  setup (props, { attrs, emit, slots }) {\n    const { themeClasses } = provideTheme(props)\n    const { densityClasses } = useDensity(props)\n    const { dimensionStyles } = useDimension(props)\n    const { elevationClasses } = useElevation(props)\n    const { ssr } = useDisplay()\n\n    const roundedForContainer = toRef(() => Array.isArray(props.rounded) ? props.rounded[0] : props.rounded)\n    const roundedForControls = toRef(() => Array.isArray(props.rounded) ? props.rounded.at(-1) : props.rounded ?? false)\n    const { roundedClasses: roundedContainerClasses } = useRounded(roundedForContainer)\n    const { roundedClasses: roundedControlsClasses } = useRounded(roundedForControls)\n\n    const containerRef = ref<HTMLDivElement>()\n    const videoRef = ref<HTMLVideoElement>()\n    const controlsRef = ref<VVideoControls>()\n\n    const playing = useProxiedModel(props, 'playing')\n    const progress = useProxiedModel(props, 'progress')\n    const volume = useProxiedModel(props, 'volume', 0, (v?: number | string) => Number(v ?? 0))\n\n    const fullscreen = shallowRef(false)\n    const waiting = shallowRef(false)\n    const triggered = shallowRef(false)\n    const startAfterLoad = shallowRef(false)\n    const error = useProxiedModel(props, 'error')\n    const state = shallowRef<'idle' | 'loading' | 'loaded' | 'error'>(props.autoplay ? 'loading' : 'idle')\n    const duration = shallowRef(0)\n\n    const fullscreenEnabled = toRef(() => !props.noFullscreen && !String(attrs.controlsList ?? '').includes('nofullscreen'))\n\n    function onTimeupdate () {\n      const { currentTime, duration } = videoRef.value!\n      progress.value = duration === 0 ? 0 : 100 * currentTime / duration\n    }\n\n    async function onTriggered () {\n      await nextTick()\n      if (!videoRef.value) return\n      videoRef.value.addEventListener('timeupdate', onTimeupdate)\n      videoRef.value.volume = volume.value / 100\n      if (state.value !== 'loaded') {\n        state.value = 'loading'\n      }\n    }\n\n    function onVideoLoaded () {\n      state.value = 'loaded'\n      duration.value = videoRef.value!.duration\n\n      const startTime = Number(props.startAt ?? 0)\n      if (startTime && startTime <= duration.value) {\n        videoRef.value!.currentTime = startTime\n        progress.value = duration.value === 0 ? 0 : 100 * startTime / duration.value\n      }\n\n      if (startAfterLoad.value) {\n        setTimeout(() => playing.value = true, 100)\n      }\n\n      emit('loaded', videoRef.value!)\n    }\n\n    function onVideoError (e: Event) {\n      state.value = 'error'\n      error.value = videoRef.value!.error as MediaError\n    }\n\n    watch(error, v => {\n      if (v && state.value !== 'error') {\n        videoRef.value?.pause()\n        state.value = 'error'\n      }\n    }, { immediate: true })\n\n    function retry () {\n      if (state.value !== 'error') return\n\n      error.value = false\n      state.value = 'loading'\n      triggered.value = true\n\n      videoRef.value?.load()\n      if (!props.srcObject) {\n        videoRef.value?.play()\n      }\n    }\n\n    function onClick () {\n      if (['loaded', 'error'].includes(state.value)) return\n\n      triggered.value = true\n      startAfterLoad.value = !startAfterLoad.value\n    }\n\n    function onKeydown (e: KeyboardEvent) {\n      if (!videoRef.value || e.ctrlKey) return\n      if (e.key.startsWith('Arrow')) {\n        e.preventDefault()\n      }\n      switch (true) {\n        case e.key === ' ': {\n          if (!['A', 'BUTTON'].includes((e.target as Element)?.tagName)) {\n            e.preventDefault()\n            playing.value = !playing.value\n          }\n          break\n        }\n        case e.key === 'ArrowRight': {\n          const step = 10 * (e.shiftKey ? 6 : 1)\n          videoRef.value.currentTime = Math.min(videoRef.value.currentTime + step, duration.value)\n          // TODO: show skip indicator\n          break\n        }\n        case e.key === 'ArrowLeft': {\n          const step = 10 * (e.shiftKey ? 6 : 1)\n          videoRef.value.currentTime = Math.max(videoRef.value.currentTime - step, 0)\n          // TODO: show skip indicator\n          break\n        }\n        case createRange(10).map(String).includes(e.key): {\n          skipTo(Number(e.key) * 10)\n          break\n        }\n        case e.key === 'ArrowUp': {\n          volume.value = Math.min(volume.value + 10, 100)\n          // TODO: show volume change indicator\n          break\n        }\n        case e.key === 'ArrowDown': {\n          volume.value = Math.max(volume.value - 10, 0)\n          // TODO: show volume change indicator\n          break\n        }\n        case e.key === 'm': {\n          controlsRef.value?.toggleMuted()\n          break\n        }\n        case e.key === 'f': {\n          toggleFullscreen()\n          break\n        }\n      }\n    }\n\n    function skipTo (v: number) {\n      if (!videoRef.value) return\n      progress.value = v\n      videoRef.value.currentTime = duration.value * v / 100\n    }\n\n    watch(() => props.src, v => {\n      progress.value = 0\n    })\n\n    watch(() => props.srcObject, async v => {\n      if (v) triggered.value = true\n      await nextTick()\n      if (videoRef.value) videoRef.value.srcObject = v ?? null\n    })\n\n    watch(videoRef, v => {\n      if (v && props.srcObject) v.srcObject = props.srcObject\n    })\n\n    watch(playing, v => {\n      if (!videoRef.value) return\n      if (v) {\n        videoRef.value.play()\n      } else {\n        videoRef.value.pause()\n      }\n    })\n\n    watch(volume, v => {\n      if (!videoRef.value) return\n      videoRef.value.volume = v / 100\n    })\n\n    watch(triggered, () => onTriggered(), { once: true })\n\n    watch(() => props.eager, v => v && (triggered.value = true), { immediate: true })\n\n    onMounted(() => {\n      if (props.autoplay && !ssr) {\n        triggered.value = true\n        startAfterLoad.value = true\n      }\n    })\n\n    onBeforeUnmount(() => {\n      videoRef.value?.removeEventListener('timeupdate', onTimeupdate)\n      document.body.removeEventListener('keydown', fullscreenExitShortcut)\n      document.removeEventListener('fullscreenchange', onFullscreenExit)\n    })\n\n    function focusSlider () {\n      const container = videoRef.value?.closest('.v-video') as HTMLElement\n      const innerSlider = container?.querySelector('[role=\"slider\"]') as HTMLElement\n      innerSlider?.focus()\n    }\n\n    function fullscreenExitShortcut (e: KeyboardEvent) {\n      if (['ESC', 'f'].includes(e.key)) {\n        toggleFullscreen()\n        document.body.removeEventListener('keydown', fullscreenExitShortcut)\n      }\n    }\n\n    async function toggleFullscreen () {\n      if (!fullscreenEnabled.value || !document.fullscreenEnabled) {\n        return\n      }\n      if (document.fullscreenElement) {\n        document.exitFullscreen()\n        onFullscreenExit()\n      } else {\n        await containerRef.value?.requestFullscreen()\n        document.body.addEventListener('keydown', fullscreenExitShortcut)\n        document.addEventListener('fullscreenchange', onFullscreenExit)\n        fullscreen.value = true\n      }\n    }\n\n    function onFullscreenExit () {\n      // event fires with a delay after requestFullscreen(), ignore first run\n      if (document.fullscreenElement) return\n\n      focusSlider()\n      fullscreen.value = false\n      document.body.removeEventListener('keydown', fullscreenExitShortcut)\n      document.removeEventListener('fullscreenchange', onFullscreenExit)\n    }\n\n    function onVideoClick (e: Event) {\n      e.preventDefault()\n      if (state.value === 'loaded') {\n        playing.value = !playing.value\n        focusSlider()\n      }\n    }\n\n    function onDoubleClick (e: Event) {\n      e.preventDefault()\n      toggleFullscreen()\n    }\n\n    let lastTap = 0\n    function onTouchend (e: Event) {\n      const now = performance.now()\n      if ((now - lastTap) < 500) {\n        e.preventDefault()\n        toggleFullscreen()\n      } else {\n        lastTap = now\n      }\n    }\n\n    useRender(() => {\n      const showControls = state.value === 'loaded' &&\n        props.variant === 'player' &&\n        props.controlsVariant !== 'hidden'\n\n      const posterTransition = props.variant === 'background'\n        ? 'poster-fade-out'\n        : 'fade-transition'\n\n      const controlsProps = {\n        ...VVideoControls.filterProps(omit(props, ['variant', 'rounded', 'hideVolume'])),\n        rounded: Array.isArray(props.rounded) ? props.rounded.at(-1) : props.rounded,\n        fullscreen: fullscreen.value,\n        hideVolume: props.hideVolume || props.muted,\n        hideFullscreen: props.hideFullscreen || !fullscreenEnabled.value,\n        density: props.density,\n        variant: props.controlsVariant,\n        playing: playing.value,\n        progress: progress.value,\n        duration: duration.value,\n        volume: volume.value,\n        ...props.controlsProps,\n      }\n\n      const controlsEventHandlers = {\n        onSkip: (v: number) => skipTo(v),\n        'onClick:fullscreen': () => toggleFullscreen(),\n        'onUpdate:playing': (v: boolean) => playing.value = v,\n        'onUpdate:progress': (v: number) => skipTo(v),\n        'onUpdate:volume': (v: number) => volume.value = v,\n        onClick: (e: Event) => e.stopPropagation(),\n      }\n\n      const controlslist = [\n        attrs.controlslist,\n        props.noFullscreen ? 'nofullscreen' : '',\n      ].filter(Boolean).join(' ')\n\n      const loadingIndicator = (\n        <VProgressCircular\n          indeterminate\n          color={ props.color }\n          width=\"3\"\n          size={ Math.min(100, Number(props.height) / 2 || 50) }\n        />\n      )\n\n      const overlayPlayIcon = (\n        <VIconBtn\n          icon=\"$play\"\n          size=\"80\"\n          color=\"#fff\"\n          variant=\"outlined\"\n          iconSize=\"50\"\n          class={[\n            'v-video__center-icon',\n            'v-video__center-icon--play',\n          ]}\n          onClick={ onVideoClick }\n        />\n      )\n\n      const errorIconProps = {\n        icon: '$warning',\n        size: '70',\n      }\n\n      const activeOverlays = {\n        playIcon: props.variant === 'player' &&\n          state.value === 'loaded' &&\n          !props.hideOverlay &&\n          !playing.value,\n        poster: state.value !== 'loaded' && state.value !== 'error',\n        loading: props.variant === 'player' &&\n          state.value !== 'error' &&\n          (\n            state.value === 'loading' ||\n            waiting.value\n          ),\n        error: props.variant === 'player' && state.value === 'error',\n      }\n\n      return (\n        <div\n          ref={ containerRef }\n          class={[\n            'v-video',\n            `v-video--variant-${props.variant}`,\n            `v-video--${state.value}`,\n            { 'v-video--playing': playing.value },\n            themeClasses.value,\n            densityClasses.value,\n            roundedContainerClasses.value,\n            props.class,\n          ]}\n          style={[\n            { '--v-video-aspect-ratio': props.aspectRatio },\n            props.variant === 'background' ? [] : pick(dimensionStyles.value, ['width', 'minWidth', 'maxWidth']),\n            props.style,\n          ]}\n          onKeydown={ onKeydown }\n          onClick={ onClick }\n        >\n          <div\n            class={[\n              'v-video__content',\n              elevationClasses.value,\n            ]}\n            style={[\n              props.variant === 'background' ? [] : dimensionStyles.value,\n            ]}\n          >\n            { (props.eager || triggered.value) && (\n              <video\n                key=\"video-element\"\n                class={[\n                  'v-video__video',\n                  roundedContainerClasses.value,\n                ]}\n                { ...omit(attrs, ['controlslist', 'class', 'style']) }\n                controlslist={ controlslist }\n                autoplay={ props.autoplay }\n                muted={ props.muted }\n                playsinline\n                ref={ videoRef }\n                onLoadeddata={ onVideoLoaded }\n                onError={ onVideoError }\n                onPlay={ () => playing.value = true }\n                onPause={ () => playing.value = false }\n                onWaiting={ () => waiting.value = true }\n                onPlaying={ () => waiting.value = false }\n                onClick={ onVideoClick }\n                onDblclick={ onDoubleClick }\n                onTouchend={ onTouchend }\n              >\n                { slots.sources?.() ?? <source src={ props.src } type={ props.type } /> }\n              </video>\n            )}\n            <Transition name=\"fade-transition\">\n              { activeOverlays.playIcon && (\n                <div class=\"v-video__overlay-fill\">\n                  { overlayPlayIcon }\n                </div>\n              )}\n            </Transition>\n            { props.variant === 'player' &&\n              !!slots.header &&\n              (\n                <div key=\"header\" class=\"v-video__header\">\n                  { slots.header() }\n                </div>\n              )\n            }\n            <MaybeTransition transition={ posterTransition }>\n              { activeOverlays.poster && (\n                <div class=\"v-video__overlay-fill\">\n                  <VImg cover src={ props.image }>\n                    <div\n                      class={[\n                        'v-video__overlay-fill',\n                        ...roundedContainerClasses.value,\n                      ]}\n                    >\n                      { props.variant === 'player' && overlayPlayIcon }\n                    </div>\n                  </VImg>\n                </div>\n              )}\n            </MaybeTransition>\n            { activeOverlays.loading && (\n              <div key=\"loading-overlay\" class=\"v-video__overlay-fill\">\n                { loadingIndicator }\n              </div>\n            )}\n            { activeOverlays.error && (\n              <div key=\"error-overlay\" class=\"v-video__overlay-fill\">\n                {\n                  slots.error\n                    ? (\n                      <VDefaultsProvider defaults={{ VIcon: errorIconProps }}>\n                        { slots.error?.({ error: error.value }) }\n                      </VDefaultsProvider>\n                    )\n                    : <VIcon { ...errorIconProps } />\n                }\n              </div>\n            )}\n          </div>\n          <MaybeTransition key=\"actions\" transition={ props.controlsTransition }>\n            { showControls && (\n              <VVideoControls\n                ref={ controlsRef }\n                class={ roundedControlsClasses.value }\n                { ...controlsProps }\n                { ...controlsEventHandlers }\n              >\n                {{\n                  default: slots.controls,\n                  prepend: slots.prepend,\n                  append: slots.append,\n                }}\n              </VVideoControls>\n            )}\n          </MaybeTransition>\n        </div>\n      )\n    })\n\n    return {\n      video: videoRef,\n      ...forwardRefs({\n        retry,\n        skipTo,\n        toggleFullscreen,\n      }, controlsRef),\n    }\n  },\n})\n\nexport type VVideo = InstanceType<typeof VVideo>\n"
  },
  {
    "path": "packages/vuetify/src/labs/VVideo/VVideoControls.tsx",
    "content": "/* eslint-disable complexity */\n\n// Components\nimport { VVideoVolume } from './VVideoVolume'\nimport { VDefaultsProvider } from '@/components/VDefaultsProvider/VDefaultsProvider'\nimport { VSpacer } from '@/components/VGrid/VSpacer'\nimport { VSlider } from '@/components/VSlider/VSlider'\nimport { VIconBtn } from '@/labs/VIconBtn/VIconBtn'\n\n// Composables\nimport { useBackgroundColor } from '@/composables/color'\nimport { makeDensityProps, useDensity } from '@/composables/density'\nimport { makeElevationProps, useElevation } from '@/composables/elevation'\nimport { useLocale } from '@/composables/locale'\nimport { useProxiedModel } from '@/composables/proxiedModel'\nimport { makeThemeProps, provideTheme } from '@/composables/theme'\n\n// Directives\nimport vTooltip from '@/directives/tooltip'\n\n// Utilities\nimport { computed, shallowRef, toRef } from 'vue'\nimport { formatTime, genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType, Ref } from 'vue'\n\nexport type VVideoControlsActionsSlot = {\n  play: () => void\n  pause: () => void\n  skipTo: (v: number) => void\n  volume: Ref<number>\n  playing: boolean\n  progress: number\n  toggleMuted: () => void\n  fullscreen: boolean\n  toggleFullscreen: () => void\n  labels: Record<string, string>\n}\n\nexport type VVideoControlsSlots = {\n  default: VVideoControlsActionsSlot\n  prepend: VVideoControlsActionsSlot\n  append: VVideoControlsActionsSlot\n}\n\nconst allowedVariants = ['hidden', 'default', 'tube', 'mini'] as const\nexport type VVideoControlsVariant = typeof allowedVariants[number]\n\nexport const makeVVideoControlsProps = propsFactory({\n  color: String,\n  backgroundColor: String,\n  trackColor: String,\n  playing: Boolean,\n  hidePlay: Boolean,\n  hideVolume: Boolean,\n  hideFullscreen: Boolean,\n  hideProgressBar: { type: Boolean, default: true },\n  fullscreen: Boolean,\n  floating: Boolean,\n  splitTime: Boolean,\n  pills: Boolean,\n  detached: Boolean,\n  progress: {\n    type: Number,\n    default: 0,\n  },\n  duration: {\n    type: Number,\n    default: 0,\n  },\n  volume: [Number, String],\n  variant: {\n    type: String as PropType<VVideoControlsVariant>,\n    default: 'default',\n    validator: (v: any) => allowedVariants.includes(v),\n  },\n  volumeProps: Object as PropType<Pick<VVideoVolume['$props'], 'direction' | 'inline' | 'sliderProps' | 'menuProps'>>,\n\n  ...makeDensityProps(),\n  ...makeElevationProps(),\n  ...makeThemeProps(),\n}, 'VVideoControls')\n\nexport const VVideoControls = genericComponent<VVideoControlsSlots>()({\n  name: 'VVideoControls',\n\n  directives: { vTooltip: vTooltip as any },\n\n  props: makeVVideoControlsProps(),\n\n  emits: {\n    'update:playing': (val: boolean) => true,\n    'update:progress': (val: number) => true,\n    'update:volume': (val: number) => true,\n    skip: (val: number) => true,\n    'click:fullscreen': () => true,\n  },\n\n  setup (props, { emit, slots }) {\n    const { t } = useLocale()\n    const { themeClasses, current: currentTheme } = provideTheme(props)\n    const { densityClasses } = useDensity(props)\n    const { elevationClasses } = useElevation(props)\n\n    const { backgroundColorClasses, backgroundColorStyles } = useBackgroundColor(() => {\n      const fallbackBackground = props.detached ? 'surface' : undefined\n      return props.backgroundColor ?? fallbackBackground\n    })\n\n    const trackColor = toRef(() => {\n      if (props.trackColor) {\n        return props.trackColor\n      }\n\n      const fallback = currentTheme.value.dark || !props.pills ? undefined : 'surface'\n      return (props.pills ? props.backgroundColor : props.color) ?? fallback\n    })\n\n    const playing = useProxiedModel(props, 'playing')\n    const progress = useProxiedModel(props, 'progress')\n    const volume = useProxiedModel(props, 'volume', 0, (v?: number | string) => Number(v ?? 0))\n    const lastVolume = shallowRef<number>()\n\n    const currentTime = computed(() => {\n      const secondsElapsed = Math.round(props.progress / 100 * props.duration)\n      return {\n        elapsed: formatTime(secondsElapsed),\n        remaining: formatTime(props.duration - secondsElapsed),\n        total: formatTime(props.duration),\n      }\n    })\n\n    const labels = computed(() => {\n      const playIconLocaleKey = playing.value ? 'pause' : 'play'\n      const volumeIconLocaleKey = props.volumeProps?.inline ? (volume.value ? 'mute' : 'unmute') : 'showVolume'\n      const fullscreenIconLocaleKey = props.fullscreen ? 'exitFullscreen' : 'enterFullscreen'\n      return {\n        seek: t('$vuetify.video.seek'),\n        volume: t('$vuetify.video.volume'),\n        playAction: t(`$vuetify.video.${playIconLocaleKey}`),\n        volumeAction: t(`$vuetify.video.${volumeIconLocaleKey}`),\n        fullscreenAction: t(`$vuetify.video.${fullscreenIconLocaleKey}`),\n      }\n    })\n\n    function play () {\n      playing.value = true\n    }\n\n    function pause () {\n      playing.value = false\n    }\n\n    function skipTo (v: number) {\n      progress.value = v\n    }\n\n    function toggleMuted () {\n      if (volume.value) {\n        lastVolume.value = volume.value\n        volume.value = 0\n      } else {\n        volume.value = lastVolume.value ?? 100\n      }\n    }\n\n    function toggleFullscreen () {\n      emit('click:fullscreen')\n    }\n\n    useRender(() => {\n      const sizes = props.pills\n        ? [42, 36, 30]\n        : [32, 28, 24]\n\n      const innerDefaults = {\n        VIconBtn: {\n          size: props.density === 'compact' ? sizes[2]\n          : props.density === 'comfortable' ? sizes[1]\n          : sizes[0],\n          iconSize: props.density === 'compact' ? 20\n          : props.density === 'comfortable' ? 24\n          : 26,\n          variant: 'text',\n          color: props.color,\n        },\n        VSlider: {\n          thumbSize: props.variant === 'tube' ? 10 : 16,\n          hideDetails: true,\n        },\n      }\n\n      const regularBtnSize = innerDefaults.VIconBtn.size\n      const playBtnSize = props.pills ? (regularBtnSize + 8) : regularBtnSize\n\n      const pillClasses = [\n        'v-video-control__pill',\n        props.pills ? elevationClasses.value : [],\n        props.pills ? backgroundColorClasses.value : [],\n      ]\n\n      const pillStyles = props.pills ? backgroundColorStyles.value : []\n\n      const slotProps = {\n        play,\n        pause,\n        playing: playing.value,\n        progress: progress.value,\n        currentTime: currentTime.value,\n        skipTo,\n        volume,\n        toggleMuted,\n        fullscreen: props.fullscreen,\n        toggleFullscreen,\n        labels: labels.value,\n      }\n\n      return (\n        <div\n          class={[\n            'v-video-controls',\n            `v-video-controls--variant-${props.variant}`,\n            { 'v-video-controls--pills': props.pills },\n            { 'v-video-controls--detached': props.detached },\n            { 'v-video-controls--floating': props.floating },\n            { 'v-video-controls--split-time': props.splitTime },\n            !props.pills ? backgroundColorClasses.value : [],\n            props.detached && !props.pills ? elevationClasses.value : [],\n            densityClasses.value,\n            themeClasses.value,\n          ]}\n          style={[\n            !props.pills ? backgroundColorStyles.value : [],\n            { '--v-video-controls-pill-height': `${regularBtnSize}px` },\n          ]}\n        >\n          <VDefaultsProvider defaults={ innerDefaults }>\n            { slots.default?.(slotProps) ?? (\n              <>\n                { props.variant !== 'mini' && (\n                  <>\n                    { !props.hidePlay && (\n                      <div\n                        class={[pillClasses, 'v-video__action-play']}\n                        style={ pillStyles }\n                      >\n                        <VIconBtn\n                          icon={ playing.value ? '$pause' : '$play' }\n                          size={ playBtnSize }\n                          aria-label={ labels.value.playAction }\n                          v-tooltip={[labels.value.playAction, 'top']}\n                          onClick={ () => playing.value = !playing.value }\n                        />\n                      </div>\n                    )}\n                    { slots.prepend && (\n                      <div\n                        class={ pillClasses }\n                        style={ pillStyles }\n                      >\n                        { slots.prepend(slotProps) }\n                      </div>\n                    )}\n                    { props.splitTime\n                      ? (\n                        <span\n                          class={[pillClasses, 'v-video__time']}\n                          style={ pillStyles }\n                        >\n                          { currentTime.value.elapsed }\n                        </span>\n                      )\n                      : props.variant !== 'default'\n                        ? (\n                          <span\n                            class={[pillClasses, 'v-video__time']}\n                            style={ pillStyles }\n                          >\n                            { currentTime.value.elapsed } / { currentTime.value.total }\n                          </span>\n                        )\n                        : ''\n                    }\n                    { props.hideProgressBar\n                      ? <VSpacer />\n                      : (\n                          <VSlider\n                            modelValue={ props.progress }\n                            noKeyboard\n                            color={ trackColor.value ?? 'surface-variant' }\n                            trackColor={ props.variant === 'tube' ? 'white' : undefined }\n                            class=\"v-video__track\"\n                            thumbLabel=\"always\"\n                            aria-label={ labels.value.seek }\n                            onUpdate:modelValue={ skipTo }\n                          >\n                            {{\n                              'thumb-label': () => currentTime.value.elapsed,\n                            }}\n                          </VSlider>\n                      )\n                    }\n                    { props.variant === 'tube' && <VSpacer /> }\n                    { props.splitTime\n                      ? (\n                        <span\n                          class={[pillClasses, 'v-video__time']}\n                          style={ pillStyles }\n                        >\n                          { currentTime.value.remaining }\n                        </span>\n                      )\n                      : ''\n                    }\n                  </>\n                )}\n                { props.variant === 'mini' && (\n                  <>\n                    <VSpacer />\n                    { slots.prepend && (\n                      <div\n                        class={ pillClasses }\n                        style={ pillStyles }\n                      >\n                        { slots.prepend(slotProps) }\n                      </div>\n                    )}\n                    { !props.hidePlay && (\n                      <div\n                        class={[pillClasses, 'v-video__action-play']}\n                        style={ pillStyles }\n                      >\n                        <VIconBtn\n                          icon={ playing.value ? '$pause' : '$play' }\n                          size={ playBtnSize }\n                          aria-label={ labels.value.playAction }\n                          v-tooltip={[labels.value.playAction, 'top']}\n                          onClick={ () => playing.value = !playing.value }\n                        />\n                      </div>\n                    )}\n                  </>\n                )}\n                { (!props.hideVolume || !props.hideFullscreen || slots.append) && (\n                  <div\n                    class={ pillClasses }\n                    style={ pillStyles }\n                  >\n                    { !props.hideVolume && (\n                      <VVideoVolume\n                        key=\"volume-control\"\n                        sliderProps={{ color: props.color }}\n                        modelValue={ volume.value }\n                        label={ labels.value.volumeAction }\n                        onUpdate:modelValue={ v => volume.value = v }\n                        onClick={ () => props.volumeProps?.inline && toggleMuted() }\n                        { ...props.volumeProps }\n                      />\n                    )}\n                    { slots.append?.(slotProps) }\n                    { !props.hideFullscreen && (\n                      <VIconBtn\n                        icon={ props.fullscreen ? '$fullscreenExit' : '$fullscreen' }\n                        aria-label={ labels.value.fullscreenAction }\n                        v-tooltip={[labels.value.fullscreenAction, 'top']}\n                        onClick={ toggleFullscreen }\n                      />\n                    )}\n                  </div>\n                )}\n\n                { props.variant === 'mini' && (<VSpacer />) }\n              </>\n            )}\n          </VDefaultsProvider>\n        </div>\n      )\n    })\n\n    return {\n      toggleMuted,\n    }\n  },\n})\n\nexport type VVideoControls = InstanceType<typeof VVideoControls>\n"
  },
  {
    "path": "packages/vuetify/src/labs/VVideo/VVideoVolume.tsx",
    "content": "// Components\nimport { VIcon } from '@/components/VIcon/VIcon'\nimport { VMenu } from '@/components/VMenu/VMenu'\nimport { VSlider } from '@/components/VSlider/VSlider'\nimport { VIconBtn } from '@/labs/VIconBtn/VIconBtn'\n\n// Composables\nimport { makeComponentProps } from '@/composables/component'\nimport { useLocale } from '@/composables/locale'\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Directives\nimport vTooltip from '@/directives/tooltip'\n\n// Utilities\nimport { ref, toRef } from 'vue'\nimport { EventProp, genericComponent, propsFactory, useRender } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\n\nexport const makeVVideoVolumeProps = propsFactory({\n  inline: Boolean,\n  label: String,\n  direction: {\n    type: String as PropType<'horizontal' | 'vertical'>,\n    default: 'vertical',\n  },\n  modelValue: {\n    type: Number,\n    default: 0,\n  },\n  menuProps: Object as PropType<VMenu['$props']>,\n  sliderProps: Object as PropType<Pick<VSlider['$props'], 'color' | 'disabled' | 'thumbSize' | 'trackColor' | 'maxWidth' | 'width'>>,\n  onClick: EventProp<[MouseEvent | KeyboardEvent]>(),\n\n  ...makeComponentProps(),\n}, 'VVideoVolume')\n\nexport const VVideoVolume = genericComponent()({\n  name: 'VVideoVolume',\n\n  directives: { vTooltip: vTooltip as any },\n\n  props: makeVVideoVolumeProps(),\n\n  emits: {\n    'update:modelValue': (val: number) => true,\n  },\n\n  setup (props, { attrs }) {\n    const { t } = useLocale()\n    const volume = useProxiedModel(props, 'modelValue')\n\n    const volumeIcon = toRef(() => volume.value > 70 ? '$volumeHigh'\n      : volume.value > 40 ? '$volumeMedium'\n      : volume.value > 10 ? '$volumeLow'\n      : '$volumeOff')\n\n    const containerRef = ref<HTMLElement>()\n\n    useRender(() => {\n      const sliderDefaults = {\n        hideDetails: true,\n        step: 5,\n        thumbSize: 16,\n      }\n\n      return (\n        <div\n          class={[\n            'v-video-volume',\n            { 'v-video-volume--inline': props.inline },\n            props.class,\n          ]}\n          style={ props.style }\n          ref={ containerRef }\n        >\n            <VIconBtn\n              icon={ volumeIcon.value }\n              aria-label={ props.label }\n              v-tooltip={[props.label, 'top']}\n              onClick={ props.onClick as any }\n              { ...attrs }\n            >\n              <VIcon />\n              { !props.inline && (\n                <VMenu\n                  offset=\"8\"\n                  activator=\"parent\"\n                  attach={ containerRef.value }\n                  location={ props.menuProps?.location ?? 'top center' }\n                  closeOnContentClick={ false }\n                >\n                  <div\n                    class={[\n                      'v-video-volume__menu',\n                      `v-video-volume__menu--${props.direction}`,\n                    ]}\n                  >\n                    <VSlider\n                      direction={ props.direction }\n                      aria-label={ t('$vuetify.video.volume') }\n                      modelValue={ volume.value }\n                      onUpdate:modelValue={ v => volume.value = v }\n                      { ...sliderDefaults }\n                      { ...props.sliderProps }\n                    />\n                  </div>\n                </VMenu>\n              )}\n            </VIconBtn>\n\n            { props.inline && (\n              <VSlider\n                class=\"v-video-volume-inline__slider\"\n                minWidth=\"50\"\n                aria-label={ t('$vuetify.video.volume') }\n                modelValue={ volume.value }\n                onUpdate:modelValue={ v => volume.value = v }\n                onKeydown={ (e: KeyboardEvent) => { e.stopPropagation() } }\n                { ...sliderDefaults }\n                { ...props.sliderProps }\n              />\n            )}\n        </div>\n      )\n    })\n  },\n})\n\nexport type VVideoVolume = InstanceType<typeof VVideoVolume>\n"
  },
  {
    "path": "packages/vuetify/src/labs/VVideo/_variables.scss",
    "content": "@use 'sass:math';\n@use '../../styles/settings';\n\n// Defaults\n$video-player-width: 100% !default;\n$video-aspect-ratio: math.div(16, 9) !default;\n\n$video-elevation: 2 !default;\n$video-padding: 0px !default;\n$video-rounded-border-radius: settings.$border-radius-root !default;\n$video-controls-floating-margin: 12px !default;\n$video-density: ('default': 0, 'comfortable': -1, 'compact': -2) !default;\n\n$video-center-icon-border: 5px solid currentColor !default;\n$video-center-icon-opacity: .6 !default;\n$video-center-icon-hover-transform: scale(1.05) !default;\n\n$video-tube-track-top: -8px !default;\n$video-tube-track-hover-offset: 10px !default;\n\n$video-time-font-size: 0.875rem !default;\n$video-time-line-height: 1 !default;\n$video-time-letter-spacing: 0.02em !default;\n$video-time-pill-padding: 0 16px !default;\n\n$video-controls-height: 58px !default;\n$video-controls-padding: 8px !default;\n$video-controls-gap: 16px !default;\n$video-controls-pill-gap: 8px !default;\n$video-controls-pill-padding: 0 6px !default;\n$video-controls-pill-border-radius: 99px !default;\n$video-controls-pill-backdrop-filter: blur(5px) !default;\n$video-controls-default-background-opacity: .8 !default;\n$video-controls-default-background-color: var(--v-theme-surface) !default;\n$video-controls-default-color: rgb(var(--v-theme-on-surface)) !default;\n$video-controls-default-backdrop-filter: blur(5px) !default;\n$video-controls-split-time-padding-inline: 20px !default;\n$video-controls-detached-offset: 12px !default;\n$video-controls-detached-padding-inline: 12px !default;\n\n$video-volume-menu-elevation: 1 !default;\n$video-volume-menu-border-radius: settings.$border-radius-root !default;\n$video-volume-horizontal-margin: 0 16px !default;\n$video-volume-horizontal-menu-width: 100px !default;\n$video-volume-horizontal-menu-height: 40px !default;\n$video-volume-vertical-margin: 16px 0 !default;\n$video-volume-vertical-menu-width: 40px !default;\n$video-volume-vertical-menu-height: 100px !default;\n\n$video-volume-menu-border-color: rgba(var(--v-border-color), var(--v-border-opacity)) !default;\n$video-volume-menu-border-style: solid !default;\n$video-volume-menu-border-width: thin !default;\n$video-volume-menu-border-thin-width: thin !default;\n$video-volume-menu-border: (\n  $video-volume-menu-border-color,\n  $video-volume-menu-border-style,\n  $video-volume-menu-border-width,\n  $video-volume-menu-border-thin-width\n) !default;\n"
  },
  {
    "path": "packages/vuetify/src/labs/VVideo/index.ts",
    "content": "export { VVideo } from './VVideo'\nexport { VVideoControls } from './VVideoControls'\nexport { VVideoVolume } from './VVideoVolume'\n"
  },
  {
    "path": "packages/vuetify/src/labs/allComponents.ts",
    "content": "export * from '@/components'\nexport * from './components'\n"
  },
  {
    "path": "packages/vuetify/src/labs/components.ts",
    "content": "export * from './VAvatarGroup'\nexport * from './VColorInput'\nexport * from './VCommandPalette'\nexport * from './VDateInput'\nexport * from './VFileUpload'\nexport * from './VIconBtn'\nexport * from './VMaskInput'\nexport * from './VPicker'\nexport * from './VPie'\nexport * from './VStepperVertical'\nexport * from './VProgress'\nexport * from './VPullToRefresh'\nexport * from './VVideo'\n"
  },
  {
    "path": "packages/vuetify/src/labs/composables.ts",
    "content": "export * from './rules'\n"
  },
  {
    "path": "packages/vuetify/src/labs/entry-bundler.ts",
    "content": "/* eslint-disable local-rules/sort-imports */\n\n// Components\nimport * as components from './allComponents'\nimport * as directives from '@/directives'\nimport { createVuetify as _createVuetify } from '@/framework'\n\n// Types\nimport type { VuetifyOptions } from '@/framework'\n\nexport * from '@/entry-bundler'\nexport { components }\n\nexport const createVuetify = (options: VuetifyOptions = {}) => {\n  return _createVuetify({ components, directives, ...options })\n}\n"
  },
  {
    "path": "packages/vuetify/src/labs/index.ts",
    "content": "export * as components from './components'\nexport * as composables from './composables'\n"
  },
  {
    "path": "packages/vuetify/src/labs/rules/index.ts",
    "content": "export * from './rules'\nexport * from './plugin'\n"
  },
  {
    "path": "packages/vuetify/src/labs/rules/plugin.ts",
    "content": "// Composables\nimport { createRules, RulesSymbol } from './rules'\n\n// Types\nimport type { App } from 'vue'\nimport type { RulesOptions } from './rules'\nimport type { LocaleInstance } from '@/composables/locale'\n\nexport interface RulesPlugin {\n  install: (app: App) => void\n}\n\nexport function createRulesPlugin (rules: RulesOptions, locale: LocaleInstance): RulesPlugin {\n  return {\n    install (app: App) {\n      app.provide(RulesSymbol, createRules(rules, locale))\n    },\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/labs/rules/rules.ts",
    "content": "// Utilities\nimport { computed, inject, toRef } from 'vue'\n\n// Types\nimport type { InjectionKey, Ref } from 'vue'\nimport type { LocaleInstance } from '@/composables/locale'\nimport type { ValidationProps, ValidationRule } from '@/composables/validation'\n\nexport type ValidationRuleBuilderWithoutOptions = (err?: string) => ValidationRule\nexport type ValidationRuleBuilderWithOptions<T> = (options: T, err?: string) => ValidationRule\nexport type ValidationRuleBuilder =\n  | ValidationRuleBuilderWithoutOptions\n  | ValidationRuleBuilderWithOptions<any>\n\nexport interface RuleAliases {\n  [name: string]: ValidationRuleBuilder\n  required: ValidationRuleBuilderWithoutOptions\n  email: ValidationRuleBuilderWithoutOptions\n  number: ValidationRuleBuilderWithoutOptions\n  integer: ValidationRuleBuilderWithoutOptions\n  capital: ValidationRuleBuilderWithoutOptions\n  maxLength: ValidationRuleBuilderWithOptions<number>\n  minLength: ValidationRuleBuilderWithOptions<number>\n  strictLength: ValidationRuleBuilderWithOptions<number>\n  exclude: ValidationRuleBuilderWithOptions<string[]>\n  notEmpty: ValidationRuleBuilderWithoutOptions\n  pattern: ValidationRuleBuilderWithOptions<RegExp>\n}\n\nexport type RulesOptions = {\n  aliases?: Partial<RuleAliases>\n}\n\ntype ValidationRuleParams = [any, string?]\nexport type ValidationAlias = string | [string, ...ValidationRuleParams]\n\nexport type RulesInstance = {\n  resolve: (fn: () => ValidationProps['rules']) => Readonly<Ref<any[]>>\n  aliases: RuleAliases\n}\n\nexport function createRules (options: RulesOptions | undefined, locale: LocaleInstance) {\n  const { t } = locale\n\n  const aliases: RuleAliases = {\n    required: (err?: string) => {\n      return (v: any) => {\n        // If the modifier .number is used, the 0 will be a number and it's a falsy value so we need to check for it\n        return v === 0 || !!v || t(err || '$vuetify.rules.required')\n      }\n    },\n    email: (err?: string) => {\n      return (v: any) => (!v || (typeof v === 'string' && /^.+@\\S+\\.\\S+$/.test(v))) || t(err || '$vuetify.rules.email')\n    },\n    number: (err?: string) => {\n      return (v: string) => !v || !isNaN(Number(v)) || t(err || '$vuetify.rules.number')\n    },\n    integer: (err?: string) => {\n      return (v: string) => (/^[\\d]*$/.test(v)) || t(err || '$vuetify.rules.integer')\n    },\n    capital: (err?: string) => {\n      return (v: string) => (/^[A-Z]*$/.test(v)) || t(err || '$vuetify.rules.capital')\n    },\n    maxLength: (len: number, err?: string) => {\n      return (v: any) => (!v || v.length <= len) || t(err || '$vuetify.rules.maxLength', len)\n    },\n    minLength: (len: number, err?: string) => {\n      return (v: any) => (!v || v.length >= len) || t(err || '$vuetify.rules.minLength', len)\n    },\n    strictLength: (len: number, err?: string) => {\n      return (v: any) => (!v || v.length === len) || t(err || '$vuetify.rules.strictLength', len)\n    },\n    exclude: (forbiddenCharacters: string[], err?: string) => {\n      return (v: string) => {\n        let error: string | true = true\n        for (const character of forbiddenCharacters) {\n          if (v.includes(character)) error = err || t('$vuetify.rules.exclude', character)\n        }\n        return error\n      }\n    },\n    notEmpty: (err?: string) => {\n      return (v: any) => (v && v.length > 0) || t(err || '$vuetify.rules.notEmpty')\n    },\n    pattern: (pattern: RegExp, err?: string) => {\n      return (v: any) => (!v || pattern.test(v) || t(err || '$vuetify.rules.pattern'))\n    },\n\n    ...options?.aliases,\n  }\n\n  function resolve (fn: () => ValidationProps['rules']) {\n    return computed(() => fn().map(rule => {\n      let ruleName: string | null = null\n      let ruleParams: ValidationRuleParams = [undefined]\n      if (Array.isArray(rule)) {\n        ruleName = rule[0]\n        ruleParams = rule.slice(1) as ValidationRuleParams\n      } else if (typeof rule === 'string') {\n        ruleName = rule\n      }\n\n      if (ruleName !== null) {\n        if (ruleName.startsWith('$')) {\n          ruleName = ruleName.slice(1)\n        }\n\n        return aliases[ruleName]?.(...ruleParams)\n      } else {\n        return rule\n      }\n    }))\n  }\n\n  return {\n    resolve,\n    aliases,\n  }\n}\n\nexport const RulesSymbol: InjectionKey<RulesInstance> = Symbol.for('vuetify:rules')\n\nexport function useRules (): RuleAliases\nexport function useRules (fn: () => ValidationProps['rules']): Readonly<Ref<ValidationProps['rules']>> | Readonly<Ref<ValidationRule[]>>\n\nexport function useRules (fn?: () => ValidationProps['rules']) {\n  const rules = inject(RulesSymbol, null)\n\n  if (!fn) {\n    if (!rules) {\n      throw new Error('Could not find Vuetify rules injection')\n    }\n    return rules.aliases\n  }\n\n  return rules?.resolve(fn) ?? toRef(fn)\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/__tests__/index.spec.ts",
    "content": "// Utilities\nimport { unfill } from '@test'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport * as locales from '../'\n\ndescribe('locales', () => {\n  it('should have listed all available locales in index.ts', async () => {\n    const imported = Object.keys(locales).filter(key => key !== 'default')\n    const dir = fs.readdirSync(path.resolve(__dirname, '..'))\n      .filter(filename => !['adapters', 'index.ts', '__tests__'].includes(filename))\n      .map(filename => filename.replace(/\\.ts$/, '').replace('-', ''))\n\n    expect(imported).toHaveLength(dir.length)\n    expect(imported).toStrictEqual(expect.arrayContaining(dir))\n  })\n\n  it('should have same structure for all translations', () => {\n    /** replace all values of deeply nested objects with their types */\n    const enUnfilled = unfill(locales.en)\n\n    for (const [locale, messages] of Object.entries(locales)) {\n      expect({ [locale]: unfill(messages) }).toStrictEqual(expect.objectContaining({ [locale]: enUnfilled }))\n    }\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/locale/adapters/vue-i18n.ts",
    "content": "// Composables\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { toRef, watch } from 'vue'\n\n// Types\nimport type { Ref } from 'vue'\nimport type { I18n, useI18n } from 'vue-i18n'\nimport type { LocaleInstance, LocaleMessages, LocaleOptions } from '@/composables/locale'\n\ntype VueI18nAdapterParams = {\n  i18n: I18n<any, {}, {}, string, false>\n  useI18n: typeof useI18n\n}\n\nfunction useProvided <T> (props: any, prop: string, provided: Ref<T>) {\n  const internal = useProxiedModel(props, prop)\n\n  internal.value = props[prop] ?? provided.value\n\n  watch(provided, v => {\n    if (props[prop] == null) {\n      internal.value = v\n    }\n  })\n\n  return internal as Ref<T>\n}\n\nfunction inferDecimalSeparator (format: (v: number) => string) {\n  return format(0.1).includes(',') ? ',' : '.'\n}\n\nfunction createProvideFunction (data: {\n  current: Ref<string>\n  fallback: Ref<string>\n  messages: Ref<LocaleMessages>\n  useI18n: typeof useI18n\n}) {\n  return (props: LocaleOptions): LocaleInstance => {\n    const current = useProvided(props, 'locale', data.current)\n    const fallback = useProvided(props, 'fallback', data.fallback)\n    const messages = useProvided(props, 'messages', data.messages)\n\n    const i18n = data.useI18n({\n      locale: current.value,\n      fallbackLocale: fallback.value,\n      messages: messages.value as any,\n      useScope: 'local',\n      legacy: false,\n      inheritLocale: false,\n    })\n\n    watch(current, v => {\n      i18n.locale.value = v\n    })\n\n    return {\n      name: 'vue-i18n',\n      current,\n      fallback,\n      messages,\n      decimalSeparator: toRef(() => props.decimalSeparator ?? inferDecimalSeparator(i18n.n)),\n      t: (key: string, ...params: unknown[]) => i18n.t(key, params),\n      n: i18n.n,\n      provide: createProvideFunction({ current, fallback, messages, useI18n: data.useI18n }),\n    }\n  }\n}\n\nexport function createVueI18nAdapter ({ i18n, useI18n }: VueI18nAdapterParams): LocaleInstance {\n  const current = i18n.global.locale\n  const fallback = i18n.global.fallbackLocale as Ref<any>\n  const messages = i18n.global.messages\n\n  return {\n    name: 'vue-i18n',\n    current,\n    fallback,\n    messages,\n    decimalSeparator: toRef(() => inferDecimalSeparator(i18n.global.n)),\n    t: (key: string, ...params: unknown[]) => i18n.global.t(key, params),\n    n: i18n.global.n,\n    provide: createProvideFunction({ current, fallback, messages, useI18n }),\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/adapters/vuetify.ts",
    "content": "// Composables\nimport { useProxiedModel } from '@/composables/proxiedModel'\n\n// Utilities\nimport { ref, shallowRef, toRef, watch } from 'vue'\nimport { consoleError, consoleWarn, getObjectValueByPath } from '@/util'\n\n// Locales\nimport en from '@/locale/en'\n\n// Types\nimport type { Ref } from 'vue'\nimport type { LocaleInstance, LocaleMessages, LocaleOptions } from '@/composables/locale'\n\nconst LANG_PREFIX = '$vuetify.'\n\nconst replace = (str: string, params: unknown[]) => {\n  return str.replace(/\\{(\\d+)\\}/g, (match: string, index: string) => {\n    return String(params[Number(index)])\n  })\n}\n\nconst createTranslateFunction = (\n  current: Ref<string>,\n  fallback: Ref<string>,\n  messages: Ref<LocaleMessages>,\n) => {\n  return (key: string, ...params: unknown[]) => {\n    if (!key.startsWith(LANG_PREFIX)) {\n      return replace(key, params)\n    }\n\n    const shortKey = key.replace(LANG_PREFIX, '')\n    const currentLocale = current.value && messages.value[current.value]\n    const fallbackLocale = fallback.value && messages.value[fallback.value]\n\n    let str: string = getObjectValueByPath(currentLocale, shortKey, null)\n\n    if (!str) {\n      consoleWarn(`Translation key \"${key}\" not found in \"${current.value}\", trying fallback locale`)\n      str = getObjectValueByPath(fallbackLocale, shortKey, null)\n    }\n\n    if (!str) {\n      consoleError(`Translation key \"${key}\" not found in fallback`)\n      str = key\n    }\n\n    if (typeof str !== 'string') {\n      consoleError(`Translation key \"${key}\" has a non-string value`)\n      str = key\n    }\n\n    return replace(str, params)\n  }\n}\n\nfunction createNumberFunction (current: Ref<string>, fallback: Ref<string>) {\n  return (value: number, options?: Intl.NumberFormatOptions) => {\n    const numberFormat = new Intl.NumberFormat([current.value, fallback.value], options)\n\n    return numberFormat.format(value)\n  }\n}\n\nfunction inferDecimalSeparator (current: Ref<string>, fallback: Ref<string>) {\n  const format = createNumberFunction(current, fallback)\n  return format(0.1).includes(',') ? ',' : '.'\n}\n\nfunction useProvided <T> (props: any, prop: string, provided: Ref<T>) {\n  const internal = useProxiedModel(props, prop, props[prop] ?? provided.value)\n\n  // TODO: Remove when defaultValue works\n  internal.value = props[prop] ?? provided.value\n\n  watch(provided, v => {\n    if (props[prop] == null) {\n      internal.value = provided.value\n    }\n  })\n\n  return internal as Ref<T>\n}\n\nfunction createProvideFunction (state: { current: Ref<string>, fallback: Ref<string>, messages: Ref<LocaleMessages> }) {\n  return (props: LocaleOptions): LocaleInstance => {\n    const current = useProvided(props, 'locale', state.current)\n    const fallback = useProvided(props, 'fallback', state.fallback)\n    const messages = useProvided(props, 'messages', state.messages)\n\n    return {\n      name: 'vuetify',\n      current,\n      fallback,\n      messages,\n      decimalSeparator: toRef(() => inferDecimalSeparator(current, fallback)),\n      t: createTranslateFunction(current, fallback, messages),\n      n: createNumberFunction(current, fallback),\n      provide: createProvideFunction({ current, fallback, messages }),\n    }\n  }\n}\n\nexport function createVuetifyAdapter (options?: LocaleOptions): LocaleInstance {\n  const current = shallowRef(options?.locale ?? 'en')\n  const fallback = shallowRef(options?.fallback ?? 'en')\n  const messages = ref({ en, ...options?.messages })\n\n  return {\n    name: 'vuetify',\n    current,\n    fallback,\n    messages,\n    decimalSeparator: toRef(() => options?.decimalSeparator ?? inferDecimalSeparator(current, fallback)),\n    t: createTranslateFunction(current, fallback, messages),\n    n: createNumberFunction(current, fallback),\n    provide: createProvideFunction({ current, fallback, messages }),\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/af.ts",
    "content": "export default {\n  badge: 'Kenteken',\n  open: 'Maak oop',\n  close: 'Maak toe',\n  dismiss: 'Verwerp',\n  confirmEdit: {\n    ok: 'OK',\n    cancel: 'Kanselleer',\n  },\n  dataIterator: {\n    noResultsText: 'Geen ooreenstemmende resultate is gevind nie',\n    loadingText: 'Laai item...',\n  },\n  dataTable: {\n    itemsPerPageText: 'Rye per bladsy:',\n    ariaLabel: {\n      sortDescending: 'Gesorteer aflopend.',\n      sortAscending: 'Gesorteer oplopend.',\n      sortNone: 'Nie gesorteer nie.',\n      activateNone: 'Aktiveer om sortering te verwyder.',\n      activateDescending: 'Aktiveer om aflopend te sorteer.',\n      activateAscending: 'Aktiveer om oplopend te sorteer.',\n    },\n    sortBy: 'Sorteer volgens',\n  },\n  dataFooter: {\n    itemsPerPageText: 'Aantal per bladsy:',\n    itemsPerPageAll: 'Alles',\n    nextPage: 'Volgende bladsy',\n    prevPage: 'Vorige bladsy',\n    firstPage: 'Eerste bladsy',\n    lastPage: 'Laaste bladsy',\n    pageText: '{0}-{1} van {2}',\n  },\n  dateRangeInput: {\n    divider: 'tot',\n  },\n  datePicker: {\n    itemsSelected: '{0} gekies',\n    range: {\n      title: 'Kies datums',\n      header: 'Voer datums in',\n    },\n    title: 'Kies datum',\n    header: 'Voer datum in',\n    input: {\n      placeholder: 'Voer datum in',\n    },\n    ariaLabel: {\n      previousMonth: 'Vorige maand',\n      nextMonth: 'Volgende maand',\n      selectYear: 'Kies jaar',\n      previousYear: 'Vorige jaar',\n      nextYear: 'Volgende jaar',\n      selectMonth: 'Kies maand',\n      selectDate: '{0}',\n      currentDate: 'Vandag, {0}',\n    },\n  },\n  noDataText: 'Geen data is beskikbaar nie',\n  carousel: {\n    prev: 'Vorige visuele',\n    next: 'Volgende visuele',\n    ariaLabel: {\n      delimiter: 'Carousel skyfie {0} van {1}',\n    },\n  },\n  calendar: {\n    moreEvents: '{0} meer',\n    today: 'Vandag',\n  },\n  input: {\n    clear: 'Maak skoon {0}',\n    prependAction: '{0} voorafgevoegde aksie',\n    appendAction: '{0} bygevoegde aksie',\n    otp: 'Voer asseblief OTP-karakter {0} in',\n  },\n  fileInput: {\n    counter: '{0} lêers',\n    counterSize: '{0} lêers ({1} in totaal)',\n  },\n  fileUpload: {\n    title: 'Sleep en los lêers hier',\n    divider: 'of',\n    browse: 'Blaai deur lêers',\n  },\n  timePicker: {\n    am: 'VM',\n    pm: 'NM',\n    title: 'Kies tyd',\n    hour: 'Uur',\n    minute: 'Minute',\n    second: 'Sekondes',\n    notAllowed: 'Waarde word nie toegelaat nie',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'Paginasie-navigasie',\n      next: 'Volgende bladsy',\n      previous: 'Vorige bladsy',\n      page: 'Gaan na bladsy {0}',\n      currentPage: 'Huidige bladsy, Bladsy {0}',\n      first: 'Eerste bladsy',\n      last: 'Laaste bladsy',\n    },\n  },\n  stepper: {\n    next: 'Volgende',\n    prev: 'Vorige',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'Gradering {0} van {1}',\n    },\n  },\n  loading: 'Laai...',\n  infiniteScroll: {\n    loadMore: 'Laai meer',\n    empty: 'Geen meer nie',\n  },\n  rules: {\n    required: 'Hierdie veld is verpligtend',\n    email: 'Voer asseblief \\'n geldige e-posadres in',\n    number: 'Hierdie veld kan slegs syfers bevat',\n    integer: 'Hierdie veld kan slegs heelgetalle bevat',\n    capital: 'Hierdie veld kan slegs hoofletters bevat',\n    maxLength: 'Jy moet \\'n maksimum van {0} karakters invoer',\n    minLength: 'Jy moet \\'n minimum van {0} karakters invoer',\n    strictLength: 'Die lengte van die ingevoerde veld is ongeldig',\n    exclude: 'Die {0} karakter is nie toegelaat nie',\n    notEmpty: 'Kies asseblief ten minste een waarde',\n    pattern: 'Ongeldige formaat',\n  },\n  command: {\n    search: 'Tik \\'n opdrag of soek...',\n  },\n  hotkey: {\n    then: 'dan',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: 'Up Arrow',\n    downArrow: 'Down Arrow',\n    leftArrow: 'Left Arrow',\n    rightArrow: 'Right Arrow',\n    backspace: 'Backspace',\n    space: 'Spasie',\n    plus: 'plus',\n    shortcut: 'Sleutelbordkortpad: {0}',\n    or: 'of',\n  },\n  video: {\n    play: 'Speel',\n    pause: 'Pouseer',\n    seek: 'Soek',\n    volume: 'Volume',\n    showVolume: 'Wys volumebeheer',\n    mute: 'Demp',\n    unmute: 'Ontdemp',\n    enterFullscreen: 'Volskerm',\n    exitFullscreen: 'Verlaat volskerm',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'Kies kleur van die skerm af',\n      hueSlider: 'Tint',\n      alphaSlider: 'Alfa',\n      redInput: 'Rooi',\n      greenInput: 'Groen',\n      blueInput: 'Blou',\n      alphaInput: 'Alfa',\n      hueInput: 'Tint',\n      saturationInput: 'Versadiging',\n      lightnessInput: 'Ligtheid',\n      hexInput: 'HEX-waarde',\n      hexaInput: 'HEX met alfa-waarde',\n      changeFormat: 'Verander kleurformaat',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/ar.ts",
    "content": "export default {\n  badge: 'شارة',\n  open: 'Open',\n  close: 'إغلاق',\n  dismiss: 'Dismiss',\n  confirmEdit: {\n    ok: 'OK',\n    cancel: 'Cancel',\n  },\n  dataIterator: {\n    noResultsText: 'لم يتم إيجاد نتائج',\n    loadingText: 'يتم جلب العناصر...',\n  },\n  dataTable: {\n    itemsPerPageText: 'عدد الصفوف لكل صفحة:',\n    ariaLabel: {\n      sortDescending: 'مرتب تنازلياً.',\n      sortAscending: 'مرتب تصاعدياً.',\n      sortNone: 'غير مرتب.',\n      activateNone: 'نشط لإزالة الترتيب.',\n      activateDescending: 'نشط للترتيب تنازلياً.',\n      activateAscending: 'نشط للترتيب تصاعدياً.',\n    },\n    sortBy: 'رتب حسب',\n  },\n  dataFooter: {\n    itemsPerPageText: 'عدد العناصر لكل صفحة:',\n    itemsPerPageAll: 'الكل',\n    nextPage: 'الصفحة التالية',\n    prevPage: 'الصفحة السابقة',\n    firstPage: 'الصفحة الأولى',\n    lastPage: 'الصفحة الأخيرة',\n    pageText: '{0}-{1} من {2}',\n  },\n  dateRangeInput: {\n    divider: 'to',\n  },\n  datePicker: {\n    itemsSelected: '{0} محدد',\n    range: {\n      title: 'اختر التواريخ',\n      header: 'أدخل التواريخ',\n    },\n    title: 'اختر التاريخ',\n    header: 'أدخل التاريخ',\n    input: {\n      placeholder: 'أدخل التاريخ',\n    },\n    ariaLabel: {\n      previousMonth: 'الشهر السابق',\n      nextMonth: 'الشهر التالي',\n      selectYear: 'اختر السنة',\n      previousYear: 'السنة السابقة',\n      nextYear: 'السنة التالية',\n      selectMonth: 'اختر الشهر',\n      selectDate: '{0}',\n      currentDate: 'اليوم، {0}',\n    },\n  },\n  noDataText: 'لا توجد بيانات',\n  carousel: {\n    prev: 'المعروض السابق',\n    next: 'المعروض التالي',\n    ariaLabel: {\n      delimiter: 'المعروض رقم {0} من {1}',\n    },\n  },\n  calendar: {\n    moreEvents: '{0} أكثر',\n    today: 'Today',\n  },\n  input: {\n    clear: 'Clear {0}',\n    prependAction: '{0} prepended action',\n    appendAction: '{0} appended action',\n    otp: 'Please enter OTP character {0}',\n  },\n  fileInput: {\n    counter: '{0} ملفات',\n    counterSize: '{0} ملفات ({1} في المجموع)',\n  },\n  fileUpload: {\n    title: 'Drag and drop files here',\n    divider: 'or',\n    browse: 'Browse Files',\n  },\n  timePicker: {\n    am: 'صباحاً',\n    pm: 'مساءً',\n    title: 'حدد الوقت',\n    hour: 'ساعة',\n    minute: 'دقائق',\n    second: 'ثواني',\n    notAllowed: 'القيمة غير مسموح بها',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'الإنتقال بين الصفحات',\n      next: 'الصفحة التالية',\n      previous: 'الصفحة السابقة',\n      page: '{0} انتقل إلى الصفحة',\n      currentPage: '{0} الصفحة الحالية رقمها',\n      first: 'First page',\n      last: 'Last page',\n    },\n  },\n  stepper: {\n    next: 'Next',\n    prev: 'Previous',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'القييم {0} من {1}',\n    },\n  },\n  loading: 'Loading...',\n  infiniteScroll: {\n    loadMore: 'Load more',\n    empty: 'No more',\n  },\n  rules: {\n    required: 'هذه الخانة مطلوبه',\n    email: 'يرجى إدخال بريد إلكتروني صالح',\n    number: 'هذه الخانة يمكن أن تحتوي على أرقام فقط',\n    integer: 'هذه الخانة يمكن أن تحتوي على أعداد صحيحة فقط',\n    capital: 'هذه الخانة يمكن أن تحتوي على أحرف كبيرة فقط',\n    maxLength: 'يجب أن تدخل بحد أقصى {0} حرف',\n    minLength: 'يجب أن تدخل بحد أدنى {0} حرف',\n    strictLength: 'طول الحقل المدخل غير صالح',\n    exclude: 'الحرف {0} غير مسموح به',\n    notEmpty: 'يرجى اختيار قيمة واحدة على الأقل',\n    pattern: 'تنسيق غير صالح',\n  },\n  command: {\n    search: 'اكتب أمراً أو ابحث...',\n  },\n  hotkey: {\n    then: 'ثم',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: 'السهم العلوي',\n    downArrow: 'السهم السفلي',\n    leftArrow: 'السهم الأيسر',\n    rightArrow: 'السهم الأيمن',\n    backspace: 'مسافة للخلف',\n    space: 'مسافة',\n    plus: 'زائد',\n    shortcut: 'اختصار لوحة المفاتيح: {0}',\n    or: 'or',\n  },\n  video: {\n    play: 'تشغيل',\n    pause: 'إيقاف مؤقت',\n    seek: 'بحث',\n    volume: 'مستوى الصوت',\n    showVolume: 'إظهار التحكم في مستوى الصوت',\n    mute: 'كتم الصوت',\n    unmute: 'إلغاء كتم الصوت',\n    enterFullscreen: 'ملء الشاشة',\n    exitFullscreen: 'الخروج من وضع ملء الشاشة',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'اختيار لون من الشاشة',\n      hueSlider: 'درجة اللون',\n      alphaSlider: 'الشفافية',\n      redInput: 'أحمر',\n      greenInput: 'أخضر',\n      blueInput: 'أزرق',\n      alphaInput: 'الشفافية',\n      hueInput: 'درجة اللون',\n      saturationInput: 'التشبع اللوني',\n      lightnessInput: 'السطوع',\n      hexInput: 'قيمة HEX',\n      hexaInput: 'قيمة HEX مع الشفافية',\n      changeFormat: 'تغيير تنسيق اللون',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/az.ts",
    "content": "export default {\n  badge: 'Nişan',\n  open: 'Açıq',\n  close: 'Bağla',\n  dismiss: 'Rədd et',\n  confirmEdit: {\n    ok: 'OK',\n    cancel: 'İmtina',\n  },\n  dataIterator: {\n    noResultsText: 'Uyğun məlumat tapılmadı',\n    loadingText: 'Yüklənir... Zəhmət olmasa, gözləyin.',\n  },\n  dataTable: {\n    itemsPerPageText: 'Səhifə başı sətir sayı:',\n    ariaLabel: {\n      sortDescending: 'Azalan sıra ilə düzülmüş.',\n      sortAscending: 'Artan sıra ilə düzülmüş.',\n      sortNone: 'Sıralanmamışdır.',\n      activateNone: 'Sıralamanı yığışdır.',\n      activateDescending: 'Azalan sıra ilə düz.',\n      activateAscending: 'Artan sıra ilə düz.',\n    },\n    sortBy: 'Sırala',\n  },\n  dataFooter: {\n    itemsPerPageText: 'Səhifə başı sətir sayı:',\n    itemsPerPageAll: 'Hamısı',\n    nextPage: 'Növbəti səhifə',\n    prevPage: 'Əvvəlki səhifə',\n    firstPage: 'İlk səhifə',\n    lastPage: 'Son səhifə',\n    pageText: '{0} - {1} arası, Cəmi: {2} qeydiyyat',\n  },\n  dateRangeInput: {\n    divider: 'ilə',\n  },\n  datePicker: {\n    itemsSelected: '{0} seçilib',\n    range: {\n      title: 'Tarixləri seçin',\n      header: 'Tarixləri daxil edin',\n    },\n    title: 'Tarixi seçin',\n    header: 'Tarixi daxil edin',\n    input: {\n      placeholder: 'Tarixi daxil edin',\n    },\n    ariaLabel: {\n      previousMonth: 'Əvvəlki ay',\n      nextMonth: 'Növbəti ay',\n      selectYear: 'İli seçin',\n      previousYear: 'Əvvəlki il',\n      nextYear: 'Növbəti il',\n      selectMonth: 'Ayı seçin',\n      selectDate: '{0}',\n      currentDate: 'Bu gün, {0}',\n    },\n  },\n  noDataText: 'Heç bir məlumat yoxdur.',\n  carousel: {\n    prev: 'Əvvəlki görüntü',\n    next: 'Növbəti görüntü',\n    ariaLabel: {\n      delimiter: 'Galereya səhifə {0} / {1}',\n    },\n  },\n  calendar: {\n    moreEvents: '{0} ədəd daha',\n    today: 'Bu gün',\n  },\n  input: {\n    clear: 'Təmizlə {0}',\n    prependAction: '{0} qabaqcıl əməliyyat',\n    appendAction: '{0} sonrakı əməliyyat',\n    otp: 'OTP daxil et {0}',\n  },\n  fileInput: {\n    counter: '{0} fayl',\n    counterSize: '{0} fayl (cəmi {1})',\n  },\n  fileUpload: {\n    title: 'Faylları buraya sürüşdürün',\n    divider: 'və ya',\n    browse: 'Fayllara baxın',\n  },\n  timePicker: {\n    am: 'Səhər',\n    pm: 'Axşam',\n    title: 'Vaxtı seçin',\n    hour: 'Saat',\n    minute: 'Dəqiqə',\n    second: 'Saniyə',\n    notAllowed: 'Dəyərə icazə verilmir',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'Səhifələmə Naviqasiyası',\n      next: 'Növbəti səhifə',\n      previous: 'Əvvəlki səhifə',\n      page: 'Səhifəyə get {0}',\n      currentPage: 'Cari səhifə, Səhifə {0}',\n      first: 'İlk səhifə',\n      last: 'Son səhifə',\n    },\n  },\n  stepper: {\n    next: 'Növbəti',\n    prev: 'Əvvəlki',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'Reytinq {0}/{1}',\n    },\n  },\n  loading: 'Yüklənir...',\n  infiniteScroll: {\n    loadMore: 'Daha çox yüklə',\n    empty: 'Daha yoxdur',\n  },\n  rules: {\n    required: 'Bu sahə tələb olunur',\n    email: 'Zəhmət olmasa etibarlı bir e-poçt daxil edin',\n    number: 'Bu sahə yalnız rəqəmlərdən ibarət ola bilər',\n    integer: 'Bu sahə yalnız tam ədədlərdən ibarət ola bilər',\n    capital: 'Bu sahə yalnız böyük hərflərdən ibarət ola bilər',\n    maxLength: 'Maksimum {0} simvol daxil etməlisiniz',\n    minLength: 'Minimum {0} simvol daxil etməlisiniz',\n    strictLength: 'Daxil edilən sahənin uzunluğu yanlışdır',\n    exclude: '{0} simvoluna icazə verilmir',\n    notEmpty: 'Zəhmət olmasa ən azı bir dəyər seçin',\n    pattern: 'Yanlış format',\n  },\n  command: {\n    search: 'Əmr yazın və ya axtarış edin...',\n  },\n  hotkey: {\n    then: 'sonra',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: 'Yuxarı Ox',\n    downArrow: 'Aşağı Ox',\n    leftArrow: 'Sol Ox',\n    rightArrow: 'Sağ Ox',\n    backspace: 'Geri Sil',\n    space: 'Boşluq',\n    plus: 'plus',\n    shortcut: 'Klaviatura qısayolu: {0}',\n    or: 'və ya',\n  },\n  video: {\n    play: 'Oynat',\n    pause: 'Pauza',\n    seek: 'Axtar',\n    volume: 'Səs',\n    showVolume: 'Səs səviyyəsini göstər',\n    mute: 'Səsi kəs',\n    unmute: 'Səsi aç',\n    enterFullscreen: 'Tam ekran',\n    exitFullscreen: 'Tam ekrandan çıx',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'Ekrandan rəng seçin',\n      hueSlider: 'Rəng çaları',\n      alphaSlider: 'Alfa',\n      redInput: 'Qırmızı',\n      greenInput: 'Yaşıl',\n      blueInput: 'Mavi',\n      alphaInput: 'Alfa',\n      hueInput: 'Rəng çaları',\n      saturationInput: 'Doyğunluq',\n      lightnessInput: 'Açıqlıq',\n      hexInput: 'HEX dəyəri',\n      hexaInput: 'Alfa dəyəri ilə HEX',\n      changeFormat: 'Rəng formatını dəyişdirin',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/bg.ts",
    "content": "export default {\n  badge: 'Значка',\n  open: 'Отвори',\n  close: 'Затвори',\n  dismiss: 'Отхвърли',\n  confirmEdit: {\n    ok: 'OK',\n    cancel: 'Отмяна',\n  },\n  dataIterator: {\n    noResultsText: 'Не са намерени записи',\n    loadingText: 'Зареждане на елементи...',\n  },\n  dataTable: {\n    itemsPerPageText: 'Редове на страница:',\n    ariaLabel: {\n      sortDescending: 'Подреди в намаляващ ред.',\n      sortAscending: 'Подреди в нарастващ ред.',\n      sortNone: 'Без подредба.',\n      activateNone: 'Активирай за премахване на подредбата.',\n      activateDescending: 'Активирай за подредба в намаляващ ред.',\n      activateAscending: 'Активирай за подредба в нарастващ ред.',\n    },\n    sortBy: 'Сортирай по',\n  },\n  dataFooter: {\n    itemsPerPageText: 'Елементи на страница:',\n    itemsPerPageAll: 'Всички',\n    nextPage: 'Следваща страница',\n    prevPage: 'Предишна страница',\n    firstPage: 'Първа страница',\n    lastPage: 'Последна страница',\n    pageText: '{0}-{1} от {2}',\n  },\n  dateRangeInput: {\n    divider: 'до',\n  },\n  datePicker: {\n    itemsSelected: '{0} избрани',\n    range: {\n      title: 'Избор на дати',\n      header: 'Въвеждане на дати',\n    },\n    title: 'Избор на дата',\n    header: 'Въвеждане на дата',\n    input: {\n      placeholder: 'Въведете дата',\n    },\n    ariaLabel: {\n      previousMonth: 'Предишен месец',\n      nextMonth: 'Следващ месец',\n      selectYear: 'Изберете година',\n      previousYear: 'Предишна година',\n      nextYear: 'Следваща година',\n      selectMonth: 'Изберете месец',\n      selectDate: '{0}',\n      currentDate: 'Днес, {0}',\n    },\n  },\n  noDataText: 'Няма налични данни',\n  carousel: {\n    prev: 'Предишна визуализация',\n    next: 'Следваща визуализация',\n    ariaLabel: {\n      delimiter: 'Кадър {0} от {1} на въртележката',\n    },\n  },\n  calendar: {\n    moreEvents: 'Още {0}',\n    today: 'Днес',\n  },\n  input: {\n    clear: 'Изчисти {0}',\n    prependAction: '{0} предшестващо действие',\n    appendAction: '{0} последващо действие',\n    otp: 'Моля, въведете OTP символ {0}',\n  },\n  fileInput: {\n    counter: '{0} файла',\n    counterSize: '{0} файла ({1} общо)',\n  },\n  fileUpload: {\n    title: 'Плъзнете и пуснете файлове тук',\n    divider: 'или',\n    browse: 'Разгледайте файлове',\n  },\n  timePicker: {\n    am: 'пр. обяд',\n    pm: 'сл. обяд',\n    title: 'Изберете време',\n    hour: 'Час',\n    minute: 'Минути',\n    second: 'Секунди',\n    notAllowed: 'Стойността не е разрешена',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'Странициране',\n      next: 'Следваща страница',\n      previous: 'Предишна страница',\n      page: 'Отиди на страница {0}',\n      currentPage: 'Текуща страница, Страница {0}',\n      first: 'Първа страница',\n      last: 'Последна страница',\n    },\n  },\n  stepper: {\n    next: 'Следващ',\n    prev: 'Предишен',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'Оценка {0} от {1}',\n    },\n  },\n  loading: 'Зареждане...',\n  infiniteScroll: {\n    loadMore: 'Зареди още',\n    empty: 'Няма повече',\n  },\n  rules: {\n    required: 'Това поле е задължително',\n    email: 'Моля, въведете валиден имейл',\n    number: 'Това поле може да съдържа само числа',\n    integer: 'Това поле може да съдържа само цели числа',\n    capital: 'Това поле може да съдържа само главни букви',\n    maxLength: 'Трябва да въведете максимум {0} символа',\n    minLength: 'Трябва да въведете минимум {0} символа',\n    strictLength: 'Дължината на въведеното поле е невалидна',\n    exclude: 'Символът {0} не е позволен',\n    notEmpty: 'Моля, изберете поне една стойност',\n    pattern: 'Невалиден формат',\n  },\n  command: {\n    search: 'Въведете команда или търсете...',\n  },\n  hotkey: {\n    then: 'след това',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: 'Горна стрелка',\n    downArrow: 'Долна стрелка',\n    leftArrow: 'Лява стрелка',\n    rightArrow: 'Дясна стрелка',\n    backspace: 'Връщане назад',\n    space: 'Интервал',\n    plus: 'плюс',\n    shortcut: 'Клавиатурна комбинация: {0}',\n    or: 'или',\n  },\n  video: {\n    play: 'Пусни',\n    pause: 'Пауза',\n    seek: 'Търсене',\n    volume: 'Сила на звука',\n    showVolume: 'Покажи контрола за силата на звука',\n    mute: 'Без звук',\n    unmute: 'Включи звука',\n    enterFullscreen: 'Цял екран',\n    exitFullscreen: 'Изход от цял екран',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'Вземане на цвят от екрана',\n      hueSlider: 'Цветови тон',\n      alphaSlider: 'Алфа',\n      redInput: 'Червено',\n      greenInput: 'Зелено',\n      blueInput: 'Синьо',\n      alphaInput: 'Алфа',\n      hueInput: 'Цветови тон',\n      saturationInput: 'Наситеност',\n      lightnessInput: 'Светлина',\n      hexInput: 'HEX стойност',\n      hexaInput: 'HEX стойност с алфа',\n      changeFormat: 'Промяна на цветовия формат',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/ca.ts",
    "content": "export default {\n  badge: 'Insígnia',\n  open: 'Obrir',\n  close: 'Tancar',\n  dismiss: 'Descartar',\n  confirmEdit: {\n    ok: 'OK',\n    cancel: 'Cancel·lar',\n  },\n  dataIterator: {\n    noResultsText: 'Sense dades per mostrar',\n    loadingText: 'Carregant...',\n  },\n  dataTable: {\n    itemsPerPageText: 'Files per pàgina:',\n    ariaLabel: {\n      sortDescending: 'Ordre descendent.',\n      sortAscending: 'Ordre ascendent.',\n      sortNone: 'Sense ordenar.',\n      activateNone: 'Premi per treure la ordenació.',\n      activateDescending: 'Premi per ordenar descendent.',\n      activateAscending: 'Premi per ordenar ascendent.',\n    },\n    sortBy: 'Ordenat per',\n  },\n  dataFooter: {\n    itemsPerPageText: 'Elements per pàgina:',\n    itemsPerPageAll: 'Tot',\n    nextPage: 'Pàgina següent',\n    prevPage: 'Pàgina anterior',\n    firstPage: 'Primera pàgina',\n    lastPage: 'Última pàgina',\n    pageText: '{0}-{1} de {2}',\n  },\n  dateRangeInput: {\n    divider: 'fins a',\n  },\n  datePicker: {\n    itemsSelected: '{0} seleccionats',\n    range: {\n      title: 'Selecciona dates',\n      header: 'Introdueix les dates',\n    },\n    title: 'Selecciona data',\n    header: 'Introdueix la data',\n    input: {\n      placeholder: 'Introdueix la data',\n    },\n    ariaLabel: {\n      previousMonth: 'Mes anterior',\n      nextMonth: 'Mes següent',\n      selectYear: 'Selecciona any',\n      previousYear: 'Any anterior',\n      nextYear: 'Any següent',\n      selectMonth: 'Selecciona mes',\n      selectDate: '{0}',\n      currentDate: 'Avui, {0}',\n    },\n  },\n  noDataText: 'Sense dades',\n  carousel: {\n    prev: 'Visualització prèvia',\n    next: 'Visualització següent',\n    ariaLabel: {\n      delimiter: 'Diapositiva {0} de {1}',\n    },\n  },\n  calendar: {\n    moreEvents: '{0} més',\n    today: 'Avui',\n  },\n  input: {\n    clear: 'Esborra {0}',\n    prependAction: 'Acció prefixada {0}',\n    appendAction: 'Acció afegida {0}',\n    otp: 'Si us plau, introdueix el caràcter OTP {0}',\n  },\n  fileInput: {\n    counter: '{0} fitxers',\n    counterSize: '{0} fitxers ({1} en total)',\n  },\n  fileUpload: {\n    title: 'Arrossega i deixa anar els fitxers aquí',\n    divider: 'o',\n    browse: 'Explora fitxers',\n  },\n  timePicker: {\n    am: 'AM',\n    pm: 'PM',\n    title: 'Selecciona l’hora',\n    hour: 'Hora',\n    minute: 'Minuts',\n    second: 'Segons',\n    notAllowed: 'El valor no està permès',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'Navegació de la pàgina',\n      next: 'Pàgina següent',\n      previous: 'Pàgina anterior',\n      page: 'Ves a la pàgina {0}',\n      currentPage: 'Pàgina actual, pàgina {0}',\n      first: 'Primera pàgina',\n      last: 'Última pàgina',\n    },\n  },\n  stepper: {\n    next: 'Següent',\n    prev: 'Anterior',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'Puntuació {0} de {1}',\n    },\n  },\n  loading: 'Carregant...',\n  infiniteScroll: {\n    loadMore: 'Carrega més',\n    empty: 'No hi ha més',\n  },\n  rules: {\n    required: 'Aquest camp és obligatori',\n    email: 'Si us plau, introdueix un correu electrònic vàlid',\n    number: 'Aquest camp només pot contenir números',\n    integer: 'Aquest camp només pot contenir valors enters',\n    capital: 'Aquest camp només pot contenir lletres majúscules',\n    maxLength: 'Has d’introduir un màxim de {0} caràcters',\n    minLength: 'Has d’introduir un mínim de {0} caràcters',\n    strictLength: 'La longitud del camp introduït no és vàlida',\n    exclude: 'El caràcter {0} no està permès',\n    notEmpty: 'Si us plau, tria almenys un valor',\n    pattern: 'Format no vàlid',\n  },\n  command: {\n    search: 'Escriu una ordre o cerca...',\n  },\n  hotkey: {\n    then: 'després',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Intro',\n    escape: 'Escape',\n    upArrow: 'Fletxa amunt',\n    downArrow: 'Fletxa avall',\n    leftArrow: 'Fletxa esquerra',\n    rightArrow: 'Fletxa dreta',\n    backspace: 'Retrocés',\n    space: 'Espai',\n    plus: 'més',\n    shortcut: 'Drecera de teclat: {0}',\n    or: 'o',\n  },\n  video: {\n    play: 'Reproduir',\n    pause: 'Paura',\n    seek: 'Cercar',\n    volume: 'Volum',\n    showVolume: 'Mostrar control de volum',\n    mute: 'Silenciar',\n    unmute: 'Activar so',\n    enterFullscreen: 'Pantalla completa',\n    exitFullscreen: 'Sortir de pantalla completa',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'Seleccionar color de la pantalla',\n      hueSlider: 'To',\n      alphaSlider: 'Alfa',\n      redInput: 'Vermell',\n      greenInput: 'Verd',\n      blueInput: 'Blau',\n      alphaInput: 'Alfa',\n      hueInput: 'To',\n      saturationInput: 'Saturació',\n      lightnessInput: 'Lluminositat',\n      hexInput: 'Valor HEX',\n      hexaInput: 'Valor HEX amb alfa',\n      changeFormat: 'Canviar format de color',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/ckb.ts",
    "content": "export default {\n  badge: 'باج',\n  open: 'کردنەوە',\n  close: 'داخستن',\n  dismiss: 'ڕەتکردنەوە',\n  confirmEdit: {\n    ok: 'باشە',\n    cancel: 'هەڵوەشاندنەوە',\n  },\n  dataIterator: {\n    noResultsText: 'هیچ تۆمارێکی هاوتا نەدۆزرایەوە',\n    loadingText: 'بارکردنی ئایتمەکان...',\n  },\n  dataTable: {\n    itemsPerPageText: 'ڕیزەکان بۆ هەر پەڕەیەک:',\n    ariaLabel: {\n      sortDescending: '.سەر بەرەو خوار ڕیزکراوە',\n      sortAscending: '.سەر بەرەو ژوور ڕیزکراوە',\n      sortNone: 'ڕیزنەکراوە.',\n      activateNone: 'چالاککردن بۆ لابردنی ڕیزکردن.',\n      activateDescending: 'چالاککردن بۆ ڕیزکردنی سەربەرەوخوار.',\n      activateAscending: 'چالاککردن بۆ ڕیزکردنی سەر بەرەو ژوور.',\n    },\n    sortBy: 'ڕیزکردن بەپێی',\n  },\n  dataFooter: {\n    itemsPerPageText: 'ئایتمەکان بۆ هەر پەڕەیەک:',\n    itemsPerPageAll: 'هەمووی',\n    nextPage: 'پەڕەی دواتر',\n    prevPage: 'پەڕەی پێشوو',\n    firstPage: 'پەڕەی یەکەم',\n    lastPage: 'پەڕەی کۆتایی',\n    pageText: '{0}-{1} لە {2}',\n  },\n  dateRangeInput: {\n    divider: 'بۆ',\n  },\n  datePicker: {\n    itemsSelected: '{0} هەڵبژێردراوە',\n    range: {\n      title: 'بژاردنی بەروارەکان',\n      header: 'بەروارەکان بنووسە',\n    },\n    title: 'بژاردنی بەروار',\n    header: 'بەروار بنووسە',\n    input: {\n      placeholder: 'بەروار بنووسە',\n    },\n    ariaLabel: {\n      previousMonth: 'مانگی پێشوو',\n      nextMonth: 'مانگی داهاتوو',\n      selectYear: 'ساڵ هەڵبژێرە',\n      previousYear: 'ساڵی پێشوو',\n      nextYear: 'ساڵی داهاتوو',\n      selectMonth: 'مانگ هەڵبژێرە',\n      selectDate: '{0}',\n      currentDate: 'ئەمڕو، {0}',\n    },\n  },\n  noDataText: 'هیچ داتایەک بەردەست نیە',\n  carousel: {\n    prev: 'بینراوی پێشوو',\n    next: 'بینراوی داهاتوو',\n    ariaLabel: {\n      delimiter: 'سلایدی کارۆسێل {0} لە {1}',\n    },\n  },\n  calendar: {\n    moreEvents: '{0} زیاتر',\n    today: 'ئەمڕو',\n  },\n  input: {\n    clear: 'سڕینەوە {0}',\n    prependAction: '{0} کرداری پێشەوە',\n    appendAction: '{0} کرداری دواتر',\n    otp: 'تکایە نووسینی نمرەی OTP {0}',\n  },\n  fileInput: {\n    counter: '{0} فایل',\n    counterSize: '{0} فایل ({1} لە کۆی گشتی)',\n  },\n  fileUpload: {\n    title: 'فایلەکان بکشە و دابنێ لێرە',\n    divider: 'یان',\n    browse: 'گەڕان بۆ فایلەکان',\n  },\n  timePicker: {\n    am: 'پێش نیوەڕۆژ',\n    pm: 'دوای نیوەڕۆژ',\n    title: 'کات دیاریبکە',\n    hour: 'کاتژمێر',\n    minute: 'خولەک',\n    second: 'چرکە',\n    notAllowed: 'بەهاکە ڕێگەپێدراو نییە',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'ڕێنیشاندەری پەڕەگۆڕکێ',\n      next: 'پەڕەی دواتر',\n      previous: 'پەڕەی پێشوو',\n      page: 'بڕۆ بۆ پەڕەی {0}',\n      currentPage: 'پەڕەی ئێستا، پەڕە {0}',\n      first: 'پەڕەی یەکەم',\n      last: 'پەڕەی کۆتایی',\n    },\n  },\n  stepper: {\n    next: 'داهاتوو',\n    prev: 'پێشوو',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'هەڵسەنگاندن {0} لە {1}',\n    },\n  },\n  loading: 'بارکردن...',\n  infiniteScroll: {\n    loadMore: 'زیاتر باربکە',\n    empty: 'هیچتر نیە',\n  },\n  rules: {\n    required: 'ئەم خانە پێویستە',\n    email: 'تکایە ئیمەیڵێکی دروست بنووسە',\n    number: 'ئەم خانە تەنها دەتوانێت ژمارەکان بگرێت',\n    integer: 'ئەم خانە تەنها دەتوانێت نرخی تەواو بگرێت',\n    capital: 'ئەم خانە تەنها دەتوانێت پیتە گەورەکان بگرێت',\n    maxLength: 'پێویستە زۆرترین {0} پیت بنووسیت',\n    minLength: 'پێویستە کەمترین {0} پیت بنووسیت',\n    strictLength: 'درێژیی خانەی نووسراو نادروستە',\n    exclude: 'پیتەکەی {0} ڕێپێدراو نیە',\n    notEmpty: 'تکایە بەلایەنی کەم یەک هەڵبژێرە',\n    pattern: 'فۆرماتەکە نادروستە',\n  },\n  command: {\n    search: 'فرمان بنووسە یان بگەڕە...',\n  },\n  hotkey: {\n    then: 'پاشان',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: 'تیری سەرەوە',\n    downArrow: 'تیری خوارەوە',\n    leftArrow: 'تیری چەپ',\n    rightArrow: 'تیری ڕاست',\n    backspace: 'Backspace',\n    space: 'بۆشایی',\n    plus: 'زیادکردن',\n    shortcut: 'کورتەبڕی تەختەکلیل: {0}',\n    or: 'یان',\n  },\n  video: {\n    play: 'لێدان',\n    pause: 'ڕاگرتن',\n    seek: 'گەڕان',\n    volume: 'دەنگ',\n    showVolume: 'پیشاندانی کۆنترۆڵی دەنگ',\n    mute: 'بێدەنگکردن',\n    unmute: 'لە بێدەنگی دەرهێنان',\n    enterFullscreen: 'پڕ بە شاشە',\n    exitFullscreen: 'چوونە دەرەوە لە پڕ بە شاشە',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'ڕەنگ لەسەر شاشە هەڵبژێرە',\n      hueSlider: 'ڕەنگ',\n      alphaSlider: 'ئەلفا',\n      redInput: 'سوور',\n      greenInput: 'سەوز',\n      blueInput: 'شین',\n      alphaInput: 'ئەلفا',\n      hueInput: 'ڕەنگ',\n      saturationInput: 'تێربوون',\n      lightnessInput: 'کاڵی',\n      hexInput: 'بەهای HEX',\n      hexaInput: 'HEX لەگەڵ بەهای ئەلفا',\n      changeFormat: 'گۆڕینی فۆرماتی ڕەنگ',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/cs.ts",
    "content": "export default {\n  badge: 'Odznak',\n  open: 'Otevřít',\n  close: 'Zavřít',\n  dismiss: 'Zavřít',\n  confirmEdit: {\n    ok: 'OK',\n    cancel: 'Zrušit',\n  },\n  dataIterator: {\n    noResultsText: 'Nenalezeny žádné záznamy',\n    loadingText: 'Načítám položky...',\n  },\n  dataTable: {\n    itemsPerPageText: 'Řádků na stránku:',\n    ariaLabel: {\n      sortDescending: 'Řazeno sestupně.',\n      sortAscending: 'Řazeno vzestupně.',\n      sortNone: 'Neseřazeno.',\n      activateNone: 'Aktivováním vypnete řazení.',\n      activateDescending: 'Aktivováním se bude řadit sestupně.',\n      activateAscending: 'Aktivováním se bude řadit vzestupně.',\n    },\n    sortBy: 'Řadit dle',\n  },\n  dataFooter: {\n    itemsPerPageText: 'Položek na stránku:',\n    itemsPerPageAll: 'Vše',\n    nextPage: 'Další strana',\n    prevPage: 'Předchozí strana',\n    firstPage: 'První strana',\n    lastPage: 'Poslední strana',\n    pageText: '{0}-{1} z {2}',\n  },\n  dateRangeInput: {\n    divider: 'do',\n  },\n  datePicker: {\n    itemsSelected: '{0} vybráno',\n    range: {\n      title: 'Vyberte datumy',\n      header: 'Zadejte datumy',\n    },\n    title: 'Vyberte datum',\n    header: 'Zadejte datum',\n    input: {\n      placeholder: 'Zadejte datum',\n    },\n    ariaLabel: {\n      previousMonth: 'Předchozí měsíc',\n      nextMonth: 'Další měsíc',\n      selectYear: 'Vyberte rok',\n      previousYear: 'Předchozí rok',\n      nextYear: 'Další rok',\n      selectMonth: 'Vyberte měsíc',\n      selectDate: '{0}',\n      currentDate: 'Dnes, {0}',\n    },\n  },\n  noDataText: 'Nejsou dostupná žádná data',\n  carousel: {\n    prev: 'Předchozí obrázek',\n    next: 'Další obrázek',\n    ariaLabel: {\n      delimiter: 'Obrázek {0} z {1}',\n    },\n  },\n  calendar: {\n    moreEvents: '{0} dalších',\n    today: 'Dnes',\n  },\n  input: {\n    clear: 'Vymazat {0}',\n    prependAction: '{0} předřazená akce',\n    appendAction: '{0} připojená akce',\n    otp: 'Vložte OTP znak {0}',\n  },\n  fileInput: {\n    counter: '{0} souborů',\n    counterSize: '{0} souborů ({1} celkem)',\n  },\n  fileUpload: {\n    title: 'Přetáhněte soubory sem',\n    divider: 'nebo',\n    browse: 'Procházet soubory',\n  },\n  timePicker: {\n    am: 'Dopoledne',\n    pm: 'Odpoledne',\n    title: 'Vyberte čas',\n    hour: 'Hodina',\n    minute: 'Minuty',\n    second: 'Sekundy',\n    notAllowed: 'Hodnota není povolena',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'Navigace po stránkách',\n      next: 'Další strana',\n      previous: 'Předchozí strana',\n      page: 'Přejít na stránku {0}',\n      currentPage: 'Aktuální stránka, stránka {0}',\n      first: 'První stránka',\n      last: 'Poslední stránka',\n    },\n  },\n  stepper: {\n    next: 'Další',\n    prev: 'Předchozí',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'Hodnocení {0} z {1}',\n    },\n  },\n  loading: 'Načítám...',\n  infiniteScroll: {\n    loadMore: 'Načíst více',\n    empty: 'Žádné další',\n  },\n  rules: {\n    required: 'Toto pole je povinné',\n    email: 'Zadejte platný e-mail',\n    number: 'Toto pole může obsahovat pouze čísla',\n    integer: 'Toto pole může obsahovat pouze celá čísla',\n    capital: 'Toto pole může obsahovat pouze velká písmena',\n    maxLength: 'Musíte zadat maximálně {0} znaků',\n    minLength: 'Musíte zadat minimálně {0} znaků',\n    strictLength: 'Délka zadaného pole je neplatná',\n    exclude: 'Znak {0} není povolen',\n    notEmpty: 'Vyberte alespoň jednu hodnotu',\n    pattern: 'Neplatný formát',\n  },\n  command: {\n    search: 'Zadejte příkaz nebo hledejte...',\n  },\n  hotkey: {\n    then: 'poté',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: 'Šipka nahoru',\n    downArrow: 'Šipka dolů',\n    leftArrow: 'Šipka vlevo',\n    rightArrow: 'Šipka vpravo',\n    backspace: 'Backspace',\n    space: 'Mezerník',\n    plus: 'plus',\n    shortcut: 'Klávesová zkratka: {0}',\n    or: 'nebo',\n  },\n  video: {\n    play: 'Přehrát',\n    pause: 'Pozastavit',\n    seek: 'Vyhledat',\n    volume: 'Hlasitost',\n    showVolume: 'Zobrazit ovládání hlasitosti',\n    mute: 'Ztlumit',\n    unmute: 'Zrušit ztlumení',\n    enterFullscreen: 'Celá obrazovka',\n    exitFullscreen: 'Ukončit celou obrazovku',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'Vybrat barvu z obrazovky',\n      hueSlider: 'Odstín',\n      alphaSlider: 'Alfa',\n      redInput: 'Červená',\n      greenInput: 'Zelená',\n      blueInput: 'Modrá',\n      alphaInput: 'Alfa',\n      hueInput: 'Odstín',\n      saturationInput: 'Sytost',\n      lightnessInput: 'Světlost',\n      hexInput: 'HEX hodnota',\n      hexaInput: 'HEX s alfa hodnotou',\n      changeFormat: 'Změnit formát barvy',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/da.ts",
    "content": "export default {\n  badge: 'Emblem',\n  open: 'Åbn',\n  close: 'Luk',\n  dismiss: 'Afvis',\n  confirmEdit: {\n    ok: 'OK',\n    cancel: 'Annuller',\n  },\n  dataIterator: {\n    noResultsText: 'Ingen matchende data fundet',\n    loadingText: 'Indhenter data...',\n  },\n  dataTable: {\n    itemsPerPageText: 'Rækker pr. side:',\n    ariaLabel: {\n      sortDescending: 'Sorteret faldende.',\n      sortAscending: 'Sorteret stigende.',\n      sortNone: 'Ikke sorteret.',\n      activateNone: 'Aktiver for at fjerne sortering.',\n      activateDescending: 'Aktiver for at sortere faldende.',\n      activateAscending: 'Aktiver for at sortere stigende.',\n    },\n    sortBy: 'Sorter efter',\n  },\n  dataFooter: {\n    itemsPerPageText: 'Rækker pr. side:',\n    itemsPerPageAll: 'Alle',\n    nextPage: 'Næste side',\n    prevPage: 'Forrige side',\n    firstPage: 'Første side',\n    lastPage: 'Sidste side',\n    pageText: '{0}-{1} af {2}',\n  },\n  dateRangeInput: {\n    divider: 'til',\n  },\n  datePicker: {\n    itemsSelected: '{0} valgt',\n    range: {\n      title: 'Vælg datoer',\n      header: 'Indtast datoer',\n    },\n    title: 'Vælg dato',\n    header: 'Indtast dato',\n    input: {\n      placeholder: 'Indtast dato',\n    },\n    ariaLabel: {\n      previousMonth: 'Forrige måned',\n      nextMonth: 'Næste måned',\n      selectYear: 'Vælg år',\n      previousYear: 'Forrige år',\n      nextYear: 'Næste år',\n      selectMonth: 'Vælg måned',\n      selectDate: '{0}',\n      currentDate: 'I dag, {0}',\n    },\n  },\n  noDataText: 'Ingen data tilgængelig',\n  carousel: {\n    prev: 'Forrige visuelle',\n    next: 'Næste visuelle',\n    ariaLabel: {\n      delimiter: 'Karrusel dias {0} af {1}',\n    },\n  },\n  calendar: {\n    moreEvents: '{0} mere',\n    today: 'I dag',\n  },\n  input: {\n    clear: 'Ryd {0}',\n    prependAction: '{0} foranstillet handling',\n    appendAction: '{0} efterstillet handling',\n    otp: 'Indtast OTP-tegn {0}',\n  },\n  fileInput: {\n    counter: '{0} filer',\n    counterSize: '{0} filer ({1} i alt)',\n  },\n  fileUpload: {\n    title: 'Træk og slip filer her',\n    divider: 'eller',\n    browse: 'Gennemse filer',\n  },\n  timePicker: {\n    am: 'AM',\n    pm: 'PM',\n    title: 'Vælg tidspunkt',\n    hour: 'Time',\n    minute: 'Minutter',\n    second: 'Sekunder',\n    notAllowed: 'Værdien er ikke tilladt',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'Pagineringsnavigation',\n      next: 'Næste side',\n      previous: 'Forrige side',\n      page: 'Gå til side {0}',\n      currentPage: 'Nuværende side, Side {0}',\n      first: 'Første side',\n      last: 'Sidste side',\n    },\n  },\n  stepper: {\n    next: 'Næste',\n    prev: 'Forrige',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'Bedømmelse {0} af {1}',\n    },\n  },\n  loading: 'Indlæser...',\n  infiniteScroll: {\n    loadMore: 'Indlæs mere',\n    empty: 'Ingen flere',\n  },\n  rules: {\n    required: 'Dette felt er påkrævet',\n    email: 'Indtast venligst en gyldig e-mail',\n    number: 'Dette felt kan kun indeholde tal',\n    integer: 'Dette felt kan kun indeholde heltal',\n    capital: 'Dette felt kan kun indeholde store bogstaver',\n    maxLength: 'Du skal indtaste maksimalt {0} tegn',\n    minLength: 'Du skal indtaste mindst {0} tegn',\n    strictLength: 'Længden af det indtastede felt er ugyldig',\n    exclude: 'Tegnet {0} er ikke tilladt',\n    notEmpty: 'Vælg venligst mindst én værdi',\n    pattern: 'Ugyldigt format',\n  },\n  command: {\n    search: 'Skriv en kommando eller søg...',\n  },\n  hotkey: {\n    then: 'derefter',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: 'Pil op',\n    downArrow: 'Pil ned',\n    leftArrow: 'Pil venstre',\n    rightArrow: 'Pil højre',\n    backspace: 'Slet',\n    space: 'Mellemrum',\n    plus: 'plus',\n    shortcut: 'Tastaturgenvej: {0}',\n    or: 'eller',\n  },\n  video: {\n    play: 'Afspil',\n    pause: 'Pause',\n    seek: 'Søg',\n    volume: 'Lydstyrke',\n    showVolume: 'Vis lydstyrkekontrol',\n    mute: 'Slå lyd fra',\n    unmute: 'Slå lyd til',\n    enterFullscreen: 'Fuld skærm',\n    exitFullscreen: 'Afslut fuld skærm',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'Vælg farve fra skærmen',\n      hueSlider: 'Farvetone',\n      alphaSlider: 'Alfa',\n      redInput: 'Rød',\n      greenInput: 'Grøn',\n      blueInput: 'Blå',\n      alphaInput: 'Alfa',\n      hueInput: 'Farvetone',\n      saturationInput: 'Mætning',\n      lightnessInput: 'Lyshed',\n      hexInput: 'HEX-værdi',\n      hexaInput: 'HEX med alfaværdi',\n      changeFormat: 'Skift farveformat',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/de.ts",
    "content": "export default {\n  badge: 'Abzeichen',\n  open: 'Öffnen',\n  close: 'Schließen',\n  dismiss: 'Verwerfen',\n  confirmEdit: {\n    ok: 'OK',\n    cancel: 'Abbrechen',\n  },\n  dataIterator: {\n    noResultsText: 'Keine Elemente gefunden',\n    loadingText: 'Lade Elemente...',\n  },\n  dataTable: {\n    itemsPerPageText: 'Zeilen pro Seite:',\n    ariaLabel: {\n      sortDescending: 'Absteigend sortiert.',\n      sortAscending: 'Aufsteigend sortiert.',\n      sortNone: 'Nicht sortiert.',\n      activateNone: 'Aktivieren um Sortierung zu entfernen.',\n      activateDescending: 'Aktivieren um absteigend zu sortieren.',\n      activateAscending: 'Aktivieren um aufsteigend zu sortieren.',\n    },\n    sortBy: 'Sortiere nach',\n  },\n  dataFooter: {\n    itemsPerPageText: 'Elemente pro Seite:',\n    itemsPerPageAll: 'Alle',\n    nextPage: 'Nächste Seite',\n    prevPage: 'Vorherige Seite',\n    firstPage: 'Erste Seite',\n    lastPage: 'Letzte Seite',\n    pageText: '{0}-{1} von {2}',\n  },\n  dateRangeInput: {\n    divider: 'bis',\n  },\n  datePicker: {\n    itemsSelected: '{0} ausgewählt',\n    range: {\n      title: 'Daten auswählen',\n      header: 'Daten eingeben',\n    },\n    title: 'Datum auswählen',\n    header: 'Datum eingeben',\n    input: {\n      placeholder: 'Datum eingeben',\n    },\n    ariaLabel: {\n      previousMonth: 'Vorheriger Monat',\n      nextMonth: 'Nächster Monat',\n      selectYear: 'Jahr auswählen',\n      previousYear: 'Vorheriges Jahr',\n      nextYear: 'Nächstes Jahr',\n      selectMonth: 'Monat auswählen',\n      selectDate: '{0}',\n      currentDate: 'Heute, {0}',\n    },\n  },\n  noDataText: 'Keine Daten vorhanden',\n  carousel: {\n    prev: 'Vorheriges Bild',\n    next: 'Nächstes Bild',\n    ariaLabel: {\n      delimiter: 'Element {0} von {1}',\n    },\n  },\n  calendar: {\n    moreEvents: '{0} mehr',\n    today: 'Heute',\n  },\n  input: {\n    clear: '{0} leeren',\n    prependAction: '{0} vorangestellte Aktion',\n    appendAction: '{0} angehängte Aktion',\n    otp: 'Bitte OTP-Zeichen {0} eingeben',\n  },\n  fileInput: {\n    counter: '{0} Dateien',\n    counterSize: '{0} Dateien ({1} gesamt)',\n  },\n  fileUpload: {\n    title: 'Datei hier ablegen',\n    divider: 'oder',\n    browse: 'Dateien durchsuchen',\n  },\n  timePicker: {\n    am: 'AM',\n    pm: 'PM',\n    title: 'Uhrzeit auswählen',\n    hour: 'Stunde',\n    minute: 'Minuten',\n    second: 'Sekunden',\n    notAllowed: 'Wert ist nicht erlaubt',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'Seitennavigation',\n      next: 'Nächste Seite',\n      previous: 'Vorherige Seite',\n      page: 'Gehe zu Seite {0}',\n      currentPage: 'Aktuelle Seite, Seite {0}',\n      first: 'Erste Seite',\n      last: 'Letzte Seite',\n    },\n  },\n  stepper: {\n    next: 'Weiter',\n    prev: 'Zurück',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'Bewertung {0} von {1}',\n    },\n  },\n  loading: 'Laden...',\n  infiniteScroll: {\n    loadMore: 'Mehr laden',\n    empty: 'Nichts weiteres',\n  },\n  rules: {\n    required: 'Dieses Feld ist erforderlich',\n    email: 'Bitte geben Sie eine gültige E-Mail-Adresse ein',\n    number: 'Dieses Feld darf nur Zahlen enthalten',\n    integer: 'Dieses Feld darf nur Ganzzahlen enthalten',\n    capital: 'Dieses Feld darf nur Großbuchstaben enthalten',\n    maxLength: 'Sie dürfen maximal {0} Zeichen eingeben',\n    minLength: 'Sie müssen mindestens {0} Zeichen eingeben',\n    strictLength: 'Die Länge des eingegebenen Feldes ist ungültig',\n    exclude: 'Das Zeichen {0} ist nicht erlaubt',\n    notEmpty: 'Bitte wählen Sie mindestens einen Wert aus',\n    pattern: 'Ungültiges Format',\n  },\n  command: {\n    search: 'Geben Sie einen Befehl ein oder suchen Sie...',\n  },\n  hotkey: {\n    then: 'dann',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Eingabe',\n    escape: 'Escape',\n    upArrow: 'Pfeil nach oben',\n    downArrow: 'Pfeil nach unten',\n    leftArrow: 'Pfeil nach links',\n    rightArrow: 'Pfeil nach rechts',\n    backspace: 'Rücktaste',\n    space: 'Leertaste',\n    plus: 'plus',\n    shortcut: 'Tastenkürzel: {0}',\n    or: 'oder',\n  },\n  video: {\n    play: 'Abspielen',\n    pause: 'Pause',\n    seek: 'Suchen',\n    volume: 'Lautstärke',\n    showVolume: 'Lautstärkeregler anzeigen',\n    mute: 'Stummschalten',\n    unmute: 'Stummschaltung aufheben',\n    enterFullscreen: 'Vollbild',\n    exitFullscreen: 'Vollbild beenden',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'Farbe vom Bildschirm auswählen',\n      hueSlider: 'Farbton',\n      alphaSlider: 'Transparenz',\n      redInput: 'Rot',\n      greenInput: 'Grün',\n      blueInput: 'Blau',\n      alphaInput: 'Transparenz',\n      hueInput: 'Farbton',\n      saturationInput: 'Sättigung',\n      lightnessInput: 'Helligkeit',\n      hexInput: 'HEX-Wert',\n      hexaInput: 'HEX-Wert mit Transparenz',\n      changeFormat: 'Farbformat ändern',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/el.ts",
    "content": "export default {\n  badge: 'Σήμα',\n  open: 'Άνοιγμα',\n  close: 'Κλείσιμο',\n  dismiss: 'Απόρριψη',\n  confirmEdit: {\n    ok: 'OK',\n    cancel: 'Ακύρωση',\n  },\n  dataIterator: {\n    noResultsText: 'Δε βρέθηκαν αποτελέσματα',\n    loadingText: 'Φόρτωση αντικειμένου...',\n  },\n  dataTable: {\n    itemsPerPageText: 'Γραμμές ανά σελίδα:',\n    ariaLabel: {\n      sortDescending: 'Ταξινομημένο φθίνουσα.',\n      sortAscending: 'Ταξινομημένο αύξουσα.',\n      sortNone: 'Χωρίς ταξινόμηση.',\n      activateNone: 'Ενεργοποιήστε για να καταργήσετε την ταξινόμηση.',\n      activateDescending: 'Ενεργοποιήστε για φθίνουσα ταξινόμηση.',\n      activateAscending: 'Ενεργοποιήστε για αύξουσα ταξινόμηση.',\n    },\n    sortBy: 'Ταξινόμηση κατά',\n  },\n  dataFooter: {\n    itemsPerPageText: 'Αντικείμενα ανά σελίδα:',\n    itemsPerPageAll: 'Όλα',\n    nextPage: 'Επόμενη σελίδα',\n    prevPage: 'Προηγούμενη σελίδα',\n    firstPage: 'Πρώτη σελίδα',\n    lastPage: 'Τελευταία σελίδα',\n    pageText: '{0}-{1} από {2}',\n  },\n  dateRangeInput: {\n    divider: 'έως',\n  },\n  datePicker: {\n    itemsSelected: '{0} επιλεγμένα',\n    range: {\n      title: 'Επιλέξτε ημερομηνίες',\n      header: 'Εισαγάγετε ημερομηνίες',\n    },\n    title: 'Επιλέξτε ημερομηνία',\n    header: 'Εισαγάγετε ημερομηνία',\n    input: {\n      placeholder: 'Εισαγάγετε ημερομηνία',\n    },\n    ariaLabel: {\n      previousMonth: 'Προηγούμενος μήνας',\n      nextMonth: 'Επόμενος μήνας',\n      selectYear: 'Επιλέξτε έτος',\n      previousYear: 'Προηγούμενο έτος',\n      nextYear: 'Επόμενο έτος',\n      selectMonth: 'Επιλέξτε μήνα',\n      selectDate: '{0}',\n      currentDate: 'Σήμερα, {0}',\n    },\n  },\n  noDataText: 'Χωρίς δεδομένα',\n  carousel: {\n    prev: 'הקודם חזותי',\n    next: 'הבא חזותי',\n    ariaLabel: {\n      delimiter: 'Διαφάνεια καρουζέλ {0} από {1}',\n    },\n  },\n  calendar: {\n    moreEvents: '{0} ακόμη',\n    today: 'Σήμερα',\n  },\n  input: {\n    clear: 'Καθαρισμός {0}',\n    prependAction: '{0} προσαρτημένη ενέργεια',\n    appendAction: '{0} επισυναπτόμενη ενέργεια',\n    otp: 'Παρακαλώ εισαγάγετε χαρακτήρα OTP {0}',\n  },\n  fileInput: {\n    counter: '{0} αρχεία',\n    counterSize: '{0} αρχεία ({1} συνολικά)',\n  },\n  fileUpload: {\n    title: 'Σύρετε και αποθέστε αρχεία εδώ',\n    divider: 'ή',\n    browse: 'Αναζήτηση αρχείων',\n  },\n  timePicker: {\n    am: 'ΠΜ',\n    pm: 'ΜΜ',\n    title: 'Επιλέξτε ώρα',\n    hour: 'Ώρα',\n    minute: 'Λεπτά',\n    second: 'Δευτερόλεπτα',\n    notAllowed: 'Η τιμή δεν επιτρέπεται',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'Πλοήγηση με προορισμούς',\n      next: 'Επόμενη σελίδα',\n      previous: 'Προηγούμενη σελίδα',\n      page: 'Πήγαινε στην σελίδα {0}',\n      currentPage: 'Τρέχουσα σελίδα, σελίδα {0}',\n      first: 'Πρώτη σελίδα',\n      last: 'Τελευταία σελίδα',\n    },\n  },\n  stepper: {\n    next: 'Επόμενο',\n    prev: 'Προηγούμενο',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'Βαθμολογία {0} από {1}',\n    },\n  },\n  loading: 'Φόρτωση...',\n  infiniteScroll: {\n    loadMore: 'Φόρτωση περισσότερων',\n    empty: 'Δεν υπάρχουν άλλα',\n  },\n  rules: {\n    required: 'Αυτό το πεδίο είναι υποχρεωτικό',\n    email: 'Παρακαλώ εισάγετε μια έγκυρη διεύθυνση email',\n    number: 'Αυτό το πεδίο μπορεί να περιέχει μόνο αριθμούς',\n    integer: 'Αυτό το πεδίο μπορεί να περιέχει μόνο ακέραιους αριθμούς',\n    capital: 'Αυτό το πεδίο μπορεί να περιέχει μόνο κεφαλαία γράμματα',\n    maxLength: 'Πρέπει να εισάγετε το πολύ {0} χαρακτήρες',\n    minLength: 'Πρέπει να εισάγετε τουλάχιστον {0} χαρακτήρες',\n    strictLength: 'Το μήκος του πεδίου που εισήχθη δεν είναι έγκυρο',\n    exclude: 'Ο χαρακτήρας {0} δεν επιτρέπεται',\n    notEmpty: 'Παρακαλώ επιλέξτε τουλάχιστον μία τιμή',\n    pattern: 'Μη έγκυρη μορφή',\n  },\n  command: {\n    search: 'Πληκτρολογήστε μια εντολή ή αναζητήστε...',\n  },\n  hotkey: {\n    then: 'στη συνέχεια',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: 'Πάνω βέλος',\n    downArrow: 'Κάτω βέλος',\n    leftArrow: 'Αριστερό βέλος',\n    rightArrow: 'Δεξί βέλος',\n    backspace: 'Backspace',\n    space: 'Διάστημα',\n    plus: 'συν',\n    shortcut: 'Συντόμευση πληκτρολογίου: {0}',\n    or: 'ή',\n  },\n  video: {\n    play: 'Αναπαραγωγή',\n    pause: 'Παύση',\n    seek: 'Αναζήτηση',\n    volume: 'Ένταση',\n    showVolume: 'Εμφάνιση ελέγχου έντασης',\n    mute: 'Σίγαση',\n    unmute: 'Κατάργηση σίγασης',\n    enterFullscreen: 'Πλήρης οθόνη',\n    exitFullscreen: 'Έξοδος από πλήρη οθόνη',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'Επιλογή χρώματος από την οθόνη',\n      hueSlider: 'Απόχρωση',\n      alphaSlider: 'Άλφα',\n      redInput: 'Κόκκινο',\n      greenInput: 'Πράσινο',\n      blueInput: 'Μπλε',\n      alphaInput: 'Άλφα',\n      hueInput: 'Απόχρωση',\n      saturationInput: 'Κορεσμός',\n      lightnessInput: 'Φωτεινότητα',\n      hexInput: 'Δεκαεξαδική τιμή',\n      hexaInput: 'Δεκαεξαδική τιμή με άλφα',\n      changeFormat: 'Αλλαγή μορφής χρώματος',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/en.ts",
    "content": "export default {\n  badge: 'Badge',\n  open: 'Open',\n  close: 'Close',\n  dismiss: 'Dismiss',\n  confirmEdit: {\n    ok: 'OK',\n    cancel: 'Cancel',\n  },\n  dataIterator: {\n    noResultsText: 'No matching records found',\n    loadingText: 'Loading items...',\n  },\n  dataTable: {\n    itemsPerPageText: 'Rows per page:',\n    ariaLabel: {\n      sortDescending: 'Sorted descending.',\n      sortAscending: 'Sorted ascending.',\n      sortNone: 'Not sorted.',\n      activateNone: 'Activate to remove sorting.',\n      activateDescending: 'Activate to sort descending.',\n      activateAscending: 'Activate to sort ascending.',\n    },\n    sortBy: 'Sort by',\n  },\n  dataFooter: {\n    itemsPerPageText: 'Items per page:',\n    itemsPerPageAll: 'All',\n    nextPage: 'Next page',\n    prevPage: 'Previous page',\n    firstPage: 'First page',\n    lastPage: 'Last page',\n    pageText: '{0}-{1} of {2}',\n  },\n  dateRangeInput: {\n    divider: 'to',\n  },\n  datePicker: {\n    itemsSelected: '{0} selected',\n    range: {\n      title: 'Select dates',\n      header: 'Enter dates',\n    },\n    title: 'Select date',\n    header: 'Enter date',\n    input: {\n      placeholder: 'Enter date',\n    },\n    ariaLabel: {\n      previousMonth: 'Previous month',\n      nextMonth: 'Next month',\n      selectYear: 'Select year',\n      previousYear: 'Previous year',\n      nextYear: 'Next year',\n      selectMonth: 'Select month',\n      selectDate: '{0}', // Full date format\n      currentDate: 'Today, {0}',\n    },\n  },\n  noDataText: 'No data available',\n  carousel: {\n    prev: 'Previous visual',\n    next: 'Next visual',\n    ariaLabel: {\n      delimiter: 'Carousel slide {0} of {1}',\n    },\n  },\n  calendar: {\n    moreEvents: '{0} more',\n    today: 'Today',\n  },\n  input: {\n    clear: 'Clear {0}',\n    prependAction: '{0} prepended action',\n    appendAction: '{0} appended action',\n    otp: 'Please enter OTP character {0}',\n  },\n  fileInput: {\n    counter: '{0} files',\n    counterSize: '{0} files ({1} in total)',\n  },\n  fileUpload: {\n    title: 'Drag and drop files here',\n    divider: 'or',\n    browse: 'Browse Files',\n  },\n  timePicker: {\n    am: 'AM',\n    pm: 'PM',\n    title: 'Select Time',\n    hour: 'Hour',\n    minute: 'Minute',\n    second: 'Second',\n    notAllowed: 'Value is not allowed',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'Pagination Navigation',\n      next: 'Next page',\n      previous: 'Previous page',\n      page: 'Go to page {0}',\n      currentPage: 'Page {0}, Current page',\n      first: 'First page',\n      last: 'Last page',\n    },\n  },\n  stepper: {\n    next: 'Next',\n    prev: 'Previous',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'Rating {0} of {1}',\n    },\n  },\n  loading: 'Loading...',\n  infiniteScroll: {\n    loadMore: 'Load more',\n    empty: 'No more',\n  },\n  rules: {\n    required: 'This field is required',\n    email: 'Please enter a valid email',\n    number: 'This field can only contain numbers',\n    integer: 'This field can only contain integer values',\n    capital: 'This field can only contain uppercase letters',\n    maxLength: 'You must enter a maximum of {0} characters',\n    minLength: 'You must enter a minimum of {0} characters',\n    strictLength: 'The length of the entered field is invalid',\n    exclude: 'The {0} character is not allowed',\n    notEmpty: 'Please choose at least one value',\n    pattern: 'Invalid format',\n  },\n  command: {\n    search: 'Type a command or search...',\n  },\n  hotkey: {\n    then: 'then',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    space: 'Space',\n    shift: 'Shift',\n    alt: 'Alt',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: 'Up Arrow',\n    downArrow: 'Down Arrow',\n    leftArrow: 'Left Arrow',\n    rightArrow: 'Right Arrow',\n    backspace: 'Backspace',\n    option: 'Option',\n    plus: 'plus',\n    shortcut: 'Keyboard shortcut: {0}',\n    or: 'or',\n  },\n  video: {\n    play: 'Play',\n    pause: 'Pause',\n    seek: 'Seek',\n    volume: 'Volume',\n    showVolume: 'Show volume control',\n    mute: 'Mute',\n    unmute: 'Unmute',\n    enterFullscreen: 'Full screen',\n    exitFullscreen: 'Exit full screen',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'Select color with eyedropper',\n      hueSlider: 'Hue',\n      alphaSlider: 'Alpha',\n      redInput: 'Red value',\n      greenInput: 'Green value',\n      blueInput: 'Blue value',\n      alphaInput: 'Alpha value',\n      hueInput: 'Hue value',\n      saturationInput: 'Saturation value',\n      lightnessInput: 'Lightness value',\n      hexInput: 'HEX value',\n      hexaInput: 'HEX with alpha value',\n      changeFormat: 'Change color format',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/es.ts",
    "content": "export default {\n  badge: 'Placa',\n  open: 'Abrir',\n  close: 'Cerrar',\n  dismiss: 'Descartar',\n  confirmEdit: {\n    ok: 'OK',\n    cancel: 'Cancelar',\n  },\n  dataIterator: {\n    noResultsText: 'Ningún elemento coincide con la búsqueda',\n    loadingText: 'Cargando...',\n  },\n  dataTable: {\n    itemsPerPageText: 'Filas por página:',\n    ariaLabel: {\n      sortDescending: 'Orden descendente.',\n      sortAscending: 'Orden ascendente.',\n      sortNone: 'Sin ordenar.',\n      activateNone: 'Pulse para quitar orden.',\n      activateDescending: 'Pulse para ordenar de forma descendente.',\n      activateAscending: 'Pulse para ordenar de forma ascendente.',\n    },\n    sortBy: 'Ordenado por',\n  },\n  dataFooter: {\n    itemsPerPageText: 'Elementos por página:',\n    itemsPerPageAll: 'Todos',\n    nextPage: 'Página siguiente',\n    prevPage: 'Página anterior',\n    firstPage: 'Primera página',\n    lastPage: 'Última página',\n    pageText: '{0}-{1} de {2}',\n  },\n  dateRangeInput: {\n    divider: 'a',\n  },\n  datePicker: {\n    itemsSelected: '{0} seleccionados',\n    range: {\n      title: 'Seleccionar fechas',\n      header: 'Introducir fechas',\n    },\n    title: 'Seleccionar fecha',\n    header: 'Introducir fecha',\n    input: {\n      placeholder: 'Introducir fecha',\n    },\n    ariaLabel: {\n      previousMonth: 'Mes anterior',\n      nextMonth: 'Mes siguiente',\n      selectYear: 'Seleccionar año',\n      previousYear: 'Año anterior',\n      nextYear: 'Año siguiente',\n      selectMonth: 'Seleccionar mes',\n      selectDate: '{0}',\n      currentDate: 'Hoy, {0}',\n    },\n  },\n  noDataText: 'No hay datos disponibles',\n  carousel: {\n    prev: 'Visual anterior',\n    next: 'Visual siguiente',\n    ariaLabel: {\n      delimiter: 'Visual {0} de {1}',\n    },\n  },\n  calendar: {\n    moreEvents: '{0} más',\n    today: 'Hoy',\n  },\n  input: {\n    clear: 'Borrar {0}',\n    prependAction: '{0} acción adelantada',\n    appendAction: '{0} acción añadida',\n    otp: 'Por favor, introduzca el carácter OTP {0}',\n  },\n  fileInput: {\n    counter: '{0} archivos',\n    counterSize: '{0} archivos ({1} en total)',\n  },\n  fileUpload: {\n    title: 'Arrastra y suelta archivos aquí',\n    divider: 'o',\n    browse: 'Explorar archivos',\n  },\n  timePicker: {\n    am: 'AM',\n    pm: 'PM',\n    title: 'Seleccionar hora',\n    hour: 'Hora',\n    minute: 'Minutos',\n    second: 'Segundos',\n    notAllowed: 'El valor no está permitido',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'Navegación de paginación',\n      next: 'Página siguiente',\n      previous: 'Página anterior',\n      page: 'Ir a la página {0}',\n      currentPage: 'Página actual, página {0}',\n      first: 'Primera página',\n      last: 'Última página',\n    },\n  },\n  stepper: {\n    next: 'Siguiente',\n    prev: 'Anterior',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'Puntuación {0} de {1}',\n    },\n  },\n  loading: 'Cargando...',\n  infiniteScroll: {\n    loadMore: 'Cargar más',\n    empty: 'No hay más',\n  },\n  rules: {\n    required: 'Este campo es obligatorio',\n    email: 'Por favor, introduce un correo electrónico válido',\n    number: 'Este campo solo puede contener números',\n    integer: 'Este campo solo puede contener valores enteros',\n    capital: 'Este campo solo puede contener letras mayúsculas',\n    maxLength: 'Debes introducir un máximo de {0} caracteres',\n    minLength: 'Debes introducir un mínimo de {0} caracteres',\n    strictLength: 'La longitud del campo introducido no es válida',\n    exclude: 'El carácter {0} no está permitido',\n    notEmpty: 'Por favor, elige al menos un valor',\n    pattern: 'Formato inválido',\n  },\n  command: {\n    search: 'Escribe un comando o busca...',\n  },\n  hotkey: {\n    then: 'luego',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Intro',\n    escape: 'Escape',\n    upArrow: 'Flecha arriba',\n    downArrow: 'Flecha abajo',\n    leftArrow: 'Flecha izquierda',\n    rightArrow: 'Flecha derecha',\n    backspace: 'Retroceso',\n    space: 'Espacio',\n    plus: 'más',\n    shortcut: 'Atajo de teclado: {0}',\n    or: 'o',\n  },\n  video: {\n    play: 'Reproducir',\n    pause: 'Pausa',\n    seek: 'Buscar',\n    volume: 'Volumen',\n    showVolume: 'Mostrar control de volumen',\n    mute: 'Silenciar',\n    unmute: 'Activar sonido',\n    enterFullscreen: 'Pantalla completa',\n    exitFullscreen: 'Salir de pantalla completa',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'Seleccionar color de la pantalla',\n      hueSlider: 'Tono',\n      alphaSlider: 'Alfa',\n      redInput: 'Rojo',\n      greenInput: 'Verde',\n      blueInput: 'Azul',\n      alphaInput: 'Alfa',\n      hueInput: 'Tono',\n      saturationInput: 'Saturación',\n      lightnessInput: 'Luminosidad',\n      hexInput: 'Valor HEX',\n      hexaInput: 'Valor HEX con alfa',\n      changeFormat: 'Cambiar formato de color',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/et.ts",
    "content": "export default {\n  badge: 'Märk',\n  open: 'Ava',\n  close: 'Sulge',\n  dismiss: 'Loobu',\n  confirmEdit: {\n    ok: 'OK',\n    cancel: 'Tühista',\n  },\n  dataIterator: {\n    noResultsText: 'Vastavaid kirjeid ei leitud',\n    loadingText: 'Andmeid laaditakse...',\n  },\n  dataTable: {\n    itemsPerPageText: 'Ridu leheküljel:',\n    ariaLabel: {\n      sortDescending: 'Kahanevalt sorteeritud.',\n      sortAscending: 'Kasvavalt sorteeritud.',\n      sortNone: 'Ei ole sorteeritud.',\n      activateNone: 'Vajuta uuesti sorteerimise eemaldamiseks.',\n      activateDescending: 'Vajuta uuesti, et sorteerida kahanevalt.',\n      activateAscending: 'Vajuta kasvavalt sorteerimiseks.',\n    },\n    sortBy: 'Sorteerimise alus',\n  },\n  dataFooter: {\n    itemsPerPageText: 'Kirjeid leheküljel:',\n    itemsPerPageAll: 'Kõik',\n    nextPage: 'Järgmine lehekülg',\n    prevPage: 'Eelmine lehekülg',\n    firstPage: 'Esimene lehekülg',\n    lastPage: 'Viimane lehekülg',\n    pageText: '{0}-{1} {2}st',\n  },\n  dateRangeInput: {\n    divider: 'kuni',\n  },\n  datePicker: {\n    itemsSelected: '{0} valitud',\n    range: {\n      title: 'Vali kuupäevad',\n      header: 'Sisesta kuupäevad',\n    },\n    title: 'Vali kuupäev',\n    header: 'Sisesta kuupäev',\n    input: {\n      placeholder: 'Sisesta kuupäev',\n    },\n    ariaLabel: {\n      previousMonth: 'Eelmine kuu',\n      nextMonth: 'Järgmine kuu',\n      selectYear: 'Vali aasta',\n      previousYear: 'Eelmine aasta',\n      nextYear: 'Järgmine aasta',\n      selectMonth: 'Valige kuu',\n      selectDate: '{0}',\n      currentDate: 'Täna, {0}',\n    },\n  },\n  noDataText: 'Andmed puuduvad',\n  carousel: {\n    prev: 'Eelmine visuaalne',\n    next: 'Järgmine visuaalne',\n    ariaLabel: {\n      delimiter: 'Karusselli slaid {0} {1}st',\n    },\n  },\n  calendar: {\n    moreEvents: '{0} veel',\n    today: 'Täna',\n  },\n  input: {\n    clear: 'Tühjenda {0}',\n    prependAction: '{0} eelnev toiming',\n    appendAction: '{0} lisatud toiming',\n    otp: 'Palun sisesta OTP sümbol {0}',\n  },\n  fileInput: {\n    counter: '{0} faili',\n    counterSize: '{0} faili (kokku {1})',\n  },\n  fileUpload: {\n    title: 'Lohista ja lase failid siia',\n    divider: 'või',\n    browse: 'Sirvi faile',\n  },\n  timePicker: {\n    am: 'AM',\n    pm: 'PM',\n    title: 'Vali aeg',\n    hour: 'Tund',\n    minute: 'Minut',\n    second: 'Sekund',\n    notAllowed: 'Väärtus ei ole lubatud',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'Lehekülgede navigeerimine',\n      next: 'Järgmine lehekülg',\n      previous: 'Eelmine lehekülg',\n      page: 'Mine lehele {0}',\n      currentPage: 'Praegune leht, leht {0}',\n      first: 'Esimene lehekülg',\n      last: 'Viimane lehekülg',\n    },\n  },\n  stepper: {\n    next: 'Järgmine',\n    prev: 'Eelmine',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'Hinnang {0} {1}st',\n    },\n  },\n  loading: 'Laadimine...',\n  infiniteScroll: {\n    loadMore: 'Laadi rohkem',\n    empty: 'Pole rohkem',\n  },\n  rules: {\n    required: 'See väli on kohustuslik',\n    email: 'Palun sisesta kehtiv e-posti aadress',\n    number: 'See väli võib sisaldada ainult numbreid',\n    integer: 'See väli võib sisaldada ainult täisarve',\n    capital: 'See väli võib sisaldada ainult suurtähti',\n    maxLength: 'Sisestada tuleb maksimaalselt {0} märki',\n    minLength: 'Sisestada tuleb vähemalt {0} märki',\n    strictLength: 'Sisestatud välja pikkus ei ole kehtiv',\n    exclude: 'Märk {0} ei ole lubatud',\n    notEmpty: 'Palun vali vähemalt üks väärtus',\n    pattern: 'Vale vorming',\n  },\n  command: {\n    search: 'Sisestage käsk või otsige...',\n  },\n  hotkey: {\n    then: 'siis',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: 'Nool üles',\n    downArrow: 'Nool alla',\n    leftArrow: 'Nool vasakule',\n    rightArrow: 'Nool paremale',\n    backspace: 'Tagasiklahv',\n    space: 'Tühik',\n    plus: 'pluss',\n    shortcut: 'Klaviatuuri otsetee: {0}',\n    or: 'või',\n  },\n  video: {\n    play: 'Esita',\n    pause: 'Peata',\n    seek: 'Otsi',\n    volume: 'Helitugevus',\n    showVolume: 'Näita helitugevuse regulaatorit',\n    mute: 'Vaigista',\n    unmute: 'Lülita vaigistus välja',\n    enterFullscreen: 'Täisekraan',\n    exitFullscreen: 'Välju täisekraanilt',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'Võta värv ekraanilt',\n      hueSlider: 'Toon',\n      alphaSlider: 'Alfa',\n      redInput: 'Punane',\n      greenInput: 'Roheline',\n      blueInput: 'Sinine',\n      alphaInput: 'Alfa',\n      hueInput: 'Toon',\n      saturationInput: 'Küllastus',\n      lightnessInput: 'Heledus',\n      hexInput: 'HEKS väärtus',\n      hexaInput: 'HEKS koos alfa väärtusega',\n      changeFormat: 'Muuda värvi formaati',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/fa.ts",
    "content": "export default {\n  badge: 'نشان',\n  open: 'باز کردن',\n  close: 'بستن',\n  dismiss: 'رد کردن',\n  confirmEdit: {\n    ok: 'تایید',\n    cancel: 'لغو',\n  },\n  dataIterator: {\n    noResultsText: 'نتیجه‌ای یافت نشد',\n    loadingText: 'در حال بارگذاری...',\n  },\n  dataTable: {\n    itemsPerPageText: 'ردیف در صفحه:',\n    ariaLabel: {\n      sortDescending: 'مرتب‌سازی نزولی',\n      sortAscending: 'مرتب‌سازی صعودی',\n      sortNone: 'بدون مرتب‌سازی',\n      activateNone: 'غیرفعال‌سازی مرتب‌سازی',\n      activateDescending: 'غیرفعال‌سازی مرتب‌سازی نزولی',\n      activateAscending: 'غیرفعال‌سازی مرتب‌سازی صعودی',\n    },\n    sortBy: 'مرتب‌سازی براساس',\n  },\n  dataFooter: {\n    itemsPerPageText: 'ردیف در صفحه:',\n    itemsPerPageAll: 'همه',\n    nextPage: 'صفحه‌ی بعد',\n    prevPage: 'صفحه‌ی قبل',\n    firstPage: 'صفحه‌ی یکم',\n    lastPage: 'صفحه‌ی آخر',\n    pageText: '{0} تا {1} از {2}',\n  },\n  dateRangeInput: {\n    divider: 'تا',\n  },\n  datePicker: {\n    itemsSelected: '{0} انتخاب‌شده',\n    range: {\n      title: 'انتخاب تاریخ‌ها',\n      header: 'تاریخ‌ها را وارد کنید',\n    },\n    title: 'انتخاب تاریخ',\n    header: 'تاریخ را وارد کنید',\n    input: {\n      placeholder: 'تاریخ را وارد کنید',\n    },\n    ariaLabel: {\n      previousMonth: 'ماه قبل',\n      nextMonth: 'ماه بعد',\n      selectYear: 'انتخاب سال',\n      previousYear: 'سال قبل',\n      nextYear: 'سال بعد',\n      selectMonth: 'انتخاب ماه',\n      selectDate: '{0}',\n      currentDate: 'امروز، {0}',\n    },\n  },\n  noDataText: 'داده‌ای موجود نیست',\n  carousel: {\n    prev: 'اسلاید قبلی',\n    next: 'اسلاید بعدی',\n    ariaLabel: {\n      delimiter: 'اسلاید {0} از {1}',\n    },\n  },\n  calendar: {\n    moreEvents: '{بیشتر {0',\n    today: 'امروز',\n  },\n  input: {\n    clear: 'پاکسازی {0}',\n    prependAction: '{0} اقدام پیشین',\n    appendAction: '{0} اقدام افزوده‌شده',\n    otp: 'لطفا کد را وارد کنید {0}',\n  },\n  fileInput: {\n    counter: '{0} پرونده',\n    counterSize: '{0} پرونده ({1} در کل)',\n  },\n  fileUpload: {\n    title: 'فایل‌ها را اینجا بکشید و رها کنید',\n    divider: 'یا',\n    browse: 'مرور فایل‌ها',\n  },\n  timePicker: {\n    am: 'قبل از ظهر',\n    pm: 'بعد از ظهر',\n    title: 'انتخاب زمان',\n    hour: 'ساعت',\n    minute: 'دقیقه',\n    second: 'ثانیه',\n    notAllowed: 'مقدار مجاز نیست',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'جهت یابی صفحه',\n      next: 'صفحه‌ی بعد',\n      previous: 'صفحه‌ی قبلی',\n      page: 'برو صفحه {0}',\n      currentPage: '{0} صفحه‌ی فعلی ، صفحه‌ی',\n      first: 'صفحه‌ی اول',\n      last: 'صفحه‌ی آخر',\n    },\n  },\n  stepper: {\n    next: 'بعدی',\n    prev: 'قبلی',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'امتیاز {0} از {1}',\n    },\n  },\n  loading: 'در حال بارگذاری...',\n  infiniteScroll: {\n    loadMore: 'بارگذاری بیشتر',\n    empty: 'پایان',\n  },\n  rules: {\n    required: 'این فیلد الزامی است',\n    email: 'لطفاً یک ایمیل معتبر وارد کنید',\n    number: 'این فیلد فقط می‌تواند شامل اعداد باشد',\n    integer: 'این فیلد فقط می‌تواند شامل اعداد صحیح باشد',\n    capital: 'این فیلد فقط می‌تواند شامل حروف بزرگ باشد',\n    maxLength: 'حداکثر باید {0} کاراکتر وارد کنید',\n    minLength: 'حداقل باید {0} کاراکتر وارد کنید',\n    strictLength: 'طول فیلد وارد شده نامعتبر است',\n    exclude: 'کاراکتر {0} مجاز نیست',\n    notEmpty: 'لطفاً حداقل یک مقدار انتخاب کنید',\n    pattern: 'فرمت نامعتبر',\n  },\n  command: {\n    search: 'دستور را تایپ کنید یا جستجو کنید...',\n  },\n  hotkey: {\n    then: 'سپس',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: 'پیکان بالا',\n    downArrow: 'پیکان پایین',\n    leftArrow: 'پیکان چپ',\n    rightArrow: 'پیکان راست',\n    backspace: 'Backspace',\n    space: 'فاصله',\n    plus: 'بعلاوه',\n    shortcut: 'میانبر صفحه کلید: {0}',\n    or: 'یا',\n  },\n  video: {\n    play: 'پخش',\n    pause: 'مکث',\n    seek: 'جستجو',\n    volume: 'صدا',\n    showVolume: 'نمایش کنترل صدا',\n    mute: 'بی‌صدا',\n    unmute: 'با صدا',\n    enterFullscreen: 'تمام صفحه',\n    exitFullscreen: 'خروج از تمام صفحه',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'انتخاب رنگ از صفحه',\n      hueSlider: 'فام',\n      alphaSlider: 'آلفا',\n      redInput: 'قرمز',\n      greenInput: 'سبز',\n      blueInput: 'آبی',\n      alphaInput: 'آلفا',\n      hueInput: 'فام',\n      saturationInput: 'اشباع',\n      lightnessInput: 'روشنایی',\n      hexInput: 'مقدار HEX',\n      hexaInput: 'HEX با مقدار آلفا',\n      changeFormat: 'تغییر فرمت رنگ',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/fi.ts",
    "content": "export default {\n  badge: 'Infopiste',\n  open: 'Avaa',\n  close: 'Sulje',\n  dismiss: 'Hylkää',\n  confirmEdit: {\n    ok: 'OK',\n    cancel: 'Peruuta',\n  },\n  dataIterator: {\n    noResultsText: 'Ei osumia',\n    loadingText: 'Ladataan kohteita...',\n  },\n  dataTable: {\n    itemsPerPageText: 'Rivejä sivulla:',\n    ariaLabel: {\n      sortDescending: ': Järjestetty laskevasti. Poista järjestäminen aktivoimalla.',\n      sortAscending: ': Järjestetty nousevasti. Järjestä laskevasti aktivoimalla.',\n      sortNone: ': Ei järjestetty. Järjestä nousevasti aktivoimalla.',\n      activateNone: 'Aktivoi lajittelun poistamiseksi.',\n      activateDescending: 'Aktivoi laskevien laskevien lajittelemiseksi.',\n      activateAscending: 'Aktivoi lajitella nouseva.',\n    },\n    sortBy: 'Järjestä',\n  },\n  dataFooter: {\n    itemsPerPageText: 'Kohteita sivulla:',\n    itemsPerPageAll: 'Kaikki',\n    nextPage: 'Seuraava sivu',\n    prevPage: 'Edellinen sivu',\n    firstPage: 'Ensimmäinen sivu',\n    lastPage: 'Viimeinen sivu',\n    pageText: '{0}-{1} ({2})',\n  },\n  dateRangeInput: {\n    divider: '–',\n  },\n  datePicker: {\n    itemsSelected: '{0} valittu',\n    range: {\n      title: 'Valitse päivämäärät',\n      header: 'Syötä päivämäärät',\n    },\n    title: 'Valitse päivämäärä',\n    header: 'Syötä päivämäärä',\n    input: {\n      placeholder: 'Syötä päivämäärä',\n    },\n    ariaLabel: {\n      previousMonth: 'Edellinen kuukausi',\n      nextMonth: 'Seuraava kuukausi',\n      selectYear: 'Valitse vuosi',\n      previousYear: 'Edellinen vuosi',\n      nextYear: 'Seuraava vuosi',\n      selectMonth: 'Valitse kuukausi',\n      selectDate: '{0}',\n      currentDate: 'Tänään, {0}',\n    },\n  },\n  noDataText: 'Ei dataa',\n  carousel: {\n    prev: 'Edellinen kuva',\n    next: 'Seuraava kuva',\n    ariaLabel: {\n      delimiter: 'Karusellin kuva {0}/{1}',\n    },\n  },\n  calendar: {\n    moreEvents: '{0} lisää',\n    today: 'Tänään',\n  },\n  input: {\n    clear: 'Tyhjennä {0}',\n    prependAction: '{0} edeltävä toiminto',\n    appendAction: '{0} lisätty toiminto',\n    otp: 'Syötä OTP-merkki {0}',\n  },\n  fileInput: {\n    counter: '{0} tiedostoa',\n    counterSize: '{0} tiedostoa ({1} yhteensä)',\n  },\n  fileUpload: {\n    title: 'Vedä ja pudota tiedostot tähän',\n    divider: 'tai',\n    browse: 'Selaa tiedostoja',\n  },\n  timePicker: {\n    am: 'ap.',\n    pm: 'ip.',\n    title: 'Valitse aika',\n    hour: 'Tunti',\n    minute: 'Minuutit',\n    second: 'Sekunnit',\n    notAllowed: 'Arvo ei ole sallittu',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'Sivutuksen navigointi',\n      next: 'Seuraava sivu',\n      previous: 'Edellinen sivu',\n      page: 'Mene sivulle {0}',\n      currentPage: 'Nykyinen sivu, Sivu {0}',\n      first: 'Ensimmäinen sivu',\n      last: 'Viimeinen sivu',\n    },\n  },\n  stepper: {\n    next: 'Seuraava',\n    prev: 'Edellinen',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'Luokitus {0}/{1}',\n    },\n  },\n  loading: 'Ladataan...',\n  infiniteScroll: {\n    loadMore: 'Lataa lisää',\n    empty: 'Ei enempää',\n  },\n  rules: {\n    required: 'Tämä kenttä on pakollinen',\n    email: 'Anna kelvollinen sähköpostiosoite',\n    number: 'Tämä kenttä voi sisältää vain numeroita',\n    integer: 'Tämä kenttä voi sisältää vain kokonaislukuja',\n    capital: 'Tämä kenttä voi sisältää vain isoja kirjaimia',\n    maxLength: 'Sinun tulee syöttää enintään {0} merkkiä',\n    minLength: 'Sinun tulee syöttää vähintään {0} merkkiä',\n    strictLength: 'Syötetyn kentän pituus on virheellinen',\n    exclude: 'Merkki {0} ei ole sallittu',\n    notEmpty: 'Valitse ainakin yksi arvo',\n    pattern: 'Virheellinen muoto',\n  },\n  command: {\n    search: 'Kirjoita komento tai hae...',\n  },\n  hotkey: {\n    then: 'sitten',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: 'Nuoli ylös',\n    downArrow: 'Nuoli alas',\n    leftArrow: 'Nuoli vasemmalle',\n    rightArrow: 'Nuoli oikealle',\n    backspace: 'Askelpalautin',\n    space: 'Välilyönti',\n    plus: 'plus',\n    shortcut: 'Näppäinyhdistelmä: {0}',\n    or: 'tai',\n  },\n  video: {\n    play: 'Toista',\n    pause: 'Tauko',\n    seek: 'Hae',\n    volume: 'Äänenvoimakkuus',\n    showVolume: 'Näytä äänenvoimakkuuden säädin',\n    mute: 'Mykistä',\n    unmute: 'Poista mykistys',\n    enterFullscreen: 'Koko näyttö',\n    exitFullscreen: 'Poistu koko näytöstä',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'Valitse väri näytöltä',\n      hueSlider: 'Sävy',\n      alphaSlider: 'Alfa',\n      redInput: 'Punainen',\n      greenInput: 'Vihreä',\n      blueInput: 'Sininen',\n      alphaInput: 'Alfa',\n      hueInput: 'Sävy',\n      saturationInput: 'Kylläisyys',\n      lightnessInput: 'Vaaleus',\n      hexInput: 'HEX-arvo',\n      hexaInput: 'HEX alfa-arvolla',\n      changeFormat: 'Vaihda värimuotoa',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/fr.ts",
    "content": "export default {\n  badge: 'Badge',\n  open: 'Ouvrir',\n  close: 'Fermer',\n  dismiss: 'Ignorer',\n  confirmEdit: {\n    ok: 'OK',\n    cancel: 'Annuler',\n  },\n  dataIterator: {\n    noResultsText: 'Aucun enregistrement correspondant trouvé',\n    loadingText: `Chargement de l'élément...`,\n  },\n  dataTable: {\n    itemsPerPageText: 'Lignes par page :',\n    ariaLabel: {\n      sortDescending: 'Tri décroissant.',\n      sortAscending: 'Tri croissant.',\n      sortNone: 'Non trié.',\n      activateNone: 'Activer pour supprimer le tri.',\n      activateDescending: 'Activer pour trier par ordre décroissant.',\n      activateAscending: 'Activer pour trier par ordre croissant.',\n    },\n    sortBy: 'Trier par',\n  },\n  dataFooter: {\n    itemsPerPageText: 'Éléments par page :',\n    itemsPerPageAll: 'Tous',\n    nextPage: 'Page suivante',\n    prevPage: 'Page précédente',\n    firstPage: 'Première page',\n    lastPage: 'Dernière page',\n    pageText: '{0}-{1} de {2}',\n  },\n  dateRangeInput: {\n    divider: 'à',\n  },\n  datePicker: {\n    itemsSelected: '{0} sélectionné(s)',\n    range: {\n      title: 'Sélectionner des dates',\n      header: 'Entrer des dates',\n    },\n    title: 'Sélectionner une date',\n    header: 'Entrer une date',\n    input: {\n      placeholder: 'Entrer une date',\n    },\n    ariaLabel: {\n      previousMonth: 'Mois précédent',\n      nextMonth: 'Mois suivant',\n      selectYear: 'Sélectionner une année',\n      previousYear: 'Année précédente',\n      nextYear: 'Année suivante',\n      selectMonth: 'Sélectionner un mois',\n      selectDate: '{0}',\n      currentDate: 'Aujourd\\'hui, {0}',\n    },\n  },\n  noDataText: 'Aucune donnée disponible',\n  carousel: {\n    prev: 'Visuel précédent',\n    next: 'Visuel suivant',\n    ariaLabel: {\n      delimiter: 'Diapositive {0} de {1}',\n    },\n  },\n  calendar: {\n    moreEvents: '{0} de plus',\n    today: 'Aujourd\\'hui',\n  },\n  input: {\n    clear: 'Vider {0}',\n    prependAction: '{0} action avant',\n    appendAction: '{0} action après',\n    otp: 'Caractère {0} du mot de passe à usage unique',\n  },\n  fileInput: {\n    counter: '{0} fichier(s)',\n    counterSize: '{0} fichier(s) ({1} au total)',\n  },\n  fileUpload: {\n    title: 'Glissez-déposez des fichiers ici',\n    divider: 'ou',\n    browse: 'Parcourir les fichiers',\n  },\n  timePicker: {\n    am: 'AM',\n    pm: 'PM',\n    title: 'Sélectionner une heure',\n    hour: 'Heure',\n    minute: 'Minute',\n    second: 'Seconde',\n    notAllowed: 'La valeur n\\'est pas autorisée',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'Navigation de pagination',\n      next: 'Page suivante',\n      previous: 'Page précédente',\n      page: 'Aller à la page {0}',\n      currentPage: 'Page actuelle, Page {0}',\n      first: 'Première page',\n      last: 'Dernière page',\n    },\n  },\n  stepper: {\n    next: 'Suivant',\n    prev: 'Précédent',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'Note de {0} sur {1}',\n    },\n  },\n  loading: 'Chargement...',\n  infiniteScroll: {\n    loadMore: 'Charger plus',\n    empty: 'Aucune donnée supplémentaire',\n  },\n  rules: {\n    required: 'Ce champ est requis',\n    email: 'Veuillez entrer une adresse email valide',\n    number: 'Ce champ ne peut contenir que des chiffres',\n    integer: 'Ce champ ne peut contenir que des valeurs entières',\n    capital: 'Ce champ ne peut contenir que des lettres majuscules',\n    maxLength: 'Vous devez entrer un maximum de {0} caractères',\n    minLength: 'Vous devez entrer un minimum de {0} caractères',\n    strictLength: 'La longueur du champ entré est invalide',\n    exclude: 'Le caractère {0} n’est pas autorisé',\n    notEmpty: 'Veuillez choisir au moins une valeur',\n    pattern: 'Format invalide',\n  },\n  command: {\n    search: 'Tapez une commande ou recherchez...',\n  },\n  hotkey: {\n    then: 'puis',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Entrée',\n    escape: 'Échap',\n    upArrow: 'Flèche haut',\n    downArrow: 'Flèche bas',\n    leftArrow: 'Flèche gauche',\n    rightArrow: 'Flèche droite',\n    backspace: 'Retour',\n    space: 'Espace',\n    plus: 'plus',\n    shortcut: 'Raccourci clavier : {0}',\n    or: 'ou',\n  },\n  video: {\n    play: 'Lire',\n    pause: 'Pause',\n    seek: 'Chercher',\n    volume: 'Volume',\n    showVolume: 'Afficher le contrôle du volume',\n    mute: 'Muet',\n    unmute: 'Activer le son',\n    enterFullscreen: 'Plein écran',\n    exitFullscreen: 'Quitter le plein écran',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'Sélectionner une couleur à l\\'écran',\n      hueSlider: 'Teinte',\n      alphaSlider: 'Opacité',\n      redInput: 'Rouge',\n      greenInput: 'Vert',\n      blueInput: 'Bleu',\n      alphaInput: 'Opacité',\n      hueInput: 'Teinte',\n      saturationInput: 'Saturation',\n      lightnessInput: 'Luminosité',\n      hexInput: 'Valeur HEX',\n      hexaInput: 'Valeur HEX avec opacité',\n      changeFormat: 'Changer le format de couleur',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/he.ts",
    "content": "export default {\n  badge: 'תג',\n  open: 'פתח',\n  close: 'סגור',\n  dismiss: 'התעלם',\n  confirmEdit: {\n    ok: 'אישור',\n    cancel: 'ביטול',\n  },\n  dataIterator: {\n    noResultsText: 'לא נמצאו תוצאות מתאימות',\n    loadingText: 'טוען פריט...',\n  },\n  dataTable: {\n    itemsPerPageText: 'שורות לעמוד:',\n    ariaLabel: {\n      sortDescending: 'ממוין לפי סדר עולה. לחץ להספקת המיון.',\n      sortAscending: 'ממוין לפי סדר יורד. לחץ למיון לפי סדר עולה.',\n      sortNone: 'לא ממוין. לחץ למיון לפי סדר עולה.',\n      activateNone: 'הפעל להסרת המיון.',\n      activateDescending: 'הפעל למיון יורד.',\n      activateAscending: 'הפעל למיון עולה.',\n    },\n    sortBy: 'סדר לפי',\n  },\n  dataFooter: {\n    itemsPerPageText: 'פריטים לדף:',\n    itemsPerPageAll: 'הכל',\n    nextPage: 'עמוד הבא',\n    prevPage: 'עמוד הקודם',\n    firstPage: 'עמוד ראשון',\n    lastPage: 'עמוד אחרון',\n    pageText: '{0}-{1} מתוך {2}',\n  },\n  dateRangeInput: {\n    divider: 'עד',\n  },\n  datePicker: {\n    itemsSelected: '{0} נבחר',\n    range: {\n      title: 'בחר תאריכים',\n      header: 'הזן תאריכים',\n    },\n    title: 'בחר תאריך',\n    header: 'הזן תאריך',\n    input: {\n      placeholder: 'הזן תאריך',\n    },\n    ariaLabel: {\n      previousMonth: 'החודש הקודם',\n      nextMonth: 'החודש הבא',\n      selectYear: 'בחר שנה',\n      previousYear: 'השנה הקודמת',\n      nextYear: 'השנה הבאה',\n      selectMonth: 'בחר חודש',\n      selectDate: '{0}',\n      currentDate: 'היום, {0}',\n    },\n  },\n  noDataText: 'אין נתונים זמינים',\n  carousel: {\n    prev: 'מצג קודם',\n    next: 'מצג הבא',\n    ariaLabel: {\n      delimiter: 'שקופית {0} מתוך {1}',\n    },\n  },\n  calendar: {\n    moreEvents: '{0} נוספים',\n    today: 'היום',\n  },\n  input: {\n    clear: 'נקה {0}',\n    prependAction: '{0} פעולה מקדימה',\n    appendAction: '{0} פעולה נוספת',\n    otp: 'נא להזין תו OTP {0}',\n  },\n  fileInput: {\n    counter: '{0} קבצים',\n    counterSize: '{0} קבצים ({1} בסך הכל)',\n  },\n  fileUpload: {\n    title: 'גרור ושחרר קבצים כאן',\n    divider: 'או',\n    browse: 'עיון בקבצים',\n  },\n  timePicker: {\n    am: 'לפנה\"צ',\n    pm: 'אחה\"צ',\n    title: 'בחר שעה',\n    hour: 'שעה',\n    minute: 'דקות',\n    second: 'שניות',\n    notAllowed: 'הערך אינו מותר',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'ניווט עימוד',\n      next: 'עמוד הבא',\n      previous: 'עמוד הקודם',\n      page: '{0} לך לעמוד',\n      currentPage: '{0} עמוד נוכחי, עמוד',\n      first: 'First page',\n      last: 'Last page',\n    },\n  },\n  stepper: {\n    next: 'הבא',\n    prev: 'הקודם',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'דירוג {0} מתוך {1}',\n    },\n  },\n  loading: 'טוען...',\n  infiniteScroll: {\n    loadMore: 'טען עוד',\n    empty: 'אין עוד נתונים',\n  },\n  rules: {\n    required: 'שדה זה נדרש',\n    email: 'נא להזין כתובת דוא\"ל תקפה',\n    number: 'שדה זה יכול להכיל רק מספרים',\n    integer: 'שדה זה יכול להכיל רק ערכים שלמים',\n    capital: 'שדה זה יכול להכיל רק אותיות רישיות',\n    maxLength: 'יש להזין מקסימום {0} תווים',\n    minLength: 'יש להזין מינימום {0} תווים',\n    strictLength: 'אורך השדה שהוזן אינו תקף',\n    exclude: 'התו {0} אינו מותר',\n    notEmpty: 'נא לבחור לפחות ערך אחד',\n    pattern: 'פורמט לא תקף',\n  },\n  command: {\n    search: 'הקלד פקודה או חפש...',\n  },\n  hotkey: {\n    then: 'אז',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: 'חץ למעלה',\n    downArrow: 'חץ למטה',\n    leftArrow: 'חץ שמאלה',\n    rightArrow: 'חץ ימינה',\n    backspace: 'Backspace',\n    space: 'רווח',\n    plus: 'פלוס',\n    shortcut: 'קיצור דרך במקלדת: {0}',\n    or: 'או',\n  },\n  video: {\n    play: 'נגן',\n    pause: 'השהה',\n    seek: 'חפש',\n    volume: 'עוצמת שמע',\n    showVolume: 'הצג בקרת עוצמת שמע',\n    mute: 'השתק',\n    unmute: 'בטל השתקה',\n    enterFullscreen: 'מסך מלא',\n    exitFullscreen: 'צא ממסך מלא',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'בחר צבע מהמסך',\n      hueSlider: 'גוון',\n      alphaSlider: 'אלפא',\n      redInput: 'אדום',\n      greenInput: 'ירוק',\n      blueInput: 'כחול',\n      alphaInput: 'אלפא',\n      hueInput: 'גוון',\n      saturationInput: 'רוויה',\n      lightnessInput: 'בהירות',\n      hexInput: 'ערך HEX',\n      hexaInput: 'HEX עם ערך אלפא',\n      changeFormat: 'שנה פורמט צבע',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/hr.ts",
    "content": "export default {\n  badge: 'Bedž',\n  open: 'Otvori',\n  close: 'Zatvori',\n  dismiss: 'Odbaci',\n  confirmEdit: {\n    ok: 'OK',\n    cancel: 'Odustani',\n  },\n  dataIterator: {\n    noResultsText: 'Nisu pronađene odgovarajuće stavke',\n    loadingText: 'Učitavanje...',\n  },\n  dataTable: {\n    itemsPerPageText: 'Redaka po stranici:',\n    ariaLabel: {\n      sortDescending: 'Sortirano silazno.',\n      sortAscending: 'Sortirano uzlazno.',\n      sortNone: 'Nije sortirano.',\n      activateNone: 'Odaberite za uklanjanje sortiranja.',\n      activateDescending: 'Odaberite za silazno sortiranje.',\n      activateAscending: 'Odaberite za uzlazno sortiranje.',\n    },\n    sortBy: 'Sortirajte po',\n  },\n  dataFooter: {\n    itemsPerPageText: 'Stavki po stranici:',\n    itemsPerPageAll: 'Sve',\n    nextPage: 'Sljedeća stranica',\n    prevPage: 'Prethodna stranica',\n    firstPage: 'Prva stranica',\n    lastPage: 'Posljednja stranica',\n    pageText: '{0}-{1} od {2}',\n  },\n  dateRangeInput: {\n    divider: 'do',\n  },\n  datePicker: {\n    itemsSelected: '{0} odabrano',\n    range: {\n      title: 'Odaberite datume',\n      header: 'Unesite datume',\n    },\n    title: 'Odaberite datum',\n    header: 'Unesite datum',\n    input: {\n      placeholder: 'Unesite datum',\n    },\n    ariaLabel: {\n      previousMonth: 'Prethodni mjesec',\n      nextMonth: 'Sljedeći mjesec',\n      selectYear: 'Odaberite godinu',\n      previousYear: 'Prethodna godina',\n      nextYear: 'Sljedeća godina',\n      selectMonth: 'Odaberite mjesec',\n      selectDate: '{0}',\n      currentDate: 'Danas, {0}',\n    },\n  },\n  noDataText: 'Nema dostupnih podataka',\n  carousel: {\n    prev: 'Prethodno',\n    next: 'Sljedeće',\n    ariaLabel: {\n      delimiter: 'Slajd {0} od {1}',\n    },\n  },\n  calendar: {\n    moreEvents: 'Još {0}',\n    today: 'Danas',\n  },\n  input: {\n    clear: 'Očisti {0}',\n    prependAction: '{0} prethodna radnja',\n    appendAction: '{0} dodana radnja',\n    otp: 'Unesite OTP znak {0}',\n  },\n  fileInput: {\n    counter: 'Odabranih datoteka: {0}',\n    counterSize: 'Odabranih datoteka: {0} ({1} ukupno)',\n  },\n  fileUpload: {\n    title: 'Povucite i ispustite datoteke ovdje',\n    divider: 'ili',\n    browse: 'Pregledaj datoteke',\n  },\n  timePicker: {\n    am: 'AM',\n    pm: 'PM',\n    title: 'Odaberite vrijeme',\n    hour: 'Sat',\n    minute: 'Minute',\n    second: 'Sekunde',\n    notAllowed: 'Vrijednost nije dopuštena',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'Navigacija stranicama',\n      next: 'Sljedeća stranica',\n      previous: 'Prethodna stranica',\n      page: 'Idi na stranicu {0}',\n      currentPage: 'Trenutna stranica, stranica {0}',\n      first: 'Prva stranica',\n      last: 'Posljednja stranica',\n    },\n  },\n  stepper: {\n    next: 'Sljedeće',\n    prev: 'Prethodno',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'Ocjena {0} od {1}',\n    },\n  },\n  loading: 'Učitavanje...',\n  infiniteScroll: {\n    loadMore: 'Učitaj više',\n    empty: 'Nema više',\n  },\n  rules: {\n    required: 'Ovo polje je obavezno',\n    email: 'Unesite valjanu e-mail adresu',\n    number: 'Ovo polje može sadržavati samo brojeve',\n    integer: 'Ovo polje može sadržavati samo cijele brojeve',\n    capital: 'Ovo polje može sadržavati samo velika slova',\n    maxLength: 'Morate unijeti najviše {0} znakova',\n    minLength: 'Morate unijeti najmanje {0} znakova',\n    strictLength: 'Duljina unesenog polja nije valjana',\n    exclude: 'Znak {0} nije dopušten',\n    notEmpty: 'Odaberite barem jednu vrijednost',\n    pattern: 'Nevaljan format',\n  },\n  command: {\n    search: 'Unesite naredbu ili pretražite...',\n  },\n  hotkey: {\n    then: 'zatim',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: 'Strelica gore',\n    downArrow: 'Strelica dolje',\n    leftArrow: 'Strelica lijevo',\n    rightArrow: 'Strelica desno',\n    backspace: 'Backspace',\n    space: 'Razmak',\n    plus: 'plus',\n    shortcut: 'Tipkovnička prečica: {0}',\n    or: 'ili',\n  },\n  video: {\n    play: 'Reproduciraj',\n    pause: 'Pauziraj',\n    seek: 'Traži',\n    volume: 'Glasnoća',\n    showVolume: 'Prikaži kontrolu glasnoće',\n    mute: 'Isključi zvuk',\n    unmute: 'Uključi zvuk',\n    enterFullscreen: 'Puni zaslon',\n    exitFullscreen: 'Izađi iz punog zaslona',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'Odaberite boju sa zaslona',\n      hueSlider: 'Nijansa',\n      alphaSlider: 'Prozirnost',\n      redInput: 'Crvena',\n      greenInput: 'Zelena',\n      blueInput: 'Plava',\n      alphaInput: 'Prozirnost',\n      hueInput: 'Nijansa',\n      saturationInput: 'Zasićenost',\n      lightnessInput: 'Svjetlina',\n      hexInput: 'HEX vrijednost',\n      hexaInput: 'HEX vrijednost s prozirnošću',\n      changeFormat: 'Promijeni format boje',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/hu.ts",
    "content": "export default {\n  badge: 'Jelvény',\n  open: 'Megnyit',\n  close: 'Bezárás',\n  dismiss: 'Elutasít',\n  confirmEdit: {\n    ok: 'OK',\n    cancel: 'Mégsem',\n  },\n  dataIterator: {\n    noResultsText: 'Nincs egyező találat',\n    loadingText: 'Betöltés...',\n  },\n  dataTable: {\n    itemsPerPageText: 'Elem oldalanként:',\n    ariaLabel: {\n      sortDescending: 'Csökkenő sorrendbe rendezve.',\n      sortAscending: 'Növekvő sorrendbe rendezve.',\n      sortNone: 'Rendezetlen.',\n      activateNone: 'Rendezés törlése.',\n      activateDescending: 'Aktiváld a csökkenő rendezésért.',\n      activateAscending: 'Aktiváld a növekvő rendezésért.',\n    },\n    sortBy: 'Rendezés',\n  },\n  dataFooter: {\n    itemsPerPageText: 'Elem oldalanként:',\n    itemsPerPageAll: 'Mind',\n    nextPage: 'Következő oldal',\n    prevPage: 'Előző oldal',\n    firstPage: 'Első oldal',\n    lastPage: 'Utolsó oldal',\n    pageText: '{0}-{1} / {2}',\n  },\n  dateRangeInput: {\n    divider: '–',\n  },\n  datePicker: {\n    itemsSelected: '{0} kiválasztva',\n    range: {\n      title: 'Válassza ki a dátumokat',\n      header: 'Adja meg a dátumokat',\n    },\n    title: 'Válassza ki a dátumot',\n    header: 'Adja meg a dátumot',\n    input: {\n      placeholder: 'Adja meg a dátumot',\n    },\n    ariaLabel: {\n      previousMonth: 'Előző hónap',\n      nextMonth: 'Következő hónap',\n      selectYear: 'Év kiválasztása',\n      previousYear: 'Előző év',\n      nextYear: 'Következő év',\n      selectMonth: 'Hónap kiválasztása',\n      selectDate: '{0}',\n      currentDate: 'Ma, {0}',\n    },\n  },\n  noDataText: 'Nincs elérhető adat',\n  carousel: {\n    prev: 'Előző',\n    next: 'Következő',\n    ariaLabel: {\n      delimiter: 'Dia {0}/{1}',\n    },\n  },\n  calendar: {\n    moreEvents: '{0} további',\n    today: 'Ma',\n  },\n  input: {\n    clear: 'Törlés {0}',\n    prependAction: '{0} előrehozott művelet',\n    appendAction: '{0} hozzáadott művelet',\n    otp: 'Kérjük, adja meg az OTP karaktert: {0}',\n  },\n  fileInput: {\n    counter: '{0} fájl',\n    counterSize: '{0} fájl ({1} összesen)',\n  },\n  fileUpload: {\n    title: 'Húzza ide a fájlokat',\n    divider: 'vagy',\n    browse: 'Tallózás',\n  },\n  timePicker: {\n    am: 'de',\n    pm: 'du',\n    title: 'Válassza ki az időpontot',\n    hour: 'Óra',\n    minute: 'Perc',\n    second: 'Másodperc',\n    notAllowed: 'Az érték nem engedélyezett',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'Oldal navigáció',\n      next: 'Következő oldal',\n      previous: 'Előző oldal',\n      page: 'Menj a(z) {0}. oldalra',\n      currentPage: 'Aktuális oldal: {0}',\n      first: 'Első oldal',\n      last: 'Utolsó oldal',\n    },\n  },\n  stepper: {\n    next: 'Következő',\n    prev: 'Előző',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'Értékelés: {0} / {1}',\n    },\n  },\n  loading: 'Betöltés...',\n  infiniteScroll: {\n    loadMore: 'Továbbiak betöltése',\n    empty: 'Nincsen több',\n  },\n  rules: {\n    required: 'Ez a mező kötelező',\n    email: 'Kérlek, adj meg egy érvényes e-mail címet',\n    number: 'Ez a mező csak számokat tartalmazhat',\n    integer: 'Ez a mező csak egész számokat tartalmazhat',\n    capital: 'Ez a mező csak nagybetűket tartalmazhat',\n    maxLength: 'Maximum {0} karaktert adhatsz meg',\n    minLength: 'Minimum {0} karaktert kell megadnod',\n    strictLength: 'A megadott mező hossza érvénytelen',\n    exclude: 'A(z) {0} karakter nem engedélyezett',\n    notEmpty: 'Kérlek, válassz legalább egy értéket',\n    pattern: 'Érvénytelen formátum',\n  },\n  command: {\n    search: 'Írjon be parancsot vagy keressen...',\n  },\n  hotkey: {\n    then: 'majd',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: 'Fel nyíl',\n    downArrow: 'Le nyíl',\n    leftArrow: 'Bal nyíl',\n    rightArrow: 'Jobb nyíl',\n    backspace: 'Backspace',\n    space: 'Szóköz',\n    plus: 'plusz',\n    shortcut: 'Billentyűparancs: {0}',\n    or: 'vagy',\n  },\n  video: {\n    play: 'Lejátszás',\n    pause: 'Szünet',\n    seek: 'Keresés',\n    volume: 'Hangerő',\n    showVolume: 'Hangerőszabályzó megjelenítése',\n    mute: 'Némítás',\n    unmute: 'Némítás feloldása',\n    enterFullscreen: 'Teljes képernyő',\n    exitFullscreen: 'Kilépés a teljes képernyőből',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'Szín kiválasztása a képernyőről',\n      hueSlider: 'Árnyalat',\n      alphaSlider: 'Átlátszóság',\n      redInput: 'Vörös',\n      greenInput: 'Zöld',\n      blueInput: 'Kék',\n      alphaInput: 'Átlátszóság',\n      hueInput: 'Árnyalat',\n      saturationInput: 'Telítettség',\n      lightnessInput: 'Világosság',\n      hexInput: 'HEX érték',\n      hexaInput: 'HEX érték átlátszósággal',\n      changeFormat: 'Színformátum módosítása',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/id.ts",
    "content": "export default {\n  badge: 'Lencana',\n  open: 'Buka',\n  close: 'Tutup',\n  dismiss: 'Tutup',\n  confirmEdit: {\n    ok: 'OK',\n    cancel: 'Batal',\n  },\n  dataIterator: {\n    noResultsText: 'Tidak ditemukan catatan yang cocok',\n    loadingText: 'Memuat data...',\n  },\n  dataTable: {\n    itemsPerPageText: 'Baris per halaman:',\n    ariaLabel: {\n      sortDescending: 'Diurutkan kebawah.',\n      sortAscending: 'Diurutkan keatas.',\n      sortNone: 'Tidak diurutkan.',\n      activateNone: 'Aktifkan untuk menghapus penyortiran.',\n      activateDescending: 'Aktifkan untuk mengurutkan kebawah.',\n      activateAscending: 'Aktifkan untuk mengurutkan keatas.',\n    },\n    sortBy: 'Urutkan berdasar',\n  },\n  dataFooter: {\n    itemsPerPageText: 'Item per halaman:',\n    itemsPerPageAll: 'Semua',\n    nextPage: 'Halaman selanjutnya',\n    prevPage: 'Halaman sebelumnya',\n    firstPage: 'Halaman pertama',\n    lastPage: 'Halaman terakhir',\n    pageText: '{0}-{1} dari {2}',\n  },\n  dateRangeInput: {\n    divider: 'hingga',\n  },\n  datePicker: {\n    itemsSelected: '{0} dipilih',\n    range: {\n      title: 'Pilih tanggal',\n      header: 'Masukkan tanggal',\n    },\n    title: 'Pilih tanggal',\n    header: 'Masukkan tanggal',\n    input: {\n      placeholder: 'Masukkan tanggal',\n    },\n    ariaLabel: {\n      previousMonth: 'Bulan sebelumnya',\n      nextMonth: 'Bulan berikutnya',\n      selectYear: 'Pilih tahun',\n      previousYear: 'Tahun sebelumnya',\n      nextYear: 'Tahun berikutnya',\n      selectMonth: 'Pilih bulan',\n      selectDate: '{0}',\n      currentDate: 'Hari ini, {0}',\n    },\n  },\n  noDataText: 'Tidak ada data tersedia',\n  carousel: {\n    prev: 'Visual sebelumnya',\n    next: 'Visual selanjutnya',\n    ariaLabel: {\n      delimiter: 'Slide {0} dari {1}',\n    },\n  },\n  calendar: {\n    moreEvents: '{0} lagi',\n    today: 'Hari ini',\n  },\n  input: {\n    clear: 'Bersihkan {0}',\n    prependAction: '{0} aksi diawal',\n    appendAction: '{0} aksi diakhir',\n    otp: 'Masukkan karakter OTP {0}',\n  },\n  fileInput: {\n    counter: '{0} berkas',\n    counterSize: '{0} berkas (dari total {1})',\n  },\n  fileUpload: {\n    title: 'Seret dan lepas berkas di sini',\n    divider: 'atau',\n    browse: 'Telusuri Berkas',\n  },\n  timePicker: {\n    am: 'AM',\n    pm: 'PM',\n    title: 'Pilih Waktu',\n    hour: 'Jam',\n    minute: 'Menit',\n    second: 'Detik',\n    notAllowed: 'Nilai tidak diizinkan',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'Navigasi Halaman',\n      next: 'Halaman selanjutnya',\n      previous: 'Halaman sebelumnya',\n      page: 'Buka halaman {0}',\n      currentPage: 'Halaman saat ini, Halaman {0}',\n      first: 'Halaman pertama',\n      last: 'Halaman terakhir',\n    },\n  },\n  stepper: {\n    next: 'Selanjutnya',\n    prev: 'Sebelumnya',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'Penilaian {0} dari {1}',\n    },\n  },\n  loading: 'Memuat...',\n  infiniteScroll: {\n    loadMore: 'Muat lebih banyak',\n    empty: 'Tidak ada lagi',\n  },\n  rules: {\n    required: 'Kolom ini wajib diisi',\n    email: 'Masukkan alamat email yang valid',\n    number: 'Kolom ini hanya boleh berisi angka',\n    integer: 'Kolom ini hanya boleh berisi bilangan bulat',\n    capital: 'Kolom ini hanya boleh berisi huruf kapital',\n    maxLength: 'Anda harus memasukkan maksimum {0} karakter',\n    minLength: 'Anda harus memasukkan minimum {0} karakter',\n    strictLength: 'Panjang kolom yang dimasukkan tidak valid',\n    exclude: 'Karakter {0} tidak diperbolehkan',\n    notEmpty: 'Pilih setidaknya satu nilai',\n    pattern: 'Format tidak valid',\n  },\n  command: {\n    search: 'Ketik perintah atau cari...',\n  },\n  hotkey: {\n    then: 'kemudian',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: 'Panah Atas',\n    downArrow: 'Panah Bawah',\n    leftArrow: 'Panah Kiri',\n    rightArrow: 'Panah Kanan',\n    backspace: 'Hapus',\n    space: 'Spasi',\n    plus: 'plus',\n    shortcut: 'Pintasan keyboard: {0}',\n    or: 'atau',\n  },\n  video: {\n    play: 'Putar',\n    pause: 'Jeda',\n    seek: 'Cari',\n    volume: 'Volume',\n    showVolume: 'Tampilkan kontrol volume',\n    mute: 'Bisukan',\n    unmute: 'Bunyikan',\n    enterFullscreen: 'Layar penuh',\n    exitFullscreen: 'Keluar dari layar penuh',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'Pilih warna dari layar',\n      hueSlider: 'Rona',\n      alphaSlider: 'Alfa',\n      redInput: 'Merah',\n      greenInput: 'Hijau',\n      blueInput: 'Biru',\n      alphaInput: 'Alfa',\n      hueInput: 'Rona',\n      saturationInput: 'Saturasi',\n      lightnessInput: 'Kecerahan',\n      hexInput: 'Nilai HEX',\n      hexaInput: 'HEX dengan nilai alfa',\n      changeFormat: 'Ubah format warna',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/index.ts",
    "content": "export { default as af } from './af'\nexport { default as ar } from './ar'\nexport { default as bg } from './bg'\nexport { default as ca } from './ca'\nexport { default as ckb } from './ckb'\nexport { default as cs } from './cs'\nexport { default as da } from './da'\nexport { default as de } from './de'\nexport { default as el } from './el'\nexport { default as en } from './en'\nexport { default as es } from './es'\nexport { default as et } from './et'\nexport { default as fa } from './fa'\nexport { default as fi } from './fi'\nexport { default as fr } from './fr'\nexport { default as hr } from './hr'\nexport { default as hu } from './hu'\nexport { default as he } from './he'\nexport { default as id } from './id'\nexport { default as it } from './it'\nexport { default as ja } from './ja'\nexport { default as km } from './km'\nexport { default as ko } from './ko'\nexport { default as lv } from './lv'\nexport { default as lt } from './lt'\nexport { default as nl } from './nl'\nexport { default as no } from './no'\nexport { default as pl } from './pl'\nexport { default as pt } from './pt'\nexport { default as ro } from './ro'\nexport { default as ru } from './ru'\nexport { default as sk } from './sk'\nexport { default as sl } from './sl'\nexport { default as srCyrl } from './sr-Cyrl'\nexport { default as srLatn } from './sr-Latn'\nexport { default as sv } from './sv'\nexport { default as th } from './th'\nexport { default as tr } from './tr'\nexport { default as az } from './az'\nexport { default as uk } from './uk'\nexport { default as vi } from './vi'\nexport { default as zhHans } from './zh-Hans'\nexport { default as zhHant } from './zh-Hant'\n"
  },
  {
    "path": "packages/vuetify/src/locale/it.ts",
    "content": "export default {\n  badge: 'Distintivo',\n  open: 'Apri',\n  close: 'Chiudi',\n  dismiss: 'Ignora',\n  confirmEdit: {\n    ok: 'OK',\n    cancel: 'Annulla',\n  },\n  dataIterator: {\n    noResultsText: 'Nessun risultato trovato',\n    loadingText: 'Caricamento in corso...',\n  },\n  dataTable: {\n    itemsPerPageText: 'Righe per pagina:',\n    ariaLabel: {\n      sortDescending: 'Ordinati in ordine decrescente.',\n      sortAscending: 'Ordinati in ordine crescente.',\n      sortNone: 'Non ordinato.',\n      activateNone: `Attiva per rimuovere l'ordinamento.`,\n      activateDescending: 'Attiva per ordinare in ordine decrescente.',\n      activateAscending: 'Attiva per ordinare in ordine crescente.',\n    },\n    sortBy: 'Ordina per',\n  },\n  dataFooter: {\n    itemsPerPageText: 'Elementi per pagina:',\n    itemsPerPageAll: 'Tutti',\n    nextPage: 'Pagina seguente',\n    prevPage: 'Pagina precedente',\n    firstPage: 'Prima pagina',\n    lastPage: 'Ultima pagina',\n    pageText: '{0}-{1} di {2}',\n  },\n  dateRangeInput: {\n    divider: 'a',\n  },\n  datePicker: {\n    itemsSelected: '{0} selezionato/i',\n    range: {\n      title: 'Seleziona date',\n      header: 'Inserisci date',\n    },\n    title: 'Seleziona data',\n    header: 'Inserisci data',\n    input: {\n      placeholder: 'Inserisci data',\n    },\n    ariaLabel: {\n      previousMonth: 'Mese precedente',\n      nextMonth: 'Mese successivo',\n      selectYear: 'Seleziona anno',\n      previousYear: 'Anno precedente',\n      nextYear: 'Anno successivo',\n      selectMonth: 'Seleziona mese',\n      selectDate: '{0}',\n      currentDate: 'Oggi, {0}',\n    },\n  },\n  noDataText: 'Nessun elemento disponibile',\n  carousel: {\n    prev: 'Vista precedente',\n    next: 'Prossima vista',\n    ariaLabel: {\n      delimiter: 'Slide carosello {0} di {1}',\n    },\n  },\n  calendar: {\n    moreEvents: '{0} di più',\n    today: 'Oggi',\n  },\n  input: {\n    clear: 'Cancella {0}',\n    prependAction: 'Azione precedente {0}',\n    appendAction: 'Azione successiva {0}',\n    otp: 'Inserisci il codice OTP {0}',\n  },\n  fileInput: {\n    counter: '{0} file',\n    counterSize: '{0} file ({1} in totale)',\n  },\n  fileUpload: {\n    title: 'Trascina e rilascia i file qui',\n    divider: 'o',\n    browse: 'Sfoglia i file',\n  },\n  timePicker: {\n    am: 'AM',\n    pm: 'PM',\n    title: 'Seleziona l\\'ora',\n    hour: 'Ora',\n    minute: 'Minuti',\n    second: 'Secondi',\n    notAllowed: 'Il valore non è consentito',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'Navigazione impaginazione',\n      next: 'Pagina seguente',\n      previous: 'Pagina precedente',\n      page: 'Vai alla pagina {0}',\n      currentPage: 'Pagina corrente, pagina {0}',\n      first: 'Prima pagina',\n      last: 'Ultima pagina',\n    },\n  },\n  stepper: {\n    next: 'Successivo',\n    prev: 'Precedente',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'Valutazione {0} di {1}',\n    },\n  },\n  loading: 'Caricamento...',\n  infiniteScroll: {\n    loadMore: 'Carica altro',\n    empty: 'Nessun elemento',\n  },\n  rules: {\n    required: 'Questo campo è obbligatorio',\n    email: 'Inserisci un indirizzo email valido',\n    number: 'Questo campo può contenere solo numeri',\n    integer: 'Questo campo può contenere solo valori interi',\n    capital: 'Questo campo può contenere solo lettere maiuscole',\n    maxLength: 'Devi inserire un massimo di {0} caratteri',\n    minLength: 'Devi inserire un minimo di {0} caratteri',\n    strictLength: 'La lunghezza del campo inserito non è valida',\n    exclude: 'Il carattere {0} non è consentito',\n    notEmpty: 'Seleziona almeno un valore',\n    pattern: 'Formato non valido',\n  },\n  command: {\n    search: 'Digita un comando o cerca...',\n  },\n  hotkey: {\n    then: 'poi',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Invio',\n    escape: 'Escape',\n    upArrow: 'Freccia su',\n    downArrow: 'Freccia giù',\n    leftArrow: 'Freccia sinistra',\n    rightArrow: 'Freccia destra',\n    backspace: 'Canc',\n    space: 'Spazio',\n    plus: 'più',\n    shortcut: 'Scorciatoia da tastiera: {0}',\n    or: 'o',\n  },\n  video: {\n    play: 'Riproduci',\n    pause: 'Metti in pausa',\n    seek: 'Cerca',\n    volume: 'Volume',\n    showVolume: 'Mostra controllo volume',\n    mute: 'Muto',\n    unmute: 'Riattiva audio',\n    enterFullscreen: 'Schermo intero',\n    exitFullscreen: 'Esci da schermo intero',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'Seleziona il colore dallo schermo',\n      hueSlider: 'Tonalità',\n      alphaSlider: 'Trasparenza',\n      redInput: 'Rosso',\n      greenInput: 'Verde',\n      blueInput: 'Blu',\n      alphaInput: 'Trasparenza',\n      hueInput: 'Tonalità',\n      saturationInput: 'Saturazione',\n      lightnessInput: 'Luminosità',\n      hexInput: 'Valore esadecimale',\n      hexaInput: 'Valore esadecimale con trasparenza',\n      changeFormat: 'Cambia formato colore',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/ja.ts",
    "content": "export default {\n  badge: 'バッジ',\n  open: '開く',\n  close: '閉じる',\n  dismiss: '閉じる',\n  confirmEdit: {\n    ok: 'OK',\n    cancel: 'キャンセル',\n  },\n  dataIterator: {\n    noResultsText: '検索結果が見つかりません。',\n    loadingText: '項目をロード中です...',\n  },\n  dataTable: {\n    itemsPerPageText: '1ページあたりの行数：',\n    ariaLabel: {\n      sortDescending: '降順の並び替え。',\n      sortAscending: '昇順の並び替え。',\n      sortNone: 'ソートされていません。',\n      activateNone: 'ソートを削除するには有効にしてください。',\n      activateDescending: '降順の並び替えのためには有効にしてください。',\n      activateAscending: '昇順のソートのためには有効にしてください。',\n    },\n    sortBy: 'ソート方式',\n  },\n  dataFooter: {\n    itemsPerPageText: '1ページあたりの件数：',\n    itemsPerPageAll: 'すべて',\n    nextPage: '次のページ',\n    prevPage: '前のページ',\n    firstPage: '最初のページ',\n    lastPage: '最後のページ',\n    pageText: '{0}-{1} 件目 / {2}件',\n  },\n  dateRangeInput: {\n    divider: 'から',\n  },\n  datePicker: {\n    itemsSelected: '{0} 選択済',\n    range: {\n      title: '日付を選択',\n      header: '日付を入力',\n    },\n    title: '日付を選択',\n    header: '日付を入力',\n    input: {\n      placeholder: '日付を入力',\n    },\n    ariaLabel: {\n      previousMonth: '前の月',\n      nextMonth: '次の月',\n      selectYear: '年を選択',\n      previousYear: '前の年',\n      nextYear: '次の年',\n      selectMonth: '月を選択',\n      selectDate: '{0}',\n      currentDate: '今日、{0}',\n    },\n  },\n  noDataText: 'データはありません。',\n  carousel: {\n    prev: '前のビジュアル',\n    next: '次のビジュアル',\n    ariaLabel: {\n      delimiter: 'カルーセルのスライド {0}件目 / {1}件',\n    },\n  },\n  calendar: {\n    moreEvents: 'さらに{0}',\n    today: '今日',\n  },\n  input: {\n    clear: 'クリア {0}',\n    prependAction: '{0} の前に追加されたアクション',\n    appendAction: '{0} の後に追加されたアクション',\n    otp: '{0}番目のワンタイムパスワードを入力してください',\n  },\n  fileInput: {\n    counter: '{0} ファイル',\n    counterSize: '{0} ファイル (合計 {1})',\n  },\n  fileUpload: {\n    title: 'ここにファイルをドラッグ＆ドロップ',\n    divider: 'または',\n    browse: 'ファイルを選択',\n  },\n  timePicker: {\n    am: '午前',\n    pm: '午後',\n    title: '時間を選択',\n    hour: '時',\n    minute: '分',\n    second: '秒',\n    notAllowed: '値は許可されていません',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'ページネーションナビゲーション',\n      next: '次のページ',\n      previous: '前のページ',\n      page: '{0}ページ目に移動',\n      currentPage: '現在のページ、ページ {0}',\n      first: '最初のページ',\n      last: '最後のページ',\n    },\n  },\n  stepper: {\n    next: '次へ',\n    prev: '前へ',\n  },\n  rating: {\n    ariaLabel: {\n      item: '評価 {1} のうち {0}',\n    },\n  },\n  loading: 'ロード中...',\n  infiniteScroll: {\n    loadMore: 'さらに読み込む',\n    empty: 'データがありません',\n  },\n  rules: {\n    required: 'このフィールドは必須です',\n    email: '有効なメールアドレスを入力してください',\n    number: 'このフィールドには数字のみ入力できます',\n    integer: 'このフィールドには整数のみ入力できます',\n    capital: 'このフィールドには大文字のみ入力できます',\n    maxLength: '最大{0}文字まで入力してください',\n    minLength: '最低{0}文字以上入力してください',\n    strictLength: '入力されたフィールドの長さが無効です',\n    exclude: '{0}という文字は使用できません',\n    notEmpty: '少なくとも1つの値を選んでください',\n    pattern: '無効な形式です',\n  },\n  command: {\n    search: 'コマンドを入力するか検索...',\n  },\n  hotkey: {\n    then: '次に',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: '上矢印',\n    downArrow: '下矢印',\n    leftArrow: '左矢印',\n    rightArrow: '右矢印',\n    backspace: 'バックスペース',\n    space: 'スペース',\n    plus: 'プラス',\n    shortcut: 'キーボードショートカット: {0}',\n    or: 'または',\n  },\n  video: {\n    play: '再生',\n    pause: '一時停止',\n    seek: 'シーク',\n    volume: '音量',\n    showVolume: '音量コントロールを表示',\n    mute: 'ミュート',\n    unmute: 'ミュート解除',\n    enterFullscreen: '全画面表示',\n    exitFullscreen: '全画面表示を終了',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: '画面から色を選択',\n      hueSlider: '色相',\n      alphaSlider: 'アルファ',\n      redInput: '赤',\n      greenInput: '緑',\n      blueInput: '青',\n      alphaInput: 'アルファ',\n      hueInput: '色相',\n      saturationInput: '彩度',\n      lightnessInput: '明度',\n      hexInput: 'HEX値',\n      hexaInput: 'アルファ付きHEX値',\n      changeFormat: 'カラーフォーマットを変更',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/km.ts",
    "content": "export default {\n  badge: 'ផ្លាក',\n  open: 'បើក',\n  close: 'បិទ',\n  dismiss: 'បោះបង់',\n  confirmEdit: {\n    ok: 'យល់ព្រម',\n    cancel: 'បោះបង់',\n  },\n  dataIterator: {\n    noResultsText: 'មិនមានទិន្នន័យដែលត្រូវគ្នាទេ',\n    loadingText: 'កំពុងដំណើរការ...',\n  },\n  dataTable: {\n    itemsPerPageText: 'ជ្រើសរើសពត៌មានក្នុងមួយទំព័រ:',\n    ariaLabel: {\n      sortDescending: 'តំណទំហំចុះរួម។',\n      sortAscending: 'តំណទំហំឡើងរួម។',\n      sortNone: 'មិនចុះរួម។',\n      activateNone: 'ចុចដើម្បីដកតំណទំហំ។',\n      activateDescending: 'ចុចដើម្បីតំណទំហំចុះរួម។',\n      activateAscending: 'ចុចដើម្បីតំណទំហំឡើងរួម។',\n    },\n    sortBy: 'តម្រៀបតាម',\n  },\n  dataFooter: {\n    itemsPerPageText: 'ទំនិញក្នុងមួយទំព័រ:',\n    itemsPerPageAll: 'ទាំងអស់',\n    nextPage: 'ទំព័របន្ទាប់',\n    prevPage: 'ទំព័រមុន',\n    firstPage: 'ទំព័រដំបូង',\n    lastPage: 'ទំព័រចុងក្រោយ',\n    pageText: '{0}-{1} នៃ {2}',\n  },\n  dateRangeInput: {\n    divider: 'ដល់',\n  },\n  datePicker: {\n    itemsSelected: '{0} ត្រូវបានជ្រើសរើស',\n    range: {\n      title: 'ជ្រើសរើសកាលបរិច្ឆេទ',\n      header: 'បញ្ចូលកាលបរិច្ឆេទ',\n    },\n    title: 'ជ្រើសរើសកាលបរិច្ឆេទ',\n    header: 'បញ្ចូលកាលបរិច្ឆេទ',\n    input: {\n      placeholder: 'បញ្ចូលកាលបរិច្ឆេទ',\n    },\n    ariaLabel: {\n      previousMonth: 'Previous month',\n      nextMonth: 'Next month',\n      selectYear: 'Select year',\n      previousYear: 'ឆ្នាំមុន',\n      nextYear: 'ឆ្នាំក្រោយ',\n      selectMonth: 'ជ្រើសរើសខែ',\n      selectDate: '{0}',\n      currentDate: 'Today, {0}',\n    },\n  },\n  noDataText: 'គ្មានទិន្នន័យដែលមាន',\n  carousel: {\n    prev: 'រុករករូបភាពមុន',\n    next: 'រុករករូបភាពបន្ទាប់',\n    ariaLabel: {\n      delimiter: 'រូបភាពទី {0} នៃ {1} ក្នុងកម្រិតការរុករក',\n    },\n  },\n  calendar: {\n    moreEvents: '{0} ទៀត',\n    today: 'ថ្ងៃនេះ',\n  },\n  input: {\n    clear: 'សម្អាត {0}',\n    prependAction: '{0} សម្អាតសកម្ម',\n    appendAction: '{0} សម្អាតសកម្ម',\n    otp: 'សូមបញ្ចូលតួអក្សរ OTP {0}',\n  },\n  fileInput: {\n    counter: '{0} ឯកសារ',\n    counterSize: '{0} ឯកសារ ({1} សរុប)',\n  },\n  fileUpload: {\n    title: 'អូសហើយទម្លាក់ឯកសារនៅទីនេះ',\n    divider: 'ឬ',\n    browse: 'រកមើលឯកសារ',\n  },\n  timePicker: {\n    am: 'ព្រឹក',\n    pm: 'ល្ងាច',\n    title: 'ជ្រើសរើសម៉ោង',\n    hour: 'ម៉ោង',\n    minute: 'នាទី',\n    second: 'វិនាទី',\n    notAllowed: 'តម្លៃមិនត្រូវបានអនុញ្ញាតទេ',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'ការរុករកទំព័រ',\n      next: 'ទំព័របន្ទាប់',\n      previous: 'ទំព័រមុន',\n      page: 'ទៅទំព័រ {0}',\n      currentPage: 'ទំព័រ {0}, ទំព័របច្ចុប្បន្ន',\n      first: 'ទំព័រដំបូង',\n      last: 'ទំព័រចុងក្រោយ',\n    },\n  },\n  stepper: {\n    next: 'បន្ទាប់',\n    prev: 'មុន',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'ការវាយតម្លៃ {0} នៃ {1}',\n    },\n  },\n  loading: 'កំពុងដំណើរការ...',\n  infiniteScroll: {\n    loadMore: 'ទាញយកបន្ថែម',\n    empty: 'គ្មានទំព័រទៀត',\n  },\n  rules: {\n    required: 'វាលនេះត្រូវបានទាមទារ',\n    email: 'សូមបញ្ចូលអ៊ីមែលត្រឹមត្រូវ',\n    number: 'វាលនេះអាចមានតែលេខប៉ុណ្ណោះ',\n    integer: 'វាលនេះអាចមានតែចំនួនគត់ប៉ុណ្ណោះ',\n    capital: 'វាលនេះអាចមានតែអក្សរធំប៉ុណ្ណោះ',\n    maxLength: 'អ្នកត្រូវបញ្ចូលអតិបរមា {0} តួអក្សរ',\n    minLength: 'អ្នកត្រូវបញ្ចូលយ៉ាងហោចណាស់ {0} តួអក្សរ',\n    strictLength: 'ប្រវែងនៃវាលដែលបានបញ្ចូលមិនត្រឹមត្រូវទេ',\n    exclude: 'តួអក្សរ {0} មិនត្រូវបានអនុញ្ញាតទេ',\n    notEmpty: 'សូមជ្រើសរើសយ៉ាងហោចណាស់តម្លៃមួយ',\n    pattern: 'ទម្រង់មិនត្រឹមត្រូវ',\n  },\n  command: {\n    search: 'វាយបញ្ចូលពាក្យបញ្ជា ឬស្វាគមន៍...',\n  },\n  hotkey: {\n    then: 'បន្ទាប់មក',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: 'ព្រួញ​ឡើង​លើ',\n    downArrow: 'ព្រួញ​ចុះក្រោម',\n    leftArrow: 'ព្រួញ​ឆ្វេង',\n    rightArrow: 'ព្រួញ​ស្តាំ',\n    backspace: 'Backspace',\n    space: 'ដកឃ្លា',\n    plus: 'បូក',\n    shortcut: 'គ្រាប់ចុចរហ័ស: {0}',\n    or: 'ឬ',\n  },\n  video: {\n    play: 'លេង',\n    pause: 'ផ្អាក',\n    seek: 'ស្វែងរក',\n    volume: 'កម្រិតសំឡេង',\n    showVolume: 'បង្ហាញការគ្រប់គ្រងកម្រិតសំឡេង',\n    mute: 'បិទសំឡេង',\n    unmute: 'បើក​សំឡេង',\n    enterFullscreen: 'ពេញអេក្រង់',\n    exitFullscreen: 'ចេញពីអេក្រង់ពេ',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'ជ្រើសរើសពណ៌ពីអេក្រង់',\n      hueSlider: 'ពណ៌',\n      alphaSlider: 'អាល់ហ្វា',\n      redInput: 'ក្រហម',\n      greenInput: 'បៃតង',\n      blueInput: 'ខៀវ',\n      alphaInput: 'អាល់ហ្វា',\n      hueInput: 'ពណ៌',\n      saturationInput: 'តិត្ថិភាព',\n      lightnessInput: 'ពន្លឺ',\n      hexInput: 'តម្លៃ HEX',\n      hexaInput: 'HEX ដែលមានតម្លៃអាល់ហ្វា',\n      changeFormat: 'ប្ដូរទម្រង់ពណ៌',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/ko.ts",
    "content": "export default {\n  badge: '배지',\n  open: '열기',\n  close: '닫기',\n  dismiss: '닫기',\n  confirmEdit: {\n    ok: '확인',\n    cancel: '취소',\n  },\n  dataIterator: {\n    noResultsText: '일치하는 항목이 없습니다.',\n    loadingText: '불러오는 중...',\n  },\n  dataTable: {\n    itemsPerPageText: '페이지 당 행 수:',\n    ariaLabel: {\n      sortDescending: '내림차순 정렬.',\n      sortAscending: '오름차순 정렬.',\n      sortNone: '정렬하지 않음.',\n      activateNone: '정렬을 취소하려면 활성화하세요.',\n      activateDescending: '내림차순 정렬을 위해 활성화하세요.',\n      activateAscending: '오름차순 정렬을 위해 활성화하세요.',\n    },\n    sortBy: '정렬 기준',\n  },\n  dataFooter: {\n    itemsPerPageText: '페이지 당 항목 수:',\n    itemsPerPageAll: '전체',\n    nextPage: '다음 페이지',\n    prevPage: '이전 페이지',\n    firstPage: '첫 페이지',\n    lastPage: '마지막 페이지',\n    pageText: '{2} 중 {0}-{1}',\n  },\n  dateRangeInput: {\n    divider: '부터',\n  },\n  datePicker: {\n    itemsSelected: '{0}개 선택됨',\n    range: {\n      title: '날짜 선택',\n      header: '날짜 입력',\n    },\n    title: '날짜 선택',\n    header: '날짜 입력',\n    input: {\n      placeholder: '날짜 입력',\n    },\n    ariaLabel: {\n      previousMonth: '이전 달',\n      nextMonth: '다음 달',\n      selectYear: '연도 선택',\n      previousYear: '이전 연도',\n      nextYear: '다음 연도',\n      selectMonth: '월 선택',\n      selectDate: '{0}',\n      currentDate: '오늘, {0}',\n    },\n  },\n  noDataText: '데이터가 없습니다.',\n  carousel: {\n    prev: '이전 화면',\n    next: '다음 화면',\n    ariaLabel: {\n      delimiter: '캐러셀 슬라이드 {0} / {1}',\n    },\n  },\n  calendar: {\n    moreEvents: '{0} 더보기',\n    today: '오늘',\n  },\n  input: {\n    clear: '{0} 지우기',\n    prependAction: '{0} 앞에 추가된 동작',\n    appendAction: '{0} 뒤에 추가된 동작',\n    otp: 'OTP 문자 {0}를 입력하세요',\n  },\n  fileInput: {\n    counter: '{0}개 파일',\n    counterSize: '{0}개 파일 (총 {1})',\n  },\n  fileUpload: {\n    title: '파일을 여기에 드래그 앤 드롭하세요',\n    divider: '또는',\n    browse: '파일 찾기',\n  },\n  timePicker: {\n    am: '오전',\n    pm: '오후',\n    title: '시간을 선택하세요',\n    hour: '시간',\n    minute: '분',\n    second: '초',\n    notAllowed: '값이 허용되지 않습니다',\n  },\n  pagination: {\n    ariaLabel: {\n      root: '페이지 탐색',\n      next: '다음 페이지',\n      previous: '이전 페이지',\n      page: '{0} 페이지로 이동',\n      currentPage: '현재 페이지, 페이지 {0}',\n      first: '첫 페이지',\n      last: '마지막 페이지',\n    },\n  },\n  stepper: {\n    next: '다음',\n    prev: '이전',\n  },\n  rating: {\n    ariaLabel: {\n      item: '{1} 중 {0} 점',\n    },\n  },\n  loading: '불러오는 중...',\n  infiniteScroll: {\n    loadMore: '더 불러오기',\n    empty: '더 이상 항목이 없습니다',\n  },\n  rules: {\n    required: '이 필드는 필수입니다',\n    email: '유효한 이메일을 입력해주세요',\n    number: '이 필드는 숫자만 포함할 수 있습니다',\n    integer: '이 필드는 정수만 포함할 수 있습니다',\n    capital: '이 필드는 대문자만 포함할 수 있습니다',\n    maxLength: '최대 {0}자를 입력해야 합니다',\n    minLength: '최소 {0}자를 입력해야 합니다',\n    strictLength: '입력한 필드의 길이가 유효하지 않습니다',\n    exclude: '{0} 문자는 허용되지 않습니다',\n    notEmpty: '최소 하나의 값을 선택해주세요',\n    pattern: '형식이 유효하지 않습니다',\n  },\n  command: {\n    search: '명령을 입력하거나 검색하세요...',\n  },\n  hotkey: {\n    then: '그 다음',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: '위쪽 화살표',\n    downArrow: '아래쪽 화살표',\n    leftArrow: '왼쪽 화살표',\n    rightArrow: '오른쪽 화살표',\n    backspace: '백스페이스',\n    space: '스페이스',\n    plus: '플러스',\n    shortcut: '키보드 단축키: {0}',\n    or: '또는',\n  },\n  video: {\n    play: '재생',\n    pause: '일시정지',\n    seek: '탐색',\n    volume: '볼륨',\n    showVolume: '볼륨 조절 표시',\n    mute: '음소거',\n    unmute: '음소거 해제',\n    enterFullscreen: '전체 화면',\n    exitFullscreen: '전체 화면 종료',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: '화면에서 색상 선택',\n      hueSlider: '색조',\n      alphaSlider: '투명도',\n      redInput: '빨강',\n      greenInput: '초록',\n      blueInput: '파랑',\n      alphaInput: '투명도',\n      hueInput: '색조',\n      saturationInput: '채도',\n      lightnessInput: '명도',\n      hexInput: 'HEX 값',\n      hexaInput: '알파 값이 있는 HEX',\n      changeFormat: '색상 형식 변경',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/lt.ts",
    "content": "export default {\n  badge: 'Ženklelis',\n  open: 'Atidaryti',\n  close: 'Uždaryti',\n  dismiss: 'Atmesti',\n  confirmEdit: {\n    ok: 'Gerai',\n    cancel: 'Atšaukti',\n  },\n  dataIterator: {\n    noResultsText: 'Nerasta atitinkančių įrašų',\n    loadingText: 'Kraunama...',\n  },\n  dataTable: {\n    itemsPerPageText: 'Eilutės per puslapį:',\n    ariaLabel: {\n      sortDescending: 'Išrikiuota mažėjimo tvarka.',\n      sortAscending: 'Išrikiuota didėjimo tvarka.',\n      sortNone: 'Nerikiuota.',\n      activateNone: 'Suaktyvinkite, jei norite rikiavimą pašalinti.',\n      activateDescending: 'Suaktyvinkite, jei norite rikiuoti mažėjimo tvarka.',\n      activateAscending: 'Suaktyvinkite, jei norite rikiuoti didėjimo tvarka.',\n    },\n    sortBy: 'Rikiuoti pagal',\n  },\n  dataFooter: {\n    itemsPerPageText: 'Įrašai per puslapį:',\n    itemsPerPageAll: 'Visi',\n    nextPage: 'Kitas puslapis',\n    prevPage: 'Ankstesnis puslapis',\n    firstPage: 'Pirmas puslapis',\n    lastPage: 'Paskutinis puslapis',\n    pageText: '{0}-{1} iš {2}',\n  },\n  dateRangeInput: {\n    divider: 'iki',\n  },\n  datePicker: {\n    itemsSelected: '{0} parinkta',\n    range: {\n      title: 'Pasirinkite datas',\n      header: 'Įveskite datas',\n    },\n    title: 'Pasirinkite datą',\n    header: 'Įveskite datą',\n    input: {\n      placeholder: 'Įveskite datą',\n    },\n    ariaLabel: {\n      previousMonth: 'Ankstesnis mėnuo',\n      nextMonth: 'Kitas mėnuo',\n      selectYear: 'Pasirinkite metus',\n      previousYear: 'Praėję metai',\n      nextYear: 'Kiti metai',\n      selectMonth: 'Pasirinkite mėnesį',\n      selectDate: '{0}',\n      currentDate: 'Šiandien, {0}',\n    },\n  },\n  noDataText: 'Nėra duomenų',\n  carousel: {\n    prev: 'Ankstesnioji skaidrė',\n    next: 'Kita skaidrė',\n    ariaLabel: {\n      delimiter: 'Skaidrė {0} iš {1}',\n    },\n  },\n  calendar: {\n    moreEvents: 'Daugiau {0}',\n    today: 'Šiandien',\n  },\n  input: {\n    clear: 'Išvalyti {0}',\n    prependAction: '{0} pridėtas veiksmas',\n    appendAction: '{0} pridėtas veiksmas',\n    otp: 'Prašome įvesti OTP simbolį {0}',\n  },\n  fileInput: {\n    counter: '{0} failų',\n    counterSize: '{0} failų ({1} iš viso)',\n  },\n  fileUpload: {\n    title: 'Vilkite ir numeskite failus čia',\n    divider: 'arba',\n    browse: 'Naršyti failus',\n  },\n  timePicker: {\n    am: 'AM',\n    pm: 'PM',\n    title: 'Pasirinkite laiką',\n    hour: 'Valanda',\n    minute: 'Minutės',\n    second: 'Sekundės',\n    notAllowed: 'Reikšmė neleidžiama',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'Puslapio naršymas',\n      next: 'Kitas puslapis',\n      previous: 'Ankstesnis puslapis',\n      page: 'Eiti į puslapį {0}',\n      currentPage: 'Dabartinis puslapis, puslapis {0}',\n      first: 'Pirmas puslapis',\n      last: 'Paskutinis puslapis',\n    },\n  },\n  stepper: {\n    next: 'Kitas',\n    prev: 'Ankstesnis',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'Įvertinimas {0} iš {1}',\n    },\n  },\n  loading: 'Kraunama...',\n  infiniteScroll: {\n    loadMore: 'Užkrauti daugiau',\n    empty: 'Daugiau nėra',\n  },\n  rules: {\n    required: 'Šis laukas yra privalomas',\n    email: 'Prašome įvesti galiojantį el. pašto adresą',\n    number: 'Šiame lauke gali būti tik skaičiai',\n    integer: 'Šiame lauke gali būti tik sveiki skaičiai',\n    capital: 'Šiame lauke gali būti tik didžiosios raidės',\n    maxLength: 'Turite įvesti ne daugiau kaip {0} simbolių',\n    minLength: 'Turite įvesti bent {0} simbolius',\n    strictLength: 'Įvesto lauko ilgis yra neteisingas',\n    exclude: 'Simbolis {0} nėra leidžiamas',\n    notEmpty: 'Prašome pasirinkti bent vieną reikšmę',\n    pattern: 'Neteisingas formatas',\n  },\n  command: {\n    search: 'Įveskite komandą arba ieškokite...',\n  },\n  hotkey: {\n    then: 'tada',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: 'Rodyklė į viršų',\n    downArrow: 'Rodyklė žemyn',\n    leftArrow: 'Rodyklė kairėn',\n    rightArrow: 'Rodyklė dešinėn',\n    backspace: 'Backspace',\n    space: 'Tarpas',\n    plus: 'plius',\n    shortcut: 'Klaviatūros trumpinys: {0}',\n    or: 'arba',\n  },\n  video: {\n    play: 'Groti',\n    pause: 'Pauzė',\n    seek: 'Ieškoti',\n    volume: 'Garsumas',\n    showVolume: 'Rodyti garso valdymą',\n    mute: 'Nutildyti',\n    unmute: 'Įjungti garsą',\n    enterFullscreen: 'Visas ekranas',\n    exitFullscreen: 'Išeiti iš viso ekrano',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'Pasirinkite spalvą iš ekrano',\n      hueSlider: 'Atspalvis',\n      alphaSlider: 'Skaidrumas',\n      redInput: 'Raudona',\n      greenInput: 'Žalia',\n      blueInput: 'Mėlyna',\n      alphaInput: 'Skaidrumas',\n      hueInput: 'Atspalvis',\n      saturationInput: 'Sodrumas',\n      lightnessInput: 'Šviesumas',\n      hexInput: 'HEX reikšmė',\n      hexaInput: 'HEX su skaidrumo reikšme',\n      changeFormat: 'Keisti spalvos formatą',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/lv.ts",
    "content": "export default {\n  badge: 'Žetons',\n  open: 'Atvērt',\n  close: 'Aizvērt',\n  dismiss: 'Noraidīt',\n  confirmEdit: {\n    ok: 'Labi',\n    cancel: 'Atcelt',\n  },\n  dataIterator: {\n    noResultsText: 'Nekas netika atrasts',\n    loadingText: 'Ielādē...',\n  },\n  dataTable: {\n    itemsPerPageText: 'Rādīt lapā:',\n    ariaLabel: {\n      sortDescending: 'Sakārtots dilstošā secībā.',\n      sortAscending: 'Sakārtots augošā secībā.',\n      sortNone: 'Nav sakārtots.',\n      activateNone: 'Aktivizēt, lai noņemtu kārtošanu.',\n      activateDescending: 'Aktivizēt, lai sakārtotu dilstošā secībā.',\n      activateAscending: 'Aktivizēt, lai sakārtotu augošā secībā.',\n    },\n    sortBy: 'Kārtot pēc',\n  },\n  dataFooter: {\n    itemsPerPageText: 'Rādīt lapā:',\n    itemsPerPageAll: 'Visu',\n    nextPage: 'Nākamā lapa',\n    prevPage: 'Iepriekšējā lapa',\n    firstPage: 'Pirmā lapa',\n    lastPage: 'Pēdējā lapa',\n    pageText: '{0}-{1} no {2}',\n  },\n  dateRangeInput: {\n    divider: 'līdz',\n  },\n  datePicker: {\n    itemsSelected: '{0} izvēlēts',\n    range: {\n      title: 'Izvēlieties datumus',\n      header: 'Ievadiet datumus',\n    },\n    title: 'Izvēlieties datumu',\n    header: 'Ievadiet datumu',\n    input: {\n      placeholder: 'Ievadiet datumu',\n    },\n    ariaLabel: {\n      previousMonth: 'Iepriekšējais mēnesis',\n      nextMonth: 'Nākamais mēnesis',\n      selectYear: 'Izvēlieties gadu',\n      previousYear: 'Iepriekšējais gads',\n      nextYear: 'Nākamais gads',\n      selectMonth: 'Izvēlieties mēnesi',\n      selectDate: '{0}',\n      currentDate: 'Šodien, {0}',\n    },\n  },\n  noDataText: 'Nav pieejamu datu',\n  carousel: {\n    prev: 'Iepriekšējais slaids',\n    next: 'Nākamais slaids',\n    ariaLabel: {\n      delimiter: 'Karuseļa slaids {0} no {1}',\n    },\n  },\n  calendar: {\n    moreEvents: 'Vēl {0}',\n    today: 'Šodien',\n  },\n  input: {\n    clear: 'Notīrīt {0}',\n    prependAction: '{0} pievienota darbība sākumā',\n    appendAction: '{0} pievienota darbība beigās',\n    otp: 'Lūdzu, ievadiet OTP simbolu {0}',\n  },\n  fileInput: {\n    counter: '{0} faili',\n    counterSize: '{0} faili (kopā {1})',\n  },\n  fileUpload: {\n    title: 'Velciet un nometiet failus šeit',\n    divider: 'vai',\n    browse: 'Pārlūkot failus',\n  },\n  timePicker: {\n    am: 'AM',\n    pm: 'PM',\n    title: 'Izvēlieties laiku',\n    hour: 'Stunda',\n    minute: 'Minūtes',\n    second: 'Sekundes',\n    notAllowed: 'Vērtība nav atļauta',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'Navigācija lapošanā',\n      next: 'Nākamā lapa',\n      previous: 'Iepriekšējā lapa',\n      page: 'Iet uz lapu {0}',\n      currentPage: 'Pašreizējā lapa, lapa {0}',\n      first: 'Pirmā lapa',\n      last: 'Pēdējā lapa',\n    },\n  },\n  stepper: {\n    next: 'Nākamais',\n    prev: 'Iepriekšējais',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'Vērtējums {0} no {1}',\n    },\n  },\n  loading: 'Ielādē...',\n  infiniteScroll: {\n    loadMore: 'Ielādēt vairāk',\n    empty: 'Nav vairāk vienumu',\n  },\n  rules: {\n    required: 'Šis lauks ir obligāts',\n    email: 'Lūdzu, ievadiet derīgu e-pasta adresi',\n    number: 'Šis lauks var saturēt tikai ciparus',\n    integer: 'Šis lauks var saturēt tikai veselus skaitļus',\n    capital: 'Šis lauks var saturēt tikai lielos burtus',\n    maxLength: 'Jums jāievada maksimāli {0} rakstzīmes',\n    minLength: 'Jums jāievada vismaz {0} rakstzīmes',\n    strictLength: 'Ievadītā lauka garums nav derīgs',\n    exclude: 'Rakstzīme {0} nav atļauta',\n    notEmpty: 'Lūdzu, izvēlieties vismaz vienu vērtību',\n    pattern: 'Nederīgs formāts',\n  },\n  command: {\n    search: 'Ierakstiet komandu vai meklējiet...',\n  },\n  hotkey: {\n    then: 'tad',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: 'Augšup bulta',\n    downArrow: 'Lejup bulta',\n    leftArrow: 'Kreisā bulta',\n    rightArrow: 'Labā bulta',\n    backspace: 'Atpakaļatkāpe',\n    space: 'Atstarpe',\n    plus: 'plus',\n    shortcut: 'Tastatūras saīsne: {0}',\n    or: 'vai',\n  },\n  video: {\n    play: 'Atskaņot',\n    pause: 'Pauzēt',\n    seek: 'Meklēt',\n    volume: 'Skaļums',\n    showVolume: 'Rādīt skaļuma kontroli',\n    mute: 'Izslēgt skaņu',\n    unmute: 'Ieslēgt skaņu',\n    enterFullscreen: 'Pilnekrāna režīms',\n    exitFullscreen: 'Iziet no pilnekrāna režīma',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'Izvēlēties krāsu no ekrāna',\n      hueSlider: 'Tonis',\n      alphaSlider: 'Caurspīdīgums',\n      redInput: 'Sarkans',\n      greenInput: 'Zaļš',\n      blueInput: 'Zils',\n      alphaInput: 'Caurspīdīgums',\n      hueInput: 'Tonis',\n      saturationInput: 'Piesātinājums',\n      lightnessInput: 'Gaišums',\n      hexInput: 'HEX vērtība',\n      hexaInput: 'HEX ar caurspīdīguma vērtību',\n      changeFormat: 'Mainīt krāsas formātu',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/nl.ts",
    "content": "export default {\n  badge: 'Insigne',\n  open: 'Openen',\n  close: 'Sluiten',\n  dismiss: 'Negeren',\n  confirmEdit: {\n    ok: 'OK',\n    cancel: 'Annuleren',\n  },\n  dataIterator: {\n    noResultsText: 'Geen overeenkomende resultaten gevonden',\n    loadingText: 'Bezig met laden...',\n  },\n  dataTable: {\n    itemsPerPageText: 'Rijen per pagina:',\n    ariaLabel: {\n      sortDescending: 'Aflopend gesorteerd.',\n      sortAscending: 'Oplopend gesorteerd.',\n      sortNone: 'Niet gesorteerd.',\n      activateNone: 'Activeer om de sortering te verwijderen.',\n      activateDescending: 'Activeer om aflopend te sorteren.',\n      activateAscending: 'Activeer om oplopend te sorteren.',\n    },\n    sortBy: 'Sorteer op',\n  },\n  dataFooter: {\n    itemsPerPageText: 'Aantal per pagina:',\n    itemsPerPageAll: 'Alles',\n    nextPage: 'Volgende pagina',\n    prevPage: 'Vorige pagina',\n    firstPage: 'Eerste pagina',\n    lastPage: 'Laatste pagina',\n    pageText: '{0}-{1} van {2}',\n  },\n  dateRangeInput: {\n    divider: 'tot',\n  },\n  datePicker: {\n    itemsSelected: '{0} geselecteerd',\n    range: {\n      title: 'Selecteer datums',\n      header: 'Voer datums in',\n    },\n    title: 'Selecteer datum',\n    header: 'Voer datum in',\n    input: {\n      placeholder: 'Voer datum in',\n    },\n    ariaLabel: {\n      previousMonth: 'Vorige maand',\n      nextMonth: 'Volgende maand',\n      selectYear: 'Selecteer jaar',\n      previousYear: 'Vorig jaar',\n      nextYear: 'Volgend jaar',\n      selectMonth: 'Selecteer maand',\n      selectDate: '{0}',\n      currentDate: 'Vandaag, {0}',\n    },\n  },\n  noDataText: 'Geen gegevens beschikbaar',\n  carousel: {\n    prev: 'Vorige weergave',\n    next: 'Volgende weergave',\n    ariaLabel: {\n      delimiter: 'Carrousel afbeelding {0} van {1}',\n    },\n  },\n  calendar: {\n    moreEvents: '{0} meer',\n    today: 'Vandaag',\n  },\n  input: {\n    clear: 'Maak {0} leeg',\n    prependAction: '{0} voorafgaande actie',\n    appendAction: '{0} bijgevoegde actie',\n    otp: 'Voer OTP-teken {0} in',\n  },\n  fileInput: {\n    counter: '{0} bestanden',\n    counterSize: '{0} bestanden ({1} in totaal)',\n  },\n  fileUpload: {\n    title: 'Sleep en zet bestanden hier neer',\n    divider: 'of',\n    browse: 'Blader door bestanden',\n  },\n  timePicker: {\n    am: 'AM',\n    pm: 'PM',\n    title: 'Selecteer tijd',\n    hour: 'Uur',\n    minute: 'Minuten',\n    second: 'Seconden',\n    notAllowed: 'Waarde is niet toegestaan',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'Pagina navigatie',\n      next: 'Volgende pagina',\n      previous: 'Vorige pagina',\n      page: 'Ga naar pagina {0}',\n      currentPage: 'Huidige pagina, pagina {0}',\n      first: 'Eerste pagina',\n      last: 'Laatste pagina',\n    },\n  },\n  stepper: {\n    next: 'Volgende',\n    prev: 'Vorige',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'Beoordeling {0} van {1}',\n    },\n  },\n  loading: 'Bezig met laden...',\n  infiniteScroll: {\n    loadMore: 'Meer laden',\n    empty: 'Geen meer items',\n  },\n  rules: {\n    required: 'Dit veld is verplicht',\n    email: 'Voer een geldig e-mailadres in',\n    number: 'Dit veld mag alleen nummers bevatten',\n    integer: 'Dit veld mag alleen gehele getallen bevatten',\n    capital: 'Dit veld mag alleen hoofdletters bevatten',\n    maxLength: 'Je mag maximaal {0} tekens invoeren',\n    minLength: 'Je moet minimaal {0} tekens invoeren',\n    strictLength: 'De lengte van het ingevoerde veld is ongeldig',\n    exclude: 'Het teken {0} is niet toegestaan',\n    notEmpty: 'Kies ten minste één waarde',\n    pattern: 'Ongeldig formaat',\n  },\n  command: {\n    search: 'Typ een opdracht of zoek...',\n  },\n  hotkey: {\n    then: 'dan',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: 'Pijl omhoog',\n    downArrow: 'Pijl omlaag',\n    leftArrow: 'Pijl naar links',\n    rightArrow: 'Pijl naar rechts',\n    backspace: 'Backspace',\n    space: 'Spatie',\n    plus: 'plus',\n    shortcut: 'Toetsenbordsnelkoppeling: {0}',\n    or: 'of',\n  },\n  video: {\n    play: 'Afspelen',\n    pause: 'Pauzeren',\n    seek: 'Zoeken',\n    volume: 'Volume',\n    showVolume: 'Volumeregeling weergeven',\n    mute: 'Dempen',\n    unmute: 'Dempen opheffen',\n    enterFullscreen: 'Volledig scherm',\n    exitFullscreen: 'Volledig scherm verlaten',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'Kies een kleur van het scherm',\n      hueSlider: 'Tint',\n      alphaSlider: 'Alpha',\n      redInput: 'Rood',\n      greenInput: 'Groen',\n      blueInput: 'Blauw',\n      alphaInput: 'Alpha',\n      hueInput: 'Tint',\n      saturationInput: 'Verzadiging',\n      lightnessInput: 'Helderheid',\n      hexInput: 'HEX-waarde',\n      hexaInput: 'HEX met alpha-waarde',\n      changeFormat: 'Wijzig kleurformaat',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/no.ts",
    "content": "export default {\n  badge: 'Skilt',\n  open: 'Åpne',\n  close: 'Lukk',\n  dismiss: 'Avvis',\n  confirmEdit: {\n    ok: 'OK',\n    cancel: 'Avbryt',\n  },\n  dataIterator: {\n    noResultsText: 'Fant ingen matchende elementer.',\n    loadingText: 'Laster...',\n  },\n  dataTable: {\n    itemsPerPageText: 'Rader per side:',\n    ariaLabel: {\n      sortDescending: 'Sortert synkende.',\n      sortAscending: 'Sortert stigende.',\n      sortNone: 'Ikke sortert.',\n      activateNone: 'Aktiver for å fjerne sortering.',\n      activateDescending: 'Aktiver for å sortere synkende.',\n      activateAscending: 'Aktiver for å sortere stigende.',\n    },\n    sortBy: 'Sorter etter',\n  },\n  dataFooter: {\n    itemsPerPageText: 'Elementer per side:',\n    itemsPerPageAll: 'Alle',\n    nextPage: 'Neste side',\n    prevPage: 'Forrige side',\n    firstPage: 'Første side',\n    lastPage: 'Siste side',\n    pageText: '{0}-{1} av {2}',\n  },\n  dateRangeInput: {\n    divider: 'til',\n  },\n  datePicker: {\n    itemsSelected: '{0} valgt',\n    range: {\n      title: 'Velg datoer',\n      header: 'Velg datoer',\n    },\n    title: 'Velg dato',\n    header: 'Velg dato',\n    input: {\n      placeholder: 'Fyll inn dato',\n    },\n    ariaLabel: {\n      previousMonth: 'Forrige måned',\n      nextMonth: 'Neste måned',\n      selectYear: 'Velg år',\n      previousYear: 'Forrige år',\n      nextYear: 'Neste år',\n      selectMonth: 'Velg måned',\n      selectDate: '{0}',\n      currentDate: 'I dag, {0}',\n    },\n  },\n  noDataText: 'Ingen data er tilgjengelig',\n  carousel: {\n    prev: 'Forrige bilde',\n    next: 'Neste bilde',\n    ariaLabel: {\n      delimiter: 'Karusellbilde {0} av {1}',\n    },\n  },\n  calendar: {\n    moreEvents: '{0} flere',\n    today: 'I dag',\n  },\n  input: {\n    clear: 'Fjern {0}',\n    prependAction: '{0} foranstilt handling',\n    appendAction: '{0} etterstilt handling',\n    otp: 'Vennligst skriv inn OTP-tegn {0}',\n  },\n  fileInput: {\n    counter: '{0} filer',\n    counterSize: '{0} filer ({1} totalt)',\n  },\n  fileUpload: {\n    title: 'Dra og slipp filer her',\n    divider: 'eller',\n    browse: 'Bla gjennom filer',\n  },\n  timePicker: {\n    am: 'AM',\n    pm: 'PM',\n    title: 'Velg tid',\n    hour: 'Time',\n    minute: 'Minutter',\n    second: 'Sekunder',\n    notAllowed: 'Verdien er ikke tillatt',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'Paginasjonsnavigasjon',\n      next: 'Neste side',\n      previous: 'Forrige side',\n      page: 'Gå til side {0}',\n      currentPage: 'Gjeldende side, side {0}',\n      first: 'Første side',\n      last: 'Siste side',\n    },\n  },\n  stepper: {\n    next: 'Neste',\n    prev: 'Forrige',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'Anmeldelse {0} av {1}',\n    },\n  },\n  loading: 'Laster...',\n  infiniteScroll: {\n    loadMore: 'Last flere',\n    empty: 'Det var alt',\n  },\n  rules: {\n    required: 'Dette feltet er påkrevd',\n    email: 'Vennligst skriv inn en gyldig e-postadresse',\n    number: 'Dette feltet kan kun inneholde tall',\n    integer: 'Dette feltet kan kun inneholde heltall',\n    capital: 'Dette feltet kan kun inneholde store bokstaver',\n    maxLength: 'Du må skrive inn maksimalt {0} tegn',\n    minLength: 'Du må skrive inn minimum {0} tegn',\n    strictLength: 'Lengden på det angitte feltet er ugyldig',\n    exclude: 'Tegnet {0} er ikke tillatt',\n    notEmpty: 'Vennligst velg minst én verdi',\n    pattern: 'Ugyldig format',\n  },\n  command: {\n    search: 'Skriv en kommando eller søk...',\n  },\n  hotkey: {\n    then: 'deretter',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: 'Pil opp',\n    downArrow: 'Pil ned',\n    leftArrow: 'Pil venstre',\n    rightArrow: 'Pil høyre',\n    backspace: 'Slett',\n    space: 'Mellomrom',\n    plus: 'pluss',\n    shortcut: 'Tastatursnarveier: {0}',\n    or: 'eller',\n  },\n  video: {\n    play: 'Spill av',\n    pause: 'Pause',\n    seek: 'Søk',\n    volume: 'Volum',\n    showVolume: 'Vis volumkontroll',\n    mute: ' Demp',\n    unmute: 'Slå på lyd',\n    enterFullscreen: 'Fullskjerm',\n    exitFullscreen: 'Avslutt fullskjerm',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'Velg farge fra skjermen',\n      hueSlider: 'Fargetone',\n      alphaSlider: 'Alfa',\n      redInput: 'Rød',\n      greenInput: 'Grønn',\n      blueInput: 'Blå',\n      alphaInput: 'Alfa',\n      hueInput: 'Fargetone',\n      saturationInput: 'Metning',\n      lightnessInput: 'Lyshet',\n      hexInput: 'HEX-verdi',\n      hexaInput: 'HEX med alfa-verdi',\n      changeFormat: 'Endre fargeformat',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/pl.ts",
    "content": "export default {\n  badge: 'Odznaka',\n  open: 'Otwórz',\n  close: 'Zamknij',\n  dismiss: 'Odrzuć',\n  confirmEdit: {\n    ok: 'OK',\n    cancel: 'Anuluj',\n  },\n  dataIterator: {\n    noResultsText: 'Nie znaleziono danych odpowiadających wyszukiwaniu',\n    loadingText: 'Wczytywanie danych...',\n  },\n  dataTable: {\n    itemsPerPageText: 'Wierszy na stronie:',\n    ariaLabel: {\n      sortDescending: 'Sortowanie malejąco. Kliknij aby zmienić.',\n      sortAscending: 'Sortowanie rosnąco. Kliknij aby zmienić.',\n      sortNone: 'Bez sortowania. Kliknij aby posortować rosnąco.',\n      activateNone: 'Kliknij aby usunąć sortowanie.',\n      activateDescending: 'Kliknij aby posortować malejąco.',\n      activateAscending: 'Kliknij aby posortować rosnąco.',\n    },\n    sortBy: 'Sortuj według',\n  },\n  dataFooter: {\n    itemsPerPageText: 'Pozycji na stronie:',\n    itemsPerPageAll: 'Wszystkie',\n    nextPage: 'Następna strona',\n    prevPage: 'Poprzednia strona',\n    firstPage: 'Pierwsza strona',\n    lastPage: 'Ostatnia strona',\n    pageText: '{0}-{1} z {2}',\n  },\n  dateRangeInput: {\n    divider: 'do',\n  },\n  datePicker: {\n    itemsSelected: '{0} wybrano',\n    range: {\n      title: 'Wybór zakresu dat',\n      header: 'Wprowadź zakres dat',\n    },\n    title: 'Wybór daty',\n    header: 'Wprowadź datę',\n    input: {\n      placeholder: 'Wprowadź datę',\n    },\n    ariaLabel: {\n      previousMonth: 'Poprzedni miesiąc',\n      nextMonth: 'Następny miesiąc',\n      selectYear: 'Wybierz rok',\n      previousYear: 'Poprzedni rok',\n      nextYear: 'Następny rok',\n      selectMonth: 'Wybierz miesiąc',\n      selectDate: '{0}',\n      currentDate: 'Dzisiaj, {0}',\n    },\n  },\n  noDataText: 'Brak danych',\n  carousel: {\n    prev: 'Poprzedni obraz',\n    next: 'Następny obraz',\n    ariaLabel: {\n      delimiter: 'Obraz {0} z {1}',\n    },\n  },\n  calendar: {\n    moreEvents: '{0} więcej',\n    today: 'Dzisiaj',\n  },\n  input: {\n    clear: 'Wyczyść {0}',\n    prependAction: '{0} dodatkowa akcja',\n    appendAction: '{0} dodatkowa akcja',\n    otp: 'Proszę wprowadzić znak nr {0}',\n  },\n  fileInput: {\n    counter: 'Liczba plików: {0}',\n    counterSize: 'Liczba plików: {0} (łącznie {1})',\n  },\n  fileUpload: {\n    title: 'Przeciągnij i upuść pliki tutaj',\n    divider: 'lub',\n    browse: 'Przeglądaj pliki',\n  },\n  timePicker: {\n    am: 'AM',\n    pm: 'PM',\n    title: 'Wybierz godzinę',\n    hour: 'Godzina',\n    minute: 'Minuty',\n    second: 'Sekudy',\n    notAllowed: 'Wartość jest niedozwolona',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'Nawigacja paginacyjna',\n      next: 'Następna strona',\n      previous: 'Poprzednia strona',\n      page: 'Idź do strony {0}',\n      currentPage: 'Bieżąca strona, strona {0}',\n      first: 'Pierwsza strona',\n      last: 'Ostatnia strona',\n    },\n  },\n  stepper: {\n    next: 'Następny',\n    prev: 'Poprzedni',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'Ocena {0} na {1}',\n    },\n  },\n  loading: 'Wczytywanie danych...',\n  infiniteScroll: {\n    loadMore: 'Wczytaj więcej',\n    empty: 'Brak kolejnych danych',\n  },\n  rules: {\n    required: 'To pole jest wymagane',\n    email: 'Proszę podać prawidłowy adres e-mail',\n    number: 'To pole może zawierać tylko cyfry',\n    integer: 'To pole może zawierać tylko liczby całkowite',\n    capital: 'To pole może zawierać tylko wielkie litery',\n    maxLength: 'Musisz wprowadzić maksymalnie {0} znaków',\n    minLength: 'Musisz wprowadzić co najmniej {0} znaków',\n    strictLength: 'Długość wprowadzonego pola jest nieprawidłowa',\n    exclude: 'Znak {0} nie jest dozwolony',\n    notEmpty: 'Proszę wybrać co najmniej jedną wartość',\n    pattern: 'Nieprawidłowy format',\n  },\n  command: {\n    search: 'Wpisz polecenie lub szukaj...',\n  },\n  hotkey: {\n    then: 'następnie',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: 'Strzałka w górę',\n    downArrow: 'Strzałka w dół',\n    leftArrow: 'Strzałka w lewo',\n    rightArrow: 'Strzałka w prawo',\n    backspace: 'Backspace',\n    space: 'Spacja',\n    plus: 'plus',\n    shortcut: 'Skrót klawiszowy: {0}',\n    or: 'lub',\n  },\n  video: {\n    play: 'Odtwórz',\n    pause: 'Wstrzymaj',\n    seek: 'Przewiń',\n    volume: 'Głośność',\n    showVolume: 'Pokaż regulację głośności',\n    mute: 'Wycisz',\n    unmute: 'Wyłącz wyciszenie',\n    enterFullscreen: 'Pełny ekran',\n    exitFullscreen: 'Opuść pełny ekran',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'Pobierz kolor z ekranu',\n      hueSlider: 'Odcień',\n      alphaSlider: 'Przezroczystość',\n      redInput: 'Czerwony',\n      greenInput: 'Zielony',\n      blueInput: 'Niebieski',\n      alphaInput: 'Przezroczystość',\n      hueInput: 'Odcień',\n      saturationInput: 'Nasycenie',\n      lightnessInput: 'Jasność',\n      hexInput: 'Wartość szesnastkowa',\n      hexaInput: 'Wartość szesnastkowa z kanałem alfa',\n      changeFormat: 'Zmień format koloru',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/pt.ts",
    "content": "export default {\n  badge: 'Distintivo',\n  open: 'Abrir',\n  close: 'Fechar',\n  dismiss: 'Dispensar',\n  confirmEdit: {\n    ok: 'OK',\n    cancel: 'Cancelar',\n  },\n  dataIterator: {\n    noResultsText: 'Nenhum dado encontrado',\n    loadingText: 'Carregando itens...',\n  },\n  dataTable: {\n    itemsPerPageText: 'Linhas por página:',\n    ariaLabel: {\n      sortDescending: 'Ordenado decrescente.',\n      sortAscending: 'Ordenado crescente.',\n      sortNone: 'Não ordenado.',\n      activateNone: 'Ative para remover a ordenação.',\n      activateDescending: 'Ative para ordenar decrescente.',\n      activateAscending: 'Ative para ordenar crescente.',\n    },\n    sortBy: 'Ordenar por',\n  },\n  dataFooter: {\n    itemsPerPageText: 'Itens por página:',\n    itemsPerPageAll: 'Todos',\n    nextPage: 'Próxima página',\n    prevPage: 'Página anterior',\n    firstPage: 'Primeira página',\n    lastPage: 'Última página',\n    pageText: '{0}-{1} de {2}',\n  },\n  dateRangeInput: {\n    divider: 'até',\n  },\n  datePicker: {\n    itemsSelected: '{0} selecionados',\n    range: {\n      title: 'Selecione as datas',\n      header: 'Digite as datas',\n    },\n    title: 'Selecione a data',\n    header: 'Digite a data',\n    input: {\n      placeholder: 'Insira a data',\n    },\n    ariaLabel: {\n      previousMonth: 'Mês anterior',\n      nextMonth: 'Próximo mês',\n      selectYear: 'Selecionar ano',\n      previousYear: 'Ano anterior',\n      nextYear: 'Próximo ano',\n      selectMonth: 'Selecionar mês',\n      selectDate: '{0}',\n      currentDate: 'Hoje, {0}',\n    },\n  },\n  noDataText: 'Não há dados disponíveis',\n  carousel: {\n    prev: 'Visão anterior',\n    next: 'Próxima visão',\n    ariaLabel: {\n      delimiter: 'Slide {0} de {1} do carrossel',\n    },\n  },\n  calendar: {\n    moreEvents: 'Mais {0}',\n    today: 'Hoje',\n  },\n  input: {\n    clear: 'Limpar {0}',\n    prependAction: '{0} ação antes',\n    appendAction: '{0} ação depois',\n    otp: 'Por favor, insira o caractere OTP {0}',\n  },\n  fileInput: {\n    counter: '{0} arquivo(s)',\n    counterSize: '{0} arquivo(s) ({1} no total)',\n  },\n  fileUpload: {\n    title: 'Arraste e solte os arquivos aqui',\n    divider: 'ou',\n    browse: 'Procurar arquivos',\n  },\n  timePicker: {\n    am: 'AM',\n    pm: 'PM',\n    title: 'Selecione o horário',\n    hour: 'Hora',\n    minute: 'Minuto',\n    second: 'Segundos',\n    notAllowed: 'O valor não é permitido',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'Navegação de paginação',\n      next: 'Próxima página',\n      previous: 'Página anterior',\n      page: 'Ir à página {0}',\n      currentPage: 'Página atual, página {0}',\n      first: 'Primeira página',\n      last: 'Última página',\n    },\n  },\n  stepper: {\n    next: 'Próximo',\n    prev: 'Anterior',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'Avaliação {0} de {1}',\n    },\n  },\n  loading: 'Carregando...',\n  infiniteScroll: {\n    loadMore: 'Carregar mais',\n    empty: 'Não há mais dados',\n  },\n  rules: {\n    required: 'Este campo é obrigatório',\n    email: 'Por favor, insira um e-mail válido',\n    number: 'Este campo só pode conter números',\n    integer: 'Este campo só pode conter valores inteiros',\n    capital: 'Este campo só pode conter letras maiúsculas',\n    maxLength: 'Você deve inserir no máximo {0} caracteres',\n    minLength: 'Você deve inserir no mínimo {0} caracteres',\n    strictLength: 'O comprimento do campo inserido é inválido',\n    exclude: 'O caractere {0} não é permitido',\n    notEmpty: 'Por favor, escolha pelo menos um valor',\n    pattern: 'Formato inválido',\n  },\n  command: {\n    search: 'Digite um comando ou pesquise...',\n  },\n  hotkey: {\n    then: 'então',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: 'Seta para cima',\n    downArrow: 'Seta para baixo',\n    leftArrow: 'Seta para a esquerda',\n    rightArrow: 'Seta para a direita',\n    backspace: 'Backspace',\n    space: 'Espaço',\n    plus: 'mais',\n    shortcut: 'Atalho de teclado: {0}',\n    or: 'ou',\n  },\n  video: {\n    play: 'Reproduzir',\n    pause: 'Pausar',\n    seek: 'Buscar',\n    volume: 'Volume',\n    showVolume: 'Mostrar controle de volume',\n    mute: 'Silenciar',\n    unmute: 'Ativar som',\n    enterFullscreen: 'Tela cheia',\n    exitFullscreen: 'Sair da tela cheia',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'Selecionar cor da tela',\n      hueSlider: 'Matiz',\n      alphaSlider: 'Alfa',\n      redInput: 'Vermelho',\n      greenInput: 'Verde',\n      blueInput: 'Azul',\n      alphaInput: 'Alfa',\n      hueInput: 'Matiz',\n      saturationInput: 'Saturação',\n      lightnessInput: 'Luminosidade',\n      hexInput: 'Valor HEX',\n      hexaInput: 'HEX com valor alfa',\n      changeFormat: 'Alterar formato da cor',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/ro.ts",
    "content": "export default {\n  badge: 'Insignă',\n  open: 'Open',\n  close: 'Închideți',\n  dismiss: 'Dismiss',\n  confirmEdit: {\n    ok: 'OK',\n    cancel: 'Anulează',\n  },\n  dataIterator: {\n    noResultsText: 'Nu s-au găsit înregistrări corespunzătoare',\n    loadingText: 'Se încarcă articolele...',\n  },\n  dataTable: {\n    itemsPerPageText: 'Rânduri pe pagină:',\n    ariaLabel: {\n      sortDescending: 'Sortate descendent.',\n      sortAscending: 'Sortate ascendent.',\n      sortNone: 'Nesortate.',\n      activateNone: 'Activați pentru a elimina sortarea.',\n      activateDescending: 'Activați pentru a sorta descendent.',\n      activateAscending: 'Activați pentru a sorta ascendent.',\n    },\n    sortBy: 'Sortați după',\n  },\n  dataFooter: {\n    itemsPerPageText: 'Articole pe pagină:',\n    itemsPerPageAll: 'Toate',\n    nextPage: 'Pagina următoare',\n    prevPage: 'Pagina anterioară',\n    firstPage: 'Prima pagină',\n    lastPage: 'Ultima pagină',\n    pageText: '{0}-{1} din {2}',\n  },\n  dateRangeInput: {\n    divider: 'până la',\n  },\n  datePicker: {\n    itemsSelected: '{0} selectate',\n    range: {\n      title: 'Selectați datele',\n      header: 'Introduceți datele',\n    },\n    title: 'Selectați data',\n    header: 'Introduceți data',\n    input: {\n      placeholder: 'Introduceți data',\n    },\n    ariaLabel: {\n      previousMonth: 'Luna anterioară',\n      nextMonth: 'Luna următoare',\n      selectYear: 'Selectați anul',\n      previousYear: 'Anul precedent',\n      nextYear: 'Anul următor',\n      selectMonth: 'Selectați luna',\n      selectDate: '{0}',\n      currentDate: 'Astăzi, {0}',\n    },\n  },\n  noDataText: 'Nu există date disponibile',\n  carousel: {\n    prev: 'Vizualul anterior',\n    next: 'Vizualul următor',\n    ariaLabel: {\n      delimiter: 'Slide carusel {0} din {1}',\n    },\n  },\n  calendar: {\n    moreEvents: 'încă {0}',\n    today: 'Today',\n  },\n  input: {\n    clear: 'Șterge {0}',\n    prependAction: '{0} acțiune de inserare la început',\n    appendAction: '{0} acțiune de inserare la sfârșit',\n    otp: 'Introduceți caracterul OTP {0}',\n  },\n  fileInput: {\n    counter: '{0} fișiere',\n    counterSize: '{0} fișiere ({1} în total)',\n  },\n  fileUpload: {\n    title: 'Trageți și plasați fișierele aici',\n    divider: 'sau',\n    browse: 'Răsfoiți fișiere',\n  },\n  timePicker: {\n    am: 'AM',\n    pm: 'PM',\n    title: 'Selectați ora',\n    hour: 'Oră',\n    minute: 'Minute',\n    second: 'Secunde',\n    notAllowed: 'Valoarea nu este permisă',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'Navigare prin pagini',\n      next: 'Pagina următoare',\n      previous: 'Pagina anterioară',\n      page: 'Mergeți la pagina {0}',\n      currentPage: 'Pagina curentă, pagina {0}',\n      first: 'Prima pagină',\n      last: 'Ultima pagină',\n    },\n  },\n  stepper: {\n    next: 'Următor',\n    prev: 'Înapoi',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'Evaluare {0} din {1}',\n    },\n  },\n  loading: 'Se încarcă...',\n  infiniteScroll: {\n    loadMore: 'Încarcă mai multe',\n    empty: 'Nu mai există',\n  },\n  rules: {\n    required: 'Acest câmp este obligatoriu',\n    email: 'Vă rugăm să introduceți o adresă de email validă',\n    number: 'Acest câmp poate conține doar numere',\n    integer: 'Acest câmp poate conține doar valori întregi',\n    capital: 'Acest câmp poate conține doar litere mari',\n    maxLength: 'Trebuie să introduceți maximum {0} caractere',\n    minLength: 'Trebuie să introduceți minimum {0} caractere',\n    strictLength: 'Lungimea câmpului introdus este invalidă',\n    exclude: 'Caracterele {0} nu sunt permise',\n    notEmpty: 'Vă rugăm să alegeți cel puțin o valoare',\n    pattern: 'Format invalid',\n  },\n  command: {\n    search: 'Tastați o comandă sau căutați...',\n  },\n  hotkey: {\n    then: 'apoi',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: 'Săgeată sus',\n    downArrow: 'Săgeată jos',\n    leftArrow: 'Săgeată stânga',\n    rightArrow: 'Săgeată dreapta',\n    backspace: 'Backspace',\n    space: 'Spațiu',\n    plus: 'plus',\n    shortcut: 'Comandă rapidă tastatură: {0}',\n    or: 'sau',\n  },\n  video: {\n    play: 'Redare',\n    pause: 'Pauză',\n    seek: 'Căutare',\n    volume: 'Volum',\n    showVolume: 'Afișare control volum',\n    mute: 'Fără sunet',\n    unmute: 'Cu sunet',\n    enterFullscreen: 'Ecran complet',\n    exitFullscreen: 'Ieșire din ecran complet',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'Alege culoarea de pe ecran',\n      hueSlider: 'Nuanță',\n      alphaSlider: 'Alfa',\n      redInput: 'Roșu',\n      greenInput: 'Verde',\n      blueInput: 'Albastru',\n      alphaInput: 'Alfa',\n      hueInput: 'Nuanță',\n      saturationInput: 'Saturație',\n      lightnessInput: 'Luminozitate',\n      hexInput: 'Valoare HEX',\n      hexaInput: 'Valoare HEX cu alfa',\n      changeFormat: 'Schimbă formatul culorii',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/ru.ts",
    "content": "export default {\n  badge: 'Знак',\n  open: 'Открыть',\n  close: 'Закрыть',\n  dismiss: 'Отклонить',\n  confirmEdit: {\n    ok: 'ОК',\n    cancel: 'Отмена',\n  },\n  dataIterator: {\n    noResultsText: 'Не найдено подходящих записей',\n    loadingText: 'Запись загружается...',\n  },\n  dataTable: {\n    itemsPerPageText: 'Строк на странице:',\n    ariaLabel: {\n      sortDescending: 'Упорядочено по убыванию.',\n      sortAscending: 'Упорядочено по возрастанию.',\n      sortNone: 'Не упорядочено.',\n      activateNone: 'Активируйте, чтобы убрать сортировку.',\n      activateDescending: 'Активируйте для упорядочивания убыванию.',\n      activateAscending: 'Активируйте для упорядочивания по возрастанию.',\n    },\n    sortBy: 'Сортировать по',\n  },\n  dataFooter: {\n    itemsPerPageText: 'Записей на странице:',\n    itemsPerPageAll: 'Все',\n    nextPage: 'Следующая страница',\n    prevPage: 'Предыдущая страница',\n    firstPage: 'Первая страница',\n    lastPage: 'Последняя страница',\n    pageText: '{0}-{1} из {2}',\n  },\n  dateRangeInput: {\n    divider: 'до',\n  },\n  datePicker: {\n    itemsSelected: '{0} выбрано',\n    range: {\n      title: 'Выбранные даты',\n      header: 'Ввод дат',\n    },\n    title: 'Выбор даты',\n    header: 'Ввод даты',\n    input: {\n      placeholder: 'Введите дату',\n    },\n    ariaLabel: {\n      previousMonth: 'Предыдущий месяц',\n      nextMonth: 'Следующий месяц',\n      selectYear: 'Выбрать год',\n      previousYear: 'Предыдущий год',\n      nextYear: 'Следующий год',\n      selectMonth: 'Выбрать месяц',\n      selectDate: '{0}',\n      currentDate: 'Сегодня, {0}',\n    },\n  },\n  noDataText: 'Отсутствуют данные',\n  carousel: {\n    prev: 'Предыдущий слайд',\n    next: 'Следующий слайд',\n    ariaLabel: {\n      delimiter: 'Слайд {0} из {1}',\n    },\n  },\n  calendar: {\n    moreEvents: 'Еще {0}',\n    today: 'Сегодня',\n  },\n  input: {\n    clear: 'Очистить {0}',\n    prependAction: '{0} предварительных действий',\n    appendAction: '{0} добавочных действий',\n    otp: 'Пожалуйста введите символы OTP {0}',\n  },\n  fileInput: {\n    counter: 'Файлов: {0}',\n    counterSize: 'Файлов: {0} (всего {1})',\n  },\n  fileUpload: {\n    title: 'Перетащите файлы сюда',\n    divider: 'или',\n    browse: 'Просмотр файлов',\n  },\n  timePicker: {\n    am: 'AM',\n    pm: 'PM',\n    title: 'Выберите время',\n    hour: 'Час',\n    minute: 'Минуты',\n    second: 'Секунды',\n    notAllowed: 'Значение не разрешено',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'Навигация по страницам',\n      next: 'Следующая страница',\n      previous: 'Предыдущая страница',\n      page: 'Перейти на страницу {0}',\n      currentPage: 'Текущая страница, Страница {0}',\n      first: 'Первая страница',\n      last: 'Последняя страница',\n    },\n  },\n  stepper: {\n    next: 'Следующий',\n    prev: 'Предыдущий',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'Рейтинг {0} из {1}',\n    },\n  },\n  loading: 'Загрузка...',\n  infiniteScroll: {\n    loadMore: 'Загрузить ещё',\n    empty: 'Больше нечего загружать',\n  },\n  rules: {\n    required: 'Это поле обязательно',\n    email: 'Пожалуйста, введите действительный email',\n    number: 'Это поле может содержать только цифры',\n    integer: 'Это поле может содержать только целые числа',\n    capital: 'Это поле может содержать только заглавные буквы',\n    maxLength: 'Вы должны ввести не более {0} символов',\n    minLength: 'Вы должны ввести не менее {0} символов',\n    strictLength: 'Длина введенного поля недействительна',\n    exclude: 'Символ {0} не разрешен',\n    notEmpty: 'Пожалуйста, выберите хотя бы одно значение',\n    pattern: 'Недопустимый формат',\n  },\n  command: {\n    search: 'Введите команду или введите...',\n  },\n  hotkey: {\n    then: 'затем',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: 'Стрелка вверх',\n    downArrow: 'Стрелка вниз',\n    leftArrow: 'Стрелка влево',\n    rightArrow: 'Стрелка вправо',\n    backspace: 'Backspace',\n    space: 'Пробел',\n    plus: 'плюс',\n    shortcut: 'Сочетание клавиш: {0}',\n    or: 'или',\n  },\n  video: {\n    play: 'Воспроизвести',\n    pause: 'Пауза',\n    seek: 'Перемотка',\n    volume: 'Громкость',\n    showVolume: 'Показать регулятор громкости',\n    mute: 'Отключить звук',\n    unmute: 'Включить звук',\n    enterFullscreen: 'Полноэкранный режим',\n    exitFullscreen: 'Выйти из полноэкранного режима',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'Выбрать цвет с экрана',\n      hueSlider: 'Оттенок',\n      alphaSlider: 'Прозрачность',\n      redInput: 'Красный',\n      greenInput: 'Зеленый',\n      blueInput: 'Синий',\n      alphaInput: 'Прозрачность',\n      hueInput: 'Оттенок',\n      saturationInput: 'Насыщенность',\n      lightnessInput: 'Яркость',\n      hexInput: 'Значение HEX',\n      hexaInput: 'Значение HEX с прозрачностью',\n      changeFormat: 'Изменить формат цвета',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/sk.ts",
    "content": "export default {\n  badge: 'Odznak',\n  open: 'Otvoriť',\n  close: 'Zavrieť',\n  dismiss: 'Zrušiť',\n  confirmEdit: {\n    ok: 'OK',\n    cancel: 'Zrušiť',\n  },\n  dataIterator: {\n    noResultsText: 'Neboli nájdené žiadne záznamy',\n    loadingText: 'Načítavam položky...',\n  },\n  dataTable: {\n    itemsPerPageText: 'Počet riadkov na stránku:',\n    ariaLabel: {\n      sortDescending: 'Zoradené zostupne.',\n      sortAscending: 'Zoradené vzostupne.',\n      sortNone: 'Nezoradené.',\n      activateNone: 'Aktivujte na zrušenie zoradenia.',\n      activateDescending: 'Aktivujte na zoradenie zostupne.',\n      activateAscending: 'Aktivujte na zoradenie vzostupne.',\n    },\n    sortBy: 'Zoradiť podľa',\n  },\n  dataFooter: {\n    itemsPerPageText: 'Počet položiek na stránku:',\n    itemsPerPageAll: 'Všetko',\n    nextPage: 'Ďalšia stránka',\n    prevPage: 'Predchádzajúca stránka',\n    firstPage: 'Prvá stránka',\n    lastPage: 'Posledná stránka',\n    pageText: '{0}–{1} z {2}',\n  },\n  dateRangeInput: {\n    divider: 'až',\n  },\n  datePicker: {\n    itemsSelected: '{0} vybraných',\n    range: {\n      title: 'Vyberte rozsah dátumov',\n      header: 'Zadajte rozsah dátumov',\n    },\n    title: 'Vyberte dátum',\n    header: 'Zadajte dátum',\n    input: {\n      placeholder: 'Zadajte dátum',\n    },\n    ariaLabel: {\n      previousMonth: 'Predchádzajúci mesiac',\n      nextMonth: 'Ďalší mesiac',\n      selectYear: 'Vyberte rok',\n      previousYear: 'Predchádzajúci rok',\n      nextYear: 'Nasledujúci rok',\n      selectMonth: 'Vyberte mesiac',\n      selectDate: '{0}',\n      currentDate: 'Dnes, {0}',\n    },\n  },\n  noDataText: 'Nie sú dostupné žiadne dáta',\n  carousel: {\n    prev: 'Predchádzajúci obrázok',\n    next: 'Další obrázok',\n    ariaLabel: {\n      delimiter: 'Snímka {0} z {1}',\n    },\n  },\n  calendar: {\n    moreEvents: '{0} ďalších',\n    today: 'Dnes',\n  },\n  input: {\n    clear: 'Vymazať {0}',\n    prependAction: 'Akcia pred {0}',\n    appendAction: 'Akcia za {0}',\n    otp: 'Prosím zadajte OTP znak {0}',\n  },\n  fileInput: {\n    counter: '{0} súborov',\n    counterSize: '{0} súborov ({1} celkom)',\n  },\n  fileUpload: {\n    title: 'Sem presuňte súbory',\n    divider: 'alebo',\n    browse: 'Prehliadať súbory',\n  },\n  timePicker: {\n    am: 'AM',\n    pm: 'PM',\n    title: 'Vyberte čas',\n    hour: 'Hodina',\n    minute: 'Minúty',\n    second: 'Sekundy',\n    notAllowed: 'Hodnota nie je povolená',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'Navigácia stránkovania',\n      next: 'Ďalšia stránka',\n      previous: 'Predchádzajúca stránka',\n      page: 'Ísť na stránku {0}',\n      currentPage: 'Aktuálna stránka, stránka {0}',\n      first: 'Prvá stránka',\n      last: 'Posledná stránka',\n    },\n  },\n  stepper: {\n    next: 'Ďalší',\n    prev: 'Predchádzajúci',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'Hodnotenie {0} z {1}',\n    },\n  },\n  loading: 'Načítavam...',\n  infiniteScroll: {\n    loadMore: 'Načítať viac',\n    empty: 'Žiadne ďalšie',\n  },\n  rules: {\n    required: 'Toto pole je povinné',\n    email: 'Zadajte platnú e-mailovú adresu',\n    number: 'Toto pole môže obsahovať iba čísla',\n    integer: 'Toto pole môže obsahovať iba celé čísla',\n    capital: 'Toto pole môže obsahovať iba veľké písmená',\n    maxLength: 'Musíte zadať maximálne {0} znakov',\n    minLength: 'Musíte zadať minimálne {0} znakov',\n    strictLength: 'Dĺžka zadaného poľa je neplatná',\n    exclude: 'Znak {0} nie je povolený',\n    notEmpty: 'Vyberte aspoň jednu hodnotu',\n    pattern: 'Neplatný formát',\n  },\n  command: {\n    search: 'Zadajte príkaz alebo hľadajte...',\n  },\n  hotkey: {\n    then: 'potom',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: 'Šípka hore',\n    downArrow: 'Šípka dole',\n    leftArrow: 'Šípka vľavo',\n    rightArrow: 'Šípka vpravo',\n    backspace: 'Backspace',\n    space: 'Medzera',\n    plus: 'plus',\n    shortcut: 'Klávesová skratka: {0}',\n    or: 'alebo',\n  },\n  video: {\n    play: 'Prehrať',\n    pause: 'Pozastaviť',\n    seek: 'Vyhľadať',\n    volume: 'Hlasitosť',\n    showVolume: 'Zobraziť ovládanie hlasitosti',\n    mute: 'Stlmiť',\n    unmute: 'Zrušiť stlmenie',\n    enterFullscreen: 'Celá obrazovka',\n    exitFullscreen: 'Opustiť celú obrazovku',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'Vybrať farbu z obrazovky',\n      hueSlider: 'Odtieň',\n      alphaSlider: 'Alfa',\n      redInput: 'Červená',\n      greenInput: 'Zelená',\n      blueInput: 'Modrá',\n      alphaInput: 'Alfa',\n      hueInput: 'Odtieň',\n      saturationInput: 'Sýtosť',\n      lightnessInput: 'Svetlosť',\n      hexInput: 'HEX hodnota',\n      hexaInput: 'HEX s alfa hodnotou',\n      changeFormat: 'Zmeniť formát farby',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/sl.ts",
    "content": "export default {\n  badge: 'Značka',\n  open: 'Odpri',\n  close: 'Zapri',\n  dismiss: 'Opusti',\n  confirmEdit: {\n    ok: 'V redu',\n    cancel: 'Prekliči',\n  },\n  dataIterator: {\n    noResultsText: 'Ni iskanega zapisa',\n    loadingText: 'Nalaganje ...',\n  },\n  dataTable: {\n    itemsPerPageText: 'Vrstic na stran:',\n    ariaLabel: {\n      sortDescending: 'Razvrščeno padajoče.',\n      sortAscending: 'Razvrščeno naraščajoče.',\n      sortNone: 'Ni razvrščeno.',\n      activateNone: 'Aktivirajte za odstranitev razvrščanja.',\n      activateDescending: 'Aktivirajte za padajoče razvrščanje.',\n      activateAscending: 'Aktivirajte za naraščajoče razvrščanje.',\n    },\n    sortBy: 'Razvrsti po',\n  },\n  dataFooter: {\n    itemsPerPageText: 'Elementov na stran:',\n    itemsPerPageAll: 'Vsi',\n    nextPage: 'Naslednja stran',\n    prevPage: 'Prejšnja stran',\n    firstPage: 'Prva stran',\n    lastPage: 'Zadnja stran',\n    pageText: '{0}-{1} od {2}',\n  },\n  dateRangeInput: {\n    divider: 'do',\n  },\n  datePicker: {\n    itemsSelected: '{0} izbranih',\n    range: {\n      title: 'Izberite datume',\n      header: 'Vnesite datume',\n    },\n    title: 'Izberite datum',\n    header: 'Vnesite datum',\n    input: {\n      placeholder: 'Vnesite datum',\n    },\n    ariaLabel: {\n      previousMonth: 'Prejšnji mesec',\n      nextMonth: 'Naslednji mesec',\n      selectYear: 'Izberite leto',\n      previousYear: 'Prejšnje leto',\n      nextYear: 'Naslednje leto',\n      selectMonth: 'Izberite mesec',\n      selectDate: '{0}',\n      currentDate: 'Danes, {0}',\n    },\n  },\n  noDataText: 'Ni podatkov',\n  carousel: {\n    prev: 'Prejšnji prikaz',\n    next: 'Naslednji prikaz',\n    ariaLabel: {\n      delimiter: 'Prikaz {0} od {1}',\n    },\n  },\n  calendar: {\n    moreEvents: 'Še {0}',\n    today: 'Danes',\n  },\n  input: {\n    clear: 'Počisti {0}',\n    prependAction: 'Dejanje pred {0}',\n    appendAction: 'Dejanje po {0}',\n    otp: 'Vnesite {0}. OTP znak',\n  },\n  fileInput: {\n    counter: '{0} datotek',\n    counterSize: '{0} datotek (skupno {1})',\n  },\n  fileUpload: {\n    title: 'Povlecite in spustite datoteke tukaj',\n    divider: 'ali',\n    browse: 'Prebrskaj datoteke',\n  },\n  timePicker: {\n    am: 'AM',\n    pm: 'PM',\n    title: 'Izberite čas',\n    hour: 'Ura',\n    minute: 'Minute',\n    second: 'Sekunde',\n    notAllowed: 'Vrednost ni dovoljena',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'Navigacija po straneh',\n      next: 'Naslednja stran',\n      previous: 'Prejšnja stran',\n      page: 'Pojdi na stran {0}',\n      currentPage: 'Trenutna stran, stran {0}',\n      first: 'Prva stran',\n      last: 'Zadnja stran',\n    },\n  },\n  stepper: {\n    next: 'Naprej',\n    prev: 'Nazaj',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'Ocena {0} od {1}',\n    },\n  },\n  loading: 'Nalaganje ...',\n  infiniteScroll: {\n    loadMore: 'Naloži več',\n    empty: 'Konec',\n  },\n  rules: {\n    required: 'To polje je obvezno',\n    email: 'Vnesite veljaven e-poštni naslov',\n    number: 'To polje lahko vsebuje samo številke',\n    integer: 'To polje lahko vsebuje samo cela števila',\n    capital: 'To polje lahko vsebuje samo velike črke',\n    maxLength: 'Vnesti morate največ {0} znakov',\n    minLength: 'Vnesti morate najmanj {0} znakov',\n    strictLength: 'Dolžina vnesenega polja ni veljavna',\n    exclude: 'Znak {0} ni dovoljen',\n    notEmpty: 'Izberite vsaj eno vrednost',\n    pattern: 'Neveljaven format',\n  },\n  command: {\n    search: 'Vnesite ukaz ali iščite...',\n  },\n  hotkey: {\n    then: 'nato',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: 'Puščica gor',\n    downArrow: 'Puščica dol',\n    leftArrow: 'Puščica levo',\n    rightArrow: 'Puščica desno',\n    backspace: 'Backspace',\n    space: 'Presledek',\n    plus: 'plus',\n    shortcut: 'Tipkovnična bližnjica: {0}',\n    or: 'ali',\n  },\n  video: {\n    play: 'Predvajaj',\n    pause: 'Zaustavi',\n    seek: 'Išči',\n    volume: 'Glasnost',\n    showVolume: 'Prikaži nadzor glasnosti',\n    mute: 'Utišaj',\n    unmute: 'Vklopi zvok',\n    enterFullscreen: 'Celozaslonski način',\n    exitFullscreen: 'Izhod iz celozaslonskega načina',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'Izberi barvo z zaslona',\n      hueSlider: 'Barvni odtenek',\n      alphaSlider: 'Alfa',\n      redInput: 'Rdeča',\n      greenInput: 'Zelena',\n      blueInput: 'Modra',\n      alphaInput: 'Alfa',\n      hueInput: 'Barvni odtenek',\n      saturationInput: 'Nasičenost',\n      lightnessInput: 'Svetlost',\n      hexInput: 'HEX vrednost',\n      hexaInput: 'HEX z alfa vrednostjo',\n      changeFormat: 'Spremeni format barve',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/sr-Cyrl.ts",
    "content": "export default {\n  badge: 'Значка',\n  open: 'Отвори',\n  close: 'Затвори',\n  dismiss: 'Одбаци',\n  confirmEdit: {\n    ok: 'У реду',\n    cancel: 'Откажи',\n  },\n  dataIterator: {\n    noResultsText: 'Ни један запис није пронађен',\n    loadingText: 'Учитавање ставке...',\n  },\n  dataTable: {\n    itemsPerPageText: 'Редова по страници:',\n    ariaLabel: {\n      sortDescending: 'Сортирано опадајуће.',\n      sortAscending: 'Сортирано растуће.',\n      sortNone: 'Није сортирано.',\n      activateNone: 'Кликни да уклониш сортирање.',\n      activateDescending: 'Кликни да сортираш опадајуће.',\n      activateAscending: 'Кликни да сортираш растуће.',\n    },\n    sortBy: 'Сортирај по',\n  },\n  dataFooter: {\n    itemsPerPageText: 'Ставки по страници:',\n    itemsPerPageAll: 'Све',\n    nextPage: 'Следећа страница',\n    prevPage: 'Претходна страница',\n    firstPage: 'Прва страница',\n    lastPage: 'Последња страница',\n    pageText: '{0}-{1} од {2}',\n  },\n  dateRangeInput: {\n    divider: 'до',\n  },\n  datePicker: {\n    itemsSelected: '{0} изабрано',\n    range: {\n      title: 'Изаберите датуме',\n      header: 'Унесите датуме',\n    },\n    title: 'Изаберите датум',\n    header: 'Унесите датум',\n    input: {\n      placeholder: 'Унесите датум',\n    },\n    ariaLabel: {\n      previousMonth: 'Previous month',\n      nextMonth: 'Next month',\n      selectYear: 'Select year',\n      previousYear: 'Претходна година',\n      nextYear: 'Следећа година',\n      selectMonth: 'Изаберите месец',\n      selectDate: '{0}',\n      currentDate: 'Today, {0}',\n    },\n  },\n  noDataText: 'Нема доступних података',\n  carousel: {\n    prev: 'Претходна слика',\n    next: 'Следећа слика',\n    ariaLabel: {\n      delimiter: 'Слика {0} од {1}',\n    },\n  },\n  calendar: {\n    moreEvents: '{0} више',\n    today: 'Данас',\n  },\n  input: {\n    clear: 'Очисти {0}',\n    prependAction: '{0} претходна акција',\n    appendAction: '{0} додатна акција',\n    otp: 'Унесите OTP знак {0}',\n  },\n  fileInput: {\n    counter: '{0} фајлова',\n    counterSize: '{0} фајлова ({1} укупно)',\n  },\n  fileUpload: {\n    title: 'Превуците и отпустите фајлове овде',\n    divider: 'или',\n    browse: 'Прегледај фајлове',\n  },\n  timePicker: {\n    am: 'АМ',\n    pm: 'ПМ',\n    title: 'Изаберите време',\n    hour: 'Сат',\n    minute: 'Минути',\n    second: 'Секунде',\n    notAllowed: 'Вредност није дозвољена',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'Навигација страницама',\n      next: 'Следећа страница',\n      previous: 'Претходна страница',\n      page: 'Иди на страницу {0}',\n      currentPage: 'Тренутна страница, страница {0}',\n      first: 'Прва страница',\n      last: 'Последња страница',\n    },\n  },\n  stepper: {\n    next: 'Следеће',\n    prev: 'Претходно',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'Оцена {0} од {1}',\n    },\n  },\n  loading: 'Учитавање...',\n  infiniteScroll: {\n    loadMore: 'Учитај више',\n    empty: 'Нема више података',\n  },\n  rules: {\n    required: 'Ово поље је обавезно',\n    email: 'Унесите важећу е-маил адресу',\n    number: 'Ово поље може садржати само бројеве',\n    integer: 'Ово поље може садржати само целе бројеве',\n    capital: 'Ово поље може садржати само велика слова',\n    maxLength: 'Морате унети максимум {0} карактера',\n    minLength: 'Морате унети минимум {0} карактера',\n    strictLength: 'Дужина унетог поља није важећа',\n    exclude: 'Карактер {0} није дозвољен',\n    notEmpty: 'Изаберите бар једну вредност',\n    pattern: 'Неважећи формат',\n  },\n  command: {\n    search: 'Унесите команду или претражите...',\n  },\n  hotkey: {\n    then: 'затим',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: 'Стрелица нагоре',\n    downArrow: 'Стрелица надоле',\n    leftArrow: 'Стрелица налево',\n    rightArrow: 'Стрелица надесно',\n    backspace: 'Backspace',\n    space: 'Размак',\n    plus: 'плус',\n    shortcut: 'Пречица на тастатури: {0}',\n    or: 'или',\n  },\n  video: {\n    play: 'Пусти',\n    pause: 'Паузирај',\n    seek: 'Тражи',\n    volume: 'Јачина звука',\n    showVolume: 'Прикажи контролу јачине звука',\n    mute: 'Искључи звук',\n    unmute: 'Укључи звук',\n    enterFullscreen: 'Цео екран',\n    exitFullscreen: 'Изађи из целог екрана',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'Изаберите боју са екрана',\n      hueSlider: 'Нијанса',\n      alphaSlider: 'Алфа',\n      redInput: 'Црвена',\n      greenInput: 'Зелена',\n      blueInput: 'Плава',\n      alphaInput: 'Алфа',\n      hueInput: 'Нијанса',\n      saturationInput: 'Засићеност',\n      lightnessInput: 'Осветљеност',\n      hexInput: 'ХЕКС вредност',\n      hexaInput: 'ХЕКС са алфа вредношћу',\n      changeFormat: 'Промени формат боје',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/sr-Latn.ts",
    "content": "export default {\n  badge: 'Značka',\n  open: 'Otvori',\n  close: 'Zatvori',\n  dismiss: 'Odbaci',\n  confirmEdit: {\n    ok: 'U redu',\n    cancel: 'Otkaži',\n  },\n  dataIterator: {\n    noResultsText: 'Nijedan zapis nije pronađen',\n    loadingText: 'Učitavanje stavki...',\n  },\n  dataTable: {\n    itemsPerPageText: 'Redova po stranici:',\n    ariaLabel: {\n      sortDescending: 'Sortirano opadajuće.',\n      sortAscending: 'Sortirano rastuće.',\n      sortNone: 'Nije sortirano.',\n      activateNone: 'Klikni da ukloniš sortiranje.',\n      activateDescending: 'Klikni da sortiraš opadajuće.',\n      activateAscending: 'Klikni da sortiraš rastuće.',\n    },\n    sortBy: 'Sortiraj po',\n  },\n  dataFooter: {\n    itemsPerPageText: 'Stavki po stranici:',\n    itemsPerPageAll: 'Sve',\n    nextPage: 'Sledeća stranica',\n    prevPage: 'Prethodna stranica',\n    firstPage: 'Prva stranica',\n    lastPage: 'Poslednja stranica',\n    pageText: '{0}-{1} od {2}',\n  },\n  dateRangeInput: {\n    divider: 'do',\n  },\n  datePicker: {\n    itemsSelected: '{0} izabrano',\n    range: {\n      title: 'Izaberite datume',\n      header: 'Unesite datume',\n    },\n    title: 'Izaberite datum',\n    header: 'Unesite datum',\n    input: {\n      placeholder: 'Unesite datum',\n    },\n    ariaLabel: {\n      previousMonth: 'Prethodni mesec',\n      nextMonth: 'Sledeći mesec',\n      selectYear: 'Izaberi godinu',\n      previousYear: 'Prethodna godina',\n      nextYear: 'Sledeća godina',\n      selectMonth: 'Izaberi mesec',\n      selectDate: '{0}',\n      currentDate: 'Danas, {0}',\n    },\n  },\n  noDataText: 'Nema dostupnih podataka',\n  carousel: {\n    prev: 'Prethodna slika',\n    next: 'Sledeća slika',\n    ariaLabel: {\n      delimiter: 'Slika {0} od {1}',\n    },\n  },\n  calendar: {\n    moreEvents: '{0} više',\n    today: 'Danas',\n  },\n  input: {\n    clear: 'Obriši {0}',\n    prependAction: '{0} prethodna radnja',\n    appendAction: '{0} sledeća radnja',\n    otp: 'Unesite OTP znak {0}',\n  },\n  fileInput: {\n    counter: '{0} fajlova',\n    counterSize: '{0} fajlova ({1} ukupno)',\n  },\n  fileUpload: {\n    title: 'Prevucite i otpustite fajlove ovde',\n    divider: 'ili',\n    browse: 'Pregledaj fajlove',\n  },\n  timePicker: {\n    am: 'AM',\n    pm: 'PM',\n    title: 'Izaberite vreme',\n    hour: 'Sat',\n    minute: 'Minute',\n    second: 'Sekunde',\n    notAllowed: 'Vrednost nije dozvoljena',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'Navigacija stranicama',\n      next: 'Sledeća stranica',\n      previous: 'Prethodna stranica',\n      page: 'Idi na stranu {0}',\n      currentPage: 'Trenutna stranica, stranica {0}',\n      first: 'Prva stranica',\n      last: 'Poslednja stranica',\n    },\n  },\n  stepper: {\n    next: 'Sledeće',\n    prev: 'Prethodno',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'Ocena {0} od {1}',\n    },\n  },\n  loading: 'Učitavanje...',\n  infiniteScroll: {\n    loadMore: 'Učitaj još',\n    empty: 'Nema više podataka',\n  },\n  rules: {\n    required: 'Ovo polje je obavezno',\n    email: 'Unesite važeću e-mail adresu',\n    number: 'Ovo polje može sadržati samo brojeve',\n    integer: 'Ovo polje može sadržati samo cele brojeve',\n    capital: 'Ovo polje može sadržati samo velika slova',\n    maxLength: 'Morate uneti maksimum {0} karaktera',\n    minLength: 'Morate uneti minimum {0} karaktera',\n    strictLength: 'Dužina unetog polja nije važeća',\n    exclude: 'Karakter {0} nije dozvoljen',\n    notEmpty: 'Izaberite bar jednu vrednost',\n    pattern: 'Nevažeći format',\n  },\n  command: {\n    search: 'Unesite naredbu ili pretražite...',\n  },\n  hotkey: {\n    then: 'zatim',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: 'Strelica gore',\n    downArrow: 'Strelica dole',\n    leftArrow: 'Strelica levo',\n    rightArrow: 'Strelica desno',\n    backspace: 'Backspace',\n    space: 'Razmak',\n    plus: 'plus',\n    shortcut: 'Prečica na tastaturi: {0}',\n    or: 'ili',\n  },\n  video: {\n    play: 'Reprodukuj',\n    pause: 'Pauziraj',\n    seek: 'Traži',\n    volume: 'Jačina zvuka',\n    showVolume: 'Prikaži kontrolu jačine zvuka',\n    mute: 'Isključi zvuk',\n    unmute: 'Uključi zvuk',\n    enterFullscreen: 'Prikaz preko cijelog ekrana',\n    exitFullscreen: 'Izađi iz prikaza preko cijelog ekrana',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'Izaberite boju sa ekrana',\n      hueSlider: 'Nijansa',\n      alphaSlider: 'Alfa',\n      redInput: 'Crvena',\n      greenInput: 'Zelena',\n      blueInput: 'Plava',\n      alphaInput: 'Alfa',\n      hueInput: 'Nijansa',\n      saturationInput: 'Zasićenost',\n      lightnessInput: 'Svetlina',\n      hexInput: 'HEX vrednost',\n      hexaInput: 'HEX sa alfa vrednošću',\n      changeFormat: 'Promeni format boje',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/sv.ts",
    "content": "export default {\n  badge: 'Bricka',\n  open: 'Öppna',\n  close: 'Stäng',\n  dismiss: 'Avvisa',\n  confirmEdit: {\n    ok: 'OK',\n    cancel: 'Avbryt',\n  },\n  dataIterator: {\n    noResultsText: 'Hittade inga poster',\n    loadingText: 'Laddar data...',\n  },\n  dataTable: {\n    itemsPerPageText: 'Rader per sida:',\n    ariaLabel: {\n      sortDescending: 'Fallande sortering.',\n      sortAscending: 'Stigande sortering.',\n      sortNone: 'Osorterat.',\n      activateNone: 'Aktivera för att ta bort sortering.',\n      activateDescending: 'Aktivera för att sortera fallande.',\n      activateAscending: 'Aktivera för att sortera stigande.',\n    },\n    sortBy: 'Sortera efter',\n  },\n  dataFooter: {\n    itemsPerPageText: 'Objekt per sida:',\n    itemsPerPageAll: 'Alla',\n    nextPage: 'Nästa sida',\n    prevPage: 'Föregående sida',\n    firstPage: 'Första sidan',\n    lastPage: 'Sista sidan',\n    pageText: '{0}-{1} av {2}',\n  },\n  dateRangeInput: {\n    divider: 'till',\n  },\n  datePicker: {\n    itemsSelected: '{0} valda',\n    range: {\n      title: 'Välj datum',\n      header: 'Välj datum',\n    },\n    title: 'Välj datum',\n    header: 'Välj datum',\n    input: {\n      placeholder: 'Välj datum',\n    },\n    ariaLabel: {\n      previousMonth: 'Föregående månad',\n      nextMonth: 'Nästa månad',\n      selectYear: 'Välj år',\n      previousYear: 'Föregående år',\n      nextYear: 'Nästa år',\n      selectMonth: 'Välj månad',\n      selectDate: '{0}',\n      currentDate: 'Idag, {0}',\n    },\n  },\n  noDataText: 'Ingen data tillgänglig',\n  carousel: {\n    prev: 'Föregående vy',\n    next: 'Nästa vy',\n    ariaLabel: {\n      delimiter: 'Karusellvy {0} av {1}',\n    },\n  },\n  calendar: {\n    moreEvents: '{0} fler',\n    today: 'Idag',\n  },\n  input: {\n    clear: 'Rensa {0}',\n    prependAction: '{0} föregående åtgärd',\n    appendAction: '{0} efterföljande åtgärd',\n    otp: 'Vänligen ange OTP-tecken {0}',\n  },\n  fileInput: {\n    counter: '{0} filer',\n    counterSize: '{0} filer ({1})',\n  },\n  fileUpload: {\n    title: 'Dra och släpp filer här',\n    divider: 'eller',\n    browse: 'Bläddra bland filer',\n  },\n  timePicker: {\n    am: 'FM',\n    pm: 'EM',\n    title: 'Välj tid',\n    hour: 'Timme',\n    minute: 'Minuter',\n    second: 'Sekunder',\n    notAllowed: 'Värdet är inte tillåtet',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'Paginering',\n      next: 'Nästa sida',\n      previous: 'Föregående sida',\n      page: 'Gå till sida {0}',\n      currentPage: 'Aktuell sida, sida {0}',\n      first: 'Första sidan',\n      last: 'Sista sidan',\n    },\n  },\n  stepper: {\n    next: 'Next',\n    prev: 'Previous',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'Betyg {0} av {1}',\n    },\n  },\n  loading: 'Laddar...',\n  infiniteScroll: {\n    loadMore: 'Ladda fler',\n    empty: 'Inga fler',\n  },\n  rules: {\n    required: 'Detta fält är obligatoriskt',\n    email: 'Ange en giltig e-postadress',\n    number: 'Detta fält kan bara innehålla siffror',\n    integer: 'Detta fält kan bara innehålla heltal',\n    capital: 'Detta fält kan bara innehålla stora bokstäver',\n    maxLength: 'Du måste ange högst {0} tecken',\n    minLength: 'Du måste ange minst {0} tecken',\n    strictLength: 'Längden på det angivna fältet är ogiltig',\n    exclude: 'Tecknet {0} är inte tillåtet',\n    notEmpty: 'Välj minst ett värde',\n    pattern: 'Ogiltigt format',\n  },\n  command: {\n    search: 'Skriv ett kommando eller sök...',\n  },\n  hotkey: {\n    then: 'sedan',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: 'Pil upp',\n    downArrow: 'Pil ner',\n    leftArrow: 'Pil vänster',\n    rightArrow: 'Pil höger',\n    backspace: 'Backsteg',\n    space: 'Mellanslag',\n    plus: 'plus',\n    shortcut: 'Tangentbordsgenväg: {0}',\n    or: 'eller',\n  },\n  video: {\n    play: 'Spela upp',\n    pause: 'Pausa',\n    seek: 'Sök',\n    volume: 'Volym',\n    showVolume: 'Visa volymkontroll',\n    mute: 'Stäng av ljud',\n    unmute: 'Slå på ljud',\n    enterFullscreen: 'Helskärm',\n    exitFullscreen: 'Avsluta helskärm',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'Välj färg från skärmen',\n      hueSlider: 'Nyans',\n      alphaSlider: 'Alfa',\n      redInput: 'Röd',\n      greenInput: 'Grön',\n      blueInput: 'Blå',\n      alphaInput: 'Alfa',\n      hueInput: 'Nyans',\n      saturationInput: 'Mättnad',\n      lightnessInput: 'Ljushet',\n      hexInput: 'HEX-värde',\n      hexaInput: 'HEX med alfavärde',\n      changeFormat: 'Ändra färgformat',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/th.ts",
    "content": "export default {\n  badge: 'สัญลักษณ์',\n  open: 'เปิด',\n  close: 'ปิด',\n  dismiss: 'ยกเลิก',\n  confirmEdit: {\n    ok: 'ตกลง',\n    cancel: 'ยกเลิก',\n  },\n  dataIterator: {\n    noResultsText: 'ไม่พบข้อมูลที่ค้นหา',\n    loadingText: 'กำลังโหลดข้อมูล...',\n  },\n  dataTable: {\n    itemsPerPageText: 'แถวต่อหน้า:',\n    ariaLabel: {\n      sortDescending: 'เรียงจากมากไปน้อยอยู่',\n      sortAscending: 'เรียงจากน้อยไปมากอยู่',\n      sortNone: 'ไม่ได้เรียงลำดับ',\n      activateNone: 'กดเพื่อปิดการเรียงลำดับ',\n      activateDescending: 'กดเพื่อเรียงจากมากไปน้อย',\n      activateAscending: 'กดเพื่อเรียงจากน้อยไปมาก',\n    },\n    sortBy: 'เรียงตาม',\n  },\n  dataFooter: {\n    itemsPerPageText: 'รายการต่อหน้า:',\n    itemsPerPageAll: 'ทั้งหมด',\n    nextPage: 'หน้าต่อไป',\n    prevPage: 'หน้าที่แล้ว',\n    firstPage: 'หน้าแรก',\n    lastPage: 'หน้าสุดท้าย',\n    pageText: '{0}-{1} จาก {2}',\n  },\n  dateRangeInput: {\n    divider: 'ถึง',\n  },\n  datePicker: {\n    itemsSelected: 'เลือกแล้ว {0} รายการ',\n    range: {\n      title: 'เลือกวันที่',\n      header: 'ป้อนวันที่',\n    },\n    title: 'เลือกวันที่',\n    header: 'ป้อนวันที่',\n    input: {\n      placeholder: 'ป้อนวันที่',\n    },\n    ariaLabel: {\n      previousMonth: 'เดือนก่อนหน้า',\n      nextMonth: 'เดือนถัดไป',\n      selectYear: 'เลือกปี',\n      previousYear: 'ปีก่อนหน้า',\n      nextYear: 'ปีถัดไป',\n      selectMonth: 'เลือกเดือน',\n      selectDate: '{0}',\n      currentDate: 'วันนี้, {0}',\n    },\n  },\n  noDataText: 'ไม่มีข้อมูล',\n  carousel: {\n    prev: 'ภาพก่อนหน้า',\n    next: 'ภาพถัดไป',\n    ariaLabel: {\n      delimiter: 'ภาพสไลด์ที่ {0} จาก {1}',\n    },\n  },\n  calendar: {\n    moreEvents: 'มีอีก {0}',\n    today: 'วันนี้',\n  },\n  input: {\n    clear: 'ล้าง {0}',\n    prependAction: 'การกระทำก่อนหน้า {0}',\n    appendAction: 'การกระทำเพิ่มเติม {0}',\n    otp: 'กรุณากรอกตัวอักษร OTP ตัวที่ {0}',\n  },\n  fileInput: {\n    counter: '{0} ไฟล์',\n    counterSize: '{0} ไฟล์ (รวม {1})',\n  },\n  fileUpload: {\n    title: 'ลากและวางไฟล์ที่นี่',\n    divider: 'หรือ',\n    browse: 'เลือกไฟล์',\n  },\n  timePicker: {\n    am: 'ช่วงเช้า',\n    pm: 'ช่วงบ่าย',\n    title: 'เลือกเวลา',\n    hour: 'ชั่วโมง',\n    minute: 'นาที',\n    second: 'วินาที',\n    notAllowed: 'ค่าไม่ได้รับอนุญาต',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'การนำทางไปยังหน้า',\n      next: 'หน้าต่อไป',\n      previous: 'หน้าที่แล้ว',\n      page: 'ไปที่หน้า {0}',\n      currentPage: 'หน้าปัจจุบัน (หน้า {0})',\n      first: 'หน้าแรก',\n      last: 'หน้าสุดท้าย',\n    },\n  },\n  stepper: {\n    next: 'ถัดไป',\n    prev: 'ก่อนหน้า',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'คะแนน {0} จาก {1}',\n    },\n  },\n  loading: 'กำลังโหลด...',\n  infiniteScroll: {\n    loadMore: 'โหลดเพิ่มเติม',\n    empty: 'ไม่มีข้อมูลเพิ่มเติม',\n  },\n  rules: {\n    required: 'ช่องนี้จำเป็นต้องกรอก',\n    email: 'กรุณากรอกอีเมลที่ถูกต้อง',\n    number: 'ช่องนี้สามารถมีเฉพาะตัวเลขเท่านั้น',\n    integer: 'ช่องนี้สามารถมีเฉพาะจำนวนเต็มเท่านั้น',\n    capital: 'ช่องนี้สามารถมีเฉพาะตัวพิมพ์ใหญ่เท่านั้น',\n    maxLength: 'คุณต้องกรอกสูงสุด {0} อักขระ',\n    minLength: 'คุณต้องกรอกขั้นต่ำ {0} อักขระ',\n    strictLength: 'ความยาวของช่องที่กรอกไม่ถูกต้อง',\n    exclude: 'อักขระ {0} ไม่ได้รับอนุญาต',\n    notEmpty: 'กรุณาเลือกอย่างน้อยหนึ่งค่า',\n    pattern: 'รูปแบบไม่ถูกต้อง',\n  },\n  command: {\n    search: 'พิมพ์คำสั่งหรือค้นหา...',\n  },\n  hotkey: {\n    then: 'จากนั้น',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: 'ลูกศรขึ้น',\n    downArrow: 'ลูกศรลง',\n    leftArrow: 'ลูกศรซ้าย',\n    rightArrow: 'ลูกศรขวา',\n    backspace: 'Backspace',\n    space: 'เว้นวรรค',\n    plus: 'บวก',\n    shortcut: 'ทางลัดแป้นพิมพ์: {0}',\n    or: 'หรือ',\n  },\n  video: {\n    play: 'เล่น',\n    pause: 'หยุดชั่วคราว',\n    seek: 'ค้นหา',\n    volume: 'ระดับเสียง',\n    showVolume: 'แสดงตัวควบคุมระดับเสียง',\n    mute: 'ปิดเสียง',\n    unmute: 'เปิดเสียง',\n    enterFullscreen: 'เต็มหน้าจอ',\n    exitFullscreen: 'ออกจากเต็มหน้าจอ',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'เลือกสีจากหน้าจอ',\n      hueSlider: 'ค่าสี',\n      alphaSlider: 'ค่าความโปร่งใส',\n      redInput: 'สีแดง',\n      greenInput: 'สีเขียว',\n      blueInput: 'สีน้ำเงิน',\n      alphaInput: 'ค่าความโปร่งใส',\n      hueInput: 'ค่าสี',\n      saturationInput: 'ค่าความอิ่มตัวของสี',\n      lightnessInput: 'ค่าความสว่าง',\n      hexInput: 'ค่า HEX',\n      hexaInput: 'ค่า HEX พร้อมค่าความโปร่งใส',\n      changeFormat: 'เปลี่ยนรูปแบบสี',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/tr.ts",
    "content": "export default {\n  badge: 'Rozet',\n  open: 'Aç',\n  close: 'Kapat',\n  dismiss: 'Kapat',\n  confirmEdit: {\n    ok: 'Tamam',\n    cancel: 'İptal',\n  },\n  dataIterator: {\n    noResultsText: 'Eşleşen veri bulunamadı',\n    loadingText: 'Yükleniyor... Lütfen bekleyin.',\n  },\n  dataTable: {\n    itemsPerPageText: 'Sayfa başına satır:',\n    ariaLabel: {\n      sortDescending: 'Z den A ya sıralı.',\n      sortAscending: 'A dan Z ye sıralı.',\n      sortNone: 'Sıralı değil. ',\n      activateNone: 'Sıralamayı kaldırmak için etkinleştir.',\n      activateDescending: 'Z den A ya sıralamak için etkinleştir.',\n      activateAscending: 'A dan Z ye sıralamak için etkinleştir.',\n    },\n    sortBy: 'Sırala',\n  },\n  dataFooter: {\n    itemsPerPageText: 'Sayfa başına satır:',\n    itemsPerPageAll: 'Hepsi',\n    nextPage: 'Sonraki sayfa',\n    prevPage: 'Önceki sayfa',\n    firstPage: 'İlk sayfa',\n    lastPage: 'Son sayfa',\n    pageText: '{0} - {1} arası, Toplam: {2} kayıt',\n  },\n  dateRangeInput: {\n    divider: 'ile',\n  },\n  datePicker: {\n    itemsSelected: '{0} seçildi',\n    range: {\n      title: 'Tarihleri seçin',\n      header: 'Tarihleri girin',\n    },\n    title: 'Tarih seçin',\n    header: 'Tarih girin',\n    input: {\n      placeholder: 'Tarih girin',\n    },\n    ariaLabel: {\n      previousMonth: 'Önceki ay',\n      nextMonth: 'Sonraki ay',\n      selectYear: 'Yıl seçin',\n      previousYear: 'Önceki yıl',\n      nextYear: 'Sonraki yıl',\n      selectMonth: 'Ay seçin',\n      selectDate: '{0}',\n      currentDate: 'Bugün, {0}',\n    },\n  },\n  noDataText: 'Bu görünümde veri yok.',\n  carousel: {\n    prev: 'Önceki görsel',\n    next: 'Sonraki görsel',\n    ariaLabel: {\n      delimiter: 'Galeri sayfa {0} / {1}',\n    },\n  },\n  calendar: {\n    moreEvents: '{0} tane daha',\n    today: 'Bugün',\n  },\n  input: {\n    clear: '{0} temizle',\n    prependAction: '{0} ön işlem',\n    appendAction: '{0} ek işlem',\n    otp: 'Lütfen OTP karakterini girin {0}',\n  },\n  fileInput: {\n    counter: '{0} dosya',\n    counterSize: '{0} dosya (toplamda {1})',\n  },\n  fileUpload: {\n    title: 'Dosyaları buraya sürükleyip bırakın',\n    divider: 'veya',\n    browse: 'Dosyalara göz at',\n  },\n  timePicker: {\n    am: 'ÖÖ',\n    pm: 'ÖS',\n    title: 'Saat seçin',\n    hour: 'Saat',\n    minute: 'Dakika',\n    second: 'Saniye',\n    notAllowed: 'Değere izin verilmiyor',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'Sayfalandırma Navigasyonu',\n      next: 'Sonraki sayfa',\n      previous: 'Önceki sayfa',\n      page: 'Sayfaya git {0}',\n      currentPage: 'Geçerli Sayfa, Sayfa {0}',\n      first: 'İlk sayfa',\n      last: 'Son sayfa',\n    },\n  },\n  stepper: {\n    next: 'İleri',\n    prev: 'Geri',\n  },\n  rating: {\n    ariaLabel: {\n      item: '{1} üzerinden {0} puan',\n    },\n  },\n  loading: 'Yükleniyor...',\n  infiniteScroll: {\n    loadMore: 'Daha fazla yükle',\n    empty: 'Daha fazla içerik yok',\n  },\n  rules: {\n    required: 'Bu alan zorunludur',\n    email: 'Lütfen geçerli bir e-posta adresi girin',\n    number: 'Bu alan sadece sayılar içerebilir',\n    integer: 'Bu alan sadece tam sayılar içerebilir',\n    capital: 'Bu alan sadece büyük harfler içerebilir',\n    maxLength: 'En fazla {0} karakter girmelisiniz',\n    minLength: 'En az {0} karakter girmelisiniz',\n    strictLength: 'Girilen alanın uzunluğu geçersiz',\n    exclude: '{0} karakteri izin verilmez',\n    notEmpty: 'Lütfen en az bir değer seçin',\n    pattern: 'Geçersiz biçim',\n  },\n  command: {\n    search: 'Komut yazın veya arayın...',\n  },\n  hotkey: {\n    then: 'sonra',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: 'Yukarı Ok',\n    downArrow: 'Aşağı Ok',\n    leftArrow: 'Sol Ok',\n    rightArrow: 'Sağ Ok',\n    backspace: 'Geri Al',\n    space: 'Boşluk',\n    plus: 'artı',\n    shortcut: 'Klavye kısayolu: {0}',\n    or: 'veya',\n  },\n  video: {\n    play: 'Oynat',\n    pause: 'Duraklat',\n    seek: 'Ara',\n    volume: 'Ses',\n    showVolume: 'Ses kontrolünü göster',\n    mute: 'Sesi kapat',\n    unmute: 'Sesi aç',\n    enterFullscreen: 'Tam ekran',\n    exitFullscreen: 'Tam ekrandan çık',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'Ekranda renk seç',\n      hueSlider: 'Ton',\n      alphaSlider: 'Alfa',\n      redInput: 'Kırmızı',\n      greenInput: 'Yeşil',\n      blueInput: 'Mavi',\n      alphaInput: 'Alfa',\n      hueInput: 'Ton',\n      saturationInput: 'Doygunluk',\n      lightnessInput: 'Parlaklık',\n      hexInput: 'HEX değeri',\n      hexaInput: 'Alfa değerli HEX',\n      changeFormat: 'Renk biçimini değiştir',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/uk.ts",
    "content": "export default {\n  badge: 'Значок',\n  open: 'Відкрити',\n  close: 'Закрити',\n  dismiss: 'Відхилити',\n  confirmEdit: {\n    ok: 'ОК',\n    cancel: 'Скасувати',\n  },\n  dataIterator: {\n    noResultsText: 'В результаті пошуку нічого не знайдено',\n    loadingText: 'Завантаження...',\n  },\n  dataTable: {\n    itemsPerPageText: 'Рядків на сторінці:',\n    ariaLabel: {\n      sortDescending: 'Відсортовано за спаданням.',\n      sortAscending: 'Відсортовано за зростанням.',\n      sortNone: 'Не відсортовано.',\n      activateNone: 'Активувати, щоб видалити сортування.',\n      activateDescending: 'Активувати, щоб відсортувати за спаданням.',\n      activateAscending: 'Активувати, щоб відсортувати за зростанням.',\n    },\n    sortBy: 'Відсортувати за',\n  },\n  dataFooter: {\n    itemsPerPageText: 'Елементів на сторінці:',\n    itemsPerPageAll: 'Всі',\n    nextPage: 'Наступна сторінка',\n    prevPage: 'Попередня сторінка',\n    firstPage: 'Перша сторінка',\n    lastPage: 'Остання сторінка',\n    pageText: '{0}-{1} з {2}',\n  },\n  dateRangeInput: {\n    divider: 'до',\n  },\n  datePicker: {\n    itemsSelected: 'Вибрано {0}',\n    range: {\n      title: 'Оберіть дати',\n      header: 'Введіть дати',\n    },\n    title: 'Оберіть дату',\n    header: 'Введіть дату',\n    input: {\n      placeholder: 'Введіть дату',\n    },\n    ariaLabel: {\n      previousMonth: 'Попередній місяць',\n      nextMonth: 'Наступний місяць',\n      selectYear: 'Виберіть рік',\n      previousYear: 'Попередній рік',\n      nextYear: 'Наступний рік',\n      selectMonth: 'Виберіть місяць',\n      selectDate: '{0}',\n      currentDate: 'Сьогодні, {0}',\n    },\n  },\n  noDataText: 'Немає даних для відображення',\n  carousel: {\n    prev: 'Попередній слайд',\n    next: 'Наступий слайд',\n    ariaLabel: {\n      delimiter: 'Слайд {0} з {1}',\n    },\n  },\n  calendar: {\n    moreEvents: 'Ще {0}',\n    today: 'Сьогодні',\n  },\n  input: {\n    clear: 'Очистити {0}',\n    prependAction: '{0} попередня дія',\n    appendAction: '{0} наступна дія',\n    otp: 'Будь ласка, введіть символ OTP {0}',\n  },\n  fileInput: {\n    counter: '{0} файлів',\n    counterSize: '{0} файлів ({1} загалом)',\n  },\n  fileUpload: {\n    title: 'Перетягніть файли сюди',\n    divider: 'або',\n    browse: 'Переглянути файли',\n  },\n  timePicker: {\n    am: 'AM',\n    pm: 'PM',\n    title: 'Оберіть час',\n    hour: 'Година',\n    minute: 'Хвилини',\n    second: 'Секунди',\n    notAllowed: 'Значення не дозволено',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'Навігація по сторінках',\n      next: 'Наступна сторінка',\n      previous: 'Попередня сторінка',\n      page: 'Перейти на сторінку {0}',\n      currentPage: 'Поточна сторінка, Сторінка {0}',\n      first: 'Перша сторінка',\n      last: 'Остання сторінка',\n    },\n  },\n  stepper: {\n    next: 'Далі',\n    prev: 'Назад',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'Оцінка {0} з {1}',\n    },\n  },\n  loading: 'Завантаження...',\n  infiniteScroll: {\n    loadMore: 'Завантажити більше',\n    empty: 'Немає більше даних',\n  },\n  rules: {\n    required: 'Це поле є обов’язковим',\n    email: 'Будь ласка, введіть дійсну електронну адресу',\n    number: 'Це поле може містити лише цифри',\n    integer: 'Це поле може містити лише цілі числа',\n    capital: 'Це поле може містити лише великі літери',\n    maxLength: 'Ви повинні ввести максимум {0} символів',\n    minLength: 'Ви повинні ввести мінімум {0} символів',\n    strictLength: 'Довжина введеного поля є недійсною',\n    exclude: 'Символ {0} не дозволений',\n    notEmpty: 'Будь ласка, виберіть принаймні одне значення',\n    pattern: 'Недійсний формат',\n  },\n  command: {\n    search: 'Введіть команду або виконайте пошук...',\n  },\n  hotkey: {\n    then: 'потім',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: 'Стрілка вгору',\n    downArrow: 'Стрілка вниз',\n    leftArrow: 'Стрілка вліво',\n    rightArrow: 'Стрілка вправо',\n    backspace: 'Backspace',\n    space: 'Пробіл',\n    plus: 'плюс',\n    shortcut: 'Комбінація клавіш: {0}',\n    or: 'або',\n  },\n  video: {\n    play: 'Відтворити',\n    pause: 'Пауза',\n    seek: 'Пошук',\n    volume: 'Гучність',\n    showVolume: 'Показати регулятор гучності',\n    mute: 'Вимкнути звук',\n    unmute: 'Увімкнути звук',\n    enterFullscreen: 'На весь екран',\n    exitFullscreen: 'Вийти з повноекранного режиму',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'Вибрати колір з екрана',\n      hueSlider: 'Відтінок',\n      alphaSlider: 'Прозорість',\n      redInput: 'Червоний',\n      greenInput: 'Зелений',\n      blueInput: 'Синій',\n      alphaInput: 'Прозорість',\n      hueInput: 'Відтінок',\n      saturationInput: 'Насиченість',\n      lightnessInput: 'Яскравість',\n      hexInput: 'HEX значення',\n      hexaInput: 'HEX зі значенням прозорості',\n      changeFormat: 'Змінити формат кольору',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/vi.ts",
    "content": "export default {\n  badge: 'Huy hiệu',\n  open: 'Mở',\n  close: 'Đóng',\n  dismiss: 'Bỏ qua',\n  confirmEdit: {\n    ok: 'OK',\n    cancel: 'Hủy',\n  },\n  dataIterator: {\n    noResultsText: 'Không tìm thấy kết quả nào',\n    loadingText: 'Đang tải...',\n  },\n  dataTable: {\n    itemsPerPageText: 'Số hàng mỗi trang:',\n    ariaLabel: {\n      sortDescending: 'Sắp xếp giảm dần.',\n      sortAscending: 'Sắp xếp tăng dần.',\n      sortNone: 'Không sắp xếp.',\n      activateNone: 'Kích hoạt để bỏ sắp xếp.',\n      activateDescending: 'Kích hoạt để sắp xếp giảm dần.',\n      activateAscending: 'Kích hoạt để sắp xếp tăng dần.',\n    },\n    sortBy: 'Sắp xếp',\n  },\n  dataFooter: {\n    itemsPerPageText: 'Số mục mỗi trang:',\n    itemsPerPageAll: 'Toàn bộ',\n    nextPage: 'Trang tiếp theo',\n    prevPage: 'Trang trước',\n    firstPage: 'Trang đầu',\n    lastPage: 'Trang cuối',\n    pageText: '{0}-{1} trên {2}',\n  },\n  dateRangeInput: {\n    divider: 'đến',\n  },\n  datePicker: {\n    itemsSelected: '{0} mục đã chọn',\n    range: {\n      title: 'Chọn ngày',\n      header: 'Nhập ngày',\n    },\n    title: 'Chọn ngày',\n    header: 'Nhập ngày',\n    input: {\n      placeholder: 'Nhập ngày',\n    },\n    ariaLabel: {\n      previousMonth: 'Tháng trước',\n      nextMonth: 'Tháng sau',\n      selectYear: 'Chọn năm',\n      previousYear: 'Năm trước',\n      nextYear: 'Năm sau',\n      selectMonth: 'Chọn tháng',\n      selectDate: '{0}',\n      currentDate: 'Hôm nay, {0}',\n    },\n  },\n  noDataText: 'Không có dữ liệu',\n  carousel: {\n    prev: 'Ảnh trước',\n    next: 'Ảnh tiếp theo',\n    ariaLabel: {\n      delimiter: 'Carousel slide {0} trên {1}',\n    },\n  },\n  calendar: {\n    moreEvents: '{0} nữa',\n    today: 'Hôm nay',\n  },\n  input: {\n    clear: 'Xóa {0}',\n    prependAction: 'Hành động trước {0}',\n    appendAction: 'Hành động sau {0}',\n    otp: 'Vui lòng nhập ký tự OTP thứ {0}',\n  },\n  fileInput: {\n    counter: '{0} tệp',\n    counterSize: '{0} tệp (tổng cộng {1})',\n  },\n  fileUpload: {\n    title: 'Kéo và thả tệp vào đây',\n    divider: 'hoặc',\n    browse: 'Chọn tệp',\n  },\n  timePicker: {\n    am: 'SA',\n    pm: 'CH',\n    title: 'Chọn thời gian',\n    hour: 'Giờ',\n    minute: 'Phút',\n    second: 'Giây',\n    notAllowed: 'Giá trị không được phép',\n  },\n  pagination: {\n    ariaLabel: {\n      root: 'Điều hướng phân trang',\n      next: 'Trang tiếp theo',\n      previous: 'Trang trước',\n      page: 'Đến trang {0}',\n      currentPage: 'Trang hiện tại, Trang {0}',\n      first: 'Trang đầu tiên',\n      last: 'Trang cuối cùng',\n    },\n  },\n  stepper: {\n    next: 'Tiếp theo',\n    prev: 'Trước',\n  },\n  rating: {\n    ariaLabel: {\n      item: 'Đánh giá {0} trên {1}',\n    },\n  },\n  loading: 'Đang tải...',\n  infiniteScroll: {\n    loadMore: 'Tải thêm',\n    empty: 'Không còn dữ liệu',\n  },\n  rules: {\n    required: 'Trường này là bắt buộc',\n    email: 'Vui lòng nhập một email hợp lệ',\n    number: 'Trường này chỉ có thể chứa số',\n    integer: 'Trường này chỉ có thể chứa số nguyên',\n    capital: 'Trường này chỉ có thể chứa chữ cái in hoa',\n    maxLength: 'Bạn phải nhập tối đa {0} ký tự',\n    minLength: 'Bạn phải nhập tối thiểu {0} ký tự',\n    strictLength: 'Độ dài của trường đã nhập không hợp lệ',\n    exclude: 'Ký tự {0} không được phép',\n    notEmpty: 'Vui lòng chọn ít nhất một giá trị',\n    pattern: 'Định dạng không hợp lệ',\n  },\n  command: {\n    search: 'Nhập lệnh hoặc tìm kiếm...',\n  },\n  hotkey: {\n    then: 'sau đó',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: 'Mũi tên lên',\n    downArrow: 'Mũi tên xuống',\n    leftArrow: 'Mũi tên trái',\n    rightArrow: 'Mũi tên phải',\n    backspace: 'Backspace',\n    space: 'Khoảng trắng',\n    plus: 'cộng',\n    shortcut: 'Phím tắt: {0}',\n    or: 'hoặc',\n  },\n  video: {\n    play: 'Phát',\n    pause: 'Tạm dừng',\n    seek: 'Tìm kiếm',\n    volume: 'Âm lượng',\n    showVolume: 'Hiện điều khiển âm lượng',\n    mute: 'Tắt tiếng',\n    unmute: 'Bật tiếng',\n    enterFullscreen: 'Toàn màn hình',\n    exitFullscreen: 'Thoát toàn màn hình',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: 'Chọn màu từ màn hình',\n      hueSlider: 'Sắc độ',\n      alphaSlider: 'Độ trong suốt',\n      redInput: 'Đỏ',\n      greenInput: 'Xanh lục',\n      blueInput: 'Xanh lam',\n      alphaInput: 'Độ trong suốt',\n      hueInput: 'Sắc độ',\n      saturationInput: 'Độ bão hòa',\n      lightnessInput: 'Độ sáng',\n      hexInput: 'Giá trị HEX',\n      hexaInput: 'Giá trị HEX có độ trong suốt',\n      changeFormat: 'Thay đổi định dạng màu',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/zh-Hans.ts",
    "content": "export default {\n  badge: '徽章',\n  open: '打开',\n  close: '关闭',\n  dismiss: '取消',\n  confirmEdit: {\n    ok: '确定',\n    cancel: '取消',\n  },\n  dataIterator: {\n    noResultsText: '没有符合条件的结果',\n    loadingText: '加载中……',\n  },\n  dataTable: {\n    itemsPerPageText: '每页数目：',\n    ariaLabel: {\n      sortDescending: '：降序排列。',\n      sortAscending: '：升序排列。',\n      sortNone: '：未排序。',\n      activateNone: '点击以移除排序。',\n      activateDescending: '点击以降序排列。',\n      activateAscending: '点击以升序排列。',\n    },\n    sortBy: '排序方式',\n  },\n  dataFooter: {\n    itemsPerPageText: '每页数目：',\n    itemsPerPageAll: '全部',\n    nextPage: '下一页',\n    prevPage: '上一页',\n    firstPage: '首页',\n    lastPage: '尾页',\n    pageText: '{0}-{1} 共 {2}',\n  },\n  dateRangeInput: {\n    divider: '至',\n  },\n  datePicker: {\n    itemsSelected: '已选择 {0} 项',\n    range: {\n      title: '选择日期',\n      header: '输入日期',\n    },\n    title: '选择日期',\n    header: '输入日期',\n    input: {\n      placeholder: '输入日期',\n    },\n    ariaLabel: {\n      previousMonth: '上个月',\n      nextMonth: '下个月',\n      selectYear: '选择年份',\n      previousYear: '上一年',\n      nextYear: '下一年',\n      selectMonth: '选择月份',\n      selectDate: '{0}',\n      currentDate: '今天，{0}',\n    },\n  },\n  noDataText: '没有数据',\n  carousel: {\n    prev: '上一张',\n    next: '下一张',\n    ariaLabel: {\n      delimiter: '幻灯片 {0} / {1}',\n    },\n  },\n  calendar: {\n    moreEvents: '还有 {0} 项',\n    today: '今天',\n  },\n  input: {\n    clear: '清除 {0}',\n    prependAction: '{0} 前置操作',\n    appendAction: '{0} 后置操作',\n    otp: '请输入第 {0} 位 OTP',\n  },\n  fileInput: {\n    counter: '{0} 个文件',\n    counterSize: '{0} 个文件（共 {1}）',\n  },\n  fileUpload: {\n    title: '拖放文件到此处',\n    divider: '或',\n    browse: '浏览文件',\n  },\n  timePicker: {\n    am: '上午',\n    pm: '下午',\n    title: '选择时间',\n    hour: '小时',\n    minute: '分钟',\n    second: '秒',\n    notAllowed: '值不允许',\n  },\n  pagination: {\n    ariaLabel: {\n      root: '分页导航',\n      next: '下一页',\n      previous: '上一页',\n      page: '转到页面 {0}',\n      currentPage: '当前页 {0}',\n      first: '第一页',\n      last: '最后一页',\n    },\n  },\n  stepper: {\n    next: '下一步',\n    prev: '上一步',\n  },\n  rating: {\n    ariaLabel: {\n      item: '评分 {0} / {1}',\n    },\n  },\n  loading: '加载中...',\n  infiniteScroll: {\n    loadMore: '加载更多',\n    empty: '没有更多内容',\n  },\n  rules: {\n    required: '此字段为必填项',\n    email: '请输入有效的电子邮件地址',\n    number: '此字段只能包含数字',\n    integer: '此字段只能包含整数',\n    capital: '此字段只能包含大写字母',\n    maxLength: '您最多可以输入{0}个字符',\n    minLength: '您必须至少输入{0}个字符',\n    strictLength: '输入字段的长度无效',\n    exclude: '字符{0}是不允许的',\n    notEmpty: '请至少选择一个值',\n    pattern: '格式无效',\n  },\n  command: {\n    search: '输入命令或搜索...',\n  },\n  hotkey: {\n    then: '然后',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: '上箭头',\n    downArrow: '下箭头',\n    leftArrow: '左箭头',\n    rightArrow: '右箭头',\n    backspace: '退格',\n    space: '空格',\n    plus: '加',\n    shortcut: '键盘快捷键：{0}',\n    or: '或',\n  },\n  video: {\n    play: '播放',\n    pause: '暂停',\n    seek: '跳转',\n    volume: '音量',\n    showVolume: '显示音量控制',\n    mute: '静音',\n    unmute: '取消静音',\n    enterFullscreen: '全屏',\n    exitFullscreen: '退出全屏',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: '从屏幕拾取颜色',\n      hueSlider: '色相',\n      alphaSlider: '不透明度',\n      redInput: '红色',\n      greenInput: '绿色',\n      blueInput: '蓝色',\n      alphaInput: '不透明度',\n      hueInput: '色相',\n      saturationInput: '饱和度',\n      lightnessInput: '亮度',\n      hexInput: 'HEX 值',\n      hexaInput: '带不透明度 HEX 值',\n      changeFormat: '更改颜色格式',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/locale/zh-Hant.ts",
    "content": "export default {\n  badge: '徽章',\n  open: '開啟',\n  close: '關閉',\n  dismiss: '關閉',\n  confirmEdit: {\n    ok: '確定',\n    cancel: '取消',\n  },\n  dataIterator: {\n    noResultsText: '沒有符合條件的結果',\n    loadingText: '讀取中...',\n  },\n  dataTable: {\n    itemsPerPageText: '每頁列數：',\n    ariaLabel: {\n      sortDescending: '：降序排列。',\n      sortAscending: '：升序排列。',\n      sortNone: '無排序方式。點擊以升序排列。',\n      activateNone: '點擊以移除排序方式。',\n      activateDescending: '點擊以降序排列。',\n      activateAscending: '點擊以移除排序方式。',\n    },\n    sortBy: '排序方式',\n  },\n  dataFooter: {\n    itemsPerPageText: '每頁項目：',\n    itemsPerPageAll: '全部',\n    nextPage: '下一頁',\n    prevPage: '上一頁',\n    firstPage: '第一頁',\n    lastPage: '最後頁',\n    pageText: '{2} 條中的 {0}~{1} 條',\n  },\n  dateRangeInput: {\n    divider: '至',\n  },\n  datePicker: {\n    itemsSelected: '已選擇 {0} 個日期',\n    range: {\n      title: '選擇日期範圍',\n      header: '輸入日期範圍',\n    },\n    title: '選擇日期',\n    header: '輸入日期',\n    input: {\n      placeholder: '請輸入日期',\n    },\n    ariaLabel: {\n      previousMonth: '上個月',\n      nextMonth: '下個月',\n      selectYear: '選擇年份',\n      previousYear: '上一年',\n      nextYear: '下一年',\n      selectMonth: '選擇月份',\n      selectDate: '{0}',\n      currentDate: '今天，{0}',\n    },\n  },\n  noDataText: '沒有資料',\n  carousel: {\n    prev: '上一張',\n    next: '下一張',\n    ariaLabel: {\n      delimiter: '第 {0} 張 / 共 {1} 張',\n    },\n  },\n  calendar: {\n    moreEvents: '還有其他 {0} 項',\n    today: '今天',\n  },\n  input: {\n    clear: '清除 {0}',\n    prependAction: '{0} 前置操作',\n    appendAction: '{0} 附加操作',\n    otp: '請輸入第 {0} 個 OTP 字元',\n  },\n  fileInput: {\n    counter: '{0} 個檔案',\n    counterSize: '{0} 個檔案（共 {1}）',\n  },\n  fileUpload: {\n    title: '拖曳檔案至此',\n    divider: '或',\n    browse: '瀏覽檔案',\n  },\n  timePicker: {\n    am: '上午',\n    pm: '下午',\n    title: '選擇時間',\n    hour: '小時',\n    minute: '分鐘',\n    second: '秒',\n    notAllowed: '值不允許',\n  },\n  pagination: {\n    ariaLabel: {\n      root: '分頁導航',\n      next: '下一頁',\n      previous: '上一頁',\n      page: '轉到頁面 {0}',\n      currentPage: '當前頁 {0}',\n      first: '第一頁',\n      last: '最後一頁',\n    },\n  },\n  stepper: {\n    next: '下一步',\n    prev: '上一步',\n  },\n  rating: {\n    ariaLabel: {\n      item: '評分 {0} / {1}',\n    },\n  },\n  loading: '載入中...',\n  infiniteScroll: {\n    loadMore: '載入更多',\n    empty: '沒有更多內容',\n  },\n  rules: {\n    required: '此欄位為必填項',\n    email: '請輸入有效的電子郵件地址',\n    number: '此欄位只能包含數字',\n    integer: '此欄位只能包含整數',\n    capital: '此欄位只能包含大寫字母',\n    maxLength: '您最多可以輸入{0}個字符',\n    minLength: '您必須至少輸入{0}個字符',\n    strictLength: '輸入欄位的長度無效',\n    exclude: '字符{0}是不允許的',\n    notEmpty: '請至少選擇一個值',\n    pattern: '格式無效',\n  },\n  command: {\n    search: '輸入指令或搜尋...',\n  },\n  hotkey: {\n    then: '然後',\n    ctrl: 'Ctrl',\n    command: 'Command',\n    shift: 'Shift',\n    alt: 'Alt',\n    option: 'Option',\n    enter: 'Enter',\n    escape: 'Escape',\n    upArrow: '上箭頭',\n    downArrow: '下箭頭',\n    leftArrow: '左箭頭',\n    rightArrow: '右箭頭',\n    backspace: '退格',\n    space: '空格',\n    plus: '加',\n    shortcut: '鍵盤快捷鍵：{0}',\n    or: '或',\n  },\n  video: {\n    play: '播放',\n    pause: '暫停',\n    seek: '搜尋',\n    volume: '音量',\n    showVolume: '顯示音量控制',\n    mute: '靜音',\n    unmute: '取消靜音',\n    enterFullscreen: '全螢幕',\n    exitFullscreen: '退出全螢幕',\n  },\n  colorPicker: {\n    ariaLabel: {\n      eyedropper: '從螢幕上選取顏色',\n      hueSlider: '色相',\n      alphaSlider: '透明度',\n      redInput: '紅色',\n      greenInput: '綠色',\n      blueInput: '藍色',\n      alphaInput: '透明度',\n      hueInput: '色相',\n      saturationInput: '飽和度',\n      lightnessInput: '亮度',\n      hexInput: '十六進位值',\n      hexaInput: '帶透明度的十六進位值',\n      changeFormat: '變更顏色格式',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/src/shims.d.ts",
    "content": "/* eslint-disable local-rules/sort-imports */\n\nimport 'vue/jsx'\nimport type { UnwrapNestedRefs, VNodeChild } from 'vue'\n\n// These already exist in scope in the final bundle\n// @skip-build\nimport type {\n  DateInstance,\n  DefaultsInstance,\n  DisplayInstance,\n  IconOptions,\n  LocaleInstance,\n  RtlInstance,\n  ThemeInstance,\n} from './framework'\n\ndeclare global {\n  namespace JSX {\n    interface ElementChildrenAttribute {\n      $children: {}\n    }\n  }\n}\n\ndeclare module 'vue' {\n  interface Vuetify {\n    defaults: DefaultsInstance\n    display: UnwrapNestedRefs<DisplayInstance>\n    theme: UnwrapNestedRefs<ThemeInstance>\n    icons: IconOptions\n    locale: UnwrapNestedRefs<LocaleInstance & RtlInstance>\n    date: DateInstance\n  }\n\n  export interface ComponentCustomProperties {\n    $vuetify: Vuetify\n  }\n  export interface HTMLAttributes {\n    $children?: VNodeChild\n  }\n  export interface SVGAttributes {\n    $children?: VNodeChild\n  }\n  export interface GlobalComponents {\n    // @generate-components\n  }\n  export interface GlobalDirectives {\n    // @generate-directives\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/styles/colors.scss",
    "content": "@use './generic/colors';\n"
  },
  {
    "path": "packages/vuetify/src/styles/core.scss",
    "content": "@forward './settings';\n\n@use './generic/layers';\n@use './generic/animations';\n@use './generic/reset';\n@use './generic/transitions';\n@use './generic/rtl';\n\n@use './elements/blockquote';\n@use './elements/global';\n"
  },
  {
    "path": "packages/vuetify/src/styles/elements/_blockquote.sass",
    "content": "@use '../settings'\n@use '../tools'\n\n@include tools.layer('components')\n  .blockquote\n    margin: 0\n    padding: settings.$spacer*4 0 settings.$spacer*4 settings.$spacer*6\n    font-size: settings.$blockquote-font-size\n    font-weight: settings.$blockquote-font-weight\n"
  },
  {
    "path": "packages/vuetify/src/styles/elements/_global.sass",
    "content": "@use '../settings'\n@use '../tools'\n\n@include tools.layer('core.base')\n  html\n    font-family: settings.$body-font-family\n    line-height: settings.$line-height-root\n    font-size: settings.$font-size-root\n    overflow-x: hidden\n    text-rendering: optimizeLegibility\n    -webkit-font-smoothing: antialiased\n    -moz-osx-font-smoothing: grayscale\n    -webkit-tap-highlight-color: rgba(0, 0, 0, 0)\n\n  html.overflow-y-hidden\n    overflow-y: hidden\n\n  :root\n    --v-theme-overlay-multiplier: 1\n    --v-scrollbar-offset: 0px\n\n  // iOS Safari hack to allow click events on body\n  @supports (-webkit-touch-callout: none)\n    body\n      cursor: pointer\n"
  },
  {
    "path": "packages/vuetify/src/styles/elements/_index.sass",
    "content": "@use './blockquote'\n@use './global'\n"
  },
  {
    "path": "packages/vuetify/src/styles/generic/_animations.scss",
    "content": "@use '../tools';\n\n@include tools.layer('transitions') {\n  @keyframes v-shake {\n    59% {\n      margin-left: 0;\n    }\n\n    60%, 80% {\n      margin-left: 2px;\n    }\n\n    70%, 90% {\n      margin-left: -2px;\n    }\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/styles/generic/_colors.scss",
    "content": "@use 'sass:map';\n@use '../settings';\n@use '../settings/colors';\n@use '../tools';\n@use '../tools/functions' as *;\n\n@mixin background-color($color_value) {\n  & {\n    background-color: $color_value;\n  }\n}\n@mixin text-color($color_value) {\n  & {\n    color: $color_value;\n  }\n}\n@mixin background-text-color($color_name, $color_type) {\n  $map_value: map-deep-get(colors.$text-on-colors, $color_name, $color_type);\n\n  & {\n    color: $map_value;\n  }\n}\n\n@if (settings.$color-pack) {\n  @include tools.layer('utilities.theme-background') {\n    @each $color_name, $color_value in colors.$shades {\n      .bg-#{$color_name} {\n        @include background-color($color_value);\n\n        @if (map.has-key(colors.$text-on-colors, 'shades')) {\n          @include background-text-color('shades', $color_name);\n        }\n      }\n    }\n\n    @each $color_name, $color_color in colors.$colors {\n      @each $color_type, $color_value in $color_color {\n        @if ($color_type == 'base') {\n          .bg-#{$color_name} {\n            @include background-color($color_value);\n\n            @if (map.has-key(colors.$text-on-colors, $color_name)) {\n              @include background-text-color($color_name, $color_type);\n            }\n          }\n        } @else if ($color_type != 'shades') {\n          .bg-#{$color_name}-#{$color_type} {\n            @include background-color($color_value);\n\n            @if (map.has-key(colors.$text-on-colors, $color_name)) {\n              @include background-text-color($color_name, $color_type);\n            }\n          }\n        }\n      }\n    }\n  }\n\n  @include tools.layer('utilities.theme-foreground') {\n    @each $color_name, $color_value in colors.$shades {\n      .text-#{$color_name} {\n        @include text-color($color_value);\n      }\n    }\n\n    @each $color_name, $color_color in colors.$colors {\n      @each $color_type, $color_value in $color_color {\n        @if ($color_type == 'base') {\n          .text-#{$color_name} {\n            @include text-color($color_value);\n          }\n        } @else if ($color_type != 'shades') {\n          .text-#{$color_name}-#{$color_type} {\n            @include text-color($color_value);\n          }\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/styles/generic/_index.scss",
    "content": "@use './layers';\n@use './animations';\n@use './theme';\n@use './colors';\n@use './reset';\n@use './transitions';\n@use './rtl';\n"
  },
  {
    "path": "packages/vuetify/src/styles/generic/_layers.scss",
    "content": "@use '../settings';\n\n@layer vuetify-core {\n  @layer reset, base;\n}\n\n@layer vuetify-components;\n\n// Contextual styles for nested components\n// This replaces hacks like .v-btn.v-btn and most of !important\n@layer vuetify-overrides;\n\n@layer vuetify-utilities {\n  @layer theme-base;\n  @layer typography;\n  @layer helpers;\n  @layer theme-background;\n  @layer theme-foreground;\n}\n\n// Rules that need to override theme or utils\n@layer vuetify-final {\n  @layer transitions, trumps;\n};\n"
  },
  {
    "path": "packages/vuetify/src/styles/generic/_reset.scss",
    "content": "@use '../settings';\n@use '../tools';\n\n@if (settings.$reset) {\n  @include tools.layer('core.reset') {\n    html {\n      box-sizing: border-box;\n      /* Prevent adjustments of font size after orientation changes in iOS */\n      -webkit-text-size-adjust: 100%;\n      tab-size: 4;\n      margin: 0;\n    }\n\n    body {\n      margin: 0;\n    }\n\n    *,\n    ::before,\n    ::after {\n      background-repeat: no-repeat;\n      box-sizing: inherit;\n    }\n\n    ::before,\n    ::after {\n      text-decoration: inherit;\n      vertical-align: inherit;\n    }\n\n\n    input {\n      border-radius: 0;\n    }\n\n    /* Replace pointer cursor in disabled elements */\n    [disabled] {\n      cursor: default;\n    }\n\n    [type=\"number\"]::-webkit-inner-spin-button,\n    [type=\"number\"]::-webkit-outer-spin-button {\n      /* Correct the cursor style of increment and decrement buttons in Chrome */\n      height: auto;\n    }\n\n    [type=\"search\"] {\n      -webkit-appearance: textfield; /* Correct the odd appearance in Chrome and Safari */\n      outline-offset: -2px; /* Correct the outline style in Safari */\n    }\n\n    [type=\"search\"]::-webkit-search-cancel-button,\n    [type=\"search\"]::-webkit-search-decoration {\n      /* Remove the inner padding in Chrome and Safari on macOS */\n      -webkit-appearance: none;\n    }\n\n    button,\n    input,\n    optgroup,\n    select,\n    textarea {\n      font: inherit;\n    }\n\n    optgroup {\n      /* Restore the font weight unset by the previous rule */\n      font-weight: bold;\n    }\n\n    /* Apply cursor pointer to button elements */\n    button,\n    [type=\"button\"],\n    [type=\"reset\"],\n    [type=\"submit\"],\n    [role=\"button\"] {\n      cursor: pointer;\n      color: inherit;\n    }\n\n    /* Specify the progress cursor of updating elements */\n    [aria-busy=\"true\"] {\n      cursor: progress;\n    }\n\n    /* Specify the pointer cursor of trigger elements */\n    [aria-controls] {\n      cursor: pointer;\n    }\n\n    /* Specify the unstyled cursor of disabled, not-editable, or otherwise inoperable elements */\n    [aria-disabled=\"true\"] {\n      cursor: default;\n    }\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/styles/generic/_rtl.scss",
    "content": "@use '../tools';\n\n@include tools.layer('core.base') {\n  .v-locale {\n    &--is-rtl {\n      direction: rtl;\n    }\n\n    &--is-ltr {\n      direction: ltr;\n    }\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/styles/generic/_theme.scss",
    "content": "@use '../tools';\n\n@include tools.layer('utilities.theme-base') {\n  .v-theme-on-light {\n    color: rgb(var(--v-theme-on-light));\n  }\n  .v-theme-on-dark {\n    color: rgb(var(--v-theme-on-dark));\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/styles/generic/_transitions.scss",
    "content": "@use '../settings';\n@use '../tools';\n\n@mixin transition-default() {\n  &-enter-active {\n    transition-duration: settings.$transition-duration-root;\n    transition-timing-function: settings.$standard-easing;\n  }\n\n  &-leave-active {\n    transition-duration: settings.$transition-duration-root;\n    transition-timing-function: settings.$standard-easing;\n  }\n\n  &-move {\n    transition-duration: settings.$transition-move-duration-root;\n    transition-property: transform;\n    transition-timing-function: settings.$standard-easing;\n  }\n}\n@mixin fade-out() {\n  &-leave-to {\n    opacity: 0;\n  }\n  &-leave-active {\n    transition-duration: 100ms;\n  }\n}\n\n@include tools.layer('transitions') {\n  @media (prefers-reduced-motion: no-preference) {\n    // Component specific transitions\n    .dialog-transition,\n    .dialog-bottom-transition,\n    .dialog-top-transition {\n      &-enter-active {\n        transition-duration: 225ms;\n        transition-timing-function: settings.$decelerated-easing;\n      }\n\n      &-leave-active {\n        transition-duration: 125ms;\n        transition-timing-function: settings.$accelerated-easing;\n      }\n\n      &-enter-active,\n      &-leave-active {\n        transition-property: transform, opacity;\n        pointer-events: none;\n      }\n    }\n\n    .dialog-transition {\n      &-enter-from, &-leave-to {\n        transform: scale(0.9);\n        opacity: 0;\n      }\n\n      &-enter-to, &-leave-from {\n        opacity: 1;\n      }\n    }\n\n    .dialog-bottom-transition {\n      &-enter-from, &-leave-to {\n        transform: translateY(calc(50vh + 50%));\n      }\n    }\n\n    .dialog-top-transition {\n      &-enter-from, &-leave-to {\n        transform: translateY(calc(-50vh - 50%));\n      }\n    }\n\n    .picker-transition,\n    .picker-reverse-transition {\n      @include transition-default();\n\n      &-enter-from,\n      &-leave-to {\n        opacity: 0;\n      }\n\n      &-leave-from,\n      &-leave-active,\n      &-leave-to {\n        position: absolute;\n      }\n\n      &-enter-active,\n      &-leave-active {\n        transition-property: transform, opacity;\n      }\n    }\n\n    .picker-transition {\n      @include transition-default();\n\n      &-enter-from {\n        transform: translate(100%, 0);\n      }\n\n      &-leave-to {\n        transform: translate(-100%, 0);\n      }\n    }\n\n    .picker-reverse-transition {\n      @include transition-default();\n\n      &-enter-from {\n        transform: translate(-100%, 0);\n      }\n\n      &-leave-to {\n        transform: translate(100%, 0);\n      }\n    }\n\n    // Generic transitions\n    .expand-transition {\n      @include transition-default();\n\n      &-enter-active,\n      &-leave-active {\n        transition-property: height;\n      }\n    }\n\n    .expand-x-transition {\n      @include transition-default();\n\n      &-enter-active,\n      &-leave-active {\n        transition-property: width;\n      }\n    }\n\n    .expand-both-transition {\n      @include transition-default();\n\n      &-enter-active,\n      &-leave-active {\n        transition-property: height, width !important;\n      }\n    }\n\n    .scale-transition {\n      @include transition-default();\n      @include fade-out();\n\n      &-enter-from {\n        opacity: 0;\n        transform: scale(0);\n      }\n\n      &-enter-active,\n      &-leave-active {\n        transition-property: transform, opacity;\n      }\n    }\n\n    .scale-rotate-transition {\n      @include transition-default();\n      @include fade-out();\n\n      &-enter-from {\n        opacity: 0;\n        transform: scale(0) rotate(-45deg);\n      }\n\n      &-enter-active,\n      &-leave-active {\n        transition-property: transform, opacity;\n      }\n    }\n\n    .scale-rotate-reverse-transition {\n      @include transition-default();\n      @include fade-out();\n\n      &-enter-from {\n        opacity: 0;\n        transform: scale(0) rotate(45deg);\n      }\n\n      &-enter-active,\n      &-leave-active {\n        transition-property: transform, opacity;\n      }\n    }\n\n    .message-transition {\n      @include transition-default();\n\n      &-enter-from, &-leave-to {\n        opacity: 0;\n        transform: translateY(-15px);\n      }\n\n      &-leave-from, &-leave-active {\n        position: absolute;\n      }\n\n      &-enter-active,\n      &-leave-active {\n        transition-property: transform, opacity;\n      }\n    }\n\n    .slide-y-transition {\n      @include transition-default();\n\n      &-enter-from, &-leave-to {\n        opacity: 0;\n        transform: translateY(-15px);\n      }\n\n      &-enter-active,\n      &-leave-active {\n        transition-property: transform, opacity;\n      }\n    }\n\n    .slide-y-reverse-transition {\n      @include transition-default();\n\n      &-enter-from, &-leave-to {\n        opacity: 0;\n        transform: translateY(15px);\n      }\n\n      &-enter-active,\n      &-leave-active {\n        transition-property: transform, opacity;\n      }\n    }\n\n    .scroll-y-transition {\n      @include transition-default();\n\n      &-enter-from, &-leave-to {\n        opacity: 0;\n      }\n\n      &-enter-from {\n        transform: translateY(-15px);\n      }\n\n      &-leave-to {\n        transform: translateY(15px);\n      }\n\n      &-enter-active,\n      &-leave-active {\n        transition-property: transform, opacity;\n      }\n    }\n\n    .scroll-y-reverse-transition {\n      @include transition-default();\n\n      &-enter-from, &-leave-to {\n        opacity: 0;\n      }\n\n      &-enter-from {\n        transform: translateY(15px);\n      }\n\n      &-leave-to {\n        transform: translateY(-15px);\n      }\n\n      &-enter-active,\n      &-leave-active {\n        transition-property: transform, opacity;\n      }\n    }\n\n    .scroll-x-transition {\n      @include transition-default();\n\n      &-enter-from, &-leave-to {\n        opacity: 0;\n      }\n\n      &-enter-from {\n        transform: translateX(-15px);\n      }\n\n      &-leave-to {\n        transform: translateX(15px);\n      }\n\n      &-enter-active,\n      &-leave-active {\n        transition-property: transform, opacity;\n      }\n    }\n\n    .scroll-x-reverse-transition {\n      @include transition-default();\n\n      &-enter-from, &-leave-to {\n        opacity: 0;\n      }\n\n      &-enter-from {\n        transform: translateX(15px);\n      }\n\n      &-leave-to {\n        transform: translateX(-15px);\n      }\n\n      &-enter-active,\n      &-leave-active {\n        transition-property: transform, opacity;\n      }\n    }\n\n    .slide-x-transition {\n      @include transition-default();\n\n      &-enter-from, &-leave-to {\n        opacity: 0;\n        transform: translateX(-15px);\n      }\n\n      &-enter-active,\n      &-leave-active {\n        transition-property: transform, opacity;\n      }\n    }\n\n    .slide-x-reverse-transition {\n      @include transition-default();\n\n      &-enter-from, &-leave-to {\n        opacity: 0;\n        transform: translateX(15px);\n      }\n\n      &-enter-active,\n      &-leave-active {\n        transition-property: transform, opacity;\n      }\n    }\n\n    .fade-transition {\n      @include transition-default();\n\n      &-enter-from, &-leave-to {\n        opacity: 0;\n      }\n\n      &-enter-active,\n      &-leave-active {\n        transition-property: opacity;\n      }\n    }\n\n    .fab-transition {\n      @include transition-default();\n\n      &-enter-from, &-leave-to {\n        transform: scale(0) rotate(-45deg);\n      }\n\n      &-enter-active,\n      &-leave-active {\n        transition-property: transform;\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/styles/main.sass",
    "content": "// Modeled after ITCSS https://www.xfive.co/blog/itcss-scalable-maintainable-css-architecture/\n\n@forward './settings'\n@use './generic'\n@use './elements'\n@use './utilities/index'\n"
  },
  {
    "path": "packages/vuetify/src/styles/settings/_colors.scss",
    "content": "@use 'sass:map';\n@use '../tools/functions' as *;\n\n$shades: () !default;\n$shades: map-deep-merge(\n  (\n    'black': #000000,\n    'white': #FFFFFF,\n    'transparent': transparent\n  ),\n  $shades\n);\n\n$text-on-shades: () !default;\n$text-on-shades: map-deep-merge(\n  (\n    'black': map.get($shades, 'white'),\n    'white': map.get($shades, 'black'),\n    'transparent': currentColor\n  ),\n  $text-on-shades\n);\n\n$red: () !default;\n$red: map-deep-merge(\n  (\n    'base': #F44336,\n    'lighten-5': #FFEBEE,\n    'lighten-4': #FFCDD2,\n    'lighten-3': #EF9A9A,\n    'lighten-2': #E57373,\n    'lighten-1': #EF5350,\n    'darken-1': #E53935,\n    'darken-2': #D32F2F,\n    'darken-3': #C62828,\n    'darken-4': #B71C1C,\n    'accent-1': #FF8A80,\n    'accent-2': #FF5252,\n    'accent-3': #FF1744,\n    'accent-4': #D50000\n  ),\n  $red\n);\n\n$text-on-red: () !default;\n$text-on-red: map-deep-merge(\n  (\n    'base': map.get($shades, 'white'),\n    'lighten-5': map.get($shades, 'black'),\n    'lighten-4': map.get($shades, 'black'),\n    'lighten-3': map.get($shades, 'black'),\n    'lighten-2': map.get($shades, 'white'),\n    'lighten-1': map.get($shades, 'white'),\n    'darken-1': map.get($shades, 'white'),\n    'darken-2': map.get($shades, 'white'),\n    'darken-3': map.get($shades, 'white'),\n    'darken-4': map.get($shades, 'white'),\n    'accent-1': map.get($shades, 'black'),\n    'accent-2': map.get($shades, 'white'),\n    'accent-3': map.get($shades, 'white'),\n    'accent-4': map.get($shades, 'white')\n  ),\n  $text-on-red\n);\n\n$pink: () !default;\n$pink: map-deep-merge(\n  (\n    'base': #e91e63,\n    'lighten-5': #fce4ec,\n    'lighten-4': #f8bbd0,\n    'lighten-3': #f48fb1,\n    'lighten-2': #f06292,\n    'lighten-1': #ec407a,\n    'darken-1': #d81b60,\n    'darken-2': #c2185b,\n    'darken-3': #ad1457,\n    'darken-4': #880e4f,\n    'accent-1': #ff80ab,\n    'accent-2': #ff4081,\n    'accent-3': #f50057,\n    'accent-4': #c51162\n  ),\n  $pink\n);\n\n$text-on-pink: () !default;\n$text-on-pink: map-deep-merge(\n  (\n    'base': map.get($shades, 'white'),\n    'lighten-5': map.get($shades, 'black'),\n    'lighten-4': map.get($shades, 'black'),\n    'lighten-3': map.get($shades, 'black'),\n    'lighten-2': map.get($shades, 'white'),\n    'lighten-1': map.get($shades, 'white'),\n    'darken-1': map.get($shades, 'white'),\n    'darken-2': map.get($shades, 'white'),\n    'darken-3': map.get($shades, 'white'),\n    'darken-4': map.get($shades, 'white'),\n    'accent-1': map.get($shades, 'white'),\n    'accent-2': map.get($shades, 'white'),\n    'accent-3': map.get($shades, 'white'),\n    'accent-4': map.get($shades, 'white')\n  ),\n  $text-on-pink\n);\n\n$purple: () !default;\n$purple: map-deep-merge(\n  (\n    'base': #9c27b0,\n    'lighten-5': #f3e5f5,\n    'lighten-4': #e1bee7,\n    'lighten-3': #ce93d8,\n    'lighten-2': #ba68c8,\n    'lighten-1': #ab47bc,\n    'darken-1': #8e24aa,\n    'darken-2': #7b1fa2,\n    'darken-3': #6a1b9a,\n    'darken-4': #4a148c,\n    'accent-1': #ea80fc,\n    'accent-2': #e040fb,\n    'accent-3': #d500f9,\n    'accent-4': #aa00ff\n  ),\n  $purple\n);\n\n$text-on-purple: () !default;\n$text-on-purple: map-deep-merge(\n  (\n    'base': map.get($shades, 'white'),\n    'lighten-5': map.get($shades, 'black'),\n    'lighten-4': map.get($shades, 'black'),\n    'lighten-3': map.get($shades, 'white'),\n    'lighten-2': map.get($shades, 'white'),\n    'lighten-1': map.get($shades, 'white'),\n    'darken-1': map.get($shades, 'white'),\n    'darken-2': map.get($shades, 'white'),\n    'darken-3': map.get($shades, 'white'),\n    'darken-4': map.get($shades, 'white'),\n    'accent-1': map.get($shades, 'white'),\n    'accent-2': map.get($shades, 'white'),\n    'accent-3': map.get($shades, 'white'),\n    'accent-4': map.get($shades, 'white')\n  ),\n  $text-on-purple\n);\n\n$deep-purple: () !default;\n$deep-purple: map-deep-merge(\n  (\n    'base': #673ab7,\n    'lighten-5': #ede7f6,\n    'lighten-4': #d1c4e9,\n    'lighten-3': #b39ddb,\n    'lighten-2': #9575cd,\n    'lighten-1': #7e57c2,\n    'darken-1': #5e35b1,\n    'darken-2': #512da8,\n    'darken-3': #4527a0,\n    'darken-4': #311b92,\n    'accent-1': #b388ff,\n    'accent-2': #7c4dff,\n    'accent-3': #651fff,\n    'accent-4': #6200ea\n  ),\n  $deep-purple\n);\n\n$text-on-deep-purple: () !default;\n$text-on-deep-purple: map-deep-merge(\n  (\n    'base': map.get($shades, 'white'),\n    'lighten-5': map.get($shades, 'black'),\n    'lighten-4': map.get($shades, 'black'),\n    'lighten-3': map.get($shades, 'white'),\n    'lighten-2': map.get($shades, 'white'),\n    'lighten-1': map.get($shades, 'white'),\n    'darken-1': map.get($shades, 'white'),\n    'darken-2': map.get($shades, 'white'),\n    'darken-3': map.get($shades, 'white'),\n    'darken-4': map.get($shades, 'white'),\n    'accent-1': map.get($shades, 'white'),\n    'accent-2': map.get($shades, 'white'),\n    'accent-3': map.get($shades, 'white'),\n    'accent-4': map.get($shades, 'white')\n  ),\n  $text-on-deep-purple\n);\n\n$indigo: () !default;\n$indigo: map-deep-merge(\n  (\n    'base': #3f51b5,\n    'lighten-5': #e8eaf6,\n    'lighten-4': #c5cae9,\n    'lighten-3': #9fa8da,\n    'lighten-2': #7986cb,\n    'lighten-1': #5c6bc0,\n    'darken-1': #3949ab,\n    'darken-2': #303f9f,\n    'darken-3': #283593,\n    'darken-4': #1a237e,\n    'accent-1': #8c9eff,\n    'accent-2': #536dfe,\n    'accent-3': #3d5afe,\n    'accent-4': #304ffe\n  ),\n  $indigo\n);\n\n$text-on-indigo: () !default;\n$text-on-indigo: map-deep-merge(\n  (\n    'base': map.get($shades, 'white'),\n    'lighten-5': map.get($shades, 'black'),\n    'lighten-4': map.get($shades, 'black'),\n    'lighten-3': map.get($shades, 'white'),\n    'lighten-2': map.get($shades, 'white'),\n    'lighten-1': map.get($shades, 'white'),\n    'darken-1': map.get($shades, 'white'),\n    'darken-2': map.get($shades, 'white'),\n    'darken-3': map.get($shades, 'white'),\n    'darken-4': map.get($shades, 'white'),\n    'accent-1': map.get($shades, 'white'),\n    'accent-2': map.get($shades, 'white'),\n    'accent-3': map.get($shades, 'white'),\n    'accent-4': map.get($shades, 'white')\n  ),\n  $text-on-indigo\n);\n\n$blue: () !default;\n$blue: map-deep-merge(\n  (\n    'base': #2196F3,\n    'lighten-5': #E3F2FD,\n    'lighten-4': #BBDEFB,\n    'lighten-3': #90CAF9,\n    'lighten-2': #64B5F6,\n    'lighten-1': #42A5F5,\n    'darken-1': #1E88E5,\n    'darken-2': #1976D2,\n    'darken-3': #1565C0,\n    'darken-4': #0D47A1,\n    'accent-1': #82B1FF,\n    'accent-2': #448AFF,\n    'accent-3': #2979FF,\n    'accent-4': #2962FF,\n  ),\n  $blue\n);\n\n$text-on-blue: () !default;\n$text-on-blue: map-deep-merge(\n  (\n    'base': map.get($shades, 'white'),\n    'lighten-5': map.get($shades, 'black'),\n    'lighten-4': map.get($shades, 'black'),\n    'lighten-3': map.get($shades, 'black'),\n    'lighten-2': map.get($shades, 'black'),\n    'lighten-1': map.get($shades, 'white'),\n    'darken-1': map.get($shades, 'white'),\n    'darken-2': map.get($shades, 'white'),\n    'darken-3': map.get($shades, 'white'),\n    'darken-4': map.get($shades, 'white'),\n    'accent-1': map.get($shades, 'black'),\n    'accent-2': map.get($shades, 'white'),\n    'accent-3': map.get($shades, 'white'),\n    'accent-4': map.get($shades, 'white')\n  ),\n  $text-on-blue\n);\n\n$light-blue: () !default;\n$light-blue: map-deep-merge(\n  (\n    'base': #03a9f4,\n    'lighten-5': #e1f5fe,\n    'lighten-4': #b3e5fc,\n    'lighten-3': #81d4fa,\n    'lighten-2': #4fc3f7,\n    'lighten-1': #29b6f6,\n    'darken-1': #039be5,\n    'darken-2': #0288d1,\n    'darken-3': #0277bd,\n    'darken-4': #01579b,\n    'accent-1': #80d8ff,\n    'accent-2': #40c4ff,\n    'accent-3': #00b0ff,\n    'accent-4': #0091ea\n  ),\n  $light-blue\n);\n\n$text-on-light-blue: () !default;\n$text-on-light-blue: map-deep-merge(\n  (\n    'base': map.get($shades, 'white'),\n    'lighten-5': map.get($shades, 'black'),\n    'lighten-4': map.get($shades, 'black'),\n    'lighten-3': map.get($shades, 'black'),\n    'lighten-2': map.get($shades, 'black'),\n    'lighten-1': map.get($shades, 'black'),\n    'darken-1': map.get($shades, 'white'),\n    'darken-2': map.get($shades, 'white'),\n    'darken-3': map.get($shades, 'white'),\n    'darken-4': map.get($shades, 'white'),\n    'accent-1': map.get($shades, 'black'),\n    'accent-2': map.get($shades, 'black'),\n    'accent-3': map.get($shades, 'white'),\n    'accent-4': map.get($shades, 'white')\n  ),\n  $text-on-light-blue\n);\n\n$cyan: () !default;\n$cyan: map-deep-merge(\n  (\n    'base': #00bcd4,\n    'lighten-5': #e0f7fa,\n    'lighten-4': #b2ebf2,\n    'lighten-3': #80deea,\n    'lighten-2': #4dd0e1,\n    'lighten-1': #26c6da,\n    'darken-1': #00acc1,\n    'darken-2': #0097a7,\n    'darken-3': #00838f,\n    'darken-4': #006064,\n    'accent-1': #84ffff,\n    'accent-2': #18ffff,\n    'accent-3': #00e5ff,\n    'accent-4': #00b8d4\n  ),\n  $cyan\n);\n\n$text-on-cyan: () !default;\n$text-on-cyan: map-deep-merge(\n  (\n    'base': map.get($shades, 'black'),\n    'lighten-5': map.get($shades, 'black'),\n    'lighten-4': map.get($shades, 'black'),\n    'lighten-3': map.get($shades, 'black'),\n    'lighten-2': map.get($shades, 'black'),\n    'lighten-1': map.get($shades, 'black'),\n    'darken-1': map.get($shades, 'white'),\n    'darken-2': map.get($shades, 'white'),\n    'darken-3': map.get($shades, 'white'),\n    'darken-4': map.get($shades, 'white'),\n    'accent-1': map.get($shades, 'black'),\n    'accent-2': map.get($shades, 'black'),\n    'accent-3': map.get($shades, 'black'),\n    'accent-4': map.get($shades, 'white')\n  ),\n  $text-on-cyan\n);\n\n$teal: () !default;\n$teal: map-deep-merge(\n  (\n    'base': #009688,\n    'lighten-5': #e0f2f1,\n    'lighten-4': #b2dfdb,\n    'lighten-3': #80cbc4,\n    'lighten-2': #4db6ac,\n    'lighten-1': #26a69a,\n    'darken-1': #00897b,\n    'darken-2': #00796b,\n    'darken-3': #00695c,\n    'darken-4': #004d40,\n    'accent-1': #a7ffeb,\n    'accent-2': #64ffda,\n    'accent-3': #1de9b6,\n    'accent-4': #00bfa5\n  ),\n  $teal\n);\n\n$text-on-teal: () !default;\n$text-on-teal: map-deep-merge(\n  (\n    'base': map.get($shades, 'white'),\n    'lighten-5': map.get($shades, 'black'),\n    'lighten-4': map.get($shades, 'black'),\n    'lighten-3': map.get($shades, 'black'),\n    'lighten-2': map.get($shades, 'white'),\n    'lighten-1': map.get($shades, 'white'),\n    'darken-1': map.get($shades, 'white'),\n    'darken-2': map.get($shades, 'white'),\n    'darken-3': map.get($shades, 'white'),\n    'darken-4': map.get($shades, 'white'),\n    'accent-1': map.get($shades, 'black'),\n    'accent-2': map.get($shades, 'black'),\n    'accent-3': map.get($shades, 'black'),\n    'accent-4': map.get($shades, 'white')\n  ),\n  $text-on-teal\n);\n\n$green: () !default;\n$green: map-deep-merge(\n  (\n    'base': #4CAF50,\n    'lighten-5': #E8F5E9,\n    'lighten-4': #C8E6C9,\n    'lighten-3': #A5D6A7,\n    'lighten-2': #81C784,\n    'lighten-1': #66BB6A,\n    'darken-1': #43A047,\n    'darken-2': #388E3C,\n    'darken-3': #2E7D32,\n    'darken-4': #1B5E20,\n    'accent-1': #B9F6CA,\n    'accent-2': #69F0AE,\n    'accent-3': #00E676,\n    'accent-4': #00C853\n  ),\n  $green\n);\n\n$text-on-green: () !default;\n$text-on-green: map-deep-merge(\n  (\n    'base': map.get($shades, 'white'),\n    'lighten-5': map.get($shades, 'black'),\n    'lighten-4': map.get($shades, 'black'),\n    'lighten-3': map.get($shades, 'black'),\n    'lighten-2': map.get($shades, 'black'),\n    'lighten-1': map.get($shades, 'white'),\n    'darken-1': map.get($shades, 'white'),\n    'darken-2': map.get($shades, 'white'),\n    'darken-3': map.get($shades, 'white'),\n    'darken-4': map.get($shades, 'white'),\n    'accent-1': map.get($shades, 'black'),\n    'accent-2': map.get($shades, 'black'),\n    'accent-3': map.get($shades, 'black'),\n    'accent-4': map.get($shades, 'black')\n  ),\n  $text-on-green\n);\n\n$light-green: () !default;\n$light-green: map-deep-merge(\n  (\n    'base': #8bc34a,\n    'lighten-5': #f1f8e9,\n    'lighten-4': #dcedc8,\n    'lighten-3': #c5e1a5,\n    'lighten-2': #aed581,\n    'lighten-1': #9ccc65,\n    'darken-1': #7cb342,\n    'darken-2': #689f38,\n    'darken-3': #558b2f,\n    'darken-4': #33691e,\n    'accent-1': #ccff90,\n    'accent-2': #b2ff59,\n    'accent-3': #76ff03,\n    'accent-4': #64dd17\n  ),\n  $light-green\n);\n\n$text-on-light-green: () !default;\n$text-on-light-green: map-deep-merge(\n  (\n    'base': map.get($shades, 'black'),\n    'lighten-5': map.get($shades, 'black'),\n    'lighten-4': map.get($shades, 'black'),\n    'lighten-3': map.get($shades, 'black'),\n    'lighten-2': map.get($shades, 'black'),\n    'lighten-1': map.get($shades, 'black'),\n    'darken-1': map.get($shades, 'white'),\n    'darken-2': map.get($shades, 'white'),\n    'darken-3': map.get($shades, 'white'),\n    'darken-4': map.get($shades, 'white'),\n    'accent-1': map.get($shades, 'black'),\n    'accent-2': map.get($shades, 'black'),\n    'accent-3': map.get($shades, 'black'),\n    'accent-4': map.get($shades, 'black')\n  ),\n  $text-on-light-green\n);\n\n$lime: () !default;\n$lime: map-deep-merge(\n  (\n    'base': #cddc39,\n    'lighten-5': #f9fbe7,\n    'lighten-4': #f0f4c3,\n    'lighten-3': #e6ee9c,\n    'lighten-2': #dce775,\n    'lighten-1': #d4e157,\n    'darken-1': #c0ca33,\n    'darken-2': #afb42b,\n    'darken-3': #9e9d24,\n    'darken-4': #827717,\n    'accent-1': #f4ff81,\n    'accent-2': #eeff41,\n    'accent-3': #c6ff00,\n    'accent-4': #aeea00\n  ),\n  $lime\n);\n\n$text-on-lime: () !default;\n$text-on-lime: map-deep-merge(\n  (\n    'base': map.get($shades, 'black'),\n    'lighten-5': map.get($shades, 'black'),\n    'lighten-4': map.get($shades, 'black'),\n    'lighten-3': map.get($shades, 'black'),\n    'lighten-2': map.get($shades, 'black'),\n    'lighten-1': map.get($shades, 'black'),\n    'darken-1': map.get($shades, 'black'),\n    'darken-2': map.get($shades, 'black'),\n    'darken-3': map.get($shades, 'white'),\n    'darken-4': map.get($shades, 'white'),\n    'accent-1': map.get($shades, 'black'),\n    'accent-2': map.get($shades, 'black'),\n    'accent-3': map.get($shades, 'black'),\n    'accent-4': map.get($shades, 'black')\n  ),\n  $text-on-lime\n);\n\n$yellow: () !default;\n$yellow: map-deep-merge(\n  (\n    'base': #ffeb3b,\n    'lighten-5': #fffde7,\n    'lighten-4': #fff9c4,\n    'lighten-3': #fff59d,\n    'lighten-2': #fff176,\n    'lighten-1': #ffee58,\n    'darken-1': #fdd835,\n    'darken-2': #fbc02d,\n    'darken-3': #f9a825,\n    'darken-4': #f57f17,\n    'accent-1': #ffff8d,\n    'accent-2': #ffff00,\n    'accent-3': #ffea00,\n    'accent-4': #ffd600\n  ),\n  $yellow\n);\n\n$text-on-yellow: () !default;\n$text-on-yellow: map-deep-merge(\n  (\n    'base': map.get($shades, 'black'),\n    'lighten-5': map.get($shades, 'black'),\n    'lighten-4': map.get($shades, 'black'),\n    'lighten-3': map.get($shades, 'black'),\n    'lighten-2': map.get($shades, 'black'),\n    'lighten-1': map.get($shades, 'black'),\n    'darken-1': map.get($shades, 'black'),\n    'darken-2': map.get($shades, 'black'),\n    'darken-3': map.get($shades, 'black'),\n    'darken-4': map.get($shades, 'white'),\n    'accent-1': map.get($shades, 'black'),\n    'accent-2': map.get($shades, 'black'),\n    'accent-3': map.get($shades, 'black'),\n    'accent-4': map.get($shades, 'black')\n  ),\n  $text-on-yellow\n);\n\n$amber: () !default;\n$amber: map-deep-merge(\n  (\n    'base': #ffc107,\n    'lighten-5': #fff8e1,\n    'lighten-4': #ffecb3,\n    'lighten-3': #ffe082,\n    'lighten-2': #ffd54f,\n    'lighten-1': #ffca28,\n    'darken-1': #ffb300,\n    'darken-2': #ffa000,\n    'darken-3': #ff8f00,\n    'darken-4': #ff6f00,\n    'accent-1': #ffe57f,\n    'accent-2': #ffd740,\n    'accent-3': #ffc400,\n    'accent-4': #ffab00\n  ),\n  $amber\n);\n\n$text-on-amber: () !default;\n$text-on-amber: map-deep-merge(\n  (\n    'base': map.get($shades, 'black'),\n    'lighten-5': map.get($shades, 'black'),\n    'lighten-4': map.get($shades, 'black'),\n    'lighten-3': map.get($shades, 'black'),\n    'lighten-2': map.get($shades, 'black'),\n    'lighten-1': map.get($shades, 'black'),\n    'darken-1': map.get($shades, 'black'),\n    'darken-2': map.get($shades, 'black'),\n    'darken-3': map.get($shades, 'black'),\n    'darken-4': map.get($shades, 'white'),\n    'accent-1': map.get($shades, 'black'),\n    'accent-2': map.get($shades, 'black'),\n    'accent-3': map.get($shades, 'black'),\n    'accent-4': map.get($shades, 'black')\n  ),\n  $text-on-amber\n);\n\n$orange: () !default;\n$orange: map-deep-merge(\n  (\n    'base': #ff9800,\n    'lighten-5': #fff3e0,\n    'lighten-4': #ffe0b2,\n    'lighten-3': #ffcc80,\n    'lighten-2': #ffb74d,\n    'lighten-1': #ffa726,\n    'darken-1': #fb8c00,\n    'darken-2': #f57c00,\n    'darken-3': #ef6c00,\n    'darken-4': #e65100,\n    'accent-1': #ffd180,\n    'accent-2': #ffab40,\n    'accent-3': #ff9100,\n    'accent-4': #ff6d00\n  ),\n  $orange\n);\n\n$text-on-orange: () !default;\n$text-on-orange: map-deep-merge(\n  (\n    'base': map.get($shades, 'black'),\n    'lighten-5': map.get($shades, 'black'),\n    'lighten-4': map.get($shades, 'black'),\n    'lighten-3': map.get($shades, 'black'),\n    'lighten-2': map.get($shades, 'black'),\n    'lighten-1': map.get($shades, 'black'),\n    'darken-1': map.get($shades, 'white'),\n    'darken-2': map.get($shades, 'white'),\n    'darken-3': map.get($shades, 'white'),\n    'darken-4': map.get($shades, 'white'),\n    'accent-1': map.get($shades, 'black'),\n    'accent-2': map.get($shades, 'black'),\n    'accent-3': map.get($shades, 'black'),\n    'accent-4': map.get($shades, 'white')\n  ),\n  $text-on-orange\n);\n\n$deep-orange: () !default;\n$deep-orange: map-deep-merge(\n  (\n    'base': #ff5722,\n    'lighten-5': #fbe9e7,\n    'lighten-4': #ffccbc,\n    'lighten-3': #ffab91,\n    'lighten-2': #ff8a65,\n    'lighten-1': #ff7043,\n    'darken-1': #f4511e,\n    'darken-2': #e64a19,\n    'darken-3': #d84315,\n    'darken-4': #bf360c,\n    'accent-1': #ff9e80,\n    'accent-2': #ff6e40,\n    'accent-3': #ff3d00,\n    'accent-4': #dd2c00\n  ),\n  $deep-orange\n);\n\n$text-on-deep-orange: () !default;\n$text-on-deep-orange: map-deep-merge(\n  (\n    'base': map.get($shades, 'white'),\n    'lighten-5': map.get($shades, 'black'),\n    'lighten-4': map.get($shades, 'black'),\n    'lighten-3': map.get($shades, 'black'),\n    'lighten-2': map.get($shades, 'black'),\n    'lighten-1': map.get($shades, 'white'),\n    'darken-1': map.get($shades, 'white'),\n    'darken-2': map.get($shades, 'white'),\n    'darken-3': map.get($shades, 'white'),\n    'darken-4': map.get($shades, 'white'),\n    'accent-1': map.get($shades, 'black'),\n    'accent-2': map.get($shades, 'white'),\n    'accent-3': map.get($shades, 'white'),\n    'accent-4': map.get($shades, 'white')\n  ),\n  $text-on-deep-orange\n);\n\n$brown: () !default;\n$brown: map-deep-merge(\n  (\n    'base': #795548,\n    'lighten-5': #efebe9,\n    'lighten-4': #d7ccc8,\n    'lighten-3': #bcaaa4,\n    'lighten-2': #a1887f,\n    'lighten-1': #8d6e63,\n    'darken-1': #6d4c41,\n    'darken-2': #5d4037,\n    'darken-3': #4e342e,\n    'darken-4': #3e2723\n  ),\n  $brown\n);\n\n$text-on-brown: () !default;\n$text-on-brown: map-deep-merge(\n  (\n    'base': map.get($shades, 'white'),\n    'lighten-5': map.get($shades, 'black'),\n    'lighten-4': map.get($shades, 'black'),\n    'lighten-3': map.get($shades, 'black'),\n    'lighten-2': map.get($shades, 'white'),\n    'lighten-1': map.get($shades, 'white'),\n    'darken-1': map.get($shades, 'white'),\n    'darken-2': map.get($shades, 'white'),\n    'darken-3': map.get($shades, 'white'),\n    'darken-4': map.get($shades, 'white')\n  ),\n  $text-on-brown\n);\n\n$blue-grey: () !default;\n$blue-grey: map-deep-merge(\n  (\n    'base': #607d8b,\n    'lighten-5': #eceff1,\n    'lighten-4': #cfd8dc,\n    'lighten-3': #b0bec5,\n    'lighten-2': #90a4ae,\n    'lighten-1': #78909c,\n    'darken-1': #546e7a,\n    'darken-2': #455a64,\n    'darken-3': #37474f,\n    'darken-4': #263238\n  ),\n  $blue-grey\n);\n\n$text-on-blue-grey: () !default;\n$text-on-blue-grey: map-deep-merge(\n  (\n    'base': map.get($shades, 'white'),\n    'lighten-5': map.get($shades, 'black'),\n    'lighten-4': map.get($shades, 'black'),\n    'lighten-3': map.get($shades, 'black'),\n    'lighten-2': map.get($shades, 'white'),\n    'lighten-1': map.get($shades, 'white'),\n    'darken-1': map.get($shades, 'white'),\n    'darken-2': map.get($shades, 'white'),\n    'darken-3': map.get($shades, 'white'),\n    'darken-4': map.get($shades, 'white')\n  ),\n  $text-on-blue-grey\n);\n\n$grey: () !default;\n$grey: map-deep-merge(\n  (\n    'base': #9e9e9e,\n    'lighten-5': #fafafa,\n    'lighten-4': #f5f5f5,\n    'lighten-3': #eeeeee,\n    'lighten-2': #e0e0e0,\n    'lighten-1': #bdbdbd,\n    'darken-1': #757575,\n    'darken-2': #616161,\n    'darken-3': #424242,\n    'darken-4': #212121\n  ),\n  $grey\n);\n\n$text-on-grey: () !default;\n$text-on-grey: map-deep-merge(\n  (\n    'base': map.get($shades, 'white'),\n    'lighten-5': map.get($shades, 'black'),\n    'lighten-4': map.get($shades, 'black'),\n    'lighten-3': map.get($shades, 'black'),\n    'lighten-2': map.get($shades, 'black'),\n    'lighten-1': map.get($shades, 'black'),\n    'darken-1': map.get($shades, 'white'),\n    'darken-2': map.get($shades, 'white'),\n    'darken-3': map.get($shades, 'white'),\n    'darken-4': map.get($shades, 'white')\n  ),\n  $text-on-grey\n);\n\n$colors: () !default;\n$colors: map-deep-merge(\n  (\n    'red': $red,\n    'pink': $pink,\n    'purple': $purple,\n    'deep-purple': $deep-purple,\n    'indigo': $indigo,\n    'blue': $blue,\n    'light-blue': $light-blue,\n    'cyan': $cyan,\n    'teal': $teal,\n    'green': $green,\n    'light-green': $light-green,\n    'lime': $lime,\n    'yellow': $yellow,\n    'amber': $amber,\n    'orange': $orange,\n    'deep-orange': $deep-orange,\n    'brown': $brown,\n    'blue-grey': $blue-grey,\n    'grey': $grey,\n    'shades': $shades\n  ),\n  $colors\n);\n\n$text-on-colors: () !default;\n$text-on-colors: map-deep-merge(\n  (\n    'red': $text-on-red,\n    'pink': $text-on-pink,\n    'purple': $text-on-purple,\n    'deep-purple': $text-on-deep-purple,\n    'indigo': $text-on-indigo,\n    'blue': $text-on-blue,\n    'light-blue': $text-on-light-blue,\n    'cyan': $text-on-cyan,\n    'teal': $text-on-teal,\n    'green': $text-on-green,\n    'light-green': $text-on-light-green,\n    'lime': $text-on-lime,\n    'yellow': $text-on-yellow,\n    'amber': $text-on-amber,\n    'orange': $text-on-orange,\n    'deep-orange': $text-on-deep-orange,\n    'brown': $text-on-brown,\n    'blue-grey': $text-on-blue-grey,\n    'grey': $text-on-grey,\n    'shades': $text-on-shades\n  ),\n  $text-on-colors\n);\n"
  },
  {
    "path": "packages/vuetify/src/styles/settings/_elevations.scss",
    "content": "@use '../tools/functions' as *;\n\n$shadow-key-color: rgba(var(--v-shadow-color), var(--v-shadow-key-opacity, 0.3)) !default;\n$shadow-ambient-color: rgba(var(--v-shadow-color), var(--v-shadow-ambient-opacity, 0.15)) !default;\n\n$shadow-key: () !default;\n$shadow-key: map-deep-merge(\n  (\n    0: (0px 0px 0px 0px $shadow-key-color),\n    1: (0px 1px 2px 0px $shadow-key-color),\n    2: (0px 1px 2px 0px $shadow-key-color),\n    3: (0px 1px 3px 0px $shadow-key-color),\n    4: (0px 2px 3px 0px $shadow-key-color),\n    5: (0px 4px 4px 0px $shadow-key-color)\n  ),\n  $shadow-key\n);\n\n$shadow-ambient: () !default;\n$shadow-ambient: map-deep-merge(\n  (\n    0: (0px 0px 0px 0px $shadow-ambient-color),\n    1: (0px 1px 3px 1px $shadow-ambient-color),\n    2: (0px 2px 6px 2px $shadow-ambient-color),\n    3: (0px 4px 8px 3px $shadow-ambient-color),\n    4: (0px 6px 10px 4px $shadow-ambient-color),\n    5: (0px 8px 12px 6px $shadow-ambient-color)\n  ),\n  $shadow-ambient\n);\n\n$elevation-overlay-step: 2%;"
  },
  {
    "path": "packages/vuetify/src/styles/settings/_index.sass",
    "content": "@forward './variables'\n@forward './colors'\n@forward './elevations'\n@forward './utilities'\n"
  },
  {
    "path": "packages/vuetify/src/styles/settings/_utilities.scss",
    "content": "@use 'sass:map';\n@use './variables';\n@use '../tools/functions' as *;\n\n$utilities: () !default;\n@if ($utilities != false) {\n  $utilities: map-deep-merge(\n    (\n      // Display utilities\n      \"overflow\": (\n        property: overflow,\n        values: auto hidden visible scroll,\n      ),\n      \"overflow-x\": (\n        property: overflow-x,\n        values: auto hidden scroll\n      ),\n      \"overflow-y\": (\n        property: overflow-y,\n        values: auto hidden scroll\n      ),\n      \"display\": (\n        responsive: true,\n        print: true,\n        property: display,\n        class: d,\n        values: none inline inline-block block table table-row table-cell flex inline-flex\n      ),\n      \"float\": (\n        responsive: true,\n        print: true,\n        property: float,\n        class: float,\n        values: none left right\n      ),\n      \"float:rtl\": (\n        responsive: true,\n        print: true,\n        property: float,\n        class: float,\n        values: (\n          end: left,\n          start: right,\n        )\n      ),\n      \"float:ltr\": (\n        responsive: true,\n        print: true,\n        property: float,\n        class: float,\n        values: (\n          end: right,\n          start: left,\n        )\n      ),\n\n      // Flex utilities\n      \"flex\": (\n        responsive: true,\n        property: flex,\n        values: (\n          fill: 1 1 auto,\n          '1-1': 1 1 auto,\n          '1-0': 1 0 auto,\n          '0-1': 0 1 auto,\n          '0-0': 0 0 auto,\n          '1-1-100': 1 1 100%,\n          '1-0-100': 1 0 100%,\n          '0-1-100': 0 1 100%,\n          '0-0-100': 0 0 100%,\n          '1-1-0': 1 1 0,\n          '1-0-0': 1 0 0,\n          '0-1-0': 0 1 0,\n          '0-0-0': 0 0 0,\n        )\n      ),\n      \"flex-direction\": (\n        responsive: true,\n        property: flex-direction,\n        class: flex,\n        values: row column row-reverse column-reverse\n      ),\n      \"flex-grow\": (\n        responsive: true,\n        property: flex-grow,\n        class: flex,\n        values: (\n          grow-0: 0,\n          grow-1: 1,\n        )\n      ),\n      \"flex-shrink\": (\n        responsive: true,\n        property: flex-shrink,\n        class: flex,\n        values: (\n          shrink-0: 0,\n          shrink-1: 1,\n        )\n      ),\n      \"flex-wrap\": (\n        responsive: true,\n        property: flex-wrap,\n        class: flex,\n        values: wrap nowrap wrap-reverse\n      ),\n      \"justify-content\": (\n        responsive: true,\n        property: justify-content,\n        class: justify,\n        values: (\n          start: flex-start,\n          end: flex-end,\n          center: center,\n          space-between: space-between,\n          space-around: space-around,\n          space-evenly: space-evenly,\n        )\n      ),\n      \"justify-items\": (\n        responsive: true,\n        property: justify-items,\n        values: (\n          start: flex-start,\n          end: flex-end,\n          center: center,\n          stretch: stretch,\n        )\n      ),\n      \"align-items\": (\n        responsive: true,\n        property: align-items,\n        class: align,\n        values: (\n          start: flex-start,\n          end: flex-end,\n          center: center,\n          baseline: baseline,\n          stretch: stretch,\n        )\n      ),\n      \"align-content\": (\n        responsive: true,\n        property: align-content,\n        values: (\n          start: flex-start,\n          end: flex-end,\n          center: center,\n          space-between: space-between,\n          space-around: space-around,\n          space-evenly: space-evenly,\n          stretch: stretch,\n        )\n      ),\n      \"align-self\": (\n        responsive: true,\n        property: align-self,\n        values: (\n          auto: auto,\n          start: flex-start,\n          end: flex-end,\n          center: center,\n          baseline: baseline,\n          stretch: stretch,\n        )\n      ),\n      \"order\": (\n        responsive: true,\n        property: order,\n        values: (\n          first: -1,\n          0: 0,\n          1: 1,\n          2: 2,\n          3: 3,\n          4: 4,\n          5: 5,\n          6: 6,\n          7: 7,\n          8: 8,\n          9: 9,\n          10: 10,\n          11: 11,\n          12: 12,\n          last: 13,\n        ),\n      ),\n\n      // gap utilities\n      \"gap\": (\n        responsive: true,\n        property: gap,\n        class: ga,\n        values: map.merge(variables.$spacers, (auto: auto))\n      ),\n      \"gap-row\": (\n        responsive: true,\n        property: row-gap,\n        class: gr,\n        values: map.merge(variables.$spacers, (auto: auto))\n      ),\n      \"gap-column\": (\n        responsive: true,\n        property: column-gap,\n        class: gc,\n        values: map.merge(variables.$spacers, (auto: auto))\n      ),\n\n      // Margin utilities\n      \"margin\": (\n        responsive: true,\n        property: margin,\n        class: ma,\n        values: map.merge(variables.$spacers, (auto: auto))\n      ),\n      \"margin-x\": (\n        responsive: true,\n        property: margin-right margin-left,\n        class: mx,\n        values: map.merge(variables.$spacers, (auto: auto))\n      ),\n      \"margin-y\": (\n        responsive: true,\n        property: margin-top margin-bottom,\n        class: my,\n        values: map.merge(variables.$spacers, (auto: auto))\n      ),\n      \"margin-top\": (\n        responsive: true,\n        property: margin-top,\n        class: mt,\n        values: map.merge(variables.$spacers, (auto: auto))\n      ),\n      \"margin-right\": (\n        responsive: true,\n        property: margin-right,\n        class: mr,\n        values: map.merge(variables.$spacers, (auto: auto))\n      ),\n      \"margin-bottom\": (\n        responsive: true,\n        property: margin-bottom,\n        class: mb,\n        values: map.merge(variables.$spacers, (auto: auto))\n      ),\n      \"margin-left\": (\n        responsive: true,\n        property: margin-left,\n        class: ml,\n        values: map.merge(variables.$spacers, (auto: auto))\n      ),\n      \"margin-start\": (\n        responsive: true,\n        property: margin-inline-start,\n        class: ms,\n        values: map.merge(variables.$spacers, (auto: auto))\n      ),\n      \"margin-end\": (\n        responsive: true,\n        property: margin-inline-end,\n        class: me,\n        values: map.merge(variables.$spacers, (auto: auto))\n      ),\n\n      // Negative margin utilities\n      \"negative-margin\": (\n        responsive: true,\n        property: margin,\n        class: ma,\n        values: variables.$negative-spacers\n      ),\n      \"negative-margin-x\": (\n        responsive: true,\n        property: margin-right margin-left,\n        class: mx,\n        values: variables.$negative-spacers\n      ),\n      \"negative-margin-y\": (\n        responsive: true,\n        property: margin-top margin-bottom,\n        class: my,\n        values: variables.$negative-spacers\n      ),\n      \"negative-margin-top\": (\n        responsive: true,\n        property: margin-top,\n        class: mt,\n        values: variables.$negative-spacers\n      ),\n      \"negative-margin-right\": (\n        responsive: true,\n        property: margin-right,\n        class: mr,\n        values: variables.$negative-spacers\n      ),\n      \"negative-margin-bottom\": (\n        responsive: true,\n        property: margin-bottom,\n        class: mb,\n        values: variables.$negative-spacers\n      ),\n      \"negative-margin-left\": (\n        responsive: true,\n        property: margin-left,\n        class: ml,\n        values: variables.$negative-spacers\n      ),\n      \"negative-margin-start\": (\n        responsive: true,\n        property: margin-inline-start,\n        class: ms,\n        values: variables.$negative-spacers\n      ),\n      \"negative-margin-end\": (\n        responsive: true,\n        property: margin-inline-end,\n        class: me,\n        values: variables.$negative-spacers\n      ),\n\n      // Padding utilities\n      \"padding\": (\n        responsive: true,\n        property: padding,\n        class: pa,\n        values: variables.$spacers\n      ),\n      \"padding-x\": (\n        responsive: true,\n        property: padding-right padding-left,\n        class: px,\n        values: variables.$spacers\n      ),\n      \"padding-y\": (\n        responsive: true,\n        property: padding-top padding-bottom,\n        class: py,\n        values: variables.$spacers\n      ),\n      \"padding-top\": (\n        responsive: true,\n        property: padding-top,\n        class: pt,\n        values: variables.$spacers\n      ),\n      \"padding-right\": (\n        responsive: true,\n        property: padding-right,\n        class: pr,\n        values: variables.$spacers\n      ),\n      \"padding-bottom\": (\n        responsive: true,\n        property: padding-bottom,\n        class: pb,\n        values: variables.$spacers\n      ),\n      \"padding-left\": (\n        responsive: true,\n        property: padding-left,\n        class: pl,\n        values: variables.$spacers\n      ),\n      \"padding-start\": (\n        responsive: true,\n        property: padding-inline-start,\n        class: ps,\n        values: variables.$spacers\n      ),\n      \"padding-end\": (\n        responsive: true,\n        property: padding-inline-end,\n        class: pe,\n        values: variables.$spacers\n      ),\n\n      // Border radius\n      \"rounded\": (\n        property: border-radius,\n        class: rounded,\n        values: variables.$rounded\n      ),\n      \"rounded-top\": (\n        property: border-top-left-radius border-top-right-radius,\n        class: rounded-t,\n        values: variables.$rounded\n      ),\n      \"rounded-end\": (\n        property: (ltr: border-top-right-radius border-bottom-right-radius, rtl: border-top-left-radius border-bottom-left-radius),\n        class: rounded-e,\n        values: variables.$rounded\n      ),\n      \"rounded-bottom\": (\n        property: border-bottom-left-radius border-bottom-right-radius,\n        class: rounded-b,\n        values: variables.$rounded\n      ),\n      \"rounded-start\": (\n        property: (ltr: border-top-left-radius border-bottom-left-radius, rtl: border-top-right-radius border-bottom-right-radius),\n        class: rounded-s,\n        values: variables.$rounded\n      ),\n      \"rounded-top-start\": (\n        property: (ltr: border-top-left-radius, rtl: border-top-right-radius),\n        class: rounded-ts,\n        values: variables.$rounded\n      ),\n      \"rounded-top-end\": (\n        property: (ltr: border-top-right-radius, rtl: border-top-left-radius),\n        class: rounded-te,\n        values: variables.$rounded\n      ),\n      \"rounded-bottom-end\": (\n        property: (ltr: border-bottom-right-radius, rtl: border-bottom-left-radius),\n        class: rounded-be,\n        values: variables.$rounded\n      ),\n      \"rounded-bottom-start\": (\n        property: (ltr: border-bottom-left-radius, rtl: border-bottom-right-radius),\n        class: rounded-bs,\n        values: variables.$rounded\n      ),\n\n      // Border\n      \"border\": (\n        property: border-width border-style border-color,\n        class: border,\n        values: variables.$borders\n      ),\n      \"border-current\": (\n        property: border-color,\n        class: border,\n        values: (current: currentColor)\n      ),\n      \"border-opacity\": (\n        property: --v-border-opacity,\n        class: border-opacity,\n        values: variables.$border-opacities\n      ),\n      \"border-top\": (\n        property: border-block-start-width border-block-start-style border-block-start-color,\n        class: border-t,\n        values: variables.$borders\n      ),\n      \"border-end\": (\n        property: border-inline-end-width border-inline-end-style border-inline-end-color,\n        class: border-e,\n        values: variables.$borders\n      ),\n      \"border-bottom\": (\n        property: border-block-end-width border-block-end-style border-block-end-color,\n        class: border-b,\n        values: variables.$borders\n      ),\n      \"border-start\": (\n        property: border-inline-start-width border-inline-start-style border-inline-start-color,\n        class: border-s,\n        values: variables.$borders\n      ),\n      \"border-style\": (\n        property: border-style,\n        class: border,\n        values: solid dashed dotted double none\n      ),\n\n      // Text\n      \"text-align\": (\n        responsive: true,\n        property: text-align,\n        class: text,\n        values: left right center justify start end\n      ),\n      \"text-decoration\": (\n        property: text-decoration,\n        class: text-decoration,\n        values: line-through none overline underline\n      ),\n      \"white-space\": (\n        property: white-space,\n        class: text,\n        values: (\n          wrap: normal,\n          no-wrap: nowrap,\n          pre: pre,\n          pre-line: pre-line,\n          pre-wrap: pre-wrap,\n        )\n      ),\n      \"overflow-wrap\": (\n        property: overflow-wrap word-break, // word-break for IE & < Edge 18\n        class: text,\n        values: (break: break-word)\n      ),\n      \"opacity\": (\n        property: opacity,\n        class: opacity,\n        values: variables.$opacities\n      ),\n      \"text-opacity\": (\n        property: color,\n        class: text,\n        values: (\n          high-emphasis: theme-color('on-background', var(--v-high-emphasis-opacity)),\n          medium-emphasis: theme-color('on-background', var(--v-medium-emphasis-opacity)),\n          disabled: theme-color('on-background', var(--v-disabled-opacity)),\n        )\n      ),\n      \"text-overflow\": (\n        property: white-space overflow text-overflow,\n        class: text,\n        values: (truncate: nowrap hidden ellipsis)\n      ),\n      \"typography\": (\n        responsive: true,\n        property: (\n          font-size,\n          font-weight,\n          line-height,\n          letter-spacing,\n          font-family,\n        ),\n        class: text,\n        values: variables.$flat-typography\n      ),\n      \"text-transform\": (\n        property: text-transform,\n        class: text,\n        values: none capitalize lowercase uppercase\n      ),\n      \"font-weight\": (\n        property: font-weight,\n        class: font-weight,\n        values: variables.$font-weights\n      ),\n      \"font-italic\": (\n        property: font-style,\n        class: font,\n        values: italic\n      ),\n      \"text-mono\": (\n        property: font-family,\n        class: text,\n        values: (\n          mono: monospace\n        )\n      ),\n      // Position\n      \"position\": (\n        property: position,\n        class: position,\n        values: static relative fixed absolute sticky\n      ),\n      \"top\": (\n        property: top,\n        class: top,\n        values: 0\n      ),\n      \"right\": (\n        property: right,\n        class: right,\n        values: 0\n      ),\n      \"bottom\": (\n        property: bottom,\n        class: bottom,\n        values: 0\n      ),\n      \"left\": (\n        property: left,\n        class: left,\n        values: 0\n      ),\n      // Cursor\n      \"cursor\": (\n        property: cursor,\n        class: cursor,\n        values: auto default pointer wait text move help not-allowed progress grab grabbing none\n      ),\n      // Sizing\n      \"fill-height\": (\n        property: height,\n        class: fill,\n        values: (\n          height: 100%\n        )\n      ),\n      \"height\": (\n        property: height,\n        responsive: true,\n        class: h,\n        values: (\n          auto: auto,\n          screen: 100vh,\n          0: 0,\n          25: 25%,\n          50: 50%,\n          75: 75%,\n          100: 100%\n        )\n      ),\n      \"height-screen\": (\n        property: height,\n        class: h,\n        values: (\n          screen: 100dvh\n        )\n      ),\n      \"width\": (\n        property: width,\n        responsive: true,\n        class: w,\n        values: (\n          auto: auto,\n          0: 0,\n          25: 25%,\n          33: 33%,\n          50: 50%,\n          66: 66%,\n          75: 75%,\n          100: 100%\n        )\n      )\n    ),\n    $utilities\n  );\n} @else {\n  $utilities: ();\n}\n"
  },
  {
    "path": "packages/vuetify/src/styles/settings/_variables.scss",
    "content": "@use 'sass:math';\n@use 'sass:map';\n@use 'sass:meta';\n@use '../tools/functions' as *;\n\n$color-pack: true !default;\n$reset: true !default;\n\n$misc: () !default;\n$misc: map-deep-merge(\n  (\n    elevation: true,\n    hidden: true,\n    'sr-only': true,\n    'pointer-events': true,\n  ),\n  $misc\n);\n\n$body-font-family: var(--v-font-body, 'Roboto', sans-serif) !default;\n$font-size-root: 1rem !default;\n$line-height-root: 1.5 !default;\n$border-color-root: rgba(var(--v-border-color), var(--v-border-opacity)) !default;\n$border-radius-root: 4px !default;\n$border-style-root: solid !default;\n$border-width-root: thin !default;\n$transition-duration-root: 0.3s !default;\n$transition-move-duration-root: 0.5s !default;\n\n$borders: () !default;\n$borders: map-deep-merge(\n  (\n    0: 0,\n    null: $border-width-root,\n    thin: $border-width-root,\n    sm: 1px,\n    md: 2px,\n    lg: 4px,\n    xl: 8px\n  ),\n  $borders\n);\n\n@each $key, $border in $borders {\n  $borders: map-deep-merge(\n    $borders,\n    ( $key: $border $border-style-root $border-color-root )\n  )\n}\n\n$border-opacities: () !default;\n$border-opacities: map-deep-merge(\n  (\n    0: 0,\n    null: .12,\n    25: .25,\n    50: .50,\n    75: .75,\n    100: 1\n  ),\n  $border-opacities\n);\n\n$opacities: () !default;\n$opacities: map-deep-merge(\n  (\n    hover: var(--v-hover-opacity),\n    focus: var(--v-focus-opacity),\n    selected: var(--v-selected-opacity),\n    activated: var(--v-activated-opacity),\n    pressed: var(--v-pressed-opacity),\n    dragged: var(--v-dragged-opacity),\n    0: 0,\n    10: .1,\n    20: .2,\n    30: .3,\n    40: .4,\n    50: .5,\n    60: .6,\n    70: .7,\n    80: .8,\n    90: .9,\n    100: 1\n  ),\n  $opacities\n);\n\n$states: () !default;\n$states: map-deep-merge(\n    (\n    'hover': var(--v-hover-opacity),\n    'focus': var(--v-focus-opacity),\n    'selected': var(--v-selected-opacity),\n    'activated': var(--v-activated-opacity),\n    'pressed': var(--v-pressed-opacity),\n    'dragged': var(--v-dragged-opacity)\n  ),\n  $states\n);\n\n$rounded: () !default;\n$rounded: map-deep-merge(\n  (\n    0: 0,\n    'sm': $border-radius-root * .5,\n    null: $border-radius-root,\n    'md': $border-radius-root,\n    'lg': $border-radius-root * 2,\n    'xl': $border-radius-root * 6,\n    'pill': 9999px,\n    'circle': 50%,\n    'shaped': $border-radius-root * 6 0\n  ),\n  $rounded\n);\n\n$spacer: 4px !default;\n$spacers-steps: 16 !default;\n\n$spacers: () !default;\n@if (meta.type-of($spacers) == list) {\n  @for $i from 0 through $spacers-steps {\n    $spacers: map.merge($spacers, ($i: $spacer * $i))\n  }\n}\n\n$negative-spacers: () !default;\n@if (meta.type-of($negative-spacers) == list) {\n  @for $i from 1 through $spacers-steps {\n    $negative-spacers: map.merge($negative-spacers, (\"n\" + $i: -$spacer * $i))\n  }\n}\n\n$grid-breakpoints: () !default;\n$grid-breakpoints: map-deep-merge(\n  (\n    'xs': 0,\n    'sm': 600px,\n    'md': 840px,\n    'lg': 1145px,\n    'xl': 1545px,\n    'xxl': 2138px,\n  ),\n  $grid-breakpoints\n);\n\n$grid-gutter: $spacer * 6 !default;\n$grid-density: ('default': 0, 'comfortable': -1, 'compact': -2) !default;\n$grid-columns: 12 !default;\n$container-padding-x: $spacer * 4 !default;\n\n$container-max-widths: () !default;\n$container-max-widths: map-deep-merge(\n  (\n    'xs': null,\n    'sm': null,\n    'md': 100 * math.floor(map.get($grid-breakpoints, 'md') * 0.009375),\n    'lg': 100 * math.floor(map.get($grid-breakpoints, 'lg') * 0.009375),\n    'xl': 100 * math.floor(map.get($grid-breakpoints, 'xl') * 0.009375),\n    'xxl': 100 * math.floor(map.get($grid-breakpoints, 'xxl') * 0.009375),\n  ),\n  $container-max-widths\n);\n\n// Avoid using *-and-down where possible\n$display-breakpoints: () !default;\n$display-breakpoints: map-deep-merge(\n  (\n    'print-only': 'only print',\n    'screen-only': 'only screen',\n    'xs': '(max-width: #{map.get($grid-breakpoints, 'sm') - 0.02})',\n    'sm': '(min-width: #{map.get($grid-breakpoints, 'sm')}) and (max-width: #{map.get($grid-breakpoints, 'md') - 0.02})',\n    'md': '(min-width: #{map.get($grid-breakpoints, 'md')}) and (max-width: #{map.get($grid-breakpoints, 'lg') - 0.02})',\n    'lg': '(min-width: #{map.get($grid-breakpoints, 'lg')}) and (max-width: #{map.get($grid-breakpoints, 'xl') - 0.02})',\n    'xl': '(min-width: #{map.get($grid-breakpoints, 'xl')}) and (max-width: #{map.get($grid-breakpoints, 'xxl') - 0.02})',\n    'xxl': '(min-width: #{map.get($grid-breakpoints, 'xxl')})',\n    'sm-and-up': '(min-width: #{map.get($grid-breakpoints, 'sm')})',\n    'md-and-up': '(min-width: #{map.get($grid-breakpoints, 'md')})',\n    'lg-and-up': '(min-width: #{map.get($grid-breakpoints, 'lg')})',\n    'xl-and-up': '(min-width: #{map.get($grid-breakpoints, 'xl')})',\n    'sm-and-down': '(max-width: #{map.get($grid-breakpoints, 'md') - 0.02})',\n    'md-and-down': '(max-width: #{map.get($grid-breakpoints, 'lg') - 0.02})',\n    'lg-and-down': '(max-width: #{map.get($grid-breakpoints, 'xl') - 0.02})',\n    'xl-and-down': '(max-width: #{map.get($grid-breakpoints, 'xxl') - 0.02})',\n  ),\n  $display-breakpoints\n);\n\n$font-weights: () !default;\n$font-weights: map-deep-merge(\n  (\n    'thin': 100,\n    'light': 300,\n    'regular': 400,\n    'medium': 500,\n    'semibold': 600,\n    'bold': 700,\n    'black': 900\n  ),\n  $font-weights\n);\n\n$heading-font-family: var(--v-font-heading, #{$body-font-family}) !default;\n\n$typography: () !default;\n$typography: map-deep-merge(\n  (\n    'display-large': (\n      'size': 3.5625rem,\n      'weight': 400,\n      'line-height': 1.1228070175,\n      'letter-spacing': -.0043859649em,\n      'font-family': $heading-font-family\n    ),\n    'display-medium': (\n      'size': 2.8125rem,\n      'weight': 400,\n      'line-height': 1.1555555556,\n      'letter-spacing': normal,\n      'font-family': $heading-font-family\n    ),\n    'display-small': (\n      'size': 2.25rem,\n      'weight': 400,\n      'line-height': 1.2222222222,\n      'letter-spacing': normal,\n      'font-family': $heading-font-family\n    ),\n    'headline-large': (\n      'size': 2rem,\n      'weight': 400,\n      'line-height': 1.25,\n      'letter-spacing': normal,\n      'font-family': $heading-font-family\n    ),\n    'headline-medium': (\n      'size': 1.75rem,\n      'weight': 400,\n      'line-height': 1.2857142857,\n      'letter-spacing': normal,\n      'font-family': $heading-font-family\n    ),\n    'headline-small': (\n      'size': 1.5rem,\n      'weight': 400,\n      'line-height': 1.3333333333,\n      'letter-spacing': normal,\n      'font-family': $heading-font-family\n    ),\n    'title-large': (\n      'size': 1.375rem,\n      'weight': 400,\n      'line-height': 1.2727272727,\n      'letter-spacing': normal,\n      'font-family': $heading-font-family\n    ),\n    'title-medium': (\n      'size': 1rem,\n      'weight': 500,\n      'line-height': 1.5,\n      'letter-spacing': .009375em,\n      'font-family': $body-font-family\n    ),\n    'title-small': (\n      'size': .875rem,\n      'weight': 500,\n      'line-height': 1.4285714286,\n      'letter-spacing': .0071428571em,\n      'font-family': $body-font-family\n    ),\n    'body-large': (\n      'size': 1rem,\n      'weight': 400,\n      'line-height': 1.5,\n      'letter-spacing': .03125em,\n      'font-family': $body-font-family\n    ),\n    'body-medium': (\n      'size': .875rem,\n      'weight': 400,\n      'line-height': 1.4285714286,\n      'letter-spacing': .0178571429em,\n      'font-family': $body-font-family\n    ),\n    'body-small': (\n      'size': .75rem,\n      'weight': 400,\n      'line-height': 1.3333333333,\n      'letter-spacing': .0333333333em,\n      'font-family': $body-font-family\n    ),\n    'label-large': (\n      'size': .875rem,\n      'weight': 500,\n      'line-height': 1.4285714286,\n      'letter-spacing': .0071428571em,\n      'font-family': $body-font-family\n    ),\n    'label-medium': (\n      'size': .75rem,\n      'weight': 500,\n      'line-height': 1.3333333333,\n      'letter-spacing': .0416666667em,\n      'font-family': $body-font-family\n    ),\n    'label-small': (\n      'size': .6875rem,\n      'weight': 500,\n      'line-height': 1.4545454545,\n      'letter-spacing': .0454545455em,\n      'font-family': $body-font-family\n    )\n  ),\n  $typography\n);\n\n$flat-typography: () !default;\n@each $type, $values in $typography {\n  $flat-typography: map-deep-merge(\n    $flat-typography,\n    (#{$type}: (\n      map.get($values, 'size'),\n      map.get($values, 'weight'),\n      map.get($values, 'line-height'),\n      map.get($values, 'letter-spacing'),\n      map.get($values, 'font-family')\n    ))\n  );\n}\n\n// Mapping from transition to easings:\n// fast-out-slow-in -> standard\n// linear-out-slow-in -> decelerated\n// fast-out-linear-in -> accelerated\n// ease-in-out -> standard or accelerated depending on usage\n// fast-in-fast-out -> accelerated\n// swing -> standard\n\n$standard-easing: cubic-bezier(0.4, 0, 0.2, 1) !default;\n$decelerated-easing: cubic-bezier(0.0, 0, 0.2, 1) !default; // Entering\n$accelerated-easing: cubic-bezier(0.4, 0, 1, 1) !default; // Leaving\n\n// Elements\n$blockquote-font-size: 18px !default;\n$blockquote-font-weight: 300 !default;\n\n$sizes: (\n  'x-small',\n  'small',\n  'default',\n  'large',\n  'x-large'\n) !default;\n\n$size-scale: $spacer * 2 !default;\n$size-scales: (\n  'x-small': -2,\n  'small': -1,\n  'default': 0,\n  'large': 1,\n  'x-large': 2\n) !default;\n"
  },
  {
    "path": "packages/vuetify/src/styles/tools/_absolute.sass",
    "content": "@mixin absolute($pseudo: false)\n  &\n    @if ($pseudo)\n      content: ''\n    position: absolute\n    top: 0\n    left: 0\n    width: 100%\n    height: 100%\n"
  },
  {
    "path": "packages/vuetify/src/styles/tools/_border.sass",
    "content": "@mixin border($color: null, $style: null, $width: null, $thin-width: false)\n  &\n    border-color: $color\n    border-style: $style\n    border-width: $width\n\n  @if $thin-width\n    &--border\n      border-width: $thin-width\n      box-shadow: none\n"
  },
  {
    "path": "packages/vuetify/src/styles/tools/_density.sass",
    "content": "@use '../settings'\n\n@mixin density($name, $densities)\n  @each $density, $multiplier in $densities\n    .#{$name}--density-#{$density}\n      @content($multiplier * settings.$spacer)\n"
  },
  {
    "path": "packages/vuetify/src/styles/tools/_display.sass",
    "content": "@use './functions' as *\n@use '../settings' as *\n\n=media-breakpoint-up($name, $breakpoints: $grid-breakpoints)\n  $min: breakpoint-min($name, $breakpoints)\n  @if $min\n    @media (min-width: $min)\n      @content\n  @else\n    @content\n"
  },
  {
    "path": "packages/vuetify/src/styles/tools/_elevation.sass",
    "content": "@use 'sass:map'\n@use '../settings'\n\n@mixin elevation($z)\n  &\n    box-shadow: map.get(settings.$shadow-key, $z), map.get(settings.$shadow-ambient, $z)\n    --v-elevation-overlay: color-mix(in srgb, var(--v-elevation-overlay-color) #{$z * settings.$elevation-overlay-step}, transparent)\n\n@mixin elevationTransition($duration: 280ms, $easing: cubic-bezier(0.4, 0, 0.2, 1))\n  &\n    transition: $duration $easing\n    transition-property: box-shadow, --v-elevation-overlay\n"
  },
  {
    "path": "packages/vuetify/src/styles/tools/_functions.sass",
    "content": "@use 'sass:list'\n@use 'sass:map'\n@use 'sass:math'\n@use 'sass:meta'\n\n@function map-deep-set($map, $keys, $value)\n  $maps: ($map,)\n  $result: null\n\n  // If the last key is a map already\n  // Warn the user we will be overriding it with $value\n  @if meta.type-of(list.nth($keys, -1)) == \"map\"\n    @warn \"The last key you specified is a map; it will be override with `#{$value}`.\"\n\n  // If $keys is a single key\n  // Just merge and return\n  @if list.length($keys) == 1\n    @return map.merge($map, ( $keys: $value ))\n\n  // Loop from the first to the second to last key from $keys\n  // Store the associated map to this key in the $maps list\n  // If the key doesn't exist, throw an error\n  @for $i from 1 through list.length($keys) - 1\n    $current-key: list.nth($keys, $i)\n    $current-map: list.nth($maps, -1)\n    $current-get: map.get($current-map, $current-key)\n\n    @if $current-get == null\n      @error \"Key `#{$current-key}` doesn't exist at current level in map.\"\n\n    $maps: list.append($maps, $current-get)\n\n  // Loop from the last map to the first one\n  // Merge it with the previous one\n  @for $i from list.length($maps) through 1\n    $current-map: list.nth($maps, $i)\n    $current-key: list.nth($keys, $i)\n    @if $i == list.length($maps)\n      $result: map.merge($current-map, ($current-key: $value))\n    @else\n      $result: map.merge($current-map, ($current-key: $result))\n\n  // Return result\n  @return $result\n\n@function map-deep-get($map, $keys...)\n  @each $key in $keys\n    $map: map.get($map, $key)\n\n  @return $map\n\n@function breakpoint-min($name, $breakpoints)\n  $min: map.get($breakpoints, $name)\n  @if $min != 0\n    @return $min\n  @else\n    @return null\n\n@function breakpoint-infix($name, $breakpoints)\n  @if breakpoint-min($name, $breakpoints) == null\n    @return ''\n  @else\n    @return '-#{$name}'\n\n// Adapted from https://gist.github.com/pentzzsolt/4949bbd7691d43d00616dc4f1451cae9#file-non-destructive-map-merge-4-scss\n@function map-deep-merge($parent-map, $child-map)\n  $result: $parent-map\n\n  @each $key, $child in $child-map\n    $parent-has-key: map.has-key($result, $key)\n    $parent-value: map.get($result, $key)\n    $parent-type: meta.type-of($parent-value)\n    $child-type: meta.type-of($child)\n    $parent-is-map: $parent-type == map\n    $child-is-map: $child-type == map\n\n    @if (not $parent-has-key) or ($parent-type != $child-type) or (not ($parent-is-map and $child-is-map))\n      $result: map.merge($result, ( $key: $child ))\n\n    @else\n      $result: map.merge($result, ( $key: map-deep-merge($parent-value, $child) ))\n\n  @return $result\n\n@function theme-color($color, $opacity: 1)\n  $color: rgb(var(--v-theme-#{$color}))\n  $color: color-mix(in srgb, $color calc($opacity * 100%), transparent)\n  @return $color\n\n@function roundEven($val)\n  @return 2 * math.round($val * .5)\n"
  },
  {
    "path": "packages/vuetify/src/styles/tools/_index.sass",
    "content": "@forward '_absolute'\n@forward '_functions'\n@forward '_border'\n@forward '_density'\n@forward '_elevation'\n@forward '_layer'\n@forward '_position'\n@forward '_rounded'\n@forward '_rtl'\n@forward '_states'\n@forward '_theme'\n@forward '_typography'\n@forward '_utilities'\n@forward '_variant'\n@forward '_display'\n"
  },
  {
    "path": "packages/vuetify/src/styles/tools/_layer.scss",
    "content": "@use '../settings';\n\n@mixin layer ($name) {\n  @if ($name == 'transitions' or $name == 'trumps') {\n    $name: 'final.' + $name;\n  }\n  @at-root (without: layer) {\n    @layer vuetify-#{$name} {\n      @content;\n    }\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/styles/tools/_position.sass",
    "content": "@mixin position($positions)\n  @each $position in $positions\n    &--#{$position}\n      position: #{$position}\n"
  },
  {
    "path": "packages/vuetify/src/styles/tools/_rounded.sass",
    "content": "@mixin rounded($radius: null)\n  &\n    border-radius: $radius\n"
  },
  {
    "path": "packages/vuetify/src/styles/tools/_rtl.sass",
    "content": "@use 'sass:selector'\n\n@mixin rtl()\n  @at-root #{selector.append('.v-locale--is-rtl', &)},\n  .v-locale--is-rtl &\n    @content\n\n@mixin ltr()\n  @at-root #{selector.append('.v-locale--is-ltr', &)},\n  .v-locale--is-ltr &\n    @content\n"
  },
  {
    "path": "packages/vuetify/src/styles/tools/_states.sass",
    "content": "@use 'sass:map'\n@use 'sass:string'\n@use '../settings'\n\n@mixin states ($selector: '&::before', $active: true)\n  @if string.slice(string.unquote($selector), 1, 1) != '&'\n    $selector: #{'>'} #{$selector}\n\n  &:hover\n    #{$selector}\n      opacity: calc(#{map.get(settings.$states, 'hover')} * var(--v-theme-overlay-multiplier))\n\n  &:focus-visible\n    #{$selector}\n      opacity: calc(#{map.get(settings.$states, 'focus')} * var(--v-theme-overlay-multiplier))\n\n  @supports not selector(:focus-visible)\n    &:focus\n      #{$selector}\n        opacity: calc(#{map.get(settings.$states, 'focus')} * var(--v-theme-overlay-multiplier))\n\n  @if ($active)\n    &--active,\n    &[aria-haspopup=\"menu\"][aria-expanded=\"true\"]\n      @include active-states($selector)\n\n@mixin active-states ($selector, $base: map.get(settings.$states, 'activated'))\n  #{$selector}\n    opacity: calc(#{$base} * var(--v-theme-overlay-multiplier))\n\n  &:hover\n    #{$selector}\n      opacity: calc((#{$base} + #{map.get(settings.$states, 'hover')}) * var(--v-theme-overlay-multiplier))\n\n  &:focus-visible\n    #{$selector}\n      opacity: calc((#{$base} + #{map.get(settings.$states, 'focus')}) * var(--v-theme-overlay-multiplier))\n\n  @supports not selector(:focus-visible)\n    &:focus\n      #{$selector}\n        opacity: calc((#{$base} + #{map.get(settings.$states, 'focus')}) * var(--v-theme-overlay-multiplier))\n"
  },
  {
    "path": "packages/vuetify/src/styles/tools/_theme.sass",
    "content": "@mixin theme ($background, $color)\n  &\n    background: $background\n    color: $color\n"
  },
  {
    "path": "packages/vuetify/src/styles/tools/_typography.sass",
    "content": "@mixin typography ($font-size, $font-weight, $letter-spacing, $line-height, $text-transform)\n  &\n    font-size: $font-size\n    font-weight: $font-weight\n    letter-spacing: $letter-spacing\n    line-height: $line-height\n    text-transform: $text-transform\n"
  },
  {
    "path": "packages/vuetify/src/styles/tools/_utilities.sass",
    "content": "@use 'sass:list'\n@use 'sass:map'\n@use 'sass:meta'\n\n=generate-utility($utility, $infix, $forceDir)\n  $values: map.get($utility, values)\n\n  // If the values are a list or string, convert it into a map\n  @if meta.type-of($values) == \"string\" or meta.type-of(list.nth($values, 1)) != \"list\"\n    $values: list.zip($values, $values)\n\n  @each $value in $values\n    $properties: map.get($utility, property)\n\n    // Multiple properties are possible, for example with vertical or horizontal margins or paddings\n    @if meta.type-of($properties) == 'string'\n      $properties: list.append((), $properties)\n\n    // Property can be a map, where the key is a mixin to include\n    @if meta.type-of($properties) == 'map'\n      @each $dir in $properties\n        $mixin: list.nth($dir, 1)\n        // SASS doesn't support dynamic mixin invocation\n        // https://github.com/sass/sass/issues/626\n        @if $mixin == 'ltr'\n          .v-locale--is-ltr\n            @include generate-utility-body($utility, list.nth($dir, 2), $value, $infix)\n        @else if $mixin == 'rtl'\n          .v-locale--is-rtl\n            @include generate-utility-body($utility, list.nth($dir, 2), $value, $infix)\n        @else\n          @error 'Only RTL and LTR are supported'\n    @else\n      @if $forceDir == 'ltr'\n        .v-locale--is-ltr\n          @include generate-utility-body($utility, $properties, $value, $infix)\n      @else if $forceDir == 'rtl'\n        .v-locale--is-rtl\n          @include generate-utility-body($utility, $properties, $value, $infix)\n      @else\n        @include generate-utility-body($utility, $properties, $value, $infix)\n\n=generate-utility-body($utility, $properties, $value, $infix)\n  // Use custom class if present\n  $property-class: map.get($utility, class)\n  @if not $property-class\n    $property-class: list.nth($properties, 1)\n\n  // Don't prefix if value key is null (eg. with shadow class)\n  $property-class-modifier: ''\n  @if list.nth($value, 1)\n    $property-class-modifier: '-' + list.nth($value, 1)\n\n  $value: list.nth($value, 2)\n\n  .#{$property-class + $infix + $property-class-modifier}\n    @for $i from 1 through list.length($properties)\n      $property: list.nth($properties, $i)\n      $val: $value\n      @if meta.type-of($value) == 'list' and list.length($properties) == list.length($value)\n        $val: list.nth($value, $i)\n      @if $val != false\n        #{$property}: #{meta.inspect($val)}\n"
  },
  {
    "path": "packages/vuetify/src/styles/tools/_variant.sass",
    "content": "@use \"./absolute\" as *\n@use \"./elevation\" as *\n@use \"../settings/variables\" as *\n\n@mixin variant($contained-background, $contained-color, $contained-elevation, $plain-opacity, $name)\n  &--variant-plain,\n  &--variant-outlined,\n  &--variant-text,\n  &--variant-tonal\n    background: transparent\n    color: inherit\n\n  &--variant-plain\n    opacity: $plain-opacity\n\n    &:focus,\n    &:hover\n      opacity: 1\n\n  &--variant-plain\n    .#{$name}__overlay\n      display: none\n\n  &--variant-elevated,\n  &--variant-flat\n    background: $contained-background\n    color: $contained-color\n\n  @if ($contained-elevation > 0)\n    &--variant-elevated\n      @include elevation($contained-elevation)\n\n  &--variant-flat\n    @include elevation(0)\n\n  &--variant-outlined\n    border: $border-width-root solid currentColor\n\n  &--variant-text\n    .#{$name}__overlay\n      background: currentColor\n\n  &--variant-tonal\n    .#{$name}__underlay\n      background: currentColor\n      opacity: var(--v-activated-opacity)\n      border-radius: inherit\n      top: 0\n      right: 0\n      bottom: 0\n      left: 0\n      pointer-events: none\n\n  .#{$name}__underlay\n    position: absolute\n"
  },
  {
    "path": "packages/vuetify/src/styles/utilities/_display.sass",
    "content": "@use 'sass:list'\n@use 'sass:map'\n@use '../settings'\n@use '../tools'\n\n@if (settings.$utilities != false and map.get(settings.$misc, 'hidden') != false and list.length(settings.$utilities) > 0)\n  @include tools.layer('utilities.helpers')\n    @each $size, $media_query in settings.$display-breakpoints\n      .hidden\n        &-#{$size}\n          @media #{$media_query}\n            display: none !important\n"
  },
  {
    "path": "packages/vuetify/src/styles/utilities/_elevation.scss",
    "content": "@use 'sass:list';\n@use 'sass:map';\n@use '../tools';\n@use '../settings';\n\n@if (settings.$utilities != false and map.get(settings.$misc, 'elevation') != false and list.length(settings.$utilities) > 0) {\n  @property --v-elevation-overlay {\n    syntax: '<color>';\n    inherits: false;\n    initial-value: transparent;\n  }\n\n  @include tools.layer('utilities.helpers') {\n    @for $z from 0 through 5 {\n      .elevation-#{$z} {\n        @include tools.elevation($z);\n      }\n    }\n\n    .elevation-overlay {\n      background-image: linear-gradient(var(--v-elevation-overlay), var(--v-elevation-overlay));\n    }\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/styles/utilities/_index.sass",
    "content": "@use 'sass:string'\n@use 'sass:map'\n@use 'sass:meta'\n@use '../settings'\n@use '../tools'\n@use './display'\n@use './elevation'\n@use './pointer-events'\n@use './screenreaders'\n\n@include tools.layer('utilities.typography')\n  $typography: map.get(settings.$utilities, 'typography')\n  @if not ($typography == null or $typography == false)\n    @each $breakpoint in map.keys(settings.$grid-breakpoints)\n      @include tools.media-breakpoint-up($breakpoint)\n        $infix: tools.breakpoint-infix($breakpoint, settings.$grid-breakpoints)\n        @if map.get($typography, responsive) or $infix == \"\"\n          @include tools.generate-utility($typography, $infix, 'bidi')\n\n@include tools.layer('utilities.helpers')\n  @each $breakpoint in map.keys(settings.$grid-breakpoints)\n    // Generate media query if needed\n    @include tools.media-breakpoint-up($breakpoint)\n      $infix: tools.breakpoint-infix($breakpoint, settings.$grid-breakpoints)\n\n      // Loop over each utility property\n      @each $key, $utility in settings.$utilities\n        @if not ($key == 'typography')\n          // The utility can be disabled with `false`, thus check if the utility is a map first\n          // Only proceed if responsive media queries are enabled or if it's the base media query\n          @if string.slice($key, -4) == ':ltr'\n            @if meta.type-of($utility) == \"map\" and (map.get($utility, responsive) or $infix == \"\")\n              @include tools.generate-utility($utility, $infix, 'ltr')\n          @else if string.slice($key, -4) == ':rtl'\n            @if meta.type-of($utility) == \"map\" and (map.get($utility, responsive) or $infix == \"\")\n              @include tools.generate-utility($utility, $infix, 'rtl')\n          @else\n            @if meta.type-of($utility) == \"map\" and (map.get($utility, responsive) or $infix == \"\")\n              @include tools.generate-utility($utility, $infix, 'bidi')\n\n  // Print utilities\n  @media print\n    @each $key, $utility in settings.$utilities\n      // The utility can be disabled with `false`, thus check if the utility is a map first\n      // Then check if the utility needs print styles\n      @if string.slice($key, -4) == ':ltr'\n        @if meta.type-of($utility) == \"map\" and map.get($utility, print) == true\n          @include tools.generate-utility($utility, \"-print\", 'ltr')\n      @else if string.slice($key, -4) == ':rtl'\n        @if meta.type-of($utility) == \"map\" and map.get($utility, print) == true\n          @include tools.generate-utility($utility, \"-print\", 'rtl')\n      @else\n        @if meta.type-of($utility) == \"map\" and map.get($utility, print) == true\n          @include tools.generate-utility($utility, \"-print\", 'bidi')\n"
  },
  {
    "path": "packages/vuetify/src/styles/utilities/_pointer-events.sass",
    "content": "@use 'sass:list'\n@use 'sass:map'\n@use '../settings'\n@use '../tools'\n\n@if (settings.$utilities != false and map.get(settings.$misc, 'pointer-events') != false and list.length(settings.$utilities) > 0)\n  @include tools.layer('utilities.helpers')\n    .pointer-events-none\n      pointer-events: none !important\n\n    .pointer-events-auto\n      pointer-events: auto !important\n\n    .pointer-pass-through\n      pointer-events: none !important\n      > *\n        pointer-events: auto !important\n"
  },
  {
    "path": "packages/vuetify/src/styles/utilities/_screenreaders.sass",
    "content": "// Source: https://github.com/twbs/bootstrap/blob/master/scss/mixins/_screen-reader.scss\n@use 'sass:list'\n@use 'sass:map'\n@use '../settings'\n@use '../tools'\n\n@if (settings.$utilities != false and map.get(settings.$misc, 'sr-only') != false and list.length(settings.$utilities) > 0)\n  @include tools.layer('utilities.helpers')\n    .d-sr-only,\n    .d-sr-only-focusable:not(:focus)\n      border: 0 !important\n      clip: rect(0, 0, 0, 0) !important\n      height: 1px !important\n      margin: -1px !important // Fix for https://github.com/twbs/bootstrap/issues/25686\n      overflow: hidden !important\n      padding: 0 !important\n      position: absolute !important\n      white-space: nowrap !important\n      width: 1px !important\n"
  },
  {
    "path": "packages/vuetify/src/styles/utilities.scss",
    "content": "@use './utilities/index';\n"
  },
  {
    "path": "packages/vuetify/src/types.ts",
    "content": "/*\n * PUBLIC INTERFACES ONLY\n * Imports in our code should be to the actual source, not this file\n */\n\n// Util\nexport type { Anchor, JSXComponent } from '@/util'\n\n// Composables\nexport type { DateOptions, DateInstance, DateModule } from '@/composables/date'\nexport type { DefaultsInstance } from '@/composables/defaults'\nexport type { DisplayBreakpoint, DisplayInstance, DisplayThresholds } from '@/composables/display'\nexport type { FilterFunction, InternalItem, FilterMatch } from '@/composables/filter'\nexport type { SubmitEventPromise } from '@/composables/form'\nexport type { GoToInstance } from '@/composables/goto'\nexport type { IconAliases, IconProps, IconSet, IconOptions } from '@/composables/icons'\nexport type { LocaleInstance, LocaleMessages, RtlInstance, LocaleOptions, RtlOptions } from '@/composables/locale'\nexport type { ActiveStrategy } from '@/composables/nested/activeStrategies'\nexport type { OpenStrategy } from '@/composables/nested/openStrategies'\nexport type { SelectStrategy } from '@/composables/nested/selectStrategies'\nexport type { ThemeDefinition, ThemeInstance } from '@/composables/theme'\nexport type { ValidationRule } from '@/composables/validation'\n\n// Components\nexport type {\n  DataTableHeader,\n  DataTableCompareFunction,\n  RowPropsFunction as DataTableRowPropsFunction,\n  CellPropsFunction as DataTableCellPropsFunction,\n  HeaderCellPropsFunction as DataTableHeaderCellPropsFunction,\n} from '@/components/VDataTable/types'\nexport type { SortItem as DataTableSortItem } from '@/components/VDataTable/composables/sort'\nexport type { LocationStrategyFunction } from '@/components/VOverlay/locationStrategies'\nexport type { ScrollStrategyFunction } from '@/components/VOverlay/scrollStrategies'\nexport type { SnackbarMessage as SnackbarQueueMessage } from '@/components/VSnackbarQueue/VSnackbarQueue'\n"
  },
  {
    "path": "packages/vuetify/src/util/__tests__/colorUtils.spec.ts",
    "content": "// Utilities\nimport { APCAcontrast } from '../color/APCA'\nimport * as transformCIELAB from '../color/transformCIELAB'\nimport * as transformSRGB from '../color/transformSRGB'\nimport {\n  classToHex,\n  getContrast,\n  getLuma,\n  isCssColor,\n  parseColor,\n  parseGradient,\n} from '../colorUtils'\n\nconst colors = {\n  red: {\n    base: '#ff0000',\n    lighten1: '#ff6666',\n  },\n}\nconst currentTheme = { primary: '#1976d2' }\n\ndescribe('isCssColor', () => {\n  it('should return true if css color is passed', () => {\n    expect(isCssColor('#ff0000')).toBeTruthy()\n    expect(isCssColor('#fff')).toBeTruthy()\n    expect(isCssColor('rgb(255, 255, 255)')).toBeTruthy()\n    expect(isCssColor('rgba(255, 0, 0, 0.8)')).toBeTruthy()\n    expect(isCssColor('var(--my-color)')).toBeTruthy()\n  })\n\n  it('should return false if non-css color is passed', () => {\n    expect(isCssColor('red')).toBeFalsy()\n    expect(isCssColor('primary')).toBeFalsy()\n  })\n})\n\ndescribe('parseColor', () => {\n  it('should convert a hex string to a number', () => {\n    expect(parseColor('#123456')).toEqual({ r: 0x12, g: 0x34, b: 0x56, a: undefined })\n    expect(parseColor('#abc')).toEqual({ r: 0xaa, g: 0xbb, b: 0xcc, a: undefined })\n    expect(parseColor('876543')).toEqual({ r: 0x87, g: 0x65, b: 0x43, a: undefined })\n    expect(parseColor('669')).toEqual({ r: 0x66, g: 0x66, b: 0x99, a: undefined })\n    expect(parseColor('fff')).toEqual({ r: 0xff, g: 0xff, b: 0xff, a: undefined })\n  })\n\n  it('should parse a CSS color string', () => {\n    expect(parseColor('rgb(255, 0, 0)')).toEqual({ r: 255, g: 0, b: 0, a: undefined })\n    expect(parseColor('rgb(255 0 0)')).toEqual({ r: 255, g: 0, b: 0, a: undefined })\n    expect(parseColor('rgba(255, 0, 0, 0.5)')).toEqual({ r: 255, g: 0, b: 0, a: 0.5 })\n    expect(parseColor('rgba(255 0 0 / 0.5)')).toEqual({ r: 255, g: 0, b: 0, a: 0.5 })\n    expect(parseColor('hsl(100, 50%, 25%)')).toEqual({ r: 53, g: 96, b: 32, a: undefined })\n    expect(parseColor('hsla(100, 50%, 25%, 0.5)')).toEqual({ r: 53, g: 96, b: 32, a: 0.5 })\n    expect(parseColor('hsl(100 50 25 / 0.5)')).toEqual({ r: 53, g: 96, b: 32, a: 0.5 })\n  })\n\n  it('should parse rgb object', () => {\n    const rgb = { r: 128, g: 128, b: 0 }\n    expect(parseColor(rgb)).toEqual(expect.objectContaining({\n      r: expect.any(Number),\n      g: expect.any(Number),\n      b: expect.any(Number),\n    }))\n\n    const rgba = { r: 128, g: 0, b: 255, a: 0.2 }\n    expect(parseColor(rgba)).toEqual(expect.objectContaining({\n      r: expect.any(Number),\n      g: expect.any(Number),\n      b: expect.any(Number),\n      a: 0.2,\n    }))\n  })\n\n  it('should parse hsl object', () => {\n    const hsl = { h: 220, s: 0.5, l: 1 }\n    expect(parseColor(hsl)).toEqual(expect.objectContaining({\n      r: expect.any(Number),\n      g: expect.any(Number),\n      b: expect.any(Number),\n    }))\n\n    const hsla = { h: 220, s: 0.5, l: 1, a: 0.4 }\n    expect(parseColor(hsla)).toEqual(expect.objectContaining({\n      r: expect.any(Number),\n      g: expect.any(Number),\n      b: expect.any(Number),\n      a: 0.4,\n    }))\n  })\n\n  it('should parse hsv object', () => {\n    const hsv = { h: 220, s: 0.5, v: 1 }\n    expect(parseColor(hsv)).toEqual(expect.objectContaining({\n      r: expect.any(Number),\n      g: expect.any(Number),\n      b: expect.any(Number),\n    }))\n\n    const hsva = { h: 220, s: 0.5, v: 1, a: 0.4 }\n    expect(parseColor(hsva)).toEqual(expect.objectContaining({\n      r: expect.any(Number),\n      g: expect.any(Number),\n      b: expect.any(Number),\n      a: 0.4,\n    }))\n  })\n\n  it('should reject invalid formats', async () => {\n    // @ts-expect-error\n    expect(() => parseColor([]))\n      .toThrowErrorMatchingInlineSnapshot(`\n        [TypeError: Invalid color: Array\n        Expected #hex, #hexa, rgb(), rgba(), hsl(), hsla(), object or number]\n      `)\n    // @ts-expect-error\n    expect(() => parseColor(() => {}))\n      .toThrowErrorMatchingInlineSnapshot(`\n        [TypeError: Invalid color: () => {\n            }\n        Expected #hex, #hexa, rgb(), rgba(), hsl(), hsla(), object or number]\n      `)\n\n    parseColor(-1)\n    parseColor('#1000000')\n    parseColor('#13')\n    parseColor('#6')\n    parseColor('red')\n\n    expect(`'-1' is not a valid hex color`).toHaveBeenTipped()\n    expect(`'#1000000' is not a valid hex(a) color`).toHaveBeenTipped()\n    expect(`'#13' is not a valid hex(a) color`).toHaveBeenTipped()\n    expect(`'#6' is not a valid hex(a) color`).toHaveBeenTipped()\n    expect(`'red' is not a valid hex(a) color`).toHaveBeenTipped()\n  })\n})\n\ndescribe('classToHex', () => {\n  it('should convert a color class string to a hex string', () => {\n    expect(classToHex('red', colors, currentTheme)).toBe('#ff0000')\n    expect(classToHex('red lighten-1', colors, currentTheme)).toBe('#ff6666')\n    expect(classToHex('primary', colors, currentTheme)).toBe('#1976d2')\n  })\n})\n\ndescribe('transformSRGB', () => {\n  it('should convert sRGB to XYZ', () => {\n    expect(transformSRGB.toXYZ({ r: 0, g: 0, b: 0 })).toEqual([0, 0, 0])\n    expect(transformSRGB.toXYZ({ r: 0xff, g: 0xff, b: 0xff })).toEqual([0.9505, 1, 1.0890])\n    expect(transformSRGB.toXYZ({ r: 0xfc, g: 0xfb, b: 0xf4 })).toEqual(closeTo([0.909712, 0.962215, 0.993659], 6))\n    expect(transformSRGB.toXYZ({ r: 0x45, g: 0xa0, b: 0x81 })).toEqual(closeTo([0.189875, 0.279918, 0.251711], 6))\n    expect(transformSRGB.toXYZ({ r: 0x19, g: 0x19, b: 0x95 })).toEqual(closeTo([0.061733, 0.030719, 0.287013], 6))\n    expect(transformSRGB.toXYZ({ r: 0xcd, g: 0x66, b: 0x00 })).toEqual(closeTo([0.299282, 0.224819, 0.027620], 6))\n  })\n\n  it('should convert XYZ to sRGB', () => {\n    expect(transformSRGB.fromXYZ([0, 0, 0])).toEqual({ r: 0, g: 0, b: 0, a: undefined })\n    expect(transformSRGB.fromXYZ([0.9505, 1, 1.0890])).toEqual({ r: 0xff, g: 0xff, b: 0xff, a: undefined })\n    expect(transformSRGB.fromXYZ([0.909712, 0.962215, 0.993659])).toEqual({ r: 0xfc, g: 0xfb, b: 0xf4, a: undefined })\n    expect(transformSRGB.fromXYZ([0.189875, 0.279918, 0.251711])).toEqual({ r: 0x45, g: 0xa0, b: 0x81, a: undefined })\n    expect(transformSRGB.fromXYZ([0.061733, 0.030719, 0.287013])).toEqual({ r: 0x19, g: 0x19, b: 0x95, a: undefined })\n    expect(transformSRGB.fromXYZ([0.299282, 0.224819, 0.027620])).toEqual({ r: 0xcd, g: 0x66, b: 0x00, a: undefined })\n  })\n})\n\ndescribe('transformCIELAB', () => {\n  it('should convert LAB to XYZ', () => {\n    expect(transformCIELAB.toXYZ([0, 0, 0])).toEqual([0, 0, 0])\n    expect(transformCIELAB.toXYZ([100, 0.0053, -0.0104])).toEqual(closeTo([0.9505, 1, 1.0890], 4))\n    expect(transformCIELAB.toXYZ([98.5202, -0.8731, 3.4542])).toEqual(closeTo([0.909713, 0.962215, 0.99366], 6))\n    expect(transformCIELAB.toXYZ([59.8813, -34.7853, 8.0829])).toEqual(closeTo([0.189875, 0.279918, 0.251711], 6))\n    expect(transformCIELAB.toXYZ([20.3296, 44.3917, -65.5991])).toEqual(closeTo([0.061733, 0.030719, 0.287014], 6))\n    expect(transformCIELAB.toXYZ([54.5346, 36.1321, 62.8465])).toEqual(closeTo([0.299282, 0.224819, 0.027620], 6))\n  })\n\n  it('should convert XYZ to LAB', () => {\n    expect(transformCIELAB.fromXYZ([0, 0, 0])).toEqual([0, 0, 0])\n    expect(transformCIELAB.fromXYZ([0.9505, 1, 1.0890])).toEqual(closeTo([100, 0.0053, -0.0104], 4))\n    expect(transformCIELAB.fromXYZ([0.909712, 0.962215, 0.993659])).toEqual(closeTo([98.5202, -0.8731, 3.4542], 4))\n    expect(transformCIELAB.fromXYZ([0.189875, 0.279918, 0.251711])).toEqual(closeTo([59.8813, -34.7853, 8.0829], 4))\n    expect(transformCIELAB.fromXYZ([0.061733, 0.030719, 0.287014])).toEqual(closeTo([20.3296, 44.3917, -65.5991], 4))\n    expect(transformCIELAB.fromXYZ([0.299282, 0.224819, 0.027620])).toEqual(closeTo([54.5346, 36.1321, 62.8465], 4))\n  })\n})\n\ndescribe('parseGradient', () => {\n  it('should replace colors with their valid forms', () => {\n    expect(\n      parseGradient('to top, red lighten-1, rgba(#000, .8)', colors, currentTheme)\n    ).toBe('to top, #ff6666, rgba(0,0,0, .8)')\n    expect(\n      parseGradient('to top, #fff, primary', colors, currentTheme)\n    ).toBe('to top, #fff, #1976d2')\n    expect(\n      parseGradient('to top, var(--foo), rgba(#0000, .6)', colors, currentTheme)\n    ).toBe('to top, var(--foo), rgba(0,0,0, .6)')\n  })\n})\n\ndescribe('getContrast', () => {\n  it.each([\n    ['#000000', '#000000', 1],\n    ['#FFFFFF', '#000000', 21],\n    ['#FF0000', '#000000', 5.252],\n    ['#EEEEEE', '#333333', 10.88977979803735],\n    ['#111111', '#222222', 1.1868686010078233],\n  ])('given %s and %s, should return contrast ratio value of %d', (first, second, ratio) => {\n    expect(getContrast(first, second)).toEqual(ratio)\n  })\n\n  it.each([\n    ['#FFFFFF', '#000000', 21],\n    ['#000000', '#FFFFFF', 21],\n    ['#EEEEEE', '#333333', 10.88977979803735],\n    ['#333333', '#EEEEEE', 10.88977979803735],\n  ])('should not care which order colors are checked', (first, second, ratio) => {\n    expect(getContrast(first, second)).toEqual(ratio)\n  })\n})\n\ndescribe('getLuma', () => {\n  it('should return the Luma of a color', () => {\n    expect(getLuma('#45a081')).toBeCloseTo(0.279918, 6)\n    expect(getLuma('#191995')).toBeCloseTo(0.030719, 6)\n    expect(getLuma('#cd6600')).toBeCloseTo(0.224819, 6)\n    expect(getLuma(0)).toBe(0)\n    expect(getLuma(0xffffff)).toBe(1)\n  })\n})\n\ndescribe('APCAcontrast', () => {\n  it.each([\n    ['#888', '#fff', 66.89346308821438],\n    ['#aaa', '#000', -60.438571788907524],\n    ['#def', '#123', -98.44863435731264],\n    ['#123', '#234', 1.276075977788573],\n  ])('%s on %s', (text, bg, expected) => {\n    expect(APCAcontrast(parseColor(text), parseColor(bg))).toBeCloseTo(expected, 13)\n  })\n})\n\nfunction closeTo (arr: number[], precision = 3) {\n  return arr.map(n => expect.closeTo(n, precision))\n}\n"
  },
  {
    "path": "packages/vuetify/src/util/__tests__/deepEqual.spec.ts",
    "content": "import { deepEqual } from '../deepEqual'\n\ndescribe('helpers', () => {\n  it('should execute basic comparison', () => {\n    // Null\n    expect(deepEqual(null, null)).toBe(true)\n    expect(deepEqual(null, undefined)).toBe(false)\n    expect(deepEqual(null, false)).toBe(false)\n    expect(deepEqual(null, 0)).toBe(false)\n    expect(deepEqual(null, '')).toBe(false)\n    expect(deepEqual(null, [])).toBe(false)\n    expect(deepEqual(null, {})).toBe(false)\n\n    // Undefined\n    expect(deepEqual(undefined, undefined)).toBe(true)\n    expect(deepEqual(undefined, null)).toBe(false)\n    expect(deepEqual(undefined, false)).toBe(false)\n    expect(deepEqual(undefined, 0)).toBe(false)\n    expect(deepEqual(undefined, '')).toBe(false)\n    expect(deepEqual(undefined, [])).toBe(false)\n    expect(deepEqual(undefined, {})).toBe(false)\n\n    // Boolean\n    expect(deepEqual(true, true)).toBe(true)\n    expect(deepEqual(true, false)).toBe(false)\n    expect(deepEqual(true, undefined)).toBe(false)\n    expect(deepEqual(true, null)).toBe(false)\n    expect(deepEqual(true, 0)).toBe(false)\n    expect(deepEqual(true, 1)).toBe(false)\n    expect(deepEqual(true, '')).toBe(false)\n    expect(deepEqual(true, 'abc')).toBe(false)\n    expect(deepEqual(true, [1, 2])).toBe(false)\n    expect(deepEqual(true, { x: 1 })).toBe(false)\n\n    expect(deepEqual(false, false)).toBe(true)\n    expect(deepEqual(false, true)).toBe(false)\n    expect(deepEqual(false, undefined)).toBe(false)\n    expect(deepEqual(false, null)).toBe(false)\n    expect(deepEqual(false, 0)).toBe(false)\n    expect(deepEqual(false, 1)).toBe(false)\n    expect(deepEqual(false, '')).toBe(false)\n    expect(deepEqual(false, 'abc')).toBe(false)\n    expect(deepEqual(false, [1, 2])).toBe(false)\n    expect(deepEqual(false, { x: 1 })).toBe(false)\n\n    // Number\n    expect(deepEqual(5, 5)).toBe(true)\n    expect(deepEqual(8, 8.0)).toBe(true)\n    expect(deepEqual(8, '8')).toBe(false)\n    expect(deepEqual(-10, -10)).toBe(true)\n\n    expect(deepEqual(0, '')).toBe(false)\n    expect(deepEqual(0, false)).toBe(false)\n    expect(deepEqual(0, null)).toBe(false)\n    expect(deepEqual(0, undefined)).toBe(false)\n\n    // String\n    expect(deepEqual('', '')).toBe(true)\n    expect(deepEqual('a', 'a')).toBe(true)\n    expect(deepEqual('a', 'b')).toBe(false)\n    expect(deepEqual('a', 'A')).toBe(false)\n    expect(deepEqual('abc', 'abc')).toBe(true)\n    expect(deepEqual('Abc', 'abc')).toBe(false)\n    expect(deepEqual(' ', '')).toBe(false)\n\n    // Array\n    expect(deepEqual([], [])).toBe(true)\n    expect(deepEqual([1], [1.0])).toBe(true)\n    expect(deepEqual([1, '2'], [1, '2'])).toBe(true)\n    expect(deepEqual([1, { x: 1, y: 2 }], [1, { x: 1, y: 2 }])).toBe(true)\n    expect(deepEqual([1, { x: 1, y: null }], [1, { x: 1, y: false }])).toBe(false)\n    expect(deepEqual([1, [1, 2]], [1, [1, 2]])).toBe(true)\n\n    // Object\n    expect(deepEqual({}, {})).toBe(true)\n    expect(deepEqual({ x: 1 }, { x: 1 })).toBe(true)\n    expect(deepEqual({ x: 1 }, {})).toBe(false)\n    expect(deepEqual({ x: { a: 1, b: 2 } }, { x: { a: 1, b: 2 } })).toBe(true)\n\n    // Date\n    const currentDate = new Date()\n    const futureDate = new Date(1000)\n\n    expect(deepEqual(currentDate, currentDate)).toBe(true)\n    expect(deepEqual({ date: currentDate }, { date: currentDate })).toBe(true)\n    expect(deepEqual(currentDate, futureDate)).toBe(false)\n    expect(deepEqual({ date: currentDate }, { date: futureDate })).toBe(false)\n  })\n\n  it('should not fail on circular self-reference', () => {\n    const circular = { me: null as any }\n    circular.me = circular\n\n    expect(deepEqual(circular, circular)).toBe(true)\n    expect(deepEqual({ r: circular }, { r: circular })).toBe(true)\n    expect(deepEqual({ r: circular, x: 1 }, { r: circular, x: 2 })).toBe(false)\n    expect(deepEqual({ r: [circular] }, { r: [circular] })).toBe(true)\n  })\n\n  it('should not fail on circular cross-reference', () => {\n    const a = {} as any\n    const b = {} as any\n    a.item = { item: { item: { item: { item: { item: { item: b } } } } } }\n    b.item = { item: { item: { item: { item: { item: { item: a } } } } } }\n\n    const c = {} as any\n    c.item = { item: { item: c } }\n\n    expect(deepEqual(a, a)).toBe(true)\n    expect(deepEqual(a, b)).toBe(true)\n    expect(deepEqual(a, c)).toBe(true)\n\n    // sanity check\n    a.item.item.item.item.item.foo = 1\n    expect(deepEqual(a, a)).toBe(true)\n    expect(deepEqual(a, b)).toBe(false)\n  })\n\n  it('should not fail on more complex circular cross-reference', () => {\n    const a = { foo: 1, bar: null as any }\n    const b = { foo: 1, bar: null as any }\n    const c = { a, b }\n    a.bar = c\n    b.bar = c\n\n    expect(deepEqual(a, a)).toBe(true)\n    expect(deepEqual(a, b)).toBe(true)\n  })\n\n  it('should not fail on circular cross-reference with Sets', () => {\n    const setA = new Set()\n    const setB = new Set()\n    const setC = new Set()\n    setA.add(setC)\n    setB.add(setC)\n    setC.add(setA)\n    setC.add(setB)\n\n    expect(deepEqual(setA, setA)).toBe(true)\n    expect(deepEqual(setB, setB)).toBe(true)\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/util/__tests__/dom.spec.ts",
    "content": "// Utilities\nimport { mount } from '@vue/test-utils'\nimport { defineComponent, h } from 'vue'\nimport {\n  attachedRoot,\n} from '../dom'\n\nconst FooComponent = defineComponent(() => () => h('div', ['foo']))\n\ndescribe('dom', () => {\n  it('should properly detect an element\\'s root', () => {\n    const shadowHost = document.createElement('div')\n    expect(attachedRoot(shadowHost)).toBeNull()\n\n    const shadowRoot = shadowHost.attachShadow({ mode: 'closed' })\n    expect(attachedRoot(shadowRoot)).toBeNull()\n\n    document.body.appendChild(shadowHost)\n    expect(attachedRoot(shadowHost)).toBe(document)\n\n    expect(attachedRoot(shadowRoot)).toBe(shadowRoot)\n\n    const insideDiv = document.createElement('div')\n    expect(attachedRoot(insideDiv)).toBeNull()\n\n    shadowRoot.appendChild(insideDiv)\n    expect(attachedRoot(insideDiv)).toBe(shadowRoot)\n  })\n\n  it('should detect the root of mounted components', () => {\n    const attachedWrapper = mount(FooComponent, { attachTo: 'body' })\n    expect(attachedRoot(attachedWrapper.element)).toBe(document)\n\n    const detachedWrapper = mount(FooComponent, { attachTo: undefined })\n    expect(attachedRoot(detachedWrapper.element)).toBeNull()\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/util/__tests__/getCurrentInstance.spec.tsx",
    "content": "// Utilities\nimport { mount } from '@vue/test-utils'\nimport { getCurrentInstance } from '../getCurrentInstance'\n\ndescribe('getCurrentInstance.ts', () => {\n  it('should get and return current vm instance or throw error', () => {\n    expect(\n      () => getCurrentInstance('foobar')\n    ).toThrow('[Vuetify] foobar must be called from inside a setup function')\n\n    expect(\n      () => mount({\n        setup () {\n          getCurrentInstance('foobar')\n\n          return () => (<div></div>)\n        },\n      })\n    ).not.toThrow('[Vuetify] foobar must be called from inside a setup function')\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/util/__tests__/helpers.spec.ts",
    "content": "// Utilities\nimport { isProxy, isRef, ref } from 'vue'\nimport {\n  arrayDiff,\n  camelizeProps,\n  convertToUnit,\n  defer,\n  destructComputed,\n  extractNumber,\n  getNestedValue,\n  getObjectValueByPath,\n  getPropertyFromItem,\n  humanReadableFileSize,\n  isEmpty,\n  mergeDeep,\n} from '../helpers'\n\ndescribe('helpers', () => {\n  it('should return set difference of arrays A and B', () => {\n    expect(arrayDiff(['one', 'two'], ['one'])).toEqual([])\n    expect(arrayDiff(['one'], ['one', 'two'])).toEqual(['two'])\n    expect(arrayDiff([], [])).toEqual([])\n    expect(arrayDiff([], ['one'])).toEqual(['one'])\n    expect(arrayDiff(['one'], ['two'])).toEqual(['two'])\n    expect(arrayDiff(['one', 'two'], ['one', 'three'])).toEqual(['three'])\n  })\n\n  it('should get value directly on object if not undefined', () => {\n    const obj = {\n      a: 'foo',\n      'b.a': 'foobar',\n      b: {\n        a: 1,\n      },\n      'c.d': undefined,\n      c: {\n        d: 'bar',\n      },\n    }\n\n    expect(getObjectValueByPath(obj, 'a')).toBe('foo')\n    expect(getObjectValueByPath(obj, 'b.a')).toBe('foobar')\n    expect(getObjectValueByPath(obj, 'c.d')).toBe('bar')\n  })\n\n  it('should get nested value', () => {\n    const obj = {\n      a: {\n        b: {\n          c: 1,\n          d: 2,\n        },\n        e: [\n          { f: 'f' },\n          'e1',\n        ],\n      },\n      g: null,\n    }\n\n    expect(getNestedValue(obj, ['a', 'b', 'c'])).toBe(1)\n    expect(getNestedValue(obj, ['a', 'b', 'd'])).toBe(2)\n    expect(getNestedValue(obj, ['a', 'b'])).toEqual({ c: 1, d: 2 })\n    expect(getNestedValue(obj, ['a', 'e', '0', 'f'])).toBe('f')\n    expect(getNestedValue(obj, ['a', 'e', 0, 'f'])).toBe('f')\n    expect(getNestedValue(obj, ['a', 'e', '1'])).toBe('e1')\n    expect(getNestedValue(obj, ['g'])).toBeNull()\n    expect(getNestedValue(obj, ['missing', 'key'])).toBeUndefined()\n\n    const arr = ['val', obj]\n\n    expect(getNestedValue(arr, ['1', 'a', 'b', 'c'])).toBe(1)\n    expect(getNestedValue(arr, ['1', 'a', 'e', 0, 'f'])).toBe('f')\n    expect(getNestedValue(arr, [0])).toBe('val')\n    expect(getNestedValue(arr, [1])).toEqual(obj)\n\n    expect(getNestedValue('str', [])).toBe('str')\n    expect(getNestedValue(5, [])).toBe(5)\n    expect(getNestedValue(null, [])).toBeNull()\n\n    expect(getNestedValue(null, ['a'])).toBeUndefined()\n  })\n\n  it('should get property from items', () => {\n    const obj = {\n      a: {\n        b: 1,\n      },\n      c: [2, 3, { d: 'd' }],\n      'x.y': 'comp',\n      x: {\n        y: 'nested',\n      },\n    }\n    expect(getPropertyFromItem(obj, 'a.b')).toBe(1)\n    expect(getPropertyFromItem(obj, 'c.0')).toBe(2)\n    expect(getPropertyFromItem(obj, 'c.2.d')).toBe('d')\n    expect(getPropertyFromItem(obj, 'c.2.d.x', 'fallback')).toBe('fallback')\n    expect(getPropertyFromItem(obj, o => Number(o.a.b) + Number(o.c[0]))).toBe(3)\n    expect(getPropertyFromItem(obj, ['c', 2, 'd'])).toBe('d')\n    expect(getPropertyFromItem(obj, 'x.y')).toBe('comp')\n    expect(getPropertyFromItem(obj, ['x', 'y'])).toBe('nested')\n    expect(getPropertyFromItem(obj, ['x.y'])).toBe('comp')\n  })\n\n  it('should get property from primitive items', () => {\n    const a = 1\n    const b = 'string'\n    const c = Symbol('symbol')\n    const d = false\n\n    expect(getPropertyFromItem(a, v => v)).toBe(a)\n    expect(getPropertyFromItem(b, v => v)).toBe(b)\n    expect(getPropertyFromItem(c, v => v)).toBe(c)\n    expect(getPropertyFromItem(d, v => v)).toBe(d)\n  })\n\n  it('should return proper value in convertToUnit', () => {\n    expect(convertToUnit(undefined)).toBeUndefined()\n    expect(convertToUnit(null)).toBeUndefined()\n    expect(convertToUnit('')).toBeUndefined()\n\n    expect(convertToUnit(0)).toBe('0px')\n    expect(convertToUnit(3)).toBe('3px')\n    expect(convertToUnit(3.14)).toBe('3.14px')\n\n    expect(convertToUnit(0, 'em')).toBe('0em')\n    expect(convertToUnit(3, 'em')).toBe('3em')\n    expect(convertToUnit(3.14, 'em')).toBe('3.14em')\n\n    expect(convertToUnit('0vw')).toBe('0vw')\n    expect(convertToUnit('3vw')).toBe('3vw')\n    expect(convertToUnit('3.14vw')).toBe('3.14vw')\n\n    expect(convertToUnit('foo')).toBe('foo')\n  })\n\n  it('humanReadableFileSize should format file sizes with base 1024', () => {\n    expect(humanReadableFileSize(0, 1024)).toBe('0 B')\n    expect(humanReadableFileSize(512, 1024)).toBe('512 B')\n\n    expect(humanReadableFileSize(1024, 1024)).toBe('1.0 KiB')\n    expect(humanReadableFileSize(4096, 1024)).toBe('4.0 KiB')\n\n    expect(humanReadableFileSize(1048576, 1024)).toBe('1.0 MiB')\n    expect(humanReadableFileSize(2097152, 1024)).toBe('2.0 MiB')\n\n    expect(humanReadableFileSize(1073741824, 1024)).toBe('1.0 GiB')\n    expect(humanReadableFileSize(2147483648, 1024)).toBe('2.0 GiB')\n  })\n\n  it('humanReadableFileSize should format file sizes with base 1000', () => {\n    expect(humanReadableFileSize(0)).toBe('0 B')\n    expect(humanReadableFileSize(512)).toBe('512 B')\n\n    expect(humanReadableFileSize(1000)).toBe('1.0 kB')\n    expect(humanReadableFileSize(4000)).toBe('4.0 kB')\n\n    expect(humanReadableFileSize(1000000)).toBe('1.0 MB')\n    expect(humanReadableFileSize(2000000)).toBe('2.0 MB')\n\n    expect(humanReadableFileSize(1000000000)).toBe('1.0 GB')\n    expect(humanReadableFileSize(2000000000)).toBe('2.0 GB')\n  })\n\n  describe('mergeDeep', () => {\n    it('should include all properties from both source and target', () => {\n      expect(mergeDeep({ a: 'foo' }, { b: 'bar' })).toEqual({ a: 'foo', b: 'bar' })\n    })\n\n    it('should not mutate source object', () => {\n      const source = { a: 'foo' }\n      const target = { b: 'bar' }\n      const result = mergeDeep(source, target)\n\n      expect(result).not.toBe(source)\n      expect(source).not.toHaveProperty('b')\n    })\n\n    it('should overwrite source properties', () => {\n      expect(mergeDeep({ a: 'foo' }, { a: 'bar' })).toEqual({ a: 'bar' })\n    })\n\n    it('should recursively merge', () => {\n      expect(mergeDeep({ a: { b: 'foo' } }, { c: { d: 'bar' } })).toEqual({ a: { b: 'foo' }, c: { d: 'bar' } })\n    })\n\n    it('should not recursively merge arrays', () => {\n      expect(mergeDeep({ a: ['foo'] }, { a: ['bar'] })).toEqual({ a: ['bar'] })\n    })\n\n    it('should use arrayFn function if provided', () => {\n      expect(mergeDeep({ a: ['foo'] }, { a: ['bar'] }, (a, b) => [...a, ...b])).toEqual({ a: ['foo', 'bar'] })\n    })\n\n    it('should not recursively merge non-plain objects', () => {\n      const plain = { a: 'foo' }\n      const div = document.createElement('div')\n      const span = document.createElement('span')\n\n      expect(mergeDeep({ a: plain }, { a: div }).a).toBe(div)\n      expect(mergeDeep({ a: div }, { a: plain }).a).toBe(plain)\n      expect(mergeDeep({ a: div }, { a: span }).a).toBe(span)\n    })\n  })\n\n  describe('destructComputed', () => {\n    it('should return object as refs', () => {\n      const obj = destructComputed(() => {\n        return {\n          a: 'foo',\n          b: 'bar',\n        }\n      })\n\n      expect(obj).toHaveProperty('a')\n      expect(obj).toHaveProperty('b')\n      expect(isRef(obj.a)).toBeTruthy()\n      expect(isRef(obj.b)).toBeTruthy()\n      expect(isProxy(obj)).toBeFalsy()\n    })\n\n    it('should be reactive', async () => {\n      const val = ref('foo')\n      const obj = destructComputed(() => {\n        return {\n          a: val.value,\n        }\n      })\n\n      expect(obj.a.value).toBe('foo')\n\n      val.value = 'bar'\n\n      expect(obj.a.value).toBe('bar')\n    })\n  })\n\n  describe('isEmpty', () => {\n    it('should be empty value', () => {\n      expect(isEmpty(null)).toBeTruthy()\n      expect(isEmpty(undefined)).toBeTruthy()\n      expect(isEmpty('')).toBeTruthy()\n      expect(isEmpty(' ')).toBeTruthy()\n      expect(isEmpty('sample text')).toBeFalsy()\n      expect(isEmpty(12345)).toBeFalsy()\n    })\n  })\n\n  describe('defer', () => {\n    beforeAll(() => {\n      vi.useFakeTimers()\n    })\n\n    it('executes callback immediately if timeout is 0', () => {\n      const mockCallback = vi.fn()\n      defer(0, mockCallback)()\n\n      expect(mockCallback).toHaveBeenCalledWith()\n    })\n\n    it('executes callback after specified timeout', () => {\n      const mockCallback = vi.fn()\n      defer(1000, mockCallback)\n\n      expect(mockCallback).not.toHaveBeenCalled()\n      vi.advanceTimersByTime(1000)\n      expect(mockCallback).toHaveBeenCalledWith()\n    })\n\n    it('provides a function to clear the timeout', () => {\n      const mockCallback = vi.fn()\n      const clear = defer(1000, mockCallback)\n\n      clear()\n      vi.advanceTimersByTime(1000)\n\n      expect(mockCallback).not.toHaveBeenCalled()\n    })\n  })\n\n  describe('extractNumber', () => {\n    it('should parse valid number out of text', () => {\n      // dot\n      expect(extractNumber(' 2,142,400.50 ', 2, '.')).toBe('2142400.50')\n      expect(extractNumber(' 100 %', 1, '.')).toBe('100')\n      expect(extractNumber(' .4099 ', 2, '.')).toBe('.40')\n      expect(extractNumber('v: 15.00 ', 0, '.')).toBe('15')\n      expect(extractNumber('$ 2,132.00', 2, '.')).toBe('2132.00')\n      expect(extractNumber('$ 32.00', 2, '.')).toBe('32.00')\n      expect(extractNumber(' -6.67 USD', 2, '.')).toBe('-6.67')\n      expect(extractNumber('($9,000.00)', 2, '.')).toBe('9000.00')\n      expect(extractNumber(' 23 567.20 ', 2, '.')).toBe('23567.20')\n      expect(extractNumber('-200.99 ', 1, '.')).toBe('-200.9')\n\n      // comma\n      expect(extractNumber(' 2,142,400.50 ', 2, ',')).toBe('2,14')\n      expect(extractNumber(' 100 %', 1, ',')).toBe('100')\n      expect(extractNumber(' ,4099 ', 2, ',')).toBe(',40')\n      expect(extractNumber('v: 15.00 ', 0, ',')).toBe('1500')\n      expect(extractNumber('$ 2,132.00', 2, ',')).toBe('2,13')\n      expect(extractNumber('$ 32,00', 2, ',')).toBe('32,00')\n      expect(extractNumber(' -6,67 USD', 2, ',')).toBe('-6,67')\n      expect(extractNumber('($9.000,00)', 2, ',')).toBe('9000,00')\n      expect(extractNumber(' 23 567,20 ', 2, ',')).toBe('23567,20')\n      expect(extractNumber('-200,99 ', 1, ',')).toBe('-200,9')\n    })\n  })\n\n  describe('camelizeProps', () => {\n    it('should convert kebab-case props to camelCase', () => {\n      const props = {\n        'background-color': 'red',\n        fontSize: '16px',\n        'border-radius': '4px',\n      }\n\n      const result = camelizeProps(props)\n\n      expect(result).toEqual({\n        backgroundColor: 'red',\n        fontSize: '16px',\n        borderRadius: '4px',\n      })\n    })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/util/__tests__/propsFactory.spec.ts",
    "content": "// Utilities\nimport { propsFactory } from '../propsFactory'\n\ndescribe('propsFactory', () => {\n  it.each([\n    [String, undefined, { type: String }],\n    [String, '', { type: String, default: '' }],\n    [String, false, { type: String, default: false }],\n    [{ type: String }, '', { type: String, default: '' }],\n\n    [[Boolean, String], undefined, { type: [Boolean, String] }],\n    [[Boolean, String], 6, { type: [Boolean, String], default: 6 }],\n\n    [null, undefined, { type: null }],\n  ])('propsFactory %#', (definition, defaults, result) => {\n    expect(\n      // @ts-expect-error\n      propsFactory({ foo: definition })(\n        defaults === undefined ? defaults : { foo: defaults }\n      )\n    ).toStrictEqual({ foo: result })\n  })\n\n  it.each([\n    [String, undefined, { type: String }],\n    [String, 'bar', { type: String, source: 'bar' }],\n    [{ type: String }, 'bar', { type: String, source: 'bar' }],\n    [[Boolean, String], 'bar', { type: [Boolean, String], source: 'bar' }],\n  ])('should set source property %#', (definition, source, result) => {\n    expect(\n      // @ts-expect-error\n      propsFactory({ foo: definition }, source)()\n    ).toStrictEqual({ foo: result })\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/util/__tests__/throttle.spec.ts",
    "content": "import { throttle } from '../throttle'\n\n// Utilities\nimport { wait } from '@test'\n\ndescribe('throttle', { retry: 3 }, () => {\n  it('should execute only the calls right before the interval', async () => {\n    const result = [] as number[]\n    const pushThrottled = throttle((v: number) => result.push(v), 100, { leading: false, trailing: false })\n\n    let lastId = 0\n    const interval = setInterval(() => pushThrottled(++lastId), 30)\n    await wait(280)\n    clearInterval(interval)\n\n    expect(result).toStrictEqual([5, 9])\n  })\n\n  it('should execute only the calls right before the interval + trailing one', async () => {\n    const result = [] as number[]\n    const pushThrottled = throttle((v: number) => result.push(v), 100, { leading: false, trailing: true })\n\n    let lastId = 0\n    const interval = setInterval(() => pushThrottled(++lastId), 30)\n    await wait(280)\n    clearInterval(interval)\n    await wait(100)\n\n    expect(result).toStrictEqual([4, 7, 9])\n  })\n\n  it('should keep throttling after executing trailing call', async () => {\n    const result = [] as number[]\n    const pushThrottled = throttle((v: number) => result.push(v), 100, { leading: false, trailing: true })\n\n    let lastId = 0\n    setTimeout(() => pushThrottled(++lastId), 0)\n    setTimeout(() => pushThrottled(++lastId), 40)\n    setTimeout(() => pushThrottled(++lastId), 180)\n    setTimeout(() => pushThrottled(++lastId), 190)\n    await wait(280)\n\n    expect(result).toStrictEqual([2, 4])\n  })\n\n  it('should execute only the calls right before the interval + leading and trailing', async () => {\n    const result = [] as number[]\n    const pushThrottled = throttle((v: number) => result.push(v), 100)\n\n    let lastId = 0\n    const interval = setInterval(() => pushThrottled(++lastId), 30)\n    await wait(280)\n    clearInterval(interval)\n    await wait(100)\n\n    expect(result).toStrictEqual([1, 4, 7, 9])\n  })\n\n  it('should pass calls the same way when resumed', async () => {\n    const result = [] as number[]\n    const pushThrottled = throttle((v: number) => result.push(v), 100)\n\n    let lastId = 0\n    let interval = setInterval(() => pushThrottled(++lastId), 30)\n    await wait(280)\n    clearInterval(interval)\n    await wait(150)\n\n    lastId = 200\n    interval = setInterval(() => pushThrottled(++lastId), 30)\n    await wait(280)\n    clearInterval(interval)\n    await wait(100)\n\n    expect(result).toStrictEqual([1, 4, 7, 9, 201, 204, 207, 209])\n  })\n})\n"
  },
  {
    "path": "packages/vuetify/src/util/anchor.ts",
    "content": "// Utilities\nimport { includes } from '@/util/helpers'\n\nconst block = ['top', 'bottom'] as const\nconst inline = ['start', 'end', 'left', 'right'] as const\ntype Tblock = typeof block[number]\ntype Tinline = typeof inline[number]\nexport type Anchor =\n  | Tblock\n  | Tinline\n  | 'center'\n  | 'center center'\n  | `${Tblock} ${Tinline | 'center'}`\n  | `${Tinline} ${Tblock | 'center'}`\nexport type ParsedAnchor =\n  | { side: 'center', align: 'center' }\n  | { side: Tblock, align: 'left' | 'right' | 'center' }\n  | { side: 'left' | 'right', align: Tblock | 'center' }\n\n/** Parse a raw anchor string into an object */\nexport function parseAnchor (anchor: Anchor, isRtl: boolean) {\n  let [side, align] = anchor.split(' ') as [Tblock | Tinline | 'center', Tblock | Tinline | 'center' | undefined]\n  if (!align) {\n    align =\n      includes(block, side) ? 'start'\n      : includes(inline, side) ? 'top'\n      : 'center'\n  }\n\n  return {\n    side: toPhysical(side, isRtl),\n    align: toPhysical(align, isRtl),\n  } as ParsedAnchor\n}\n\nexport function toPhysical (str: 'center' | Tblock | Tinline, isRtl: boolean) {\n  if (str === 'start') return isRtl ? 'right' : 'left'\n  if (str === 'end') return isRtl ? 'left' : 'right'\n  return str\n}\n\nexport function flipSide (anchor: ParsedAnchor) {\n  return {\n    side: {\n      center: 'center',\n      top: 'bottom',\n      bottom: 'top',\n      left: 'right',\n      right: 'left',\n    }[anchor.side],\n    align: anchor.align,\n  } as ParsedAnchor\n}\n\nexport function flipAlign (anchor: ParsedAnchor) {\n  return {\n    side: anchor.side,\n    align: {\n      center: 'center',\n      top: 'bottom',\n      bottom: 'top',\n      left: 'right',\n      right: 'left',\n    }[anchor.align],\n  } as ParsedAnchor\n}\n\nexport function flipCorner (anchor: ParsedAnchor) {\n  return {\n    side: anchor.align,\n    align: anchor.side,\n  } as ParsedAnchor\n}\n\nexport function getAxis (anchor: ParsedAnchor) {\n  return includes(block, anchor.side) ? 'y' : 'x'\n}\n"
  },
  {
    "path": "packages/vuetify/src/util/animation.ts",
    "content": "// Utilities\nimport { Box } from '@/util/box'\n\n/** @see https://stackoverflow.com/a/57876601/2074736 */\nexport function nullifyTransforms (el: HTMLElement): Box {\n  const rect = new Box(el)\n  const style = getComputedStyle(el)\n  const tx = style.transform\n\n  if (tx) {\n    let ta, sx, sy, dx, dy\n    if (tx.startsWith('matrix3d(')) {\n      ta = tx.slice(9, -1).split(/, /)\n      sx = Number(ta[0])\n      sy = Number(ta[5])\n      dx = Number(ta[12])\n      dy = Number(ta[13])\n    } else if (tx.startsWith('matrix(')) {\n      ta = tx.slice(7, -1).split(/, /)\n      sx = Number(ta[0])\n      sy = Number(ta[3])\n      dx = Number(ta[4])\n      dy = Number(ta[5])\n    } else {\n      return new Box(rect)\n    }\n\n    const to = style.transformOrigin\n    const x = rect.x - dx - (1 - sx) * parseFloat(to)\n    const y = rect.y - dy - (1 - sy) * parseFloat(to.slice(to.indexOf(' ') + 1))\n    const w = sx ? rect.width / sx : el.offsetWidth + 1\n    const h = sy ? rect.height / sy : el.offsetHeight + 1\n\n    return new Box({ x, y, width: w, height: h })\n  } else {\n    return new Box(rect)\n  }\n}\n\nexport function animate (\n  el: Element,\n  keyframes: Keyframe[] | PropertyIndexedKeyframes | null,\n  options?: number | KeyframeAnimationOptions\n) {\n  if (typeof el.animate === 'undefined') return { finished: Promise.resolve() }\n\n  let animation: Animation\n  try {\n    animation = el.animate(keyframes, options)\n  } catch (err) {\n    return { finished: Promise.resolve() }\n  }\n\n  if (typeof animation.finished === 'undefined') {\n    (animation as any).finished = new Promise(resolve => {\n      animation.onfinish = () => {\n        resolve(animation)\n      }\n    })\n  }\n\n  return animation\n}\n"
  },
  {
    "path": "packages/vuetify/src/util/bindProps.ts",
    "content": "// Utilities\nimport { eventName, isOn } from '@/util/helpers'\n\nconst handlers = new WeakMap<HTMLElement, Set<[string, () => void]>>()\n\nexport function bindProps (el: HTMLElement, props: Record<string, any>) {\n  Object.keys(props).forEach(k => {\n    if (isOn(k)) {\n      const name = eventName(k)\n      const handler = handlers.get(el)\n      if (props[k] == null) {\n        handler?.forEach(v => {\n          const [n, fn] = v\n          if (n === name) {\n            el.removeEventListener(name, fn)\n            handler.delete(v)\n          }\n        })\n      } else if (!handler || ![...handler]?.some(v => v[0] === name && v[1] === props[k])) {\n        el.addEventListener(name, props[k])\n        const _handler = handler || new Set()\n        _handler.add([name, props[k]])\n        if (!handlers.has(el)) handlers.set(el, _handler)\n      }\n    } else {\n      if (props[k] == null) {\n        el.removeAttribute(k)\n      } else {\n        el.setAttribute(k, props[k])\n      }\n    }\n  })\n}\n\nexport function unbindProps (el: HTMLElement, props: Record<string, any>) {\n  Object.keys(props).forEach(k => {\n    if (isOn(k)) {\n      const name = eventName(k)\n      const handler = handlers.get(el)\n      handler?.forEach(v => {\n        const [n, fn] = v\n        if (n === name) {\n          el.removeEventListener(name, fn)\n          handler.delete(v)\n        }\n      })\n    } else {\n      el.removeAttribute(k)\n    }\n  })\n}\n"
  },
  {
    "path": "packages/vuetify/src/util/box.ts",
    "content": "export class Box {\n  x: number\n  y: number\n  width: number\n  height: number\n\n  constructor (args: Element | {\n    x: number\n    y: number\n    width: number\n    height: number\n  }) {\n    const pageScale = document.body.currentCSSZoom ?? 1\n    const isElement = args instanceof Element\n    const factor = isElement ? 1 + (1 - pageScale) / pageScale : 1\n\n    const { x, y, width, height } = isElement ? args.getBoundingClientRect() : args\n\n    this.x = x * factor\n    this.y = y * factor\n    this.width = width * factor\n    this.height = height * factor\n  }\n\n  get top () { return this.y }\n  get bottom () { return this.y + this.height }\n  get left () { return this.x }\n  get right () { return this.x + this.width }\n}\n\nexport function getOverflow (a: Box, b: Box) {\n  return {\n    x: {\n      before: Math.max(0, b.left - a.left),\n      after: Math.max(0, a.right - b.right),\n    },\n    y: {\n      before: Math.max(0, b.top - a.top),\n      after: Math.max(0, a.bottom - b.bottom),\n    },\n  }\n}\n\nexport function getTargetBox (target: HTMLElement | [x: number, y: number]): Box {\n  if (Array.isArray(target)) {\n    const pageScale = document.body.currentCSSZoom ?? 1\n    const factor = 1 + (1 - pageScale) / pageScale\n\n    return new Box({\n      x: target[0] * factor,\n      y: target[1] * factor,\n      width: 0 * factor,\n      height: 0 * factor,\n    })\n  } else {\n    return new Box(target)\n  }\n}\n\nexport function getElementBox (el: HTMLElement) {\n  if (el === document.documentElement) {\n    if (!visualViewport) {\n      return new Box({\n        x: 0,\n        y: 0,\n        width: document.documentElement.clientWidth,\n        height: document.documentElement.clientHeight,\n      })\n    } else {\n      const pageScale = document.body.currentCSSZoom ?? 1\n      return new Box({\n        x: visualViewport.scale > 1 ? 0 : visualViewport.offsetLeft,\n        y: visualViewport.scale > 1 ? 0 : visualViewport.offsetTop,\n        width: visualViewport.width * visualViewport.scale / pageScale,\n        height: visualViewport.height * visualViewport.scale / pageScale,\n      })\n    }\n  } else {\n    return new Box(el)\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/util/color/APCA.ts",
    "content": "/**\n * WCAG 3.0 APCA perceptual contrast algorithm from https://github.com/Myndex/SAPC-APCA\n * @licence https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document\n * @see https://www.w3.org/WAI/GL/task-forces/silver/wiki/Visual_Contrast_of_Text_Subgroup\n */\n// Types\nimport type { RGB } from '@/util'\n\n// MAGICAL NUMBERS\n\n// sRGB Conversion to Relative Luminance (Y)\n\n// Transfer Curve (aka \"Gamma\") for sRGB linearization\n// Simple power curve vs piecewise described in docs\n// Essentially, 2.4 best models actual display\n// characteristics in combination with the total method\nconst mainTRC = 2.4\n\nconst Rco = 0.2126729 // sRGB Red Coefficient (from matrix)\nconst Gco = 0.7151522 // sRGB Green Coefficient (from matrix)\nconst Bco = 0.0721750 // sRGB Blue Coefficient (from matrix)\n\n// For Finding Raw SAPC Contrast from Relative Luminance (Y)\n\n// Constants for SAPC Power Curve Exponents\n// One pair for normal text, and one for reverse\n// These are the \"beating heart\" of SAPC\nconst normBG = 0.55\nconst normTXT = 0.58\nconst revTXT = 0.57\nconst revBG = 0.62\n\n// For Clamping and Scaling Values\n\nconst blkThrs = 0.03 // Level that triggers the soft black clamp\nconst blkClmp = 1.45 // Exponent for the soft black clamp curve\nconst deltaYmin = 0.0005 // Lint trap\nconst scaleBoW = 1.25 // Scaling for dark text on light\nconst scaleWoB = 1.25 // Scaling for light text on dark\nconst loConThresh = 0.078 // Threshold for new simple offset scale\nconst loConFactor = 12.82051282051282 // = 1/0.078,\nconst loConOffset = 0.06 // The simple offset\nconst loClip = 0.001 // Output clip (lint trap #2)\n\nexport function APCAcontrast (text: RGB, background: RGB) {\n  // Linearize sRGB\n  const Rtxt = (text.r / 255) ** mainTRC\n  const Gtxt = (text.g / 255) ** mainTRC\n  const Btxt = (text.b / 255) ** mainTRC\n\n  const Rbg = (background.r / 255) ** mainTRC\n  const Gbg = (background.g / 255) ** mainTRC\n  const Bbg = (background.b / 255) ** mainTRC\n\n  // Apply the standard coefficients and sum to Y\n  let Ytxt = (Rtxt * Rco) + (Gtxt * Gco) + (Btxt * Bco)\n  let Ybg = (Rbg * Rco) + (Gbg * Gco) + (Bbg * Bco)\n\n  // Soft clamp Y when near black.\n  // Now clamping all colors to prevent crossover errors\n  if (Ytxt <= blkThrs) Ytxt += (blkThrs - Ytxt) ** blkClmp\n  if (Ybg <= blkThrs) Ybg += (blkThrs - Ybg) ** blkClmp\n\n  // Return 0 Early for extremely low ∆Y (lint trap #1)\n  if (Math.abs(Ybg - Ytxt) < deltaYmin) return 0.0\n\n  // SAPC CONTRAST\n\n  let outputContrast: number // For weighted final values\n  if (Ybg > Ytxt) {\n    // For normal polarity, black text on white\n    // Calculate the SAPC contrast value and scale\n\n    const SAPC = ((Ybg ** normBG) - (Ytxt ** normTXT)) * scaleBoW\n\n    // NEW! SAPC SmoothScale™\n    // Low Contrast Smooth Scale Rollout to prevent polarity reversal\n    // and also a low clip for very low contrasts (lint trap #2)\n    // much of this is for very low contrasts, less than 10\n    // therefore for most reversing needs, only loConOffset is important\n    outputContrast =\n      (SAPC < loClip) ? 0.0\n      : (SAPC < loConThresh) ? SAPC - SAPC * loConFactor * loConOffset\n      : SAPC - loConOffset\n  } else {\n    // For reverse polarity, light text on dark\n    // WoB should always return negative value.\n\n    const SAPC = ((Ybg ** revBG) - (Ytxt ** revTXT)) * scaleWoB\n\n    outputContrast =\n      (SAPC > -loClip) ? 0.0\n      : (SAPC > -loConThresh) ? SAPC - SAPC * loConFactor * loConOffset\n      : SAPC + loConOffset\n  }\n\n  return outputContrast * 100\n}\n"
  },
  {
    "path": "packages/vuetify/src/util/color/transformCIELAB.ts",
    "content": "// Types\nimport type { LAB, XYZ } from '../colorUtils'\n\nconst delta = 0.20689655172413793 // 6÷29\n\nconst cielabForwardTransform = (t: number): number => (\n  t > delta ** 3\n    ? Math.cbrt(t)\n    : (t / (3 * delta ** 2)) + 4 / 29\n)\n\nconst cielabReverseTransform = (t: number): number => (\n  t > delta\n    ? t ** 3\n    : (3 * delta ** 2) * (t - 4 / 29)\n)\n\nexport function fromXYZ (xyz: XYZ): LAB {\n  const transform = cielabForwardTransform\n  const transformedY = transform(xyz[1])\n\n  return [\n    116 * transformedY - 16,\n    500 * (transform(xyz[0] / 0.95047) - transformedY),\n    200 * (transformedY - transform(xyz[2] / 1.08883)),\n  ]\n}\n\nexport function toXYZ (lab: LAB): XYZ {\n  const transform = cielabReverseTransform\n  const Ln = (lab[0] + 16) / 116\n  return [\n    transform(Ln + lab[1] / 500) * 0.95047,\n    transform(Ln),\n    transform(Ln - lab[2] / 200) * 1.08883,\n  ]\n}\n"
  },
  {
    "path": "packages/vuetify/src/util/color/transformSRGB.ts",
    "content": "// Utilities\nimport { clamp } from '@/util/helpers'\n\n// Types\nimport type { RGB, XYZ } from '../colorUtils'\n\n// For converting XYZ to sRGB\nconst srgbForwardMatrix = [\n  [3.2406, -1.5372, -0.4986],\n  [-0.9689, 1.8758, 0.0415],\n  [0.0557, -0.2040, 1.0570],\n]\n\n// Forward gamma adjust\nconst srgbForwardTransform = (C: number): number => (\n  C <= 0.0031308\n    ? C * 12.92\n    : 1.055 * C ** (1 / 2.4) - 0.055\n)\n\n// For converting sRGB to XYZ\nconst srgbReverseMatrix = [\n  [0.4124, 0.3576, 0.1805],\n  [0.2126, 0.7152, 0.0722],\n  [0.0193, 0.1192, 0.9505],\n]\n\n// Reverse gamma adjust\nconst srgbReverseTransform = (C: number): number => (\n  C <= 0.04045\n    ? C / 12.92\n    : ((C + 0.055) / 1.055) ** 2.4\n)\n\nexport function fromXYZ (xyz: XYZ): RGB {\n  const rgb = Array(3)\n  const transform = srgbForwardTransform\n  const matrix = srgbForwardMatrix\n\n  // Matrix transform, then gamma adjustment\n  for (let i = 0; i < 3; ++i) {\n    // Rescale back to [0, 255]\n    rgb[i] = Math.round(clamp(transform(\n      matrix[i][0] * xyz[0] +\n      matrix[i][1] * xyz[1] +\n      matrix[i][2] * xyz[2]\n    )) * 255)\n  }\n\n  return {\n    r: rgb[0],\n    g: rgb[1],\n    b: rgb[2],\n  }\n}\n\nexport function toXYZ ({ r, g, b }: RGB): XYZ {\n  const xyz: XYZ = [0, 0, 0]\n  const transform = srgbReverseTransform\n  const matrix = srgbReverseMatrix\n\n  // Rescale from [0, 255] to [0, 1] then adjust sRGB gamma to linear RGB\n  r = transform(r / 255)\n  g = transform(g / 255)\n  b = transform(b / 255)\n\n  // Matrix color space transform\n  for (let i = 0; i < 3; ++i) {\n    xyz[i] = matrix[i][0] * r + matrix[i][1] * g + matrix[i][2] * b\n  }\n\n  return xyz\n}\n"
  },
  {
    "path": "packages/vuetify/src/util/colorUtils.ts",
    "content": "// Utilities\nimport { APCAcontrast } from './color/APCA'\nimport { consoleWarn } from './console'\nimport { chunk, has, padEnd } from './helpers'\nimport * as CIELAB from '@/util/color/transformCIELAB'\nimport * as sRGB from '@/util/color/transformSRGB'\n\n// Types\nimport type { Colors } from '@/composables/theme'\n\nexport type XYZ = [number, number, number]\nexport type LAB = [number, number, number]\nexport type HSV = { h: number, s: number, v: number, a?: number }\nexport type RGB = { r: number, g: number, b: number, a?: number }\nexport type HSL = { h: number, s: number, l: number, a?: number }\nexport type Hex = string & { __hexBrand: never }\nexport type Color = string | number | HSV | RGB | HSL\n\nexport function isCssColor (color?: string | null | false): boolean {\n  return !!color && /^(#|var\\(--|(rgb|hsl)a?\\()/.test(color)\n}\n\nexport function isParsableColor (color: string): boolean {\n  return isCssColor(color) && !/^((rgb|hsl)a?\\()?var\\(--/.test(color)\n}\n\nconst cssColorRe = /^(?<fn>(?:rgb|hsl)a?)\\((?<values>.+)\\)/\nconst mappers = {\n  rgb: (r: number, g: number, b: number, a?: number) => ({ r, g, b, a }),\n  rgba: (r: number, g: number, b: number, a?: number) => ({ r, g, b, a }),\n  hsl: (h: number, s: number, l: number, a?: number) => HSLtoRGB({ h, s, l, a }),\n  hsla: (h: number, s: number, l: number, a?: number) => HSLtoRGB({ h, s, l, a }),\n  hsv: (h: number, s: number, v: number, a?: number) => HSVtoRGB({ h, s, v, a }),\n  hsva: (h: number, s: number, v: number, a?: number) => HSVtoRGB({ h, s, v, a }),\n}\n\nexport function parseColor (color: Color): RGB {\n  if (typeof color === 'number') {\n    if (isNaN(color) || color < 0 || color > 0xFFFFFF) { // int can't have opacity\n      consoleWarn(`'${color}' is not a valid hex color`)\n    }\n\n    return {\n      r: (color & 0xFF0000) >> 16,\n      g: (color & 0xFF00) >> 8,\n      b: (color & 0xFF),\n    }\n  } else if (typeof color === 'string' && cssColorRe.test(color)) {\n    const { groups } = color.match(cssColorRe)!\n    const { fn, values } = groups as { fn: keyof typeof mappers, values: string }\n    const realValues = values.split(/,\\s*|\\s*\\/\\s*|\\s+/)\n      .map((v, i) => {\n        if (\n          v.endsWith('%') ||\n          // unitless slv are %\n          (i > 0 && i < 3 && ['hsl', 'hsla', 'hsv', 'hsva'].includes(fn))\n        ) {\n          return parseFloat(v) / 100\n        } else {\n          return parseFloat(v)\n        }\n      }) as [number, number, number, number?]\n\n    return mappers[fn](...realValues)\n  } else if (typeof color === 'string') {\n    let hex = color.startsWith('#') ? color.slice(1) : color\n\n    if ([3, 4].includes(hex.length)) {\n      hex = hex.split('').map(char => char + char).join('')\n    } else if (![6, 8].includes(hex.length)) {\n      consoleWarn(`'${color}' is not a valid hex(a) color`)\n    }\n\n    const int = parseInt(hex, 16)\n    if (isNaN(int) || int < 0 || int > 0xFFFFFFFF) {\n      consoleWarn(`'${color}' is not a valid hex(a) color`)\n    }\n\n    return HexToRGB(hex as Hex)\n  } else if (typeof color === 'object') {\n    if (has(color, ['r', 'g', 'b'])) {\n      return color\n    } else if (has(color, ['h', 's', 'l'])) {\n      return HSVtoRGB(HSLtoHSV(color))\n    } else if (has(color, ['h', 's', 'v'])) {\n      return HSVtoRGB(color)\n    }\n  }\n\n  throw new TypeError(`Invalid color: ${color == null ? color : (String(color) || (color as any).constructor.name)}\\nExpected #hex, #hexa, rgb(), rgba(), hsl(), hsla(), object or number`)\n}\n\nexport function RGBToInt (color: RGB) {\n  return (color.r << 16) + (color.g << 8) + color.b\n}\n\nexport function classToHex (\n  color: string,\n  colors: Record<string, Record<string, string>>,\n  currentTheme: Partial<Colors>,\n): string {\n  const [colorName, colorModifier] = color\n    .toString().trim().replace('-', '').split(' ', 2) as (string | undefined)[]\n\n  let hexColor = ''\n  if (colorName && colorName in colors) {\n    if (colorModifier && colorModifier in colors[colorName]) {\n      hexColor = colors[colorName][colorModifier]\n    } else if ('base' in colors[colorName]) {\n      hexColor = colors[colorName].base\n    }\n  } else if (colorName && colorName in currentTheme) {\n    hexColor = currentTheme[colorName] as string\n  }\n\n  return hexColor\n}\n\n/** Converts HSVA to RGBA. Based on formula from https://en.wikipedia.org/wiki/HSL_and_HSV */\nexport function HSVtoRGB (hsva: HSV): RGB {\n  const { h, s, v, a } = hsva\n  const f = (n: number) => {\n    const k = (n + (h / 60)) % 6\n    return v - v * s * Math.max(Math.min(k, 4 - k, 1), 0)\n  }\n\n  const rgb = [f(5), f(3), f(1)].map(v => Math.round(v * 255))\n\n  return { r: rgb[0], g: rgb[1], b: rgb[2], a }\n}\n\nexport function HSLtoRGB (hsla: HSL): RGB {\n  return HSVtoRGB(HSLtoHSV(hsla))\n}\n\n/** Converts RGBA to HSVA. Based on formula from https://en.wikipedia.org/wiki/HSL_and_HSV */\nexport function RGBtoHSV (rgba: RGB): HSV {\n  if (!rgba) return { h: 0, s: 1, v: 1, a: 1 }\n\n  const r = rgba.r / 255\n  const g = rgba.g / 255\n  const b = rgba.b / 255\n  const max = Math.max(r, g, b)\n  const min = Math.min(r, g, b)\n\n  let h = 0\n\n  if (max !== min) {\n    if (max === r) {\n      h = 60 * (0 + ((g - b) / (max - min)))\n    } else if (max === g) {\n      h = 60 * (2 + ((b - r) / (max - min)))\n    } else if (max === b) {\n      h = 60 * (4 + ((r - g) / (max - min)))\n    }\n  }\n\n  if (h < 0) h = h + 360\n\n  const s = max === 0 ? 0 : (max - min) / max\n  const hsv = [h, s, max]\n\n  return { h: hsv[0], s: hsv[1], v: hsv[2], a: rgba.a }\n}\n\nexport function HSVtoHSL (hsva: HSV): HSL {\n  const { h, s, v, a } = hsva\n\n  const l = v - (v * s / 2)\n\n  const sprime = l === 1 || l === 0 ? 0 : (v - l) / Math.min(l, 1 - l)\n\n  return { h, s: sprime, l, a }\n}\n\nexport function HSLtoHSV (hsl: HSL): HSV {\n  const { h, s, l, a } = hsl\n\n  const v = l + s * Math.min(l, 1 - l)\n\n  const sprime = v === 0 ? 0 : 2 - (2 * l / v)\n\n  return { h, s: sprime, v, a }\n}\n\nexport function RGBtoCSS ({ r, g, b, a }: RGB): string {\n  return a === undefined ? `rgb(${r}, ${g}, ${b})` : `rgba(${r}, ${g}, ${b}, ${a})`\n}\n\nexport function HSVtoCSS (hsva: HSV): string {\n  return RGBtoCSS(HSVtoRGB(hsva))\n}\n\nfunction toHex (v: number) {\n  const h = Math.round(v).toString(16)\n  return ('00'.substr(0, 2 - h.length) + h).toUpperCase()\n}\n\nexport function RGBtoHex ({ r, g, b, a }: RGB): Hex {\n  return `#${[\n    toHex(r),\n    toHex(g),\n    toHex(b),\n    a !== undefined ? toHex(Math.round(a * 255)) : '',\n  ].join('')}` as Hex\n}\n\nexport function HexToRGB (hex: Hex): RGB {\n  hex = parseHex(hex)\n  let [r, g, b, a] = chunk(hex, 2).map((c: string) => parseInt(c, 16))\n  a = a === undefined ? a : (a / 255)\n\n  return { r, g, b, a }\n}\n\nexport function HexToHSV (hex: Hex): HSV {\n  const rgb = HexToRGB(hex)\n  return RGBtoHSV(rgb)\n}\n\nexport function HSVtoHex (hsva: HSV): Hex {\n  return RGBtoHex(HSVtoRGB(hsva))\n}\n\nexport function parseHex (hex: string): Hex {\n  if (hex.startsWith('#')) {\n    hex = hex.slice(1)\n  }\n\n  hex = hex.replace(/([^0-9a-f])/gi, 'F')\n\n  if (hex.length === 3 || hex.length === 4) {\n    hex = hex.split('').map(x => x + x).join('')\n  }\n\n  if (hex.length !== 6) {\n    hex = padEnd(padEnd(hex, 6), 8, 'F')\n  }\n\n  return hex as Hex\n}\n\nexport function parseGradient (\n  gradient: string,\n  colors: Record<string, Record<string, string>>,\n  currentTheme: Partial<Colors>,\n) {\n  return gradient.replace(/([a-z]+(\\s[a-z]+-[1-5])?)(?=$|,)/gi, x => {\n    return classToHex(x, colors, currentTheme) || x\n  }).replace(/(rgba\\()#[0-9a-f]+(?=,)/gi, x => {\n    return 'rgba(' + Object.values(HexToRGB(parseHex(x.replace(/rgba\\(/, '')))).slice(0, 3).join(',')\n  })\n}\n\nexport function lighten (value: RGB, amount: number): RGB {\n  const lab = CIELAB.fromXYZ(sRGB.toXYZ(value))\n  lab[0] = lab[0] + amount * 10\n\n  return sRGB.fromXYZ(CIELAB.toXYZ(lab))\n}\n\nexport function darken (value: RGB, amount: number): RGB {\n  const lab = CIELAB.fromXYZ(sRGB.toXYZ(value))\n  lab[0] = lab[0] - amount * 10\n\n  return sRGB.fromXYZ(CIELAB.toXYZ(lab))\n}\n\n/**\n * Calculate the relative luminance of a given color\n * @see https://www.w3.org/TR/WCAG20/#relativeluminancedef\n */\nexport function getLuma (color: Color) {\n  const rgb = parseColor(color)\n\n  return sRGB.toXYZ(rgb)[1]\n}\n\n/**\n * Returns the contrast ratio (1-21) between two colors.\n * @see https://www.w3.org/TR/WCAG20/#contrast-ratiodef\n */\nexport function getContrast (first: Color, second: Color) {\n  const l1 = getLuma(first)\n  const l2 = getLuma(second)\n\n  const light = Math.max(l1, l2)\n  const dark = Math.min(l1, l2)\n\n  return (light + 0.05) / (dark + 0.05)\n}\n\nexport function hasLightForeground (color: Color) {\n  const blackContrast = Math.abs(APCAcontrast(parseColor(0), parseColor(color)))\n  const whiteContrast = Math.abs(APCAcontrast(parseColor(0xffffff), parseColor(color)))\n\n  // TODO: warn about poor color selections\n  // const contrastAsText = Math.abs(APCAcontrast(colorVal, colorToInt(theme.colors.background)))\n  // const minContrast = Math.max(blackContrast, whiteContrast)\n  // if (minContrast < 60) {\n  //   consoleInfo(`${key} theme color ${color} has poor contrast (${minContrast.toFixed()}%)`)\n  // } else if (contrastAsText < 60 && !['background', 'surface'].includes(color)) {\n  //   consoleInfo(`${key} theme color ${color} has poor contrast as text (${contrastAsText.toFixed()}%)`)\n  // }\n\n  // Prefer white text if both have an acceptable contrast ratio\n  return whiteContrast > Math.min(blackContrast, 50)\n}\n"
  },
  {
    "path": "packages/vuetify/src/util/colors.ts",
    "content": "export const red = {\n  base: '#f44336',\n  lighten5: '#ffebee',\n  lighten4: '#ffcdd2',\n  lighten3: '#ef9a9a',\n  lighten2: '#e57373',\n  lighten1: '#ef5350',\n  darken1: '#e53935',\n  darken2: '#d32f2f',\n  darken3: '#c62828',\n  darken4: '#b71c1c',\n  accent1: '#ff8a80',\n  accent2: '#ff5252',\n  accent3: '#ff1744',\n  accent4: '#d50000',\n}\n\nexport const pink = {\n  base: '#e91e63',\n  lighten5: '#fce4ec',\n  lighten4: '#f8bbd0',\n  lighten3: '#f48fb1',\n  lighten2: '#f06292',\n  lighten1: '#ec407a',\n  darken1: '#d81b60',\n  darken2: '#c2185b',\n  darken3: '#ad1457',\n  darken4: '#880e4f',\n  accent1: '#ff80ab',\n  accent2: '#ff4081',\n  accent3: '#f50057',\n  accent4: '#c51162',\n}\n\nexport const purple = {\n  base: '#9c27b0',\n  lighten5: '#f3e5f5',\n  lighten4: '#e1bee7',\n  lighten3: '#ce93d8',\n  lighten2: '#ba68c8',\n  lighten1: '#ab47bc',\n  darken1: '#8e24aa',\n  darken2: '#7b1fa2',\n  darken3: '#6a1b9a',\n  darken4: '#4a148c',\n  accent1: '#ea80fc',\n  accent2: '#e040fb',\n  accent3: '#d500f9',\n  accent4: '#aa00ff',\n}\n\nexport const deepPurple = {\n  base: '#673ab7',\n  lighten5: '#ede7f6',\n  lighten4: '#d1c4e9',\n  lighten3: '#b39ddb',\n  lighten2: '#9575cd',\n  lighten1: '#7e57c2',\n  darken1: '#5e35b1',\n  darken2: '#512da8',\n  darken3: '#4527a0',\n  darken4: '#311b92',\n  accent1: '#b388ff',\n  accent2: '#7c4dff',\n  accent3: '#651fff',\n  accent4: '#6200ea',\n}\n\nexport const indigo = {\n  base: '#3f51b5',\n  lighten5: '#e8eaf6',\n  lighten4: '#c5cae9',\n  lighten3: '#9fa8da',\n  lighten2: '#7986cb',\n  lighten1: '#5c6bc0',\n  darken1: '#3949ab',\n  darken2: '#303f9f',\n  darken3: '#283593',\n  darken4: '#1a237e',\n  accent1: '#8c9eff',\n  accent2: '#536dfe',\n  accent3: '#3d5afe',\n  accent4: '#304ffe',\n}\n\nexport const blue = {\n  base: '#2196f3',\n  lighten5: '#e3f2fd',\n  lighten4: '#bbdefb',\n  lighten3: '#90caf9',\n  lighten2: '#64b5f6',\n  lighten1: '#42a5f5',\n  darken1: '#1e88e5',\n  darken2: '#1976d2',\n  darken3: '#1565c0',\n  darken4: '#0d47a1',\n  accent1: '#82b1ff',\n  accent2: '#448aff',\n  accent3: '#2979ff',\n  accent4: '#2962ff',\n}\n\nexport const lightBlue = {\n  base: '#03a9f4',\n  lighten5: '#e1f5fe',\n  lighten4: '#b3e5fc',\n  lighten3: '#81d4fa',\n  lighten2: '#4fc3f7',\n  lighten1: '#29b6f6',\n  darken1: '#039be5',\n  darken2: '#0288d1',\n  darken3: '#0277bd',\n  darken4: '#01579b',\n  accent1: '#80d8ff',\n  accent2: '#40c4ff',\n  accent3: '#00b0ff',\n  accent4: '#0091ea',\n}\n\nexport const cyan = {\n  base: '#00bcd4',\n  lighten5: '#e0f7fa',\n  lighten4: '#b2ebf2',\n  lighten3: '#80deea',\n  lighten2: '#4dd0e1',\n  lighten1: '#26c6da',\n  darken1: '#00acc1',\n  darken2: '#0097a7',\n  darken3: '#00838f',\n  darken4: '#006064',\n  accent1: '#84ffff',\n  accent2: '#18ffff',\n  accent3: '#00e5ff',\n  accent4: '#00b8d4',\n}\n\nexport const teal = {\n  base: '#009688',\n  lighten5: '#e0f2f1',\n  lighten4: '#b2dfdb',\n  lighten3: '#80cbc4',\n  lighten2: '#4db6ac',\n  lighten1: '#26a69a',\n  darken1: '#00897b',\n  darken2: '#00796b',\n  darken3: '#00695c',\n  darken4: '#004d40',\n  accent1: '#a7ffeb',\n  accent2: '#64ffda',\n  accent3: '#1de9b6',\n  accent4: '#00bfa5',\n}\n\nexport const green = {\n  base: '#4caf50',\n  lighten5: '#e8f5e9',\n  lighten4: '#c8e6c9',\n  lighten3: '#a5d6a7',\n  lighten2: '#81c784',\n  lighten1: '#66bb6a',\n  darken1: '#43a047',\n  darken2: '#388e3c',\n  darken3: '#2e7d32',\n  darken4: '#1b5e20',\n  accent1: '#b9f6ca',\n  accent2: '#69f0ae',\n  accent3: '#00e676',\n  accent4: '#00c853',\n}\n\nexport const lightGreen = {\n  base: '#8bc34a',\n  lighten5: '#f1f8e9',\n  lighten4: '#dcedc8',\n  lighten3: '#c5e1a5',\n  lighten2: '#aed581',\n  lighten1: '#9ccc65',\n  darken1: '#7cb342',\n  darken2: '#689f38',\n  darken3: '#558b2f',\n  darken4: '#33691e',\n  accent1: '#ccff90',\n  accent2: '#b2ff59',\n  accent3: '#76ff03',\n  accent4: '#64dd17',\n}\n\nexport const lime = {\n  base: '#cddc39',\n  lighten5: '#f9fbe7',\n  lighten4: '#f0f4c3',\n  lighten3: '#e6ee9c',\n  lighten2: '#dce775',\n  lighten1: '#d4e157',\n  darken1: '#c0ca33',\n  darken2: '#afb42b',\n  darken3: '#9e9d24',\n  darken4: '#827717',\n  accent1: '#f4ff81',\n  accent2: '#eeff41',\n  accent3: '#c6ff00',\n  accent4: '#aeea00',\n}\n\nexport const yellow = {\n  base: '#ffeb3b',\n  lighten5: '#fffde7',\n  lighten4: '#fff9c4',\n  lighten3: '#fff59d',\n  lighten2: '#fff176',\n  lighten1: '#ffee58',\n  darken1: '#fdd835',\n  darken2: '#fbc02d',\n  darken3: '#f9a825',\n  darken4: '#f57f17',\n  accent1: '#ffff8d',\n  accent2: '#ffff00',\n  accent3: '#ffea00',\n  accent4: '#ffd600',\n}\n\nexport const amber = {\n  base: '#ffc107',\n  lighten5: '#fff8e1',\n  lighten4: '#ffecb3',\n  lighten3: '#ffe082',\n  lighten2: '#ffd54f',\n  lighten1: '#ffca28',\n  darken1: '#ffb300',\n  darken2: '#ffa000',\n  darken3: '#ff8f00',\n  darken4: '#ff6f00',\n  accent1: '#ffe57f',\n  accent2: '#ffd740',\n  accent3: '#ffc400',\n  accent4: '#ffab00',\n}\n\nexport const orange = {\n  base: '#ff9800',\n  lighten5: '#fff3e0',\n  lighten4: '#ffe0b2',\n  lighten3: '#ffcc80',\n  lighten2: '#ffb74d',\n  lighten1: '#ffa726',\n  darken1: '#fb8c00',\n  darken2: '#f57c00',\n  darken3: '#ef6c00',\n  darken4: '#e65100',\n  accent1: '#ffd180',\n  accent2: '#ffab40',\n  accent3: '#ff9100',\n  accent4: '#ff6d00',\n}\n\nexport const deepOrange = {\n  base: '#ff5722',\n  lighten5: '#fbe9e7',\n  lighten4: '#ffccbc',\n  lighten3: '#ffab91',\n  lighten2: '#ff8a65',\n  lighten1: '#ff7043',\n  darken1: '#f4511e',\n  darken2: '#e64a19',\n  darken3: '#d84315',\n  darken4: '#bf360c',\n  accent1: '#ff9e80',\n  accent2: '#ff6e40',\n  accent3: '#ff3d00',\n  accent4: '#dd2c00',\n}\n\nexport const brown = {\n  base: '#795548',\n  lighten5: '#efebe9',\n  lighten4: '#d7ccc8',\n  lighten3: '#bcaaa4',\n  lighten2: '#a1887f',\n  lighten1: '#8d6e63',\n  darken1: '#6d4c41',\n  darken2: '#5d4037',\n  darken3: '#4e342e',\n  darken4: '#3e2723',\n}\n\nexport const blueGrey = {\n  base: '#607d8b',\n  lighten5: '#eceff1',\n  lighten4: '#cfd8dc',\n  lighten3: '#b0bec5',\n  lighten2: '#90a4ae',\n  lighten1: '#78909c',\n  darken1: '#546e7a',\n  darken2: '#455a64',\n  darken3: '#37474f',\n  darken4: '#263238',\n}\n\nexport const grey = {\n  base: '#9e9e9e',\n  lighten5: '#fafafa',\n  lighten4: '#f5f5f5',\n  lighten3: '#eeeeee',\n  lighten2: '#e0e0e0',\n  lighten1: '#bdbdbd',\n  darken1: '#757575',\n  darken2: '#616161',\n  darken3: '#424242',\n  darken4: '#212121',\n}\n\nexport const shades = {\n  black: '#000000',\n  white: '#ffffff',\n  transparent: '#ffffff00',\n}\n\nexport default {\n  red,\n  pink,\n  purple,\n  deepPurple,\n  indigo,\n  blue,\n  lightBlue,\n  cyan,\n  teal,\n  green,\n  lightGreen,\n  lime,\n  yellow,\n  amber,\n  orange,\n  deepOrange,\n  brown,\n  blueGrey,\n  grey,\n  shades,\n}\n"
  },
  {
    "path": "packages/vuetify/src/util/console.ts",
    "content": "/* eslint-disable no-console */\n\n// Utilities\nimport { warn } from 'vue'\n\nexport function consoleWarn (message: string): void {\n  warn(`Vuetify: ${message}`)\n}\n\nexport function consoleError (message: string): void {\n  warn(`Vuetify error: ${message}`)\n}\n\nexport function deprecate (original: string, replacement: string | string[]) {\n  replacement = Array.isArray(replacement)\n    ? replacement.slice(0, -1).map(s => `'${s}'`).join(', ') + ` or '${replacement.at(-1)}'`\n    : `'${replacement}'`\n  warn(`[Vuetify UPGRADE] '${original}' is deprecated, use ${replacement} instead.`)\n}\nexport function breaking (original: string, replacement: string) {\n  // warn(`[Vuetify BREAKING] '${original}' has been removed, use '${replacement}' instead. For more information, see the upgrade guide https://github.com/vuetifyjs/vuetify/releases/tag/v2.0.0#user-content-upgrade-guide`)\n}\nexport function removed (original: string) {\n  // warn(`[Vuetify REMOVED] '${original}' has been removed. You can safely omit it.`)\n}\n"
  },
  {
    "path": "packages/vuetify/src/util/createSimpleFunctional.ts",
    "content": "// Composables\nimport { makeComponentProps } from '@/composables/component'\n\n// Utilities\nimport { camelize, capitalize, h } from 'vue'\nimport { genericComponent } from './defineComponent'\n\nexport function createSimpleFunctional (\n  klass: string,\n  tag = 'div',\n  name?: string\n) {\n  return genericComponent()({\n    name: name ?? capitalize(camelize(klass.replace(/__/g, '-'))),\n\n    props: {\n      tag: {\n        type: String,\n        default: tag,\n      },\n\n      ...makeComponentProps(),\n    },\n\n    setup (props, { slots }) {\n      return () => {\n        return h(props.tag, {\n          class: [klass, props.class],\n          style: props.style,\n        }, slots.default?.())\n      }\n    },\n  })\n}\n"
  },
  {
    "path": "packages/vuetify/src/util/deepEqual.ts",
    "content": "import { isPrimitive } from './helpers'\n\nfunction updateRecursionCache (a: any, b: any, cache: WeakMap<any, any>, result: boolean) {\n  if (!cache || isPrimitive(a) || isPrimitive(b)) return\n\n  const visitedObject = cache.get(a)\n  if (visitedObject) {\n    visitedObject.set(b, result)\n  } else {\n    const newCacheItem = new WeakMap()\n    newCacheItem.set(b, result)\n    cache.set(a, newCacheItem)\n  }\n}\n\nfunction findCachedComparison (a: any, b: any, cache: WeakMap<any, any>): boolean | null {\n  if (!cache || isPrimitive(a) || isPrimitive(b)) return null\n\n  const r1 = cache.get(a)?.get(b)\n  if (typeof r1 === 'boolean') return r1\n  const r2 = cache.get(b)?.get(a)\n  if (typeof r2 === 'boolean') return r2\n  return null\n}\n\nexport type ValueComparator = (a: any, b: any) => boolean\n\nexport function deepEqual (a: any, b: any, recursionCache = new WeakMap()): boolean {\n  if (a === b) return true\n\n  if (\n    a instanceof Date &&\n    b instanceof Date &&\n    a.getTime() !== b.getTime()\n  ) {\n    // If the values are Date, compare them as timestamps\n    return false\n  }\n\n  if (a !== Object(a) || b !== Object(b)) {\n    // If the values aren't objects, they were already checked for equality\n    return false\n  }\n\n  const props = Object.keys(a)\n\n  if (props.length !== Object.keys(b).length) {\n    // Different number of props, don't bother to check\n    return false\n  }\n\n  const cachedComparisonResult = findCachedComparison(a, b, recursionCache)\n  if (cachedComparisonResult) {\n    return cachedComparisonResult\n  }\n\n  updateRecursionCache(a, b, recursionCache, true)\n\n  return props.every(p => deepEqual(a[p], b[p], recursionCache))\n}\n"
  },
  {
    "path": "packages/vuetify/src/util/defineComponent.tsx",
    "content": "// Composables\nimport { injectDefaults, internalUseDefaults } from '@/composables/defaults'\n\n// Utilities\nimport {\n  defineComponent as _defineComponent, // eslint-disable-line no-restricted-imports\n} from 'vue'\nimport { consoleWarn } from '@/util/console'\nimport { pick } from '@/util/helpers'\nimport { propsFactory } from '@/util/propsFactory'\n\n// Types\nimport type {\n  AllowedComponentProps,\n  Component,\n  ComponentCustomProps,\n  ComponentInjectOptions,\n  ComponentObjectPropsOptions,\n  ComponentOptions,\n  ComponentOptionsMixin,\n  ComponentOptionsWithObjectProps,\n  ComponentOptionsWithoutProps,\n  ComponentPropsOptions,\n  ComponentPublicInstance,\n  ComputedOptions,\n  DefineComponent,\n  EmitsOptions,\n  ExtractDefaultPropTypes,\n  ExtractPropTypes,\n  FunctionalComponent,\n  MethodOptions,\n  ObjectEmitsOptions,\n  SlotsType,\n  VNode,\n  VNodeChild,\n  VNodeProps,\n} from 'vue'\n\n// No props\nexport function defineComponent<\n  Props = {},\n  RawBindings = {},\n  D = {},\n  C extends ComputedOptions = {},\n  M extends MethodOptions = {},\n  Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,\n  Extends extends ComponentOptionsMixin = ComponentOptionsMixin,\n  E extends EmitsOptions = {},\n  EE extends string = string,\n  I extends {} = {},\n  II extends string = string,\n  S extends SlotsType = {},\n>(\n  options: ComponentOptionsWithoutProps<\n    Props,\n    RawBindings,\n    D,\n    C,\n    M,\n    Mixin,\n    Extends,\n    E,\n    EE,\n    I,\n    II,\n    S\n  >\n): DefineComponent<Props, RawBindings, D, C, M, Mixin, Extends, E, EE>\n\n// Object Props\nexport function defineComponent<\n  PropsOptions extends Readonly<ComponentPropsOptions>,\n  RawBindings,\n  D,\n  C extends ComputedOptions = {},\n  M extends MethodOptions = {},\n  Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,\n  Extends extends ComponentOptionsMixin = ComponentOptionsMixin,\n  E extends EmitsOptions = {},\n  EE extends string = string,\n  I extends {} = {},\n  II extends string = string,\n  S extends SlotsType = {},\n>(\n  options: ComponentOptionsWithObjectProps<\n    PropsOptions,\n    RawBindings,\n    D,\n    C,\n    M,\n    Mixin,\n    Extends,\n    E,\n    EE,\n    I,\n    II,\n    S\n  >\n): DefineComponent<PropsOptions, RawBindings, D, C, M, Mixin, Extends, E, EE> & FilterPropsOptions<PropsOptions>\n\n// Implementation\nexport function defineComponent (options: ComponentOptions) {\n  options._setup = options._setup ?? options.setup\n\n  if (!options.name) {\n    consoleWarn('The component is missing an explicit name, unable to generate default prop value')\n\n    return options\n  }\n\n  if (options._setup) {\n    options.props = propsFactory(options.props ?? {}, options.name)()\n    const propKeys = Object.keys(options.props).filter(key => key !== 'class' && key !== 'style')\n    options.filterProps = function filterProps (props: Record<string, any>) {\n      return pick(props, propKeys)\n    }\n\n    options.props._as = String\n    options.setup = function setup (props: Record<string, any>, ctx) {\n      const defaults = injectDefaults()\n\n      // Skip props proxy if defaults are not provided\n      if (!defaults.value) return options._setup(props, ctx)\n\n      const { props: _props, provideSubDefaults } = internalUseDefaults(props, props._as ?? options.name, defaults)\n\n      const setupBindings = options._setup(_props, ctx)\n\n      provideSubDefaults()\n\n      return setupBindings\n    }\n  }\n\n  return options\n}\n\ntype ToListeners<T extends string | number | symbol> = { [K in T]: K extends `on${infer U}` ? Uncapitalize<U> : K }[T]\n\nexport type SlotsToProps<\n  U extends RawSlots,\n  T = MakeInternalSlots<U>\n> = {\n  $children?: (\n    | VNodeChild\n    | (T extends { default: infer V } ? V : {})\n    | { [K in keyof T]?: T[K] }\n    | { $stable?: boolean }\n  )\n  'v-slots'?: { [K in keyof T]?: T[K] | false }\n} & {\n  [K in keyof T as `v-slot:${K & string}`]?: T[K] | false\n}\n\ntype RawSlots = Record<string, unknown>\ntype Slot<T> = [T] extends [never] ? () => VNodeChild : (arg: T) => VNodeChild\ntype VueSlot<T> = [T] extends [never] ? () => VNode[] : (arg: T) => VNode[]\ntype MakeInternalSlots<T extends RawSlots> = {\n  [K in keyof T]: Slot<T[K]>\n}\ntype MakeSlots<T extends RawSlots> = {\n  [K in keyof T]: VueSlot<T[K]>\n}\n\nexport type GenericProps<Props, Slots extends Record<string, unknown>> = {\n  $props: Props & SlotsToProps<Slots>\n  $slots: MakeSlots<Slots>\n}\n\ntype DefineComponentWithGenericProps<T extends (new (props: Record<string, any>, slots: RawSlots) => {\n  $props?: Record<string, any>\n})> = <\n  PropsOptions extends Readonly<ComponentObjectPropsOptions>,\n  RawBindings,\n  D,\n  C extends ComputedOptions = {},\n  M extends MethodOptions = {},\n  Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,\n  Extends extends ComponentOptionsMixin = ComponentOptionsMixin,\n  E extends EmitsOptions = Record<string, any>,\n  EE extends string = string,\n  I extends ComponentInjectOptions = {},\n  II extends string = string,\n  // Slots extends RawSlots = ConstructorParameters<T> extends [any, infer SS extends RawSlots | undefined] ? Exclude<SS, undefined> : {},\n  Slots extends RawSlots = ConstructorParameters<T>[1],\n  S extends SlotsType = SlotsType<Partial<MakeSlots<Slots>>>,\n  III = InstanceType<T>,\n  P = III extends Record<'$props', any>\n    ? Omit<PropsOptions, keyof III['$props']>\n    : PropsOptions,\n  EEE extends EmitsOptions = E extends any[]\n    ? E\n    : III extends Record<'$props', any>\n      ? Omit<E, ToListeners<keyof III['$props']>>\n      : E,\n  Base = DefineComponent<\n    P,\n    RawBindings,\n    D,\n    C,\n    M,\n    Mixin,\n    Extends,\n    EEE,\n    EE,\n    PublicProps,\n    ExtractPropTypes<P> & ({} extends E ? {} : EmitsToProps<EEE>),\n    ExtractDefaultPropTypes<P>,\n    S\n  >\n>(\n  options: ComponentOptionsWithObjectProps<PropsOptions, RawBindings, D, C, M, Mixin, Extends, E, EE, I, II, S>\n) => Base & T & FilterPropsOptions<PropsOptions>\n\ntype DefineComponentWithSlots<Slots extends RawSlots> = <\n  PropsOptions extends Readonly<ComponentPropsOptions>,\n  RawBindings,\n  D,\n  C extends ComputedOptions = {},\n  M extends MethodOptions = {},\n  Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,\n  Extends extends ComponentOptionsMixin = ComponentOptionsMixin,\n  E extends EmitsOptions = Record<string, any>,\n  EE extends string = string,\n  I extends ComponentInjectOptions = {},\n  II extends string = string,\n  S extends SlotsType = SlotsType<Partial<MakeSlots<Slots>>>,\n>(\n  options: ComponentOptionsWithObjectProps<PropsOptions, RawBindings, D, C, M, Mixin, Extends, E, EE, I, II, S>\n) => DefineComponent<\n  ExtractPropTypes<PropsOptions> & SlotsToProps<Slots>,\n  RawBindings,\n  D,\n  C,\n  M,\n  Mixin,\n  Extends,\n  E,\n  EE,\n  PublicProps,\n  ExtractPropTypes<PropsOptions> & SlotsToProps<Slots> & ({} extends E ? {} : EmitsToProps<E>),\n  ExtractDefaultPropTypes<PropsOptions>,\n  S\n> & FilterPropsOptions<PropsOptions>\n\n// No argument - simple default slot\nexport function genericComponent (exposeDefaults?: boolean): DefineComponentWithSlots<{ default: never }>\n\n// Generic constructor argument - generic props and slots\nexport function genericComponent<T extends (new (props: Record<string, any>, slots: any) => {\n  $props?: Record<string, any>\n})> (exposeDefaults?: boolean): DefineComponentWithGenericProps<T>\n\n// Slots argument - simple slots\nexport function genericComponent<\n  Slots extends RawSlots\n> (exposeDefaults?: boolean): DefineComponentWithSlots<Slots>\n\n// Implementation\nexport function genericComponent (exposeDefaults = true) {\n  return (options: any) => ((exposeDefaults ? defineComponent : _defineComponent) as any)(options)\n}\n\nexport function defineFunctionalComponent<\n  T extends FunctionalComponent<Props>,\n  PropsOptions = ComponentObjectPropsOptions,\n  Defaults = ExtractDefaultPropTypes<PropsOptions>,\n  Props = Readonly<ExtractPropTypes<PropsOptions>>,\n> (props: PropsOptions, render: T): FunctionalComponent<Partial<Defaults> & Omit<Props, keyof Defaults>> {\n  render.props = props as any\n  return render as any\n}\n\ntype EmitsToProps<T extends EmitsOptions> = T extends string[]\n  ? {\n    [K in string & `on${Capitalize<T[number]>}`]?: (...args: any[]) => any\n  }\n  : T extends ObjectEmitsOptions\n    ? {\n      [K in string &\n        `on${Capitalize<string & keyof T>}`]?: K extends `on${infer C}`\n        ? T[Uncapitalize<C>] extends null\n          ? (...args: any[]) => any\n          : (\n            ...args: T[Uncapitalize<C>] extends (...args: infer P) => any\n              ? P\n              : never\n          ) => any\n        : never\n    }\n    : {}\n\ntype PublicProps =\n  & VNodeProps\n  & AllowedComponentProps\n  & ComponentCustomProps\n\n// Adds a filterProps method to the component options\nexport interface FilterPropsOptions<PropsOptions extends Readonly<ComponentPropsOptions>, Props = ExtractPropTypes<PropsOptions>> {\n  filterProps<\n    T extends Partial<Props>,\n    U extends Exclude<keyof Props, Exclude<keyof Props, keyof T>>\n  > (props: T): Partial<Pick<T, U>>\n}\n\n// https://github.com/vuejs/core/pull/10557\nexport type ComponentInstance<T> = T extends { new (): ComponentPublicInstance<any, any, any> }\n  ? InstanceType<T>\n  : T extends FunctionalComponent<infer Props, infer Emits>\n    ? ComponentPublicInstance<Props, {}, {}, {}, {}, ShortEmitsToObject<Emits>>\n    : T extends Component<\n          infer Props,\n          infer RawBindings,\n          infer D,\n          infer C,\n          infer M\n        >\n      ? // NOTE we override Props/RawBindings/D to make sure is not `unknown`\n      ComponentPublicInstance<\n          unknown extends Props ? {} : Props,\n          unknown extends RawBindings ? {} : RawBindings,\n          unknown extends D ? {} : D,\n          C,\n          M\n        >\n      : never // not a vue Component\n\ntype ShortEmitsToObject<E> = E extends Record<string, any[]> ? {\n  [K in keyof E]: (...args: E[K]) => any;\n} : E;\n\nexport type JSXComponent<Props = any> =\n  | { new (): ComponentPublicInstance<Props> }\n  | FunctionalComponent<Props>\n"
  },
  {
    "path": "packages/vuetify/src/util/dom.ts",
    "content": "/**\n * Returns:\n *  - 'null' if the node is not attached to the DOM\n *  - the root node (HTMLDocument | ShadowRoot) otherwise\n */\nexport function attachedRoot (node: Node): null | HTMLDocument | ShadowRoot {\n  /* istanbul ignore next */\n  if (typeof node.getRootNode !== 'function') {\n    // Shadow DOM not supported (IE11), lets find the root of this node\n    while (node.parentNode) node = node.parentNode\n\n    // The root parent is the document if the node is attached to the DOM\n    if (node !== document) return null\n\n    return document\n  }\n\n  const root = node.getRootNode()\n\n  // The composed root node is the document if the node is attached to the DOM\n  if (root !== document && root.getRootNode({ composed: true }) !== document) return null\n\n  return root as HTMLDocument | ShadowRoot\n}\n"
  },
  {
    "path": "packages/vuetify/src/util/easing.ts",
    "content": "// Utilities\nimport { computed, shallowRef, toValue, watch } from 'vue'\nimport { clamp } from './helpers'\nimport { PREFERS_REDUCED_MOTION } from '@/util/globals'\n\n// Types\nimport type { MaybeRefOrGetter, Ref } from 'vue'\n\nexport const standardEasing = 'cubic-bezier(0.4, 0, 0.2, 1)'\nexport const deceleratedEasing = 'cubic-bezier(0.0, 0, 0.2, 1)' // Entering\nexport const acceleratedEasing = 'cubic-bezier(0.4, 0, 1, 1)' // Leaving\n\nexport type EasingFunction = (n: number) => number\n\nexport const easingPatterns = {\n  linear: (t: number) => t,\n  easeInQuad: (t: number) => t ** 2,\n  easeOutQuad: (t: number) => t * (2 - t),\n  easeInOutQuad: (t: number) => (t < 0.5 ? 2 * t ** 2 : -1 + (4 - 2 * t) * t),\n  easeInCubic: (t: number) => t ** 3,\n  easeOutCubic: (t: number) => --t ** 3 + 1,\n  easeInOutCubic: (t: number) => t < 0.5 ? 4 * t ** 3 : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1,\n  easeInQuart: (t: number) => t ** 4,\n  easeOutQuart: (t: number) => 1 - --t ** 4,\n  easeInOutQuart: (t: number) => (t < 0.5 ? 8 * t ** 4 : 1 - 8 * --t ** 4),\n  easeInQuint: (t: number) => t ** 5,\n  easeOutQuint: (t: number) => 1 + --t ** 5,\n  easeInOutQuint: (t: number) => t < 0.5 ? 16 * t ** 5 : 1 + 16 * --t ** 5,\n  instant: (t: number) => 1,\n} as const\n\nexport type EasingOptions = {\n  duration?: number\n  transition?: EasingFunction\n}\n\ntype InternalEasingOptions = {\n  duration: number\n  transition: EasingFunction\n}\n\nexport function useTransition (source: MaybeRefOrGetter<number>, options: MaybeRefOrGetter<EasingOptions>) {\n  const defaultTransition: InternalEasingOptions = {\n    duration: 300,\n    transition: easingPatterns.easeInOutCubic,\n  }\n\n  let raf = -1\n  const outputRef = shallowRef(toValue(source))\n\n  watch(() => toValue(source), async to => {\n    cancelAnimationFrame(raf)\n    const easing = { ...defaultTransition, ...toValue(options) }\n    await executeTransition(outputRef, outputRef.value, to, easing)\n  })\n\n  function executeTransition (out: Ref<number>, from: number, to: number, options: InternalEasingOptions) {\n    const startTime = performance.now()\n    const ease = PREFERS_REDUCED_MOTION() ? easingPatterns.instant\n      : options.transition ?? easingPatterns.easeInOutCubic\n\n    return new Promise<void>(resolve => {\n      raf = requestAnimationFrame(function step (currentTime: number) {\n        const timeElapsed = currentTime - startTime\n        const progress = timeElapsed / options.duration\n        out.value = from + (to - from) * ease(clamp(progress, 0, 1))\n\n        if (progress < 1) {\n          raf = requestAnimationFrame(step)\n        } else {\n          out.value = to\n          resolve()\n        }\n      })\n    })\n  }\n\n  return computed(() => outputRef.value)\n}\n"
  },
  {
    "path": "packages/vuetify/src/util/events.ts",
    "content": "// Utilities\nimport { callEvent, isOn } from '@/util/helpers'\n\ntype EventHandler = (event: Event) => any\n\nexport function getPrefixedEventHandlers<T extends `:${string}`> (\n  attrs: Record<string, any>,\n  suffix: T,\n  getData: EventHandler\n): Record<`${string}${T}`, EventHandler> {\n  return Object.keys(attrs)\n    .filter(key => isOn(key) && key.endsWith(suffix))\n    .reduce((acc: any, key) => {\n      acc[key.slice(0, -suffix.length)] = (event: Event) => callEvent(attrs[key], event, getData(event))\n      return acc\n    }, {} as Record<`${string}${T}`, EventHandler>)\n}\n"
  },
  {
    "path": "packages/vuetify/src/util/getCurrentInstance.ts",
    "content": "// Utilities\nimport { getCurrentInstance as _getCurrentInstance } from 'vue'\nimport { toKebabCase } from '@/util/helpers'\n\nexport function getCurrentInstance (name: string, message?: string) {\n  const vm = _getCurrentInstance()\n\n  if (!vm) {\n    throw new Error(`[Vuetify] ${name} ${message || 'must be called from inside a setup function'}`)\n  }\n\n  return vm\n}\n\nexport function getCurrentInstanceName (name = 'composables') {\n  const vm = getCurrentInstance(name).type\n\n  return toKebabCase(vm?.aliasName || vm?.name)\n}\n"
  },
  {
    "path": "packages/vuetify/src/util/getScrollParent.ts",
    "content": "export function getScrollParent (el?: HTMLElement, includeHidden = false) {\n  while (el) {\n    if (includeHidden ? isPotentiallyScrollable(el) : hasScrollbar(el)) return el\n    el = el.parentElement!\n  }\n\n  return document.scrollingElement as HTMLElement\n}\n\nexport function getScrollParents (el?: Element | null, stopAt?: Element | null) {\n  const elements: HTMLElement[] = []\n\n  if (stopAt && el && !stopAt.contains(el)) return elements\n\n  while (el) {\n    if (hasScrollbar(el)) elements.push(el as HTMLElement)\n    if (el === stopAt) break\n    el = el.parentElement!\n  }\n\n  return elements\n}\n\nexport function hasScrollbar (el?: Element | null) {\n  if (!el || el.nodeType !== Node.ELEMENT_NODE) return false\n\n  const style = window.getComputedStyle(el)\n  const hasVerticalScrollbar = style.overflowY === 'scroll' || (style.overflowY === 'auto' && el.scrollHeight > el.clientHeight)\n  const hasHorizontalScrollbar = style.overflowX === 'scroll' || (style.overflowX === 'auto' && el.scrollWidth > el.clientWidth)\n  return hasVerticalScrollbar || hasHorizontalScrollbar\n}\n\nfunction isPotentiallyScrollable (el?: Element | null) {\n  if (!el || el.nodeType !== Node.ELEMENT_NODE) return false\n\n  const style = window.getComputedStyle(el)\n  return ['scroll', 'auto'].includes(style.overflowY)\n}\n"
  },
  {
    "path": "packages/vuetify/src/util/globals.ts",
    "content": "export const IN_BROWSER = typeof window !== 'undefined'\nexport const SUPPORTS_INTERSECTION = IN_BROWSER && 'IntersectionObserver' in window\nexport const SUPPORTS_TOUCH = IN_BROWSER && ('ontouchstart' in window || window.navigator.maxTouchPoints > 0)\nexport const SUPPORTS_EYE_DROPPER = IN_BROWSER && 'EyeDropper' in window\nexport const SUPPORTS_MATCH_MEDIA = IN_BROWSER && 'matchMedia' in window && typeof window.matchMedia === 'function'\nexport const PREFERS_REDUCED_MOTION = () => (\n  SUPPORTS_MATCH_MEDIA && window.matchMedia('(prefers-reduced-motion: reduce)').matches\n)\n"
  },
  {
    "path": "packages/vuetify/src/util/helpers.ts",
    "content": "// Utilities\nimport {\n  camelize,\n  capitalize,\n  Comment,\n  Fragment,\n  isProxy,\n  isReactive,\n  isRef,\n  isVNode,\n  reactive,\n  shallowRef,\n  toRaw,\n  toRef,\n  unref,\n  watchEffect,\n} from 'vue'\nimport { consoleError } from '@/util/console'\nimport { IN_BROWSER } from '@/util/globals'\n\n// Types\nimport type {\n  ComponentInternalInstance,\n  ComponentPublicInstance,\n  ComputedGetter,\n  InjectionKey,\n  PropType,\n  Ref,\n  ToRef,\n  VNode,\n  VNodeArrayChildren,\n  VNodeChild,\n} from 'vue'\n\nexport function getNestedValue (obj: any, path: (string | number)[], fallback?: any): any {\n  const last = path.length - 1\n\n  if (last < 0) return obj === undefined ? fallback : obj\n\n  for (let i = 0; i < last; i++) {\n    if (obj == null) {\n      return fallback\n    }\n    obj = obj[path[i]]\n  }\n\n  if (obj == null) return fallback\n\n  return obj[path[last]] === undefined ? fallback : obj[path[last]]\n}\n\nexport function getObjectValueByPath (obj: any, path?: string | null, fallback?: any): any {\n  // credit: http://stackoverflow.com/questions/6491463/accessing-nested-javascript-objects-with-string-key#comment55278413_6491621\n  if (obj == null || !path || typeof path !== 'string') return fallback\n  if (obj[path] !== undefined) return obj[path]\n  path = path.replace(/\\[(\\w+)\\]/g, '.$1') // convert indexes to properties\n  path = path.replace(/^\\./, '') // strip a leading dot\n  return getNestedValue(obj, path.split('.'), fallback)\n}\n\nexport type SelectItemKey<T = Record<string, any>> =\n  | boolean | null | undefined // Ignored\n  | string // Lookup by key, can use dot notation for nested objects\n  | readonly (string | number)[] // Nested lookup by key, each array item is a key in the next level\n  | ((item: T, fallback?: any) => any)\n\nexport function getPropertyFromItem (\n  item: any,\n  property: SelectItemKey,\n  fallback?: any\n): any {\n  if (property === true) return item === undefined ? fallback : item\n\n  if (property == null || typeof property === 'boolean') return fallback\n\n  if (item !== Object(item)) {\n    if (typeof property !== 'function') return fallback\n\n    const value = property(item, fallback)\n\n    return typeof value === 'undefined' ? fallback : value\n  }\n\n  if (typeof property === 'string') return getObjectValueByPath(item, property, fallback)\n\n  if (Array.isArray(property)) return getNestedValue(item, property, fallback)\n\n  if (typeof property !== 'function') return fallback\n\n  const value = property(item, fallback)\n\n  return typeof value === 'undefined' ? fallback : value\n}\n\nexport function createRange (length: number, start = 0): number[] {\n  return Array.from({ length }, (v, k) => start + k)\n}\n\nexport function getZIndex (el?: Element | null): number {\n  if (!el || el.nodeType !== Node.ELEMENT_NODE) return 0\n\n  const index = Number(window.getComputedStyle(el).getPropertyValue('z-index'))\n\n  if (!index) return getZIndex(el.parentNode as Element)\n  return index\n}\n\nexport function convertToUnit (str: number, unit?: string): string\nexport function convertToUnit (str: string | number | null | undefined, unit?: string): string | undefined\nexport function convertToUnit (str: string | number | null | undefined, unit = 'px'): string | undefined {\n  if (str == null || str === '') {\n    return undefined\n  }\n  const num = Number(str)\n  if (isNaN(num)) {\n    return String(str)\n  } else if (!isFinite(num)) {\n    return undefined\n  } else {\n    return `${num}${unit}`\n  }\n}\n\nexport function isObject (obj: any): obj is Record<string, any> {\n  return obj !== null && typeof obj === 'object' && !Array.isArray(obj)\n}\n\nexport function isPlainObject (obj: any): obj is Record<string, any> {\n  let proto\n  return obj !== null && typeof obj === 'object' && (\n    (proto = Object.getPrototypeOf(obj)) === Object.prototype ||\n    proto === null\n  )\n}\n\nexport function refElement (obj?: ComponentPublicInstance<any> | HTMLElement): HTMLElement | undefined {\n  if (obj && '$el' in obj) {\n    const el = obj.$el as HTMLElement\n    if (el?.nodeType === Node.TEXT_NODE) {\n      // Multi-root component, use the first element\n      return el.nextElementSibling as HTMLElement\n    }\n    return el\n  }\n  return obj as HTMLElement\n}\n\n// KeyboardEvent.keyCode aliases\nexport const keyCodes = Object.freeze({\n  enter: 13,\n  tab: 9,\n  delete: 46,\n  esc: 27,\n  space: 32,\n  up: 38,\n  down: 40,\n  left: 37,\n  right: 39,\n  end: 35,\n  home: 36,\n  del: 46,\n  backspace: 8,\n  insert: 45,\n  pageup: 33,\n  pagedown: 34,\n  shift: 16,\n})\n\nexport const keyValues: Record<string, string> = Object.freeze({\n  enter: 'Enter',\n  tab: 'Tab',\n  delete: 'Delete',\n  esc: 'Escape',\n  space: 'Space',\n  up: 'ArrowUp',\n  down: 'ArrowDown',\n  left: 'ArrowLeft',\n  right: 'ArrowRight',\n  end: 'End',\n  home: 'Home',\n  del: 'Delete',\n  backspace: 'Backspace',\n  insert: 'Insert',\n  pageup: 'PageUp',\n  pagedown: 'PageDown',\n  shift: 'Shift',\n})\n\nexport function keys<O extends {}> (o: O) {\n  return Object.keys(o) as (keyof O)[]\n}\n\nexport function has<T extends string> (obj: object, key: T[]): obj is Record<T, unknown> {\n  return key.every(k => obj.hasOwnProperty(k))\n}\n\ntype MaybePick<\n  T extends object,\n  U extends Extract<keyof T, string>\n> = Record<string, unknown> extends T ? Partial<Pick<T, U>> : Pick<T, U>\n\n// Array of keys\nexport function pick<\n  T extends object,\n  U extends Extract<keyof T, string>\n> (obj: T, paths: readonly U[]): MaybePick<T, U> {\n  const found: any = {}\n\n  for (const key of paths) {\n    if (Object.prototype.hasOwnProperty.call(obj, key)) {\n      found[key] = obj[key]\n    }\n  }\n\n  return found\n}\n\n// Array of keys\nexport function pickWithRest<\n  T extends object,\n  U extends Extract<keyof T, string>,\n  E extends Extract<keyof T, string>\n> (obj: T, paths: U[], exclude?: E[]): [yes: MaybePick<T, Exclude<U, E>>, no: Omit<T, Exclude<U, E>>]\n// Array of keys or RegExp to test keys against\nexport function pickWithRest<\n  T extends object,\n  U extends Extract<keyof T, string>,\n  E extends Extract<keyof T, string>\n> (obj: T, paths: (U | RegExp)[], exclude?: E[]): [yes: Partial<T>, no: Partial<T>]\nexport function pickWithRest<\n  T extends object,\n  U extends Extract<keyof T, string>,\n  E extends Extract<keyof T, string>\n> (obj: T, paths: (U | RegExp)[], exclude?: E[]): [yes: Partial<T>, no: Partial<T>] {\n  const found = Object.create(null)\n  const rest = Object.create(null)\n\n  for (const key in obj) {\n    if (\n      paths.some(path => path instanceof RegExp\n        ? path.test(key)\n        : path === key\n      ) && !exclude?.some(path => path === key)\n    ) {\n      found[key] = obj[key]\n    } else {\n      rest[key] = obj[key]\n    }\n  }\n\n  return [found, rest]\n}\n\nexport function omit<\n  T extends object,\n  U extends Extract<keyof T, string>\n> (obj: T, exclude: U[]): Omit<T, U> {\n  const clone = { ...obj }\n\n  exclude.forEach(prop => delete clone[prop])\n\n  return clone\n}\n\nconst onRE = /^on[^a-z]/\nexport const isOn = (key: string) => onRE.test(key)\n\nconst bubblingEvents = [\n  'onAfterscriptexecute',\n  'onAnimationcancel',\n  'onAnimationend',\n  'onAnimationiteration',\n  'onAnimationstart',\n  'onAuxclick',\n  'onBeforeinput',\n  'onBeforescriptexecute',\n  'onChange',\n  'onClick',\n  'onCompositionend',\n  'onCompositionstart',\n  'onCompositionupdate',\n  'onContextmenu',\n  'onCopy',\n  'onCut',\n  'onDblclick',\n  'onFocusin',\n  'onFocusout',\n  'onFullscreenchange',\n  'onFullscreenerror',\n  'onGesturechange',\n  'onGestureend',\n  'onGesturestart',\n  'onGotpointercapture',\n  'onInput',\n  'onKeydown',\n  'onKeypress',\n  'onKeyup',\n  'onLostpointercapture',\n  'onMousedown',\n  'onMousemove',\n  'onMouseout',\n  'onMouseover',\n  'onMouseup',\n  'onMousewheel',\n  'onPaste',\n  'onPointercancel',\n  'onPointerdown',\n  'onPointerenter',\n  'onPointerleave',\n  'onPointermove',\n  'onPointerout',\n  'onPointerover',\n  'onPointerup',\n  'onReset',\n  'onSelect',\n  'onSubmit',\n  'onTouchcancel',\n  'onTouchend',\n  'onTouchmove',\n  'onTouchstart',\n  'onTransitioncancel',\n  'onTransitionend',\n  'onTransitionrun',\n  'onTransitionstart',\n  'onWheel',\n]\n\nconst compositionIgnoreKeys = [\n  'ArrowUp',\n  'ArrowDown',\n  'ArrowRight',\n  'ArrowLeft',\n  'Enter',\n  'Escape',\n  'Tab',\n  ' ',\n]\n\nexport function isComposingIgnoreKey (e: KeyboardEvent): boolean {\n  return e.isComposing && compositionIgnoreKeys.includes(e.key)\n}\n\n/**\n * Filter attributes that should be applied to\n * the root element of an input component. Remaining\n * attributes should be passed to the <input> element inside.\n */\nexport function filterInputAttrs (attrs: Record<string, unknown>) {\n  const [events, props] = pickWithRest(attrs, [onRE])\n  const inputEvents = omit(events, bubblingEvents)\n  const [rootAttrs, inputAttrs] = pickWithRest(props, ['class', 'style', 'id', 'inert', /^data-/])\n  Object.assign(rootAttrs, events)\n  Object.assign(inputAttrs, inputEvents)\n  return [rootAttrs, inputAttrs]\n}\n\n/**\n * Returns the set difference of B and A, i.e. the set of elements in B but not in A\n */\nexport function arrayDiff (a: any[], b: any[]): any[] {\n  const diff: any[] = []\n  for (let i = 0; i < b.length; i++) {\n    if (!a.includes(b[i])) diff.push(b[i])\n  }\n  return diff\n}\n\ntype IfAny<T, Y, N> = 0 extends (1 & T) ? Y : N;\nexport function wrapInArray<T> (\n  v: T | null | undefined\n): T extends readonly any[]\n    ? IfAny<T, T[], T>\n    : NonNullable<T>[] {\n  return v == null\n    ? [] as any\n    : Array.isArray(v)\n      ? v as any : [v] as any\n}\n\nexport function defaultFilter (value: any, search: string | null, item: any) {\n  return value != null &&\n    search != null &&\n    typeof value !== 'boolean' &&\n    value.toString().toLocaleLowerCase().indexOf(search.toLocaleLowerCase()) !== -1\n}\n\nexport function debounce (fn: Function, delay: MaybeRef<number>) {\n  let timeoutId = 0 as any\n  const wrap = (...args: any[]) => {\n    clearTimeout(timeoutId)\n    timeoutId = setTimeout(() => fn(...args), unref(delay))\n  }\n  wrap.clear = () => {\n    clearTimeout(timeoutId)\n  }\n  wrap.immediate = fn\n  return wrap\n}\n\nexport function clamp (value: number, min = 0, max = 1) {\n  return Math.max(min, Math.min(max, value))\n}\n\nexport function getDecimals (value: number) {\n  const trimmedStr = value.toString().trim()\n  return trimmedStr.includes('.')\n    ? (trimmedStr.length - trimmedStr.indexOf('.') - 1)\n    : 0\n}\n\nexport function padEnd (str: string, length: number, char = '0') {\n  return str + char.repeat(Math.max(0, length - str.length))\n}\n\nexport function padStart (str: string, length: number, char = '0') {\n  return char.repeat(Math.max(0, length - str.length)) + str\n}\n\nexport function chunk (str: string, size = 1) {\n  const chunked: string[] = []\n  let index = 0\n  while (index < str.length) {\n    chunked.push(str.substr(index, size))\n    index += size\n  }\n  return chunked\n}\n\nexport function chunkArray (array: any[], size = 1) {\n  return Array.from({ length: Math.ceil(array.length / size) }, (v, i) =>\n    array.slice(i * size, i * size + size)\n  )\n}\n\nexport function humanReadableFileSize (bytes: number, base: 1000 | 1024 = 1000): string {\n  if (bytes < base) {\n    return `${bytes} B`\n  }\n\n  const prefix = base === 1024 ? ['Ki', 'Mi', 'Gi'] : ['k', 'M', 'G']\n  let unit = -1\n  while (Math.abs(bytes) >= base && unit < prefix.length - 1) {\n    bytes /= base\n    ++unit\n  }\n  return `${bytes.toFixed(1)} ${prefix[unit]}B`\n}\n\nexport function mergeDeep (\n  source: Record<string, any> = {},\n  target: Record<string, any> = {},\n  arrayFn?: (a: unknown[], b: unknown[]) => unknown[],\n  targetCondition?: (k: string, v: unknown) => boolean,\n) {\n  const out: Record<string, any> = {}\n\n  for (const key in source) {\n    out[key] = source[key]\n  }\n\n  for (const key in target) {\n    const targetProperty = target[key]\n\n    if (targetCondition && !targetCondition(key, targetProperty)) {\n      continue\n    }\n\n    const sourceProperty = source[key]\n\n    // Only continue deep merging if\n    // both properties are plain objects\n    if (isPlainObject(sourceProperty) && isPlainObject(targetProperty)) {\n      out[key] = mergeDeep(sourceProperty, targetProperty, arrayFn, targetCondition)\n\n      continue\n    }\n\n    if (arrayFn && Array.isArray(sourceProperty) && Array.isArray(targetProperty)) {\n      out[key] = arrayFn(sourceProperty, targetProperty)\n\n      continue\n    }\n\n    out[key] = targetProperty\n  }\n\n  return out\n}\n\nexport function flattenFragments (nodes: VNode[]): VNode[] {\n  return nodes.map(node => {\n    if (node.type === Fragment) {\n      return flattenFragments(node.children as VNode[])\n    } else {\n      return node\n    }\n  }).flat()\n}\n\nexport function toKebabCase (str = '') {\n  if (toKebabCase.cache.has(str)) return toKebabCase.cache.get(str)!\n  const kebab = str\n    .replace(/[^a-z]/gi, '-')\n    .replace(/\\B([A-Z])/g, '-$1')\n    .toLowerCase()\n  toKebabCase.cache.set(str, kebab)\n  return kebab\n}\ntoKebabCase.cache = new Map<string, string>()\n\nexport type MaybeRef<T> = T | Ref<T>\n\nexport function findChildrenWithProvide (\n  key: InjectionKey<any> | symbol,\n  vnode?: VNodeChild,\n): ComponentInternalInstance[] {\n  if (!vnode || typeof vnode !== 'object') return []\n\n  if (Array.isArray(vnode)) {\n    return vnode.map(child => findChildrenWithProvide(key, child)).flat(1)\n  } else if (vnode.suspense) {\n    return findChildrenWithProvide(key, vnode.ssContent!)\n  } else if (Array.isArray(vnode.children)) {\n    return vnode.children.map(child => findChildrenWithProvide(key, child)).flat(1)\n  } else if (vnode.component) {\n    if (Object.getOwnPropertyDescriptor(vnode.component.provides, key as symbol)) {\n      return [vnode.component]\n    } else if (vnode.component.subTree) {\n      return findChildrenWithProvide(key, vnode.component.subTree).flat(1)\n    }\n  }\n\n  return []\n}\n\nexport class CircularBuffer<T = never> {\n  readonly #arr: Array<T> = []\n  #pointer = 0\n\n  constructor (public readonly size: number) {}\n\n  get isFull () {\n    return this.#arr.length === this.size\n  }\n\n  push (val: T) {\n    this.#arr[this.#pointer] = val\n    this.#pointer = (this.#pointer + 1) % this.size\n  }\n\n  values (): T[] {\n    return this.#arr.slice(this.#pointer).concat(this.#arr.slice(0, this.#pointer))\n  }\n\n  clear () {\n    this.#arr.length = 0\n    this.#pointer = 0\n  }\n}\n\nexport type UnionToIntersection<U> =\n  (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never\n\nexport function getEventCoordinates (e: MouseEvent | TouchEvent) {\n  if ('touches' in e) {\n    return { clientX: e.touches[0].clientX, clientY: e.touches[0].clientY }\n  }\n\n  return { clientX: e.clientX, clientY: e.clientY }\n}\n\n// Only allow a single return type\ntype NotAUnion<T> = [T] extends [infer U] ? _NotAUnion<U, U> : never\ntype _NotAUnion<T, U> = U extends any ? [T] extends [U] ? unknown : never : never\n\ntype ToReadonlyRefs<T> = { [K in keyof T]: Readonly<ToRef<T[K]>> }\n\n/**\n * Convert a computed ref to a record of refs.\n * The getter function must always return an object with the same keys.\n */\nexport function destructComputed<T extends object> (getter: ComputedGetter<T & NotAUnion<T>>): ToReadonlyRefs<T>\nexport function destructComputed<T extends object> (getter: ComputedGetter<T>) {\n  const refs = reactive({}) as T\n  watchEffect(() => {\n    const base = getter()\n    for (const key in base) {\n      refs[key] = base[key]\n    }\n  }, { flush: 'sync' })\n  const obj = {} as ToReadonlyRefs<T>\n  for (const key in refs) {\n    obj[key] = toRef(() => refs[key]) as any\n  }\n  return obj\n}\n\n/** Array.includes but value can be any type */\nexport function includes (arr: readonly any[], val: any) {\n  return arr.includes(val)\n}\n\nexport function eventName (propName: string) {\n  return propName[2].toLowerCase() + propName.slice(3)\n}\n\n// TODO: this should be an array but vue's types don't accept arrays: vuejs/core#8025\nexport type EventProp<T extends any[] = any[], F = (...args: T) => void> = F\nexport const EventProp = <T extends any[] = any[]>() => [Function, Array] as PropType<EventProp<T>>\n\nexport function hasEvent (props: Record<string, any>, name: string) {\n  name = 'on' + capitalize(name)\n  return !!(props[name] || props[`${name}Once`] || props[`${name}Capture`] || props[`${name}OnceCapture`] || props[`${name}CaptureOnce`])\n}\n\nexport function callEvent<T extends any[]> (handler: EventProp<T> | EventProp<T>[] | undefined, ...args: T) {\n  if (Array.isArray(handler)) {\n    for (const h of handler) {\n      h(...args)\n    }\n  } else if (typeof handler === 'function') {\n    handler(...args)\n  }\n}\n\nexport function focusableChildren (el: Element, filterByTabIndex = true) {\n  const targets = [\n    'button',\n    '[href]',\n    'input:not([type=\"hidden\"])',\n    'select',\n    'textarea',\n    'details:not(:has(> summary))',\n    'details > summary',\n    '[tabindex]',\n    '[contenteditable]:not([contenteditable=\"false\"])',\n    'audio[controls]',\n    'video[controls]',\n  ]\n    .map(s => `${s}${filterByTabIndex ? ':not([tabindex=\"-1\"])' : ''}:not([disabled], [inert])`)\n    .join(', ')\n\n  let elements\n  try {\n    elements = [...el.querySelectorAll(targets)] as HTMLElement[]\n  } catch (err) {\n    consoleError(String(err))\n    return []\n  }\n\n  return elements\n    .filter(x => !x.closest('[inert]')) // does not have inert parent\n    .filter(x => !!x.offsetParent || x.getClientRects().length > 0) // is rendered\n    .filter(x => !x.parentElement?.closest('details:not([open])') ||\n      (x.tagName === 'SUMMARY' && x.parentElement?.tagName === 'DETAILS')\n    )\n}\n\nexport function getNextElement (elements: HTMLElement[], location?: 'next' | 'prev', condition?: (el: HTMLElement) => boolean) {\n  let _el\n  let idx = elements.indexOf(document.activeElement as HTMLElement)\n  const inc = location === 'next' ? 1 : -1\n  do {\n    idx += inc\n    _el = elements[idx]\n  } while ((!_el || _el.offsetParent == null || !(condition?.(_el) ?? true)) && idx < elements.length && idx >= 0)\n  return _el\n}\n\nexport function focusChild (el: Element, location?: 'next' | 'prev' | 'first' | 'last' | number) {\n  const focusable = focusableChildren(el)\n\n  if (location == null) {\n    if (el === document.activeElement || !el.contains(document.activeElement)) {\n      focusable[0]?.focus()\n    }\n  } else if (location === 'first') {\n    focusable[0]?.focus()\n  } else if (location === 'last') {\n    focusable.at(-1)?.focus()\n  } else if (typeof location === 'number') {\n    focusable[location]?.focus()\n  } else {\n    const _el = getNextElement(focusable, location)\n    if (_el) _el.focus()\n    else focusChild(el, location === 'next' ? 'first' : 'last')\n  }\n}\n\nexport function isEmpty (val: any): boolean {\n  return val === null || val === undefined || (typeof val === 'string' && val.trim() === '')\n}\n\nexport function noop () {}\n\n/** Returns null if the selector is not supported or we can't check */\nexport function matchesSelector (el: Element | undefined, selector: string): boolean | null {\n  const supportsSelector = IN_BROWSER &&\n    typeof CSS !== 'undefined' &&\n    typeof CSS.supports !== 'undefined' &&\n    CSS.supports(`selector(${selector})`)\n\n  if (!supportsSelector) return null\n\n  try {\n    return !!el && el.matches(selector)\n  } catch (err) {\n    return null\n  }\n}\n\nexport function ensureValidVNode (vnodes: VNodeArrayChildren): VNodeArrayChildren | null {\n  return vnodes.some(child => {\n    if (!isVNode(child)) return true\n    if (child.type === Comment) return false\n    return child.type !== Fragment ||\n      ensureValidVNode(child.children as VNodeArrayChildren)\n  })\n    ? vnodes\n    : null\n}\n\ntype Slot<T> = [T] extends [never] ? () => VNodeChild : (arg: T) => VNodeChild\n\nexport function renderSlot <T> (slot: Slot<never> | undefined, fallback?: Slot<never> | undefined): VNodeChild\nexport function renderSlot <T> (slot: Slot<T> | undefined, props: T, fallback?: Slot<T> | undefined): VNodeChild\nexport function renderSlot (slot?: Slot<unknown>, props?: unknown, fallback?: Slot<unknown>) {\n  // TODO: check if slot returns elements: #18308\n  return slot?.(props) ?? fallback?.(props)\n}\n\nexport function defer (timeout: number, cb: () => void) {\n  if (!IN_BROWSER || timeout === 0) {\n    cb()\n\n    return () => {}\n  }\n\n  const timeoutId = window.setTimeout(cb, timeout)\n\n  return () => window.clearTimeout(timeoutId)\n}\n\nexport function isClickInsideElement (event: MouseEvent, targetDiv: HTMLElement) {\n  const mouseX = event.clientX\n  const mouseY = event.clientY\n\n  const divRect = targetDiv.getBoundingClientRect()\n  const divLeft = divRect.left\n  const divTop = divRect.top\n  const divRight = divRect.right\n  const divBottom = divRect.bottom\n\n  return mouseX >= divLeft && mouseX <= divRight && mouseY >= divTop && mouseY <= divBottom\n}\n\nexport type TemplateRef = {\n  (target: Element | ComponentPublicInstance | null): void\n  value: HTMLElement | ComponentPublicInstance | null | undefined\n  readonly el: HTMLElement | undefined\n}\nexport function templateRef () {\n  const el = shallowRef<HTMLElement | ComponentPublicInstance | null>()\n  const fn = (target: HTMLElement | ComponentPublicInstance | null) => {\n    el.value = target\n  }\n  Object.defineProperty(fn, 'value', {\n    enumerable: true,\n    get: () => el.value,\n    set: val => el.value = val,\n  })\n  Object.defineProperty(fn, 'el', {\n    enumerable: true,\n    get: () => refElement(el.value),\n  })\n\n  return fn as TemplateRef\n}\n\nexport function checkPrintable (e: KeyboardEvent) {\n  const isPrintableChar = e.key.length === 1\n  const noModifier = !e.ctrlKey && !e.metaKey && !e.altKey\n  return isPrintableChar && noModifier\n}\n\nexport type Primitive = string | number | boolean | symbol | bigint\nexport function isPrimitive (value: unknown): value is Primitive {\n  return typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' || typeof value === 'bigint'\n}\n\nexport function escapeForRegex (sign: string) {\n  return '\\\\^$*+?.()|{}[]'.includes(sign)\n    ? `\\\\${sign}`\n    : sign\n}\n\nexport function extractNumber (text: string, decimalDigitsLimit: number | null, decimalSeparator: string) {\n  const onlyValidCharacters = new RegExp(`[\\\\d\\\\-${escapeForRegex(decimalSeparator)}]`)\n  const cleanText = text.split('')\n    .filter(x => onlyValidCharacters.test(x))\n    .filter((x, i, all) => (i === 0 && /[-]/.test(x)) || // sign allowed at the start\n        (x === decimalSeparator && i === all.indexOf(x)) || // decimal separator allowed only once\n        /\\d/.test(x))\n    .join('')\n\n  if (decimalDigitsLimit === 0) {\n    return cleanText.split(decimalSeparator)[0]\n  }\n\n  const decimalPart = new RegExp(`${escapeForRegex(decimalSeparator)}\\\\d`)\n  if (decimalDigitsLimit !== null && decimalPart.test(cleanText)) {\n    const parts = cleanText.split(decimalSeparator)\n    return [\n      parts[0],\n      parts[1].substring(0, decimalDigitsLimit),\n    ].join(decimalSeparator)\n  }\n\n  return cleanText\n}\n\nexport function camelizeProps<T extends Record<string, unknown>> (props: T | null): T {\n  const out = {} as T\n  for (const prop in props) {\n    out[camelize(prop) as keyof T] = props[prop]\n  }\n  return out\n}\n\nexport function onlyDefinedProps (props: Record<string, any>) {\n  const booleanAttributes = ['checked', 'disabled']\n  return Object.fromEntries(Object.entries(props)\n    .filter(([key, v]) => booleanAttributes.includes(key) ? !!v : v !== undefined))\n}\n\nexport type NonEmptyArray<T> = [T, ...T[]]\n\nexport function deepToRaw<T extends {}> (value: T): T {\n  const objectIterator = (input: any): any => {\n    if (Array.isArray(input)) {\n      return input.map(item => objectIterator(item))\n    }\n    if (isRef(input) || isReactive(input) || isProxy(input)) {\n      return objectIterator(toRaw(input))\n    }\n    if (isPlainObject(input)) {\n      return Object.keys(input).reduce((acc, key) => {\n        acc[key as keyof typeof acc] = objectIterator(input[key])\n        return acc\n      }, {} as T)\n    }\n    return input\n  }\n\n  return objectIterator(value)\n}\n"
  },
  {
    "path": "packages/vuetify/src/util/indentLines.ts",
    "content": "// Types\nexport type IndentLinesVariant = 'default' | 'simple'\nexport type IndentLineType = 'leaf' | 'last-leaf' | 'line' | 'leaf-link' | 'none'\n\nexport type IndentLinesOptions = {\n  depth: number\n  isLast: boolean\n  isLastGroup: boolean\n  leafLinks: boolean\n  separateRoots: boolean\n  parentIndentLines: IndentLineType[] | undefined\n  variant: IndentLinesVariant | undefined\n}\n\nexport type IndentLines = {\n  leaf: IndentLineType[] | undefined\n  node: IndentLineType[] | undefined\n  children: IndentLineType[] | undefined\n  footer: IndentLineType[] | undefined\n}\n\nexport function getIndentLines ({\n  depth,\n  isLast,\n  isLastGroup,\n  leafLinks,\n  separateRoots,\n  parentIndentLines,\n  variant,\n}: IndentLinesOptions): IndentLines {\n  const isLastLeaf = isLast && (!isLastGroup || separateRoots || depth > 1)\n\n  if (!parentIndentLines || !depth) {\n    return {\n      leaf: undefined,\n      node: undefined,\n      children: parentIndentLines,\n      footer: parentIndentLines && (!isLastLeaf || variant === 'simple')\n        ? [...parentIndentLines, separateRoots ? 'none' : 'line']\n        : ['none'],\n    }\n  }\n\n  if (variant === 'simple') {\n    return {\n      leaf: [...parentIndentLines, 'line'],\n      node: [...parentIndentLines, 'line'],\n      children: [...parentIndentLines, 'line'],\n      footer: [...parentIndentLines, 'line', 'line'],\n    }\n  }\n\n  return {\n    leaf: [\n      ...parentIndentLines,\n      isLastLeaf ? 'last-leaf' : 'leaf',\n      ...leafLinks ? ['leaf-link'] as IndentLineType[] : [],\n    ],\n    node: [\n      ...parentIndentLines,\n      isLastLeaf ? 'last-leaf' : 'leaf',\n    ],\n    children: [\n      ...parentIndentLines,\n      isLastLeaf ? 'none' : 'line',\n    ],\n    footer: [\n      ...parentIndentLines,\n      isLastLeaf ? 'none' : 'line',\n    ],\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/src/util/index.ts",
    "content": "export * from './anchor'\nexport * from './animation'\nexport * from './bindProps'\nexport * from './colorUtils'\nexport * from './console'\nexport * from './createSimpleFunctional'\nexport * from './deepEqual'\nexport * from './defineComponent'\nexport * from './dom'\nexport * from './easing'\nexport * from './events'\nexport * from './getCurrentInstance'\nexport * from './getScrollParent'\nexport * from './globals'\nexport * from './helpers'\nexport * from './indentLines'\nexport * from './injectSelf'\nexport * from './isFixedPosition'\nexport * from './propsFactory'\nexport * from './useRender'\nexport * from './timeUtils'\nexport * from './throttle'\n"
  },
  {
    "path": "packages/vuetify/src/util/injectSelf.ts",
    "content": "// Utilities\nimport { getCurrentInstance } from '@/util/getCurrentInstance'\n\n// Types\nimport type { ComponentInternalInstance, InjectionKey } from 'vue'\n\nexport function injectSelf<T>(key: InjectionKey<T> | string, vm?: ComponentInternalInstance): T | undefined\nexport function injectSelf (key: InjectionKey<any> | string, vm = getCurrentInstance('injectSelf')) {\n  const { provides } = vm\n\n  if (provides && (key as string | symbol) in provides) {\n    // TS doesn't allow symbol as index type\n    return provides[key as string]\n  }\n  return undefined\n}\n"
  },
  {
    "path": "packages/vuetify/src/util/isFixedPosition.ts",
    "content": "export function isFixedPosition (el?: HTMLElement) {\n  while (el) {\n    if (window.getComputedStyle(el).position === 'fixed') {\n      return true\n    }\n    el = el.offsetParent as HTMLElement\n  }\n  return false\n}\n"
  },
  {
    "path": "packages/vuetify/src/util/propsFactory.ts",
    "content": "// Types\nimport type { IfAny } from '@vue/shared' // eslint-disable-line vue/prefer-import-from-vue\nimport type { ComponentObjectPropsOptions, Prop, PropType } from 'vue'\n\n/**\n * Creates a factory function for props definitions.\n * This is used to define props in a composable then override\n * default values in an implementing component.\n *\n * @example Simplified signature\n * (props: Props) => (defaults?: Record<keyof props, any>) => Props\n *\n * @example Usage\n * const makeProps = propsFactory({\n *   foo: String,\n * })\n *\n * defineComponent({\n *   props: {\n *     ...makeProps({\n *       foo: 'a',\n *     }),\n *   },\n *   setup (props) {\n *     // would be \"string | undefined\", now \"string\" because a default has been provided\n *     props.foo\n *   },\n * }\n */\n\nexport function propsFactory<\n  PropsOptions extends ComponentObjectPropsOptions\n> (props: PropsOptions, source: string) {\n  return <Defaults extends PartialKeys<PropsOptions> = {}>(\n    defaults?: Defaults\n  ): AppendDefault<PropsOptions, Defaults> => {\n    return Object.keys(props).reduce<any>((obj, prop) => {\n      const isObjectDefinition = typeof props[prop] === 'object' && props[prop] != null && !Array.isArray(props[prop])\n      const definition = isObjectDefinition ? props[prop] : { type: props[prop] }\n\n      if (defaults && prop in defaults) {\n        obj[prop] = {\n          ...definition,\n          default: defaults[prop],\n        }\n      } else {\n        obj[prop] = definition\n      }\n\n      if (source && !obj[prop].source) {\n        obj[prop].source = source\n      }\n\n      return obj\n    }, {})\n  }\n}\n\ntype AppendDefault<T extends ComponentObjectPropsOptions, D extends PartialKeys<T>> = {\n  [P in keyof T]-?: unknown extends D[P]\n    ? T[P]\n    : T[P] extends Record<string, unknown>\n      ? Omit<T[P], 'type' | 'default'> & {\n        type: PropType<MergeTypeDefault<T[P], D[P]>>\n        default: MergeDefault<T[P], D[P]>\n      }\n      : {\n        type: PropType<MergeTypeDefault<T[P], D[P]>>\n        default: MergeDefault<T[P], D[P]>\n      }\n}\n\ntype MergeTypeDefault<T, D, P = InferPropType<T>> = unknown extends D\n  ? P\n  : (P | D)\ntype MergeDefault<T, D, P = InferPropType<T>> = unknown extends D\n  ? P\n  : (NonNullable<P> | D)\n\n/**\n * Like `Partial<T>` but doesn't care what the value is\n */\ntype PartialKeys<T> = { [P in keyof T]?: unknown }\n\n// Copied from Vue\ntype InferPropType<T> = [T] extends [null]\n  ? any // null & true would fail to infer\n  : [T] extends [{ type: null | true }]\n    // As TS issue https://github.com/Microsoft/TypeScript/issues/14829\n    // somehow `ObjectConstructor` when inferred from { (): T } becomes `any`\n    // `BooleanConstructor` when inferred from PropConstructor(with PropMethod) becomes `Boolean`\n    ? any\n    : [T] extends [ObjectConstructor | { type: ObjectConstructor }]\n      ? Record<string, any>\n      : [T] extends [BooleanConstructor | { type: BooleanConstructor }]\n        ? boolean\n        : [T] extends [DateConstructor | { type: DateConstructor }]\n          ? Date\n          : [T] extends [(infer U)[] | { type: (infer U)[] }]\n            ? U extends DateConstructor\n              ? Date | InferPropType<U>\n              : InferPropType<U>\n            : [T] extends [Prop<infer V, infer D>]\n              ? unknown extends V\n                ? IfAny<V, V, D>\n                : V\n              : T\n"
  },
  {
    "path": "packages/vuetify/src/util/svg-arc-corners.ts",
    "content": "/*\n * Credits: Alexander Milevski https://github.com/w8r/svg-arc-corners\n */\n\ntype Point = [x: number, y: number]\n\nfunction pointOnArc (center: Point, radius: number, angle: number) {\n  const radians = (angle - 90) * Math.PI / 180.0\n  return [center[0] + radius * Math.cos(radians), center[1] + radius * Math.sin(radians)]\n}\n\nfunction drawCircle ([x, y]: Point, r: number, width: number) {\n  const innerRadius = r - width\n  return [\n    'M', x - r, y,\n    'A', r, r, 0, 1, 0, x + r, y,\n    'A', r, r, 0, 1, 0, x - r, y,\n    'M', x - innerRadius, y,\n    'A', innerRadius, innerRadius, 0, 1, 0, x + innerRadius, y,\n    'A', innerRadius, innerRadius, 0, 1, 0, x - innerRadius, y,\n    'Z',\n  ]\n}\n\nexport function simpleArc (center: Point, r: number, startAngle: number, endAngle: number) {\n  const start = pointOnArc(center, r, startAngle)\n  const end = pointOnArc(center, r, endAngle)\n  const sweep = endAngle - startAngle > 180 ? 1 : 0\n\n  return [\n    `M${start[0]} ${start[1]}`,\n    `A${r} ${r} 0 ${sweep} 1 ${end[0]} ${end[1]}`,\n    `L${center[0]} ${center[1]}Z`,\n  ]\n    .join(' ')\n}\n\nexport function roundedArc (center: Point, radius: number, startAngle: number, endAngle: number, width: number, rounding: number): string {\n  width = Math.min(radius, width)\n\n  if (Math.abs(endAngle - startAngle) === 360) {\n    return drawCircle(center, radius, width).join(' ')\n  }\n\n  if (rounding === 0 && radius === width) {\n    return simpleArc(center, radius, startAngle, endAngle)\n  }\n\n  const innerR = radius - width\n  const circumference = Math.abs(endAngle - startAngle)\n  rounding = Math.min(width / 2, rounding)\n\n  if (360 * (rounding / (Math.PI * (radius - width))) > Math.abs(startAngle - endAngle)) {\n    rounding = circumference / 360 * innerR * Math.PI\n  }\n\n  // inner and outer radiuses\n  const innerR2 = innerR + rounding\n  const outerRadius = radius - rounding\n\n  // butts corner points\n  const oStart = pointOnArc(center, outerRadius, startAngle)\n  const oEnd = pointOnArc(center, outerRadius, endAngle)\n\n  const iStart = pointOnArc(center, innerR2, startAngle)\n  const iEnd = pointOnArc(center, innerR2, endAngle)\n\n  const iSection = innerR ? 360 * (rounding / (2 * Math.PI * innerR)) : 0\n  const oSection = 360 * (rounding / (2 * Math.PI * radius))\n\n  // arcs endpoints\n  const iArcStart = pointOnArc(center, innerR, startAngle + iSection)\n  const iArcEnd = pointOnArc(center, innerR, endAngle - iSection)\n\n  const oArcStart = pointOnArc(center, radius, startAngle + oSection)\n  const oArcEnd = pointOnArc(center, radius, endAngle - oSection)\n\n  const arcSweep1 = circumference > 180 + 2 * oSection ? 1 : 0\n  const arcSweep2 = circumference > 180 + 2 * iSection ? 1 : 0\n\n  return [\n    // begin path\n    'M', oStart[0], oStart[1],\n    // outer start corner\n    'A', rounding, rounding, 0, 0, 1, oArcStart[0], oArcStart[1],\n    // outer main arc\n    'A', radius, radius, 0, arcSweep1, 1, oArcEnd[0], oArcEnd[1],\n    // outer end corner\n    'A', rounding, rounding, 0, 0, 1, oEnd[0], oEnd[1],\n    // end butt\n    'L', iEnd[0], iEnd[1],\n    // inner end corner\n    'A', rounding, rounding, 0, 0, 1, iArcEnd[0], iArcEnd[1],\n    // inner arc\n    'A', innerR, innerR, 0, arcSweep2, 0, iArcStart[0], iArcStart[1],\n    // inner start corner\n    'A', rounding, rounding, 0, 0, 1, iStart[0], iStart[1], 'Z', // end path\n  ]\n    .join(' ')\n}\n"
  },
  {
    "path": "packages/vuetify/src/util/throttle.ts",
    "content": "export function throttle<T extends (...args: any[]) => any> (\n  fn: T,\n  delay: number,\n  options = { leading: true, trailing: true },\n) {\n  let timeoutId = 0 as any\n  let lastExec = 0\n  let throttling = false\n  let start = 0\n\n  function clear () {\n    clearTimeout(timeoutId)\n    throttling = false\n    start = 0\n  }\n\n  const wrap = (...args: Parameters<T>): void | ReturnType<T> => {\n    clearTimeout(timeoutId)\n\n    const now = Date.now()\n\n    if (!start) start = now\n    const elapsed = now - Math.max(start, lastExec)\n\n    function invoke () {\n      lastExec = Date.now()\n      timeoutId = setTimeout(clear, delay)\n      fn(...args)\n    }\n\n    if (!throttling) {\n      throttling = true\n      if (options.leading) {\n        invoke()\n      }\n    } else if (elapsed >= delay) {\n      invoke()\n    } else if (options.trailing) {\n      timeoutId = setTimeout(invoke, delay - elapsed)\n    }\n  }\n\n  wrap.clear = clear\n  wrap.immediate = fn\n  return wrap\n}\n"
  },
  {
    "path": "packages/vuetify/src/util/timeUtils.ts",
    "content": "export function formatTime (seconds: number) {\n  return [\n    Math.floor(seconds % 60),\n    Math.floor(seconds / 60 % 60),\n    Math.floor(seconds / 60 / 60 % 60),\n  ]\n    .filter((x, i) => i < 2 || x > 0)\n    .reverse()\n    .map(String)\n    .map((x, i) => i > 0 ? x.padStart(2, '0') : x)\n    .join(':')\n}\n"
  },
  {
    "path": "packages/vuetify/src/util/useRender.ts",
    "content": "// Utilities\nimport { getCurrentInstance } from './getCurrentInstance'\n\n// Types\nimport type { VNode } from 'vue'\n\nexport function useRender (render: () => VNode): void {\n  const vm = getCurrentInstance('useRender') as any\n  vm.render = render\n}\n"
  },
  {
    "path": "packages/vuetify/test/contextStub.ts",
    "content": "// vitest/browser stub for unit tests to suppress warning\nexport const page = null\nexport const server = null\nexport const userEvent = null\nexport const cdp = null\nexport const commands = null\n"
  },
  {
    "path": "packages/vuetify/test/globals.d.ts",
    "content": "import type { CustomCommands } from './setup/browser-commands.ts'\n\ninterface CustomMatchers<R = unknown> {\n  toHaveBeenTipped: () => R\n  toHaveBeenWarned: () => R\n}\n\ndeclare module 'vitest' {\n  interface Assertion<T = any> extends CustomMatchers<T> {}\n  interface AsymmetricMatchersContaining extends CustomMatchers {}\n}\n\ndeclare module 'vitest/browser' {\n  interface BrowserCommands extends CustomCommands {}\n}\n"
  },
  {
    "path": "packages/vuetify/test/index.ts",
    "content": "// Utilities\nimport './globals.d'\nimport { render as _render } from '@testing-library/vue'\nimport { createVuetify } from '../src/framework'\nimport { mergeDeep } from '../src/util'\nimport { aliases } from '../src/iconsets/mdi-svg'\nimport { commands, page } from 'vitest/browser'\n\nimport type { RenderOptions, RenderResult } from '@testing-library/vue'\nimport type { VuetifyOptions } from '../src/framework'\n\nexport { userEvent, page, commands } from 'vitest/browser'\nexport { screen } from '@testing-library/vue'\nexport * from './templates'\n\nexport function touch (element: Element) {\n  const createTrigger = (eventName: string) => (clientX: number, clientY: number) => {\n    const touches = [{ clientX, clientY }]\n    const event = new Event(eventName)\n\n    ;(event as any).touches = touches\n    ;(event as any).changedTouches = touches\n    element.dispatchEvent(event)\n\n    return touch(element)\n  }\n\n  return {\n    start: createTrigger('touchstart'),\n    move: createTrigger('touchmove'),\n    end: createTrigger('touchend'),\n  }\n}\n\nexport const wait = (timeout?: number) => {\n  return new Promise(resolve => setTimeout(resolve, timeout))\n}\n\nexport const waitAnimationFrame = () => {\n  return new Promise(resolve => requestAnimationFrame(resolve))\n}\n\nexport const waitIdle = () => {\n  return new Promise(resolve => requestIdleCallback(resolve, { timeout: 500 }))\n}\n\nexport const click = (el: Element) => {\n  return commands.click(page.elementLocator(el).selector)\n}\n\nexport const waitForClickable = (el: Element) => {\n  return commands.waitForClickable(page.elementLocator(el).selector)\n}\n\nexport const scroll = (options: ScrollToOptions, el: Element | Window = window) => {\n  return Promise.race([\n    wait(500),\n    new Promise(resolve => {\n      el.addEventListener('scrollend', resolve, { once: true })\n      el.scroll(options)\n    }).then(waitIdle),\n  ])\n}\n\nexport function render<C> (\n  component: C,\n  options?: RenderOptions<C> | null,\n  vuetifyOptions?: VuetifyOptions\n): RenderResult {\n  const vuetify = createVuetify(mergeDeep({ icons: { aliases } }, vuetifyOptions))\n\n  const defaultOptions = {\n    global: {\n      stubs: {\n        transition: false,\n        'transition-group': false,\n      },\n      plugins: [vuetify],\n    },\n  }\n\n  const mountOptions = mergeDeep(defaultOptions, options!, (a, b) => a.concat(b))\n\n  return _render(component, mountOptions)\n}\n\nexport function unfill (o: Record<string, any>) {\n  return Object.keys(o).reduce((result, key) => {\n    result[key] = typeof o[key] === 'object' ? unfill(o[key]) : typeof o[key]\n    return result\n  }, {} as Record<string, any>)\n}\n"
  },
  {
    "path": "packages/vuetify/test/setup/browser-commands.ts",
    "content": "/// <reference types=\"@vitest/browser-playwright\" />\n\nimport type { BrowserCommandContext } from 'vitest/node'\n\nasync function drag (ctx: BrowserCommandContext, start: [number, number], ...moves: number[][]) {\n  const cdp = await ctx.provider.getCDPSession!(ctx.sessionId)\n  await cdp.send('Input.dispatchTouchEvent', {\n    type: 'touchStart',\n    touchPoints: [{ x: start[0], y: start[1] }],\n  })\n  await cdp.send('Input.dispatchTouchEvent', {\n    type: 'touchMove',\n    touchPoints: [{ x: start[0], y: start[1] }],\n  })\n  for (const move of moves) {\n    await cdp.send('Input.dispatchTouchEvent', {\n      type: 'touchMove',\n      touchPoints: [{ x: move[0], y: move[1] }],\n    })\n  }\n  await cdp.send('Input.dispatchTouchEvent', {\n    type: 'touchEnd',\n    touchPoints: [{ x: moves.at(-1)![0], y: moves.at(-1)![1] }],\n  })\n}\n\nasync function click (ctx: BrowserCommandContext, ...args: [string] | [number, number]) {\n  if (args.length === 1) {\n    const el = await ctx.page.$(args[0])\n    await el?.click()\n  } else {\n    await ctx.page.mouse.click(...args)\n  }\n}\n\nasync function waitStable (ctx: BrowserCommandContext, selector: string) {\n  const el = ctx.iframe.locator(selector)\n  const handles = await el.elementHandles()\n  if (handles.length > 1) {\n    await Promise.all(\n      handles.map(h => Promise.any([\n        h.waitForElementState('stable', { timeout: 1000 }),\n        h.waitForElementState('hidden', { timeout: 1000 }),\n      ]))\n    )\n  } else {\n    await Promise.all(\n      handles.map(h =>\n        h.waitForElementState('stable', { timeout: 1000 }),\n      )\n    )\n  }\n}\n\nasync function waitForClickable (ctx: BrowserCommandContext, selector: string) {\n  (await ctx.page.$(selector))?.click({ trial: true })\n}\n\nasync function setFocusEmulationEnabled (ctx: BrowserCommandContext) {\n  const cdp = await ctx.provider.getCDPSession!(ctx.sessionId)\n  await cdp.send('Emulation.setFocusEmulationEnabled', { enabled: true })\n}\n\nasync function setReduceMotionEnabled (ctx: BrowserCommandContext) {\n  await ctx.page.emulateMedia({\n    reducedMotion: 'reduce',\n  })\n}\n\n/**\n * Use this to run some async code in only one test at a time\n *\n * ```js\n * const lock = await commands.getLock()\n * // no other code using getLock can run until this is done\n * await a()\n * await b()\n * await commands.releaseLock(lock)\n * ```\n */\nasync function getLock () {\n  const _lastLock = getLock.lastLock\n\n  const lock = Promise.withResolvers<void>()\n  const id = getLock.lockCount++\n  getLock.locks.set(id, lock)\n  getLock.lastLock = lock.promise\n  await _lastLock\n\n  return id\n}\ngetLock.lockCount = 0\ngetLock.locks = new Map<number, PromiseWithResolvers<void>>()\ngetLock.lastLock = Promise.resolve()\n\nasync function releaseLock (ctx: BrowserCommandContext, lock: number) {\n  getLock.locks.get(lock)!.resolve()\n}\n\nlet abortTimeout: ReturnType<typeof setTimeout>\nfunction abortAfter (ctx: BrowserCommandContext, delay: number, name: string) {\n  abortTimeout = setTimeout(async () => {\n    // eslint-disable-next-line no-console\n    console.error(`[Error] Test timeout: Aborting after ${delay}ms for ${name} in ${ctx.testPath}`)\n    // eslint-disable-next-line no-console\n    console.error('[Warning] \"chrome\" process might still be running and require manual shutdown.')\n    process.exitCode = 1\n    await ctx.project.vitest.exit(true)\n  }, delay)\n}\n\nfunction clearAbortTimeout (ctx: BrowserCommandContext) {\n  clearTimeout(abortTimeout)\n}\n\nexport const commands = {\n  drag,\n  click,\n  waitStable,\n  waitForClickable,\n  setFocusEmulationEnabled,\n  setReduceMotionEnabled,\n  abortAfter,\n  clearAbortTimeout,\n  getLock,\n  releaseLock,\n}\n\nexport type CustomCommands = {\n  [k in keyof typeof commands]: typeof commands[k] extends (ctx: any, ...args: infer A) => any\n    ? (...args: A) => any\n    : 'never'\n}\n"
  },
  {
    "path": "packages/vuetify/test/setup/browser-setup.ts",
    "content": "import 'roboto-fontface'\nimport '@/styles/main.sass'\nimport { afterEach, beforeAll, beforeEach } from 'vitest'\nimport { cleanup } from '@testing-library/vue'\nimport { commands, page } from 'vitest/browser'\n\nbeforeAll(async () => {\n  await commands.setFocusEmulationEnabled()\n\n  // contextOptions.reducedMotion doesn't seem to do anything for some reason\n  await commands.setReduceMotionEnabled()\n})\n\nbeforeEach(async ctx => {\n  // Cleanup before not after, so if the test\n  // fails we can inspect what has happened\n  cleanup()\n  await page.viewport(1280, 800)\n\n  if (process.env.TEST_TDD_ONLY) {\n    let suite = ctx.task.suite\n    while (suite) {\n      if (suite.name === 'Showcase') {\n        return\n      }\n      suite = suite.suite\n    }\n    ctx.skip()\n  }\n})\n\nafterEach(async ctx => {\n  if (\n    ctx.task.result?.state === 'fail' &&\n    ctx.task.name !== 'Showcase' &&\n    !ctx.task.result.errors?.every(e => e.message.startsWith('Visual difference detected'))\n  ) {\n    // vizzly disables screenshotOnFailure\n    await page.screenshot()\n  }\n})\n"
  },
  {
    "path": "packages/vuetify/test/setup/to-have-been-warned.ts",
    "content": "import type { Mock } from 'vitest'\nimport { afterEach, beforeAll, beforeEach, expect, vi } from 'vitest'\n\nfunction noop () {}\nif (typeof console === 'undefined') {\n  (window as any).console = {\n    warn: noop,\n    error: noop,\n  }\n}\n\n// avoid info messages during test\n// eslint-disable-next-line no-console\nconsole.info = noop\n\nlet warn: Mock\nlet error: Mock\nbeforeAll(() => {\n  warn = vi.spyOn(console, 'warn').mockImplementation(noop) as any\n  error = vi.spyOn(console, 'error').mockImplementation(noop) as any\n  expect.extend({\n    toHaveBeenWarned: createCompareFn(error),\n    toHaveBeenTipped: createCompareFn(warn),\n  })\n})\n\nconst asserted: string[] = []\n\nbeforeEach(() => {\n  asserted.length = 0\n  warn.mockClear()\n  error.mockClear()\n})\n\nafterEach(() => {\n  for (const type of ['error', 'warn']) {\n    const warned = (msg: string) => asserted.some(assertedMsg => msg.toString().includes(assertedMsg))\n    for (const args of (console as any)[type].mock.calls) {\n      if (!warned(args[0])) {\n        throw new Error(`Unexpected console.${type} message: ${args[0]}`)\n      }\n    }\n  }\n})\n\nfunction createCompareFn (spy: Mock) {\n  const hasWarned = (msg: string) => {\n    for (const args of spy.mock.calls) {\n      if (args.some((arg: any) => (\n        arg.toString().includes(msg)\n      ))) return true\n    }\n    return false\n  }\n\n  return (msg: string) => {\n    asserted.push(msg)\n    const warned = Array.isArray(msg)\n      ? msg.some(hasWarned)\n      : hasWarned(msg)\n    return {\n      pass: warned,\n      message: warned\n        ? () => (`Expected message \"${msg}\" not to have been warned`)\n        : () => (`Expected message \"${msg}\" to have been warned`),\n    }\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/test/setup/unit-setup.ts",
    "content": "import { afterEach, vi } from 'vitest'\nimport { cleanup } from '@testing-library/vue'\n\n// Stub visualViewport so Vuetify components (e.g. VMenu) don't crash in JSDOM\nif (!globalThis.visualViewport) {\n  vi.stubGlobal('visualViewport', new EventTarget())\n}\n\nafterEach(() => {\n  cleanup()\n})\n"
  },
  {
    "path": "packages/vuetify/test/templates/Application.tsx",
    "content": "import { VApp } from '@/components/VApp'\nimport { VLocaleProvider } from '@/components/VLocaleProvider'\nimport type { FunctionalComponent } from 'vue'\n\nexport const Application: FunctionalComponent<{ rtl?: boolean }> = (props, { slots, attrs }) => {\n  return (\n    <VApp { ...attrs } rtl={ props.rtl }>\n      <VLocaleProvider rtl={ props.rtl }>\n        { slots.default?.() }\n      </VLocaleProvider>\n    </VApp>\n  )\n}\n"
  },
  {
    "path": "packages/vuetify/test/templates/CenteredGrid.tsx",
    "content": "import { FunctionalComponent } from 'vue'\n\nexport const CenteredGrid: FunctionalComponent<{ width?: string }> = (props, { slots, attrs }) => {\n  const width = props.width || 'auto'\n  return (\n    <div\n      class=\"d-flex flex-column mx-auto py-2\"\n      style={{ width, gridGap: '1.2rem' }}\n    >\n      { slots.default?.() }\n    </div>\n  )\n}\n"
  },
  {
    "path": "packages/vuetify/test/templates/generateStories.tsx",
    "content": "/// <reference types=\"@vizzly-testing/vitest\" />\n\n/**\n * Utilities for generating formatted mount functions\n * Some utility functions for mounting these generated examples inside of tests\n */\nimport type { FunctionalComponent } from 'vue'\nimport type { JSXComponent } from '@/util'\nimport { describe, expect, it } from 'vitest'\nimport { page } from 'vitest/browser'\nimport { render, waitIdle } from '@test'\n\ntype Stories = Record<string, JSX.Element>\ntype Props = Record<string, boolean | any[]>\ntype GenerateConfiguration = {\n  props: Props\n  component: JSXComponent\n  stories?: Stories\n} | {\n  props?: never\n  component?: never\n  stories: Stories\n}\n\ntype Example = {\n  name: string\n  mount: () => JSX.Element\n}\n\n/** Utility components */\nconst title = (key: string) => <h4 class=\"my-4\">{ key }</h4>\n\n// Spacing between content\nconst grid = (content: JSX.Element | JSX.Element[]) => <div style=\"display: flex; gap: 0.8rem;\">{ content }</div>\n\n// Spacing between mounted components\nconst Wrapper: FunctionalComponent = (_, { slots }) => <div class=\"ma-4\">{ slots.default?.() }</div>\n\n/**\n * Generate an array of Examples by iterating over Stories.\n * @param stories An object where the key is the name of the story and the value is the component to be rendered.\n * @returns An array of Examples, where the name of the story is formatted.\n * @example makeExamplesFromStories({\n    'small success button': <VBtn color=\"success\" size=\"small\">Done!</VBtn>\n  })\n */\nexport const makeExamplesFromStories = (stories: Stories): Example[] => {\n  return Object.entries(stories).map(([key, value]) => {\n    return {\n      name: key,\n      mount: () => (\n        <Wrapper>\n          { title(key) }\n          { grid(value) }\n        </Wrapper>\n      ),\n    }\n  })\n}\n\n/**\n * Generate a list of Examples by iterating over all passed in Props.\n * @param props A configuration object of props to call\n * @param Component The component to be mounted with those specific props.\n * @returns\n * @example makeExamplesFromProps({\n    color: ['success', 'error' ],\n    icon: true\n   }, VBtn)\n */\nexport const makeExamplesFromProps = (props: Props, Component: JSXComponent): Example[] => {\n  return Object.entries(props).map(([key, value]) => {\n    // Collect an array of examples by prop.\n    const variants: JSX.Element[] = []\n\n    // Props with boolean values should be rendered with both their true/false states\n    if (typeof value === 'boolean') {\n      variants.push(<Component { ...{ [key]: true } }>Is { key }</Component>)\n      variants.push(<Component { ...{ [key]: false } }>Is not { key }</Component>)\n    } else if (Array.isArray(value)) {\n      // Props with array values should be iterated over\n      value.forEach(v => {\n        variants.push(<Component { ... { [key]: v } }>{ v }</Component>)\n      })\n    }\n\n    return {\n      name: key,\n      mount: () => (\n        <Wrapper>\n          { title(key) }\n          { grid(variants) }\n        </Wrapper>\n      ),\n    }\n  })\n}\n\n/**\n * Generate a single `it` block with all of the stories and examples passed in\n * @param configuration\n * @returns\n */\nexport const showcase = ({ props, stories, component }: GenerateConfiguration) => {\n  let exampleStories: Example[]\n  let exampleProps: Example[]\n  if (stories) {\n    exampleStories = makeExamplesFromStories(stories)\n  }\n\n  if (props && !component) { throw new Error('Cannot generate examples from props without a component') }\n  if (props && component) {\n    exampleProps = makeExamplesFromProps(props, component)\n  }\n\n  // Save time by only rendering variants if we're taking screenshots\n  const matrix = (globalThis as any).__VIZZLY_SERVER_URL__\n    ? [\n      ['light', 'mobile'],\n      ['light', 'desktop'],\n      ['dark', 'mobile'],\n      ['dark', 'desktop'],\n    ] as const\n    : [['light', 'desktop']] as const\n\n  return describe('Showcase', () => {\n    it.each(matrix)('%s %s', async (theme, device) => {\n      const style = document.createElement('style')\n      style.innerHTML = `\n        *, *::before, *::after {\n          animation-duration: 0s !important;\n          animation-delay: 0s !important;\n          transition-duration: 0s !important;\n          transition-delay: 0s !important;\n        }`\n      document.head.append(style)\n\n      render(() => (\n        <>\n          { exampleStories && (\n            <>\n              <h2 class=\"mx-4 mt-10 mb-4\">Stories</h2>\n              { exampleStories.map(s => s.mount()) }\n            </>\n          )}\n          { exampleProps && (\n            <>\n              <h2 class=\"mx-4 mt-10 mb-4\">Props</h2>\n              { exampleProps.map(s => s.mount()) }\n            </>\n          )}\n        </>\n      ), null, {\n        theme: {\n          defaultTheme: theme,\n        },\n      })\n\n      let suite = (globalThis as any).__vitest_worker__.current.suite.suite\n      let name = ''\n      while (suite) {\n        name = suite.name + ' ' + name\n        suite = suite.suite\n      }\n\n      await page.viewport({ mobile: 600, desktop: 1280 }[device], document.body.scrollHeight)\n      await waitIdle()\n      await expect.soft(page).toMatchScreenshot(name.trim(), {\n        properties: { device, theme },\n      })\n    })\n  })\n}\n\n/**\n * Generate one `it` block per example passed in\n * @param stories\n * @returns\n */\nexport const generateByExample = (stories: Stories) => {\n  return makeExamplesFromStories(stories).map(({ name, mount }) => {\n    return it(name, () => {\n      render(mount)\n    })\n  })\n}\n\n/**\n * Generate one `it` block per prop passed in and render all applicable variants for those props\n * @param props\n * @param component\n * @returns\n */\nexport const generateByProps = (props: Props, component: JSXComponent) => {\n  return makeExamplesFromProps(props, component).map(({ mount, name }) => {\n    return it(name, () => {\n      render(mount)\n    })\n  })\n}\n"
  },
  {
    "path": "packages/vuetify/test/templates/gridOn.tsx",
    "content": "import { VNode } from 'vue'\n\nexport function gridOn<A, B> (a: Readonly<A[]>, b: Readonly<B[]>, fn: (a: A, b: B) => VNode) {\n  return (\n    <div class=\"d-flex flex-column\" style=\"gap: 0.4rem\">\n      { a.map(a => (\n        <>\n          <h5 style=\"margin: 0\">{ a as any }</h5>\n          <div class=\"d-flex\" style=\"gap: 0.8rem\">\n            { b.map(b => fn(a, b)) }\n          </div>\n        </>\n      ))}\n    </div>\n  )\n}\n"
  },
  {
    "path": "packages/vuetify/test/templates/index.ts",
    "content": "export * from './CenteredGrid'\nexport * from './generateStories'\nexport * from './Application'\nexport * from './gridOn'\n"
  },
  {
    "path": "packages/vuetify/tsconfig.checks.json",
    "content": "{\n  \"extends\": \"./tsconfig.dev.json\",\n  \"compilerOptions\": {\n    \"skipLibCheck\": true\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/tsconfig.dev.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"include\": [\n    \"src\",\n    \"dev\",\n    \"test\",\n    \"cypress\",\n    \"./cypress.config.ts\",\n    \"./vite.config.ts\",\n    \"./vitest.config.ts\",\n    \"./vitest.workspace.ts\"\n  ],\n  \"compilerOptions\": {\n    \"allowJs\": true,\n    \"allowImportingTsExtensions\": true,\n    \"types\": [\n      \"@vitest/browser/providers/webdriverio\"\n    ]\n  },\n  \"vueCompilerOptions\": {\n    \"strictTemplates\": true\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/tsconfig.dist.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"exclude\": [\"dev\", \"**/*.spec.*\", \"test\"],\n  \"compilerOptions\": {\n    \"outDir\": \"./lib\",\n    \"emitDeclarationOnly\": true,\n    \"skipLibCheck\": true,\n  },\n}\n"
  },
  {
    "path": "packages/vuetify/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\",\n  \"include\": [\n    \"src\",\n    \"dev\",\n  ],\n  \"exclude\": [\"**/*.spec.cy.ts\", \"**/*.spec.cy.tsx\"],\n  \"compilerOptions\": {\n    \"paths\": {\n      \"@/*\": [\"./src/*\"],\n      \"@test\": [\"./test/index.ts\"]\n    },\n    \"types\": [\n      \"node\",\n      \"vue-router\"\n    ],\n    \"stripInternal\": true,\n    \"skipLibCheck\": false\n  }\n}\n"
  },
  {
    "path": "packages/vuetify/vite.config.ts",
    "content": "import path from 'node:path'\nimport fs, { readFileSync } from 'node:fs'\nimport { fileURLToPath } from 'node:url'\n\nimport fg from 'fast-glob'\nimport { defineConfig, loadEnv } from 'vite'\n\nimport vue from '@vitejs/plugin-vue'\nimport vueJsx from '@vitejs/plugin-vue-jsx'\nimport Components from 'unplugin-vue-components/vite'\nimport livePreview from 'vite-live-preview'\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url))\nconst resolve = (file: string) => path.resolve(__dirname, file)\n\nconst vuetifyPackage = JSON.parse(fs.readFileSync('./package.json', 'utf-8'))\n\nconst index = readFileSync(resolve('src/components/index.ts'), { encoding: 'utf8' })\nconst block = Array.from(index.matchAll(/^\\/\\/ export \\* from '\\.\\/(.*)'$/gm), m => m[1])\nconst files = fg.sync(['src/components/**/index.ts', 'src/labs/**/index.ts'], { cwd: __dirname })\nconst components = files.filter(file => file.startsWith('src/labs') || !block.some(name => file.includes(`/${name}/`)))\nconst map = new Map(components.flatMap(file => {\n  const src = readFileSync(file, { encoding: 'utf8' })\n  const matches = src.matchAll(/export const (V\\w+)|export { (V\\w+) }/gm)\n  return Array.from(matches, m => [m[1] || m[2], file.replace('src/', '@/').replace('.ts', '')])\n}))\n\nconst viteSSR = process.env.TEST ? () => null : (await import('vite-ssr/plugin.js').then(m => m.default))\n\nexport default defineConfig(({ mode }) => {\n  Object.assign(process.env, loadEnv(mode, process.cwd(), ''))\n\n  return {\n    root: resolve('dev'),\n    server: {\n      host: process.env.HOST,\n      port: process.env.TEST ? undefined : Number(process.env.PORT ?? 8090),\n      strictPort: !!process.env.PORT && !process.env.TEST,\n      warmup: {\n        clientFiles: process.env.TEST ? [] : ['./index.html'],\n      },\n    },\n    preview: {\n      host: process.env.HOST,\n      port: Number(process.env.PORT ?? 8090),\n      strictPort: !!process.env.PORT,\n    },\n    resolve: {\n      alias: [\n        { find: /^vuetify$/, replacement: resolve('./src/framework.ts') },\n        { find: /^vuetify\\/(.*)/, replacement: resolve('./$1') },\n        { find: /^@\\/(.*)/, replacement: resolve('./src/$1') },\n      ],\n    },\n    plugins: [\n      vue(),\n      vueJsx({ optimize: false, enableObjectSlots: false }),\n      viteSSR(),\n      Components({\n        dts: !process.env.TEST,\n        resolvers: [\n          name => {\n            if (map.has(name)) {\n              return { name, from: map.get(name)! }\n            }\n            return undefined\n          },\n        ],\n      }),\n      livePreview(),\n    ],\n    define: {\n      __VUETIFY_VERSION__: JSON.stringify(vuetifyPackage.version),\n      'process.env.BABEL_TYPES_8_BREAKING': 'false',\n      'process.env.VITE_SSR': process.env.VITE_SSR,\n    },\n    build: {\n      minify: false,\n      sourcemap: 'inline',\n    },\n  }\n})\n"
  },
  {
    "path": "packages/vuetify/vitest.config.ts",
    "content": "import { defineConfig, mergeConfig } from 'vitest/config'\nimport { playwright } from '@vitest/browser-playwright'\nimport { vizzlyPlugin } from '@vizzly-testing/vitest'\nimport viteConfig from './vite.config'\nimport AutoImport from 'unplugin-auto-import/vite'\nimport { fileURLToPath } from 'node:url'\nimport { commands } from './test/setup/browser-commands'\n\nconst IS_RUN = process.argv.slice(2).some(v => v === 'run')\n\nexport default defineConfig(configEnv => {\n  return mergeConfig(\n    viteConfig(configEnv),\n    defineConfig({\n      root: './src',\n      resolve: {\n        alias: {\n          vue: 'vue/dist/vue.esm-bundler.js',\n          '@test': fileURLToPath(new URL('test/index.ts', import.meta.url)),\n        },\n      },\n      optimizeDeps: {\n        exclude: ['@vue/test-utils'],\n      },\n      plugins: [\n        vizzlyPlugin(),\n        AutoImport({\n          include: '**/*.spec.?(browser.)@(ts|tsx)',\n          imports: {\n            vitest: [\n              'describe',\n              'it',\n              'expect',\n              'assert',\n              'vi',\n              'beforeAll',\n              'afterAll',\n              'beforeEach',\n              'afterEach',\n            ],\n          },\n          dts: true,\n        }),\n      ],\n      server: {\n        hmr: false,\n        preTransformRequests: false,\n      },\n      clearScreen: !IS_RUN,\n      define: {\n        'process.env.TEST_TDD_ONLY': process.env.TEST_TDD_ONLY,\n      },\n      test: {\n        watch: false,\n        slowTestThreshold: Infinity,\n        setupFiles: ['../test/setup/to-have-been-warned.ts'],\n        reporters: process.env.GITHUB_ACTIONS\n          ? [['default', { summary: false }], 'github-actions']\n          : [IS_RUN ? 'dot' : ['default', { summary: false }]],\n        attachmentsDir: '../test/__attachments__',\n        coverage: {\n          provider: 'istanbul',\n          reporter: ['html', 'text-summary'],\n          clean: true,\n          reportsDirectory: '../coverage',\n        },\n        projects: [\n          {\n            extends: true,\n            resolve: {\n              alias: {\n                // Vite logs a warning for this even if we just re-export it without using anything\n                'vitest/browser': fileURLToPath(new URL('test/contextStub.ts', import.meta.url)),\n              },\n            },\n            test: {\n              name: 'unit',\n              include: ['**/*.spec.{ts,tsx}'],\n              setupFiles: ['../test/setup/unit-setup.ts'],\n              environment: 'jsdom',\n            },\n          },\n          {\n            extends: true,\n            test: {\n              name: 'browser',\n              include: ['**/*.spec.browser.{ts,tsx}'],\n              setupFiles: ['../test/setup/browser-setup.ts'],\n              bail: process.env.TEST_BAIL ? 1 : undefined,\n              browser: {\n                enabled: true,\n                provider: playwright({\n                  actionTimeout: 5000,\n                  contextOptions: {\n                    reducedMotion: 'reduce',\n                    permissions: ['clipboard-write', 'clipboard-read'],\n                  },\n                  launchOptions: {\n                    ignoreDefaultArgs: ['--hide-scrollbars'],\n                    args: [\n                      '--start-maximized',\n                      '--disable-infobars',\n                      process.env.TEST_BAIL && '--auto-open-devtools-for-tabs',\n                    ].filter(v => v != null),\n                  },\n                }),\n                ui: false,\n                headless: !process.env.TEST_BAIL,\n                screenshotDirectory: '../test/__screenshots__',\n                commands,\n                instances: [{\n                  browser: 'chromium',\n                }],\n                viewport: {\n                  width: 1280,\n                  height: 800,\n                },\n              },\n            },\n          },\n        ],\n      },\n    })\n  )\n})\n"
  },
  {
    "path": "packages/vuetify/vizzly.config.js",
    "content": "export default {\n  comparison: {\n    threshold: 1,\n    minClusterSize: 4,\n  },\n  signatureProperties: ['theme', 'device'],\n}\n"
  },
  {
    "path": "patches/@mdi__js@7.4.47.patch",
    "content": "diff --git a/package.json b/package.json\nindex 0d142171bd1599a549c1c2a903fc3be234d1505c..a2acafcb0ec6ef6e7800d7b9467956c60780d419 100644\n--- a/package.json\n+++ b/package.json\n@@ -6,6 +6,14 @@\n   \"module\": \"mdi.js\",\n   \"types\": \"mdi.d.ts\",\n   \"sideEffects\": false,\n+  \"type\": \"module\",\n+  \"exports\": {\n+    \".\": {\n+      \"types\": \"./mdi.d.ts\",\n+      \"import\": \"./mdi.js\",\n+      \"require\": \"./commonjs/mdi.js\"\n+    }\n+  },\n   \"scripts\": {\n     \"build\": \"npm update && npm install && npm run buildjs && npm run es5 && npm run commonjs\",\n     \"buildjs\": \"node build.js\",\n"
  },
  {
    "path": "patches/@testing-library__vue.patch",
    "content": "diff --git a/dist/render.js b/dist/render.js\nindex 948b5b112ddb6a86516955d45d70791960e22676..47c757c2af9eab0cf9b66f96a7d5038751065551 100644\n--- a/dist/render.js\n+++ b/dist/render.js\n@@ -43,6 +43,9 @@ function render(Component) {\n   return _objectSpread({\n     container,\n     baseElement,\n+    wrapper,\n+    element: wrapper.element,\n+    vm: wrapper.vm,\n     debug: function debug() {\n       var el = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : baseElement;\n       var maxLength = arguments.length > 1 ? arguments[1] : undefined;\ndiff --git a/types/index.d.ts b/types/index.d.ts\nindex d4edc3bfe9aa77e5ffb39c20d172d0d56aa625b6..9e749cfc116ee78bc8250f28988027921e968f79 100644\n--- a/types/index.d.ts\n+++ b/types/index.d.ts\n@@ -1,8 +1,8 @@\n // Minimum TypeScript Version: 4.0\n /* eslint-disable @typescript-eslint/no-explicit-any */\n \n-import {VNodeChild} from 'vue'\n-import {MountingOptions} from '@vue/test-utils'\n+import {ComponentPublicInstance, VNodeChild} from 'vue'\n+import {MountingOptions, VueWrapper} from '@vue/test-utils'\n import {queries, EventType, BoundFunctions} from '@testing-library/dom'\n // eslint-disable-next-line import/no-extraneous-dependencies\n import {OptionsReceived as PrettyFormatOptions} from 'pretty-format'\n@@ -23,6 +23,9 @@ type Debug = (\n export interface RenderResult extends BoundFunctions<typeof queries> {\n   container: Element\n   baseElement: Element\n+  element: Element\n+  wrapper: VueWrapper\n+  vm: ComponentPublicInstance\n   debug: Debug\n   unmount(): void\n   html(): string\n"
  },
  {
    "path": "patches/@vitest__browser.patch",
    "content": "diff --git a/dist/client/__vitest_browser__/orchestrator-8U3FyXSU.js b/dist/client/__vitest_browser__/orchestrator-8U3FyXSU.js\nindex a22a3b0d0e13e08a34bce430bc284d998de8528b..00c0722cb008a9a6d527ecfd50844d92f2674a60 100644\n--- a/dist/client/__vitest_browser__/orchestrator-8U3FyXSU.js\n+++ b/dist/client/__vitest_browser__/orchestrator-8U3FyXSU.js\n@@ -290,18 +290,9 @@ async function setIframeViewport(iframe, width, height) {\n       [{ width, height }]\n     );\n   } else {\n-    const scale = Math.min(\n-      1,\n-      iframe.parentElement.parentElement.clientWidth / width,\n-      iframe.parentElement.parentElement.clientHeight / height\n-    );\n-    iframe.parentElement.style.cssText = `\n-      width: ${width}px;\n-      height: ${height}px;\n-      transform: scale(${scale});\n-      transform-origin: left top;\n-    `;\n-    (_b = iframe.parentElement) == null ? void 0 : _b.setAttribute(\"data-scale\", String(scale));\n+    iframe.style.width = `${width}px`\n+    iframe.style.height = `${height}px`\n+    iframe.parentElement?.setAttribute('data-scale', '1')\n     await new Promise((r) => requestAnimationFrame(r));\n   }\n }\n"
  },
  {
    "path": "patches/playwright-core.patch",
    "content": "diff --git a/lib/server/registry/dependencies.js b/lib/server/registry/dependencies.js\nindex 6d24feae7024dd1d448e507d8dcb8a0ebb6a31c3..f4b3456bf992e53571687920ec6fb5b77f85ac65 100644\n--- a/lib/server/registry/dependencies.js\n+++ b/lib/server/registry/dependencies.js\n@@ -221,6 +221,11 @@ async function validateDependenciesLinux(sdkLanguage, linuxLddDirectories, dlOpe\n       missingDeps.delete(missingDep);\n     }\n   }\n+\n+  // Ubuntu 25.04 has libicu76 instead but works fine\n+  if (!missingDeps.size && missingPackages.size === 1 && missingPackages.has('libicu74'))\n+    return;\n+\n   const maybeSudo = process.getuid?.() && import_os.default.platform() !== \"win32\" ? \"sudo \" : \"\";\n   const dockerInfo = readDockerVersionSync();\n   const errorLines = [\n"
  },
  {
    "path": "pnpm-workspace.yaml",
    "content": "packages:\n  - packages/*\n\nautoInstallPeers: false\n\nignoreWorkspaceRootCheck: true\n\nignoredBuiltDependencies:\n  - '@parcel/watcher'\n  - esbuild\n  - edgedriver\n  - geckodriver\n  - unrs-resolver\n  - vue-demi\n\nlinkWorkspacePackages: deep\n\nminimumReleaseAge: 4320\n\nminimumReleaseAgeExclude:\n  - '@vuetify/one'\n  - '@vuetify/testing-library-dom'\n  - playwright\n  - playwright-core\n  - '@vizzly-testing/vitest@0.1.1'\n\nnodeLinker: hoisted\n\noverrides:\n  '@testing-library/dom': npm:@vuetify/testing-library-dom@1.0.3\n  '@types/node': $@types/node\n  '@vue/babel-plugin-jsx': npm:@vuetify/babel-plugin-jsx@1.6.0\n  brilliant-errors>bumpp: '-'\n  brilliant-errors>vitest: '-'\n  vite-ssr>react-router-dom: '-'\n  vite-ssr>react-ssr-prepass: '-'\n\npatchedDependencies:\n  '@mdi/js@7.4.47': patches/@mdi__js@7.4.47.patch\n  '@testing-library/vue': patches/@testing-library__vue.patch\n  '@vitest/browser': patches/@vitest__browser.patch\n  playwright-core: patches/playwright-core.patch\n\npeerDependencyRules:\n  allowedVersions:\n    '@sentry/vue>pinia': '*'\n    '@testing-library/user-event>@testing-library/dom': '*'\n    '@vitejs/plugin-vue': '*'\n    '@vueuse/head': '*'\n    rollup: '*'\n    vite: '*'\n\nshellEmulator: true\n\nupdateConfig:\n  ignoreDependencies:\n    - babel-plugin-add-import-extension\n"
  },
  {
    "path": "renovate.json",
    "content": "{\n  \"extends\": [\"github>vuetifyjs/renovate-config\"]\n}\n"
  },
  {
    "path": "scripts/build.js",
    "content": "import { spawn } from 'cross-spawn'\n\nlet target = process.argv[2]\nconst alias = {\n  api: '@vuetify/api-generator',\n  docs: 'vuetifyjs.com',\n  dev: 'vuetify',\n}\ntarget = alias[target] || target\n\nlet result\nif (!target) {\n  result = spawn.sync('pnpm', ['run', '-r', '--stream', 'build'], { stdio: 'inherit' })\n} else {\n  result = spawn.sync('pnpm', ['run', '-r', '--filter', target, '--stream', '--reporter-hide-prefix', 'build'], { stdio: 'inherit' })\n}\n\nprocess.exitCode = result.status\n"
  },
  {
    "path": "scripts/confirm-npm-tag.js",
    "content": "import semver from 'semver'\nimport shell from 'shelljs'\nimport inquirer from 'inquirer'\nimport lerna from '../lerna.json' with { type: 'json' }\n\nif (process.env.CI) process.exit(0)\n\n/**\n * @param command {string}\n * @returns {string}\n */\nfunction exec (command) {\n  const result = shell.exec(command, { silent: true })\n  if (result.code) {\n    shell.echo('')\n    console.error(result.stdout.trim())\n    shell.exit(1)\n  }\n  return result.stdout.trim()\n}\n\nconst branch = exec('git symbolic-ref --short HEAD')\nconst tag = semver.prerelease(lerna.version) == null ? 'latest' : branch\n\nshell.echo(`Releasing ${lerna.version} on ${branch}`)\nshell.echo(`Tag: ${tag}`)\ninquirer.prompt({\n  type: 'confirm',\n  name: 'yes',\n  message: 'Are you sure?',\n  default: true,\n}).then(({ yes }) => yes || shell.exit(1))\n"
  },
  {
    "path": "scripts/converter.js",
    "content": "// Utilities\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport glob from 'glob'\nimport stringify from 'stringify-object'\nimport url from 'node:url'\n\nconst root = path.dirname(url.fileURLToPath(import.meta.url))\nconst resolve = file => path.resolve(root, file)\n\nconst snippetsUsed = new Set()\n\nfunction genCode (value) {\n  const [lang, ...rest] = value.split('_')\n  const name = rest.join('_')\n\n  const snippet = resolve(`../packages/docs/src/snippets/${lang}/${name}.txt`)\n  // const src = fs.readFileSync(snippet, 'utf8')\n  if (snippetsUsed.has(snippet)) console.log(`Snippet \"${value}\" used multiple times`)\n  snippetsUsed.add(snippet)\n\n  // return `code(lang=\"${lang}\")\\n` + src.split('\\n').map(s => ('  | ' + s).trimEnd()).join('\\n')\n  return `code(lang=\"${lang}\" src=\"${name}\")`\n}\n\nfunction parse (child) {\n  const {\n    lang,\n    type,\n    value,\n  } = child\n\n  switch (type) {\n    case 'alert': return `alert(value=\"${value}\") ${lang}`\n    case 'heading': return `\\nh2 ${lang}`\n    case 'markup': return genCode(value)\n    case 'text': return `| ${lang}`\n  }\n\n  let ret = (type === 'up-next' ? '\\n' : '') + type\n\n  if (value) {\n    ret += '('\n    if (typeof value === 'string') {\n      ret += `value=\"${value}\"`\n    } else if (typeof value === 'object') {\n      ret += `:value=\\`${stringify(value, { indent: '  ' })}\\``\n    }\n    ret += ')'\n  }\n  if (lang) ret += ` ${lang}`\n\n  return ret\n}\n\nfunction recurse (children = []) {\n  return children.reduce((acc, cur) => {\n    if (cur.children && cur.children.length) {\n      acc = [].concat(acc, recurse(cur.children))\n    } else {\n      acc.push(parse(cur))\n    }\n\n    return acc\n  }, [])\n}\n\nconst loc = str => resolve(`../packages/docs/src/data/pages/${str}`)\nconst files = glob.sync(resolve(`../packages/docs/src/data/pages/**/*.json`))\n\nfor (const file of files) {\n  const path = file\n    .split('/pages/')\n    .pop()\n    .split('/')\n    .map(i => i.replace(/\\.json/, ''))\n    .join('/')\n  const read = JSON.parse(fs.readFileSync(loc(`${path}.json`), 'utf8'))\n  const children = recurse([read]).join('\\n').trim() + '\\n'\n\n  fs.writeFileSync(loc(`${path}.pug`), children, 'utf8')\n  fs.unlinkSync(file)\n}\n\n// snippetsUsed.forEach(file => fs.unlinkSync(file))\n"
  },
  {
    "path": "scripts/dev.js",
    "content": "import { spawn } from 'cross-spawn'\n\nlet target = process.argv[2]\nconst alias = {\n  docs: 'vuetifyjs.com',\n}\ntarget = alias[target] || target || 'vuetify'\n\nspawn('pnpm', ['run', '--filter', target, '--stream', 'dev'], { stdio: 'inherit' })\n"
  },
  {
    "path": "scripts/lint-commit-message.js",
    "content": "import fs from 'node:fs'\n\nconst reset = '\\x1b[0m'\nconst red = '\\x1b[31m'\n\nconst [messageFile] = process.argv.slice(2)\nconst currentMessage = fs.readFileSync(messageFile, 'utf8')\n  .replace(/^# ------------------------ >8 ------------------------[\\s\\S]*$|^#.*\\n/gm, '')\n\nconst errors = []\n\n/**\n * @param message {string}\n * @param cb {(currentMessage: string) => boolean}\n */\nfunction check (message, cb) {\n  if (cb(currentMessage)) {\n    errors.push(message)\n  }\n}\n\ncheck('Whitespace at beginning of message', m => /^\\s/.test(m))\ncheck('Title is too long. limit to 72 chars', m => m.trim().split(/\\r?\\n/, 1)[0].length > 72)\ncheck('Title and body must be separated by a blank line', m => {\n  const s = m.trim().split(/\\r?\\n/, 3)\n  return s[1] != null && !!s[1].length\n})\n\nif (errors.length) {\n  const s = errors.length > 1 ? 's' : ''\n  console.log()\n  console.log(red + `Error${s} in commit message:` + reset)\n  errors.forEach(err => {\n    console.log('  - ' + err)\n  })\n  console.log()\n  console.log('-'.repeat(72))\n  console.log('Original message:')\n  console.log('='.repeat(72))\n  console.log(currentMessage.trimRight())\n  console.log('='.repeat(72))\n  process.exit(1)\n}\n"
  },
  {
    "path": "scripts/options-to-composition.mjs",
    "content": "import fs from 'node:fs/promises'\nimport path from 'node:path'\nimport { ESLint } from 'eslint'\nimport { convertSrc } from 'vue-composition-converter'\n\nconst DIR = 'packages/docs/src/examples/'\n\nconst linter = new ESLint({\n  fix: true,\n  cwd: path.resolve(DIR),\n})\n\nfor (const group of await fs.readdir(DIR)) {\n  for (const file of await fs.readdir(path.join(DIR, group))) {\n    const code = await fs.readFile(path.join(DIR, group, file), 'utf-8')\n\n    const composition = /(<script setup>[\\w\\W]*?<\\/script>)/g.exec(code)\n    const options = /(<script>[\\w\\W]*?<\\/script>)/g.exec(code)\n\n    if (!(composition || options) || (composition && options)) continue\n    if (composition && !options) {\n      console.log('composition only', path.join(group, file))\n      continue\n    }\n\n    let output\n    try {\n      output = convertSrc(code)\n    } catch (e) {\n      if (e.message === 'no convert target') continue\n      else throw e\n    }\n\n    output = await linter.lintText(`<script setup>\\n${output}</script>`, { filePath: path.join(group, file) })\n\n    output = code.slice(0, options.index) + output[0].output + '\\n' + code.slice(options.index)\n\n    await fs.writeFile(path.join(DIR, group, file), output)\n    console.log('converted', path.join(group, file))\n  }\n}\n"
  },
  {
    "path": "scripts/parse-npm-tag.js",
    "content": "import semver from 'semver'\n\nconst version = process.argv[2]\n\nif (!semver.valid(version)) {\n  console.error(`Error: '${version}' is not a valid NPM version string`)\n  process.exit(9)\n}\n\nconst prerelease = semver.prerelease(version)\nconst major = semver.major(version)\n\nif (prerelease == null) {\n  if (major > 4) {\n    console.log('next')\n  } else {\n    console.log('latest')\n  }\n} else {\n  console.log('dev')\n}\n"
  },
  {
    "path": "scripts/post-install.js",
    "content": "import shell from 'shelljs'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport url from 'node:url'\n\nconst root = path.dirname(url.fileURLToPath(import.meta.url))\nconst resolve = target => path.resolve(root, target)\n\nconst devTargetFolder = '../packages/vuetify/dev'\nconst devTargetFile = `${devTargetFolder}/Playground.vue`\n\nif (!fs.existsSync(resolve(devTargetFile))) {\n  shell.cp(\n    resolve(`${devTargetFolder}/Playground.template.vue`),\n    resolve(devTargetFile)\n  )\n}\n"
  },
  {
    "path": "scripts/post-release-merge.js",
    "content": "import shell from 'shelljs'\n\nlet branch = exec('git symbolic-ref --short HEAD')\n\nif (process.env.CI) process.exit(0)\n\n/**\n * @param command {string}\n * @returns {string}\n */\nfunction exec (command) {\n  const result = shell.exec(command, { silent: true })\n  if (result.code) {\n    shell.echo('')\n    console.error(result.stdout.trim())\n    shell.exit(1)\n  }\n  return result.stdout.trim()\n}\n\nif (branch === 'master') {\n  shell.exec('git checkout dev')\n  branch = 'dev'\n  shell.exec('git pull --ff-only')\n  shell.exec('git merge master')\n\n  if (exec('git status --porcelain') === '') {\n    shell.exec('git push --no-verify')\n    shell.exec('git checkout master')\n  } else {\n    shell.echo('Please resolve conflicts then push the current branch')\n  }\n}\n"
  },
  {
    "path": "scripts/prepare-commit-message.js",
    "content": "import fs from 'node:fs'\n\nconst [messageFile, commitType] = process.argv.slice(2)\n\nif (commitType == null) {\n  const currentMessage = fs.readFileSync(messageFile)\n  const newMessage = fs.readFileSync('.github/.git_commit_msg.txt')\n  fs.writeFileSync(messageFile, newMessage)\n  fs.appendFileSync(messageFile, currentMessage)\n}\n"
  },
  {
    "path": "scripts/rules/jsx-condition-key.js",
    "content": "export default {\n  create (context) {\n    return {\n      JSXExpressionContainer (node) {\n        if (!['LogicalExpression', 'ConditionalExpression'].includes(node.expression.type)) return\n\n        if (\n          node.parent.type !== 'JSXElement' ||\n          node.parent.children.slice(node.parent.children.indexOf(node))\n            .every(child => child === node || child.type === 'JSXText')\n        ) return\n\n        const test = node.expression.type === 'LogicalExpression'\n          ? node.expression.left\n          : node.expression.test\n        if (\n          (\n            test.type === 'ChainExpression' &&\n            test.expression.type === 'CallExpression' &&\n            test.expression.callee.type === 'MemberExpression' &&\n            test.expression.callee.object.name === 'slots'\n          ) || (\n            test.type === 'MemberExpression' &&\n            test.object.name === 'slots'\n          ) || (\n            test.type === 'CallExpression' &&\n            test.callee.type === 'MemberExpression' &&\n            test.callee.object.name === 'slots'\n          )\n        ) return\n\n        const tags = node.expression.type === 'LogicalExpression'\n          ? [node.expression.right]\n          : [node.expression.consequent, node.expression.alternate]\n\n        tags.forEach(tag => {\n          if (tag.type !== 'JSXElement') return\n\n          const key = tag.openingElement.attributes.find(attr => attr.type === 'JSXAttribute' && attr.name.name === 'key')\n          if (!key) {\n            context.report({\n              loc: {\n                start: tag.openingElement.loc.start,\n                end: tag.openingElement.name.loc.end,\n              },\n              message: 'Conditional JSX elements must have a key attribute',\n            })\n          }\n        })\n      },\n    }\n  },\n}\n"
  },
  {
    "path": "scripts/rules/jsx-curly-spacing.js",
    "content": "/**\n * @fileoverview Enforce or disallow spaces inside of curly braces in JSX attributes.\n * @author Jamund Ferguson\n * @author Brandyn Bennett\n * @author Michael Ficarra\n * @author Vignesh Anand\n * @author Jamund Ferguson\n * @author Yannick Croissant\n * @author Erik Wendel\n */\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst SPACING = {\n  always: 'always',\n  never: 'never',\n}\nconst SPACING_VALUES = [SPACING.always, SPACING.never]\n\nconst messages = {\n  noNewlineAfter: 'There should be no newline after \\'{{token}}\\'',\n  noNewlineBefore: 'There should be no newline before \\'{{token}}\\'',\n  noSpaceAfter: 'There should be no space after \\'{{token}}\\'',\n  noSpaceBefore: 'There should be no space before \\'{{token}}\\'',\n  spaceNeededAfter: 'A space is required after \\'{{token}}\\'',\n  spaceNeededBefore: 'A space is required before \\'{{token}}\\'',\n}\n\nexport default {\n  meta: {\n    docs: {\n      description: 'Enforce or disallow spaces inside of curly braces in JSX attributes and expressions',\n      category: 'Stylistic Issues',\n      recommended: false,\n    },\n    fixable: 'code',\n\n    messages,\n\n    schema: {\n      definitions: {\n        basicConfig: {\n          type: 'object',\n          properties: {\n            when: {\n              enum: SPACING_VALUES,\n            },\n            allowMultiline: {\n              type: 'boolean',\n            },\n            spacing: {\n              type: 'object',\n              properties: {\n                objectLiterals: {\n                  enum: SPACING_VALUES,\n                },\n                arrayLiterals: {\n                  enum: SPACING_VALUES,\n                },\n                multilineClose: {\n                  enum: SPACING_VALUES,\n                },\n              },\n            },\n          },\n        },\n        basicConfigOrBoolean: {\n          anyOf: [{\n            $ref: '#/definitions/basicConfig',\n          }, {\n            type: 'boolean',\n          }],\n        },\n      },\n      type: 'array',\n      items: [{\n        anyOf: [{\n          allOf: [{\n            $ref: '#/definitions/basicConfig',\n          }, {\n            type: 'object',\n            properties: {\n              attributes: {\n                $ref: '#/definitions/basicConfigOrBoolean',\n              },\n              children: {\n                $ref: '#/definitions/basicConfigOrBoolean',\n              },\n            },\n          }],\n        }, {\n          enum: SPACING_VALUES,\n        }],\n      }, {\n        type: 'object',\n        properties: {\n          allowMultiline: {\n            type: 'boolean',\n          },\n          spacing: {\n            type: 'object',\n            properties: {\n              objectLiterals: {\n                enum: SPACING_VALUES,\n              },\n              arrayLiterals: {\n                enum: SPACING_VALUES,\n              },\n              multilineClose: {\n                enum: SPACING_VALUES,\n              },\n            },\n          },\n        },\n        additionalProperties: false,\n      }],\n    },\n  },\n\n  create (context) {\n    function normalizeConfig (configOrTrue, defaults, lastPass) {\n      const config = configOrTrue === true ? {} : configOrTrue\n      const when = config.when || defaults.when\n      const allowMultiline = Object.hasOwn(config, 'allowMultiline') ? config.allowMultiline : defaults.allowMultiline\n      const spacing = config.spacing || {}\n      let objectLiteralSpaces = spacing.objectLiterals || defaults.objectLiteralSpaces\n      let arrayLiteralSpaces = spacing.arrayLiterals || defaults.arrayLiteralSpaces\n      let multilineCloseSpaces = spacing.multilineClose || defaults.multilineCloseSpaces\n      if (lastPass) {\n        // On the final pass assign the values that should be derived from others if they are still undefined\n        objectLiteralSpaces = objectLiteralSpaces || when\n        arrayLiteralSpaces = arrayLiteralSpaces || when\n        multilineCloseSpaces = multilineCloseSpaces || when\n      }\n\n      return {\n        when,\n        allowMultiline,\n        objectLiteralSpaces,\n        arrayLiteralSpaces,\n        multilineCloseSpaces,\n      }\n    }\n\n    const DEFAULT_WHEN = SPACING.never\n    const DEFAULT_ALLOW_MULTILINE = true\n    const DEFAULT_ATTRIBUTES = true\n    const DEFAULT_CHILDREN = false\n\n    let originalConfig = context.options[0] || {}\n    if (SPACING_VALUES.indexOf(originalConfig) !== -1) {\n      originalConfig = Object.assign({ when: context.options[0] }, context.options[1])\n    }\n    const defaultConfig = normalizeConfig(originalConfig, {\n      when: DEFAULT_WHEN,\n      allowMultiline: DEFAULT_ALLOW_MULTILINE,\n    })\n    const attributes = Object.hasOwn(originalConfig, 'attributes') ? originalConfig.attributes : DEFAULT_ATTRIBUTES\n    const attributesConfig = attributes ? normalizeConfig(attributes, defaultConfig, true) : null\n    const children = Object.hasOwn(originalConfig, 'children') ? originalConfig.children : DEFAULT_CHILDREN\n    const childrenConfig = children ? normalizeConfig(children, defaultConfig, true) : null\n\n    // --------------------------------------------------------------------------\n    // Helpers\n    // --------------------------------------------------------------------------\n\n    /**\n     * Determines whether two adjacent tokens have a newline between them.\n     * @param {Object} left - The left token object.\n     * @param {Object} right - The right token object.\n     * @returns {boolean} Whether or not there is a newline between the tokens.\n     */\n    function isMultiline (left, right) {\n      return left.loc.end.line !== right.loc.start.line\n    }\n\n    /**\n     * Trims text of whitespace between two ranges\n     * @param {Fixer} fixer - the eslint fixer object\n     * @param {number} fromLoc - the start location\n     * @param {number} toLoc - the end location\n     * @param {string} mode - either 'start' or 'end'\n     * @param {string=} spacing - a spacing value that will optionally add a space to the removed text\n     * @returns {Object|*|{range, text}}\n     */\n    function fixByTrimmingWhitespace (fixer, fromLoc, toLoc, mode, spacing) {\n      let replacementText = context.getSourceCode().text.slice(fromLoc, toLoc)\n      if (mode === 'start') {\n        replacementText = replacementText.replace(/^\\s+/gm, '')\n      } else {\n        replacementText = replacementText.replace(/\\s+$/gm, '')\n      }\n      if (spacing === SPACING.always) {\n        if (mode === 'start') {\n          replacementText += ' '\n        } else {\n          replacementText = ` ${replacementText}`\n        }\n      }\n      return fixer.replaceTextRange([fromLoc, toLoc], replacementText)\n    }\n\n    /**\n     * Reports that there shouldn't be a newline after the first token\n     * @param {ASTNode} node - The node to report in the event of an error.\n     * @param {Token} token - The token to use for the report.\n     * @param {string} spacing\n     * @returns {void}\n     */\n    function reportNoBeginningNewline (node, token, spacing) {\n      context.report({\n        node,\n        loc: token.loc.start,\n        messageId: 'noNewlineAfter',\n        data: {\n          token: token.value,\n        },\n        fix (fixer) {\n          const nextToken = context.getSourceCode().getTokenAfter(token)\n          return fixByTrimmingWhitespace(fixer, token.range[1], nextToken.range[0], 'start', spacing)\n        },\n      })\n    }\n\n    /**\n     * Reports that there shouldn't be a newline before the last token\n     * @param {ASTNode} node - The node to report in the event of an error.\n     * @param {Token} token - The token to use for the report.\n     * @param {string} spacing\n     * @returns {void}\n     */\n    function reportNoEndingNewline (node, token, spacing) {\n      context.report({\n        node,\n        loc: token.loc.start,\n        messageId: 'noNewlineBefore',\n        data: {\n          token: token.value,\n        },\n        fix (fixer) {\n          const previousToken = context.getSourceCode().getTokenBefore(token)\n          return fixByTrimmingWhitespace(fixer, previousToken.range[1], token.range[0], 'end', spacing)\n        },\n      })\n    }\n\n    /**\n     * Reports that there shouldn't be a space after the first token\n     * @param {ASTNode} node - The node to report in the event of an error.\n     * @param {Token} token - The token to use for the report.\n     * @returns {void}\n     */\n    function reportNoBeginningSpace (node, token) {\n      context.report({\n        node,\n        loc: token.loc.start,\n        messageId: 'noSpaceAfter',\n        data: {\n          token: token.value,\n        },\n        fix (fixer) {\n          const sourceCode = context.getSourceCode()\n          const nextToken = sourceCode.getTokenAfter(token)\n          let nextComment\n\n          // eslint >=4.x\n          if (sourceCode.getCommentsAfter) {\n            nextComment = sourceCode.getCommentsAfter(token)\n            // eslint 3.x\n          } else {\n            const potentialComment = sourceCode.getTokenAfter(token, { includeComments: true })\n            nextComment = nextToken === potentialComment ? [] : [potentialComment]\n          }\n\n          // Take comments into consideration to narrow the fix range to what is actually affected. (See #1414)\n          if (nextComment.length > 0) {\n            return fixByTrimmingWhitespace(fixer, token.range[1], Math.min(nextToken.range[0], nextComment[0].range[0]), 'start')\n          }\n\n          return fixByTrimmingWhitespace(fixer, token.range[1], nextToken.range[0], 'start')\n        },\n      })\n    }\n\n    /**\n     * Reports that there shouldn't be a space before the last token\n     * @param {ASTNode} node - The node to report in the event of an error.\n     * @param {Token} token - The token to use for the report.\n     * @returns {void}\n     */\n    function reportNoEndingSpace (node, token) {\n      context.report({\n        node,\n        loc: token.loc.start,\n        messageId: 'noSpaceBefore',\n        data: {\n          token: token.value,\n        },\n        fix (fixer) {\n          const sourceCode = context.getSourceCode()\n          const previousToken = sourceCode.getTokenBefore(token)\n          let previousComment\n\n          // eslint >=4.x\n          if (sourceCode.getCommentsBefore) {\n            previousComment = sourceCode.getCommentsBefore(token)\n            // eslint 3.x\n          } else {\n            const potentialComment = sourceCode.getTokenBefore(token, { includeComments: true })\n            previousComment = previousToken === potentialComment ? [] : [potentialComment]\n          }\n\n          // Take comments into consideration to narrow the fix range to what is actually affected. (See #1414)\n          if (previousComment.length > 0) {\n            return fixByTrimmingWhitespace(fixer, Math.max(previousToken.range[1], previousComment[0].range[1]), token.range[0], 'end')\n          }\n\n          return fixByTrimmingWhitespace(fixer, previousToken.range[1], token.range[0], 'end')\n        },\n      })\n    }\n\n    /**\n     * Reports that there should be a space after the first token\n     * @param {ASTNode} node - The node to report in the event of an error.\n     * @param {Token} token - The token to use for the report.\n     * @returns {void}\n     */\n    function reportRequiredBeginningSpace (node, token) {\n      context.report({\n        node,\n        loc: token.loc.start,\n        messageId: 'spaceNeededAfter',\n        data: {\n          token: token.value,\n        },\n        fix (fixer) {\n          return fixer.insertTextAfter(token, ' ')\n        },\n      })\n    }\n\n    /**\n     * Reports that there should be a space before the last token\n     * @param {ASTNode} node - The node to report in the event of an error.\n     * @param {Token} token - The token to use for the report.\n     * @returns {void}\n     */\n    function reportRequiredEndingSpace (node, token) {\n      context.report({\n        node,\n        loc: token.loc.start,\n        messageId: 'spaceNeededBefore',\n        data: {\n          token: token.value,\n        },\n        fix (fixer) {\n          return fixer.insertTextBefore(token, ' ')\n        },\n      })\n    }\n\n    /**\n     * Determines if spacing in curly braces is valid.\n     * @param {ASTNode} node The AST node to check.\n     * @returns {void}\n     */\n    function validateBraceSpacing (node) {\n      let config\n      switch (node.parent.type) {\n        case 'JSXAttribute':\n        case 'JSXOpeningElement':\n          config = attributesConfig\n          break\n\n        case 'JSXElement':\n        case 'JSXFragment':\n          config = childrenConfig\n          break\n\n        default:\n          return\n      }\n      if (config === null) {\n        return\n      }\n\n      const sourceCode = context.getSourceCode()\n      const first = sourceCode.getFirstToken(node)\n      const last = sourceCode.getLastToken(node)\n      let second = sourceCode.getTokenAfter(first, { includeComments: true })\n      let penultimate = sourceCode.getTokenBefore(last, { includeComments: true })\n\n      if (!second) {\n        second = sourceCode.getTokenAfter(first)\n        const leadingComments = sourceCode.getNodeByRangeIndex(second.range[0]).leadingComments\n        second = leadingComments ? leadingComments[0] : second\n      }\n      if (!penultimate) {\n        penultimate = sourceCode.getTokenBefore(last)\n        const trailingComments = sourceCode.getNodeByRangeIndex(penultimate.range[0]).trailingComments\n        penultimate = trailingComments ? trailingComments[trailingComments.length - 1] : penultimate\n      }\n\n      const isObjectLiteral = second.value === '{'\n      const isArrayLiteral = second.value === '['\n      const isMultilineClose = isMultiline(first, last) && (penultimate.value === ')' || penultimate.value === '}' || penultimate.value === ']')\n      const spacing = isObjectLiteral ? config.objectLiteralSpaces\n        : isArrayLiteral ? config.arrayLiteralSpaces\n        : isMultilineClose ? (config.multilineCloseSpaces === SPACING.never ? 'mixed' : config.multilineCloseSpaces)\n        : config.when\n      if (spacing === SPACING.always) {\n        if (!sourceCode.isSpaceBetweenTokens(first, second)) {\n          reportRequiredBeginningSpace(node, first)\n        } else if (!config.allowMultiline && isMultiline(first, second)) {\n          reportNoBeginningNewline(node, first, spacing)\n        }\n        if (!sourceCode.isSpaceBetweenTokens(penultimate, last)) {\n          reportRequiredEndingSpace(node, last)\n        } else if (!config.allowMultiline && isMultiline(penultimate, last)) {\n          reportNoEndingNewline(node, last, spacing)\n        }\n      } else if (spacing === SPACING.never) {\n        if (isMultiline(first, second)) {\n          if (!config.allowMultiline) {\n            reportNoBeginningNewline(node, first, spacing)\n          }\n        } else if (sourceCode.isSpaceBetweenTokens(first, second)) {\n          reportNoBeginningSpace(node, first)\n        }\n        if (isMultiline(penultimate, last)) {\n          if (!config.allowMultiline) {\n            reportNoEndingNewline(node, last, spacing)\n          }\n        } else if (sourceCode.isSpaceBetweenTokens(penultimate, last)) {\n          reportNoEndingSpace(node, last)\n        }\n      } else if (spacing === 'mixed') {\n        if (!sourceCode.isSpaceBetweenTokens(first, second)) {\n          reportRequiredBeginningSpace(node, first)\n        } else if (!config.allowMultiline && isMultiline(first, second)) {\n          reportNoBeginningNewline(node, first, spacing)\n        }\n        if (isMultiline(penultimate, last)) {\n          if (!config.allowMultiline) {\n            reportNoEndingNewline(node, last, spacing)\n          }\n        } else if (isMultiline(first, last)) {\n          if (sourceCode.isSpaceBetweenTokens(penultimate, last)) {\n            reportNoEndingSpace(node, last)\n          }\n        } else if (!sourceCode.isSpaceBetweenTokens(penultimate, last)) {\n          reportRequiredEndingSpace(node, last)\n        }\n      }\n    }\n\n    // --------------------------------------------------------------------------\n    // Public\n    // --------------------------------------------------------------------------\n\n    return {\n      JSXExpressionContainer: validateBraceSpacing,\n      JSXSpreadAttribute: validateBraceSpacing,\n    }\n  },\n}\n"
  },
  {
    "path": "scripts/rules/jsx-prop-casing.js",
    "content": "import { camelCase } from 'lodash-es'\n\nconst hyphenatedRe = /\\w-\\w/g\n// eslint-disable-next-line max-len\nconst svgTags = new Set(['svg', 'animate', 'animateMotion', 'animateTransform', 'circle', 'clipPath', 'defs', 'desc', 'ellipse', 'filter', 'foreignObject', 'g', 'image', 'line', 'linearGradient', 'marker', 'mask', 'metadata', 'mpath', 'path', 'pattern', 'polygon', 'polyline', 'radialGradient', 'rect', 'stop', 'switch', 'symbol', 'text', 'textPath', 'tspan', 'use', 'view'])\n\nexport default {\n  meta: {\n    fixable: 'code',\n  },\n  create (context) {\n    return {\n      JSXAttribute (node) {\n        const name = node.name.name\n\n        if (\n          !hyphenatedRe.test(name) ||\n          name.startsWith('v-') ||\n          name.startsWith('aria-') ||\n          name.startsWith('data-') ||\n          svgTags.has(node.parent.name.name)\n        ) return\n\n        context.report({\n          node,\n          message: 'JSX props should be camelCase',\n          fix (fixer) {\n            return fixer.replaceText(node.name, camelCase(name))\n          },\n        })\n      },\n    }\n  },\n}\n"
  },
  {
    "path": "scripts/rules/no-components-index.js",
    "content": "export default {\n  create (context) {\n    return {\n      ImportDeclaration (node) {\n        if (node.source.value === '@/components') {\n          context.report(node.source, 'Do not import from \"@/components\"')\n        }\n      },\n    }\n  },\n}\n"
  },
  {
    "path": "scripts/rules/no-nullish-coalescing-in-condition.js",
    "content": "export default {\n  create (context) {\n    const sourceCode = context.getSourceCode()\n\n    function isParenthesised (node) {\n      const previousToken = sourceCode.getTokenBefore(node)\n      const nextToken = sourceCode.getTokenAfter(node)\n\n      return Boolean(previousToken && nextToken) &&\n        previousToken.value === '(' && previousToken.range[1] <= node.range[0] &&\n        nextToken.value === ')' && nextToken.range[0] >= node.range[1]\n    }\n\n    return {\n      ConditionalExpression (node) {\n        if (\n          node.test.type === 'LogicalExpression' &&\n          node.test.operator === '??' &&\n          !isParenthesised(node.test)\n        ) {\n          context.report({\n            node: node.test,\n            message: 'Do not use nullish coalescing in ternary conditions',\n          })\n        }\n      },\n    }\n  },\n}\n"
  },
  {
    "path": "scripts/rules/no-render-string-reference.js",
    "content": "const allowedStrings = [\n  'transition-group',\n]\n\nfunction isCreateElementCall (node) {\n  return (\n    (node.callee.type === 'Identifier' &&\n      node.callee.name === 'h') ||\n    (node.callee.type === 'MemberExpression' &&\n      node.callee.object.type === 'ThisExpression' &&\n      node.callee.property.name === '$createElement')\n  )\n}\n\nfunction isStringRender (node) {\n  return node.arguments[0] &&\n    node.arguments[0].type === 'Literal' &&\n    typeof node.arguments[0].value === 'string'\n}\n\nfunction isCustomComponent (node) {\n  return node.arguments[0] &&\n    RegExp('-').test(node.arguments[0].value) &&\n    !allowedStrings.includes(node.arguments[0].value)\n}\n\nexport default {\n  create (context) {\n    return {\n      CallExpression (node) {\n        if (isCreateElementCall(node) && isStringRender(node) && isCustomComponent(node)) {\n          context.report(node.arguments[0], 'Do not render components by a string reference')\n        }\n      },\n    }\n  },\n}\n"
  },
  {
    "path": "scripts/rules/sort-imports.js",
    "content": "const groups = [\n  {\n    label: 'Styles',\n    match: /\\.s[ac]ss$/,\n  },\n  {\n    label: 'Components',\n    match: /^@\\/components/,\n  },\n  {\n    label: 'Composables',\n    match: /^@\\/composables/,\n  },\n  {\n    label: 'Directives',\n    match: /^@\\/directives/,\n  },\n  {\n    label: 'Utilities',\n    match: /^@\\/util|^vue$|^vue-|^@vue\\/|^@jest|^@?vitest|^@test$|^@testing-library\\//,\n  },\n  {\n    label: 'Types',\n    types: true,\n  },\n]\nconst innerOrder = ['./', '..', '@/']\n\nexport default {\n  meta: {\n    fixable: 'code',\n  },\n  create (context) {\n    const sourceCode = context.getSourceCode()\n    const comments = sourceCode.getAllComments().filter(comment => comment.type === 'Line')\n    const importMap = []\n\n    return {\n      ImportDeclaration (node) {\n        const value = {\n          node,\n          source: node.source.value,\n          types: node.importKind === 'type',\n          code: sourceCode.lines.slice(node.loc.start.line - 1, node.loc.end.line).join('\\n') + '\\n',\n        }\n        const groupIdx = groups.findIndex(group => value.types ? group.types : group.match?.test(node.source.value))\n        const innerIdx = innerOrder.findIndex(prefix => node.source.value.startsWith(prefix))\n        value.groupOrder = ~groupIdx ? groupIdx : null\n        value.innerOrder = innerIdx\n        value.originalOrder = importMap.length\n\n        const groupComment = comments.findLast(c => (\n          c.range[1] < node.range[0] &&\n          /^ [A-Z][a-z]+$/.test(c.value) &&\n          !sourceCode.text.slice(c.range[1], node.range[0]).includes('\\n\\n')\n        ))\n        value.groupComment = groupComment\n        value.originalGroup = groupComment?.value.trim()\n        if (~groupIdx) {\n          value.group = groups[groupIdx].label\n        } else {\n          const groupIdx = groups.findIndex(group => group.label === value.originalGroup)\n          value.groupOrder = ~groupIdx ? groupIdx : null\n          value.group = value.originalGroup\n        }\n\n        importMap.push(value)\n      },\n      'Program:exit' () {\n        const sorted = [...importMap].sort((a, b) => {\n          if ([a.groupOrder, b.groupOrder].includes(null)) return 0\n          if (a.groupOrder === b.groupOrder) {\n            if ([a.innerOrder, b.innerOrder].includes(null)) return 0\n            if (a.innerOrder === b.innerOrder) {\n              return a.source.toLowerCase().localeCompare(b.source.toLowerCase())\n            }\n            return a.innerOrder - b.innerOrder\n          }\n          return a.groupOrder - b.groupOrder\n        }).map((value, idx) => ({\n          ...value,\n          order: idx,\n        }))\n        sorted.forEach(value => {\n          importMap[value.originalOrder] = value\n        })\n\n        const isSorted = sorted.every((value, idx) => value.order === value.originalOrder && value.group === value.originalGroup)\n\n        if (!isSorted) {\n          const problemsForward = []\n          const problemsReverse = []\n          const problemNodes = importMap.filter(value => value.order !== value.originalOrder || value.group !== value.originalGroup)\n          problemNodes.forEach(value => {\n            if (value.group !== value.originalGroup) {\n              problemsForward.push(`  ${value.source} should be in group ${value.group}`)\n            } else if (value.order < value.originalOrder) {\n              const correctNode = sorted.find(v => v.originalOrder === value.order)\n              problemsForward.push(`  ${value.source} should appear before ${correctNode.source}`)\n            }\n          })\n          ;[...problemNodes].reverse().forEach(value => {\n            if (value.group !== value.originalGroup) {\n              problemsReverse.push(`  ${value.source} should be in group ${value.group}`)\n            } else if (value.order > value.originalOrder) {\n              const correctNode = sorted.find(v => v.originalOrder === value.order)\n              problemsReverse.push(`  ${value.source} should appear after ${correctNode.source}`)\n            }\n          })\n          const problems = (problemsForward.length <= problemsReverse.length ? problemsForward : problemsReverse).join('\\n')\n\n          context.report({\n            loc: {\n              start: importMap.at(0).groupComment?.loc.start ?? importMap.at(0).node.loc.start,\n              end: importMap.at(-1).node.loc.end,\n            },\n            message: 'Imports should be sorted\\n' + problems,\n            fix (fixer) {\n              let newCode = ''\n              let currentGroup = null\n              sorted.forEach(value => {\n                if (value.group && value.group !== currentGroup) {\n                  currentGroup = value.group\n                  newCode += `\\n// ${currentGroup}\\n`\n                }\n                newCode += value.code\n              })\n              return fixer.replaceTextRange([\n                importMap.at(0).groupComment?.range[0] ?? importMap.at(0).node.range[0],\n                importMap.at(-1).node.range[0] + importMap.at(-1).code.length,\n              ], newCode.trimStart())\n            },\n          })\n        }\n      },\n    }\n  },\n}\n"
  },
  {
    "path": "scripts/rules/vitest-global-imports.js",
    "content": "export default {\n  meta: {\n    fixable: 'code',\n  },\n  create (context) {\n    return {\n      Program (node) {\n        if (node.comments.some(comment => comment.value.trim() === 'eslint-disable')) return\n\n        const vitestGlobalsImport = node.body.find(node => (\n          node.type === 'ImportDeclaration' &&\n          node.source.value === 'vitest'\n        ))\n\n        if (!vitestGlobalsImport) return\n\n        const badNodes = vitestGlobalsImport.specifiers.filter(node => (\n          ['afterAll', 'afterEach', 'assert', 'beforeAll', 'beforeEach', 'describe', 'expect', 'it', 'vi']\n            .includes(node.imported.name)\n        ))\n\n        if (badNodes.length === vitestGlobalsImport.specifiers.length) {\n          context.report({\n            node: vitestGlobalsImport,\n            message: 'Extraneous vitest imports',\n            fix (fixer) {\n              const range = vitestGlobalsImport.range\n              return fixer.removeRange([range[0], range[1] + 1])\n            },\n          })\n        } else {\n          for (const node of badNodes) {\n            context.report({\n              node,\n              message: 'Extraneous vitest import',\n              fix (fixer) {\n                return fixer.remove(node)\n              },\n            })\n          }\n        }\n      },\n    }\n  },\n}\n"
  },
  {
    "path": "scripts/tdd-run.js",
    "content": "import readline from 'node:readline/promises'\nimport { stdin as input, stdout as output } from 'node:process'\nimport { spawn } from 'cross-spawn'\nimport { getVizzlyInfo } from '@vizzly-testing/cli/client'\n\nasync function main () {\n  const args = process.argv.slice(2)\n\n  const ready = getVizzlyInfo().ready\n\n  if (!ready) {\n    spawn.sync('pnpm', ['exec', 'vizzly', 'tdd', 'start'], {\n      stdio: 'inherit',\n      env: process.env,\n    })\n    process.once('exit', () => {\n      spawn.sync('pnpm', ['exec', 'vizzly', 'tdd', 'stop'], {\n        stdio: 'inherit',\n        env: process.env,\n      })\n    })\n  }\n\n  process.env.TEST_TDD_ONLY = 1\n  const result = spawn.sync('pnpm', ['test:browser', ...args], {\n    stdio: 'inherit',\n    env: process.env,\n  })\n\n  if (!ready && result.status !== 0) {\n    const rl = readline.createInterface({ input, output })\n    rl.setPrompt('Press any key to continue...')\n    rl.prompt()\n    await new Promise(resolve => {\n      rl.input.on('keypress', (str, key) => {\n        rl.close()\n        resolve()\n      })\n    })\n  }\n\n  process.exit(result.status)\n}\nvoid main()\n"
  },
  {
    "path": "scripts/warn-npm-install.js",
    "content": "import fs from 'node:fs'\n\nconst reset = '\\x1b[0m'\nconst red = '\\x1b[31m'\nconst bright = '\\x1b[1m'\n\nconst yarn = fs.existsSync('yarn.lock')\nconst npm = fs.existsSync('package-lock.json')\nif (yarn || npm) {\n  const name = yarn ? 'yarn' : 'npm'\n  const lock = yarn ? 'yarn.lock' : 'package-lock.json'\n  console.log()\n  console.log(`${red}WARNING:${reset}`)\n  console.log(`This project uses ${bright}pnpm${reset}. Installing its dependencies with ${bright}${name}${reset} may result in errors`)\n  console.log(`Please remove ${bright}${lock}${reset} and try again, with pnpm this time`)\n  console.log(`See ${bright}https://pnpm.io/${reset}`)\n  console.log()\n  process.exit(1)\n}\n"
  },
  {
    "path": "templates/browser-test.tsx",
    "content": "import { NAME } from '..'\nimport { render, showcase, userEvent } from '@test'\n\nconst props = {}\n\nconst stories = {\n  Default: <NAME />,\n}\n\n// Tests\ndescribe('NAME', () => {\n  it('does something', async () => {\n    render(<NAME />)\n\n    await userEvent.click(screen.getByTestId(''))\n    await expect.element(screen.getByTestId('')).toHaveTextContent('')\n  })\n\n  showcase({ stories, props, component: NAME })\n})\n"
  },
  {
    "path": "templates/component.tsx",
    "content": "// Styles\nimport './NAME.sass'\n\n// Components\n\n// Composables\n\n// Utilities\nimport { genericComponent, useRender } from '@/util'\n\nexport type ComponentSlots = {\n  default: never\n}\n\nexport const NAME = genericComponent<ComponentSlots>()({\n  name: 'NAME',\n\n  props: {},\n\n  emits: {},\n\n  setup () {\n    useRender(() => (\n      <div class=\"NAME\"></div>\n    ))\n  },\n})\n\nexport type NAME = InstanceType<typeof NAME>\n"
  },
  {
    "path": "templates/page.md",
    "content": "---\nnav: TITLE\nmeta:\n  title: TITLE\n  description: ####\n  keywords: ####, ####\nrelated:\n  - ####\n  - ####\n  - ####\n---\n\n# TITLE\n"
  },
  {
    "path": "templates/unit-test.ts",
    "content": "// Utilities\nimport { render } from '@test'\n\ndescribe('NAME', () => {\n  it('', () => {\n    expect().toBe()\n  })\n})\n"
  },
  {
    "path": "tsconfig.eslint.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"include\": [\n    \"**/*.ts\",\n    \"**/*.tsx\",\n    \"**/*.js\",\n    \"**/.*.ts\",\n    \"**/.*.js\",\n    \"**/*.vue\",\n    \"**/*.json\"\n  ]\n}\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    /* Basic Options */\n    \"target\": \"ESNext\",                       /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */\n    \"module\": \"ESNext\",                       /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */\n    \"lib\": [                                  /* Specify library files to be included in the compilation */\n      \"esnext\",\n      \"dom\",\n      \"dom.iterable\"\n    ],\n    \"allowJs\": false,                         /* Allow javascript files to be compiled. */\n    // \"checkJs\": true,                       /* Report errors in .js files. */\n    \"jsx\": \"preserve\",                        /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */\n    \"declaration\": true,                      /* Generates corresponding '.d.ts' file. */\n    \"declarationMap\": false,\n    \"sourceMap\": true,                        /* Generates corresponding '.map' file. */\n    // \"outFile\": \"./\",                       /* Concatenate and emit output to single file. */\n    \"outDir\": \"./dist\",                       /* Redirect output structure to the directory. */\n    // \"rootDir\": \"./\",                       /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */\n    // \"removeComments\": true,                /* Do not emit comments to output. */\n    // \"noEmit\": true,                        /* Do not emit outputs. */\n    // \"importHelpers\": true,                 /* Import emit helpers from 'tslib'. */\n    \"downlevelIteration\": true,               /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */\n    // \"isolatedModules\": true,               /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */\n    \"skipLibCheck\": false,\n    \"noErrorTruncation\": true,\n\n    /* Strict Type-Checking Options */\n    \"strict\": true,                           /* Enable all strict type-checking options. */\n    // \"noImplicitAny\": true,                 /* Raise error on expressions and declarations with an implied 'any' type. */\n    // \"strictNullChecks\": true,              /* Enable strict null checks. */\n    // \"strictFunctionTypes\": true,           /* Enable strict checking of function types. */\n    // \"strictPropertyInitialization\": true,  /* Enable strict checking of property initialization in classes. */\n    // \"noImplicitThis\": true,                /* Raise error on 'this' expressions with an implied 'any' type. */\n    // \"alwaysStrict\": true,                  /* Parse in strict mode and emit \"use strict\" for each source file. */\n\n    /* Additional Checks */\n    \"noUnusedLocals\": true,                   /* Report errors on unused locals. */\n    // \"noUnusedParameters\": true,            /* Report errors on unused parameters. */\n    \"noImplicitReturns\": true,                /* Report error when not all code paths in function return a value. */\n    // \"noFallthroughCasesInSwitch\": true,    /* Report errors for fallthrough cases in switch statement. */\n\n    /* Module Resolution Options */\n    \"moduleResolution\": \"bundler\",               /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */\n    \"resolveJsonModule\": true,\n    // \"baseUrl\": \"./\",                       /* Base directory to resolve non-absolute module names. */\n    // \"paths\": {                             /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */\n    // },\n    // \"rootDirs\": [],                        /* List of root folders whose combined content represents the structure of the project at runtime. */\n    // \"typeRoots\": [],                       /* List of folders to include type definitions from. */\n    // \"allowSyntheticDefaultImports\": true,  /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */\n    \"esModuleInterop\": true,                  /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */\n    // \"preserveSymlinks\": true,              /* Do not resolve the real path of symlinks. */\n    // \"allowImportingTsExtensions\": true,\n\n    /* Source Map Options */\n    // \"sourceRoot\": \"./\",                    /* Specify the location where debugger should locate TypeScript files instead of source locations. */\n    // \"mapRoot\": \"./\",                       /* Specify the location where debugger should locate map files instead of generated locations. */\n    // \"inlineSourceMap\": true,               /* Emit a single file with source maps instead of having a separate file. */\n    // \"inlineSources\": true,                 /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */\n\n    /* Experimental Options */\n    \"experimentalDecorators\": true,           /* Enables experimental support for ES7 decorators. */\n    \"emitDecoratorMetadata\": true             /* Enables experimental support for emitting type metadata for decorators. */\n  },\n  \"exclude\": [\n    \"node_modules\"\n  ],\n  \"vueCompilerOptions\": {\n    \"jsxSlots\": true\n  }\n}\n"
  }
]